From 1cfcb2af48adf32bb39f73117ee69976429352d3 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sat, 23 May 2026 09:59:02 +0300 Subject: [PATCH 001/287] fix(auth): enforce scoped human role grants --- Makefile | 11 +- README.md | 2 +- cmd/evydence-worker/main.go | 2 +- cmd/evydence-worker/main_test.go | 40 +++++ docs/api.md | 6 +- docs/operations.md | 8 +- internal/adapters/httpapi/router.go | 53 +++++- internal/adapters/httpapi/router_test.go | 4 + internal/app/enterprise.go | 206 ++++++++++++++++++++++- internal/app/enterprise_test.go | 144 ++++++++++++++++ internal/app/governance_packages.go | 22 ++- internal/app/ledger.go | 76 ++++++++- internal/domain/domain.go | 20 ++- 13 files changed, 572 insertions(+), 22 deletions(-) create mode 100644 cmd/evydence-worker/main_test.go diff --git a/Makefile b/Makefile index ab02da6..60c64b6 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ GOLANGCI_LINT_VERSION ?= v2.11.4 GOSEC_VERSION ?= v2.25.0 GOVULNCHECK_VERSION ?= v1.2.0 -.PHONY: help tools fmt lint vuln gosec test test-race coverage openapi-check docs-check deploy-check sdk-check fast-check finalize compose-up compose-down migrate live-postgres-check postgres-integration-test clean +.PHONY: help tools fmt lint vuln gosec test test-race coverage openapi-check docs-check deploy-check sdk-check fast-check finalize release-check compose-up compose-down migrate live-postgres-check postgres-integration-test clean help: ## Show help @awk 'BEGIN {FS=":.*## "}; /^[a-zA-Z0-9_.-]+:.*## / { printf " %-18s %s\n", $$1, $$2 }' $(MAKEFILE_LIST) @@ -90,6 +90,15 @@ finalize: ## Thorough validity check @$(MAKE) deploy-check @$(MAKE) sdk-check +release-check: ## Release validation with security, race, and configured live integration gates + @$(MAKE) finalize + @$(MAKE) lint + @$(MAKE) gosec + @$(MAKE) vuln + @$(MAKE) test-race + @$(MAKE) live-postgres-check + @$(MAKE) postgres-integration-test + compose-up: ## Start local dependencies @docker compose up -d diff --git a/README.md b/README.md index 5c29e44..f79bfbe 100644 --- a/README.md +++ b/README.md @@ -57,4 +57,4 @@ make live-postgres-check make postgres-integration-test ``` -`make finalize` runs the project-owned formatting, unit, OpenAPI, and docs gates. +`make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. diff --git a/cmd/evydence-worker/main.go b/cmd/evydence-worker/main.go index 34260b2..0d14fec 100644 --- a/cmd/evydence-worker/main.go +++ b/cmd/evydence-worker/main.go @@ -76,7 +76,7 @@ func processJob(ctx context.Context, job postgres.ClaimedJob) error { } switch job.Kind { case "parse_sbom", "parse_vulnerability_scan", "parse_openapi_contract", "parse_vex", "sign_bundle", "verify_subject", "verify_attestation": - return nil + return errors.New("outbox job handler is not configured") default: return errors.New("unsupported outbox job kind") } diff --git a/cmd/evydence-worker/main_test.go b/cmd/evydence-worker/main_test.go new file mode 100644 index 0000000..b54c167 --- /dev/null +++ b/cmd/evydence-worker/main_test.go @@ -0,0 +1,40 @@ +package main + +import ( + "context" + "strings" + "testing" + + "github.com/aatuh/evydence/internal/adapters/postgres" +) + +func TestProcessJobFailsClosedForConfiguredButUnhandledJobs(t *testing.T) { + job := postgres.ClaimedJob{ + ID: "job_test", + TenantID: "ten_test", + Kind: "parse_sbom", + SubjectType: "sbom", + SubjectID: "sbom_test", + Payload: map[string]any{"payload_ref": "object://tenants/ten_test/payloads/sbom/raw-secret-name"}, + } + err := processJob(context.Background(), job) + if err == nil { + t.Fatal("expected recognized unhandled job to fail closed") + } + if !strings.Contains(err.Error(), "handler is not configured") { + t.Fatalf("unexpected error: %v", err) + } + if strings.Contains(err.Error(), "raw-secret-name") || strings.Contains(err.Error(), job.SubjectID) { + t.Fatalf("job error leaked payload or subject: %v", err) + } +} + +func TestProcessJobRejectsUnsupportedKinds(t *testing.T) { + err := processJob(context.Background(), postgres.ClaimedJob{Kind: "unknown", Payload: map[string]any{"token": "secret"}}) + if err == nil { + t.Fatal("expected unsupported job kind to fail") + } + if !strings.Contains(err.Error(), "unsupported outbox job kind") || strings.Contains(err.Error(), "secret") { + t.Fatalf("unexpected unsupported job error: %v", err) + } +} diff --git a/docs/api.md b/docs/api.md index 2b9a478..97d1f99 100644 --- a/docs/api.md +++ b/docs/api.md @@ -13,7 +13,7 @@ Accept: application/json Create and action endpoints require `Idempotency-Key`. Reusing the same key with the same request returns the original response. Reusing it with different request content returns `409` with `IDEMPOTENCY_KEY_REUSED`. -Errors use RFC 9457 Problem Details and include a stable `code` field. +Errors use RFC 9457 Problem Details and include stable `code` and `request_id` fields. Clients may send `X-Request-ID`; otherwise the API generates one and returns it in the response header and Problem Details body. The generated OpenAPI document is committed at `openapi.yaml` and served at `/v1/openapi.json`. @@ -21,7 +21,7 @@ The generated OpenAPI document is committed at `openapi.yaml` and served at `/v1 `POST /v1/organizations` creates a tenant-scoped organization. `POST /v1/users` creates a human user with normalized email, and `POST /v1/users/{id}/deactivate` records a deactivation transition. -`POST /v1/role-bindings` assigns a role to a user or collector. Current roles are `tenant_admin`, `security_engineer`, `release_manager`, `customer_verifier`, and `collector`. Human SSO session actors derive API scopes from role bindings. `GET /v1/role-bindings` lists tenant-scoped bindings. +`POST /v1/role-bindings` assigns a role to a user or collector. Current roles are `tenant_admin`, `security_engineer`, `release_manager`, `customer_verifier`, and `collector`. Human SSO session actors derive API scopes from role bindings and enforce `resource_type`/`resource_id` constraints for product, project, release, customer package, evidence bundle, report, export, read, and write operations where those resources are part of the request. API key and collector API key scopes remain tenant-scoped. `GET /v1/role-bindings` lists tenant-scoped bindings. `POST /v1/sso/providers` records OIDC or SAML provider metadata. `POST /v1/sso/identity-links` links a verified provider subject to an existing user. `POST /v1/sso/sessions` issues an expiring one-time session token response; the token hash is stored server-side and is not returned by list/read paths. `POST /v1/sso/sessions/{id}/revoke` revokes the session. @@ -109,7 +109,7 @@ Scoped exceptions are created with `POST /v1/exceptions` and approved separately `POST /v1/redaction-profiles` creates an explicit package redaction profile. `POST /v1/customer-packages` creates a scoped customer security package manifest with expiry and access auditing. `GET /v1/customer-packages/{id}` reads the manifest and records an access event; raw payload bytes are not returned. -`POST /v1/customer-portal/access` creates an expiring customer portal access token for one package and returns the token once. `POST /v1/customer-portal/package` accepts that token and returns the scoped package manifest without exposing the token or raw tenant evidence. +`POST /v1/customer-portal/access` creates an expiring customer portal access token for one package and returns the token once. `POST /v1/customer-portal/package` accepts that token and returns the scoped package manifest without exposing the token or raw tenant evidence. Failed portal token attempts that match a known token prefix record a safe audit-chain signal without storing or returning the supplied token. `POST /v1/questionnaire-templates` creates tenant-defined customer questionnaire templates with question-to-evidence hints. `POST /v1/questionnaire-packages` generates deterministic evidence-backed responses for a package, product, and release scope. Responses cite linked evidence IDs and include limitations for human review. diff --git a/docs/operations.md b/docs/operations.md index 739b3ee..d243f38 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -49,6 +49,8 @@ set -a; . ./.api.env; set +a go run ./cmd/evydence-worker ``` +The current API performs the implemented parsing/signing/verification work synchronously before enqueueing observability jobs. The worker fails closed for recognized job kinds that do not yet have a deterministic background handler wired, so operators see retry/failure state instead of false successful no-ops. + The API can use filesystem or S3/MinIO-compatible object storage. Object keys are generated by the application under `tenants//...`; do not grant collectors direct bucket write access. Example MinIO configuration with Docker Compose: @@ -97,7 +99,9 @@ Use `GET /v1/admin/instance` with an instance-admin scoped actor for low-detail Legal holds and retention overrides are ledger records. They help explain why evidence should be retained, but they do not configure external database backups, S3 lifecycle rules, or object-lock policies. -Customer portal access tokens are returned once by `POST /v1/customer-portal/access`, expire, and are stored as hashes. Treat them like bearer secrets and do not place them in logs or long-lived documentation. +Customer portal access tokens are returned once by `POST /v1/customer-portal/access`, expire, and are stored as hashes. Treat them like bearer secrets and do not place them in logs or long-lived documentation. Failed token attempts that match a known token prefix are recorded as safe audit-chain signals without storing the token value. + +Human SSO sessions enforce the resource constraints recorded on role bindings. Tenant-wide bindings use `resource_type=tenant` or an empty resource scope; product, project, release, customer package, and evidence bundle bindings only authorize matching resource operations. API keys and collector API keys continue to rely on explicit scopes. Use `POST /v1/merkle-batches` and `POST /v1/transparency-checkpoints` to record signed local checkpoints and optional external anchoring metadata. These support tamper-evidence but do not make public transparency mandatory. @@ -106,3 +110,5 @@ Object-retention policy APIs record and verify retention intent for tenant-prefi ## Production Caveat The API refuses `ENV=production` unless PostgreSQL is configured, a non-default API key pepper is set, and local plaintext signing-key mode is disabled. Signing-provider records are available, but production deployments should use an external signing mode and avoid storing private key material in the ledger snapshot. + +Before release labeling, run `make release-check`. It includes `make finalize`, lint, gosec, govulncheck, race tests, and live PostgreSQL checks when `EVYDENCE_TEST_DATABASE_URL` is set. diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index 011bddd..0179497 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -2,6 +2,8 @@ package httpapi import ( "bytes" + "crypto/rand" + "encoding/hex" "encoding/json" "errors" "io" @@ -20,6 +22,7 @@ import ( ) const maxJSONBody = 2 << 20 +const requestIDHeader = "X-Request-ID" type Server struct { ledger *app.Ledger @@ -44,7 +47,7 @@ func NewServer(ledger *app.Ledger) (*Server, error) { } func (s *Server) Handler() http.Handler { - return secureHeaders(s.mux) + return secureHeaders(requestIDMiddleware(s.mux)) } func (s *Server) OpenAPI() ([]byte, error) { @@ -2453,12 +2456,14 @@ func writeData(w http.ResponseWriter, status int, data any) { func writeProblem(w http.ResponseWriter, r *http.Request, err error) { status := app.StatusCode(err) + requestID := requestIDFromRequest(r) problem := httpx.Problem{ Type: "https://evydence.local/problems/" + strings.ToLower(strings.ReplaceAll(app.ProblemCode(err), "_", "-")), Title: http.StatusText(status), Detail: app.SafeErrorDetail(err), Ext: map[string]any{ - "code": app.ProblemCode(err), + "code": app.ProblemCode(err), + "request_id": requestID, }, } if r != nil { @@ -2467,6 +2472,50 @@ func writeProblem(w http.ResponseWriter, r *http.Request, err error) { httpx.WriteProblem(w, status, problem) } +func requestIDMiddleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + requestID := strings.TrimSpace(r.Header.Get(requestIDHeader)) + if !safeRequestID(requestID) { + requestID = newRequestID() + } + r.Header.Set(requestIDHeader, requestID) + w.Header().Set(requestIDHeader, requestID) + next.ServeHTTP(w, r) + }) +} + +func requestIDFromRequest(r *http.Request) string { + if r == nil { + return newRequestID() + } + requestID := strings.TrimSpace(r.Header.Get(requestIDHeader)) + if safeRequestID(requestID) { + return requestID + } + return newRequestID() +} + +func newRequestID() string { + var buf [16]byte + if _, err := rand.Read(buf[:]); err != nil { + return "req_unavailable" + } + return "req_" + hex.EncodeToString(buf[:]) +} + +func safeRequestID(value string) bool { + if len(value) < 3 || len(value) > 128 { + return false + } + for _, r := range value { + if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9') || r == '-' || r == '_' || r == '.' || r == ':' { + continue + } + return false + } + return true +} + func secureHeaders(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("X-Content-Type-Options", "nosniff") diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 042785a..6529432 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -92,6 +92,7 @@ func TestUnknownJSONFieldReturnsProblem(t *testing.T) { req.Header.Set("Authorization", "Bearer "+secret) req.Header.Set("Idempotency-Key", "unknown-field") req.Header.Set("Content-Type", "application/json") + req.Header.Set("X-Request-ID", "req-test-validation") server.Handler().ServeHTTP(rec, req) if rec.Code != http.StatusBadRequest { t.Fatalf("status = %d, want 400 body=%s", rec.Code, rec.Body.String()) @@ -99,6 +100,9 @@ func TestUnknownJSONFieldReturnsProblem(t *testing.T) { if !strings.Contains(rec.Body.String(), `"code":"VALIDATION_FAILED"`) { t.Fatalf("problem code missing: %s", rec.Body.String()) } + if rec.Header().Get("X-Request-ID") != "req-test-validation" || !strings.Contains(rec.Body.String(), `"request_id":"req-test-validation"`) { + t.Fatalf("request id missing from problem/header: header=%q body=%s", rec.Header().Get("X-Request-ID"), rec.Body.String()) + } } func TestCrossTenantEvidenceReadDenied(t *testing.T) { diff --git a/internal/app/enterprise.go b/internal/app/enterprise.go index 36c6c7f..ce6680d 100644 --- a/internal/app/enterprise.go +++ b/internal/app/enterprise.go @@ -197,6 +197,9 @@ func (l *Ledger) CreateRoleBinding(ctx context.Context, actor domain.Actor, in C if err := l.ensureRoleSubjectLocked(actor.TenantID, in.SubjectType, in.SubjectID); err != nil { return domain.RoleBinding{}, err } + if err := l.ensureRoleResourceLocked(actor.TenantID, in.ResourceType, in.ResourceID); err != nil { + return domain.RoleBinding{}, err + } binding := domain.RoleBinding{ID: newID("rbac"), TenantID: actor.TenantID, SubjectType: in.SubjectType, SubjectID: in.SubjectID, Role: in.Role, ResourceType: in.ResourceType, ResourceID: in.ResourceID, SchemaVersion: domain.RoleBindingSchemaVersion, CreatedAt: l.now()} l.roleBindings[binding.ID] = binding _, _ = l.appendChainLocked(actor.TenantID, "role_binding.created", "role_binding", binding.ID, actorType(actor), actorID(actor), "", "") @@ -457,11 +460,16 @@ func (l *Ledger) AccessCustomerPortalPackage(ctx context.Context, token string) if token == "" { return domain.CustomerSecurityPackage{}, ErrUnauthorized } + prefix := secretPrefix(token) hash := l.hashSecret(token) l.mu.Lock() defer l.mu.Unlock() for id, access := range l.portalAccess { if access.Hash != hash || access.RevokedAt != nil || !access.ExpiresAt.After(l.now()) { + if access.Prefix == prefix { + _, _ = l.appendChainLocked(access.TenantID, "customer_portal_package.access_failed", "customer_portal_access", access.ID, "customer_portal", "unverified", "", "") + _ = l.persistLocked(ctx) + } continue } pkg, ok := l.customerPackages[access.PackageID] @@ -646,6 +654,51 @@ func (l *Ledger) ensureRetentionScopeLocked(tenantID, scopeType, scopeID string) return nil } +func (l *Ledger) ensureRoleResourceLocked(tenantID, resourceType, resourceID string) error { + switch resourceType { + case "": + if resourceID != "" { + return ErrValidation + } + case "tenant": + if resourceID == "" { + return nil + } + tenant, ok := l.tenants[resourceID] + if !ok || tenant.ID != tenantID { + return ErrNotFound + } + case "product": + product, ok := l.products[resourceID] + if resourceID == "" || !ok || product.TenantID != tenantID { + return ErrNotFound + } + case "project": + project, ok := l.projects[resourceID] + if resourceID == "" || !ok || project.TenantID != tenantID { + return ErrNotFound + } + case "release": + release, ok := l.releases[resourceID] + if resourceID == "" || !ok || release.TenantID != tenantID { + return ErrNotFound + } + case "customer_security_package": + pkg, ok := l.customerPackages[resourceID] + if resourceID == "" || !ok || pkg.TenantID != tenantID { + return ErrNotFound + } + case "evidence_bundle": + bundle, ok := l.evidenceBundles[resourceID] + if resourceID == "" || !ok || bundle.TenantID != tenantID { + return ErrNotFound + } + default: + return ErrValidation + } + return nil +} + func validRoleSubject(value string) bool { return value == "user" || value == "collector" } @@ -659,13 +712,30 @@ func validRole(value string) bool { } } -func (l *Ledger) scopesForUserLocked(userID string) []string { - scopes := map[string]struct{}{} +func (l *Ledger) resourceGrantsForUserLocked(userID string) []domain.ResourceGrant { + grants := []domain.ResourceGrant{} for _, binding := range l.roleBindings { if binding.SubjectType != "user" || binding.SubjectID != userID { continue } - for _, scope := range scopesForRole(binding.Role) { + scopes := scopesForRole(binding.Role) + if len(scopes) == 0 { + continue + } + grants = append(grants, domain.ResourceGrant{ + Role: binding.Role, + ResourceType: binding.ResourceType, + ResourceID: binding.ResourceID, + Scopes: scopes, + }) + } + return grants +} + +func scopesFromResourceGrants(grants []domain.ResourceGrant) []string { + scopes := map[string]struct{}{} + for _, grant := range grants { + for _, scope := range grant.Scopes { scopes[scope] = struct{}{} } } @@ -676,6 +746,136 @@ func (l *Ledger) scopesForUserLocked(userID string) []string { return sortedStrings(out) } +type resourceRefs struct { + ProductID string + ProjectID string + ReleaseID string + CustomerPackageID string + EvidenceBundleID string +} + +func refsForEvidence(item domain.EvidenceItem) resourceRefs { + return resourceRefs{ProductID: item.ProductID, ProjectID: item.ProjectID, ReleaseID: item.ReleaseID} +} + +func (l *Ledger) authorizeResourceLocked(actor domain.Actor, scope string, refs resourceRefs) error { + if l.resourceAllowedLocked(actor, scope, refs) { + return nil + } + return ErrForbidden +} + +func (l *Ledger) resourceAllowedLocked(actor domain.Actor, scope string, refs resourceRefs) bool { + if !humanSessionActor(actor) { + return true + } + for _, grant := range actor.ResourceGrants { + if !grantHasScope(grant, scope) { + continue + } + if l.grantCoversResourceLocked(actor.TenantID, grant, refs) { + return true + } + } + return false +} + +func humanSessionActor(actor domain.Actor) bool { + return actor.UserID != "" && actor.KeyID == "" && actor.CollectorID == "" +} + +func grantHasScope(grant domain.ResourceGrant, scope string) bool { + for _, got := range grant.Scopes { + if got == "*" || got == scope || got == ScopeAdmin { + return true + } + } + return false +} + +func (l *Ledger) grantCoversResourceLocked(tenantID string, grant domain.ResourceGrant, refs resourceRefs) bool { + switch grant.ResourceType { + case "", "tenant": + return grant.ResourceID == "" || grant.ResourceID == tenantID + case "product": + return grant.ResourceID != "" && l.productCoversRefsLocked(tenantID, grant.ResourceID, refs) + case "project": + return grant.ResourceID != "" && l.projectCoversRefsLocked(tenantID, grant.ResourceID, refs) + case "release": + return grant.ResourceID != "" && l.releaseCoversRefsLocked(tenantID, grant.ResourceID, refs) + case "customer_security_package": + return refs.CustomerPackageID != "" && refs.CustomerPackageID == grant.ResourceID + case "evidence_bundle": + return refs.EvidenceBundleID != "" && refs.EvidenceBundleID == grant.ResourceID + default: + return false + } +} + +func (l *Ledger) productCoversRefsLocked(tenantID, productID string, refs resourceRefs) bool { + if refs == (resourceRefs{}) { + return false + } + if refs.ProductID != "" && refs.ProductID != productID { + return false + } + if refs.ProjectID != "" { + project, ok := l.projects[refs.ProjectID] + if !ok || project.TenantID != tenantID || project.ProductID != productID { + return false + } + } + if refs.ReleaseID != "" { + release, ok := l.releases[refs.ReleaseID] + if !ok || release.TenantID != tenantID || release.ProductID != productID { + return false + } + } + if refs.CustomerPackageID != "" { + pkg, ok := l.customerPackages[refs.CustomerPackageID] + if !ok || pkg.TenantID != tenantID || pkg.ProductID != productID { + return false + } + } + if refs.EvidenceBundleID != "" { + bundle, ok := l.evidenceBundles[refs.EvidenceBundleID] + if !ok || bundle.TenantID != tenantID { + return false + } + if bundle.ReleaseID != "" { + release, ok := l.releases[bundle.ReleaseID] + if !ok || release.TenantID != tenantID || release.ProductID != productID { + return false + } + } + } + return true +} + +func (l *Ledger) projectCoversRefsLocked(tenantID, projectID string, refs resourceRefs) bool { + if refs.ProjectID != "" { + project, ok := l.projects[refs.ProjectID] + return ok && project.TenantID == tenantID && project.ID == projectID + } + return false +} + +func (l *Ledger) releaseCoversRefsLocked(tenantID, releaseID string, refs resourceRefs) bool { + if refs.ReleaseID != "" { + release, ok := l.releases[refs.ReleaseID] + return ok && release.TenantID == tenantID && release.ID == releaseID + } + if refs.CustomerPackageID != "" { + pkg, ok := l.customerPackages[refs.CustomerPackageID] + return ok && pkg.TenantID == tenantID && pkg.ReleaseID == releaseID + } + if refs.EvidenceBundleID != "" { + bundle, ok := l.evidenceBundles[refs.EvidenceBundleID] + return ok && bundle.TenantID == tenantID && bundle.ReleaseID == releaseID + } + return false +} + func scopesForRole(role string) []string { switch role { case "tenant_admin": diff --git a/internal/app/enterprise_test.go b/internal/app/enterprise_test.go index b79173c..6f11490 100644 --- a/internal/app/enterprise_test.go +++ b/internal/app/enterprise_test.go @@ -107,6 +107,29 @@ func TestCustomerPortalRetentionQuestionnairesAndCommercialCollectors(t *testing if portalPkg.ID != pkg.ID { t.Fatalf("portal package id = %s want %s", portalPkg.ID, pkg.ID) } + badToken := token[:len(token)-1] + "x" + if badToken == token { + badToken = token[:len(token)-1] + "y" + } + if _, err := ledger.AccessCustomerPortalPackage(ctx, badToken); !errors.Is(err, ErrUnauthorized) { + t.Fatalf("bad portal token err=%v, want unauthorized", err) + } + entries, err := ledger.ListAuditLog(ctx, actor, AuditLogFilter{SubjectType: "customer_portal_access", SubjectID: access.ID, Limit: 10}) + if err != nil { + t.Fatalf("portal audit log: %v", err) + } + foundFailedAccess := false + for _, entry := range entries { + if entry.EntryType == "customer_portal_package.access_failed" && entry.ActorID == "unverified" { + foundFailedAccess = true + } + if entry.ActorID == badToken || entry.PayloadHash == badToken { + t.Fatalf("portal audit leaked token: %#v", entry) + } + } + if !foundFailedAccess { + t.Fatalf("missing failed portal access audit entry: %#v", entries) + } if _, err := ledger.CreateLegalHold(ctx, actor, CreateLegalHoldInput{ScopeType: "release", ScopeID: release.ID, Reason: "customer dispute", Owner: "legal"}); err != nil { t.Fatalf("legal hold: %v", err) } @@ -150,3 +173,124 @@ func TestCustomerPortalRetentionQuestionnairesAndCommercialCollectors(t *testing t.Fatalf("cross tenant portal err=%v, want not found", err) } } + +func TestHumanSSOSessionRoleBindingsAreResourceScoped(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + _, _, secret, err := ledger.BootstrapTenant(ctx, "Tenant", "admin", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap: %v", err) + } + admin, err := ledger.Authenticate(ctx, secret) + if err != nil { + t.Fatalf("auth: %v", err) + } + productA, err := ledger.CreateProduct(ctx, admin, "A", "a") + if err != nil { + t.Fatalf("product A: %v", err) + } + releaseA, err := ledger.CreateRelease(ctx, admin, productA.ID, "1") + if err != nil { + t.Fatalf("release A: %v", err) + } + productB, err := ledger.CreateProduct(ctx, admin, "B", "b") + if err != nil { + t.Fatalf("product B: %v", err) + } + releaseB, err := ledger.CreateRelease(ctx, admin, productB.ID, "1") + if err != nil { + t.Fatalf("release B: %v", err) + } + org, err := ledger.CreateOrganization(ctx, admin, CreateOrganizationInput{Name: "Example", Slug: "example"}) + if err != nil { + t.Fatalf("org: %v", err) + } + user, err := ledger.CreateUser(ctx, admin, CreateUserInput{OrganizationID: org.ID, Email: "release@example.test", DisplayName: "Release"}) + if err != nil { + t.Fatalf("user: %v", err) + } + if _, err := ledger.CreateRoleBinding(ctx, admin, CreateRoleBindingInput{SubjectType: "user", SubjectID: user.ID, Role: "release_manager", ResourceType: "product", ResourceID: productA.ID}); err != nil { + t.Fatalf("role binding: %v", err) + } + provider, err := ledger.CreateSSOProvider(ctx, admin, CreateSSOProviderInput{Name: "OIDC", Type: "oidc", Issuer: "https://idp.example.test", ClientID: "client"}) + if err != nil { + t.Fatalf("provider: %v", err) + } + session, sessionSecret, err := ledger.CreateSSOSession(ctx, admin, CreateSSOSessionInput{UserID: user.ID, ProviderID: provider.ID, ExpiresAt: fixedNow().Add(time.Hour)}) + if err != nil { + t.Fatalf("session: %v", err) + } + scoped, err := ledger.Authenticate(ctx, sessionSecret) + if err != nil { + t.Fatalf("session auth: %v", err) + } + if scoped.UserID != user.ID || len(scoped.ResourceGrants) != 1 || scoped.ResourceGrants[0].ResourceID != productA.ID { + t.Fatalf("scoped actor = %#v session=%#v", scoped, session) + } + products, err := ledger.ListProducts(ctx, scoped) + if err != nil { + t.Fatalf("list products: %v", err) + } + if len(products) != 1 || products[0].ID != productA.ID { + t.Fatalf("scoped products = %#v", products) + } + if _, err := ledger.GetRelease(ctx, scoped, releaseA.ID); err != nil { + t.Fatalf("get allowed release: %v", err) + } + if _, err := ledger.GetRelease(ctx, scoped, releaseB.ID); !errors.Is(err, ErrForbidden) { + t.Fatalf("get foreign product release err=%v, want forbidden", err) + } + if _, err := ledger.CreateRelease(ctx, scoped, productA.ID, "2"); err != nil { + t.Fatalf("create scoped release: %v", err) + } + if _, err := ledger.CreateRelease(ctx, scoped, productB.ID, "2"); !errors.Is(err, ErrForbidden) { + t.Fatalf("create foreign product release err=%v, want forbidden", err) + } + if _, err := ledger.CreateEvidence(ctx, scoped, CreateEvidenceInput{ProductID: productA.ID, ReleaseID: releaseA.ID, Type: "build", Title: "Build", PayloadHash: sampleDigest("allowed")}); err != nil { + t.Fatalf("create scoped evidence: %v", err) + } + if _, err := ledger.CreateEvidence(ctx, scoped, CreateEvidenceInput{ProductID: productB.ID, ReleaseID: releaseB.ID, Type: "build", Title: "Build", PayloadHash: sampleDigest("denied")}); !errors.Is(err, ErrForbidden) { + t.Fatalf("create foreign evidence err=%v, want forbidden", err) + } + if _, err := ledger.MissingEvidenceReport(ctx, scoped, releaseB.ID); !errors.Is(err, ErrForbidden) { + t.Fatalf("foreign report err=%v, want forbidden", err) + } + + profile, err := ledger.CreateRedactionProfile(ctx, admin, CreateRedactionProfileInput{Name: "customer", AllowedTypes: []string{"build"}}) + if err != nil { + t.Fatalf("profile: %v", err) + } + pkgA, err := ledger.CreateCustomerSecurityPackage(ctx, admin, CreateCustomerPackageInput{ProductID: productA.ID, ReleaseID: releaseA.ID, RedactionProfileID: profile.ID, Title: "A package", ExpiresAt: fixedNow().Add(time.Hour)}) + if err != nil { + t.Fatalf("package A: %v", err) + } + pkgB, err := ledger.CreateCustomerSecurityPackage(ctx, admin, CreateCustomerPackageInput{ProductID: productB.ID, ReleaseID: releaseB.ID, RedactionProfileID: profile.ID, Title: "B package", ExpiresAt: fixedNow().Add(time.Hour)}) + if err != nil { + t.Fatalf("package B: %v", err) + } + verifier, err := ledger.CreateUser(ctx, admin, CreateUserInput{OrganizationID: org.ID, Email: "verifier@example.test", DisplayName: "Verifier"}) + if err != nil { + t.Fatalf("verifier: %v", err) + } + if _, err := ledger.CreateRoleBinding(ctx, admin, CreateRoleBindingInput{SubjectType: "user", SubjectID: verifier.ID, Role: "customer_verifier", ResourceType: "customer_security_package", ResourceID: pkgA.ID}); err != nil { + t.Fatalf("verifier role: %v", err) + } + verifierSession, verifierSecret, err := ledger.CreateSSOSession(ctx, admin, CreateSSOSessionInput{UserID: verifier.ID, ProviderID: provider.ID, ExpiresAt: fixedNow().Add(time.Hour)}) + if err != nil { + t.Fatalf("verifier session: %v", err) + } + _ = verifierSession + verifierActor, err := ledger.Authenticate(ctx, verifierSecret) + if err != nil { + t.Fatalf("verifier auth: %v", err) + } + if _, err := ledger.AccessCustomerSecurityPackage(ctx, verifierActor, pkgA.ID); err != nil { + t.Fatalf("access scoped package: %v", err) + } + if _, err := ledger.AccessCustomerSecurityPackage(ctx, verifierActor, pkgB.ID); !errors.Is(err, ErrForbidden) { + t.Fatalf("access foreign package err=%v, want forbidden", err) + } + if _, err := ledger.SecurityReviewPackageReport(ctx, verifierActor, pkgB.ID); !errors.Is(err, ErrForbidden) { + t.Fatalf("foreign package report err=%v, want forbidden", err) + } +} diff --git a/internal/app/governance_packages.go b/internal/app/governance_packages.go index 692bc6a..ba0f01e 100644 --- a/internal/app/governance_packages.go +++ b/internal/app/governance_packages.go @@ -236,6 +236,9 @@ func (l *Ledger) CreateCustomerSecurityPackage(ctx context.Context, actor domain if err := l.ensureScopeLocked(actor.TenantID, in.ProductID, "", in.ReleaseID); err != nil { return domain.CustomerSecurityPackage{}, err } + if err := l.authorizeResourceLocked(actor, ScopePackageWrite, resourceRefs{ProductID: in.ProductID, ReleaseID: in.ReleaseID}); err != nil { + return domain.CustomerSecurityPackage{}, err + } profile, ok := l.redactions[in.RedactionProfileID] if !ok || profile.TenantID != actor.TenantID { return domain.CustomerSecurityPackage{}, ErrNotFound @@ -276,6 +279,9 @@ func (l *Ledger) AccessCustomerSecurityPackage(ctx context.Context, actor domain if !ok || pkg.TenantID != actor.TenantID { return domain.CustomerSecurityPackage{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopePackageRead, resourceRefs{ProductID: pkg.ProductID, ReleaseID: pkg.ReleaseID, CustomerPackageID: pkg.ID}); err != nil { + return domain.CustomerSecurityPackage{}, err + } if !pkg.ExpiresAt.After(l.now()) { return domain.CustomerSecurityPackage{}, ErrConflict } @@ -442,8 +448,19 @@ func (l *Ledger) ExportEvidenceBundle(ctx context.Context, actor domain.Actor, r defer l.mu.Unlock() ids := []string{} if len(evidenceIDs) == 0 { + if releaseID != "" { + release, ok := l.releases[strings.TrimSpace(releaseID)] + if !ok || release.TenantID != actor.TenantID { + return domain.EvidenceBundle{}, ErrNotFound + } + if err := l.authorizeResourceLocked(actor, ScopeBundleRead, resourceRefs{ReleaseID: release.ID}); err != nil { + return domain.EvidenceBundle{}, err + } + } else if err := l.authorizeResourceLocked(actor, ScopeBundleRead, resourceRefs{}); err != nil { + return domain.EvidenceBundle{}, err + } for _, item := range l.evidence { - if item.TenantID == actor.TenantID && (releaseID == "" || item.ReleaseID == releaseID) { + if item.TenantID == actor.TenantID && (releaseID == "" || item.ReleaseID == releaseID) && l.resourceAllowedLocked(actor, ScopeBundleRead, refsForEvidence(item)) { ids = append(ids, item.ID) } } @@ -453,6 +470,9 @@ func (l *Ledger) ExportEvidenceBundle(ctx context.Context, actor domain.Actor, r if !ok || item.TenantID != actor.TenantID { return domain.EvidenceBundle{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeBundleRead, refsForEvidence(item)); err != nil { + return domain.EvidenceBundle{}, err + } ids = append(ids, item.ID) } } diff --git a/internal/app/ledger.go b/internal/app/ledger.go index 949f3ff..5409c02 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -349,13 +349,14 @@ func (l *Ledger) Authenticate(ctx context.Context, secret string) (domain.Actor, if !ok || user.TenantID != session.TenantID || user.Status != "active" { return domain.Actor{}, ErrUnauthorized } - scopes := l.scopesForUserLocked(user.ID) + grants := l.resourceGrantsForUserLocked(user.ID) + scopes := scopesFromResourceGrants(grants) if len(scopes) == 0 { return domain.Actor{}, ErrForbidden } l.ssoSessions[id] = session _ = l.persistLocked(ctx) - return domain.Actor{TenantID: user.TenantID, UserID: user.ID, Name: user.Email, Scopes: scopes}, nil + return domain.Actor{TenantID: user.TenantID, UserID: user.ID, Name: user.Email, Scopes: scopes, ResourceGrants: grants}, nil } return domain.Actor{}, ErrUnauthorized } @@ -413,6 +414,9 @@ func (l *Ledger) CreateProduct(ctx context.Context, actor domain.Actor, name, sl } l.mu.Lock() defer l.mu.Unlock() + if err := l.authorizeResourceLocked(actor, ScopeProductWrite, resourceRefs{}); err != nil { + return domain.Product{}, err + } for _, existing := range l.products { if existing.TenantID == actor.TenantID && existing.Slug == slug { return domain.Product{}, ErrConflict @@ -438,7 +442,7 @@ func (l *Ledger) ListProducts(ctx context.Context, actor domain.Actor) ([]domain defer l.mu.Unlock() out := []domain.Product{} for _, product := range l.products { - if product.TenantID == actor.TenantID { + if product.TenantID == actor.TenantID && l.resourceAllowedLocked(actor, ScopeProductRead, resourceRefs{ProductID: product.ID}) { out = append(out, product) } } @@ -463,6 +467,9 @@ func (l *Ledger) CreateProject(ctx context.Context, actor domain.Actor, productI if !ok || product.TenantID != actor.TenantID { return domain.Project{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeProjectWrite, resourceRefs{ProductID: product.ID}); err != nil { + return domain.Project{}, err + } project := domain.Project{ID: newID("proj"), TenantID: actor.TenantID, ProductID: productID, Name: name, CreatedAt: l.now()} l.projects[project.ID] = project _, _ = l.appendChainLocked(actor.TenantID, "project.created", "project", project.ID, "api_key", actor.KeyID, "", "") @@ -489,6 +496,9 @@ func (l *Ledger) CreateRelease(ctx context.Context, actor domain.Actor, productI if !ok || product.TenantID != actor.TenantID { return domain.Release{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeReleaseWrite, resourceRefs{ProductID: product.ID}); err != nil { + return domain.Release{}, err + } for _, existing := range l.releases { if existing.TenantID == actor.TenantID && existing.ProductID == productID && existing.Version == version { return domain.Release{}, ErrConflict @@ -516,6 +526,9 @@ func (l *Ledger) GetRelease(ctx context.Context, actor domain.Actor, releaseID s if !ok || release.TenantID != actor.TenantID { return domain.Release{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeReleaseRead, resourceRefs{ReleaseID: release.ID}); err != nil { + return domain.Release{}, err + } return release, nil } @@ -532,6 +545,9 @@ func (l *Ledger) FreezeRelease(ctx context.Context, actor domain.Actor, releaseI if !ok || release.TenantID != actor.TenantID { return domain.Release{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeReleaseWrite, resourceRefs{ReleaseID: release.ID}); err != nil { + return domain.Release{}, err + } if release.State != "draft" { return domain.Release{}, ErrConflict } @@ -559,6 +575,9 @@ func (l *Ledger) ApproveRelease(ctx context.Context, actor domain.Actor, release if !ok || release.TenantID != actor.TenantID { return domain.Release{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeReleaseWrite, resourceRefs{ReleaseID: release.ID}); err != nil { + return domain.Release{}, err + } if release.State != "frozen" { return domain.Release{}, ErrConflict } @@ -647,6 +666,9 @@ func (l *Ledger) CreateEvidence(ctx context.Context, actor domain.Actor, in Crea if err := l.ensureScopeLocked(actor.TenantID, in.ProductID, in.ProjectID, in.ReleaseID); err != nil { return domain.EvidenceItem{}, err } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceWrite, resourceRefs{ProductID: in.ProductID, ProjectID: in.ProjectID, ReleaseID: in.ReleaseID}); err != nil { + return domain.EvidenceItem{}, err + } now := l.now() item := domain.EvidenceItem{ ID: newID("ev"), @@ -710,6 +732,9 @@ func (l *Ledger) GetEvidence(ctx context.Context, actor domain.Actor, id string) if !ok || item.TenantID != actor.TenantID { return domain.EvidenceItem{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceRead, refsForEvidence(item)); err != nil { + return domain.EvidenceItem{}, err + } return item, nil } @@ -733,6 +758,9 @@ func (l *Ledger) ListEvidence(ctx context.Context, actor domain.Actor, releaseID if typ != "" && item.Type != typ { continue } + if !l.resourceAllowedLocked(actor, ScopeEvidenceRead, refsForEvidence(item)) { + continue + } out = append(out, item) } sort.Slice(out, func(i, j int) bool { return out[i].ID < out[j].ID }) @@ -756,6 +784,12 @@ func (l *Ledger) SupersedeEvidence(ctx context.Context, actor domain.Actor, id, if !ok || !rok || item.TenantID != actor.TenantID || replacement.TenantID != actor.TenantID { return domain.EvidenceItem{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceWrite, refsForEvidence(item)); err != nil { + return domain.EvidenceItem{}, err + } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceWrite, refsForEvidence(replacement)); err != nil { + return domain.EvidenceItem{}, err + } if item.SupersededBy != "" { return domain.EvidenceItem{}, ErrConflict } @@ -787,18 +821,27 @@ func (l *Ledger) LinkEvidence(ctx context.Context, actor domain.Actor, id, targe if !ok || item.TenantID != actor.TenantID { return domain.EvidenceItem{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceWrite, refsForEvidence(item)); err != nil { + return domain.EvidenceItem{}, err + } switch targetType { case "release": rel, ok := l.releases[targetID] if !ok || rel.TenantID != actor.TenantID { return domain.EvidenceItem{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceWrite, resourceRefs{ReleaseID: rel.ID}); err != nil { + return domain.EvidenceItem{}, err + } item.ReleaseID = targetID case "product": prod, ok := l.products[targetID] if !ok || prod.TenantID != actor.TenantID { return domain.EvidenceItem{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceWrite, resourceRefs{ProductID: prod.ID}); err != nil { + return domain.EvidenceItem{}, err + } item.ProductID = targetID default: return domain.EvidenceItem{}, ErrValidation @@ -1007,6 +1050,9 @@ func (l *Ledger) EvaluateRelease(ctx context.Context, actor domain.Actor, releas if !ok || release.TenantID != actor.TenantID { return domain.PolicyEvaluation{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeVerifyRead, resourceRefs{ReleaseID: release.ID}); err != nil { + return domain.PolicyEvaluation{}, err + } checks := []domain.PolicyCheck{ l.checkReleaseHasEvidenceLocked(actor.TenantID, release.ID, "sbom", "release_requires_sbom", "high"), l.checkReleaseHasEvidenceLocked(actor.TenantID, release.ID, "vulnerability_scan", "release_requires_vulnerability_scan", "high"), @@ -1045,6 +1091,9 @@ func (l *Ledger) CreateReleaseBundle(ctx context.Context, actor domain.Actor, re if !ok || release.TenantID != actor.TenantID { return domain.ReleaseBundle{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeBundleWrite, resourceRefs{ReleaseID: release.ID}); err != nil { + return domain.ReleaseBundle{}, err + } evidenceIDs := []string{} for _, item := range l.evidence { if item.TenantID == actor.TenantID && item.ReleaseID == release.ID { @@ -1111,6 +1160,9 @@ func (l *Ledger) GetReleaseBundle(ctx context.Context, actor domain.Actor, id st if !ok || bundle.TenantID != actor.TenantID { return domain.ReleaseBundle{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeBundleRead, resourceRefs{ReleaseID: bundle.ReleaseID}); err != nil { + return domain.ReleaseBundle{}, err + } return bundle, nil } @@ -1127,6 +1179,9 @@ func (l *Ledger) GetSBOM(ctx context.Context, actor domain.Actor, id string) (do if !ok || sbom.TenantID != actor.TenantID { return domain.SBOM{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceRead, resourceRefs{ReleaseID: sbom.ReleaseID}); err != nil { + return domain.SBOM{}, err + } return sbom, nil } @@ -1143,6 +1198,9 @@ func (l *Ledger) GetVulnerabilityScan(ctx context.Context, actor domain.Actor, i if !ok || scan.TenantID != actor.TenantID { return domain.VulnerabilityScan{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceRead, resourceRefs{ReleaseID: scan.ReleaseID}); err != nil { + return domain.VulnerabilityScan{}, err + } return scan, nil } @@ -1159,6 +1217,9 @@ func (l *Ledger) GetOpenAPIContract(ctx context.Context, actor domain.Actor, id if !ok || contract.TenantID != actor.TenantID { return domain.OpenAPIContract{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceRead, resourceRefs{ProductID: contract.ProductID, ReleaseID: contract.ReleaseID}); err != nil { + return domain.OpenAPIContract{}, err + } return contract, nil } @@ -1175,12 +1236,18 @@ func (l *Ledger) VerifySubject(ctx context.Context, actor domain.Actor, subjectT result := "passed" switch strings.TrimSpace(subjectType) { case "audit_chain": + if err := l.authorizeResourceLocked(actor, ScopeVerifyRead, resourceRefs{}); err != nil { + return domain.VerificationResult{}, err + } checks = l.verifyChainLocked(actor.TenantID) case "evidence_item": item, ok := l.evidence[strings.TrimSpace(subjectID)] if !ok || item.TenantID != actor.TenantID { return domain.VerificationResult{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeVerifyRead, refsForEvidence(item)); err != nil { + return domain.VerificationResult{}, err + } hash, err := canonicalHash(item) if err != nil || hash != item.CanonicalHash { result = "failed" @@ -1193,6 +1260,9 @@ func (l *Ledger) VerifySubject(ctx context.Context, actor domain.Actor, subjectT if !ok || bundle.TenantID != actor.TenantID { return domain.VerificationResult{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeVerifyRead, resourceRefs{ReleaseID: bundle.ReleaseID}); err != nil { + return domain.VerificationResult{}, err + } hash, err := canonicalAnyHash(bundle.Manifest) if err != nil || hash != bundle.ManifestHash { result = "failed" diff --git a/internal/domain/domain.go b/internal/domain/domain.go index b1d9193..e589dc6 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -68,12 +68,13 @@ const ( ) type Actor struct { - TenantID string - KeyID string - UserID string - Name string - Scopes []string - CollectorID string + TenantID string + KeyID string + UserID string + Name string + Scopes []string + CollectorID string + ResourceGrants []ResourceGrant } func (a Actor) HasScope(scope string) bool { @@ -85,6 +86,13 @@ func (a Actor) HasScope(scope string) bool { return false } +type ResourceGrant struct { + Role string + ResourceType string + ResourceID string + Scopes []string +} + type Tenant struct { ID string `json:"id"` Name string `json:"name"` From 2ab05350eaeb290135ae8a6704348507ccc6a433 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sat, 23 May 2026 10:22:47 +0300 Subject: [PATCH 002/287] fix(security): harden workflow scoped grants --- docs/api.md | 2 +- internal/app/authz_inventory_test.go | 78 ++++++++ internal/app/builds.go | 10 + internal/app/controls.go | 57 ++++++ internal/app/enterprise.go | 172 +++++++++++++++++- internal/app/enterprise_test.go | 170 +++++++++++++++++ internal/app/implementation_increments.go | 65 +++++++ internal/app/integrity_runtime.go | 8 +- internal/app/ledger.go | 40 ++++ internal/app/risk_workflows.go | 103 +++++++++++ internal/app/vex.go | 19 ++ internal/domain/domain.go | 25 +-- ...0_customer_portal_access_counters.down.sql | 4 + ...800_customer_portal_access_counters.up.sql | 4 + 14 files changed, 739 insertions(+), 18 deletions(-) create mode 100644 internal/app/authz_inventory_test.go create mode 100644 migrations/20260528000800_customer_portal_access_counters.down.sql create mode 100644 migrations/20260528000800_customer_portal_access_counters.up.sql diff --git a/docs/api.md b/docs/api.md index 97d1f99..78bd1fd 100644 --- a/docs/api.md +++ b/docs/api.md @@ -21,7 +21,7 @@ The generated OpenAPI document is committed at `openapi.yaml` and served at `/v1 `POST /v1/organizations` creates a tenant-scoped organization. `POST /v1/users` creates a human user with normalized email, and `POST /v1/users/{id}/deactivate` records a deactivation transition. -`POST /v1/role-bindings` assigns a role to a user or collector. Current roles are `tenant_admin`, `security_engineer`, `release_manager`, `customer_verifier`, and `collector`. Human SSO session actors derive API scopes from role bindings and enforce `resource_type`/`resource_id` constraints for product, project, release, customer package, evidence bundle, report, export, read, and write operations where those resources are part of the request. API key and collector API key scopes remain tenant-scoped. `GET /v1/role-bindings` lists tenant-scoped bindings. +`POST /v1/role-bindings` assigns a role to a user or collector. Current roles are `tenant_admin`, `security_engineer`, `release_manager`, `customer_verifier`, and `collector`. Human SSO session actors derive API scopes from role bindings and enforce `resource_type`/`resource_id` constraints for product, project, release, customer package, evidence bundle, build, control evidence, source, deployment, incident, security scan, report, export, read, and write operations where those resources are part of the request. API key and collector API key scopes remain tenant-scoped. `GET /v1/role-bindings` lists tenant-scoped bindings. `POST /v1/sso/providers` records OIDC or SAML provider metadata. `POST /v1/sso/identity-links` links a verified provider subject to an existing user. `POST /v1/sso/sessions` issues an expiring one-time session token response; the token hash is stored server-side and is not returned by list/read paths. `POST /v1/sso/sessions/{id}/revoke` revokes the session. diff --git a/internal/app/authz_inventory_test.go b/internal/app/authz_inventory_test.go new file mode 100644 index 0000000..af465be --- /dev/null +++ b/internal/app/authz_inventory_test.go @@ -0,0 +1,78 @@ +package app + +import ( + "os" + "strings" + "testing" +) + +func TestResourceScopedAuthorizationCoverageInventory(t *testing.T) { + files := map[string][]string{ + "builds.go": { + "CreateBuildRun", + "GetBuildRun", + "UploadBuildAttestation", + }, + "controls.go": { + "LinkControlEvidence", + "ListControlEvidence", + "ControlCoverageReport", + "CRAReadinessReport", + }, + "risk_workflows.go": { + "CreateIncident", + "RecordIncidentTimelineEvent", + "CreateRemediationTask", + "IncidentReport", + "uploadSecurityScan", + "UploadManualSecurityDocument", + "VulnerabilityPostureReport", + "EvaluateCustomPolicy", + }, + "implementation_increments.go": { + "SearchEvidence", + "CreateReleaseCandidate", + "GetReleaseCandidate", + "ListReleaseCandidates", + "UpdateReleaseCandidateState", + "ListSourceRepositories", + "CreateSourceRepository", + "RecordSourceCommit", + "UpsertSourceBranch", + "RecordPullRequest", + "ListDeploymentEnvironments", + "CreateDeploymentEnvironment", + "RecordDeployment", + "GetDeployment", + "ListDeployments", + }, + } + for file, funcs := range files { + bodyBytes, err := os.ReadFile(file) + if err != nil { + t.Fatalf("read %s: %v", file, err) + } + body := string(bodyBytes) + for _, name := range funcs { + fn := functionBody(t, body, name) + if !strings.Contains(fn, "authorizeResourceLocked") && !strings.Contains(fn, "resourceAllowedLocked") { + t.Fatalf("%s.%s missing resource-scoped authorization call", file, name) + } + } + } +} + +func functionBody(t *testing.T, fileBody, name string) string { + t.Helper() + marker := "func (l *Ledger) " + name + start := strings.Index(fileBody, marker) + if start < 0 { + t.Fatalf("missing function %s", name) + } + rest := fileBody[start+len(marker):] + next := strings.Index(rest, "\nfunc ") + if next < 0 { + return rest + } + return rest[:next] +} diff --git a/internal/app/builds.go b/internal/app/builds.go index dc7430e..bc6229f 100644 --- a/internal/app/builds.go +++ b/internal/app/builds.go @@ -308,6 +308,9 @@ func (l *Ledger) CreateBuildRun(ctx context.Context, actor domain.Actor, in Crea if project.ProductID != release.ProductID { return domain.BuildRun{}, ErrValidation } + if err := l.authorizeResourceLocked(actor, ScopeBuildWrite, resourceRefs{ProductID: project.ProductID, ProjectID: project.ID, ReleaseID: release.ID}); err != nil { + return domain.BuildRun{}, err + } for _, output := range build.Outputs { if !validDigest(output.Digest) { return domain.BuildRun{}, ErrValidation @@ -350,6 +353,9 @@ func (l *Ledger) GetBuildRun(ctx context.Context, actor domain.Actor, id string) if !ok || build.TenantID != actor.TenantID { return domain.BuildRun{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeBuildRead, resourceRefs{ProjectID: build.ProjectID, ReleaseID: build.ReleaseID, BuildID: build.ID}); err != nil { + return domain.BuildRun{}, err + } return build, nil } @@ -374,6 +380,10 @@ func (l *Ledger) UploadBuildAttestation(ctx context.Context, actor domain.Actor, l.mu.Unlock() return domain.BuildAttestation{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeBuildWrite, resourceRefs{ProjectID: build.ProjectID, ReleaseID: build.ReleaseID, BuildID: build.ID}); err != nil { + l.mu.Unlock() + return domain.BuildAttestation{}, err + } if !subjectsMatchBuildOutputs(parsed.SubjectDigests, build.Outputs) { l.mu.Unlock() return domain.BuildAttestation{}, ErrValidation diff --git a/internal/app/controls.go b/internal/app/controls.go index 1b1208a..0caa326 100644 --- a/internal/app/controls.go +++ b/internal/app/controls.go @@ -219,6 +219,10 @@ func (l *Ledger) LinkControlEvidence(ctx context.Context, actor domain.Actor, co if err := l.ensureScopeLocked(actor.TenantID, in.ProductID, "", in.ReleaseID); err != nil { return domain.ControlEvidence{}, err } + refs := l.refsForControlEvidenceSubjectLocked(in.SubjectType, in.SubjectID, in.ProductID, in.ReleaseID) + if err := l.authorizeResourceLocked(actor, ScopeControlsWrite, refs); err != nil { + return domain.ControlEvidence{}, err + } if !l.controlSubjectExistsLocked(actor.TenantID, in.SubjectType, in.SubjectID, in.ProductID, in.ReleaseID) { return domain.ControlEvidence{}, ErrNotFound } @@ -272,6 +276,9 @@ func (l *Ledger) ListControlEvidence(ctx context.Context, actor domain.Actor, co if releaseID != "" && link.ReleaseID != releaseID { continue } + if !l.resourceAllowedLocked(actor, ScopeControlsRead, l.refsForControlEvidenceSubjectLocked(link.SubjectType, link.SubjectID, link.ProductID, link.ReleaseID)) { + continue + } out = append(out, link) } sort.Slice(out, func(i, j int) bool { return out[i].ID < out[j].ID }) @@ -291,6 +298,9 @@ func (l *Ledger) ControlCoverageReport(ctx context.Context, actor domain.Actor, if err != nil { return domain.ControlCoverageReport{}, err } + if err := l.authorizeResourceLocked(actor, ScopeReportRead, resourceRefs{ProductID: report.ProductID, ReleaseID: report.ReleaseID}); err != nil { + return domain.ControlCoverageReport{}, err + } return report, nil } @@ -309,6 +319,9 @@ func (l *Ledger) CRAReadinessReport(ctx context.Context, actor domain.Actor, in if err := l.ensureScopeLocked(actor.TenantID, in.ProductID, "", in.ReleaseID); err != nil { return domain.CRAReadinessReport{}, err } + if err := l.authorizeResourceLocked(actor, ScopeReportRead, resourceRefs{ProductID: in.ProductID, ReleaseID: in.ReleaseID}); err != nil { + return domain.CRAReadinessReport{}, err + } frameworkID := l.firstFrameworkIDLocked(actor.TenantID) coverage, err := l.controlCoverageReportLocked(actor.TenantID, ControlCoverageReportInput{FrameworkID: frameworkID, ProductID: in.ProductID, ReleaseID: in.ReleaseID}) if err != nil { @@ -490,6 +503,50 @@ func (l *Ledger) controlSubjectExistsLocked(tenantID, subjectType, subjectID, pr } } +func (l *Ledger) refsForControlEvidenceSubjectLocked(subjectType, subjectID, productID, releaseID string) resourceRefs { + refs := resourceRefs{ProductID: strings.TrimSpace(productID), ReleaseID: strings.TrimSpace(releaseID)} + switch strings.TrimSpace(subjectType) { + case "evidence", "evidence_item": + if item, ok := l.evidence[strings.TrimSpace(subjectID)]; ok { + refs.ProductID = nonEmpty(refs.ProductID, item.ProductID) + refs.ProjectID = item.ProjectID + refs.ReleaseID = nonEmpty(refs.ReleaseID, item.ReleaseID) + } + case "release": + refs.ReleaseID = nonEmpty(refs.ReleaseID, strings.TrimSpace(subjectID)) + case "artifact": + refs.ArtifactID = strings.TrimSpace(subjectID) + case "build": + refs.BuildID = strings.TrimSpace(subjectID) + case "build_attestation": + if attestation, ok := l.attestations[strings.TrimSpace(subjectID)]; ok { + refs.BuildID = attestation.BuildID + } + case "security_scan": + refs.SecurityScanID = strings.TrimSpace(subjectID) + case "vulnerability_scan": + if scan, ok := l.scans[strings.TrimSpace(subjectID)]; ok { + refs.ReleaseID = nonEmpty(refs.ReleaseID, scan.ReleaseID) + } + case "incident": + refs.IncidentID = strings.TrimSpace(subjectID) + case "deployment": + refs.DeploymentID = strings.TrimSpace(subjectID) + case "openapi_contract": + if contract, ok := l.contracts[strings.TrimSpace(subjectID)]; ok { + refs.ProductID = nonEmpty(refs.ProductID, contract.ProductID) + refs.ReleaseID = nonEmpty(refs.ReleaseID, contract.ReleaseID) + } + case "release_bundle": + if bundle, ok := l.bundles[strings.TrimSpace(subjectID)]; ok { + refs.ReleaseID = nonEmpty(refs.ReleaseID, bundle.ReleaseID) + } + case "customer_package": + refs.CustomerPackageID = strings.TrimSpace(subjectID) + } + return refs +} + func (l *Ledger) controlEvidenceTimeLocked(link domain.ControlEvidence) time.Time { switch link.SubjectType { case "evidence", "evidence_item": diff --git a/internal/app/enterprise.go b/internal/app/enterprise.go index ce6680d..129e1ab 100644 --- a/internal/app/enterprise.go +++ b/internal/app/enterprise.go @@ -467,6 +467,10 @@ func (l *Ledger) AccessCustomerPortalPackage(ctx context.Context, token string) for id, access := range l.portalAccess { if access.Hash != hash || access.RevokedAt != nil || !access.ExpiresAt.After(l.now()) { if access.Prefix == prefix { + now := l.now() + access.FailedAccessCount++ + access.LastFailedAt = &now + l.portalAccess[id] = access _, _ = l.appendChainLocked(access.TenantID, "customer_portal_package.access_failed", "customer_portal_access", access.ID, "customer_portal", "unverified", "", "") _ = l.persistLocked(ctx) } @@ -477,6 +481,8 @@ func (l *Ledger) AccessCustomerPortalPackage(ctx context.Context, token string) return domain.CustomerSecurityPackage{}, ErrNotFound } access.AccessCount++ + now := l.now() + access.LastAccessedAt = &now l.portalAccess[id] = access _, _ = l.appendChainLocked(access.TenantID, "customer_portal_package.accessed", "customer_security_package", pkg.ID, "customer_portal", access.ID, pkg.ManifestHash, "") if err := l.persistLocked(ctx); err != nil { @@ -747,11 +753,18 @@ func scopesFromResourceGrants(grants []domain.ResourceGrant) []string { } type resourceRefs struct { - ProductID string - ProjectID string - ReleaseID string - CustomerPackageID string - EvidenceBundleID string + ProductID string + ProjectID string + ReleaseID string + ArtifactID string + BuildID string + DeploymentID string + EnvironmentID string + IncidentID string + SecurityScanID string + SourceRepositoryID string + CustomerPackageID string + EvidenceBundleID string } func refsForEvidence(item domain.EvidenceItem) resourceRefs { @@ -825,12 +838,83 @@ func (l *Ledger) productCoversRefsLocked(tenantID, productID string, refs resour return false } } + if refs.SourceRepositoryID != "" { + repo, ok := l.repositories[refs.SourceRepositoryID] + if !ok || repo.TenantID != tenantID { + return false + } + if repo.ProjectID == "" { + return false + } + project, ok := l.projects[repo.ProjectID] + if !ok || project.TenantID != tenantID || project.ProductID != productID { + return false + } + } if refs.ReleaseID != "" { release, ok := l.releases[refs.ReleaseID] if !ok || release.TenantID != tenantID || release.ProductID != productID { return false } } + if refs.BuildID != "" { + build, ok := l.buildRuns[refs.BuildID] + if !ok || build.TenantID != tenantID { + return false + } + if build.ReleaseID != "" { + release, ok := l.releases[build.ReleaseID] + if !ok || release.TenantID != tenantID || release.ProductID != productID { + return false + } + } + if build.ProjectID != "" { + project, ok := l.projects[build.ProjectID] + if !ok || project.TenantID != tenantID || project.ProductID != productID { + return false + } + } + } + if refs.EnvironmentID != "" { + env, ok := l.environments[refs.EnvironmentID] + if !ok || env.TenantID != tenantID || env.ProductID != productID { + return false + } + } + if refs.DeploymentID != "" { + deployment, ok := l.deployments[refs.DeploymentID] + if !ok || deployment.TenantID != tenantID { + return false + } + release, ok := l.releases[deployment.ReleaseID] + if !ok || release.TenantID != tenantID || release.ProductID != productID { + return false + } + } + if refs.IncidentID != "" { + incident, ok := l.incidents[refs.IncidentID] + if !ok || incident.TenantID != tenantID || incident.ProductID != productID { + return false + } + } + if refs.SecurityScanID != "" { + scan, ok := l.securityScans[refs.SecurityScanID] + if !ok || scan.TenantID != tenantID { + return false + } + if scan.ProductID != "" && scan.ProductID != productID { + return false + } + if scan.ReleaseID != "" { + release, ok := l.releases[scan.ReleaseID] + if !ok || release.TenantID != tenantID || release.ProductID != productID { + return false + } + } + } + if refs.ArtifactID != "" && !l.artifactCoversProductLocked(tenantID, refs.ArtifactID, productID) { + return false + } if refs.CustomerPackageID != "" { pkg, ok := l.customerPackages[refs.CustomerPackageID] if !ok || pkg.TenantID != tenantID || pkg.ProductID != productID { @@ -857,6 +941,14 @@ func (l *Ledger) projectCoversRefsLocked(tenantID, projectID string, refs resour project, ok := l.projects[refs.ProjectID] return ok && project.TenantID == tenantID && project.ID == projectID } + if refs.SourceRepositoryID != "" { + repo, ok := l.repositories[refs.SourceRepositoryID] + return ok && repo.TenantID == tenantID && repo.ProjectID == projectID + } + if refs.BuildID != "" { + build, ok := l.buildRuns[refs.BuildID] + return ok && build.TenantID == tenantID && build.ProjectID == projectID + } return false } @@ -873,6 +965,76 @@ func (l *Ledger) releaseCoversRefsLocked(tenantID, releaseID string, refs resour bundle, ok := l.evidenceBundles[refs.EvidenceBundleID] return ok && bundle.TenantID == tenantID && bundle.ReleaseID == releaseID } + if refs.BuildID != "" { + build, ok := l.buildRuns[refs.BuildID] + return ok && build.TenantID == tenantID && build.ReleaseID == releaseID + } + if refs.DeploymentID != "" { + deployment, ok := l.deployments[refs.DeploymentID] + return ok && deployment.TenantID == tenantID && deployment.ReleaseID == releaseID + } + if refs.IncidentID != "" { + incident, ok := l.incidents[refs.IncidentID] + return ok && incident.TenantID == tenantID && incident.ReleaseID == releaseID + } + if refs.SecurityScanID != "" { + scan, ok := l.securityScans[refs.SecurityScanID] + return ok && scan.TenantID == tenantID && scan.ReleaseID == releaseID + } + if refs.ArtifactID != "" && l.artifactCoversReleaseLocked(tenantID, refs.ArtifactID, releaseID) { + return true + } + return false +} + +func (l *Ledger) artifactCoversProductLocked(tenantID, artifactID, productID string) bool { + for _, item := range l.evidence { + if item.TenantID == tenantID && item.ProductID == productID && evidenceReferencesArtifact(item, artifactID) { + return true + } + } + for _, build := range l.buildRuns { + if build.TenantID != tenantID { + continue + } + for _, output := range build.Outputs { + if output.ArtifactID != artifactID { + continue + } + release, ok := l.releases[build.ReleaseID] + if ok && release.TenantID == tenantID && release.ProductID == productID { + return true + } + } + } + return false +} + +func (l *Ledger) artifactCoversReleaseLocked(tenantID, artifactID, releaseID string) bool { + for _, item := range l.evidence { + if item.TenantID == tenantID && item.ReleaseID == releaseID && evidenceReferencesArtifact(item, artifactID) { + return true + } + } + for _, build := range l.buildRuns { + if build.TenantID != tenantID || build.ReleaseID != releaseID { + continue + } + for _, output := range build.Outputs { + if output.ArtifactID == artifactID { + return true + } + } + } + return false +} + +func evidenceReferencesArtifact(item domain.EvidenceItem, artifactID string) bool { + for _, ref := range item.SubjectRefs { + if ref.Type == "artifact" && ref.ID == artifactID { + return true + } + } return false } diff --git a/internal/app/enterprise_test.go b/internal/app/enterprise_test.go index 6f11490..fc5059c 100644 --- a/internal/app/enterprise_test.go +++ b/internal/app/enterprise_test.go @@ -130,6 +130,13 @@ func TestCustomerPortalRetentionQuestionnairesAndCommercialCollectors(t *testing if !foundFailedAccess { t.Fatalf("missing failed portal access audit entry: %#v", entries) } + metrics, err := ledger.Metrics(ctx, actor) + if err != nil { + t.Fatalf("metrics: %v", err) + } + if got := metrics["customer_portal_failed_access_count"]; got != 1 { + t.Fatalf("portal failed access metric = %#v, want 1", got) + } if _, err := ledger.CreateLegalHold(ctx, actor, CreateLegalHoldInput{ScopeType: "release", ScopeID: release.ID, Reason: "customer dispute", Owner: "legal"}); err != nil { t.Fatalf("legal hold: %v", err) } @@ -294,3 +301,166 @@ func TestHumanSSOSessionRoleBindingsAreResourceScoped(t *testing.T) { t.Fatalf("foreign package report err=%v, want forbidden", err) } } + +func TestHumanSSOSessionResourceScopeCoversWorkflowFamilies(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + _, _, secret, err := ledger.BootstrapTenant(ctx, "Tenant", "admin", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap: %v", err) + } + admin, err := ledger.Authenticate(ctx, secret) + if err != nil { + t.Fatalf("auth: %v", err) + } + productA, err := ledger.CreateProduct(ctx, admin, "A", "a") + if err != nil { + t.Fatalf("product A: %v", err) + } + releaseA, err := ledger.CreateRelease(ctx, admin, productA.ID, "1") + if err != nil { + t.Fatalf("release A: %v", err) + } + projectA, err := ledger.CreateProject(ctx, admin, productA.ID, "api") + if err != nil { + t.Fatalf("project A: %v", err) + } + artifactA, err := ledger.RegisterArtifact(ctx, admin, "api", "application/octet-stream", sampleDigest("artifact-a"), 10) + if err != nil { + t.Fatalf("artifact A: %v", err) + } + productB, err := ledger.CreateProduct(ctx, admin, "B", "b") + if err != nil { + t.Fatalf("product B: %v", err) + } + releaseB, err := ledger.CreateRelease(ctx, admin, productB.ID, "1") + if err != nil { + t.Fatalf("release B: %v", err) + } + projectB, err := ledger.CreateProject(ctx, admin, productB.ID, "api") + if err != nil { + t.Fatalf("project B: %v", err) + } + artifactB, err := ledger.RegisterArtifact(ctx, admin, "api-b", "application/octet-stream", sampleDigest("artifact-b"), 10) + if err != nil { + t.Fatalf("artifact B: %v", err) + } + + framework, err := ledger.CreateControlFramework(ctx, admin, CreateControlFrameworkInput{Name: "Controls", Version: "1"}) + if err != nil { + t.Fatalf("framework: %v", err) + } + control, err := ledger.CreateSecurityControl(ctx, admin, CreateSecurityControlInput{FrameworkID: framework.ID, Code: "EVD-1", Title: "Evidence", Objective: "Collect evidence", EvidenceRequirements: []domain.ControlEvidenceRequirement{{Type: "build", Required: true}}}) + if err != nil { + t.Fatalf("control: %v", err) + } + buildA, err := ledger.CreateBuildRun(ctx, admin, CreateBuildRunInput{ProjectID: projectA.ID, ReleaseID: releaseA.ID, Provider: "generic_ci", CommitSHA: "0123456789abcdef0123456789abcdef01234567", Status: "passed", StartedAt: fixedNow(), Outputs: []domain.BuildOutput{{ArtifactID: artifactA.ID, Digest: artifactA.Digest}}}) + if err != nil { + t.Fatalf("build A: %v", err) + } + buildB, err := ledger.CreateBuildRun(ctx, admin, CreateBuildRunInput{ProjectID: projectB.ID, ReleaseID: releaseB.ID, Provider: "generic_ci", CommitSHA: "1123456789abcdef0123456789abcdef01234567", Status: "passed", StartedAt: fixedNow(), Outputs: []domain.BuildOutput{{ArtifactID: artifactB.ID, Digest: artifactB.Digest}}}) + if err != nil { + t.Fatalf("build B: %v", err) + } + incidentA, err := ledger.CreateIncident(ctx, admin, CreateIncidentInput{ProductID: productA.ID, ReleaseID: releaseA.ID, Title: "incident A", Severity: "high"}) + if err != nil { + t.Fatalf("incident A: %v", err) + } + incidentB, err := ledger.CreateIncident(ctx, admin, CreateIncidentInput{ProductID: productB.ID, ReleaseID: releaseB.ID, Title: "incident B", Severity: "high"}) + if err != nil { + t.Fatalf("incident B: %v", err) + } + envA, err := ledger.CreateDeploymentEnvironment(ctx, admin, CreateEnvironmentInput{ProductID: productA.ID, Name: "prod-a", Kind: "production"}) + if err != nil { + t.Fatalf("env A: %v", err) + } + envB, err := ledger.CreateDeploymentEnvironment(ctx, admin, CreateEnvironmentInput{ProductID: productB.ID, Name: "prod-b", Kind: "production"}) + if err != nil { + t.Fatalf("env B: %v", err) + } + depA, err := ledger.RecordDeployment(ctx, admin, RecordDeploymentInput{EnvironmentID: envA.ID, ReleaseID: releaseA.ID, ArtifactIDs: []string{artifactA.ID}, Status: deploymentStatusSucceeded, StartedAt: fixedNow()}) + if err != nil { + t.Fatalf("deployment A: %v", err) + } + depB, err := ledger.RecordDeployment(ctx, admin, RecordDeploymentInput{EnvironmentID: envB.ID, ReleaseID: releaseB.ID, ArtifactIDs: []string{artifactB.ID}, Status: deploymentStatusSucceeded, StartedAt: fixedNow()}) + if err != nil { + t.Fatalf("deployment B: %v", err) + } + repoA, err := ledger.CreateSourceRepository(ctx, admin, CreateRepositoryInput{ProjectID: projectA.ID, Provider: "github", FullName: "org/a"}) + if err != nil { + t.Fatalf("repo A: %v", err) + } + repoB, err := ledger.CreateSourceRepository(ctx, admin, CreateRepositoryInput{ProjectID: projectB.ID, Provider: "github", FullName: "org/b"}) + if err != nil { + t.Fatalf("repo B: %v", err) + } + + org, err := ledger.CreateOrganization(ctx, admin, CreateOrganizationInput{Name: "Example", Slug: "example"}) + if err != nil { + t.Fatalf("org: %v", err) + } + user, err := ledger.CreateUser(ctx, admin, CreateUserInput{OrganizationID: org.ID, Email: "scoped@example.test", DisplayName: "Scoped"}) + if err != nil { + t.Fatalf("user: %v", err) + } + if _, err := ledger.CreateRoleBinding(ctx, admin, CreateRoleBindingInput{SubjectType: "user", SubjectID: user.ID, Role: "tenant_admin", ResourceType: "product", ResourceID: productA.ID}); err != nil { + t.Fatalf("role binding: %v", err) + } + provider, err := ledger.CreateSSOProvider(ctx, admin, CreateSSOProviderInput{Name: "OIDC", Type: "oidc", Issuer: "https://idp.example.test", ClientID: "client"}) + if err != nil { + t.Fatalf("provider: %v", err) + } + _, sessionSecret, err := ledger.CreateSSOSession(ctx, admin, CreateSSOSessionInput{UserID: user.ID, ProviderID: provider.ID, ExpiresAt: fixedNow().Add(time.Hour)}) + if err != nil { + t.Fatalf("session: %v", err) + } + scoped, err := ledger.Authenticate(ctx, sessionSecret) + if err != nil { + t.Fatalf("scoped auth: %v", err) + } + + if _, err := ledger.GetBuildRun(ctx, scoped, buildA.ID); err != nil { + t.Fatalf("get allowed build: %v", err) + } + if _, err := ledger.GetBuildRun(ctx, scoped, buildB.ID); !errors.Is(err, ErrForbidden) { + t.Fatalf("get foreign build err=%v, want forbidden", err) + } + if _, err := ledger.LinkControlEvidence(ctx, scoped, control.ID, LinkControlEvidenceInput{EvidenceType: "build", SubjectType: "build", SubjectID: buildA.ID, ProductID: productA.ID, ReleaseID: releaseA.ID, Confidence: confidenceHigh}); err != nil { + t.Fatalf("link allowed control evidence: %v", err) + } + if _, err := ledger.LinkControlEvidence(ctx, scoped, control.ID, LinkControlEvidenceInput{EvidenceType: "build", SubjectType: "build", SubjectID: buildB.ID, ProductID: productB.ID, ReleaseID: releaseB.ID, Confidence: confidenceHigh}); !errors.Is(err, ErrForbidden) { + t.Fatalf("link foreign control evidence err=%v, want forbidden", err) + } + if _, err := ledger.IncidentReport(ctx, scoped, incidentA.ID); err != nil { + t.Fatalf("incident report A: %v", err) + } + if _, err := ledger.IncidentReport(ctx, scoped, incidentB.ID); !errors.Is(err, ErrForbidden) { + t.Fatalf("incident report B err=%v, want forbidden", err) + } + if _, err := ledger.UploadSecurityScan(ctx, scoped, UploadSecurityScanInput{ProductID: productB.ID, ReleaseID: releaseB.ID, Category: "secret_scan", Format: "generic", Scanner: "scan", TargetRef: "target", Raw: []byte(`{"findings":[]}`)}); !errors.Is(err, ErrForbidden) { + t.Fatalf("foreign security scan err=%v, want forbidden", err) + } + if _, err := ledger.GetDeployment(ctx, scoped, depA.ID); err != nil { + t.Fatalf("get deployment A: %v", err) + } + if _, err := ledger.GetDeployment(ctx, scoped, depB.ID); !errors.Is(err, ErrForbidden) { + t.Fatalf("get deployment B err=%v, want forbidden", err) + } + repos, err := ledger.ListSourceRepositories(ctx, scoped, "") + if err != nil { + t.Fatalf("list repos: %v", err) + } + if len(repos) != 1 || repos[0].ID != repoA.ID { + t.Fatalf("scoped repos=%#v want only %s; foreign repo was %s", repos, repoA.ID, repoB.ID) + } + if _, err := ledger.RecordSourceCommit(ctx, scoped, RecordCommitInput{RepositoryID: repoB.ID, SHA: "2123456789abcdef0123456789abcdef01234567", CommittedAt: fixedNow()}); !errors.Is(err, ErrForbidden) { + t.Fatalf("foreign source commit err=%v, want forbidden", err) + } + deployments, err := ledger.ListDeployments(ctx, scoped, "", "") + if err != nil { + t.Fatalf("list deployments: %v", err) + } + if len(deployments) != 1 || deployments[0].ID != depA.ID { + t.Fatalf("scoped deployments=%#v want only %s", deployments, depA.ID) + } +} diff --git a/internal/app/implementation_increments.go b/internal/app/implementation_increments.go index a26f740..2d12953 100644 --- a/internal/app/implementation_increments.go +++ b/internal/app/implementation_increments.go @@ -152,6 +152,9 @@ func (l *Ledger) SearchEvidence(ctx context.Context, actor domain.Actor, in Evid if item.TenantID != actor.TenantID || !matchesEvidenceSearch(item, in) { continue } + if !l.resourceAllowedLocked(actor, ScopeEvidenceRead, refsForEvidence(item)) { + continue + } out = append(out, item) } sort.Slice(out, func(i, j int) bool { @@ -184,11 +187,17 @@ func (l *Ledger) RecordEvidenceLifecycleEvent(ctx context.Context, actor domain. if !ok || item.TenantID != actor.TenantID { return domain.EvidenceLifecycleEvent{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceWrite, refsForEvidence(item)); err != nil { + return domain.EvidenceLifecycleEvent{}, err + } if in.ReplacementID != "" { replacement, ok := l.evidence[strings.TrimSpace(in.ReplacementID)] if !ok || replacement.TenantID != actor.TenantID { return domain.EvidenceLifecycleEvent{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceWrite, refsForEvidence(replacement)); err != nil { + return domain.EvidenceLifecycleEvent{}, err + } } event := domain.EvidenceLifecycleEvent{ ID: newID("elc"), @@ -223,6 +232,9 @@ func (l *Ledger) ListEvidenceLifecycleEvents(ctx context.Context, actor domain.A if !ok || item.TenantID != actor.TenantID { return nil, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceRead, refsForEvidence(item)); err != nil { + return nil, err + } out := []domain.EvidenceLifecycleEvent{} for _, event := range l.lifecycle { if event.TenantID == actor.TenantID && event.EvidenceID == item.ID { @@ -246,6 +258,9 @@ func (l *Ledger) CreateReleaseCandidate(ctx context.Context, actor domain.Actor, if !ok || release.TenantID != actor.TenantID { return domain.ReleaseCandidate{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeReleaseWrite, resourceRefs{ProductID: release.ProductID, ReleaseID: release.ID}); err != nil { + return domain.ReleaseCandidate{}, err + } if strings.TrimSpace(in.Name) == "" { return domain.ReleaseCandidate{}, ErrValidation } @@ -294,6 +309,9 @@ func (l *Ledger) GetReleaseCandidate(ctx context.Context, actor domain.Actor, id if !ok || candidate.TenantID != actor.TenantID { return domain.ReleaseCandidate{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeReleaseRead, resourceRefs{ReleaseID: candidate.ReleaseID}); err != nil { + return domain.ReleaseCandidate{}, err + } return candidate, nil } @@ -314,6 +332,9 @@ func (l *Ledger) ListReleaseCandidates(ctx context.Context, actor domain.Actor, if releaseID != "" && candidate.ReleaseID != releaseID { continue } + if !l.resourceAllowedLocked(actor, ScopeReleaseRead, resourceRefs{ReleaseID: candidate.ReleaseID}) { + continue + } out = append(out, candidate) } sort.Slice(out, func(i, j int) bool { return out[i].CreatedAt.Before(out[j].CreatedAt) }) @@ -340,6 +361,9 @@ func (l *Ledger) UpdateReleaseCandidateState(ctx context.Context, actor domain.A if candidate.State != candidateOpen { return domain.ReleaseCandidate{}, ErrConflict } + if err := l.authorizeResourceLocked(actor, ScopeReleaseWrite, resourceRefs{ReleaseID: candidate.ReleaseID}); err != nil { + return domain.ReleaseCandidate{}, err + } now := l.now() candidate.State = state if state == candidatePromoted { @@ -373,6 +397,9 @@ func (l *Ledger) RegisterContainerImage(ctx context.Context, actor domain.Actor, if !ok || artifact.TenantID != actor.TenantID || artifact.Digest != in.Digest { return domain.ContainerImage{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceWrite, resourceRefs{ArtifactID: artifact.ID}); err != nil { + return domain.ContainerImage{}, err + } } for _, existing := range l.images { if existing.TenantID == actor.TenantID && existing.Repository == in.Repository && existing.Digest == in.Digest { @@ -415,6 +442,10 @@ func (l *Ledger) CreateArtifactSignature(ctx context.Context, actor domain.Actor l.mu.Unlock() return domain.ArtifactSignature{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceWrite, resourceRefs{ArtifactID: artifact.ID}); err != nil { + l.mu.Unlock() + return domain.ArtifactSignature{}, err + } l.mu.Unlock() payloadHash, payloadRef := "", "" if len(in.RawPayload) > 0 { @@ -462,6 +493,9 @@ func (l *Ledger) GetArtifactSignature(ctx context.Context, actor domain.Actor, i if !ok || sig.TenantID != actor.TenantID { return domain.ArtifactSignature{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceRead, resourceRefs{ArtifactID: sig.ArtifactID}); err != nil { + return domain.ArtifactSignature{}, err + } return sig, nil } @@ -482,6 +516,9 @@ func (l *Ledger) ListSourceRepositories(ctx context.Context, actor domain.Actor, if projectID != "" && repo.ProjectID != projectID { continue } + if !l.resourceAllowedLocked(actor, ScopeSourceRead, resourceRefs{ProjectID: repo.ProjectID, SourceRepositoryID: repo.ID}) { + continue + } out = append(out, repo) } sort.Slice(out, func(i, j int) bool { return out[i].CreatedAt.Before(out[j].CreatedAt) }) @@ -506,6 +543,9 @@ func (l *Ledger) CreateSourceRepository(ctx context.Context, actor domain.Actor, if !ok || project.TenantID != actor.TenantID { return domain.SourceRepository{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeSourceWrite, resourceRefs{ProductID: project.ProductID, ProjectID: project.ID}); err != nil { + return domain.SourceRepository{}, err + } } for _, existing := range l.repositories { if existing.TenantID == actor.TenantID && existing.Provider == in.Provider && existing.FullName == in.FullName { @@ -551,6 +591,9 @@ func (l *Ledger) RecordSourceCommit(ctx context.Context, actor domain.Actor, in if !ok || repo.TenantID != actor.TenantID { return domain.SourceCommit{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeSourceWrite, resourceRefs{ProjectID: repo.ProjectID, SourceRepositoryID: repo.ID}); err != nil { + return domain.SourceCommit{}, err + } for _, existing := range l.commits { if existing.TenantID == actor.TenantID && existing.RepositoryID == repo.ID && existing.SHA == in.SHA { return existing, nil @@ -596,6 +639,9 @@ func (l *Ledger) UpsertSourceBranch(ctx context.Context, actor domain.Actor, in if !ok || repo.TenantID != actor.TenantID { return domain.SourceBranch{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeSourceWrite, resourceRefs{ProjectID: repo.ProjectID, SourceRepositoryID: repo.ID}); err != nil { + return domain.SourceBranch{}, err + } if in.HeadCommitID != "" { commit, ok := l.commits[strings.TrimSpace(in.HeadCommitID)] if !ok || commit.TenantID != actor.TenantID || commit.RepositoryID != repo.ID { @@ -651,6 +697,9 @@ func (l *Ledger) RecordPullRequest(ctx context.Context, actor domain.Actor, in R if !ok || repo.TenantID != actor.TenantID { return domain.PullRequest{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeSourceWrite, resourceRefs{ProjectID: repo.ProjectID, SourceRepositoryID: repo.ID}); err != nil { + return domain.PullRequest{}, err + } if in.HeadCommitID != "" { commit, ok := l.commits[strings.TrimSpace(in.HeadCommitID)] if !ok || commit.TenantID != actor.TenantID || commit.RepositoryID != repo.ID { @@ -697,6 +746,9 @@ func (l *Ledger) ListDeploymentEnvironments(ctx context.Context, actor domain.Ac if productID != "" && env.ProductID != productID { continue } + if !l.resourceAllowedLocked(actor, ScopeDeploymentRead, resourceRefs{ProductID: env.ProductID, EnvironmentID: env.ID}) { + continue + } out = append(out, env) } sort.Slice(out, func(i, j int) bool { return out[i].CreatedAt.Before(out[j].CreatedAt) }) @@ -720,6 +772,9 @@ func (l *Ledger) CreateDeploymentEnvironment(ctx context.Context, actor domain.A if !ok || product.TenantID != actor.TenantID { return domain.DeploymentEnvironment{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeDeploymentWrite, resourceRefs{ProductID: product.ID}); err != nil { + return domain.DeploymentEnvironment{}, err + } for _, existing := range l.environments { if existing.TenantID == actor.TenantID && existing.ProductID == product.ID && existing.Name == in.Name { return existing, nil @@ -767,6 +822,10 @@ func (l *Ledger) RecordDeployment(ctx context.Context, actor domain.Actor, in Re l.mu.Unlock() return domain.DeploymentEvent{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeDeploymentWrite, resourceRefs{ProductID: env.ProductID, ReleaseID: release.ID, EnvironmentID: env.ID}); err != nil { + l.mu.Unlock() + return domain.DeploymentEvent{}, err + } for _, artifactID := range in.ArtifactIDs { artifact, ok := l.artifacts[strings.TrimSpace(artifactID)] if !ok || artifact.TenantID != actor.TenantID { @@ -841,6 +900,9 @@ func (l *Ledger) GetDeployment(ctx context.Context, actor domain.Actor, id strin if !ok || deployment.TenantID != actor.TenantID { return domain.DeploymentEvent{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeDeploymentRead, resourceRefs{ReleaseID: deployment.ReleaseID, DeploymentID: deployment.ID}); err != nil { + return domain.DeploymentEvent{}, err + } return deployment, nil } @@ -864,6 +926,9 @@ func (l *Ledger) ListDeployments(ctx context.Context, actor domain.Actor, releas if environmentID != "" && deployment.EnvironmentID != environmentID { continue } + if !l.resourceAllowedLocked(actor, ScopeDeploymentRead, resourceRefs{ReleaseID: deployment.ReleaseID, DeploymentID: deployment.ID, EnvironmentID: deployment.EnvironmentID}) { + continue + } out = append(out, deployment) } sort.Slice(out, func(i, j int) bool { return out[i].CreatedAt.Before(out[j].CreatedAt) }) diff --git a/internal/app/integrity_runtime.go b/internal/app/integrity_runtime.go index c57a9d0..0c0ec11 100644 --- a/internal/app/integrity_runtime.go +++ b/internal/app/integrity_runtime.go @@ -435,7 +435,13 @@ func (l *Ledger) Metrics(ctx context.Context, actor domain.Actor) (map[string]an } l.mu.Lock() defer l.mu.Unlock() - return map[string]any{"tenant_id": actor.TenantID, "resource_counts": l.resourceCountsLocked(actor.TenantID)}, nil + portalFailures := 0 + for _, access := range l.portalAccess { + if access.TenantID == actor.TenantID { + portalFailures += access.FailedAccessCount + } + } + return map[string]any{"tenant_id": actor.TenantID, "resource_counts": l.resourceCountsLocked(actor.TenantID), "customer_portal_failed_access_count": portalFailures}, nil } func (l *Ledger) ListAuditLog(ctx context.Context, actor domain.Actor, filter AuditLogFilter) ([]domain.AuditChainEntry, error) { diff --git a/internal/app/ledger.go b/internal/app/ledger.go index 5409c02..07b48e9 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -856,6 +856,9 @@ func (l *Ledger) LinkEvidence(ctx context.Context, actor domain.Actor, id, targe } func (l *Ledger) UploadSBOM(ctx context.Context, actor domain.Actor, releaseID, artifactID string, raw []byte) (domain.SBOM, error) { + if err := require(actor, ScopeEvidenceWrite); err != nil { + return domain.SBOM{}, err + } if len(raw) == 0 || len(raw) > 20<<20 { return domain.SBOM{}, ErrValidation } @@ -880,6 +883,16 @@ func (l *Ledger) UploadSBOM(ctx context.Context, actor domain.Actor, releaseID, } components = append(components, domain.SBOMComponent{Name: component.Name, Version: component.Version, PURL: component.PURL}) } + l.mu.Lock() + if err := l.ensureScopeLocked(actor.TenantID, "", "", strings.TrimSpace(releaseID)); err != nil { + l.mu.Unlock() + return domain.SBOM{}, err + } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceWrite, resourceRefs{ReleaseID: strings.TrimSpace(releaseID)}); err != nil { + l.mu.Unlock() + return domain.SBOM{}, err + } + l.mu.Unlock() payloadHash := hashBytes(raw) payloadRef, err := l.storePayload(ctx, actor.TenantID, "sbom", "application/vnd.cyclonedx+json", payloadHash, raw) if err != nil { @@ -921,6 +934,9 @@ func (l *Ledger) UploadSBOM(ctx context.Context, actor domain.Actor, releaseID, } func (l *Ledger) UploadVulnerabilityScan(ctx context.Context, actor domain.Actor, raw []byte) (domain.VulnerabilityScan, error) { + if err := require(actor, ScopeEvidenceWrite); err != nil { + return domain.VulnerabilityScan{}, err + } if len(raw) == 0 || len(raw) > 20<<20 { return domain.VulnerabilityScan{}, ErrValidation } @@ -943,6 +959,17 @@ func (l *Ledger) UploadVulnerabilityScan(ctx context.Context, actor domain.Actor if doc.ReleaseID == "" { return domain.VulnerabilityScan{}, ErrValidation } + l.mu.Lock() + release, ok := l.releases[strings.TrimSpace(doc.ReleaseID)] + if !ok || release.TenantID != actor.TenantID { + l.mu.Unlock() + return domain.VulnerabilityScan{}, ErrNotFound + } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceWrite, resourceRefs{ProductID: release.ProductID, ReleaseID: release.ID}); err != nil { + l.mu.Unlock() + return domain.VulnerabilityScan{}, err + } + l.mu.Unlock() payloadHash := hashBytes(raw) payloadRef, err := l.storePayload(ctx, actor.TenantID, "vulnerability-scan", "application/json", payloadHash, raw) if err != nil { @@ -1001,6 +1028,16 @@ func (l *Ledger) UploadOpenAPIContract(ctx context.Context, actor domain.Actor, if err := doc.Validate(ctx); err != nil { return domain.OpenAPIContract{}, ErrValidation } + l.mu.Lock() + if err := l.ensureScopeLocked(actor.TenantID, strings.TrimSpace(productID), "", strings.TrimSpace(releaseID)); err != nil { + l.mu.Unlock() + return domain.OpenAPIContract{}, err + } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceWrite, resourceRefs{ProductID: strings.TrimSpace(productID), ReleaseID: strings.TrimSpace(releaseID)}); err != nil { + l.mu.Unlock() + return domain.OpenAPIContract{}, err + } + l.mu.Unlock() payloadHash := hashBytes(raw) payloadRef, err := l.storePayload(ctx, actor.TenantID, "openapi-contract", "application/vnd.oai.openapi+json", payloadHash, raw) if err != nil { @@ -1281,6 +1318,9 @@ func (l *Ledger) VerifySubject(ctx context.Context, actor domain.Actor, subjectT if !ok || sig.TenantID != actor.TenantID { return domain.VerificationResult{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeVerifyRead, resourceRefs{ArtifactID: sig.ArtifactID}); err != nil { + return domain.VerificationResult{}, err + } artifact, ok := l.artifacts[sig.ArtifactID] if !ok || artifact.TenantID != actor.TenantID { return domain.VerificationResult{}, ErrNotFound diff --git a/internal/app/risk_workflows.go b/internal/app/risk_workflows.go index 7003361..8ba554a 100644 --- a/internal/app/risk_workflows.go +++ b/internal/app/risk_workflows.go @@ -102,6 +102,9 @@ func (l *Ledger) CreateIncident(ctx context.Context, actor domain.Actor, in Crea if err := l.ensureScopeLocked(actor.TenantID, in.ProductID, "", in.ReleaseID); err != nil { return domain.Incident{}, err } + if err := l.authorizeResourceLocked(actor, ScopeIncidentWrite, resourceRefs{ProductID: in.ProductID, ReleaseID: in.ReleaseID}); err != nil { + return domain.Incident{}, err + } incident := domain.Incident{ ID: newID("inc"), TenantID: actor.TenantID, @@ -142,11 +145,17 @@ func (l *Ledger) RecordIncidentTimelineEvent(ctx context.Context, actor domain.A if !ok || incident.TenantID != actor.TenantID { return domain.IncidentTimelineEvent{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeIncidentWrite, resourceRefs{ProductID: incident.ProductID, ReleaseID: incident.ReleaseID, IncidentID: incident.ID}); err != nil { + return domain.IncidentTimelineEvent{}, err + } if in.EvidenceID != "" { item, ok := l.evidence[strings.TrimSpace(in.EvidenceID)] if !ok || item.TenantID != actor.TenantID { return domain.IncidentTimelineEvent{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeIncidentWrite, refsForEvidence(item)); err != nil { + return domain.IncidentTimelineEvent{}, err + } } event := domain.IncidentTimelineEvent{ ID: newID("it"), @@ -186,18 +195,27 @@ func (l *Ledger) CreateRemediationTask(ctx context.Context, actor domain.Actor, if !ok || incident.TenantID != actor.TenantID { return domain.RemediationTask{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeIncidentWrite, resourceRefs{ProductID: incident.ProductID, ReleaseID: incident.ReleaseID, IncidentID: incident.ID}); err != nil { + return domain.RemediationTask{}, err + } } if in.ReleaseID != "" { release, ok := l.releases[in.ReleaseID] if !ok || release.TenantID != actor.TenantID { return domain.RemediationTask{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeIncidentWrite, resourceRefs{ProductID: release.ProductID, ReleaseID: release.ID}); err != nil { + return domain.RemediationTask{}, err + } } if in.EvidenceID != "" { item, ok := l.evidence[strings.TrimSpace(in.EvidenceID)] if !ok || item.TenantID != actor.TenantID { return domain.RemediationTask{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeIncidentWrite, refsForEvidence(item)); err != nil { + return domain.RemediationTask{}, err + } } task := domain.RemediationTask{ ID: newID("rt"), @@ -233,6 +251,9 @@ func (l *Ledger) IncidentReport(ctx context.Context, actor domain.Actor, inciden if !ok || incident.TenantID != actor.TenantID { return domain.IncidentReport{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeIncidentRead, resourceRefs{ProductID: incident.ProductID, ReleaseID: incident.ReleaseID, IncidentID: incident.ID}); err != nil { + return domain.IncidentReport{}, err + } timeline := []domain.IncidentTimelineEvent{} linked := []string{} for _, event := range l.timeline { @@ -300,6 +321,16 @@ func (l *Ledger) uploadSecurityScan(ctx context.Context, actor domain.Actor, in if in.Format == "" { in.Format = parsed.Format } + l.mu.Lock() + if err := l.ensureScopeLocked(actor.TenantID, strings.TrimSpace(in.ProductID), "", strings.TrimSpace(in.ReleaseID)); err != nil { + l.mu.Unlock() + return domain.SecurityScan{}, err + } + if err := l.authorizeResourceLocked(actor, ScopeSecurityWrite, resourceRefs{ProductID: strings.TrimSpace(in.ProductID), ReleaseID: strings.TrimSpace(in.ReleaseID)}); err != nil { + l.mu.Unlock() + return domain.SecurityScan{}, err + } + l.mu.Unlock() payloadHash := hashBytes(in.Raw) payloadRef, err := l.storePayload(ctx, actor.TenantID, "security-scan", "application/json", payloadHash, in.Raw) if err != nil { @@ -329,11 +360,17 @@ func (l *Ledger) uploadSecurityScan(ctx context.Context, actor domain.Actor, in if err := l.ensureScopeLocked(actor.TenantID, in.ProductID, "", in.ReleaseID); err != nil { return domain.SecurityScan{}, err } + if err := l.authorizeResourceLocked(actor, ScopeSecurityWrite, resourceRefs{ProductID: in.ProductID, ReleaseID: in.ReleaseID}); err != nil { + return domain.SecurityScan{}, err + } if in.ArtifactID != "" { artifact, ok := l.artifacts[strings.TrimSpace(in.ArtifactID)] if !ok || artifact.TenantID != actor.TenantID { return domain.SecurityScan{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeSecurityWrite, resourceRefs{ProductID: in.ProductID, ReleaseID: in.ReleaseID, ArtifactID: artifact.ID}); err != nil { + return domain.SecurityScan{}, err + } } scan := domain.SecurityScan{ ID: newID("secscan"), @@ -374,6 +411,16 @@ func (l *Ledger) UploadManualSecurityDocument(ctx context.Context, actor domain. if len(in.Raw) == 0 || len(in.Raw) > 20<<20 || !validManualDocType(in.DocumentType) || in.Title == "" || !validSensitivity(in.Sensitivity) { return domain.ManualSecurityDocument{}, ErrValidation } + l.mu.Lock() + if err := l.ensureScopeLocked(actor.TenantID, strings.TrimSpace(in.ProductID), "", strings.TrimSpace(in.ReleaseID)); err != nil { + l.mu.Unlock() + return domain.ManualSecurityDocument{}, err + } + if err := l.authorizeResourceLocked(actor, ScopeSecurityWrite, resourceRefs{ProductID: strings.TrimSpace(in.ProductID), ReleaseID: strings.TrimSpace(in.ReleaseID)}); err != nil { + l.mu.Unlock() + return domain.ManualSecurityDocument{}, err + } + l.mu.Unlock() payloadHash := hashBytes(in.Raw) payloadRef, err := l.storePayload(ctx, actor.TenantID, "manual-security-document", nonEmpty(in.MediaType, "application/octet-stream"), payloadHash, in.Raw) if err != nil { @@ -402,6 +449,9 @@ func (l *Ledger) UploadManualSecurityDocument(ctx context.Context, actor domain. if err := l.ensureScopeLocked(actor.TenantID, in.ProductID, "", in.ReleaseID); err != nil { return domain.ManualSecurityDocument{}, err } + if err := l.authorizeResourceLocked(actor, ScopeSecurityWrite, resourceRefs{ProductID: in.ProductID, ReleaseID: in.ReleaseID}); err != nil { + return domain.ManualSecurityDocument{}, err + } doc := domain.ManualSecurityDocument{ ID: newID("msd"), TenantID: actor.TenantID, @@ -425,6 +475,9 @@ func (l *Ledger) UploadManualSecurityDocument(ctx context.Context, actor domain. } func (l *Ledger) UploadSPDXSBOM(ctx context.Context, actor domain.Actor, releaseID, artifactID string, raw []byte) (domain.SBOM, error) { + if err := require(actor, ScopeEvidenceWrite); err != nil { + return domain.SBOM{}, err + } if len(raw) == 0 || len(raw) > 20<<20 { return domain.SBOM{}, ErrValidation } @@ -456,6 +509,16 @@ func (l *Ledger) UploadSPDXSBOM(ctx context.Context, actor domain.Actor, release } components = append(components, domain.SBOMComponent{Name: pkg.Name, Version: pkg.VersionInfo, PURL: purl}) } + l.mu.Lock() + if err := l.ensureScopeLocked(actor.TenantID, "", "", strings.TrimSpace(releaseID)); err != nil { + l.mu.Unlock() + return domain.SBOM{}, err + } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceWrite, resourceRefs{ReleaseID: strings.TrimSpace(releaseID)}); err != nil { + l.mu.Unlock() + return domain.SBOM{}, err + } + l.mu.Unlock() payloadHash := hashBytes(raw) payloadRef, err := l.storePayload(ctx, actor.TenantID, "sbom-spdx", "application/spdx+json", payloadHash, raw) if err != nil { @@ -504,6 +567,12 @@ func (l *Ledger) CreateSBOMDiff(ctx context.Context, actor domain.Actor, in Crea if !bok || !tok || base.TenantID != actor.TenantID || target.TenantID != actor.TenantID { return domain.SBOMDiff{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceRead, resourceRefs{ReleaseID: base.ReleaseID, ArtifactID: base.ArtifactID}); err != nil { + return domain.SBOMDiff{}, err + } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceRead, resourceRefs{ReleaseID: target.ReleaseID, ArtifactID: target.ArtifactID}); err != nil { + return domain.SBOMDiff{}, err + } added, removed, unchanged := diffComponents(base.Components, target.Components) diff := domain.SBOMDiff{ ID: newID("sdiff"), @@ -536,6 +605,9 @@ func (l *Ledger) CreateSBOMDiff(ctx context.Context, actor domain.Actor, in Crea } func (l *Ledger) UploadCycloneDXVEX(ctx context.Context, actor domain.Actor, releaseID, artifactID string, raw []byte) (domain.VEXDocument, error) { + if err := require(actor, ScopeEvidenceWrite); err != nil { + return domain.VEXDocument{}, err + } if len(raw) == 0 || len(raw) > 20<<20 { return domain.VEXDocument{}, ErrValidation } @@ -555,6 +627,16 @@ func (l *Ledger) UploadCycloneDXVEX(ctx context.Context, actor domain.Actor, rel if err := strictDecode(raw, &doc); err != nil || strings.ToLower(doc.BOMFormat) != "cyclonedx" || len(doc.Vulnerabilities) == 0 { return domain.VEXDocument{}, ErrValidation } + l.mu.Lock() + if err := l.ensureScopeLocked(actor.TenantID, "", "", strings.TrimSpace(releaseID)); err != nil { + l.mu.Unlock() + return domain.VEXDocument{}, err + } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceWrite, resourceRefs{ReleaseID: strings.TrimSpace(releaseID)}); err != nil { + l.mu.Unlock() + return domain.VEXDocument{}, err + } + l.mu.Unlock() statusSummary := map[string]int{} payloadHash := hashBytes(raw) payloadRef, err := l.storePayload(ctx, actor.TenantID, "vex-cyclonedx", "application/vnd.cyclonedx+json", payloadHash, raw) @@ -616,6 +698,9 @@ func (l *Ledger) RecordVulnerabilityWorkflow(ctx context.Context, actor domain.A if !ok { return domain.VulnerabilityWorkflowRecord{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeSecurityWrite, resourceRefs{ReleaseID: scan.ReleaseID}); err != nil { + return domain.VulnerabilityWorkflowRecord{}, err + } record := domain.VulnerabilityWorkflowRecord{ID: newID("vw"), TenantID: actor.TenantID, FindingID: in.FindingID, ReleaseID: scan.ReleaseID, Action: in.Action, Reason: in.Reason, ActorID: actorID(actor), SchemaVersion: "vulnerability-workflow.v1.0.0", CreatedAt: l.now()} l.vulnWorkflow[record.ID] = record _, _ = l.appendChainLocked(actor.TenantID, "vulnerability_workflow."+record.Action, "vulnerability_finding", in.FindingID, actorType(actor), actorID(actor), "", "") @@ -634,6 +719,15 @@ func (l *Ledger) VulnerabilityPostureReport(ctx context.Context, actor domain.Ac } l.mu.Lock() defer l.mu.Unlock() + if strings.TrimSpace(releaseID) != "" { + release, ok := l.releases[strings.TrimSpace(releaseID)] + if !ok || release.TenantID != actor.TenantID { + return domain.VulnerabilityPostureReport{}, ErrNotFound + } + if err := l.authorizeResourceLocked(actor, ScopeSecurityRead, resourceRefs{ProductID: release.ProductID, ReleaseID: release.ID}); err != nil { + return domain.VulnerabilityPostureReport{}, err + } + } summary := map[string]int{} openCritical := 0 for _, scan := range l.scans { @@ -664,6 +758,12 @@ func (l *Ledger) CreateContractDiff(ctx context.Context, actor domain.Actor, in if !bok || !tok || base.TenantID != actor.TenantID || target.TenantID != actor.TenantID || base.ProductID != target.ProductID { return domain.ContractDiff{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceRead, resourceRefs{ProductID: base.ProductID, ReleaseID: base.ReleaseID}); err != nil { + return domain.ContractDiff{}, err + } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceRead, resourceRefs{ProductID: target.ProductID, ReleaseID: target.ReleaseID}); err != nil { + return domain.ContractDiff{}, err + } result := "unchanged" breaking, nonBreaking := []string{}, []string{} if base.Hash != target.Hash { @@ -734,6 +834,9 @@ func (l *Ledger) EvaluateCustomPolicy(ctx context.Context, actor domain.Actor, p if !ok || !rok || policy.TenantID != actor.TenantID || release.TenantID != actor.TenantID { return domain.CustomPolicyEvaluation{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopePolicyRead, resourceRefs{ProductID: release.ProductID, ReleaseID: release.ID}); err != nil { + return domain.CustomPolicyEvaluation{}, err + } checks := []domain.PolicyCheck{} result := "passed" for _, rule := range policy.Rules { diff --git a/internal/app/vex.go b/internal/app/vex.go index 9e6fd4d..38ef193 100644 --- a/internal/app/vex.go +++ b/internal/app/vex.go @@ -91,6 +91,10 @@ func (l *Ledger) UploadVEX(ctx context.Context, actor domain.Actor, releaseID, a return domain.VEXDocument{}, ErrNotFound } } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceWrite, resourceRefs{ReleaseID: releaseID}); err != nil { + l.mu.Unlock() + return domain.VEXDocument{}, err + } l.mu.Unlock() payloadHash := hashBytes(raw) @@ -177,6 +181,9 @@ func (l *Ledger) GetVEXDocument(ctx context.Context, actor domain.Actor, id stri if !ok || vex.TenantID != actor.TenantID { return domain.VEXDocument{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceRead, resourceRefs{ReleaseID: vex.ReleaseID}); err != nil { + return domain.VEXDocument{}, err + } return vex, nil } @@ -196,6 +203,9 @@ func (l *Ledger) CreateVulnerabilityDecision(ctx context.Context, actor domain.A if !ok { return domain.VulnerabilityDecision{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceWrite, resourceRefs{ReleaseID: scan.ReleaseID}); err != nil { + return domain.VulnerabilityDecision{}, err + } decision := l.createDecisionLocked(actor.TenantID, scan, finding, in, "api", actor.KeyID, "", "") l.decisions[decision.ID] = decision _, _ = l.appendChainLocked(actor.TenantID, "vulnerability_decision.created", "vulnerability_finding", finding.ID, "api_key", actor.KeyID, "", "") @@ -225,6 +235,9 @@ func (l *Ledger) CreateException(ctx context.Context, actor domain.Actor, in Cre if !ok || release.TenantID != actor.TenantID { return domain.Exception{}, ErrNotFound } + if err := l.authorizeResourceLocked(actor, ScopeReleaseWrite, resourceRefs{ProductID: release.ProductID, ReleaseID: release.ID}); err != nil { + return domain.Exception{}, err + } if in.FindingID != "" { scan, _, ok := l.findFindingLocked(actor.TenantID, in.FindingID) if !ok || scan.ReleaseID != in.ReleaseID { @@ -274,6 +287,9 @@ func (l *Ledger) ListExceptions(ctx context.Context, actor domain.Actor, release if releaseID != "" && exception.ReleaseID != releaseID { continue } + if !l.resourceAllowedLocked(actor, ScopeVerifyRead, resourceRefs{ReleaseID: exception.ReleaseID}) { + continue + } out = append(out, exception) } sort.Slice(out, func(i, j int) bool { return out[i].CreatedAt.Before(out[j].CreatedAt) }) @@ -296,6 +312,9 @@ func (l *Ledger) ApproveException(ctx context.Context, actor domain.Actor, id st if !exception.ExpiresAt.After(l.now()) { return domain.Exception{}, ErrConflict } + if err := l.authorizeResourceLocked(actor, ScopeReleaseWrite, resourceRefs{ReleaseID: exception.ReleaseID}); err != nil { + return domain.Exception{}, err + } if exception.Approved { return exception, nil } diff --git a/internal/domain/domain.go b/internal/domain/domain.go index e589dc6..4b76e98 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -741,17 +741,20 @@ type RetentionReport struct { } type CustomerPortalAccess struct { - ID string `json:"id"` - TenantID string `json:"tenant_id"` - PackageID string `json:"package_id"` - CustomerName string `json:"customer_name"` - Prefix string `json:"prefix"` - ExpiresAt time.Time `json:"expires_at"` - RevokedAt *time.Time `json:"revoked_at,omitempty"` - AccessCount int `json:"access_count"` - SchemaVersion string `json:"schema_version"` - CreatedAt time.Time `json:"created_at"` - Hash string `json:"-"` + ID string `json:"id"` + TenantID string `json:"tenant_id"` + PackageID string `json:"package_id"` + CustomerName string `json:"customer_name"` + Prefix string `json:"prefix"` + ExpiresAt time.Time `json:"expires_at"` + RevokedAt *time.Time `json:"revoked_at,omitempty"` + AccessCount int `json:"access_count"` + FailedAccessCount int `json:"failed_access_count"` + LastAccessedAt *time.Time `json:"last_accessed_at,omitempty"` + LastFailedAt *time.Time `json:"last_failed_at,omitempty"` + SchemaVersion string `json:"schema_version"` + CreatedAt time.Time `json:"created_at"` + Hash string `json:"-"` } type QuestionnaireTemplate struct { diff --git a/migrations/20260528000800_customer_portal_access_counters.down.sql b/migrations/20260528000800_customer_portal_access_counters.down.sql new file mode 100644 index 0000000..8e0f93d --- /dev/null +++ b/migrations/20260528000800_customer_portal_access_counters.down.sql @@ -0,0 +1,4 @@ +ALTER TABLE customer_portal_access + DROP COLUMN IF EXISTS last_failed_at, + DROP COLUMN IF EXISTS last_accessed_at, + DROP COLUMN IF EXISTS failed_access_count; diff --git a/migrations/20260528000800_customer_portal_access_counters.up.sql b/migrations/20260528000800_customer_portal_access_counters.up.sql new file mode 100644 index 0000000..fa2f020 --- /dev/null +++ b/migrations/20260528000800_customer_portal_access_counters.up.sql @@ -0,0 +1,4 @@ +ALTER TABLE customer_portal_access + ADD COLUMN IF NOT EXISTS failed_access_count integer NOT NULL DEFAULT 0, + ADD COLUMN IF NOT EXISTS last_accessed_at timestamptz, + ADD COLUMN IF NOT EXISTS last_failed_at timestamptz; From 47054d0334c500895d51bb9d273c5078f93a2776 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sat, 23 May 2026 10:22:57 +0300 Subject: [PATCH 003/287] feat(worker): validate outbox job side effects --- cmd/evydence-worker/main.go | 95 ++++++++++++++++++++++++++++++-- cmd/evydence-worker/main_test.go | 38 +++++++++++-- docs/README.md | 1 + docs/reference/worker-outbox.md | 23 ++++++++ 4 files changed, 149 insertions(+), 8 deletions(-) create mode 100644 docs/reference/worker-outbox.md diff --git a/cmd/evydence-worker/main.go b/cmd/evydence-worker/main.go index 0d14fec..26e287b 100644 --- a/cmd/evydence-worker/main.go +++ b/cmd/evydence-worker/main.go @@ -10,6 +10,7 @@ import ( "time" "github.com/aatuh/evydence/internal/adapters/postgres" + "github.com/aatuh/evydence/internal/app" ) func main() { @@ -56,7 +57,7 @@ func run() error { } for _, job := range jobs { log.Printf("processing outbox job id=%s kind=%s subject_type=%s subject_id=%s attempt=%d", job.ID, job.Kind, job.SubjectType, job.SubjectID, job.Attempts) - if err := processJob(ctx, job); err != nil { + if err := processJob(ctx, store, job); err != nil { log.Printf("outbox job failed id=%s kind=%s: %v", job.ID, job.Kind, err) if failErr := store.FailJob(ctx, job.ID, err); failErr != nil { log.Printf("record outbox failure failed id=%s: %v", job.ID, failErr) @@ -70,18 +71,104 @@ func run() error { } } -func processJob(ctx context.Context, job postgres.ClaimedJob) error { +type jobStateLoader interface { + LoadState(context.Context) (app.PersistedState, bool, error) +} + +func processJob(ctx context.Context, state jobStateLoader, job postgres.ClaimedJob) error { if err := ctx.Err(); err != nil { return err } + if state == nil { + return errors.New("outbox job handler requires durable state") + } + snapshot, ok, err := state.LoadState(ctx) + if err != nil { + return errors.New("load durable state for outbox job") + } + if !ok { + return errors.New("durable state is not initialized") + } switch job.Kind { - case "parse_sbom", "parse_vulnerability_scan", "parse_openapi_contract", "parse_vex", "sign_bundle", "verify_subject", "verify_attestation": - return errors.New("outbox job handler is not configured") + case "parse_sbom": + sbom, ok := snapshot.SBOMs[job.SubjectID] + if !ok || sbom.TenantID != job.TenantID { + return errors.New("parsed sbom is not available in durable state") + } + return requirePayloadHash(job, "") + case "parse_vulnerability_scan": + scan, ok := snapshot.Scans[job.SubjectID] + if !ok || scan.TenantID != job.TenantID { + return errors.New("parsed vulnerability scan is not available in durable state") + } + return requirePayloadHash(job, "") + case "parse_openapi_contract": + contract, ok := snapshot.Contracts[job.SubjectID] + if !ok || contract.TenantID != job.TenantID { + return errors.New("parsed openapi contract is not available in durable state") + } + return requirePayloadHash(job, contract.Hash) + case "parse_vex": + vex, ok := snapshot.VEXDocuments[job.SubjectID] + if !ok || vex.TenantID != job.TenantID { + return errors.New("parsed vex document is not available in durable state") + } + return requirePayloadHash(job, "") + case "sign_bundle": + bundle, ok := snapshot.Bundles[job.SubjectID] + if !ok || bundle.TenantID != job.TenantID { + return errors.New("release bundle is not available in durable state") + } + if len(bundle.SignatureRefs) == 0 { + return errors.New("release bundle signature is missing") + } + return requirePayloadHash(job, bundle.ManifestHash) + case "verify_subject": + resultID := payloadString(job, "result_id") + if resultID == "" { + return errors.New("verification result reference is missing") + } + result, ok := snapshot.Verifications[resultID] + if !ok || result.TenantID != job.TenantID || result.SubjectType != job.SubjectType || result.SubjectID != job.SubjectID { + return errors.New("verification result is not available in durable state") + } + if result.Result == "" { + return errors.New("verification result is incomplete") + } + return nil + case "verify_attestation": + attestation, ok := snapshot.BuildAttestations[job.SubjectID] + if !ok || attestation.TenantID != job.TenantID { + return errors.New("build attestation is not available in durable state") + } + if attestation.VerificationStatus == "" { + return errors.New("build attestation verification status is incomplete") + } + return requirePayloadHash(job, attestation.PayloadHash) default: return errors.New("unsupported outbox job kind") } } +func requirePayloadHash(job postgres.ClaimedJob, recordedHash string) error { + want := payloadString(job, "payload_hash") + if want == "" || recordedHash == "" { + return nil + } + if want != recordedHash { + return errors.New("outbox payload hash does not match durable state") + } + return nil +} + +func payloadString(job postgres.ClaimedJob, key string) string { + if job.Payload == nil { + return "" + } + value, _ := job.Payload[key].(string) + return strings.TrimSpace(value) +} + func envDefault(name, fallback string) string { if value := strings.TrimSpace(os.Getenv(name)); value != "" { return value diff --git a/cmd/evydence-worker/main_test.go b/cmd/evydence-worker/main_test.go index b54c167..1edbbb8 100644 --- a/cmd/evydence-worker/main_test.go +++ b/cmd/evydence-worker/main_test.go @@ -4,11 +4,41 @@ import ( "context" "strings" "testing" + "time" "github.com/aatuh/evydence/internal/adapters/postgres" + "github.com/aatuh/evydence/internal/app" + "github.com/aatuh/evydence/internal/domain" ) -func TestProcessJobFailsClosedForConfiguredButUnhandledJobs(t *testing.T) { +type fakeStateLoader struct { + state app.PersistedState + ok bool + err error +} + +func (f fakeStateLoader) LoadState(context.Context) (app.PersistedState, bool, error) { + return f.state, f.ok, f.err +} + +func TestProcessJobVerifiesConfiguredJobState(t *testing.T) { + job := postgres.ClaimedJob{ + ID: "job_test", + TenantID: "ten_test", + Kind: "verify_subject", + SubjectType: "release_bundle", + SubjectID: "rb_test", + Payload: map[string]any{"result_id": "vr_test", "payload_ref": "object://tenants/ten_test/payloads/raw-secret-name"}, + } + state := app.PersistedState{Verifications: map[string]domain.VerificationResult{ + "vr_test": {ID: "vr_test", TenantID: "ten_test", SubjectType: "release_bundle", SubjectID: "rb_test", Result: "passed", VerifiedAt: time.Now().UTC()}, + }} + if err := processJob(context.Background(), fakeStateLoader{state: state, ok: true}, job); err != nil { + t.Fatalf("process configured verification job: %v", err) + } +} + +func TestProcessJobFailsSafelyWhenDurableStateIsMissing(t *testing.T) { job := postgres.ClaimedJob{ ID: "job_test", TenantID: "ten_test", @@ -17,11 +47,11 @@ func TestProcessJobFailsClosedForConfiguredButUnhandledJobs(t *testing.T) { SubjectID: "sbom_test", Payload: map[string]any{"payload_ref": "object://tenants/ten_test/payloads/sbom/raw-secret-name"}, } - err := processJob(context.Background(), job) + err := processJob(context.Background(), fakeStateLoader{state: app.PersistedState{}, ok: true}, job) if err == nil { t.Fatal("expected recognized unhandled job to fail closed") } - if !strings.Contains(err.Error(), "handler is not configured") { + if !strings.Contains(err.Error(), "parsed sbom is not available") { t.Fatalf("unexpected error: %v", err) } if strings.Contains(err.Error(), "raw-secret-name") || strings.Contains(err.Error(), job.SubjectID) { @@ -30,7 +60,7 @@ func TestProcessJobFailsClosedForConfiguredButUnhandledJobs(t *testing.T) { } func TestProcessJobRejectsUnsupportedKinds(t *testing.T) { - err := processJob(context.Background(), postgres.ClaimedJob{Kind: "unknown", Payload: map[string]any{"token": "secret"}}) + err := processJob(context.Background(), fakeStateLoader{state: app.PersistedState{}, ok: true}, postgres.ClaimedJob{Kind: "unknown", Payload: map[string]any{"token": "secret"}}) if err == nil { t.Fatal("expected unsupported job kind to fail") } diff --git a/docs/README.md b/docs/README.md index 5ce6e04..4220476 100644 --- a/docs/README.md +++ b/docs/README.md @@ -14,6 +14,7 @@ This documentation is organized by task type so roadmap intent and implemented b - [API reference](api.md) describes the implemented `/v1` HTTP surface. - [OpenAPI contract](reference/openapi.md) explains how `openapi.yaml` is generated and checked. +- [Worker outbox contract](reference/worker-outbox.md) documents durable job inputs, idempotency, and safe failure behavior. ## Explanation diff --git a/docs/reference/worker-outbox.md b/docs/reference/worker-outbox.md new file mode 100644 index 0000000..d66a9e4 --- /dev/null +++ b/docs/reference/worker-outbox.md @@ -0,0 +1,23 @@ +# Worker Outbox Contract + +The worker claims PostgreSQL outbox jobs with row locking and retries failed jobs with backoff. Job handlers must be idempotent: retrying a job may verify existing durable state, but must not duplicate evidence, signatures, reports, or audit-chain entries. + +Configured job kinds: + +- `parse_sbom` +- `parse_vulnerability_scan` +- `parse_openapi_contract` +- `parse_vex` +- `sign_bundle` +- `verify_subject` +- `verify_attestation` + +Current behavior is intentionally conservative. The API performs parsing, signing, and verification synchronously before enqueueing jobs. The worker then validates that the expected durable state exists and, when a `payload_hash` is present, that the hash matches the recorded state. Missing state, incomplete verification, missing signatures, hash mismatch, uninitialized storage, and unsupported job kinds fail the job safely. + +Safe logging rules: + +- Log job ID, kind, subject type, and attempt count. +- Do not log raw payload bytes, object paths, bearer tokens, customer portal tokens, private keys, or full provider environment dumps. +- Error messages should describe the failed invariant without echoing subject IDs or raw payload fields. + +This contract supports operations evidence for asynchronous processing. It does not claim external scanner authority, complete parsing coverage, or cryptographic attestation trust unless the relevant trust roots and verification receipts are recorded. From 2981e64861be56ca9f9abae363ece3ea8de54ae2 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sat, 23 May 2026 10:23:04 +0300 Subject: [PATCH 004/287] refactor(http): split operational handlers --- .../adapters/httpapi/identity_handlers.go | 145 +++++++++ internal/adapters/httpapi/ops_handlers.go | 55 ++++ internal/adapters/httpapi/portal_handlers.go | 76 +++++ internal/adapters/httpapi/router.go | 290 ------------------ internal/adapters/httpapi/system_handlers.go | 46 +++ 5 files changed, 322 insertions(+), 290 deletions(-) create mode 100644 internal/adapters/httpapi/identity_handlers.go create mode 100644 internal/adapters/httpapi/ops_handlers.go create mode 100644 internal/adapters/httpapi/portal_handlers.go create mode 100644 internal/adapters/httpapi/system_handlers.go diff --git a/internal/adapters/httpapi/identity_handlers.go b/internal/adapters/httpapi/identity_handlers.go new file mode 100644 index 0000000..a87943d --- /dev/null +++ b/internal/adapters/httpapi/identity_handlers.go @@ -0,0 +1,145 @@ +package httpapi + +import ( + "net/http" + "time" + + "github.com/aatuh/evydence/internal/app" + "github.com/aatuh/evydence/internal/domain" +) + +func (s *Server) instanceAdminSnapshot(w http.ResponseWriter, r *http.Request) { + actor, ok := s.authenticate(w, r) + if !ok { + return + } + snapshot, err := s.ledger.InstanceAdminSnapshot(r.Context(), actor) + if err != nil { + writeProblem(w, r, err) + return + } + writeData(w, http.StatusOK, snapshot) +} + +func (s *Server) createOrganization(w http.ResponseWriter, r *http.Request) { + var req struct { + Name string `json:"name"` + Slug string `json:"slug"` + } + s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + if err := decodeJSON(body, &req); err != nil { + return 0, nil, err + } + org, err := s.ledger.CreateOrganization(r.Context(), actor, app.CreateOrganizationInput{Name: req.Name, Slug: req.Slug}) + return http.StatusCreated, org, err + }) +} + +func (s *Server) createUser(w http.ResponseWriter, r *http.Request) { + var req struct { + OrganizationID string `json:"organization_id"` + Email string `json:"email"` + DisplayName string `json:"display_name"` + } + s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + if err := decodeJSON(body, &req); err != nil { + return 0, nil, err + } + user, err := s.ledger.CreateUser(r.Context(), actor, app.CreateUserInput{OrganizationID: req.OrganizationID, Email: req.Email, DisplayName: req.DisplayName}) + return http.StatusCreated, user, err + }) +} + +func (s *Server) deactivateUser(w http.ResponseWriter, r *http.Request) { + s.create(w, r, func(actor domain.Actor, _ []byte) (int, any, error) { + user, err := s.ledger.DeactivateUser(r.Context(), actor, r.PathValue("id")) + return http.StatusOK, user, err + }) +} + +func (s *Server) createRoleBinding(w http.ResponseWriter, r *http.Request) { + var req struct { + SubjectType string `json:"subject_type"` + SubjectID string `json:"subject_id"` + Role string `json:"role"` + ResourceType string `json:"resource_type"` + ResourceID string `json:"resource_id"` + } + s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + if err := decodeJSON(body, &req); err != nil { + return 0, nil, err + } + binding, err := s.ledger.CreateRoleBinding(r.Context(), actor, app.CreateRoleBindingInput{SubjectType: req.SubjectType, SubjectID: req.SubjectID, Role: req.Role, ResourceType: req.ResourceType, ResourceID: req.ResourceID}) + return http.StatusCreated, binding, err + }) +} + +func (s *Server) listRoleBindings(w http.ResponseWriter, r *http.Request) { + actor, ok := s.authenticate(w, r) + if !ok { + return + } + bindings, err := s.ledger.ListRoleBindings(r.Context(), actor) + if err != nil { + writeProblem(w, r, err) + return + } + writeData(w, http.StatusOK, bindings) +} + +func (s *Server) createSSOProvider(w http.ResponseWriter, r *http.Request) { + var req struct { + Name string `json:"name"` + Type string `json:"type"` + Issuer string `json:"issuer"` + ClientID string `json:"client_id"` + GroupsClaim string `json:"groups_claim"` + RoleMapping map[string]string `json:"role_mapping"` + } + s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + if err := decodeJSON(body, &req); err != nil { + return 0, nil, err + } + provider, err := s.ledger.CreateSSOProvider(r.Context(), actor, app.CreateSSOProviderInput{Name: req.Name, Type: req.Type, Issuer: req.Issuer, ClientID: req.ClientID, GroupsClaim: req.GroupsClaim, RoleMapping: req.RoleMapping}) + return http.StatusCreated, provider, err + }) +} + +func (s *Server) linkSSOIdentity(w http.ResponseWriter, r *http.Request) { + var req struct { + UserID string `json:"user_id"` + ProviderID string `json:"provider_id"` + Subject string `json:"subject"` + Email string `json:"email"` + Verified bool `json:"verified"` + } + s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + if err := decodeJSON(body, &req); err != nil { + return 0, nil, err + } + link, err := s.ledger.LinkSSOIdentity(r.Context(), actor, app.LinkSSOIdentityInput{UserID: req.UserID, ProviderID: req.ProviderID, Subject: req.Subject, Email: req.Email, Verified: req.Verified}) + return http.StatusCreated, link, err + }) +} + +func (s *Server) createSSOSession(w http.ResponseWriter, r *http.Request) { + var req struct { + UserID string `json:"user_id"` + ProviderID string `json:"provider_id"` + ExpiresAt time.Time `json:"expires_at"` + } + s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + if err := decodeJSON(body, &req); err != nil { + return 0, nil, err + } + session, secret, err := s.ledger.CreateSSOSession(r.Context(), actor, app.CreateSSOSessionInput{UserID: req.UserID, ProviderID: req.ProviderID, ExpiresAt: req.ExpiresAt}) + return http.StatusCreated, map[string]any{"session": session, "secret": secret}, err + }) +} + +func (s *Server) revokeSSOSession(w http.ResponseWriter, r *http.Request) { + s.create(w, r, func(actor domain.Actor, _ []byte) (int, any, error) { + session, err := s.ledger.RevokeSSOSession(r.Context(), actor, r.PathValue("id")) + return http.StatusOK, session, err + }) +} diff --git a/internal/adapters/httpapi/ops_handlers.go b/internal/adapters/httpapi/ops_handlers.go new file mode 100644 index 0000000..2d07cc6 --- /dev/null +++ b/internal/adapters/httpapi/ops_handlers.go @@ -0,0 +1,55 @@ +package httpapi + +import ( + "net/http" + "time" + + "github.com/aatuh/evydence/internal/app" + "github.com/aatuh/evydence/internal/domain" +) + +func (s *Server) createLegalHold(w http.ResponseWriter, r *http.Request) { + var req struct { + ScopeType string `json:"scope_type"` + ScopeID string `json:"scope_id"` + Reason string `json:"reason"` + Owner string `json:"owner"` + } + s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + if err := decodeJSON(body, &req); err != nil { + return 0, nil, err + } + hold, err := s.ledger.CreateLegalHold(r.Context(), actor, app.CreateLegalHoldInput{ScopeType: req.ScopeType, ScopeID: req.ScopeID, Reason: req.Reason, Owner: req.Owner}) + return http.StatusCreated, hold, err + }) +} + +func (s *Server) createRetentionOverride(w http.ResponseWriter, r *http.Request) { + var req struct { + ScopeType string `json:"scope_type"` + ScopeID string `json:"scope_id"` + RetentionUntil time.Time `json:"retention_until"` + Reason string `json:"reason"` + Owner string `json:"owner"` + } + s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + if err := decodeJSON(body, &req); err != nil { + return 0, nil, err + } + override, err := s.ledger.CreateRetentionOverride(r.Context(), actor, app.CreateRetentionOverrideInput{ScopeType: req.ScopeType, ScopeID: req.ScopeID, RetentionUntil: req.RetentionUntil, Reason: req.Reason, Owner: req.Owner}) + return http.StatusCreated, override, err + }) +} + +func (s *Server) retentionReport(w http.ResponseWriter, r *http.Request) { + actor, ok := s.authenticate(w, r) + if !ok { + return + } + report, err := s.ledger.RetentionReport(r.Context(), actor, r.URL.Query().Get("scope_type"), r.URL.Query().Get("scope_id")) + if err != nil { + writeProblem(w, r, err) + return + } + writeData(w, http.StatusOK, report) +} diff --git a/internal/adapters/httpapi/portal_handlers.go b/internal/adapters/httpapi/portal_handlers.go new file mode 100644 index 0000000..9264b31 --- /dev/null +++ b/internal/adapters/httpapi/portal_handlers.go @@ -0,0 +1,76 @@ +package httpapi + +import ( + "net/http" + "time" + + "github.com/aatuh/evydence/internal/app" + "github.com/aatuh/evydence/internal/domain" +) + +func (s *Server) createCustomerPortalAccess(w http.ResponseWriter, r *http.Request) { + var req struct { + PackageID string `json:"package_id"` + CustomerName string `json:"customer_name"` + ExpiresAt time.Time `json:"expires_at"` + } + s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + if err := decodeJSON(body, &req); err != nil { + return 0, nil, err + } + access, secret, err := s.ledger.CreateCustomerPortalAccess(r.Context(), actor, app.CreateCustomerPortalAccessInput{PackageID: req.PackageID, CustomerName: req.CustomerName, ExpiresAt: req.ExpiresAt}) + return http.StatusCreated, map[string]any{"access": access, "secret": secret}, err + }) +} + +func (s *Server) accessCustomerPortalPackage(w http.ResponseWriter, r *http.Request) { + var req struct { + Token string `json:"token"` + } + body, err := readBody(r) + if err != nil { + writeProblem(w, r, err) + return + } + if err := decodeJSON(body, &req); err != nil { + writeProblem(w, r, err) + return + } + pkg, err := s.ledger.AccessCustomerPortalPackage(r.Context(), req.Token) + if err != nil { + writeProblem(w, r, err) + return + } + writeData(w, http.StatusOK, pkg) +} + +func (s *Server) createQuestionnaireTemplate(w http.ResponseWriter, r *http.Request) { + var req struct { + Name string `json:"name"` + Version string `json:"version"` + Questions []domain.QuestionnaireQuestion `json:"questions"` + } + s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + if err := decodeJSON(body, &req); err != nil { + return 0, nil, err + } + tpl, err := s.ledger.CreateQuestionnaireTemplate(r.Context(), actor, app.CreateQuestionnaireTemplateInput{Name: req.Name, Version: req.Version, Questions: req.Questions}) + return http.StatusCreated, tpl, err + }) +} + +func (s *Server) createQuestionnairePackage(w http.ResponseWriter, r *http.Request) { + var req struct { + TemplateID string `json:"template_id"` + PackageID string `json:"package_id"` + ProductID string `json:"product_id"` + ReleaseID string `json:"release_id"` + } + s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + if err := decodeJSON(body, &req); err != nil { + return 0, nil, err + } + pkg, err := s.ledger.CreateQuestionnairePackage(r.Context(), actor, app.CreateQuestionnairePackageInput{TemplateID: req.TemplateID, PackageID: req.PackageID, ProductID: req.ProductID, ReleaseID: req.ReleaseID}) + return http.StatusCreated, pkg, err + }) +} diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index 0179497..b1587a6 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -216,183 +216,6 @@ func (s *Server) registerRoutes() error { return nil } -func (s *Server) health(w http.ResponseWriter, _ *http.Request) { - writeData(w, http.StatusOK, map[string]string{"status": "ok"}) -} - -func (s *Server) ready(w http.ResponseWriter, r *http.Request) { - status, err := s.ledger.ReadinessStatus(r.Context()) - if err != nil { - writeProblem(w, r, err) - return - } - writeData(w, http.StatusOK, status) -} - -func (s *Server) metrics(w http.ResponseWriter, r *http.Request) { - actor, ok := s.authenticate(w, r) - if !ok { - return - } - metrics, err := s.ledger.Metrics(r.Context(), actor) - if err != nil { - writeProblem(w, r, err) - return - } - writeData(w, http.StatusOK, metrics) -} - -func (s *Server) version(w http.ResponseWriter, _ *http.Request) { - writeData(w, http.StatusOK, map[string]string{"version": "dev"}) -} - -func (s *Server) openapi(w http.ResponseWriter, _ *http.Request) { - doc, err := s.OpenAPI() - if err != nil { - writeProblem(w, nil, err) - return - } - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - _, _ = w.Write(doc) -} - -func (s *Server) instanceAdminSnapshot(w http.ResponseWriter, r *http.Request) { - actor, ok := s.authenticate(w, r) - if !ok { - return - } - snapshot, err := s.ledger.InstanceAdminSnapshot(r.Context(), actor) - if err != nil { - writeProblem(w, r, err) - return - } - writeData(w, http.StatusOK, snapshot) -} - -func (s *Server) createOrganization(w http.ResponseWriter, r *http.Request) { - var req struct { - Name string `json:"name"` - Slug string `json:"slug"` - } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { - if err := decodeJSON(body, &req); err != nil { - return 0, nil, err - } - org, err := s.ledger.CreateOrganization(r.Context(), actor, app.CreateOrganizationInput{Name: req.Name, Slug: req.Slug}) - return http.StatusCreated, org, err - }) -} - -func (s *Server) createUser(w http.ResponseWriter, r *http.Request) { - var req struct { - OrganizationID string `json:"organization_id"` - Email string `json:"email"` - DisplayName string `json:"display_name"` - } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { - if err := decodeJSON(body, &req); err != nil { - return 0, nil, err - } - user, err := s.ledger.CreateUser(r.Context(), actor, app.CreateUserInput{OrganizationID: req.OrganizationID, Email: req.Email, DisplayName: req.DisplayName}) - return http.StatusCreated, user, err - }) -} - -func (s *Server) deactivateUser(w http.ResponseWriter, r *http.Request) { - s.create(w, r, func(actor domain.Actor, _ []byte) (int, any, error) { - user, err := s.ledger.DeactivateUser(r.Context(), actor, r.PathValue("id")) - return http.StatusOK, user, err - }) -} - -func (s *Server) createRoleBinding(w http.ResponseWriter, r *http.Request) { - var req struct { - SubjectType string `json:"subject_type"` - SubjectID string `json:"subject_id"` - Role string `json:"role"` - ResourceType string `json:"resource_type"` - ResourceID string `json:"resource_id"` - } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { - if err := decodeJSON(body, &req); err != nil { - return 0, nil, err - } - binding, err := s.ledger.CreateRoleBinding(r.Context(), actor, app.CreateRoleBindingInput{SubjectType: req.SubjectType, SubjectID: req.SubjectID, Role: req.Role, ResourceType: req.ResourceType, ResourceID: req.ResourceID}) - return http.StatusCreated, binding, err - }) -} - -func (s *Server) listRoleBindings(w http.ResponseWriter, r *http.Request) { - actor, ok := s.authenticate(w, r) - if !ok { - return - } - bindings, err := s.ledger.ListRoleBindings(r.Context(), actor) - if err != nil { - writeProblem(w, r, err) - return - } - writeData(w, http.StatusOK, bindings) -} - -func (s *Server) createSSOProvider(w http.ResponseWriter, r *http.Request) { - var req struct { - Name string `json:"name"` - Type string `json:"type"` - Issuer string `json:"issuer"` - ClientID string `json:"client_id"` - GroupsClaim string `json:"groups_claim"` - RoleMapping map[string]string `json:"role_mapping"` - } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { - if err := decodeJSON(body, &req); err != nil { - return 0, nil, err - } - provider, err := s.ledger.CreateSSOProvider(r.Context(), actor, app.CreateSSOProviderInput{Name: req.Name, Type: req.Type, Issuer: req.Issuer, ClientID: req.ClientID, GroupsClaim: req.GroupsClaim, RoleMapping: req.RoleMapping}) - return http.StatusCreated, provider, err - }) -} - -func (s *Server) linkSSOIdentity(w http.ResponseWriter, r *http.Request) { - var req struct { - UserID string `json:"user_id"` - ProviderID string `json:"provider_id"` - Subject string `json:"subject"` - Email string `json:"email"` - Verified bool `json:"verified"` - } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { - if err := decodeJSON(body, &req); err != nil { - return 0, nil, err - } - link, err := s.ledger.LinkSSOIdentity(r.Context(), actor, app.LinkSSOIdentityInput{UserID: req.UserID, ProviderID: req.ProviderID, Subject: req.Subject, Email: req.Email, Verified: req.Verified}) - return http.StatusCreated, link, err - }) -} - -func (s *Server) createSSOSession(w http.ResponseWriter, r *http.Request) { - var req struct { - UserID string `json:"user_id"` - ProviderID string `json:"provider_id"` - ExpiresAt time.Time `json:"expires_at"` - } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { - if err := decodeJSON(body, &req); err != nil { - return 0, nil, err - } - session, secret, err := s.ledger.CreateSSOSession(r.Context(), actor, app.CreateSSOSessionInput{UserID: req.UserID, ProviderID: req.ProviderID, ExpiresAt: req.ExpiresAt}) - return http.StatusCreated, map[string]any{"session": session, "secret": secret}, err - }) -} - -func (s *Server) revokeSSOSession(w http.ResponseWriter, r *http.Request) { - s.create(w, r, func(actor domain.Actor, _ []byte) (int, any, error) { - session, err := s.ledger.RevokeSSOSession(r.Context(), actor, r.PathValue("id")) - return http.StatusOK, session, err - }) -} - func (s *Server) createCollector(w http.ResponseWriter, r *http.Request) { var req struct { Name string `json:"name"` @@ -1332,73 +1155,6 @@ func (s *Server) getCustomerPackage(w http.ResponseWriter, r *http.Request) { writeData(w, http.StatusOK, pkg) } -func (s *Server) createCustomerPortalAccess(w http.ResponseWriter, r *http.Request) { - var req struct { - PackageID string `json:"package_id"` - CustomerName string `json:"customer_name"` - ExpiresAt time.Time `json:"expires_at"` - } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { - if err := decodeJSON(body, &req); err != nil { - return 0, nil, err - } - access, secret, err := s.ledger.CreateCustomerPortalAccess(r.Context(), actor, app.CreateCustomerPortalAccessInput{PackageID: req.PackageID, CustomerName: req.CustomerName, ExpiresAt: req.ExpiresAt}) - return http.StatusCreated, map[string]any{"access": access, "secret": secret}, err - }) -} - -func (s *Server) accessCustomerPortalPackage(w http.ResponseWriter, r *http.Request) { - var req struct { - Token string `json:"token"` - } - body, err := readBody(r) - if err != nil { - writeProblem(w, r, err) - return - } - if err := decodeJSON(body, &req); err != nil { - writeProblem(w, r, err) - return - } - pkg, err := s.ledger.AccessCustomerPortalPackage(r.Context(), req.Token) - if err != nil { - writeProblem(w, r, err) - return - } - writeData(w, http.StatusOK, pkg) -} - -func (s *Server) createQuestionnaireTemplate(w http.ResponseWriter, r *http.Request) { - var req struct { - Name string `json:"name"` - Version string `json:"version"` - Questions []domain.QuestionnaireQuestion `json:"questions"` - } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { - if err := decodeJSON(body, &req); err != nil { - return 0, nil, err - } - tpl, err := s.ledger.CreateQuestionnaireTemplate(r.Context(), actor, app.CreateQuestionnaireTemplateInput{Name: req.Name, Version: req.Version, Questions: req.Questions}) - return http.StatusCreated, tpl, err - }) -} - -func (s *Server) createQuestionnairePackage(w http.ResponseWriter, r *http.Request) { - var req struct { - TemplateID string `json:"template_id"` - PackageID string `json:"package_id"` - ProductID string `json:"product_id"` - ReleaseID string `json:"release_id"` - } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { - if err := decodeJSON(body, &req); err != nil { - return 0, nil, err - } - pkg, err := s.ledger.CreateQuestionnairePackage(r.Context(), actor, app.CreateQuestionnairePackageInput{TemplateID: req.TemplateID, PackageID: req.PackageID, ProductID: req.ProductID, ReleaseID: req.ReleaseID}) - return http.StatusCreated, pkg, err - }) -} - func (s *Server) securityReviewPackageReport(w http.ResponseWriter, r *http.Request) { actor, ok := s.authenticate(w, r) if !ok { @@ -2177,52 +1933,6 @@ func (s *Server) verifyObjectRetentionPolicy(w http.ResponseWriter, r *http.Requ }) } -func (s *Server) createLegalHold(w http.ResponseWriter, r *http.Request) { - var req struct { - ScopeType string `json:"scope_type"` - ScopeID string `json:"scope_id"` - Reason string `json:"reason"` - Owner string `json:"owner"` - } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { - if err := decodeJSON(body, &req); err != nil { - return 0, nil, err - } - hold, err := s.ledger.CreateLegalHold(r.Context(), actor, app.CreateLegalHoldInput{ScopeType: req.ScopeType, ScopeID: req.ScopeID, Reason: req.Reason, Owner: req.Owner}) - return http.StatusCreated, hold, err - }) -} - -func (s *Server) createRetentionOverride(w http.ResponseWriter, r *http.Request) { - var req struct { - ScopeType string `json:"scope_type"` - ScopeID string `json:"scope_id"` - RetentionUntil time.Time `json:"retention_until"` - Reason string `json:"reason"` - Owner string `json:"owner"` - } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { - if err := decodeJSON(body, &req); err != nil { - return 0, nil, err - } - override, err := s.ledger.CreateRetentionOverride(r.Context(), actor, app.CreateRetentionOverrideInput{ScopeType: req.ScopeType, ScopeID: req.ScopeID, RetentionUntil: req.RetentionUntil, Reason: req.Reason, Owner: req.Owner}) - return http.StatusCreated, override, err - }) -} - -func (s *Server) retentionReport(w http.ResponseWriter, r *http.Request) { - actor, ok := s.authenticate(w, r) - if !ok { - return - } - report, err := s.ledger.RetentionReport(r.Context(), actor, r.URL.Query().Get("scope_type"), r.URL.Query().Get("scope_id")) - if err != nil { - writeProblem(w, r, err) - return - } - writeData(w, http.StatusOK, report) -} - func (s *Server) generateBackupManifest(w http.ResponseWriter, r *http.Request) { s.create(w, r, func(actor domain.Actor, _ []byte) (int, any, error) { manifest, err := s.ledger.GenerateBackupManifest(r.Context(), actor) diff --git a/internal/adapters/httpapi/system_handlers.go b/internal/adapters/httpapi/system_handlers.go new file mode 100644 index 0000000..03e4dfe --- /dev/null +++ b/internal/adapters/httpapi/system_handlers.go @@ -0,0 +1,46 @@ +package httpapi + +import ( + "net/http" +) + +func (s *Server) health(w http.ResponseWriter, _ *http.Request) { + writeData(w, http.StatusOK, map[string]string{"status": "ok"}) +} + +func (s *Server) ready(w http.ResponseWriter, r *http.Request) { + status, err := s.ledger.ReadinessStatus(r.Context()) + if err != nil { + writeProblem(w, r, err) + return + } + writeData(w, http.StatusOK, status) +} + +func (s *Server) metrics(w http.ResponseWriter, r *http.Request) { + actor, ok := s.authenticate(w, r) + if !ok { + return + } + metrics, err := s.ledger.Metrics(r.Context(), actor) + if err != nil { + writeProblem(w, r, err) + return + } + writeData(w, http.StatusOK, metrics) +} + +func (s *Server) version(w http.ResponseWriter, _ *http.Request) { + writeData(w, http.StatusOK, map[string]string{"version": "dev"}) +} + +func (s *Server) openapi(w http.ResponseWriter, _ *http.Request) { + doc, err := s.OpenAPI() + if err != nil { + writeProblem(w, nil, err) + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, _ = w.Write(doc) +} From fde39a1cb58f7f6ad038c0e869a77f4ac295e6db Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sat, 23 May 2026 10:23:13 +0300 Subject: [PATCH 005/287] chore(release): summarize validation gates --- Makefile | 18 ++++++++++++++++++ cmd/evydence-api/main.go | 31 +++++++++++++++++++++---------- cmd/evydence-api/main_test.go | 22 ++++++++++++++++++++++ docs/operations.md | 8 ++++---- 4 files changed, 65 insertions(+), 14 deletions(-) create mode 100644 cmd/evydence-api/main_test.go diff --git a/Makefile b/Makefile index 60c64b6..cc9c636 100644 --- a/Makefile +++ b/Makefile @@ -60,6 +60,7 @@ docs-check: ## Validate canonical docs exist and avoid forbidden product claims @test -f docs/tutorials/getting-started.md @test -f docs/how-to/install-and-operate.md @test -f docs/reference/openapi.md + @test -f docs/reference/worker-outbox.md @test -f docs/explanation/trust-model.md @! grep -R -i "automatically compliant\|certified secure\|legally sufficient\|SBOM is complete\|all vulnerabilities detected" README.md docs @@ -98,6 +99,23 @@ release-check: ## Release validation with security, race, and configured live in @$(MAKE) test-race @$(MAKE) live-postgres-check @$(MAKE) postgres-integration-test + @mkdir -p tmp + @{ \ + echo "evydence release-check summary"; \ + echo "generated_at=$$(date -u +%Y-%m-%dT%H:%M:%SZ)"; \ + echo "finalize=passed"; \ + echo "lint=passed"; \ + echo "gosec=passed"; \ + echo "govulncheck=passed"; \ + echo "race=passed"; \ + if [ -n "$$EVYDENCE_TEST_DATABASE_URL" ]; then \ + echo "live_postgres=passed"; \ + echo "postgres_integration=passed"; \ + else \ + echo "live_postgres=skipped EVYDENCE_TEST_DATABASE_URL unset"; \ + echo "postgres_integration=skipped EVYDENCE_TEST_DATABASE_URL unset"; \ + fi; \ + } | tee tmp/release-check-summary.txt compose-up: ## Start local dependencies @docker compose up -d diff --git a/cmd/evydence-api/main.go b/cmd/evydence-api/main.go index 154cec8..9a8ac6e 100644 --- a/cmd/evydence-api/main.go +++ b/cmd/evydence-api/main.go @@ -29,16 +29,8 @@ func run() error { production := strings.EqualFold(os.Getenv("ENV"), "production") databaseURL := strings.TrimSpace(os.Getenv("EVYDENCE_DATABASE_URL")) pepper := strings.TrimSpace(os.Getenv("EVYDENCE_API_KEY_PEPPER")) - if production { - if databaseURL == "" { - return errors.New("production requires EVYDENCE_DATABASE_URL") - } - if pepper == "" || pepper == "local-dev-pepper-change-me" { - return errors.New("production requires a non-default EVYDENCE_API_KEY_PEPPER") - } - if strings.TrimSpace(os.Getenv("EVYDENCE_SIGNING_KEY_MODE")) != "external" { - return errors.New("production requires EVYDENCE_SIGNING_KEY_MODE=external; plaintext local signing keys are dev-only") - } + if err := validateRuntimeConfig(production, databaseURL, pepper, strings.TrimSpace(os.Getenv("EVYDENCE_SIGNING_KEY_MODE")), strings.EqualFold(os.Getenv("EVYDENCE_PRINT_BOOTSTRAP_SECRET"), "true")); err != nil { + return err } cfg := app.Config{APIKeyPepper: pepper} var closeStore func() @@ -102,6 +94,25 @@ func run() error { return httpServer.ListenAndServe() } +func validateRuntimeConfig(production bool, databaseURL, pepper, signingKeyMode string, printBootstrapSecret bool) error { + if !production { + return nil + } + if strings.TrimSpace(databaseURL) == "" { + return errors.New("production requires EVYDENCE_DATABASE_URL") + } + if strings.TrimSpace(pepper) == "" || strings.TrimSpace(pepper) == "local-dev-pepper-change-me" { + return errors.New("production requires a non-default EVYDENCE_API_KEY_PEPPER") + } + if strings.TrimSpace(signingKeyMode) != "external" { + return errors.New("production requires EVYDENCE_SIGNING_KEY_MODE=external; plaintext local signing keys are dev-only") + } + if printBootstrapSecret { + return errors.New("production refuses EVYDENCE_PRINT_BOOTSTRAP_SECRET=true") + } + return nil +} + func envDefault(name, fallback string) string { if value := strings.TrimSpace(os.Getenv(name)); value != "" { return value diff --git a/cmd/evydence-api/main_test.go b/cmd/evydence-api/main_test.go new file mode 100644 index 0000000..ec5a667 --- /dev/null +++ b/cmd/evydence-api/main_test.go @@ -0,0 +1,22 @@ +package main + +import ( + "strings" + "testing" +) + +func TestValidateRuntimeConfigRejectsProductionBootstrapSecretPrinting(t *testing.T) { + err := validateRuntimeConfig(true, "postgres://example", "not-default", "external", true) + if err == nil { + t.Fatal("expected production bootstrap secret printing to be rejected") + } + if !strings.Contains(err.Error(), "EVYDENCE_PRINT_BOOTSTRAP_SECRET") { + t.Fatalf("unexpected error: %v", err) + } +} + +func TestValidateRuntimeConfigAllowsLocalBootstrapSecretPrinting(t *testing.T) { + if err := validateRuntimeConfig(false, "", "", "", true); err != nil { + t.Fatalf("local config should allow explicit bootstrap secret printing: %v", err) + } +} diff --git a/docs/operations.md b/docs/operations.md index d243f38..29c61eb 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -18,7 +18,7 @@ Backend configuration is read from environment variables: - `EVYDENCE_SKIP_MIGRATIONS`: set to `true` only when migrations are applied by an external release process. - `EVYDENCE_MIGRATIONS_DIR`: migration directory, default `migrations`. - `EVYDENCE_BOOTSTRAP_TENANT`: local bootstrap tenant name. -- `EVYDENCE_PRINT_BOOTSTRAP_SECRET`: set to `true` only for local development to print the bootstrap API key secret. +- `EVYDENCE_PRINT_BOOTSTRAP_SECRET`: set to `true` only for local development to print the bootstrap API key secret. The API rejects this setting when `ENV=production`. - `EVYDENCE_WORKER_POLL_INTERVAL`: worker outbox polling interval, default `1s`. - `EVYDENCE_SIGNING_KEY_MODE`: production currently requires `external`; local plaintext signing keys are development-only. @@ -49,7 +49,7 @@ set -a; . ./.api.env; set +a go run ./cmd/evydence-worker ``` -The current API performs the implemented parsing/signing/verification work synchronously before enqueueing observability jobs. The worker fails closed for recognized job kinds that do not yet have a deterministic background handler wired, so operators see retry/failure state instead of false successful no-ops. +The current API performs the implemented parsing/signing/verification work synchronously before enqueueing observability jobs. The worker validates that expected parsed, signed, or verified durable state exists for configured job kinds and fails safely on missing state, missing signatures, hash mismatch, or unsupported jobs. The API can use filesystem or S3/MinIO-compatible object storage. Object keys are generated by the application under `tenants//...`; do not grant collectors direct bucket write access. @@ -99,7 +99,7 @@ Use `GET /v1/admin/instance` with an instance-admin scoped actor for low-detail Legal holds and retention overrides are ledger records. They help explain why evidence should be retained, but they do not configure external database backups, S3 lifecycle rules, or object-lock policies. -Customer portal access tokens are returned once by `POST /v1/customer-portal/access`, expire, and are stored as hashes. Treat them like bearer secrets and do not place them in logs or long-lived documentation. Failed token attempts that match a known token prefix are recorded as safe audit-chain signals without storing the token value. +Customer portal access tokens are returned once by `POST /v1/customer-portal/access`, expire, and are stored as hashes. Treat them like bearer secrets and do not place them in logs or long-lived documentation. Failed token attempts that match a known token prefix increment safe counters and record audit-chain signals without storing the token value. `GET /v1/metrics` includes a tenant-safe `customer_portal_failed_access_count`; deployments should still use reverse-proxy or API-gateway throttling for the unauthenticated portal endpoint. Human SSO sessions enforce the resource constraints recorded on role bindings. Tenant-wide bindings use `resource_type=tenant` or an empty resource scope; product, project, release, customer package, and evidence bundle bindings only authorize matching resource operations. API keys and collector API keys continue to rely on explicit scopes. @@ -111,4 +111,4 @@ Object-retention policy APIs record and verify retention intent for tenant-prefi The API refuses `ENV=production` unless PostgreSQL is configured, a non-default API key pepper is set, and local plaintext signing-key mode is disabled. Signing-provider records are available, but production deployments should use an external signing mode and avoid storing private key material in the ledger snapshot. -Before release labeling, run `make release-check`. It includes `make finalize`, lint, gosec, govulncheck, race tests, and live PostgreSQL checks when `EVYDENCE_TEST_DATABASE_URL` is set. +Before release labeling, run `make release-check`. It includes `make finalize`, lint, gosec, govulncheck, race tests, and live PostgreSQL checks when `EVYDENCE_TEST_DATABASE_URL` is set. The target writes `tmp/release-check-summary.txt` with passed checks and explicit skip lines for live PostgreSQL coverage when the environment variable is unset. From e6fc145904687b49d9c0c09aa0e268efd6f90024 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sat, 23 May 2026 10:37:16 +0300 Subject: [PATCH 006/287] fix(auth): harden privileged scopes and portal secrets --- Makefile | 1 + README.md | 2 +- docs/README.md | 1 + docs/api.md | 6 +- docs/explanation/trust-model.md | 4 +- docs/how-to/install-and-operate.md | 2 + docs/operations.md | 8 +- docs/reference/release-validation.md | 50 ++++++++ internal/adapters/httpapi/router_test.go | 21 +++- internal/app/enterprise.go | 10 +- internal/app/enterprise_test.go | 154 ++++++++++++++++++++++- internal/app/integrity_runtime.go | 6 +- internal/app/ledger.go | 45 ++++++- 13 files changed, 289 insertions(+), 21 deletions(-) create mode 100644 docs/reference/release-validation.md diff --git a/Makefile b/Makefile index cc9c636..43a16d5 100644 --- a/Makefile +++ b/Makefile @@ -61,6 +61,7 @@ docs-check: ## Validate canonical docs exist and avoid forbidden product claims @test -f docs/how-to/install-and-operate.md @test -f docs/reference/openapi.md @test -f docs/reference/worker-outbox.md + @test -f docs/reference/release-validation.md @test -f docs/explanation/trust-model.md @! grep -R -i "automatically compliant\|certified secure\|legally sufficient\|SBOM is complete\|all vulnerabilities detected" README.md docs diff --git a/README.md b/README.md index f79bfbe..abb3226 100644 --- a/README.md +++ b/README.md @@ -57,4 +57,4 @@ make live-postgres-check make postgres-integration-test ``` -`make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. +`make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. The target writes `tmp/release-check-summary.txt`; see `docs/reference/release-validation.md` for the configured Postgres release profile. diff --git a/docs/README.md b/docs/README.md index 4220476..ce444e5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -15,6 +15,7 @@ This documentation is organized by task type so roadmap intent and implemented b - [API reference](api.md) describes the implemented `/v1` HTTP surface. - [OpenAPI contract](reference/openapi.md) explains how `openapi.yaml` is generated and checked. - [Worker outbox contract](reference/worker-outbox.md) documents durable job inputs, idempotency, and safe failure behavior. +- [Release validation](reference/release-validation.md) documents the configured release-check profile and live PostgreSQL evidence. ## Explanation diff --git a/docs/api.md b/docs/api.md index 78bd1fd..43a6514 100644 --- a/docs/api.md +++ b/docs/api.md @@ -23,9 +23,9 @@ The generated OpenAPI document is committed at `openapi.yaml` and served at `/v1 `POST /v1/role-bindings` assigns a role to a user or collector. Current roles are `tenant_admin`, `security_engineer`, `release_manager`, `customer_verifier`, and `collector`. Human SSO session actors derive API scopes from role bindings and enforce `resource_type`/`resource_id` constraints for product, project, release, customer package, evidence bundle, build, control evidence, source, deployment, incident, security scan, report, export, read, and write operations where those resources are part of the request. API key and collector API key scopes remain tenant-scoped. `GET /v1/role-bindings` lists tenant-scoped bindings. -`POST /v1/sso/providers` records OIDC or SAML provider metadata. `POST /v1/sso/identity-links` links a verified provider subject to an existing user. `POST /v1/sso/sessions` issues an expiring one-time session token response; the token hash is stored server-side and is not returned by list/read paths. `POST /v1/sso/sessions/{id}/revoke` revokes the session. +`POST /v1/sso/providers` records OIDC or SAML provider metadata. `POST /v1/sso/identity-links` links a verified provider subject to an existing user. `POST /v1/sso/sessions` issues an expiring one-time session token response; the token hash is stored server-side and is not returned by list/read paths. `POST /v1/sso/sessions/{id}/revoke` revokes the session. These endpoints model admin-managed identity/session records; they do not perform live OIDC discovery, JWKS validation, SAML assertion verification, browser redirects, or provider login callbacks. -`GET /v1/admin/instance` returns low-detail instance diagnostics for instance admins. It exposes operational counts only, not raw evidence payloads, API keys, session hashes, or customer portal tokens. +`GET /v1/admin/instance` returns low-detail instance diagnostics only for actors explicitly granted `instance:admin`. Tenant `admin` and ordinary wildcard `*` tenant keys remain tenant-scoped and do not satisfy this instance-wide scope unless `instance:admin` is also present. The endpoint exposes operational counts only, not raw evidence payloads, API keys, session hashes, or customer portal tokens. ## Controls And Reports @@ -109,7 +109,7 @@ Scoped exceptions are created with `POST /v1/exceptions` and approved separately `POST /v1/redaction-profiles` creates an explicit package redaction profile. `POST /v1/customer-packages` creates a scoped customer security package manifest with expiry and access auditing. `GET /v1/customer-packages/{id}` reads the manifest and records an access event; raw payload bytes are not returned. -`POST /v1/customer-portal/access` creates an expiring customer portal access token for one package and returns the token once. `POST /v1/customer-portal/package` accepts that token and returns the scoped package manifest without exposing the token or raw tenant evidence. Failed portal token attempts that match a known token prefix record a safe audit-chain signal without storing or returning the supplied token. +`POST /v1/customer-portal/access` creates an expiring customer portal access token for one package and returns the token once. `POST /v1/customer-portal/package` accepts that token and returns the scoped package manifest without exposing the token or raw tenant evidence. Failed portal token attempts that match a known token prefix record a safe audit-chain signal without storing or returning the supplied token. After repeated failed attempts for one active access record, Evydence revokes that access record and reports only tenant-safe counters. `POST /v1/questionnaire-templates` creates tenant-defined customer questionnaire templates with question-to-evidence hints. `POST /v1/questionnaire-packages` generates deterministic evidence-backed responses for a package, product, and release scope. Responses cite linked evidence IDs and include limitations for human review. diff --git a/docs/explanation/trust-model.md b/docs/explanation/trust-model.md index 700d2f5..875ce35 100644 --- a/docs/explanation/trust-model.md +++ b/docs/explanation/trust-model.md @@ -2,8 +2,8 @@ Evydence records technical evidence, hashes payloads, links evidence to products and releases, and records append-only audit-chain entries. It supports reproducible review by exposing evidence gaps, assumptions, exceptions, waivers, verification receipts, and report limitations. -Evydence trusts tenant-scoped API keys and SSO session tokens after server-side hash verification. Collector identity is derived from the collector API key binding. Customer portal access uses expiring package tokens and exposes scoped package manifests, not raw tenant evidence. +Evydence trusts tenant-scoped API keys and SSO session tokens after server-side hash verification. Instance-wide diagnostics require the explicit `instance:admin` scope; tenant `admin` and wildcard tenant keys remain tenant-scoped unless that scope is also present. Collector identity is derived from the collector API key binding. Customer portal access uses expiring package tokens and exposes scoped package manifests, not raw tenant evidence. Repeated failed portal attempts revoke the access record without storing the supplied token. -Provider metadata such as GitHub Actions, GitLab, DSSE, VEX, SBOM, OpenAPI, and scanner payloads is treated as uploaded evidence unless a configured trust root or verification path proves more. Structural parsing is not the same as provider truth or cryptographic trust. +Provider metadata such as GitHub Actions, GitLab, DSSE, VEX, SBOM, OpenAPI, scanner payloads, and SSO provider records is treated as uploaded evidence unless a configured trust root or verification path proves more. Current SSO support records provider metadata, identity links, and expiring sessions; it does not perform live OIDC or SAML login verification. Structural parsing is not the same as provider truth or cryptographic trust. Reports are readiness and evidence-organization outputs. They do not state legal compliance, certification, complete SBOM coverage, authoritative vulnerability results, or secure releases. diff --git a/docs/how-to/install-and-operate.md b/docs/how-to/install-and-operate.md index a990352..36d738a 100644 --- a/docs/how-to/install-and-operate.md +++ b/docs/how-to/install-and-operate.md @@ -26,4 +26,6 @@ make postgres-integration-test make finalize ``` +For release validation with live PostgreSQL evidence, start Compose, load `.test.env`, and run `make release-check`. The target writes `tmp/release-check-summary.txt`; the release validation reference explains the expected pass and skip lines. + Back up PostgreSQL and the configured object store together. Backup manifests help compare recorded ledger state, but restore confidence depends on matched database and object payload backups. diff --git a/docs/operations.md b/docs/operations.md index 29c61eb..0d32454 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -95,13 +95,13 @@ Use `GET /v1/ready` for low-detail readiness checks. Use `GET /v1/metrics` only Use `POST /v1/backup-manifests` after database and object-store backups complete to record a hash and consistency checks for the ledger state. The manifest is not a backup by itself and intentionally excludes raw payload bytes and private signing-key material. -Use `GET /v1/admin/instance` with an instance-admin scoped actor for low-detail tenant/resource counts. Do not expose this endpoint to customer verifier roles. +Use `GET /v1/admin/instance` only with an actor explicitly granted `instance:admin` for low-detail tenant/resource counts. Tenant `admin` and ordinary wildcard `*` tenant keys do not satisfy this instance-wide scope unless `instance:admin` is also present. Do not expose this endpoint to customer verifier roles. Legal holds and retention overrides are ledger records. They help explain why evidence should be retained, but they do not configure external database backups, S3 lifecycle rules, or object-lock policies. -Customer portal access tokens are returned once by `POST /v1/customer-portal/access`, expire, and are stored as hashes. Treat them like bearer secrets and do not place them in logs or long-lived documentation. Failed token attempts that match a known token prefix increment safe counters and record audit-chain signals without storing the token value. `GET /v1/metrics` includes a tenant-safe `customer_portal_failed_access_count`; deployments should still use reverse-proxy or API-gateway throttling for the unauthenticated portal endpoint. +Customer portal access tokens are returned once by `POST /v1/customer-portal/access`, expire, and are stored as hashes. Treat them like bearer secrets and do not place them in logs or long-lived documentation. Failed token attempts that match a known active token prefix increment safe counters and record audit-chain signals without storing the token value. After repeated failed attempts, the access record is revoked. `GET /v1/metrics` includes tenant-safe `customer_portal_failed_access_count` and `customer_portal_revoked_access_count`; deployments should still use reverse-proxy or API-gateway throttling for the unauthenticated portal endpoint. -Human SSO sessions enforce the resource constraints recorded on role bindings. Tenant-wide bindings use `resource_type=tenant` or an empty resource scope; product, project, release, customer package, and evidence bundle bindings only authorize matching resource operations. API keys and collector API keys continue to rely on explicit scopes. +Human SSO sessions enforce the resource constraints recorded on role bindings. Tenant-wide bindings use `resource_type=tenant` or an empty resource scope; product, project, release, customer package, and evidence bundle bindings only authorize matching resource operations. API keys and collector API keys continue to rely on explicit scopes. Current SSO endpoints are admin-managed provider, identity-link, and session records; production OIDC/SAML login callbacks, token/assertion verification, group synchronization, and browser session handling are not implemented yet. Use `POST /v1/merkle-batches` and `POST /v1/transparency-checkpoints` to record signed local checkpoints and optional external anchoring metadata. These support tamper-evidence but do not make public transparency mandatory. @@ -111,4 +111,4 @@ Object-retention policy APIs record and verify retention intent for tenant-prefi The API refuses `ENV=production` unless PostgreSQL is configured, a non-default API key pepper is set, and local plaintext signing-key mode is disabled. Signing-provider records are available, but production deployments should use an external signing mode and avoid storing private key material in the ledger snapshot. -Before release labeling, run `make release-check`. It includes `make finalize`, lint, gosec, govulncheck, race tests, and live PostgreSQL checks when `EVYDENCE_TEST_DATABASE_URL` is set. The target writes `tmp/release-check-summary.txt` with passed checks and explicit skip lines for live PostgreSQL coverage when the environment variable is unset. +Before release labeling, run `make release-check`. It includes `make finalize`, lint, gosec, govulncheck, race tests, and live PostgreSQL checks when `EVYDENCE_TEST_DATABASE_URL` is set. The target writes `tmp/release-check-summary.txt` with passed checks and explicit skip lines for live PostgreSQL coverage when the environment variable is unset. Use the release validation reference for the configured Postgres profile and the exact summary evidence to retain. diff --git a/docs/reference/release-validation.md b/docs/reference/release-validation.md new file mode 100644 index 0000000..6b8e862 --- /dev/null +++ b/docs/reference/release-validation.md @@ -0,0 +1,50 @@ +# Release Validation + +This reference describes the project-owned release validation profile. It is evidence for engineering review only; it does not prove legal compliance, certification, complete vulnerability detection, or secure releases. + +## Default Local Profile + +Run the default release gate from the repository root: + +```sh +make release-check +``` + +The target runs formatting, unit tests, OpenAPI drift checks, docs/deployment/SDK checks, linting, gosec, govulncheck, race tests, and the live PostgreSQL targets. When `EVYDENCE_TEST_DATABASE_URL` is unset, live PostgreSQL checks are explicitly skipped and the summary records that limitation. + +The target writes: + +```text +tmp/release-check-summary.txt +``` + +Keep this file with release evidence when preparing an internal release review. It records the pass/skip status for the gate families, including whether live PostgreSQL checks ran. + +## Configured Live PostgreSQL Profile + +Start the local dependencies and load the test profile: + +```sh +make compose-up +set -a; . ./.test.env; set +a +make release-check +``` + +The configured profile requires `EVYDENCE_TEST_DATABASE_URL`. The example `.test.env.example` points at the Docker Compose PostgreSQL service: + +```sh +EVYDENCE_TEST_DATABASE_URL=postgres://evydence:change-me@localhost:5432/evydence?sslmode=disable +``` + +With that variable set, `make release-check` applies migrations through `make live-postgres-check` and runs the Postgres-backed integration target. The summary should contain: + +```text +live_postgres=passed +postgres_integration=passed +``` + +If either line is skipped, the release evidence should state that durable-store validation was not covered in that run. + +## CI Usage + +CI should provide a disposable PostgreSQL service, set `EVYDENCE_TEST_DATABASE_URL`, run `make release-check`, and preserve `tmp/release-check-summary.txt` as a build artifact. The database should not contain production evidence, customer package tokens, signing-key material, or other real secrets. diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 6529432..b0479e0 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -133,6 +133,24 @@ func TestCrossTenantEvidenceReadDenied(t *testing.T) { } } +func TestInstanceAdminHTTPRequiresExplicitScope(t *testing.T) { + ledger := app.NewLedger(app.Config{APIKeyPepper: "test"}) + _, _, tenantSecret, err := ledger.BootstrapTenant(t.Context(), "Tenant", "tenant-admin", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap tenant: %v", err) + } + _, _, instanceSecret, err := ledger.BootstrapTenant(t.Context(), "Instance Tenant", "instance-admin", []string{"*", app.ScopeInstanceAdmin}) + if err != nil { + t.Fatalf("bootstrap instance: %v", err) + } + server, err := NewServer(ledger) + if err != nil { + t.Fatalf("server: %v", err) + } + getJSON(t, server, tenantSecret, "/v1/admin/instance", http.StatusForbidden) + getJSON(t, server, instanceSecret, "/v1/admin/instance", http.StatusOK) +} + func TestReleaseBundleVerifyFlow(t *testing.T) { server, secret := testServer(t) productBody := postJSON(t, server, secret, "/v1/products", "prod", map[string]any{"name": "Payments", "slug": "payments"}, http.StatusCreated) @@ -594,7 +612,8 @@ func TestEnterprisePortalRetentionAndCommercialCollectorHTTPFlow(t *testing.T) { if strings.Contains(getJSON(t, server, secret, "/v1/role-bindings", http.StatusOK), sessionSecret) { t.Fatalf("session secret leaked in role binding response") } - getJSON(t, server, sessionSecret, "/v1/admin/instance", http.StatusOK) + getJSON(t, server, secret, "/v1/admin/instance", http.StatusForbidden) + getJSON(t, server, sessionSecret, "/v1/admin/instance", http.StatusForbidden) productBody := postJSON(t, server, sessionSecret, "/v1/products", "ent-product", map[string]any{"name": "Enterprise Product", "slug": "enterprise-product"}, http.StatusCreated) productID := dataField(t, productBody, "id") diff --git a/internal/app/enterprise.go b/internal/app/enterprise.go index 129e1ab..03935c9 100644 --- a/internal/app/enterprise.go +++ b/internal/app/enterprise.go @@ -465,13 +465,19 @@ func (l *Ledger) AccessCustomerPortalPackage(ctx context.Context, token string) l.mu.Lock() defer l.mu.Unlock() for id, access := range l.portalAccess { - if access.Hash != hash || access.RevokedAt != nil || !access.ExpiresAt.After(l.now()) { - if access.Prefix == prefix { + if !secretHashEqual(access.Hash, hash) || access.RevokedAt != nil || !access.ExpiresAt.After(l.now()) { + if access.Prefix == prefix && access.RevokedAt == nil && access.ExpiresAt.After(l.now()) { now := l.now() access.FailedAccessCount++ + if access.RevokedAt == nil && access.FailedAccessCount >= customerPortalFailedAccessLimit { + access.RevokedAt = &now + } access.LastFailedAt = &now l.portalAccess[id] = access _, _ = l.appendChainLocked(access.TenantID, "customer_portal_package.access_failed", "customer_portal_access", access.ID, "customer_portal", "unverified", "", "") + if access.RevokedAt != nil && access.FailedAccessCount == customerPortalFailedAccessLimit { + _, _ = l.appendChainLocked(access.TenantID, "customer_portal_access.revoked_after_failed_access", "customer_portal_access", access.ID, "customer_portal", "unverified", "", "") + } _ = l.persistLocked(ctx) } continue diff --git a/internal/app/enterprise_test.go b/internal/app/enterprise_test.go index fc5059c..0b298d9 100644 --- a/internal/app/enterprise_test.go +++ b/internal/app/enterprise_test.go @@ -3,6 +3,7 @@ package app import ( "context" "errors" + "strings" "testing" "time" @@ -12,7 +13,7 @@ import ( func TestEnterpriseIdentityRBACSSOAndAdminSnapshot(t *testing.T) { ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) ctx := context.Background() - _, _, secret, err := ledger.BootstrapTenant(ctx, "Tenant", "admin", []string{"*"}) + _, _, secret, err := ledger.BootstrapTenant(ctx, "Tenant", "admin", []string{"*", ScopeInstanceAdmin}) if err != nil { t.Fatalf("bootstrap: %v", err) } @@ -77,6 +78,78 @@ func TestEnterpriseIdentityRBACSSOAndAdminSnapshot(t *testing.T) { } } +func TestInstanceAdminRequiresExplicitScope(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + _, _, tenantAdminSecret, err := ledger.BootstrapTenant(ctx, "Tenant", "tenant-admin", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap tenant admin: %v", err) + } + tenantAdmin, err := ledger.Authenticate(ctx, tenantAdminSecret) + if err != nil { + t.Fatalf("tenant admin auth: %v", err) + } + if _, err := ledger.InstanceAdminSnapshot(ctx, tenantAdmin); !errors.Is(err, ErrForbidden) { + t.Fatalf("tenant wildcard snapshot err=%v, want forbidden", err) + } + if _, err := ledger.CreateProduct(ctx, tenantAdmin, "Tenant Product", "tenant-product"); err != nil { + t.Fatalf("tenant admin should still create tenant resources: %v", err) + } + if _, _, err := ledger.CreateAPIKey(ctx, tenantAdmin, "instance-escalation", []string{ScopeInstanceAdmin}, nil); !errors.Is(err, ErrForbidden) { + t.Fatalf("tenant admin instance key creation err=%v, want forbidden", err) + } + + _, _, instanceSecret, err := ledger.BootstrapTenant(ctx, "Instance Tenant", "instance-admin", []string{"*", ScopeInstanceAdmin}) + if err != nil { + t.Fatalf("bootstrap instance admin: %v", err) + } + instanceAdmin, err := ledger.Authenticate(ctx, instanceSecret) + if err != nil { + t.Fatalf("instance admin auth: %v", err) + } + if _, err := ledger.InstanceAdminSnapshot(ctx, instanceAdmin); err != nil { + t.Fatalf("explicit instance admin snapshot: %v", err) + } + _, instanceKeySecret, err := ledger.CreateAPIKey(ctx, instanceAdmin, "instance-read", []string{ScopeInstanceAdmin}, nil) + if err != nil { + t.Fatalf("explicit instance key creation: %v", err) + } + instanceKeyActor, err := ledger.Authenticate(ctx, instanceKeySecret) + if err != nil { + t.Fatalf("instance key auth: %v", err) + } + if _, err := ledger.InstanceAdminSnapshot(ctx, instanceKeyActor); err != nil { + t.Fatalf("instance key snapshot: %v", err) + } + + org, err := ledger.CreateOrganization(ctx, tenantAdmin, CreateOrganizationInput{Name: "Example", Slug: "example"}) + if err != nil { + t.Fatalf("org: %v", err) + } + user, err := ledger.CreateUser(ctx, tenantAdmin, CreateUserInput{OrganizationID: org.ID, Email: "admin@example.test", DisplayName: "Admin"}) + if err != nil { + t.Fatalf("user: %v", err) + } + if _, err := ledger.CreateRoleBinding(ctx, tenantAdmin, CreateRoleBindingInput{SubjectType: "user", SubjectID: user.ID, Role: "tenant_admin", ResourceType: "tenant", ResourceID: tenantAdmin.TenantID}); err != nil { + t.Fatalf("role binding: %v", err) + } + provider, err := ledger.CreateSSOProvider(ctx, tenantAdmin, CreateSSOProviderInput{Name: "OIDC", Type: "oidc", Issuer: "https://idp.example.test", ClientID: "client"}) + if err != nil { + t.Fatalf("provider: %v", err) + } + _, sessionSecret, err := ledger.CreateSSOSession(ctx, tenantAdmin, CreateSSOSessionInput{UserID: user.ID, ProviderID: provider.ID, ExpiresAt: fixedNow().Add(time.Hour)}) + if err != nil { + t.Fatalf("session: %v", err) + } + sessionActor, err := ledger.Authenticate(ctx, sessionSecret) + if err != nil { + t.Fatalf("session auth: %v", err) + } + if _, err := ledger.InstanceAdminSnapshot(ctx, sessionActor); !errors.Is(err, ErrForbidden) { + t.Fatalf("tenant-admin SSO snapshot err=%v, want forbidden", err) + } +} + func TestCustomerPortalRetentionQuestionnairesAndCommercialCollectors(t *testing.T) { ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) ctx := context.Background() @@ -107,10 +180,7 @@ func TestCustomerPortalRetentionQuestionnairesAndCommercialCollectors(t *testing if portalPkg.ID != pkg.ID { t.Fatalf("portal package id = %s want %s", portalPkg.ID, pkg.ID) } - badToken := token[:len(token)-1] + "x" - if badToken == token { - badToken = token[:len(token)-1] + "y" - } + badToken := mutateTokenSuffix(token) if _, err := ledger.AccessCustomerPortalPackage(ctx, badToken); !errors.Is(err, ErrUnauthorized) { t.Fatalf("bad portal token err=%v, want unauthorized", err) } @@ -181,6 +251,80 @@ func TestCustomerPortalRetentionQuestionnairesAndCommercialCollectors(t *testing } } +func TestCustomerPortalAccessRevokesAfterRepeatedFailedAttempts(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, release, _ := setupReleaseRiskFixture(t, ledger) + profile, err := ledger.CreateRedactionProfile(ctx, actor, CreateRedactionProfileInput{Name: "customer", AllowedTypes: []string{"sbom"}}) + if err != nil { + t.Fatalf("profile: %v", err) + } + pkg, err := ledger.CreateCustomerSecurityPackage(ctx, actor, CreateCustomerPackageInput{ProductID: release.ProductID, ReleaseID: release.ID, RedactionProfileID: profile.ID, Title: "Customer", ExpiresAt: fixedNow().Add(time.Hour)}) + if err != nil { + t.Fatalf("customer package: %v", err) + } + access, token, err := ledger.CreateCustomerPortalAccess(ctx, actor, CreateCustomerPortalAccessInput{PackageID: pkg.ID, CustomerName: "ACME", ExpiresAt: fixedNow().Add(time.Hour)}) + if err != nil { + t.Fatalf("portal access: %v", err) + } + badToken := mutateTokenSuffix(token) + for i := 0; i < customerPortalFailedAccessLimit; i++ { + if _, err := ledger.AccessCustomerPortalPackage(ctx, badToken); !errors.Is(err, ErrUnauthorized) { + t.Fatalf("bad portal token attempt %d err=%v, want unauthorized", i+1, err) + } + } + if _, err := ledger.AccessCustomerPortalPackage(ctx, token); !errors.Is(err, ErrUnauthorized) { + t.Fatalf("revoked portal token err=%v, want unauthorized", err) + } + entries, err := ledger.ListAuditLog(ctx, actor, AuditLogFilter{SubjectType: "customer_portal_access", SubjectID: access.ID, Limit: 20}) + if err != nil { + t.Fatalf("audit log: %v", err) + } + var failures, revocations int + for _, entry := range entries { + switch entry.EntryType { + case "customer_portal_package.access_failed": + failures++ + case "customer_portal_access.revoked_after_failed_access": + revocations++ + } + if entry.ActorID == badToken || entry.PayloadHash == badToken { + t.Fatalf("portal audit leaked token: %#v", entry) + } + } + if failures != customerPortalFailedAccessLimit || revocations != 1 { + t.Fatalf("audit entries failures=%d revocations=%d", failures, revocations) + } + metrics, err := ledger.Metrics(ctx, actor) + if err != nil { + t.Fatalf("metrics: %v", err) + } + if metrics["customer_portal_failed_access_count"] != customerPortalFailedAccessLimit || metrics["customer_portal_revoked_access_count"] != 1 { + t.Fatalf("portal metrics = %#v", metrics) + } +} + +func TestSecretHashComparisonHelper(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + hash := ledger.hashSecret("evy_test_secret") + if !secretHashEqual(hash, hash) { + t.Fatalf("same HMAC hash did not compare equal") + } + if secretHashEqual(hash, ledger.hashSecret("evy_test_other")) { + t.Fatalf("different HMAC hashes compared equal") + } + if secretHashEqual(hash, "short") { + t.Fatalf("malformed hash compared equal") + } +} + +func mutateTokenSuffix(token string) string { + if strings.HasSuffix(token, "x") { + return token[:len(token)-1] + "y" + } + return token[:len(token)-1] + "x" +} + func TestHumanSSOSessionRoleBindingsAreResourceScoped(t *testing.T) { ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) ctx := context.Background() diff --git a/internal/app/integrity_runtime.go b/internal/app/integrity_runtime.go index 0c0ec11..3209480 100644 --- a/internal/app/integrity_runtime.go +++ b/internal/app/integrity_runtime.go @@ -436,12 +436,16 @@ func (l *Ledger) Metrics(ctx context.Context, actor domain.Actor) (map[string]an l.mu.Lock() defer l.mu.Unlock() portalFailures := 0 + portalRevoked := 0 for _, access := range l.portalAccess { if access.TenantID == actor.TenantID { portalFailures += access.FailedAccessCount + if access.RevokedAt != nil { + portalRevoked++ + } } } - return map[string]any{"tenant_id": actor.TenantID, "resource_counts": l.resourceCountsLocked(actor.TenantID), "customer_portal_failed_access_count": portalFailures}, nil + return map[string]any{"tenant_id": actor.TenantID, "resource_counts": l.resourceCountsLocked(actor.TenantID), "customer_portal_failed_access_count": portalFailures, "customer_portal_revoked_access_count": portalRevoked}, nil } func (l *Ledger) ListAuditLog(ctx context.Context, actor domain.Actor, filter AuditLogFilter) ([]domain.AuditChainEntry, error) { diff --git a/internal/app/ledger.go b/internal/app/ledger.go index 07b48e9..bf76602 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -60,6 +60,8 @@ const ( ScopeCustomerPortal = "customer:portal" ) +const customerPortalFailedAccessLimit = 5 + type Config struct { APIKeyPepper string Now func() time.Time @@ -320,7 +322,7 @@ func (l *Ledger) Authenticate(ctx context.Context, secret string) (domain.Actor, l.mu.Lock() defer l.mu.Unlock() for id, key := range l.apiKeys { - if key.Prefix != prefix || key.Hash != hash || key.RevokedAt != nil { + if key.Prefix != prefix || !secretHashEqual(key.Hash, hash) || key.RevokedAt != nil { continue } if key.ExpiresAt != nil && !key.ExpiresAt.After(l.now()) { @@ -342,7 +344,7 @@ func (l *Ledger) Authenticate(ctx context.Context, secret string) (domain.Actor, return domain.Actor{TenantID: key.TenantID, KeyID: key.ID, Name: key.Name, Scopes: append([]string(nil), key.Scopes...), CollectorID: collectorID}, nil } for id, session := range l.ssoSessions { - if session.Prefix != prefix || session.Hash != hash || session.RevokedAt != nil || !session.ExpiresAt.After(l.now()) { + if session.Prefix != prefix || !secretHashEqual(session.Hash, hash) || session.RevokedAt != nil || !session.ExpiresAt.After(l.now()) { continue } user, ok := l.users[session.UserID] @@ -368,6 +370,9 @@ func (l *Ledger) CreateAPIKey(ctx context.Context, actor domain.Actor, name stri if strings.TrimSpace(name) == "" || len(scopes) == 0 { return domain.APIKey{}, "", ErrValidation } + if err := requireGrantableScopes(actor, scopes); err != nil { + return domain.APIKey{}, "", err + } l.mu.Lock() defer l.mu.Unlock() key, secret, err := l.createAPIKeyLocked(actor.TenantID, name, scopes, expiresAt) @@ -1468,6 +1473,13 @@ func (l *Ledger) hashSecret(secret string) string { return hex.EncodeToString(mac.Sum(nil)) } +func secretHashEqual(stored, candidate string) bool { + if len(stored) != sha256.Size*2 || len(candidate) != sha256.Size*2 { + return false + } + return hmac.Equal([]byte(stored), []byte(candidate)) +} + func (l *Ledger) ensureScopeLocked(tenantID, productID, projectID, releaseID string) error { if productID != "" { product, ok := l.products[productID] @@ -1649,12 +1661,41 @@ func require(actor domain.Actor, scope string) error { if actor.TenantID == "" || (actor.KeyID == "" && actor.UserID == "" && actor.CollectorID == "") { return ErrUnauthorized } + if requiresExplicitScope(scope) { + if actorHasExactScope(actor, scope) { + return nil + } + return ErrForbidden + } if actor.HasScope(scope) || actor.HasScope(ScopeAdmin) { return nil } return ErrForbidden } +func requireGrantableScopes(actor domain.Actor, scopes []string) error { + for _, scope := range scopes { + scope = strings.TrimSpace(scope) + if requiresExplicitScope(scope) && !actorHasExactScope(actor, scope) { + return ErrForbidden + } + } + return nil +} + +func requiresExplicitScope(scope string) bool { + return scope == ScopeInstanceAdmin +} + +func actorHasExactScope(actor domain.Actor, scope string) bool { + for _, got := range actor.Scopes { + if got == scope { + return true + } + } + return false +} + func canonicalHash(item domain.EvidenceItem) (string, error) { item.CanonicalHash = "" item.ChainEntryID = "" From c41a3e7a2354f07b47fd156e85c4b28b5528539d Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sat, 23 May 2026 10:57:27 +0300 Subject: [PATCH 007/287] refactor(http): split routes and tighten contracts --- internal/adapters/httpapi/openapi.go | 93 +++++++ .../adapters/httpapi/openapi_operations.go | 106 ++++++++ .../adapters/httpapi/route_registration.go | 244 ++++++++++++++++++ internal/adapters/httpapi/router.go | 160 +----------- internal/adapters/httpapi/router_test.go | 155 +++++++++++ openapi.yaml | 2 +- 6 files changed, 600 insertions(+), 160 deletions(-) create mode 100644 internal/adapters/httpapi/openapi_operations.go create mode 100644 internal/adapters/httpapi/route_registration.go diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 40d64c3..d8a97b6 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -18,7 +18,100 @@ func NewSpecRegistry() *specs.Registry { "detail": map[string]any{"type": "string"}, "instance": map[string]any{"type": "string"}, "code": map[string]any{"type": "string"}, + "request_id": map[string]any{ + "type": "string", + "description": "Request identifier mirrored from the X-Request-ID response header.", + }, }, }) + registerCriticalSchemas(registry) return registry } + +func registerCriticalSchemas(registry *specs.Registry) { + registry.RegisterSchema("DataEnvelope", objectSchema(map[string]any{ + "data": map[string]any{}, + "meta": objectSchema(map[string]any{ + "api_version": map[string]any{"type": "string"}, + }, "api_version"), + }, "data", "meta")) + registry.RegisterSchema("InstanceAdminSnapshot", objectSchema(map[string]any{ + "tenant_count": map[string]any{"type": "integer"}, + "user_count": map[string]any{"type": "integer"}, + "api_key_count": map[string]any{"type": "integer"}, + "resource_counts": map[string]any{"type": "object", "additionalProperties": map[string]any{"type": "integer"}}, + }, "tenant_count", "resource_counts")) + registry.RegisterSchema("CreateSSOSessionRequest", objectSchema(map[string]any{ + "user_id": map[string]any{"type": "string"}, + "provider_id": map[string]any{"type": "string"}, + "expires_at": map[string]any{"type": "string", "format": "date-time"}, + }, "user_id", "provider_id", "expires_at")) + registry.RegisterSchema("SSOSessionCreateResponse", objectSchema(map[string]any{ + "session": map[string]any{"type": "object"}, + "secret": map[string]any{"type": "string", "description": "One-time SSO session bearer secret; not returned by list/read operations."}, + }, "session", "secret")) + registry.RegisterSchema("SSOSessionCreateEnvelope", dataEnvelopeSchema("#/components/schemas/SSOSessionCreateResponse")) + registry.RegisterSchema("CreateEvidenceRequest", objectSchema(map[string]any{ + "product_id": map[string]any{"type": "string"}, + "project_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "artifact_id": map[string]any{"type": "string"}, + "type": map[string]any{"type": "string"}, + "subtype": map[string]any{"type": "string"}, + "title": map[string]any{"type": "string"}, + "payload_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "payload": map[string]any{}, + "tags": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "source": map[string]any{"type": "string"}, + "subject_refs": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + }, "type", "title")) + registry.RegisterSchema("EvidenceSearchResponse", objectSchema(map[string]any{ + "items": map[string]any{"type": "array", "items": map[string]any{"type": "object"}}, + "next_cursor": map[string]any{"type": "string"}, + }, "items")) + registry.RegisterSchema("EvidenceSearchEnvelope", dataEnvelopeSchema("#/components/schemas/EvidenceSearchResponse")) + registry.RegisterSchema("CreateReleaseBundleRequest", objectSchema(map[string]any{ + "release_id": map[string]any{"type": "string"}, + }, "release_id")) + registry.RegisterSchema("ReleaseBundleVerification", objectSchema(map[string]any{ + "result": map[string]any{"type": "string", "enum": []string{"passed", "failed"}}, + "subject_type": map[string]any{"type": "string"}, + "subject_id": map[string]any{"type": "string"}, + "checked_at": map[string]any{"type": "string", "format": "date-time"}, + }, "result")) + registry.RegisterSchema("ReleaseBundleVerificationEnvelope", dataEnvelopeSchema("#/components/schemas/ReleaseBundleVerification")) + registry.RegisterSchema("CreateCustomerPortalAccessRequest", objectSchema(map[string]any{ + "package_id": map[string]any{"type": "string"}, + "customer_name": map[string]any{"type": "string"}, + "expires_at": map[string]any{"type": "string", "format": "date-time"}, + }, "package_id", "customer_name", "expires_at")) + registry.RegisterSchema("CustomerPortalAccessCreateResponse", objectSchema(map[string]any{ + "access": map[string]any{"type": "object"}, + "secret": map[string]any{"type": "string", "description": "One-time portal token; stored only as a HMAC hash."}, + }, "access", "secret")) + registry.RegisterSchema("CustomerPortalAccessCreateEnvelope", dataEnvelopeSchema("#/components/schemas/CustomerPortalAccessCreateResponse")) + registry.RegisterSchema("CustomerPortalPackageRequest", objectSchema(map[string]any{ + "token": map[string]any{"type": "string", "description": "Customer portal access token issued by createCustomerPortalAccess."}, + }, "token")) +} + +func objectSchema(properties map[string]any, required ...string) map[string]any { + schema := map[string]any{ + "type": "object", + "properties": properties, + "additionalProperties": false, + } + if len(required) > 0 { + schema["required"] = required + } + return schema +} + +func dataEnvelopeSchema(dataRef string) map[string]any { + return objectSchema(map[string]any{ + "data": map[string]any{"$ref": dataRef}, + "meta": objectSchema(map[string]any{ + "api_version": map[string]any{"type": "string"}, + }, "api_version"), + }, "data", "meta") +} diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go new file mode 100644 index 0000000..a3321df --- /dev/null +++ b/internal/adapters/httpapi/openapi_operations.go @@ -0,0 +1,106 @@ +package httpapi + +import ( + "net/http" + + "github.com/aatuh/api-toolkit/v3/specs" +) + +func withCriticalOperationDetails(operation specs.Operation) specs.Operation { + addProblemResponses(&operation) + switch operation.OperationID { + case "instanceAdminSnapshot": + operation.Description = "Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient." + operation.Responses[http.StatusOK] = jsonResponse("Instance admin snapshot envelope.", "#/components/schemas/DataEnvelope") + case "createSSOSession": + operation.Description = "Creates an admin-managed human SSO session record and returns a one-time bearer secret." + operation.RequestBody = jsonRequest("SSO session creation request.", "#/components/schemas/CreateSSOSessionRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created SSO session and one-time secret envelope.", "#/components/schemas/SSOSessionCreateEnvelope") + case "createEvidence": + operation.Description = "Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation." + operation.RequestBody = jsonRequest("Evidence creation request.", "#/components/schemas/CreateEvidenceRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created evidence item envelope.", "#/components/schemas/DataEnvelope") + case "searchEvidence": + operation.Description = "Searches tenant-scoped evidence with deterministic filters and cursor-style pagination." + operation.Parameters = append(operation.Parameters, + queryParam("product_id", "Filter by product id.", "string"), + queryParam("project_id", "Filter by project id.", "string"), + queryParam("release_id", "Filter by release id.", "string"), + queryParam("type", "Filter by evidence type.", "string"), + queryParam("source", "Filter by evidence source.", "string"), + queryParam("tag", "Filter by a single evidence tag.", "string"), + queryParam("cursor", "Opaque pagination cursor.", "string"), + queryParam("limit", "Maximum returned records.", "integer"), + ) + operation.Responses[http.StatusOK] = jsonResponse("Evidence search result envelope.", "#/components/schemas/EvidenceSearchEnvelope") + case "createReleaseBundle": + operation.Description = "Creates an immutable signed release bundle for a release." + operation.RequestBody = jsonRequest("Release bundle creation request.", "#/components/schemas/CreateReleaseBundleRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created release bundle envelope.", "#/components/schemas/DataEnvelope") + case "verifyReleaseBundle": + operation.Description = "Verifies a tenant-scoped release bundle and returns a deterministic verification result." + operation.Parameters = append(operation.Parameters, pathParam("id", "Release bundle id.")) + operation.Responses[http.StatusOK] = jsonResponse("Release bundle verification envelope.", "#/components/schemas/ReleaseBundleVerificationEnvelope") + case "createCustomerPortalAccess": + operation.Description = "Creates token-based customer portal access for a customer package and returns the token once." + operation.RequestBody = jsonRequest("Customer portal access creation request.", "#/components/schemas/CreateCustomerPortalAccessRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created portal access and one-time token envelope.", "#/components/schemas/CustomerPortalAccessCreateEnvelope") + case "accessCustomerPortalPackage": + operation.Description = "Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body." + operation.RequestBody = jsonRequest("Customer portal token request.", "#/components/schemas/CustomerPortalPackageRequest") + operation.Security = nil + operation.Scopes = nil + operation.Responses[http.StatusOK] = jsonResponse("Scoped customer package envelope.", "#/components/schemas/DataEnvelope") + } + return operation +} + +func addProblemResponses(operation *specs.Operation) { + for _, status := range []int{http.StatusBadRequest, http.StatusUnauthorized, http.StatusForbidden, http.StatusNotFound, http.StatusConflict, http.StatusUnprocessableEntity} { + operation.Responses[status] = problemResponse(http.StatusText(status)) + } +} + +func jsonRequest(description, schemaRef string) *specs.RequestBody { + return &specs.RequestBody{ + Description: description, + Required: true, + ContentTypes: []string{"application/json"}, + Content: map[string]specs.MediaType{ + "application/json": {SchemaRef: schemaRef}, + }, + } +} + +func jsonResponse(description, schemaRef string) specs.Response { + return specs.Response{ + Description: description, + ContentTypes: []string{"application/json"}, + Content: map[string]specs.MediaType{ + "application/json": {SchemaRef: schemaRef}, + }, + } +} + +func problemResponse(description string) specs.Response { + return specs.Response{ + Description: description, + ContentTypes: []string{"application/problem+json"}, + Content: map[string]specs.MediaType{ + "application/problem+json": {SchemaRef: "#/components/schemas/Problem"}, + }, + } +} + +func queryParam(name, description, typ string) specs.Parameter { + schema := map[string]any{"type": typ} + if name == "limit" { + schema["minimum"] = 1 + schema["maximum"] = 100 + } + return specs.Parameter{Name: name, In: "query", Description: description, Schema: schema} +} + +func pathParam(name, description string) specs.Parameter { + return specs.Parameter{Name: name, In: "path", Description: description, Required: true, Schema: map[string]any{"type": "string"}} +} diff --git a/internal/adapters/httpapi/route_registration.go b/internal/adapters/httpapi/route_registration.go new file mode 100644 index 0000000..7e8f09f --- /dev/null +++ b/internal/adapters/httpapi/route_registration.go @@ -0,0 +1,244 @@ +package httpapi + +import ( + "net/http" + + "github.com/aatuh/api-toolkit/v3/routecontracts" + "github.com/aatuh/api-toolkit/v3/specs" + + "github.com/aatuh/evydence/internal/app" +) + +type routeDef struct { + method string + path string + op specs.Operation + handler http.Handler +} + +func (s *Server) registerRoutes() error { + for _, route := range s.routeDefinitions() { + if err := s.routes.Register(routecontracts.Route{Method: route.method, Pattern: route.path, Handler: route.handler, Operation: route.op}); err != nil { + return err + } + } + return nil +} + +func (s *Server) routeDefinitions() []routeDef { + groups := [][]routeDef{ + s.systemRoutes(), + s.identityRoutes(), + s.collectorRoutes(), + s.controlRoutes(), + s.productReleaseRoutes(), + s.artifactBuildSourceRoutes(), + s.deploymentIncidentSecurityRoutes(), + s.packagePortalRoutes(), + s.evidenceRiskPolicyRoutes(), + s.integrityOpsRoutes(), + s.keyAndAdminRoutes(), + } + var routes []routeDef + for _, group := range groups { + routes = append(routes, group...) + } + return routes +} + +func (s *Server) systemRoutes() []routeDef { + return []routeDef{ + {http.MethodGet, "/v1/health", op("health", http.MethodGet, "/v1/health", "Health", nil), http.HandlerFunc(s.health)}, + {http.MethodGet, "/v1/ready", op("ready", http.MethodGet, "/v1/ready", "Readiness", nil), http.HandlerFunc(s.ready)}, + {http.MethodGet, "/v1/version", op("version", http.MethodGet, "/v1/version", "Version", nil), http.HandlerFunc(s.version)}, + {http.MethodGet, "/v1/metrics", op("metrics", http.MethodGet, "/v1/metrics", "Safe tenant metrics", []string{app.ScopeAdmin}), http.HandlerFunc(s.metrics)}, + {http.MethodGet, "/v1/openapi.json", op("openapi", http.MethodGet, "/v1/openapi.json", "OpenAPI", nil), http.HandlerFunc(s.openapi)}, + {http.MethodGet, "/v1/admin/instance", op("instanceAdminSnapshot", http.MethodGet, "/v1/admin/instance", "Instance admin snapshot", []string{app.ScopeInstanceAdmin}), http.HandlerFunc(s.instanceAdminSnapshot)}, + } +} + +func (s *Server) identityRoutes() []routeDef { + return []routeDef{ + {http.MethodPost, "/v1/organizations", op("createOrganization", http.MethodPost, "/v1/organizations", "Create organization", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.createOrganization)}, + {http.MethodPost, "/v1/users", op("createUser", http.MethodPost, "/v1/users", "Create user", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.createUser)}, + {http.MethodPost, "/v1/users/{id}/deactivate", op("deactivateUser", http.MethodPost, "/v1/users/{id}/deactivate", "Deactivate user", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.deactivateUser)}, + {http.MethodPost, "/v1/role-bindings", op("createRoleBinding", http.MethodPost, "/v1/role-bindings", "Create role binding", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.createRoleBinding)}, + {http.MethodGet, "/v1/role-bindings", op("listRoleBindings", http.MethodGet, "/v1/role-bindings", "List role bindings", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.listRoleBindings)}, + {http.MethodPost, "/v1/sso/providers", op("createSSOProvider", http.MethodPost, "/v1/sso/providers", "Create SSO provider", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.createSSOProvider)}, + {http.MethodPost, "/v1/sso/identity-links", op("linkSSOIdentity", http.MethodPost, "/v1/sso/identity-links", "Link SSO identity", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.linkSSOIdentity)}, + {http.MethodPost, "/v1/sso/sessions", op("createSSOSession", http.MethodPost, "/v1/sso/sessions", "Create SSO session", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.createSSOSession)}, + {http.MethodPost, "/v1/sso/sessions/{id}/revoke", op("revokeSSOSession", http.MethodPost, "/v1/sso/sessions/{id}/revoke", "Revoke SSO session", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.revokeSSOSession)}, + } +} + +func (s *Server) collectorRoutes() []routeDef { + return []routeDef{ + {http.MethodPost, "/v1/collectors", op("createCollector", http.MethodPost, "/v1/collectors", "Create collector", []string{app.ScopeCollectorAdmin}), http.HandlerFunc(s.createCollector)}, + {http.MethodGet, "/v1/collectors", op("listCollectors", http.MethodGet, "/v1/collectors", "List collectors", []string{app.ScopeCollectorRead}), http.HandlerFunc(s.listCollectors)}, + {http.MethodPost, "/v1/collectors/{id}/releases", op("recordCollectorRelease", http.MethodPost, "/v1/collectors/{id}/releases", "Record collector release evidence", []string{app.ScopeCollectorAdmin}), http.HandlerFunc(s.recordCollectorRelease)}, + {http.MethodGet, "/v1/collectors/{id}/health", op("collectorHealthReport", http.MethodGet, "/v1/collectors/{id}/health", "Collector health report", []string{app.ScopeCollectorRead}), http.HandlerFunc(s.collectorHealthReport)}, + {http.MethodPost, "/v1/commercial-collectors", op("createCommercialCollector", http.MethodPost, "/v1/commercial-collectors", "Create commercial collector definition", []string{app.ScopeCollectorAdmin}), http.HandlerFunc(s.createCommercialCollector)}, + {http.MethodGet, "/v1/commercial-collectors", op("listCommercialCollectors", http.MethodGet, "/v1/commercial-collectors", "List commercial collector definitions", []string{app.ScopeCollectorRead}), http.HandlerFunc(s.listCommercialCollectors)}, + } +} + +func (s *Server) controlRoutes() []routeDef { + return []routeDef{ + {http.MethodPost, "/v1/control-frameworks", op("createControlFramework", http.MethodPost, "/v1/control-frameworks", "Create control framework", []string{app.ScopeControlsAdmin}), http.HandlerFunc(s.createControlFramework)}, + {http.MethodGet, "/v1/control-frameworks", op("listControlFrameworks", http.MethodGet, "/v1/control-frameworks", "List control frameworks", []string{app.ScopeControlsRead}), http.HandlerFunc(s.listControlFrameworks)}, + {http.MethodGet, "/v1/control-framework-template-packs", op("listControlFrameworkTemplatePacks", http.MethodGet, "/v1/control-framework-template-packs", "List control framework template packs", []string{app.ScopeControlsRead}), http.HandlerFunc(s.listControlFrameworkTemplatePacks)}, + {http.MethodPost, "/v1/control-framework-template-packs/{slug}/install", op("installControlFrameworkTemplatePack", http.MethodPost, "/v1/control-framework-template-packs/{slug}/install", "Install control framework template pack", []string{app.ScopeControlsAdmin}), http.HandlerFunc(s.installControlFrameworkTemplatePack)}, + {http.MethodPost, "/v1/controls", op("createSecurityControl", http.MethodPost, "/v1/controls", "Create security control", []string{app.ScopeControlsAdmin}), http.HandlerFunc(s.createSecurityControl)}, + {http.MethodGet, "/v1/controls/{id}", op("getSecurityControl", http.MethodGet, "/v1/controls/{id}", "Get security control", []string{app.ScopeControlsRead}), http.HandlerFunc(s.getSecurityControl)}, + {http.MethodPost, "/v1/controls/{id}/evidence", op("linkControlEvidence", http.MethodPost, "/v1/controls/{id}/evidence", "Link control evidence", []string{app.ScopeControlsWrite}), http.HandlerFunc(s.linkControlEvidence)}, + {http.MethodGet, "/v1/control-evidence", op("listControlEvidence", http.MethodGet, "/v1/control-evidence", "List control evidence", []string{app.ScopeControlsRead}), http.HandlerFunc(s.listControlEvidence)}, + {http.MethodGet, "/v1/reports/control-coverage", op("controlCoverageReport", http.MethodGet, "/v1/reports/control-coverage", "Control coverage report", []string{app.ScopeReportRead}), http.HandlerFunc(s.controlCoverageReport)}, + {http.MethodGet, "/v1/reports/cra-readiness", op("craReadinessReport", http.MethodGet, "/v1/reports/cra-readiness", "CRA readiness report", []string{app.ScopeReportRead}), http.HandlerFunc(s.craReadinessReport)}, + } +} + +func (s *Server) productReleaseRoutes() []routeDef { + return []routeDef{ + {http.MethodPost, "/v1/products", op("createProduct", http.MethodPost, "/v1/products", "Create product", []string{app.ScopeProductWrite}), http.HandlerFunc(s.createProduct)}, + {http.MethodGet, "/v1/products", op("listProducts", http.MethodGet, "/v1/products", "List products", []string{app.ScopeProductRead}), http.HandlerFunc(s.listProducts)}, + {http.MethodPost, "/v1/projects", op("createProject", http.MethodPost, "/v1/projects", "Create project", []string{app.ScopeProjectWrite}), http.HandlerFunc(s.createProject)}, + {http.MethodPost, "/v1/releases", op("createRelease", http.MethodPost, "/v1/releases", "Create release", []string{app.ScopeReleaseWrite}), http.HandlerFunc(s.createRelease)}, + {http.MethodGet, "/v1/releases/{id}", op("getRelease", http.MethodGet, "/v1/releases/{id}", "Get release", []string{app.ScopeReleaseRead}), http.HandlerFunc(s.getRelease)}, + {http.MethodPost, "/v1/releases/{id}/freeze", op("freezeRelease", http.MethodPost, "/v1/releases/{id}/freeze", "Freeze release", []string{app.ScopeReleaseWrite}), http.HandlerFunc(s.freezeRelease)}, + {http.MethodPost, "/v1/releases/{id}/approve", op("approveRelease", http.MethodPost, "/v1/releases/{id}/approve", "Approve release", []string{app.ScopeReleaseWrite}), http.HandlerFunc(s.approveRelease)}, + {http.MethodPost, "/v1/release-candidates", op("createReleaseCandidate", http.MethodPost, "/v1/release-candidates", "Create release candidate", []string{app.ScopeReleaseWrite}), http.HandlerFunc(s.createReleaseCandidate)}, + {http.MethodGet, "/v1/release-candidates", op("listReleaseCandidates", http.MethodGet, "/v1/release-candidates", "List release candidates", []string{app.ScopeReleaseRead}), http.HandlerFunc(s.listReleaseCandidates)}, + {http.MethodGet, "/v1/release-candidates/{id}", op("getReleaseCandidate", http.MethodGet, "/v1/release-candidates/{id}", "Get release candidate", []string{app.ScopeReleaseRead}), http.HandlerFunc(s.getReleaseCandidate)}, + {http.MethodPost, "/v1/release-candidates/{id}/promote", op("promoteReleaseCandidate", http.MethodPost, "/v1/release-candidates/{id}/promote", "Promote release candidate", []string{app.ScopeReleaseWrite}), http.HandlerFunc(s.promoteReleaseCandidate)}, + {http.MethodPost, "/v1/release-candidates/{id}/reject", op("rejectReleaseCandidate", http.MethodPost, "/v1/release-candidates/{id}/reject", "Reject release candidate", []string{app.ScopeReleaseWrite}), http.HandlerFunc(s.rejectReleaseCandidate)}, + } +} + +func (s *Server) artifactBuildSourceRoutes() []routeDef { + return []routeDef{ + {http.MethodPost, "/v1/artifacts", op("registerArtifact", http.MethodPost, "/v1/artifacts", "Register artifact", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.registerArtifact)}, + {http.MethodPost, "/v1/container-images", op("registerContainerImage", http.MethodPost, "/v1/container-images", "Register container image", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.registerContainerImage)}, + {http.MethodPost, "/v1/artifact-signatures", op("createArtifactSignature", http.MethodPost, "/v1/artifact-signatures", "Create artifact signature", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.createArtifactSignature)}, + {http.MethodGet, "/v1/artifact-signatures/{id}", op("getArtifactSignature", http.MethodGet, "/v1/artifact-signatures/{id}", "Get artifact signature", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.getArtifactSignature)}, + {http.MethodPost, "/v1/artifact-signatures/{id}/verify-cosign", op("verifyCosignSignature", http.MethodPost, "/v1/artifact-signatures/{id}/verify-cosign", "Verify cosign-style artifact signature", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.verifyCosignSignature)}, + {http.MethodPost, "/v1/builds", op("createBuild", http.MethodPost, "/v1/builds", "Create build run", []string{app.ScopeBuildWrite}), http.HandlerFunc(s.createBuild)}, + {http.MethodGet, "/v1/builds/{id}", op("getBuild", http.MethodGet, "/v1/builds/{id}", "Get build run", []string{app.ScopeBuildRead}), http.HandlerFunc(s.getBuild)}, + {http.MethodPost, "/v1/builds/{id}/attestations", op("uploadBuildAttestation", http.MethodPost, "/v1/builds/{id}/attestations", "Upload build attestation", []string{app.ScopeBuildWrite}), http.HandlerFunc(s.uploadBuildAttestation)}, + {http.MethodPost, "/v1/build-attestations/{id}/verify-signature", op("verifyBuildAttestationSignature", http.MethodPost, "/v1/build-attestations/{id}/verify-signature", "Verify build attestation signature", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.verifyBuildAttestationSignature)}, + {http.MethodPost, "/v1/dsse-trust-roots", op("createDSSETrustRoot", http.MethodPost, "/v1/dsse-trust-roots", "Create DSSE trust root", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.createDSSETrustRoot)}, + {http.MethodPost, "/v1/source/repositories", op("createSourceRepository", http.MethodPost, "/v1/source/repositories", "Create source repository", []string{app.ScopeSourceWrite}), http.HandlerFunc(s.createSourceRepository)}, + {http.MethodGet, "/v1/source/repositories", op("listSourceRepositories", http.MethodGet, "/v1/source/repositories", "List source repositories", []string{app.ScopeSourceRead}), http.HandlerFunc(s.listSourceRepositories)}, + {http.MethodPost, "/v1/source/commits", op("recordSourceCommit", http.MethodPost, "/v1/source/commits", "Record source commit", []string{app.ScopeSourceWrite}), http.HandlerFunc(s.recordSourceCommit)}, + {http.MethodPost, "/v1/source/branches", op("upsertSourceBranch", http.MethodPost, "/v1/source/branches", "Record source branch", []string{app.ScopeSourceWrite}), http.HandlerFunc(s.upsertSourceBranch)}, + {http.MethodPost, "/v1/source/pull-requests", op("recordPullRequest", http.MethodPost, "/v1/source/pull-requests", "Record pull request", []string{app.ScopeSourceWrite}), http.HandlerFunc(s.recordPullRequest)}, + {http.MethodPost, "/v1/collectors/github/source-snapshots", op("uploadGitHubSourceSnapshot", http.MethodPost, "/v1/collectors/github/source-snapshots", "Upload GitHub source snapshot", []string{app.ScopeSourceWrite}), http.HandlerFunc(s.uploadGitHubSourceSnapshot)}, + {http.MethodPost, "/v1/collectors/gitlab/source-snapshots", op("uploadGitLabSourceSnapshot", http.MethodPost, "/v1/collectors/gitlab/source-snapshots", "Upload GitLab source snapshot", []string{app.ScopeSourceWrite}), http.HandlerFunc(s.uploadGitLabSourceSnapshot)}, + } +} + +func (s *Server) deploymentIncidentSecurityRoutes() []routeDef { + return []routeDef{ + {http.MethodPost, "/v1/environments", op("createDeploymentEnvironment", http.MethodPost, "/v1/environments", "Create deployment environment", []string{app.ScopeDeploymentWrite}), http.HandlerFunc(s.createDeploymentEnvironment)}, + {http.MethodGet, "/v1/environments", op("listDeploymentEnvironments", http.MethodGet, "/v1/environments", "List deployment environments", []string{app.ScopeDeploymentRead}), http.HandlerFunc(s.listDeploymentEnvironments)}, + {http.MethodPost, "/v1/deployments", op("recordDeployment", http.MethodPost, "/v1/deployments", "Record deployment", []string{app.ScopeDeploymentWrite}), http.HandlerFunc(s.recordDeployment)}, + {http.MethodGet, "/v1/deployments", op("listDeployments", http.MethodGet, "/v1/deployments", "List deployments", []string{app.ScopeDeploymentRead}), http.HandlerFunc(s.listDeployments)}, + {http.MethodGet, "/v1/deployments/{id}", op("getDeployment", http.MethodGet, "/v1/deployments/{id}", "Get deployment", []string{app.ScopeDeploymentRead}), http.HandlerFunc(s.getDeployment)}, + {http.MethodPost, "/v1/incidents", op("createIncident", http.MethodPost, "/v1/incidents", "Create incident", []string{app.ScopeIncidentWrite}), http.HandlerFunc(s.createIncident)}, + {http.MethodPost, "/v1/incidents/{id}/timeline", op("recordIncidentTimeline", http.MethodPost, "/v1/incidents/{id}/timeline", "Record incident timeline event", []string{app.ScopeIncidentWrite}), http.HandlerFunc(s.recordIncidentTimeline)}, + {http.MethodPost, "/v1/remediation-tasks", op("createRemediationTask", http.MethodPost, "/v1/remediation-tasks", "Create remediation task", []string{app.ScopeIncidentWrite}), http.HandlerFunc(s.createRemediationTask)}, + {http.MethodGet, "/v1/reports/incident-package", op("incidentReport", http.MethodGet, "/v1/reports/incident-package", "Incident package report", []string{app.ScopeIncidentRead}), http.HandlerFunc(s.incidentReport)}, + {http.MethodPost, "/v1/security-scans", op("uploadSecurityScan", http.MethodPost, "/v1/security-scans", "Upload security scan", []string{app.ScopeSecurityWrite}), http.HandlerFunc(s.uploadSecurityScan)}, + {http.MethodPost, "/v1/api-security-scans", op("uploadAPISecurityScan", http.MethodPost, "/v1/api-security-scans", "Upload API security scan", []string{app.ScopeSecurityWrite}), http.HandlerFunc(s.uploadAPISecurityScan)}, + {http.MethodPost, "/v1/security-documents", op("uploadManualSecurityDocument", http.MethodPost, "/v1/security-documents", "Upload manual security document", []string{app.ScopeSecurityWrite}), http.HandlerFunc(s.uploadManualSecurityDocument)}, + } +} + +func (s *Server) packagePortalRoutes() []routeDef { + return []routeDef{ + {http.MethodPost, "/v1/waivers", op("createWaiver", http.MethodPost, "/v1/waivers", "Create waiver", []string{app.ScopePolicyWrite}), http.HandlerFunc(s.createWaiver)}, + {http.MethodPost, "/v1/waivers/{id}/approve", op("approveWaiver", http.MethodPost, "/v1/waivers/{id}/approve", "Approve waiver", []string{app.ScopePolicyWrite}), http.HandlerFunc(s.approveWaiver)}, + {http.MethodPost, "/v1/approvals", op("createApproval", http.MethodPost, "/v1/approvals", "Create approval record", []string{app.ScopeReleaseWrite}), http.HandlerFunc(s.createApproval)}, + {http.MethodPost, "/v1/redaction-profiles", op("createRedactionProfile", http.MethodPost, "/v1/redaction-profiles", "Create redaction profile", []string{app.ScopePackageWrite}), http.HandlerFunc(s.createRedactionProfile)}, + {http.MethodPost, "/v1/customer-packages", op("createCustomerPackage", http.MethodPost, "/v1/customer-packages", "Create customer security package", []string{app.ScopePackageWrite}), http.HandlerFunc(s.createCustomerPackage)}, + {http.MethodGet, "/v1/customer-packages/{id}", op("getCustomerPackage", http.MethodGet, "/v1/customer-packages/{id}", "Get customer security package", []string{app.ScopePackageRead}), http.HandlerFunc(s.getCustomerPackage)}, + {http.MethodPost, "/v1/customer-portal/access", op("createCustomerPortalAccess", http.MethodPost, "/v1/customer-portal/access", "Create customer portal access", []string{app.ScopePackageWrite}), http.HandlerFunc(s.createCustomerPortalAccess)}, + {http.MethodPost, "/v1/customer-portal/package", op("accessCustomerPortalPackage", http.MethodPost, "/v1/customer-portal/package", "Access customer portal package", nil), http.HandlerFunc(s.accessCustomerPortalPackage)}, + {http.MethodPost, "/v1/questionnaire-templates", op("createQuestionnaireTemplate", http.MethodPost, "/v1/questionnaire-templates", "Create questionnaire template", []string{app.ScopePackageWrite}), http.HandlerFunc(s.createQuestionnaireTemplate)}, + {http.MethodPost, "/v1/questionnaire-packages", op("createQuestionnairePackage", http.MethodPost, "/v1/questionnaire-packages", "Create questionnaire package", []string{app.ScopePackageWrite}), http.HandlerFunc(s.createQuestionnairePackage)}, + {http.MethodGet, "/v1/reports/security-review-package", op("securityReviewPackageReport", http.MethodGet, "/v1/reports/security-review-package", "Security review package report", []string{app.ScopePackageRead}), http.HandlerFunc(s.securityReviewPackageReport)}, + {http.MethodGet, "/v1/reports/cra-readiness-html", op("craReadinessHTMLPackage", http.MethodGet, "/v1/reports/cra-readiness-html", "CRA readiness HTML package", []string{app.ScopeReportRead}), http.HandlerFunc(s.craReadinessHTMLPackage)}, + {http.MethodPost, "/v1/report-templates", op("createReportTemplate", http.MethodPost, "/v1/report-templates", "Create report template", []string{app.ScopeReportRead}), http.HandlerFunc(s.createReportTemplate)}, + {http.MethodPost, "/v1/report-templates/{id}/render", op("renderReportTemplate", http.MethodPost, "/v1/report-templates/{id}/render", "Render report template", []string{app.ScopeReportRead}), http.HandlerFunc(s.renderReportTemplate)}, + } +} + +func (s *Server) evidenceRiskPolicyRoutes() []routeDef { + return []routeDef{ + {http.MethodPost, "/v1/evidence-bundles", op("exportEvidenceBundle", http.MethodPost, "/v1/evidence-bundles", "Export evidence bundle", []string{app.ScopeBundleRead}), http.HandlerFunc(s.exportEvidenceBundle)}, + {http.MethodPost, "/v1/evidence-bundles/import", op("importEvidenceBundle", http.MethodPost, "/v1/evidence-bundles/import", "Import evidence bundle", []string{app.ScopeBundleWrite}), http.HandlerFunc(s.importEvidenceBundle)}, + {http.MethodPost, "/v1/sboms/spdx", op("uploadSPDXSBOM", http.MethodPost, "/v1/sboms/spdx", "Upload SPDX SBOM", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.uploadSPDXSBOM)}, + {http.MethodPost, "/v1/sbom-diffs", op("createSBOMDiff", http.MethodPost, "/v1/sbom-diffs", "Create SBOM diff", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.createSBOMDiff)}, + {http.MethodPost, "/v1/evidence", op("createEvidence", http.MethodPost, "/v1/evidence", "Create evidence", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.createEvidence)}, + {http.MethodGet, "/v1/evidence", op("listEvidence", http.MethodGet, "/v1/evidence", "List evidence", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.listEvidence)}, + {http.MethodGet, "/v1/evidence/search", op("searchEvidence", http.MethodGet, "/v1/evidence/search", "Search evidence", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.searchEvidence)}, + {http.MethodGet, "/v1/evidence/{id}", op("getEvidence", http.MethodGet, "/v1/evidence/{id}", "Get evidence", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.getEvidence)}, + {http.MethodPost, "/v1/evidence/{id}/supersede", op("supersedeEvidence", http.MethodPost, "/v1/evidence/{id}/supersede", "Supersede evidence", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.supersedeEvidence)}, + {http.MethodPost, "/v1/evidence/{id}/link", op("linkEvidence", http.MethodPost, "/v1/evidence/{id}/link", "Link evidence", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.linkEvidence)}, + {http.MethodPost, "/v1/evidence/{id}/lifecycle-events", op("recordEvidenceLifecycleEvent", http.MethodPost, "/v1/evidence/{id}/lifecycle-events", "Record evidence lifecycle event", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.recordEvidenceLifecycleEvent)}, + {http.MethodGet, "/v1/evidence/{id}/lifecycle-events", op("listEvidenceLifecycleEvents", http.MethodGet, "/v1/evidence/{id}/lifecycle-events", "List evidence lifecycle events", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.listEvidenceLifecycleEvents)}, + {http.MethodPost, "/v1/sboms", op("uploadSBOM", http.MethodPost, "/v1/sboms", "Upload CycloneDX SBOM", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.uploadSBOM)}, + {http.MethodGet, "/v1/sboms/{id}", op("getSBOM", http.MethodGet, "/v1/sboms/{id}", "Get SBOM", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.getSBOM)}, + {http.MethodPost, "/v1/vex", op("uploadVEX", http.MethodPost, "/v1/vex", "Upload OpenVEX document", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.uploadVEX)}, + {http.MethodPost, "/v1/vex/cyclonedx", op("uploadCycloneDXVEX", http.MethodPost, "/v1/vex/cyclonedx", "Upload CycloneDX VEX document", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.uploadCycloneDXVEX)}, + {http.MethodGet, "/v1/vex/{id}", op("getVEX", http.MethodGet, "/v1/vex/{id}", "Get VEX document", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.getVEX)}, + {http.MethodPost, "/v1/vulnerability-scans", op("uploadVulnerabilityScan", http.MethodPost, "/v1/vulnerability-scans", "Upload vulnerability scan", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.uploadVulnerabilityScan)}, + {http.MethodGet, "/v1/vulnerability-scans/{id}", op("getVulnerabilityScan", http.MethodGet, "/v1/vulnerability-scans/{id}", "Get vulnerability scan", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.getVulnerabilityScan)}, + {http.MethodPost, "/v1/vulnerability-findings/{id}/decisions", op("createVulnerabilityDecision", http.MethodPost, "/v1/vulnerability-findings/{id}/decisions", "Create vulnerability decision", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.createVulnerabilityDecision)}, + {http.MethodPost, "/v1/vulnerability-findings/{id}/workflow", op("recordVulnerabilityWorkflow", http.MethodPost, "/v1/vulnerability-findings/{id}/workflow", "Record vulnerability workflow event", []string{app.ScopeSecurityWrite}), http.HandlerFunc(s.recordVulnerabilityWorkflow)}, + {http.MethodGet, "/v1/reports/vulnerability-posture", op("vulnerabilityPostureReport", http.MethodGet, "/v1/reports/vulnerability-posture", "Vulnerability posture report", []string{app.ScopeSecurityRead}), http.HandlerFunc(s.vulnerabilityPostureReport)}, + {http.MethodPost, "/v1/openapi-contracts", op("uploadOpenAPIContract", http.MethodPost, "/v1/openapi-contracts", "Upload OpenAPI contract", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.uploadOpenAPIContract)}, + {http.MethodGet, "/v1/openapi-contracts/{id}", op("getOpenAPIContract", http.MethodGet, "/v1/openapi-contracts/{id}", "Get OpenAPI contract", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.getOpenAPIContract)}, + {http.MethodPost, "/v1/openapi-diffs", op("createOpenAPIDiff", http.MethodPost, "/v1/openapi-diffs", "Create OpenAPI contract diff", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.createOpenAPIDiff)}, + {http.MethodPost, "/v1/policies/evaluate", op("evaluatePolicy", http.MethodPost, "/v1/policies/evaluate", "Evaluate release policy", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.evaluatePolicy)}, + {http.MethodPost, "/v1/custom-policies", op("createCustomPolicy", http.MethodPost, "/v1/custom-policies", "Create custom policy", []string{app.ScopePolicyWrite}), http.HandlerFunc(s.createCustomPolicy)}, + {http.MethodPost, "/v1/custom-policies/{id}/evaluate", op("evaluateCustomPolicy", http.MethodPost, "/v1/custom-policies/{id}/evaluate", "Evaluate custom policy", []string{app.ScopePolicyRead}), http.HandlerFunc(s.evaluateCustomPolicy)}, + {http.MethodPost, "/v1/exceptions", op("createException", http.MethodPost, "/v1/exceptions", "Create exception", []string{app.ScopeReleaseWrite}), http.HandlerFunc(s.createException)}, + {http.MethodGet, "/v1/exceptions", op("listExceptions", http.MethodGet, "/v1/exceptions", "List exceptions", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.listExceptions)}, + {http.MethodPost, "/v1/exceptions/{id}/approve", op("approveException", http.MethodPost, "/v1/exceptions/{id}/approve", "Approve exception", []string{app.ScopeReleaseWrite}), http.HandlerFunc(s.approveException)}, + {http.MethodGet, "/v1/reports/missing-evidence", op("missingEvidenceReport", http.MethodGet, "/v1/reports/missing-evidence", "Missing evidence report", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.missingEvidenceReport)}, + {http.MethodGet, "/v1/reports/release-readiness", op("releaseReadinessReport", http.MethodGet, "/v1/reports/release-readiness", "Release readiness report", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.releaseReadinessReport)}, + } +} + +func (s *Server) integrityOpsRoutes() []routeDef { + return []routeDef{ + {http.MethodPost, "/v1/release-bundles", op("createReleaseBundle", http.MethodPost, "/v1/release-bundles", "Create release bundle", []string{app.ScopeBundleWrite}), http.HandlerFunc(s.createReleaseBundle)}, + {http.MethodGet, "/v1/release-bundles/{id}", op("getReleaseBundle", http.MethodGet, "/v1/release-bundles/{id}", "Get release bundle", []string{app.ScopeBundleRead}), http.HandlerFunc(s.getReleaseBundle)}, + {http.MethodGet, "/v1/release-bundles/{id}/manifest", op("getReleaseBundleManifest", http.MethodGet, "/v1/release-bundles/{id}/manifest", "Get release bundle manifest", []string{app.ScopeBundleRead}), http.HandlerFunc(s.getReleaseBundleManifest)}, + {http.MethodGet, "/v1/release-bundles/{id}/verify", op("verifyReleaseBundle", http.MethodGet, "/v1/release-bundles/{id}/verify", "Verify release bundle", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.verifyReleaseBundle)}, + {http.MethodGet, "/v1/audit-chain/verify", op("verifyAuditChain", http.MethodGet, "/v1/audit-chain/verify", "Verify audit chain", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.verifyAuditChain)}, + {http.MethodGet, "/v1/audit-log", op("listAuditLog", http.MethodGet, "/v1/audit-log", "List tenant audit log", []string{app.ScopeAdmin}), http.HandlerFunc(s.listAuditLog)}, + {http.MethodPost, "/v1/merkle-batches", op("createMerkleBatch", http.MethodPost, "/v1/merkle-batches", "Create Merkle checkpoint batch", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.createMerkleBatch)}, + {http.MethodGet, "/v1/merkle-batches/{id}/verify", op("verifyMerkleBatch", http.MethodGet, "/v1/merkle-batches/{id}/verify", "Verify Merkle checkpoint batch", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.verifyMerkleBatch)}, + {http.MethodPost, "/v1/transparency-checkpoints", op("createTransparencyCheckpoint", http.MethodPost, "/v1/transparency-checkpoints", "Record external transparency checkpoint", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.createTransparencyCheckpoint)}, + {http.MethodPost, "/v1/object-retention-policies", op("createObjectRetentionPolicy", http.MethodPost, "/v1/object-retention-policies", "Create object retention policy record", []string{app.ScopeAdmin}), http.HandlerFunc(s.createObjectRetentionPolicy)}, + {http.MethodPost, "/v1/object-retention-policies/{id}/verify", op("verifyObjectRetentionPolicy", http.MethodPost, "/v1/object-retention-policies/{id}/verify", "Verify object retention policy record", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.verifyObjectRetentionPolicy)}, + {http.MethodPost, "/v1/legal-holds", op("createLegalHold", http.MethodPost, "/v1/legal-holds", "Create legal hold", []string{app.ScopeAdmin}), http.HandlerFunc(s.createLegalHold)}, + {http.MethodPost, "/v1/retention-overrides", op("createRetentionOverride", http.MethodPost, "/v1/retention-overrides", "Create retention override", []string{app.ScopeAdmin}), http.HandlerFunc(s.createRetentionOverride)}, + {http.MethodGet, "/v1/reports/retention", op("retentionReport", http.MethodGet, "/v1/reports/retention", "Retention report", []string{app.ScopeAdmin}), http.HandlerFunc(s.retentionReport)}, + {http.MethodPost, "/v1/backup-manifests", op("generateBackupManifest", http.MethodPost, "/v1/backup-manifests", "Generate backup manifest", []string{app.ScopeAdmin}), http.HandlerFunc(s.generateBackupManifest)}, + {http.MethodGet, "/v1/backup-manifests/{id}/verify", op("verifyBackupManifest", http.MethodGet, "/v1/backup-manifests/{id}/verify", "Verify backup manifest", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.verifyBackupManifest)}, + } +} + +func (s *Server) keyAndAdminRoutes() []routeDef { + return []routeDef{ + {http.MethodGet, "/v1/signing-keys", op("listSigningKeys", http.MethodGet, "/v1/signing-keys", "List signing keys", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.listSigningKeys)}, + {http.MethodPost, "/v1/signing-keys/rotate", op("rotateSigningKey", http.MethodPost, "/v1/signing-keys/rotate", "Rotate signing key", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.rotateSigningKey)}, + {http.MethodPost, "/v1/signing-keys/{id}/revoke", op("revokeSigningKey", http.MethodPost, "/v1/signing-keys/{id}/revoke", "Revoke signing key", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.revokeSigningKey)}, + {http.MethodPost, "/v1/signing-providers", op("createSigningProvider", http.MethodPost, "/v1/signing-providers", "Create signing provider record", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.createSigningProvider)}, + {http.MethodPost, "/v1/verify", op("verify", http.MethodPost, "/v1/verify", "Verify subject", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.verifySubject)}, + {http.MethodPost, "/v1/api-keys", op("createAPIKey", http.MethodPost, "/v1/api-keys", "Create API key", []string{app.ScopeAdmin}), http.HandlerFunc(s.createAPIKey)}, + {http.MethodGet, "/v1/api-keys", op("listAPIKeys", http.MethodGet, "/v1/api-keys", "List API keys", []string{app.ScopeAdmin}), http.HandlerFunc(s.listAPIKeys)}, + } +} diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index b1587a6..470dad9 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -58,164 +58,6 @@ func (s *Server) ValidateRoutes() error { return s.routes.Validate() } -func (s *Server) registerRoutes() error { - routes := []struct { - method string - path string - op specs.Operation - handler http.Handler - }{ - {http.MethodGet, "/v1/health", op("health", http.MethodGet, "/v1/health", "Health", nil), http.HandlerFunc(s.health)}, - {http.MethodGet, "/v1/ready", op("ready", http.MethodGet, "/v1/ready", "Readiness", nil), http.HandlerFunc(s.ready)}, - {http.MethodGet, "/v1/version", op("version", http.MethodGet, "/v1/version", "Version", nil), http.HandlerFunc(s.version)}, - {http.MethodGet, "/v1/metrics", op("metrics", http.MethodGet, "/v1/metrics", "Safe tenant metrics", []string{app.ScopeAdmin}), http.HandlerFunc(s.metrics)}, - {http.MethodGet, "/v1/openapi.json", op("openapi", http.MethodGet, "/v1/openapi.json", "OpenAPI", nil), http.HandlerFunc(s.openapi)}, - {http.MethodGet, "/v1/admin/instance", op("instanceAdminSnapshot", http.MethodGet, "/v1/admin/instance", "Instance admin snapshot", []string{app.ScopeInstanceAdmin}), http.HandlerFunc(s.instanceAdminSnapshot)}, - {http.MethodPost, "/v1/organizations", op("createOrganization", http.MethodPost, "/v1/organizations", "Create organization", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.createOrganization)}, - {http.MethodPost, "/v1/users", op("createUser", http.MethodPost, "/v1/users", "Create user", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.createUser)}, - {http.MethodPost, "/v1/users/{id}/deactivate", op("deactivateUser", http.MethodPost, "/v1/users/{id}/deactivate", "Deactivate user", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.deactivateUser)}, - {http.MethodPost, "/v1/role-bindings", op("createRoleBinding", http.MethodPost, "/v1/role-bindings", "Create role binding", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.createRoleBinding)}, - {http.MethodGet, "/v1/role-bindings", op("listRoleBindings", http.MethodGet, "/v1/role-bindings", "List role bindings", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.listRoleBindings)}, - {http.MethodPost, "/v1/sso/providers", op("createSSOProvider", http.MethodPost, "/v1/sso/providers", "Create SSO provider", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.createSSOProvider)}, - {http.MethodPost, "/v1/sso/identity-links", op("linkSSOIdentity", http.MethodPost, "/v1/sso/identity-links", "Link SSO identity", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.linkSSOIdentity)}, - {http.MethodPost, "/v1/sso/sessions", op("createSSOSession", http.MethodPost, "/v1/sso/sessions", "Create SSO session", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.createSSOSession)}, - {http.MethodPost, "/v1/sso/sessions/{id}/revoke", op("revokeSSOSession", http.MethodPost, "/v1/sso/sessions/{id}/revoke", "Revoke SSO session", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.revokeSSOSession)}, - {http.MethodPost, "/v1/collectors", op("createCollector", http.MethodPost, "/v1/collectors", "Create collector", []string{app.ScopeCollectorAdmin}), http.HandlerFunc(s.createCollector)}, - {http.MethodGet, "/v1/collectors", op("listCollectors", http.MethodGet, "/v1/collectors", "List collectors", []string{app.ScopeCollectorRead}), http.HandlerFunc(s.listCollectors)}, - {http.MethodPost, "/v1/collectors/{id}/releases", op("recordCollectorRelease", http.MethodPost, "/v1/collectors/{id}/releases", "Record collector release evidence", []string{app.ScopeCollectorAdmin}), http.HandlerFunc(s.recordCollectorRelease)}, - {http.MethodGet, "/v1/collectors/{id}/health", op("collectorHealthReport", http.MethodGet, "/v1/collectors/{id}/health", "Collector health report", []string{app.ScopeCollectorRead}), http.HandlerFunc(s.collectorHealthReport)}, - {http.MethodPost, "/v1/control-frameworks", op("createControlFramework", http.MethodPost, "/v1/control-frameworks", "Create control framework", []string{app.ScopeControlsAdmin}), http.HandlerFunc(s.createControlFramework)}, - {http.MethodGet, "/v1/control-frameworks", op("listControlFrameworks", http.MethodGet, "/v1/control-frameworks", "List control frameworks", []string{app.ScopeControlsRead}), http.HandlerFunc(s.listControlFrameworks)}, - {http.MethodGet, "/v1/control-framework-template-packs", op("listControlFrameworkTemplatePacks", http.MethodGet, "/v1/control-framework-template-packs", "List control framework template packs", []string{app.ScopeControlsRead}), http.HandlerFunc(s.listControlFrameworkTemplatePacks)}, - {http.MethodPost, "/v1/control-framework-template-packs/{slug}/install", op("installControlFrameworkTemplatePack", http.MethodPost, "/v1/control-framework-template-packs/{slug}/install", "Install control framework template pack", []string{app.ScopeControlsAdmin}), http.HandlerFunc(s.installControlFrameworkTemplatePack)}, - {http.MethodPost, "/v1/controls", op("createSecurityControl", http.MethodPost, "/v1/controls", "Create security control", []string{app.ScopeControlsAdmin}), http.HandlerFunc(s.createSecurityControl)}, - {http.MethodGet, "/v1/controls/{id}", op("getSecurityControl", http.MethodGet, "/v1/controls/{id}", "Get security control", []string{app.ScopeControlsRead}), http.HandlerFunc(s.getSecurityControl)}, - {http.MethodPost, "/v1/controls/{id}/evidence", op("linkControlEvidence", http.MethodPost, "/v1/controls/{id}/evidence", "Link control evidence", []string{app.ScopeControlsWrite}), http.HandlerFunc(s.linkControlEvidence)}, - {http.MethodGet, "/v1/control-evidence", op("listControlEvidence", http.MethodGet, "/v1/control-evidence", "List control evidence", []string{app.ScopeControlsRead}), http.HandlerFunc(s.listControlEvidence)}, - {http.MethodPost, "/v1/products", op("createProduct", http.MethodPost, "/v1/products", "Create product", []string{app.ScopeProductWrite}), http.HandlerFunc(s.createProduct)}, - {http.MethodGet, "/v1/products", op("listProducts", http.MethodGet, "/v1/products", "List products", []string{app.ScopeProductRead}), http.HandlerFunc(s.listProducts)}, - {http.MethodPost, "/v1/projects", op("createProject", http.MethodPost, "/v1/projects", "Create project", []string{app.ScopeProjectWrite}), http.HandlerFunc(s.createProject)}, - {http.MethodPost, "/v1/releases", op("createRelease", http.MethodPost, "/v1/releases", "Create release", []string{app.ScopeReleaseWrite}), http.HandlerFunc(s.createRelease)}, - {http.MethodGet, "/v1/releases/{id}", op("getRelease", http.MethodGet, "/v1/releases/{id}", "Get release", []string{app.ScopeReleaseRead}), http.HandlerFunc(s.getRelease)}, - {http.MethodPost, "/v1/releases/{id}/freeze", op("freezeRelease", http.MethodPost, "/v1/releases/{id}/freeze", "Freeze release", []string{app.ScopeReleaseWrite}), http.HandlerFunc(s.freezeRelease)}, - {http.MethodPost, "/v1/releases/{id}/approve", op("approveRelease", http.MethodPost, "/v1/releases/{id}/approve", "Approve release", []string{app.ScopeReleaseWrite}), http.HandlerFunc(s.approveRelease)}, - {http.MethodPost, "/v1/release-candidates", op("createReleaseCandidate", http.MethodPost, "/v1/release-candidates", "Create release candidate", []string{app.ScopeReleaseWrite}), http.HandlerFunc(s.createReleaseCandidate)}, - {http.MethodGet, "/v1/release-candidates", op("listReleaseCandidates", http.MethodGet, "/v1/release-candidates", "List release candidates", []string{app.ScopeReleaseRead}), http.HandlerFunc(s.listReleaseCandidates)}, - {http.MethodGet, "/v1/release-candidates/{id}", op("getReleaseCandidate", http.MethodGet, "/v1/release-candidates/{id}", "Get release candidate", []string{app.ScopeReleaseRead}), http.HandlerFunc(s.getReleaseCandidate)}, - {http.MethodPost, "/v1/release-candidates/{id}/promote", op("promoteReleaseCandidate", http.MethodPost, "/v1/release-candidates/{id}/promote", "Promote release candidate", []string{app.ScopeReleaseWrite}), http.HandlerFunc(s.promoteReleaseCandidate)}, - {http.MethodPost, "/v1/release-candidates/{id}/reject", op("rejectReleaseCandidate", http.MethodPost, "/v1/release-candidates/{id}/reject", "Reject release candidate", []string{app.ScopeReleaseWrite}), http.HandlerFunc(s.rejectReleaseCandidate)}, - {http.MethodPost, "/v1/artifacts", op("registerArtifact", http.MethodPost, "/v1/artifacts", "Register artifact", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.registerArtifact)}, - {http.MethodPost, "/v1/container-images", op("registerContainerImage", http.MethodPost, "/v1/container-images", "Register container image", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.registerContainerImage)}, - {http.MethodPost, "/v1/artifact-signatures", op("createArtifactSignature", http.MethodPost, "/v1/artifact-signatures", "Create artifact signature", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.createArtifactSignature)}, - {http.MethodGet, "/v1/artifact-signatures/{id}", op("getArtifactSignature", http.MethodGet, "/v1/artifact-signatures/{id}", "Get artifact signature", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.getArtifactSignature)}, - {http.MethodPost, "/v1/artifact-signatures/{id}/verify-cosign", op("verifyCosignSignature", http.MethodPost, "/v1/artifact-signatures/{id}/verify-cosign", "Verify cosign-style artifact signature", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.verifyCosignSignature)}, - {http.MethodPost, "/v1/builds", op("createBuild", http.MethodPost, "/v1/builds", "Create build run", []string{app.ScopeBuildWrite}), http.HandlerFunc(s.createBuild)}, - {http.MethodGet, "/v1/builds/{id}", op("getBuild", http.MethodGet, "/v1/builds/{id}", "Get build run", []string{app.ScopeBuildRead}), http.HandlerFunc(s.getBuild)}, - {http.MethodPost, "/v1/builds/{id}/attestations", op("uploadBuildAttestation", http.MethodPost, "/v1/builds/{id}/attestations", "Upload build attestation", []string{app.ScopeBuildWrite}), http.HandlerFunc(s.uploadBuildAttestation)}, - {http.MethodPost, "/v1/build-attestations/{id}/verify-signature", op("verifyBuildAttestationSignature", http.MethodPost, "/v1/build-attestations/{id}/verify-signature", "Verify build attestation signature", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.verifyBuildAttestationSignature)}, - {http.MethodPost, "/v1/dsse-trust-roots", op("createDSSETrustRoot", http.MethodPost, "/v1/dsse-trust-roots", "Create DSSE trust root", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.createDSSETrustRoot)}, - {http.MethodPost, "/v1/source/repositories", op("createSourceRepository", http.MethodPost, "/v1/source/repositories", "Create source repository", []string{app.ScopeSourceWrite}), http.HandlerFunc(s.createSourceRepository)}, - {http.MethodGet, "/v1/source/repositories", op("listSourceRepositories", http.MethodGet, "/v1/source/repositories", "List source repositories", []string{app.ScopeSourceRead}), http.HandlerFunc(s.listSourceRepositories)}, - {http.MethodPost, "/v1/source/commits", op("recordSourceCommit", http.MethodPost, "/v1/source/commits", "Record source commit", []string{app.ScopeSourceWrite}), http.HandlerFunc(s.recordSourceCommit)}, - {http.MethodPost, "/v1/source/branches", op("upsertSourceBranch", http.MethodPost, "/v1/source/branches", "Record source branch", []string{app.ScopeSourceWrite}), http.HandlerFunc(s.upsertSourceBranch)}, - {http.MethodPost, "/v1/source/pull-requests", op("recordPullRequest", http.MethodPost, "/v1/source/pull-requests", "Record pull request", []string{app.ScopeSourceWrite}), http.HandlerFunc(s.recordPullRequest)}, - {http.MethodPost, "/v1/collectors/github/source-snapshots", op("uploadGitHubSourceSnapshot", http.MethodPost, "/v1/collectors/github/source-snapshots", "Upload GitHub source snapshot", []string{app.ScopeSourceWrite}), http.HandlerFunc(s.uploadGitHubSourceSnapshot)}, - {http.MethodPost, "/v1/collectors/gitlab/source-snapshots", op("uploadGitLabSourceSnapshot", http.MethodPost, "/v1/collectors/gitlab/source-snapshots", "Upload GitLab source snapshot", []string{app.ScopeSourceWrite}), http.HandlerFunc(s.uploadGitLabSourceSnapshot)}, - {http.MethodPost, "/v1/environments", op("createDeploymentEnvironment", http.MethodPost, "/v1/environments", "Create deployment environment", []string{app.ScopeDeploymentWrite}), http.HandlerFunc(s.createDeploymentEnvironment)}, - {http.MethodGet, "/v1/environments", op("listDeploymentEnvironments", http.MethodGet, "/v1/environments", "List deployment environments", []string{app.ScopeDeploymentRead}), http.HandlerFunc(s.listDeploymentEnvironments)}, - {http.MethodPost, "/v1/deployments", op("recordDeployment", http.MethodPost, "/v1/deployments", "Record deployment", []string{app.ScopeDeploymentWrite}), http.HandlerFunc(s.recordDeployment)}, - {http.MethodGet, "/v1/deployments", op("listDeployments", http.MethodGet, "/v1/deployments", "List deployments", []string{app.ScopeDeploymentRead}), http.HandlerFunc(s.listDeployments)}, - {http.MethodGet, "/v1/deployments/{id}", op("getDeployment", http.MethodGet, "/v1/deployments/{id}", "Get deployment", []string{app.ScopeDeploymentRead}), http.HandlerFunc(s.getDeployment)}, - {http.MethodPost, "/v1/incidents", op("createIncident", http.MethodPost, "/v1/incidents", "Create incident", []string{app.ScopeIncidentWrite}), http.HandlerFunc(s.createIncident)}, - {http.MethodPost, "/v1/incidents/{id}/timeline", op("recordIncidentTimeline", http.MethodPost, "/v1/incidents/{id}/timeline", "Record incident timeline event", []string{app.ScopeIncidentWrite}), http.HandlerFunc(s.recordIncidentTimeline)}, - {http.MethodPost, "/v1/remediation-tasks", op("createRemediationTask", http.MethodPost, "/v1/remediation-tasks", "Create remediation task", []string{app.ScopeIncidentWrite}), http.HandlerFunc(s.createRemediationTask)}, - {http.MethodGet, "/v1/reports/incident-package", op("incidentReport", http.MethodGet, "/v1/reports/incident-package", "Incident package report", []string{app.ScopeIncidentRead}), http.HandlerFunc(s.incidentReport)}, - {http.MethodPost, "/v1/security-scans", op("uploadSecurityScan", http.MethodPost, "/v1/security-scans", "Upload security scan", []string{app.ScopeSecurityWrite}), http.HandlerFunc(s.uploadSecurityScan)}, - {http.MethodPost, "/v1/api-security-scans", op("uploadAPISecurityScan", http.MethodPost, "/v1/api-security-scans", "Upload API security scan", []string{app.ScopeSecurityWrite}), http.HandlerFunc(s.uploadAPISecurityScan)}, - {http.MethodPost, "/v1/security-documents", op("uploadManualSecurityDocument", http.MethodPost, "/v1/security-documents", "Upload manual security document", []string{app.ScopeSecurityWrite}), http.HandlerFunc(s.uploadManualSecurityDocument)}, - {http.MethodPost, "/v1/waivers", op("createWaiver", http.MethodPost, "/v1/waivers", "Create waiver", []string{app.ScopePolicyWrite}), http.HandlerFunc(s.createWaiver)}, - {http.MethodPost, "/v1/waivers/{id}/approve", op("approveWaiver", http.MethodPost, "/v1/waivers/{id}/approve", "Approve waiver", []string{app.ScopePolicyWrite}), http.HandlerFunc(s.approveWaiver)}, - {http.MethodPost, "/v1/approvals", op("createApproval", http.MethodPost, "/v1/approvals", "Create approval record", []string{app.ScopeReleaseWrite}), http.HandlerFunc(s.createApproval)}, - {http.MethodPost, "/v1/redaction-profiles", op("createRedactionProfile", http.MethodPost, "/v1/redaction-profiles", "Create redaction profile", []string{app.ScopePackageWrite}), http.HandlerFunc(s.createRedactionProfile)}, - {http.MethodPost, "/v1/customer-packages", op("createCustomerPackage", http.MethodPost, "/v1/customer-packages", "Create customer security package", []string{app.ScopePackageWrite}), http.HandlerFunc(s.createCustomerPackage)}, - {http.MethodGet, "/v1/customer-packages/{id}", op("getCustomerPackage", http.MethodGet, "/v1/customer-packages/{id}", "Get customer security package", []string{app.ScopePackageRead}), http.HandlerFunc(s.getCustomerPackage)}, - {http.MethodPost, "/v1/customer-portal/access", op("createCustomerPortalAccess", http.MethodPost, "/v1/customer-portal/access", "Create customer portal access", []string{app.ScopePackageWrite}), http.HandlerFunc(s.createCustomerPortalAccess)}, - {http.MethodPost, "/v1/customer-portal/package", op("accessCustomerPortalPackage", http.MethodPost, "/v1/customer-portal/package", "Access customer portal package", nil), http.HandlerFunc(s.accessCustomerPortalPackage)}, - {http.MethodPost, "/v1/questionnaire-templates", op("createQuestionnaireTemplate", http.MethodPost, "/v1/questionnaire-templates", "Create questionnaire template", []string{app.ScopePackageWrite}), http.HandlerFunc(s.createQuestionnaireTemplate)}, - {http.MethodPost, "/v1/questionnaire-packages", op("createQuestionnairePackage", http.MethodPost, "/v1/questionnaire-packages", "Create questionnaire package", []string{app.ScopePackageWrite}), http.HandlerFunc(s.createQuestionnairePackage)}, - {http.MethodGet, "/v1/reports/security-review-package", op("securityReviewPackageReport", http.MethodGet, "/v1/reports/security-review-package", "Security review package report", []string{app.ScopePackageRead}), http.HandlerFunc(s.securityReviewPackageReport)}, - {http.MethodGet, "/v1/reports/cra-readiness-html", op("craReadinessHTMLPackage", http.MethodGet, "/v1/reports/cra-readiness-html", "CRA readiness HTML package", []string{app.ScopeReportRead}), http.HandlerFunc(s.craReadinessHTMLPackage)}, - {http.MethodPost, "/v1/report-templates", op("createReportTemplate", http.MethodPost, "/v1/report-templates", "Create report template", []string{app.ScopeReportRead}), http.HandlerFunc(s.createReportTemplate)}, - {http.MethodPost, "/v1/report-templates/{id}/render", op("renderReportTemplate", http.MethodPost, "/v1/report-templates/{id}/render", "Render report template", []string{app.ScopeReportRead}), http.HandlerFunc(s.renderReportTemplate)}, - {http.MethodPost, "/v1/evidence-bundles", op("exportEvidenceBundle", http.MethodPost, "/v1/evidence-bundles", "Export evidence bundle", []string{app.ScopeBundleRead}), http.HandlerFunc(s.exportEvidenceBundle)}, - {http.MethodPost, "/v1/evidence-bundles/import", op("importEvidenceBundle", http.MethodPost, "/v1/evidence-bundles/import", "Import evidence bundle", []string{app.ScopeBundleWrite}), http.HandlerFunc(s.importEvidenceBundle)}, - {http.MethodPost, "/v1/sboms/spdx", op("uploadSPDXSBOM", http.MethodPost, "/v1/sboms/spdx", "Upload SPDX SBOM", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.uploadSPDXSBOM)}, - {http.MethodPost, "/v1/sbom-diffs", op("createSBOMDiff", http.MethodPost, "/v1/sbom-diffs", "Create SBOM diff", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.createSBOMDiff)}, - {http.MethodPost, "/v1/evidence", op("createEvidence", http.MethodPost, "/v1/evidence", "Create evidence", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.createEvidence)}, - {http.MethodGet, "/v1/evidence", op("listEvidence", http.MethodGet, "/v1/evidence", "List evidence", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.listEvidence)}, - {http.MethodGet, "/v1/evidence/search", op("searchEvidence", http.MethodGet, "/v1/evidence/search", "Search evidence", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.searchEvidence)}, - {http.MethodGet, "/v1/evidence/{id}", op("getEvidence", http.MethodGet, "/v1/evidence/{id}", "Get evidence", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.getEvidence)}, - {http.MethodPost, "/v1/evidence/{id}/supersede", op("supersedeEvidence", http.MethodPost, "/v1/evidence/{id}/supersede", "Supersede evidence", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.supersedeEvidence)}, - {http.MethodPost, "/v1/evidence/{id}/link", op("linkEvidence", http.MethodPost, "/v1/evidence/{id}/link", "Link evidence", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.linkEvidence)}, - {http.MethodPost, "/v1/evidence/{id}/lifecycle-events", op("recordEvidenceLifecycleEvent", http.MethodPost, "/v1/evidence/{id}/lifecycle-events", "Record evidence lifecycle event", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.recordEvidenceLifecycleEvent)}, - {http.MethodGet, "/v1/evidence/{id}/lifecycle-events", op("listEvidenceLifecycleEvents", http.MethodGet, "/v1/evidence/{id}/lifecycle-events", "List evidence lifecycle events", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.listEvidenceLifecycleEvents)}, - {http.MethodPost, "/v1/sboms", op("uploadSBOM", http.MethodPost, "/v1/sboms", "Upload CycloneDX SBOM", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.uploadSBOM)}, - {http.MethodGet, "/v1/sboms/{id}", op("getSBOM", http.MethodGet, "/v1/sboms/{id}", "Get SBOM", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.getSBOM)}, - {http.MethodPost, "/v1/vex", op("uploadVEX", http.MethodPost, "/v1/vex", "Upload OpenVEX document", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.uploadVEX)}, - {http.MethodPost, "/v1/vex/cyclonedx", op("uploadCycloneDXVEX", http.MethodPost, "/v1/vex/cyclonedx", "Upload CycloneDX VEX document", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.uploadCycloneDXVEX)}, - {http.MethodGet, "/v1/vex/{id}", op("getVEX", http.MethodGet, "/v1/vex/{id}", "Get VEX document", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.getVEX)}, - {http.MethodPost, "/v1/vulnerability-scans", op("uploadVulnerabilityScan", http.MethodPost, "/v1/vulnerability-scans", "Upload vulnerability scan", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.uploadVulnerabilityScan)}, - {http.MethodGet, "/v1/vulnerability-scans/{id}", op("getVulnerabilityScan", http.MethodGet, "/v1/vulnerability-scans/{id}", "Get vulnerability scan", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.getVulnerabilityScan)}, - {http.MethodPost, "/v1/vulnerability-findings/{id}/decisions", op("createVulnerabilityDecision", http.MethodPost, "/v1/vulnerability-findings/{id}/decisions", "Create vulnerability decision", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.createVulnerabilityDecision)}, - {http.MethodPost, "/v1/vulnerability-findings/{id}/workflow", op("recordVulnerabilityWorkflow", http.MethodPost, "/v1/vulnerability-findings/{id}/workflow", "Record vulnerability workflow event", []string{app.ScopeSecurityWrite}), http.HandlerFunc(s.recordVulnerabilityWorkflow)}, - {http.MethodGet, "/v1/reports/vulnerability-posture", op("vulnerabilityPostureReport", http.MethodGet, "/v1/reports/vulnerability-posture", "Vulnerability posture report", []string{app.ScopeSecurityRead}), http.HandlerFunc(s.vulnerabilityPostureReport)}, - {http.MethodPost, "/v1/openapi-contracts", op("uploadOpenAPIContract", http.MethodPost, "/v1/openapi-contracts", "Upload OpenAPI contract", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.uploadOpenAPIContract)}, - {http.MethodGet, "/v1/openapi-contracts/{id}", op("getOpenAPIContract", http.MethodGet, "/v1/openapi-contracts/{id}", "Get OpenAPI contract", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.getOpenAPIContract)}, - {http.MethodPost, "/v1/openapi-diffs", op("createOpenAPIDiff", http.MethodPost, "/v1/openapi-diffs", "Create OpenAPI contract diff", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.createOpenAPIDiff)}, - {http.MethodPost, "/v1/policies/evaluate", op("evaluatePolicy", http.MethodPost, "/v1/policies/evaluate", "Evaluate release policy", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.evaluatePolicy)}, - {http.MethodPost, "/v1/custom-policies", op("createCustomPolicy", http.MethodPost, "/v1/custom-policies", "Create custom policy", []string{app.ScopePolicyWrite}), http.HandlerFunc(s.createCustomPolicy)}, - {http.MethodPost, "/v1/custom-policies/{id}/evaluate", op("evaluateCustomPolicy", http.MethodPost, "/v1/custom-policies/{id}/evaluate", "Evaluate custom policy", []string{app.ScopePolicyRead}), http.HandlerFunc(s.evaluateCustomPolicy)}, - {http.MethodPost, "/v1/exceptions", op("createException", http.MethodPost, "/v1/exceptions", "Create exception", []string{app.ScopeReleaseWrite}), http.HandlerFunc(s.createException)}, - {http.MethodGet, "/v1/exceptions", op("listExceptions", http.MethodGet, "/v1/exceptions", "List exceptions", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.listExceptions)}, - {http.MethodPost, "/v1/exceptions/{id}/approve", op("approveException", http.MethodPost, "/v1/exceptions/{id}/approve", "Approve exception", []string{app.ScopeReleaseWrite}), http.HandlerFunc(s.approveException)}, - {http.MethodGet, "/v1/reports/missing-evidence", op("missingEvidenceReport", http.MethodGet, "/v1/reports/missing-evidence", "Missing evidence report", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.missingEvidenceReport)}, - {http.MethodGet, "/v1/reports/release-readiness", op("releaseReadinessReport", http.MethodGet, "/v1/reports/release-readiness", "Release readiness report", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.releaseReadinessReport)}, - {http.MethodGet, "/v1/reports/control-coverage", op("controlCoverageReport", http.MethodGet, "/v1/reports/control-coverage", "Control coverage report", []string{app.ScopeReportRead}), http.HandlerFunc(s.controlCoverageReport)}, - {http.MethodGet, "/v1/reports/cra-readiness", op("craReadinessReport", http.MethodGet, "/v1/reports/cra-readiness", "CRA readiness report", []string{app.ScopeReportRead}), http.HandlerFunc(s.craReadinessReport)}, - {http.MethodPost, "/v1/release-bundles", op("createReleaseBundle", http.MethodPost, "/v1/release-bundles", "Create release bundle", []string{app.ScopeBundleWrite}), http.HandlerFunc(s.createReleaseBundle)}, - {http.MethodGet, "/v1/release-bundles/{id}", op("getReleaseBundle", http.MethodGet, "/v1/release-bundles/{id}", "Get release bundle", []string{app.ScopeBundleRead}), http.HandlerFunc(s.getReleaseBundle)}, - {http.MethodGet, "/v1/release-bundles/{id}/manifest", op("getReleaseBundleManifest", http.MethodGet, "/v1/release-bundles/{id}/manifest", "Get release bundle manifest", []string{app.ScopeBundleRead}), http.HandlerFunc(s.getReleaseBundleManifest)}, - {http.MethodGet, "/v1/release-bundles/{id}/verify", op("verifyReleaseBundle", http.MethodGet, "/v1/release-bundles/{id}/verify", "Verify release bundle", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.verifyReleaseBundle)}, - {http.MethodGet, "/v1/audit-chain/verify", op("verifyAuditChain", http.MethodGet, "/v1/audit-chain/verify", "Verify audit chain", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.verifyAuditChain)}, - {http.MethodGet, "/v1/audit-log", op("listAuditLog", http.MethodGet, "/v1/audit-log", "List tenant audit log", []string{app.ScopeAdmin}), http.HandlerFunc(s.listAuditLog)}, - {http.MethodPost, "/v1/merkle-batches", op("createMerkleBatch", http.MethodPost, "/v1/merkle-batches", "Create Merkle checkpoint batch", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.createMerkleBatch)}, - {http.MethodGet, "/v1/merkle-batches/{id}/verify", op("verifyMerkleBatch", http.MethodGet, "/v1/merkle-batches/{id}/verify", "Verify Merkle checkpoint batch", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.verifyMerkleBatch)}, - {http.MethodPost, "/v1/transparency-checkpoints", op("createTransparencyCheckpoint", http.MethodPost, "/v1/transparency-checkpoints", "Record external transparency checkpoint", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.createTransparencyCheckpoint)}, - {http.MethodPost, "/v1/object-retention-policies", op("createObjectRetentionPolicy", http.MethodPost, "/v1/object-retention-policies", "Create object retention policy record", []string{app.ScopeAdmin}), http.HandlerFunc(s.createObjectRetentionPolicy)}, - {http.MethodPost, "/v1/object-retention-policies/{id}/verify", op("verifyObjectRetentionPolicy", http.MethodPost, "/v1/object-retention-policies/{id}/verify", "Verify object retention policy record", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.verifyObjectRetentionPolicy)}, - {http.MethodPost, "/v1/legal-holds", op("createLegalHold", http.MethodPost, "/v1/legal-holds", "Create legal hold", []string{app.ScopeAdmin}), http.HandlerFunc(s.createLegalHold)}, - {http.MethodPost, "/v1/retention-overrides", op("createRetentionOverride", http.MethodPost, "/v1/retention-overrides", "Create retention override", []string{app.ScopeAdmin}), http.HandlerFunc(s.createRetentionOverride)}, - {http.MethodGet, "/v1/reports/retention", op("retentionReport", http.MethodGet, "/v1/reports/retention", "Retention report", []string{app.ScopeAdmin}), http.HandlerFunc(s.retentionReport)}, - {http.MethodPost, "/v1/backup-manifests", op("generateBackupManifest", http.MethodPost, "/v1/backup-manifests", "Generate backup manifest", []string{app.ScopeAdmin}), http.HandlerFunc(s.generateBackupManifest)}, - {http.MethodGet, "/v1/backup-manifests/{id}/verify", op("verifyBackupManifest", http.MethodGet, "/v1/backup-manifests/{id}/verify", "Verify backup manifest", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.verifyBackupManifest)}, - {http.MethodGet, "/v1/signing-keys", op("listSigningKeys", http.MethodGet, "/v1/signing-keys", "List signing keys", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.listSigningKeys)}, - {http.MethodPost, "/v1/signing-keys/rotate", op("rotateSigningKey", http.MethodPost, "/v1/signing-keys/rotate", "Rotate signing key", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.rotateSigningKey)}, - {http.MethodPost, "/v1/signing-keys/{id}/revoke", op("revokeSigningKey", http.MethodPost, "/v1/signing-keys/{id}/revoke", "Revoke signing key", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.revokeSigningKey)}, - {http.MethodPost, "/v1/signing-providers", op("createSigningProvider", http.MethodPost, "/v1/signing-providers", "Create signing provider record", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.createSigningProvider)}, - {http.MethodPost, "/v1/commercial-collectors", op("createCommercialCollector", http.MethodPost, "/v1/commercial-collectors", "Create commercial collector definition", []string{app.ScopeCollectorAdmin}), http.HandlerFunc(s.createCommercialCollector)}, - {http.MethodGet, "/v1/commercial-collectors", op("listCommercialCollectors", http.MethodGet, "/v1/commercial-collectors", "List commercial collector definitions", []string{app.ScopeCollectorRead}), http.HandlerFunc(s.listCommercialCollectors)}, - {http.MethodPost, "/v1/verify", op("verify", http.MethodPost, "/v1/verify", "Verify subject", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.verifySubject)}, - {http.MethodPost, "/v1/api-keys", op("createAPIKey", http.MethodPost, "/v1/api-keys", "Create API key", []string{app.ScopeAdmin}), http.HandlerFunc(s.createAPIKey)}, - {http.MethodGet, "/v1/api-keys", op("listAPIKeys", http.MethodGet, "/v1/api-keys", "List API keys", []string{app.ScopeAdmin}), http.HandlerFunc(s.listAPIKeys)}, - } - for _, route := range routes { - if err := s.routes.Register(routecontracts.Route{Method: route.method, Pattern: route.path, Handler: route.handler, Operation: route.op}); err != nil { - return err - } - } - return nil -} - func (s *Server) createCollector(w http.ResponseWriter, r *http.Request) { var req struct { Name string `json:"name"` @@ -2283,5 +2125,5 @@ func op(id, method, path, summary string, scopes []string) specs.Operation { if method == http.MethodPost { operation.Extensions = idempotent.OperationExtensions(true) } - return operation + return withCriticalOperationDetails(operation) } diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index b0479e0..7ef7e36 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -31,6 +31,86 @@ func TestRoutesValidateAndOpenAPIRenders(t *testing.T) { } } +func TestRouteFamiliesRegisterCriticalPaths(t *testing.T) { + server, _ := testServer(t) + groups := map[string][]routeDef{ + "system": server.systemRoutes(), + "identity": server.identityRoutes(), + "portal": server.packagePortalRoutes(), + "ops": server.integrityOpsRoutes(), + } + for name, routes := range groups { + if len(routes) == 0 { + t.Fatalf("%s route group is empty", name) + } + } + want := map[string]string{ + "instanceAdminSnapshot": "/v1/admin/instance", + "createSSOSession": "/v1/sso/sessions", + "createCustomerPortalAccess": "/v1/customer-portal/access", + "accessCustomerPortalPackage": "/v1/customer-portal/package", + "createLegalHold": "/v1/legal-holds", + "verifyReleaseBundle": "/v1/release-bundles/{id}/verify", + } + got := map[string]string{} + for _, route := range server.routeDefinitions() { + got[route.op.OperationID] = route.path + } + for opID, path := range want { + if got[opID] != path { + t.Fatalf("operation %s path = %q, want %q", opID, got[opID], path) + } + } +} + +func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { + server, _ := testServer(t) + docBytes, err := server.OpenAPI() + if err != nil { + t.Fatalf("OpenAPI: %v", err) + } + var doc map[string]any + if err := json.Unmarshal(docBytes, &doc); err != nil { + t.Fatalf("decode OpenAPI: %v", err) + } + schemas := asStringAnyMap(t, asStringAnyMap(t, doc["components"])["schemas"]) + problem := asStringAnyMap(t, schemas["Problem"]) + problemProps := asStringAnyMap(t, problem["properties"]) + if _, ok := problemProps["request_id"]; !ok { + t.Fatalf("Problem schema missing request_id: %#v", problemProps) + } + for _, schemaName := range []string{"CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "DataEnvelope"} { + if _, ok := schemas[schemaName]; !ok { + t.Fatalf("schema %s missing from OpenAPI components", schemaName) + } + } + + paths := asStringAnyMap(t, doc["paths"]) + createEvidence := operationMap(t, paths, "/v1/evidence", "post") + assertRequestRef(t, createEvidence, "#/components/schemas/CreateEvidenceRequest") + assertProblemResponseRef(t, createEvidence, "400") + searchEvidence := operationMap(t, paths, "/v1/evidence/search", "get") + assertQueryParams(t, searchEvidence, "product_id", "project_id", "release_id", "type", "source", "tag", "cursor", "limit") + createPortalAccess := operationMap(t, paths, "/v1/customer-portal/access", "post") + assertRequestRef(t, createPortalAccess, "#/components/schemas/CreateCustomerPortalAccessRequest") + assertResponseRef(t, createPortalAccess, "201", "#/components/schemas/CustomerPortalAccessCreateEnvelope") + portalPackage := operationMap(t, paths, "/v1/customer-portal/package", "post") + assertRequestRef(t, portalPackage, "#/components/schemas/CustomerPortalPackageRequest") + if _, ok := portalPackage["security"]; ok { + t.Fatalf("public portal token exchange should not advertise bearer security: %#v", portalPackage["security"]) + } + createSession := operationMap(t, paths, "/v1/sso/sessions", "post") + assertRequestRef(t, createSession, "#/components/schemas/CreateSSOSessionRequest") + assertResponseRef(t, createSession, "201", "#/components/schemas/SSOSessionCreateEnvelope") + verifyBundle := operationMap(t, paths, "/v1/release-bundles/{id}/verify", "get") + assertQueryParams(t, verifyBundle, "id") + assertResponseRef(t, verifyBundle, "200", "#/components/schemas/ReleaseBundleVerificationEnvelope") + instanceAdmin := operationMap(t, paths, "/v1/admin/instance", "get") + if !strings.Contains(asString(t, instanceAdmin["description"]), "instance:admin") { + t.Fatalf("instance admin description should document exact scope: %#v", instanceAdmin["description"]) + } +} + func TestCreateProductRequiresAuthAndIdempotency(t *testing.T) { server, secret := testServer(t) rec := httptest.NewRecorder() @@ -783,6 +863,81 @@ func getJSON(t *testing.T, server *Server, secret, path string, want int) string return rec.Body.String() } +func asStringAnyMap(t *testing.T, value any) map[string]any { + t.Helper() + out, ok := value.(map[string]any) + if !ok { + t.Fatalf("value is %T, want map[string]any: %#v", value, value) + } + return out +} + +func asString(t *testing.T, value any) string { + t.Helper() + out, ok := value.(string) + if !ok { + t.Fatalf("value is %T, want string: %#v", value, value) + } + return out +} + +func operationMap(t *testing.T, paths map[string]any, path, method string) map[string]any { + t.Helper() + pathItem := asStringAnyMap(t, paths[path]) + return asStringAnyMap(t, pathItem[method]) +} + +func assertRequestRef(t *testing.T, operation map[string]any, wantRef string) { + t.Helper() + body := asStringAnyMap(t, operation["requestBody"]) + content := asStringAnyMap(t, body["content"]) + media := asStringAnyMap(t, content["application/json"]) + schema := asStringAnyMap(t, media["schema"]) + if got := asString(t, schema["$ref"]); got != wantRef { + t.Fatalf("request schema ref = %q, want %q", got, wantRef) + } +} + +func assertProblemResponseRef(t *testing.T, operation map[string]any, status string) { + t.Helper() + assertMediaResponseRef(t, operation, status, "application/problem+json", "#/components/schemas/Problem") +} + +func assertResponseRef(t *testing.T, operation map[string]any, status, wantRef string) { + t.Helper() + assertMediaResponseRef(t, operation, status, "application/json", wantRef) +} + +func assertMediaResponseRef(t *testing.T, operation map[string]any, status, mediaType, wantRef string) { + t.Helper() + responses := asStringAnyMap(t, operation["responses"]) + response := asStringAnyMap(t, responses[status]) + content := asStringAnyMap(t, response["content"]) + media := asStringAnyMap(t, content[mediaType]) + schema := asStringAnyMap(t, media["schema"]) + if got := asString(t, schema["$ref"]); got != wantRef { + t.Fatalf("response schema ref = %q, want %q", got, wantRef) + } +} + +func assertQueryParams(t *testing.T, operation map[string]any, names ...string) { + t.Helper() + rawParams, ok := operation["parameters"].([]any) + if !ok { + t.Fatalf("parameters missing: %#v", operation["parameters"]) + } + got := map[string]bool{} + for _, raw := range rawParams { + param := asStringAnyMap(t, raw) + got[asString(t, param["name"])] = true + } + for _, name := range names { + if !got[name] { + t.Fatalf("parameter %s missing from %#v", name, rawParams) + } + } +} + func firstFindingID(t *testing.T, body string) string { t.Helper() var decoded struct { diff --git a/openapi.yaml b/openapi.yaml index 5f7976d..4e18edd 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"operationId":"instanceAdminSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"operationId":"registerArtifact","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"operationId":"generateBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"operationId":"verifyBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"operationId":"createBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"operationId":"getBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"operationId":"uploadGitHubSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"operationId":"uploadGitLabSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"operationId":"createCustomerPortalAccess","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"operationId":"accessCustomerPortalPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"createEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence/search":{"get":{"operationId":"searchEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"summary":"Health","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"operationId":"listProducts","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"operationId":"createProduct","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"operationId":"createProject","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"operationId":"ready","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"operationId":"createReleaseBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"operationId":"verifyReleaseBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"operationId":"createRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"operationId":"getRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"operationId":"approveRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"operationId":"freezeRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"operationId":"controlCoverageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"operationId":"craReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/release-readiness":{"get":{"operationId":"releaseReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"operationId":"uploadSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"operationId":"getSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"operationId":"createSSOProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"operationId":"createSSOSession","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"operationId":"uploadVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"operationId":"uploadCycloneDXVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"operationId":"getVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"operationId":"uploadVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"operationId":"getVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"422":{"description":"Verification failed"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{},"payload_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source":{"type":"string"},"subject_refs":{"items":{"type":"string"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"type":"object"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"api_key_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"},"user_count":{"type":"integer"}},"required":["tenant_count","resource_counts"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Instance admin snapshot envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"operationId":"registerArtifact","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"operationId":"generateBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"operationId":"verifyBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"operationId":"createBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"operationId":"getBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"operationId":"uploadGitHubSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"operationId":"uploadGitLabSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"operationId":"listProducts","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"operationId":"createProduct","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"operationId":"createProject","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"operationId":"ready","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"operationId":"createRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"operationId":"getRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"operationId":"approveRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"operationId":"freezeRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"operationId":"controlCoverageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"operationId":"craReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/release-readiness":{"get":{"operationId":"releaseReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"operationId":"uploadSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"operationId":"getSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"operationId":"createSSOProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"operationId":"uploadVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"operationId":"uploadCycloneDXVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"operationId":"getVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"operationId":"uploadVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"operationId":"getVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From c0f3989a74721cfd9eb7fff4cd53351889d57df6 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sat, 23 May 2026 10:57:49 +0300 Subject: [PATCH 008/287] test(authz): deepen portal and resource coverage --- Makefile | 16 +++- README.md | 2 +- docs/api.md | 2 +- docs/reference/release-validation.md | 10 ++- internal/app/enterprise_test.go | 128 +++++++++++++++++++++++++++ internal/app/ledger.go | 1 - 6 files changed, 154 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 43a16d5..f05bedf 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ GOLANGCI_LINT_VERSION ?= v2.11.4 GOSEC_VERSION ?= v2.25.0 GOVULNCHECK_VERSION ?= v1.2.0 -.PHONY: help tools fmt lint vuln gosec test test-race coverage openapi-check docs-check deploy-check sdk-check fast-check finalize release-check compose-up compose-down migrate live-postgres-check postgres-integration-test clean +.PHONY: help tools fmt lint vuln gosec test test-race coverage openapi-check docs-check deploy-check sdk-check fast-check finalize release-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean help: ## Show help @awk 'BEGIN {FS=":.*## "}; /^[a-zA-Z0-9_.-]+:.*## / { printf " %-18s %s\n", $$1, $$2 }' $(MAKEFILE_LIST) @@ -118,6 +118,20 @@ release-check: ## Release validation with security, race, and configured live in fi; \ } | tee tmp/release-check-summary.txt +release-check-local-postgres: ## Start Compose Postgres, load .test.env or .test.env.example, and run release-check + @docker compose up -d postgres + @echo "waiting for compose postgres..." + @for i in $$(seq 1 30); do \ + if docker compose exec -T postgres pg_isready -U "$${POSTGRES_USER:-evydence}" >/dev/null 2>&1; then break; fi; \ + if [ "$$i" = "30" ]; then echo "postgres did not become ready"; exit 1; fi; \ + sleep 1; \ + done + @env_file=".test.env"; \ + if [ ! -f "$$env_file" ]; then env_file=".test.env.example"; fi; \ + echo "loading $$env_file for release-check-local-postgres"; \ + set -a; . "./$$env_file"; set +a; \ + $(MAKE) release-check + compose-up: ## Start local dependencies @docker compose up -d diff --git a/README.md b/README.md index abb3226..055673c 100644 --- a/README.md +++ b/README.md @@ -57,4 +57,4 @@ make live-postgres-check make postgres-integration-test ``` -`make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. The target writes `tmp/release-check-summary.txt`; see `docs/reference/release-validation.md` for the configured Postgres release profile. +`make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. `make release-check-local-postgres` starts the local Compose PostgreSQL service, loads `.test.env` or `.test.env.example`, and runs that release gate. The target writes `tmp/release-check-summary.txt`; see `docs/reference/release-validation.md` for the configured Postgres release profile. diff --git a/docs/api.md b/docs/api.md index 43a6514..7463615 100644 --- a/docs/api.md +++ b/docs/api.md @@ -109,7 +109,7 @@ Scoped exceptions are created with `POST /v1/exceptions` and approved separately `POST /v1/redaction-profiles` creates an explicit package redaction profile. `POST /v1/customer-packages` creates a scoped customer security package manifest with expiry and access auditing. `GET /v1/customer-packages/{id}` reads the manifest and records an access event; raw payload bytes are not returned. -`POST /v1/customer-portal/access` creates an expiring customer portal access token for one package and returns the token once. `POST /v1/customer-portal/package` accepts that token and returns the scoped package manifest without exposing the token or raw tenant evidence. Failed portal token attempts that match a known token prefix record a safe audit-chain signal without storing or returning the supplied token. After repeated failed attempts for one active access record, Evydence revokes that access record and reports only tenant-safe counters. +`POST /v1/customer-portal/access` creates an expiring customer portal access token for one package and returns the token once. `POST /v1/customer-portal/package` accepts that token and returns the scoped package manifest without exposing the token or raw tenant evidence. The portal exchange intentionally does not use an API scope such as `customer:portal`; it is a package-scoped token flow. Failed portal token attempts that match a known token prefix record a safe audit-chain signal without storing or returning the supplied token. After repeated failed attempts for one active access record, Evydence revokes that access record and reports only tenant-safe counters. `POST /v1/questionnaire-templates` creates tenant-defined customer questionnaire templates with question-to-evidence hints. `POST /v1/questionnaire-packages` generates deterministic evidence-backed responses for a package, product, and release scope. Responses cite linked evidence IDs and include limitations for human review. diff --git a/docs/reference/release-validation.md b/docs/reference/release-validation.md index 6b8e862..b5c31fc 100644 --- a/docs/reference/release-validation.md +++ b/docs/reference/release-validation.md @@ -22,7 +22,15 @@ Keep this file with release evidence when preparing an internal release review. ## Configured Live PostgreSQL Profile -Start the local dependencies and load the test profile: +For the scripted local profile, run: + +```sh +make release-check-local-postgres +``` + +The target starts the Compose PostgreSQL service, waits for readiness, loads `.test.env` when present or `.test.env.example` otherwise, runs `make release-check`, and preserves `tmp/release-check-summary.txt`. + +You can also run the sequence manually: ```sh make compose-up diff --git a/internal/app/enterprise_test.go b/internal/app/enterprise_test.go index 0b298d9..338c7cb 100644 --- a/internal/app/enterprise_test.go +++ b/internal/app/enterprise_test.go @@ -304,6 +304,51 @@ func TestCustomerPortalAccessRevokesAfterRepeatedFailedAttempts(t *testing.T) { } } +func TestCustomerPortalAccessAbuseBoundaries(t *testing.T) { + now := fixedNow() + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: func() time.Time { return now }}) + ctx := context.Background() + actor, release, _ := setupReleaseRiskFixture(t, ledger) + profile, err := ledger.CreateRedactionProfile(ctx, actor, CreateRedactionProfileInput{Name: "customer", AllowedTypes: []string{"sbom"}}) + if err != nil { + t.Fatalf("profile: %v", err) + } + pkg, err := ledger.CreateCustomerSecurityPackage(ctx, actor, CreateCustomerPackageInput{ProductID: release.ProductID, ReleaseID: release.ID, RedactionProfileID: profile.ID, Title: "Customer", ExpiresAt: now.Add(4 * time.Hour)}) + if err != nil { + t.Fatalf("customer package: %v", err) + } + access, token, err := ledger.CreateCustomerPortalAccess(ctx, actor, CreateCustomerPortalAccessInput{PackageID: pkg.ID, CustomerName: "ACME", ExpiresAt: now.Add(time.Hour)}) + if err != nil { + t.Fatalf("portal access: %v", err) + } + if _, err := ledger.AccessCustomerPortalPackage(ctx, "evycp_wrongprefix"); !errors.Is(err, ErrUnauthorized) { + t.Fatalf("wrong-prefix token err=%v, want unauthorized", err) + } + metrics, err := ledger.Metrics(ctx, actor) + if err != nil { + t.Fatalf("metrics: %v", err) + } + if metrics["customer_portal_failed_access_count"] != 0 || metrics["customer_portal_revoked_access_count"] != 0 { + t.Fatalf("wrong-prefix attempt should not increment known-access metrics: %#v", metrics) + } + now = now.Add(2 * time.Hour) + if _, err := ledger.AccessCustomerPortalPackage(ctx, token); !errors.Is(err, ErrUnauthorized) { + t.Fatalf("expired token err=%v, want unauthorized", err) + } + entries, err := ledger.ListAuditLog(ctx, actor, AuditLogFilter{SubjectType: "customer_portal_access", SubjectID: access.ID, Limit: 20}) + if err != nil { + t.Fatalf("audit log: %v", err) + } + for _, entry := range entries { + if entry.EntryType == "customer_portal_package.access_failed" { + t.Fatalf("expired token should not produce failed-access audit entry: %#v", entry) + } + if strings.Contains(entry.ActorID, token) || strings.Contains(entry.PayloadHash, token) { + t.Fatalf("portal audit leaked token: %#v", entry) + } + } +} + func TestSecretHashComparisonHelper(t *testing.T) { ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) hash := ledger.hashSecret("evy_test_secret") @@ -318,6 +363,89 @@ func TestSecretHashComparisonHelper(t *testing.T) { } } +func TestResourceGrantHelperBranchCoverage(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + admin, release, artifact := setupReleaseRiskFixture(t, ledger) + project, err := ledger.CreateProject(ctx, admin, release.ProductID, "api") + if err != nil { + t.Fatalf("project: %v", err) + } + repo, err := ledger.CreateSourceRepository(ctx, admin, CreateRepositoryInput{ProjectID: project.ID, Provider: "github", FullName: "example/api", CloneURL: "https://github.com/example/api.git", DefaultBranch: "main"}) + if err != nil { + t.Fatalf("repo: %v", err) + } + build, err := ledger.CreateBuildRun(ctx, admin, CreateBuildRunInput{ + ProjectID: project.ID, + ReleaseID: release.ID, + Provider: "generic", + CommitSHA: "0123456789abcdef0123456789abcdef01234567", + Status: "passed", + StartedAt: fixedNow(), + Outputs: []domain.BuildOutput{{ArtifactID: artifact.ID, Digest: artifact.Digest}}, + }) + if err != nil { + t.Fatalf("build: %v", err) + } + evidence, err := ledger.CreateEvidence(ctx, admin, CreateEvidenceInput{ + ProductID: release.ProductID, + ProjectID: project.ID, + ReleaseID: release.ID, + Type: "build", + Title: "Build", + PayloadHash: sampleDigest("resource-helper"), + SubjectRefs: []domain.SubjectRef{{Type: "artifact", ID: artifact.ID}}, + }) + if err != nil { + t.Fatalf("evidence: %v", err) + } + _ = evidence + otherProduct, err := ledger.CreateProduct(ctx, admin, "Other", "other-resource-helper") + if err != nil { + t.Fatalf("other product: %v", err) + } + otherRelease, err := ledger.CreateRelease(ctx, admin, otherProduct.ID, "1") + if err != nil { + t.Fatalf("other release: %v", err) + } + + ledger.mu.Lock() + defer ledger.mu.Unlock() + if !ledger.productCoversRefsLocked(admin.TenantID, release.ProductID, resourceRefs{ProjectID: project.ID, SourceRepositoryID: repo.ID, ReleaseID: release.ID, BuildID: build.ID, ArtifactID: artifact.ID}) { + t.Fatalf("product grant should cover project/source/release/build/artifact refs") + } + if ledger.productCoversRefsLocked(admin.TenantID, otherProduct.ID, resourceRefs{ArtifactID: artifact.ID}) { + t.Fatalf("foreign product grant unexpectedly covered artifact") + } + if !ledger.projectCoversRefsLocked(admin.TenantID, project.ID, resourceRefs{ProjectID: project.ID}) { + t.Fatalf("project grant should cover direct project ref") + } + if !ledger.projectCoversRefsLocked(admin.TenantID, project.ID, resourceRefs{SourceRepositoryID: repo.ID}) { + t.Fatalf("project grant should cover source repository ref") + } + if !ledger.projectCoversRefsLocked(admin.TenantID, project.ID, resourceRefs{BuildID: build.ID}) { + t.Fatalf("project grant should cover build ref") + } + if !ledger.releaseCoversRefsLocked(admin.TenantID, release.ID, resourceRefs{ReleaseID: release.ID}) { + t.Fatalf("release grant should cover direct release ref") + } + if !ledger.releaseCoversRefsLocked(admin.TenantID, release.ID, resourceRefs{BuildID: build.ID, ArtifactID: artifact.ID}) { + t.Fatalf("release grant should cover build and artifact refs") + } + if ledger.releaseCoversRefsLocked(admin.TenantID, otherRelease.ID, resourceRefs{ArtifactID: artifact.ID}) { + t.Fatalf("foreign release grant unexpectedly covered artifact") + } + if !ledger.artifactCoversProductLocked(admin.TenantID, artifact.ID, release.ProductID) { + t.Fatalf("artifact should be linked to product through evidence/build output") + } + if !ledger.artifactCoversReleaseLocked(admin.TenantID, artifact.ID, release.ID) { + t.Fatalf("artifact should be linked to release through evidence/build output") + } + if ledger.artifactCoversReleaseLocked(admin.TenantID, artifact.ID, otherRelease.ID) { + t.Fatalf("artifact unexpectedly covered foreign release") + } +} + func mutateTokenSuffix(token string) string { if strings.HasSuffix(token, "x") { return token[:len(token)-1] + "y" diff --git a/internal/app/ledger.go b/internal/app/ledger.go index bf76602..d09d430 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -57,7 +57,6 @@ const ( ScopeReportRead = "report:read" ScopeIdentityAdmin = "identity:admin" ScopeInstanceAdmin = "instance:admin" - ScopeCustomerPortal = "customer:portal" ) const customerPortalFailedAccessLimit = 5 From 17c096f1f9234c16e2ee2c55fa93807e53014e77 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sat, 23 May 2026 11:23:00 +0300 Subject: [PATCH 009/287] docs: remediate documentation audit backlog --- Makefile | 34 ++- README.md | 54 +++- docs/README.md | 40 ++- docs/air-gapped.md | 33 ++- docs/api.md | 436 ++++++++++++++++++++++------- docs/architecture.md | 44 ++- docs/collectors/supply-chain.md | 40 ++- docs/how-to/install-and-operate.md | 62 +++- docs/how-to/integrate-ci.md | 76 +++++ docs/kubernetes.md | 61 +++- docs/operations.md | 127 ++------- docs/production-hardening.md | 67 ++++- docs/reference/configuration.md | 62 ++++ docs/reference/openapi.md | 41 ++- docs/sdk/README.md | 97 ++++++- docs/tutorials/getting-started.md | 210 ++++++++++++-- 16 files changed, 1195 insertions(+), 289 deletions(-) create mode 100644 docs/how-to/integrate-ci.md create mode 100644 docs/reference/configuration.md diff --git a/Makefile b/Makefile index f05bedf..4264a54 100644 --- a/Makefile +++ b/Makefile @@ -58,12 +58,44 @@ docs-check: ## Validate canonical docs exist and avoid forbidden product claims @test -f docs/release-signing.md @test -f docs/production-hardening.md @test -f docs/tutorials/getting-started.md + @test -f docs/how-to/integrate-ci.md @test -f docs/how-to/install-and-operate.md + @test -f docs/reference/configuration.md @test -f docs/reference/openapi.md @test -f docs/reference/worker-outbox.md @test -f docs/reference/release-validation.md @test -f docs/explanation/trust-model.md - @! grep -R -i "automatically compliant\|certified secure\|legally sufficient\|SBOM is complete\|all vulnerabilities detected" README.md docs + @test -f docs/collectors/source-snapshots.md + @test -f docs/collectors/supply-chain.md + @test -f docs/github-actions/release-evidence-workflow.yml + @test -f docs/github-actions/upload-build/action.yml + @test -f docs/gitlab/evydence-release-evidence.gitlab-ci.yml + @test -f docs/sdk/README.md + @for path in \ + "tutorials/getting-started.md" \ + "how-to/install-and-operate.md" \ + "how-to/integrate-ci.md" \ + "api.md" \ + "operations.md" \ + "kubernetes.md" \ + "air-gapped.md" \ + "release-signing.md" \ + "production-hardening.md" \ + "reference/configuration.md" \ + "reference/openapi.md" \ + "reference/worker-outbox.md" \ + "reference/release-validation.md" \ + "collectors/source-snapshots.md" \ + "collectors/supply-chain.md" \ + "github-actions/release-evidence-workflow.yml" \ + "github-actions/upload-build/action.yml" \ + "gitlab/evydence-release-evidence.gitlab-ci.yml" \ + "sdk/README.md" \ + "architecture.md" \ + "explanation/trust-model.md"; do \ + grep -F "$$path" docs/README.md >/dev/null || { echo "docs/README.md missing link to $$path"; exit 1; }; \ + done + @! grep -R -i "automatically compliant\|certified secure\|legally sufficient\|SBOM is complete\|all vulnerabilities detected\|scanner findings are authoritative\|regulator-ready without review" README.md docs deploy-check: ## Validate deployment and air-gap skeletons exist @test -f deploy/helm/evydence/Chart.yaml diff --git a/README.md b/README.md index 055673c..2ffff5f 100644 --- a/README.md +++ b/README.md @@ -2,26 +2,46 @@ Evydence is a self-hosted, API-first evidence ledger for software release evidence. It supports compliance readiness by organizing and verifying technical evidence, producing tamper-evident records, and showing gaps, assumptions, exceptions, and limitations. -It does not make legal compliance conclusions, certify releases as secure, prove SBOM completeness, or treat scanner findings as authoritative. +It does not make legal compliance conclusions, grant certification, prove SBOM completeness, treat scanner findings as authoritative, or guarantee release security. ## Current Implementation -This repository now contains the release-ledger MVP scaffold: +This repository contains a Go release-ledger MVP scaffold under module `github.com/aatuh/evydence`. + +### API And Contracts -- Go module `github.com/aatuh/evydence`. - HTTP API under `/v1` using `github.com/aatuh/api-toolkit/v3` route contracts, OpenAPI generation, response helpers, and Problem Details. +- Generated OpenAPI contract committed at `openapi.yaml` and served at `/v1/openapi.json`. +- Request idempotency for create/action endpoints and tenant-scoped Problem Details responses. + +### Identity And Tenant Boundaries + - Multi-tenant scoped API keys with one-time secret output, HMAC-SHA256 storage, and server-side scope checks. -- Products, projects, releases, release candidates, artifacts, container images, artifact signatures, cosign-style verification metadata, evidence search, evidence lifecycle events, CycloneDX and SPDX SBOM upload, SBOM diffs, OpenVEX and CycloneDX VEX upload, generic vulnerability scan upload, vulnerability decisions/workflow records/posture reports, security scans, manual security documents, incidents/remediation/timeline reports, organizations, human users, SSO provider/session records, role bindings, instance admin diagnostics, legal holds, retention overrides, customer portal package access, questionnaire templates/packages, commercial collector definitions, waivers, approvals, customer security packages, redaction profiles, HTML report packages, custom report templates, evidence bundle export/import, exceptions, OpenAPI upload and contract diffs, API security scan evidence, custom policy definitions/evaluations, collectors, build runs, DSSE/in-toto build attestation upload and trust-root signature verification, source repositories/commits/branches/pull requests, deployment environments/events, expanded control framework template packs, control frameworks, control evidence links, policy evaluation, missing-evidence, release-readiness, control-coverage and CRA-readiness reports, signing keys, key revocation, signing-provider records, Merkle checkpoint batches, transparency checkpoint records, object-retention policy records, backup manifests, safe metrics, readiness, admin audit-log querying, signed release bundles, and verification endpoints. +- Organizations, users, role bindings, admin-managed SSO provider/session records, collector keys, and customer portal package tokens. +- Instance diagnostics require explicit `instance:admin` scope. + +### Evidence And Release Records + +- Products, projects, releases, release candidates, artifacts, container images, artifact signatures, evidence search, evidence lifecycle events, SBOM and VEX upload, vulnerability scans, vulnerability decisions, exceptions, waivers, approvals, incidents, remediation tasks, source records, deployment events, controls, reports, policies, release bundles, evidence bundles, backup manifests, and retention records. +- Immutable or append-only behavior for evidence core fields, release bundles, approvals, exceptions, audit entries, chain entries, and related transition records. +- Release-readiness, control-coverage, CRA-readiness, vulnerability-posture, incident-package, security-review-package, retention, and backup-manifest reports with assumptions and limitations. + +### Persistence, Object Storage, And Workers + - In-process store for local demos and unit-test execution when `EVYDENCE_DATABASE_URL` is unset. -- PostgreSQL-backed durable ledger state, tenant-scoped relational resource projection rows, and persisted outbox jobs when `EVYDENCE_DATABASE_URL` is set. -- Filesystem or S3/MinIO-compatible object storage for raw upload payload bytes, keyed under tenant-prefixed paths. -- Schema migrations applied by `make migrate` or by the API/worker startup path unless `EVYDENCE_SKIP_MIGRATIONS=true`. +- PostgreSQL-backed durable ledger state, tenant-scoped relational projections, migrations, and persisted outbox jobs when `EVYDENCE_DATABASE_URL` is set. +- Filesystem or S3/MinIO-compatible object storage for raw upload payload bytes under tenant-prefixed paths. +- Polling `cmd/evydence-worker` process that claims persisted outbox jobs with PostgreSQL row locking and records retry or terminal status. + +### Tooling, Deployment, And Examples + +- `cmd/evydence` helper for hashing, manifest verification, GitHub Actions build provenance upload, release artifact manifest signing/verification, bulk upload manifests, and air-gapped evidence bundle import. - Docker Compose dependencies for PostgreSQL and MinIO. -- A polling `cmd/evydence-worker` process that claims persisted outbox jobs with PostgreSQL row locking and records retry or terminal status. -- A local `cmd/evydence` helper for hashing, manifest verification, and GitHub Actions build provenance upload. -- Offline `cmd/evydence` verification for exported evidence bundle manifests, release artifact manifest signing/verification, bulk upload manifests, and air-gapped evidence bundle import. -- Kubernetes Helm chart, air-gapped package manifest, SDK examples, GitHub Actions release workflow example, and GitLab CI template. -- Documentation portal structure under `docs/` with tutorial, how-to, reference, and explanation entry points. +- Kubernetes Helm chart under `deploy/helm/evydence`. +- Air-gapped package manifest under `deploy/airgap/manifest.yaml`. +- Lightweight Go, TypeScript, and Python SDK wrappers. +- GitHub Actions and GitLab CI workflow examples. +- Documentation portal under `docs/`. ## Local API @@ -35,13 +55,19 @@ The API listens on `EVYDENCE_ADDR`, defaulting to `:8080`. Local bootstrap outpu Use the secret as: -```sh +```http Authorization: Bearer Idempotency-Key: ``` +For a runnable first evidence flow, use [Getting started](docs/tutorials/getting-started.md). + ## Validation +The canonical release validation reference is [docs/reference/release-validation.md](docs/reference/release-validation.md). + +Common local checks: + ```sh make test make openapi-check @@ -57,4 +83,4 @@ make live-postgres-check make postgres-integration-test ``` -`make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. `make release-check-local-postgres` starts the local Compose PostgreSQL service, loads `.test.env` or `.test.env.example`, and runs that release gate. The target writes `tmp/release-check-summary.txt`; see `docs/reference/release-validation.md` for the configured Postgres release profile. +`make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. diff --git a/docs/README.md b/docs/README.md index ce444e5..d60a875 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,25 +1,43 @@ # Evydence Documentation -This documentation is organized by task type so roadmap intent and implemented behavior stay separate. +This documentation is organized by reader task. Implementation claims should be backed by committed code, `openapi.yaml`, tests, deployment files, or Makefile targets. `.initial_design.md` remains design intent. -## Tutorials +## Start Here -- [Getting started](tutorials/getting-started.md) walks through a local API run and a small release evidence flow. +- [Getting started](tutorials/getting-started.md): run the API locally and create a minimal release evidence flow. +- [Install and operate](how-to/install-and-operate.md): choose a local runtime mode, start dependencies, run migrations, and launch API/worker processes. +- [Operations](operations.md): find the canonical operator references for configuration, workers, CI, deployment, and validation. +- [API reference](api.md): integrate with the `/v1` HTTP API using authentication, idempotency, examples, and endpoint tables. ## How-To Guides -- [Install and operate](how-to/install-and-operate.md) covers local dependencies, migrations, and runtime choices. +- [Integrate CI collectors](how-to/integrate-ci.md): connect GitHub Actions, the composite upload action, GitLab CI, source snapshots, and collector supply-chain records. +- [Kubernetes deployment](kubernetes.md): install the Helm chart and verify a self-hosted cluster deployment. +- [Air-gapped installation](air-gapped.md): build, sign, transfer, verify, and import an offline package. +- [Release signing](release-signing.md): create and verify local release artifact manifests. +- [Production hardening review](production-hardening.md): review production configuration, backups, ingress, diagnostics, and customer package controls. ## Reference -- [API reference](api.md) describes the implemented `/v1` HTTP surface. -- [OpenAPI contract](reference/openapi.md) explains how `openapi.yaml` is generated and checked. -- [Worker outbox contract](reference/worker-outbox.md) documents durable job inputs, idempotency, and safe failure behavior. -- [Release validation](reference/release-validation.md) documents the configured release-check profile and live PostgreSQL evidence. +- [Configuration](reference/configuration.md): canonical environment variables and the roles of `.env.example`, `.api.env.example`, and `.test.env.example`. +- [OpenAPI contract](reference/openapi.md): generation, drift checks, and review tips for `openapi.yaml`. +- [Worker outbox contract](reference/worker-outbox.md): durable job kinds, idempotency, and safe logging rules. +- [Release validation](reference/release-validation.md): canonical `make release-check` behavior and summary evidence. +- [SDK workflow](sdk/README.md): current Go, TypeScript, and Python wrapper usage and limitations. +- [Collector supply chain](collectors/supply-chain.md): collector release evidence and health checks. +- [Source snapshot collectors](collectors/source-snapshots.md): GitHub and GitLab source metadata upload examples. + +## Workflow Examples + +- [GitHub Actions release evidence workflow](github-actions/release-evidence-workflow.yml) +- [GitHub Actions upload-build composite action](github-actions/upload-build/action.yml) +- [GitLab release evidence CI template](gitlab/evydence-release-evidence.gitlab-ci.yml) + +These examples require tenant-scoped API or collector secrets created through the API. They capture CI metadata as submitted evidence; provider-side truth still depends on the CI provider, workflow controls, and any verification receipts recorded separately. ## Explanation -- [Architecture](architecture.md) explains ports, adapters, storage, worker, and trust boundaries. -- [Trust model](explanation/trust-model.md) summarizes what Evydence verifies and what remains an assumption. +- [Architecture](architecture.md): ports/adapters boundaries, persistence, object storage, append-only behavior, and current limitations. +- [Trust model](explanation/trust-model.md): what Evydence verifies, what it records as assumptions, and where external review remains required. -Evydence supports compliance readiness and technical evidence organization. The documentation intentionally avoids legal compliance, certification, complete-SBOM, authoritative scanner, and secure-release claims. +Evydence supports compliance readiness and technical evidence organization. The documentation avoids claims that Evydence makes legal compliance conclusions, grants certification, proves SBOM completeness, treats scanner output as authoritative, or guarantees release security. diff --git a/docs/air-gapped.md b/docs/air-gapped.md index 82bac26..5946735 100644 --- a/docs/air-gapped.md +++ b/docs/air-gapped.md @@ -2,6 +2,8 @@ This is a how-to guide for offline or disconnected environments. +## Build The Package + Prepare the package on a connected build host: ```sh @@ -14,14 +16,37 @@ evydence release keygen --private-out dist/release-private.key --public-out dist evydence release sign --manifest dist/evydence-release-manifest.json --private-key dist/release-private.key --out dist/evydence-release-manifest.sig.json ``` -Transfer only the package, public key, checksums, and signature through the approved media path. Do not transfer private signing keys into the target environment unless that is the controlled signing location. +Expected package contents include: + +- `evydence-api` +- `evydence-worker` +- `evydence` +- `migrations/` +- `openapi.yaml` +- `deploy/helm/evydence/` +- `docs/air-gapped.md` +- `evydence-release-manifest.json` +- `evydence-release-manifest.sig.json` +- `release-public.key` + +The package manifest at `deploy/airgap/manifest.yaml` lists expected package contents. Keep it with release evidence. + +## Transfer + +Transfer only the package, public key, checksums, and signature through the approved media path. Do not transfer private signing keys into the target environment unless that environment is the controlled signing location. -Verify offline: +Record transfer approvals, media handling, and hash verification as separate operational evidence where your process requires it. + +## Verify Offline ```sh evydence release verify --manifest evydence-release-manifest.json --signature evydence-release-manifest.sig.json ``` +Expected result: the command exits successfully and reports that the manifest signature and referenced artifact hashes verify. + +## Import Evidence Bundles + For CI systems that cannot call the API, write an evidence bundle in CI, move it through the same controlled transfer process, then upload it from the connected side: ```sh @@ -31,4 +56,6 @@ evydence import-bundle upload \ --path evidence-bundle.json ``` -The package manifest at `deploy/airgap/manifest.yaml` lists expected package contents. It is not a backup and does not replace database, object-store, or key-management restore procedures. +Expected result: Evydence verifies and records the imported bundle manifest through the tenant-scoped API path. + +Air-gapped package manifests are not backups and do not replace database, object-store, or key-management restore procedures. Pair package evidence with the backup guidance in [Production hardening review](production-hardening.md). diff --git a/docs/api.md b/docs/api.md index 7463615..0c0c8f5 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1,6 +1,10 @@ # API Reference -The public API base path is `/v1`. +The public API base path is `/v1`. The generated contract is committed at [`../openapi.yaml`](../openapi.yaml) and served by the API at `/v1/openapi.json`. + +Use this page for common integration workflows and route lookup. Use `openapi.yaml` as the generated contract source. + +## Request Contract Common headers: @@ -11,140 +15,376 @@ Content-Type: application/json Accept: application/json ``` -Create and action endpoints require `Idempotency-Key`. Reusing the same key with the same request returns the original response. Reusing it with different request content returns `409` with `IDEMPOTENCY_KEY_REUSED`. - -Errors use RFC 9457 Problem Details and include stable `code` and `request_id` fields. Clients may send `X-Request-ID`; otherwise the API generates one and returns it in the response header and Problem Details body. - -The generated OpenAPI document is committed at `openapi.yaml` and served at `/v1/openapi.json`. - -## Enterprise Identity And Administration - -`POST /v1/organizations` creates a tenant-scoped organization. `POST /v1/users` creates a human user with normalized email, and `POST /v1/users/{id}/deactivate` records a deactivation transition. - -`POST /v1/role-bindings` assigns a role to a user or collector. Current roles are `tenant_admin`, `security_engineer`, `release_manager`, `customer_verifier`, and `collector`. Human SSO session actors derive API scopes from role bindings and enforce `resource_type`/`resource_id` constraints for product, project, release, customer package, evidence bundle, build, control evidence, source, deployment, incident, security scan, report, export, read, and write operations where those resources are part of the request. API key and collector API key scopes remain tenant-scoped. `GET /v1/role-bindings` lists tenant-scoped bindings. - -`POST /v1/sso/providers` records OIDC or SAML provider metadata. `POST /v1/sso/identity-links` links a verified provider subject to an existing user. `POST /v1/sso/sessions` issues an expiring one-time session token response; the token hash is stored server-side and is not returned by list/read paths. `POST /v1/sso/sessions/{id}/revoke` revokes the session. These endpoints model admin-managed identity/session records; they do not perform live OIDC discovery, JWKS validation, SAML assertion verification, browser redirects, or provider login callbacks. - -`GET /v1/admin/instance` returns low-detail instance diagnostics only for actors explicitly granted `instance:admin`. Tenant `admin` and ordinary wildcard `*` tenant keys remain tenant-scoped and do not satisfy this instance-wide scope unless `instance:admin` is also present. The endpoint exposes operational counts only, not raw evidence payloads, API keys, session hashes, or customer portal tokens. - -## Controls And Reports - -`POST /v1/control-frameworks` creates a tenant-scoped framework version such as an internal CRA-readiness or SSDF-lite mapping. `GET /v1/control-frameworks` lists framework versions for the tenant. - -`POST /v1/controls` creates a framework-owned control with evidence requirements. Supported requirement types currently match implemented evidence resources: `sbom`, `vulnerability_scan`, `vex`, `vulnerability_decision`, `artifact`, `build`, `build_attestation`, `openapi_contract`, `release_bundle`, and `exception`. `GET /v1/controls/{id}` reads a tenant-scoped control. - -`POST /v1/controls/{id}/evidence` appends a control evidence link to an existing subject and confidence value of `high`, `medium`, `low`, or `unsupported`. Duplicate links return the existing link. `GET /v1/control-evidence` lists links by optional control, product, or release filters. - -`GET /v1/reports/control-coverage?framework_id=...&product_id=...&release_id=...` returns deterministic coverage statuses per control: `satisfied`, `partial`, `missing`, `waived`, `not_applicable`, or `unknown`. Approved, unexpired exceptions with a matching `control_id` may waive a control. - -`GET /v1/reports/cra-readiness?product_id=...&release_id=...` returns a CRA-oriented technical evidence report built from the same control coverage engine. It includes assumptions and limitations and does not make legal compliance, certification, complete-SBOM, or secure-release claims. - -`GET /v1/control-framework-template-packs` lists built-in starter packs for CRA-readiness, NIST SSDF-lite, SOC 2-style technical evidence, and ISO 27001-style technical evidence. `POST /v1/control-framework-template-packs/{slug}/install` copies a pack into tenant-owned framework/control records. - -`POST /v1/waivers` creates a first-class waiver for a release, finding, control, or custom policy. `POST /v1/waivers/{id}/approve` records the append-only approval transition. Waivers are separate from exceptions and carry owner, risk, reason, expiry, supersession, and audit-chain entries. - -`POST /v1/approvals` creates immutable approval records for releases, contract diffs, waivers, security reviews, and customer packages. - -## CI Provenance - -Collectors are tenant-scoped automated ingesters. `POST /v1/collectors` creates a `github_actions`, `gitlab_ci`, or `generic_ci` collector and returns a one-time API key secret scoped for build/evidence upload. `GET /v1/collectors` lists collectors without key hashes or secrets. The server binds collector identity from the API key; clients must not submit `collector_id` for build attribution. - -`import_bundle` collectors are also supported for air-gapped workflows that move evidence bundles through controlled media before upload. `POST /v1/collectors/{id}/releases` records collector release supply-chain evidence such as version, artifact digest, signature, SBOM, scan, and pinning. `GET /v1/collectors/{id}/health` returns a tenant-scoped collector health report with checks and limitations. - -`POST /v1/builds` records an immutable build run. For `provider=github_actions`, the request must include `project_id`, `release_id`, `commit_sha`, `status`, `started_at`, `repository`, `workflow_ref`, `run_id`, and `run_attempt`. Supported statuses are `queued`, `running`, `passed`, `failed`, and `cancelled`. `GET /v1/builds/{id}` requires `build:read`. - -`POST /v1/builds/{id}/attestations` accepts raw DSSE JSON containing `payloadType`, base64 `payload`, and `signatures`. Evydence decodes the in-toto Statement, records subjects, predicate type, SLSA builder/build metadata when present, stores raw bytes as tenant-prefixed evidence, and marks the record structurally valid. This slice does not perform cryptographic trust-root verification. - -## Evidence Lifecycle And Search - -`GET /v1/evidence/search` filters tenant evidence by product, project, release, build, deployment, type, subtype, source system, collector, verification status, subject ref, tag, created time, and limit. Results are tenant-scoped and sorted newest first. - -`POST /v1/evidence/{id}/lifecycle-events` appends lifecycle records for `amendment`, `redaction`, `tombstone`, or `retention_marker`. These records do not mutate the immutable evidence core fields. `GET /v1/evidence/{id}/lifecycle-events` returns the timeline for one evidence item. - -## Release Candidates And Artifacts +Create and action endpoints require `Idempotency-Key`. Reusing the same key with the same request returns the original response. Reusing the same key with different request content returns `409` with `IDEMPOTENCY_KEY_REUSED`. -`POST /v1/release-candidates` records an immutable release-candidate snapshot over explicit builds, artifacts, SBOMs, scans, VEX documents, OpenAPI contracts, and bundles. `POST /v1/release-candidates/{id}/promote` and `/reject` append the terminal transition; a candidate cannot be transitioned twice. +Successful JSON responses use a `data` envelope. Errors use RFC 9457 Problem Details with stable `code` and `request_id` fields. Clients may send `X-Request-ID`; otherwise the API generates one and returns it in the response header and Problem Details body. -`POST /v1/container-images` records OCI-style image repository, tag, digest, platform, and optional artifact binding. `POST /v1/artifact-signatures` records detached artifact signature metadata and optional raw signature payload bytes in object storage. `POST /v1/verify` supports `subject_type=artifact_signature` for digest binding and signature-presence verification. +Example validation problem: -`POST /v1/artifact-signatures/{id}/verify-cosign` records cosign-style digest-bound verification metadata, including optional Rekor UUID/log index and certificate identity/issuer. The check verifies the stored artifact digest binding and signature presence, and captures transparency metadata when supplied. It does not claim full Sigstore trust-chain verification unless a later trust-root integration proves it. - -## Source And Deployment Evidence - -`POST /v1/source/repositories`, `/v1/source/commits`, `/v1/source/branches`, and `/v1/source/pull-requests` record source-control evidence without replacing the source provider as the source of truth. Commit messages are represented by hashes, not stored as raw report text. - -`POST /v1/collectors/github/source-snapshots` and `/v1/collectors/gitlab/source-snapshots` accept strict JSON snapshots containing repository, commit, branch-protection, and pull-request metadata. No live provider API calls or OIDC token verification are performed by these endpoints. +```json +{ + "type": "about:blank", + "title": "Bad Request", + "status": 400, + "code": "VALIDATION_FAILED", + "request_id": "req-test-validation" +} +``` -`POST /v1/environments` creates deployment environments for a product. `POST /v1/deployments` records deployment events linking an environment, release, artifacts, status, timing, and optional rollback reference. Rollbacks are recorded as new deployment events, not destructive edits. +## Minimal Release Evidence Workflow -## Release Risk Decisions +The getting-started tutorial has a runnable curl flow. This section is the compact API shape for client implementers. -OpenVEX ingestion is available at `POST /v1/vex` with a request body containing `release_id`, optional `artifact_id`, and `payload`. The payload must be OpenVEX JSON with author, timestamp, and one or more statements. Raw VEX bytes are stored as tenant-prefixed object payloads and represented as immutable `vex` evidence. +### 1. Create Product, Project, And Release -CycloneDX VEX ingestion is available at `POST /v1/vex/cyclonedx` for CycloneDX JSON with `vulnerabilities[].analysis`. It preserves raw payload bytes, records a `vex` evidence item, and normalizes matching finding decisions when a release finding has the same vulnerability ID. +```sh +curl -sS -X POST "$EVYDENCE_URL/v1/products" \ + -H "Authorization: Bearer $EVYDENCE_API_KEY" \ + -H "Idempotency-Key: product-payments-api" \ + -H "Content-Type: application/json" \ + --data '{"name":"Payments API","slug":"payments-api"}' +``` -Vulnerability findings from `POST /v1/vulnerability-scans` can be resolved with `POST /v1/vulnerability-findings/{id}/decisions`. Supported statuses are `affected`, `not_affected`, `fixed`, and `under_investigation`. New decisions supersede earlier decisions for the same finding. +Expected status: `201`. -`POST /v1/vulnerability-findings/{id}/workflow` appends workflow records such as scanner metadata, SLA notes, scanner disagreement, supersession, or re-open markers. `GET /v1/reports/vulnerability-posture?release_id=...` summarizes uploaded findings. These records organize scanner evidence and do not make scanner findings authoritative. +Representative response shape: -Scoped exceptions are created with `POST /v1/exceptions` and approved separately with `POST /v1/exceptions/{id}/approve`. Only approved, unexpired exceptions can affect release readiness. +```json +{ + "data": { + "id": "prod_...", + "name": "Payments API", + "slug": "payments-api", + "tenant_id": "ten_..." + } +} +``` -`GET /v1/reports/release-readiness?release_id=...` returns deterministic readiness JSON with checks, blocking findings, accepted exceptions, gaps, assumptions, and limitations. Readiness requires SBOM, vulnerability scan, artifact digest evidence, signed bundle, passed build provenance, build attestation subject matching a release artifact digest, and no unhandled open critical finding. It supports compliance readiness only and is not a legal compliance or secure-release conclusion. +Then create: -## Incidents And Remediation +```http +POST /v1/projects +POST /v1/releases +``` -`POST /v1/incidents` creates an incident linked to a product and optional release. `POST /v1/incidents/{id}/timeline` appends timeline events, optionally linked to evidence. `POST /v1/remediation-tasks` creates remediation tasks linked to an incident or release. +Representative request bodies: -`GET /v1/reports/incident-package?incident_id=...` returns a deterministic incident package with timeline events, remediation tasks, linked evidence IDs, assumptions, and limitations. It is an evidence organization report and does not prove root cause completeness or remediation sufficiency. +```json +{"product_id":"prod_...","name":"api"} +``` -## Security Evidence And SBOM Expansion +```json +{"product_id":"prod_...","version":"1.0.0"} +``` -`POST /v1/security-scans` uploads normalized SAST, DAST, secret scan, license scan, or API-security scan JSON. `POST /v1/api-security-scans` is a convenience route for API security scan evidence. Generic payloads use `findings[].severity`; SARIF payloads use `runs[].results[].level`. Secret scan evidence is marked redacted and quarantined when findings are present. +### 2. Register Artifact And Upload Evidence -`POST /v1/security-documents` uploads sensitive manual security documents with type `threat_model`, `security_review`, or `pen_test_report` and sensitivity `internal`, `confidential`, or `restricted`. Raw bytes are stored as object payloads and the API response exposes metadata, not payload contents. +Register an artifact: -`POST /v1/sboms/spdx` ingests SPDX JSON as first-class SBOM evidence. `POST /v1/sbom-diffs` compares two stored SBOMs and records added, removed, and unchanged component counts. SBOM handling does not prove SBOM completeness. +```json +{ + "name": "api.tar.gz", + "media_type": "application/gzip", + "digest": "sha256:ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", + "size": 42 +} +``` -## Packages, Templates, And Bundles +Upload generic evidence: + +```json +{ + "product_id": "prod_...", + "project_id": "proj_...", + "release_id": "rel_...", + "type": "build", + "subtype": "log", + "title": "Build evidence", + "payload_hash": "sha256:ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", + "tags": ["ci"], + "limitations": ["Captured from CI metadata submitted by the collector."] +} +``` -`POST /v1/redaction-profiles` creates an explicit package redaction profile. `POST /v1/customer-packages` creates a scoped customer security package manifest with expiry and access auditing. `GET /v1/customer-packages/{id}` reads the manifest and records an access event; raw payload bytes are not returned. +`POST /v1/evidence` creates immutable evidence metadata. Later changes are represented by supersession, lifecycle events, links, or new evidence records. -`POST /v1/customer-portal/access` creates an expiring customer portal access token for one package and returns the token once. `POST /v1/customer-portal/package` accepts that token and returns the scoped package manifest without exposing the token or raw tenant evidence. The portal exchange intentionally does not use an API scope such as `customer:portal`; it is a package-scoped token flow. Failed portal token attempts that match a known token prefix record a safe audit-chain signal without storing or returning the supplied token. After repeated failed attempts for one active access record, Evydence revokes that access record and reports only tenant-safe counters. +### 3. Upload SBOM And Vulnerability Evidence -`POST /v1/questionnaire-templates` creates tenant-defined customer questionnaire templates with question-to-evidence hints. `POST /v1/questionnaire-packages` generates deterministic evidence-backed responses for a package, product, and release scope. Responses cite linked evidence IDs and include limitations for human review. +CycloneDX SBOM: -`GET /v1/reports/security-review-package?package_id=...` returns a redaction-aware security review package report. `GET /v1/reports/cra-readiness-html?product_id=...&release_id=...` returns deterministic HTML content for CRA-readiness review with limitations and no compliance conclusion. +```http +POST /v1/sboms +``` -`POST /v1/report-templates` creates a tenant report template with explicit allowed fields. `POST /v1/report-templates/{id}/render` renders only those allowed fields into a deterministic JSON report. +```json +{ + "release_id": "rel_...", + "artifact_id": "art_...", + "payload": { + "bomFormat": "CycloneDX", + "specVersion": "1.6", + "components": [ + {"name": "openssl", "purl": "pkg:apk/openssl@3.1.0"} + ] + } +} +``` -`POST /v1/evidence-bundles` exports a portable evidence bundle manifest with evidence IDs, manifest hash, signature references, and verification instructions. `POST /v1/evidence-bundles/import` verifies and records an imported bundle manifest. The CLI command `evydence verify-evidence-bundle ` verifies bundle manifest hashes offline. +Vulnerability scan: -`POST /v1/dsse-trust-roots` configures an Ed25519 DSSE verification trust root. `POST /v1/build-attestations/{id}/verify-signature` verifies stored DSSE attestation signatures against configured trust roots and records a verification result. +```http +POST /v1/vulnerability-scans +``` -## Integrity, Audit, And Operations +```json +{ + "scanner": "grype", + "target_ref": "pkg:oci/payments-api", + "release_id": "rel_...", + "findings": [ + { + "vulnerability": "CVE-2026-0099", + "component": "pkg:apk/openssl@3.1.0", + "severity": "critical", + "state": "open" + } + ] +} +``` -`POST /v1/signing-keys/{id}/revoke` revokes a tenant signing key. Historical signatures created before revocation remain valid-at-signing when their cryptographic signature still verifies; revoked keys are not used for new signatures. +Scanner evidence is recorded for review and workflow decisions. It is not treated as authoritative by itself. -`POST /v1/signing-providers` records a signing-provider configuration reference such as `local_encrypted_dev`, `aws_kms`, `gcp_kms`, `azure_key_vault`, or `pkcs11_hsm`. The API stores provider metadata and key references, not private key material. Production still requires an external signing mode. +Decision on a finding: -`POST /v1/merkle-batches` creates a signed Merkle batch over a tenant audit-chain sequence range. `GET /v1/merkle-batches/{id}/verify` recomputes the Merkle root and verifies the checkpoint signature. +```http +POST /v1/vulnerability-findings/{id}/decisions +``` -`POST /v1/transparency-checkpoints` records optional external timestamp/transparency anchoring metadata for a Merkle batch. Public transparency is optional and not required for local trust. +```json +{ + "status": "not_affected", + "justification": "vulnerable code path is not present" +} +``` -`POST /v1/object-retention-policies` records tenant-prefixed object-retention policy intent. `POST /v1/object-retention-policies/{id}/verify` records a verification transition for the policy record. Object-lock enforcement depends on the configured object store. +Supported decision statuses are `affected`, `not_affected`, `fixed`, and `under_investigation`. -`POST /v1/backup-manifests` generates a backup manifest with a state hash, resource counts, audit-chain consistency checks, and limitations. `GET /v1/backup-manifests/{id}/verify` verifies the recorded manifest checks. The manifest intentionally excludes raw payload bytes and private keys; restore requires matched database and object-store backups. +### 4. Readiness And Bundle Retrieval -`GET /v1/ready` returns a low-detail readiness response. `GET /v1/metrics` returns tenant-scoped safe resource counts and requires admin scope. +Create a release bundle: -`GET /v1/audit-log` lists tenant audit-chain entries with optional `subject_type`, `subject_id`, `since`, and `limit` filters. It requires admin scope and returns tenant-scoped audit fields only. +```http +POST /v1/release-bundles +``` -`POST /v1/legal-holds` records a legal hold for tenant, product, project, release, or evidence scope. `POST /v1/retention-overrides` records an expiring retention override. `GET /v1/reports/retention` lists tenant-scoped legal hold and retention override records with limitations. +```json +{"release_id":"rel_..."} +``` -`POST /v1/commercial-collectors` records a commercial collector definition with provider, version, manifest digest, allowed scopes, and status. `GET /v1/commercial-collectors` lists tenant-scoped definitions. These records define extension metadata and do not grant provider trust by themselves. +Read readiness: -## Contracts And Policy V2 +```http +GET /v1/reports/release-readiness?release_id=rel_... +``` -`POST /v1/openapi-diffs` compares two uploaded OpenAPI contracts by stored contract metadata and classifies the result as unchanged, changed, or breaking when target path count decreases. Rich operation-level diffing remains future work. +Representative response shape: + +```json +{ + "data": { + "release_id": "rel_...", + "result": "failed", + "checks": [], + "blocking_findings": [], + "gaps": [], + "assumptions": [], + "limitations": [] + } +} +``` -`POST /v1/custom-policies` creates a versioned deterministic policy with simple required evidence rules. `POST /v1/custom-policies/{id}/evaluate` stores a replayable evaluation with input hash and policy checks for one release. +Readiness is deterministic and evidence-scoped. It reports checks, blockers, gaps, assumptions, and limitations; it is not a legal compliance or release-security conclusion. + +## Authentication And Scopes + +API keys and collector keys are tenant-scoped bearer secrets. Human SSO session actors derive scopes from role bindings and enforce resource constraints where those resources are part of the request. + +Important scope boundaries: + +| Boundary | Behavior | +|----------|----------| +| Tenant data | Cross-tenant reads return `404` where applicable. | +| Collector identity | Build attribution is derived from the authenticated collector key; clients must not submit `collector_id` for build attribution. | +| Instance admin | `GET /v1/admin/instance` requires explicit `instance:admin`; tenant admin and ordinary wildcard tenant keys are insufficient. | +| Customer portal | `POST /v1/customer-portal/package` is a public token exchange endpoint and intentionally does not use bearer authentication. | + +## Endpoint Catalog + +### System + +| Method | Path | Notes | +|--------|------|-------| +| `GET` | `/v1/health` | Process health. | +| `GET` | `/v1/ready` | Low-detail readiness. | +| `GET` | `/v1/version` | Version metadata. | +| `GET` | `/v1/metrics` | Tenant-safe counts; admin scope required. | +| `GET` | `/v1/openapi.json` | Generated OpenAPI. | +| `GET` | `/v1/admin/instance` | Low-detail instance counts; `instance:admin` required. | + +### Identity And Administration + +| Method | Path | Notes | +|--------|------|-------| +| `POST` | `/v1/organizations` | Create tenant-scoped organization. | +| `POST` | `/v1/users` | Create normalized human user. | +| `POST` | `/v1/users/{id}/deactivate` | Record deactivation transition. | +| `POST` | `/v1/role-bindings` | Assign role to user or collector. | +| `GET` | `/v1/role-bindings` | List tenant-scoped bindings. | +| `POST` | `/v1/sso/providers` | Record OIDC or SAML provider metadata. | +| `POST` | `/v1/sso/identity-links` | Link verified provider subject to user. | +| `POST` | `/v1/sso/sessions` | Issue one-time session secret. | +| `POST` | `/v1/sso/sessions/{id}/revoke` | Revoke session. | +| `POST` | `/v1/api-keys` | Create one-time API key secret. | +| `GET` | `/v1/api-keys` | List keys without secret hashes. | + +Current SSO endpoints model admin-managed provider, identity-link, and session records. Live OIDC discovery, JWKS validation, SAML assertion verification, browser redirects, provider login callbacks, and group synchronization are not implemented in this slice. + +### Products, Releases, Evidence, And Risk + +| Method | Path | Notes | +|--------|------|-------| +| `POST` | `/v1/products` | Create product. | +| `GET` | `/v1/products` | List products. | +| `POST` | `/v1/projects` | Create project under product. | +| `POST` | `/v1/releases` | Create release. | +| `GET` | `/v1/releases/{id}` | Read release. | +| `POST` | `/v1/releases/{id}/freeze` | Append freeze transition. | +| `POST` | `/v1/releases/{id}/approve` | Append approval transition. | +| `POST` | `/v1/artifacts` | Register artifact digest metadata. | +| `POST` | `/v1/evidence` | Create immutable evidence metadata. | +| `GET` | `/v1/evidence` | List evidence by release/type. | +| `GET` | `/v1/evidence/search` | Search by product, project, release, build, deployment, type, subtype, source, collector, verification status, subject, tag, created time, and limit. | +| `GET` | `/v1/evidence/{id}` | Read evidence. | +| `POST` | `/v1/evidence/{id}/supersede` | Supersede without mutating original. | +| `POST` | `/v1/evidence/{id}/link` | Link evidence to another subject. | +| `POST` | `/v1/evidence/{id}/lifecycle-events` | Append amendment/redaction/tombstone/retention marker. | +| `GET` | `/v1/evidence/{id}/lifecycle-events` | Read lifecycle timeline. | +| `POST` | `/v1/sboms` | Upload CycloneDX SBOM. | +| `POST` | `/v1/sboms/spdx` | Upload SPDX SBOM. | +| `POST` | `/v1/sbom-diffs` | Compare stored SBOMs. | +| `POST` | `/v1/vulnerability-scans` | Upload normalized vulnerability scan. | +| `POST` | `/v1/vulnerability-findings/{id}/decisions` | Superseding decision record. | +| `POST` | `/v1/vulnerability-findings/{id}/workflow` | Append workflow event. | +| `GET` | `/v1/reports/vulnerability-posture` | Summarize findings for a release. | +| `GET` | `/v1/reports/release-readiness` | Deterministic readiness report. | + +### CI, Source, Deployment, And Collectors + +| Method | Path | Notes | +|--------|------|-------| +| `POST` | `/v1/collectors` | Create collector and one-time key. | +| `GET` | `/v1/collectors` | List collectors without secrets. | +| `POST` | `/v1/collectors/{id}/releases` | Record collector release evidence. | +| `GET` | `/v1/collectors/{id}/health` | Collector health report. | +| `POST` | `/v1/builds` | Record immutable build run. | +| `GET` | `/v1/builds/{id}` | Read build run. | +| `POST` | `/v1/builds/{id}/attestations` | Upload DSSE in-toto attestation JSON. | +| `POST` | `/v1/build-attestations/{id}/verify-signature` | Verify against configured DSSE trust roots. | +| `POST` | `/v1/source/repositories` | Record source repository. | +| `GET` | `/v1/source/repositories` | List repositories. | +| `POST` | `/v1/source/commits` | Record source commit. | +| `POST` | `/v1/source/branches` | Record branch state. | +| `POST` | `/v1/source/pull-requests` | Record pull request metadata. | +| `POST` | `/v1/collectors/github/source-snapshots` | Upload strict GitHub source snapshot. | +| `POST` | `/v1/collectors/gitlab/source-snapshots` | Upload strict GitLab source snapshot. | +| `POST` | `/v1/environments` | Create deployment environment. | +| `GET` | `/v1/environments` | List environments. | +| `POST` | `/v1/deployments` | Record deployment event. | +| `GET` | `/v1/deployments` | List deployments. | +| `GET` | `/v1/deployments/{id}` | Read deployment event. | + +Source snapshots capture submitted provider metadata. They do not call provider APIs or verify OIDC tokens. + +### Controls, Reports, Packages, And Governance + +| Method | Path | Notes | +|--------|------|-------| +| `POST` | `/v1/control-frameworks` | Create framework version. | +| `GET` | `/v1/control-frameworks` | List frameworks. | +| `GET` | `/v1/control-framework-template-packs` | List built-in starter packs. | +| `POST` | `/v1/control-framework-template-packs/{slug}/install` | Copy starter pack to tenant records. | +| `POST` | `/v1/controls` | Create control. | +| `GET` | `/v1/controls/{id}` | Read control. | +| `POST` | `/v1/controls/{id}/evidence` | Append control evidence link. | +| `GET` | `/v1/control-evidence` | List links. | +| `GET` | `/v1/reports/control-coverage` | Deterministic control coverage. | +| `GET` | `/v1/reports/cra-readiness` | Technical evidence readiness report with limitations. | +| `POST` | `/v1/exceptions` | Create exception. | +| `POST` | `/v1/exceptions/{id}/approve` | Approve exception. | +| `GET` | `/v1/exceptions` | List exceptions. | +| `POST` | `/v1/waivers` | Create waiver. | +| `POST` | `/v1/waivers/{id}/approve` | Approve waiver. | +| `POST` | `/v1/approvals` | Create immutable approval record. | +| `POST` | `/v1/redaction-profiles` | Create package redaction profile. | +| `POST` | `/v1/customer-packages` | Create scoped customer package manifest. | +| `GET` | `/v1/customer-packages/{id}` | Read package manifest and record access. | +| `POST` | `/v1/customer-portal/access` | Create one-time package access token. | +| `POST` | `/v1/customer-portal/package` | Exchange package token for scoped manifest. | +| `POST` | `/v1/questionnaire-templates` | Create questionnaire template. | +| `POST` | `/v1/questionnaire-packages` | Generate evidence-backed responses. | +| `GET` | `/v1/reports/security-review-package` | Redaction-aware package report. | +| `GET` | `/v1/reports/cra-readiness-html` | HTML CRA-readiness review content. | +| `POST` | `/v1/report-templates` | Create allowed-field template. | +| `POST` | `/v1/report-templates/{id}/render` | Render deterministic JSON report. | + +### Integrity, Verification, And Operations + +| Method | Path | Notes | +|--------|------|-------| +| `POST` | `/v1/release-bundles` | Create signed release bundle. | +| `GET` | `/v1/release-bundles/{id}` | Read bundle metadata. | +| `GET` | `/v1/release-bundles/{id}/manifest` | Read bundle manifest. | +| `GET` | `/v1/release-bundles/{id}/verify` | Verify bundle. | +| `POST` | `/v1/verify` | Verify supported subject types. | +| `GET` | `/v1/audit-chain/verify` | Verify tenant audit chain. | +| `GET` | `/v1/audit-log` | List tenant audit entries; admin scope required. | +| `GET` | `/v1/signing-keys` | List keys. | +| `POST` | `/v1/signing-keys/rotate` | Rotate signing key. | +| `POST` | `/v1/signing-keys/{id}/revoke` | Revoke key for new signatures. | +| `POST` | `/v1/signing-providers` | Record external signing-provider metadata. | +| `POST` | `/v1/merkle-batches` | Create signed checkpoint batch. | +| `GET` | `/v1/merkle-batches/{id}/verify` | Verify batch. | +| `POST` | `/v1/transparency-checkpoints` | Record external anchoring metadata. | +| `POST` | `/v1/object-retention-policies` | Record retention policy intent. | +| `POST` | `/v1/object-retention-policies/{id}/verify` | Record verification transition. | +| `POST` | `/v1/legal-holds` | Record legal hold. | +| `POST` | `/v1/retention-overrides` | Record retention override. | +| `GET` | `/v1/reports/retention` | List retention records. | +| `POST` | `/v1/backup-manifests` | Generate backup manifest. | +| `GET` | `/v1/backup-manifests/{id}/verify` | Verify backup manifest. | + +### Security Evidence And Contracts + +| Method | Path | Notes | +|--------|------|-------| +| `POST` | `/v1/security-scans` | Upload SAST, DAST, secret scan, license scan, or API-security scan JSON. | +| `POST` | `/v1/api-security-scans` | Convenience API-security scan route. | +| `POST` | `/v1/security-documents` | Upload sensitive manual security document metadata/payload. | +| `POST` | `/v1/vex` | Upload OpenVEX. | +| `POST` | `/v1/vex/cyclonedx` | Upload CycloneDX VEX. | +| `GET` | `/v1/vex/{id}` | Read VEX metadata. | +| `POST` | `/v1/openapi-contracts` | Upload OpenAPI contract. | +| `GET` | `/v1/openapi-contracts/{id}` | Read contract metadata. | +| `POST` | `/v1/openapi-diffs` | Compare stored contracts. | +| `POST` | `/v1/policies/evaluate` | Evaluate built-in release policy. | +| `POST` | `/v1/custom-policies` | Create deterministic custom policy. | +| `POST` | `/v1/custom-policies/{id}/evaluate` | Store replayable policy evaluation. | + +## Current Contract Limitations + +- `openapi.yaml` is generated as compact JSON-style YAML and is optimized for drift checks and tooling, not prose review. +- A subset of high-value operations has precise named schemas and response envelopes. Many route responses remain generic envelopes. +- Operation-level examples are maintained here and in tests until the generator emits richer examples. +- OpenAPI diffing currently classifies broad path-count changes; rich operation-level compatibility analysis remains future work. + +These limitations should be called out in release evidence when API contract review is part of the release process. diff --git a/docs/architecture.md b/docs/architecture.md index d1814a4..92b39e9 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -10,16 +10,48 @@ Evydence follows a ports-and-adapters shape: - `internal/adapters/objectstore/s3` stores the same tenant-prefixed object keys in S3/MinIO-compatible buckets. - `cmd/*` contains process entry points. -Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and also rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for the implemented release, evidence, source, deployment, and control resources. The projection supports operational querying and migration discipline while keeping the application store contract small. +Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. -## Security Boundaries +## Tenant And Auth Boundaries -Tenant isolation is enforced in application methods before reads and writes return data. API keys are scoped, revocable, and stored as HMAC-SHA256 hashes with `EVYDENCE_API_KEY_PEPPER`. Human SSO session tokens and customer portal package tokens are also stored as hashes and returned only once. Human actors derive scopes from tenant role bindings; collector identity is server-derived from the API key binding and is not trusted from build upload request bodies. Evidence, evidence lifecycle events, incidents, remediation tasks, security scans, manual security documents, SBOM diffs, VEX documents, vulnerability decisions/workflow records, organizations, users, role bindings, SSO providers, SSO sessions, legal holds, retention overrides, customer portal access records, questionnaire packages, commercial collector definitions, waivers, approvals, customer packages, report templates, evidence bundles, exceptions, build runs, build attestations, release candidates, artifact signatures, source-control records, deployment events, contract diffs, custom policy evaluations, control evidence links, and release bundle records are append-only in behavior; changes are represented by supersession, lifecycle events, approval transitions, session revocation, package access records, links, verification receipts, rollback-as-new-event records, or new audit-chain entries. +Tenant isolation is enforced in application methods before reads and writes return data. API keys are scoped, revocable, and stored as HMAC-SHA256 hashes with `EVYDENCE_API_KEY_PEPPER`. -When `EVYDENCE_DATABASE_URL` is set, mutations are saved to PostgreSQL before successful responses return. Upload payload bytes, including raw SBOM, vulnerability scan, OpenAPI, OpenVEX, and DSSE build-attestation payloads, are written to the configured filesystem object store with tenant-prefixed keys and SHA-256 digest checks before metadata is accepted. Outbox jobs are persisted in PostgreSQL and claimed by workers with `FOR UPDATE SKIP LOCKED`. +Human SSO session tokens and customer portal package tokens are also stored as hashes and returned only once. Human actors derive scopes from tenant role bindings. Collector identity is server-derived from the API key binding and is not trusted from build upload request bodies. -Release readiness is deterministic and evidence-scoped. Open critical vulnerability findings block readiness unless the latest decision marks the finding `not_affected` or `fixed`, or an approved unexpired exception applies to the release/finding. Passed build provenance and a structurally valid build attestation must link to release artifact digests. Source snapshots, deployment records, incident packages, security scans, manual reviews, SBOM diffs, contract diffs, API security checks, customer packages, customer portal package access, questionnaire packages, evidence bundles, and custom policies add traceability and reproducible decisions but do not prove provider truth, scanner authority, runtime security, legal sufficiency, or secure releases. Control coverage and CRA-readiness reports use versioned tenant-created controls, explicit evidence links, approved unexpired control exceptions, and built-in starter packs for CRA-readiness, NIST SSDF-lite, SOC 2-style technical evidence, and ISO 27001-style technical evidence. GitHub OIDC subject metadata can be captured, but OIDC token verification and live provider API verification are roadmap work. DSSE attestation signatures can be verified against configured Ed25519 trust roots when raw attestation bytes are available. Cosign-style artifact verification records digest binding, signature presence, and optional Rekor metadata without overstating full Sigstore trust-chain validation. Signing keys support revocation and valid-at-signing semantics for historical signatures. Merkle batches, signed checkpoints, optional transparency checkpoint records, backup manifests, object-retention policy records, legal holds, retention overrides, readiness, metrics, instance admin diagnostics, and admin audit queries provide operational integrity and review surfaces. Collector supply-chain records track pinned collector versions with signature, SBOM, and scan evidence where available; commercial collector definitions add extension metadata without granting provider trust. Air-gapped import-bundle workflows preserve the same tenant-scoped import path after controlled transfer. Reports include gaps, assumptions, and limitations and do not make legal compliance or secure-release claims. +Instance diagnostics require explicit `instance:admin` scope. Tenant admin and ordinary wildcard tenant keys do not satisfy that instance-wide scope by themselves. + +## Storage And Append-Only Behavior + +When `EVYDENCE_DATABASE_URL` is set, mutations are saved to PostgreSQL before successful responses return. Upload payload bytes, including raw SBOM, vulnerability scan, OpenAPI, OpenVEX, and DSSE build-attestation payloads, are written to the configured object store with tenant-prefixed keys and SHA-256 digest checks before metadata is accepted. + +Evidence, evidence lifecycle events, incidents, remediation tasks, security scans, manual security documents, SBOM diffs, VEX documents, vulnerability decisions/workflow records, organizations, users, role bindings, SSO providers, SSO sessions, legal holds, retention overrides, customer portal access records, questionnaire packages, commercial collector definitions, waivers, approvals, customer packages, report templates, evidence bundles, exceptions, build runs, build attestations, release candidates, artifact signatures, source-control records, deployment events, contract diffs, custom policy evaluations, control evidence links, and release bundle records are append-only in behavior. Changes are represented by supersession, lifecycle events, approval transitions, session revocation, package access records, links, verification receipts, rollback-as-new-event records, or new audit-chain entries. + +Outbox jobs are persisted in PostgreSQL and claimed by workers with `FOR UPDATE SKIP LOCKED`. + +## Verification And Trust + +Release readiness is deterministic and evidence-scoped. Open critical vulnerability findings block readiness unless the latest decision marks the finding `not_affected` or `fixed`, or an approved unexpired exception applies to the release or finding. Passed build provenance and a structurally valid build attestation must link to release artifact digests. + +DSSE attestation signatures can be verified against configured Ed25519 trust roots when raw attestation bytes are available. Cosign-style artifact verification records digest binding, signature presence, and optional Rekor metadata without overstating full Sigstore trust-chain validation. Signing keys support revocation and valid-at-signing semantics for historical signatures. + +Merkle batches, signed checkpoints, optional transparency checkpoint records, backup manifests, object-retention policy records, legal holds, retention overrides, readiness, metrics, instance admin diagnostics, and admin audit queries provide operational integrity and review surfaces. + +## Reports And Customer-Facing Packages + +Control coverage and CRA-readiness reports use versioned tenant-created controls, explicit evidence links, approved unexpired control exceptions, and built-in starter packs for CRA-readiness, NIST SSDF-lite, SOC 2-style technical evidence, and ISO 27001-style technical evidence. + +Source snapshots, deployment records, incident packages, security scans, manual reviews, SBOM diffs, contract diffs, API security checks, customer packages, customer portal package access, questionnaire packages, evidence bundles, and custom policies add traceability and reproducible decisions. Reports include gaps, assumptions, and limitations. + +Customer-facing packages require explicit package scope, redaction profile, expiry, and access auditing. Raw tenant evidence payload bytes are not returned by customer package read paths. + +## Provider And Deployment Boundaries + +GitHub OIDC subject metadata can be captured, but OIDC token verification and live provider API verification are roadmap work. Collector supply-chain records track pinned collector versions with signature, SBOM, and scan evidence where available; commercial collector definitions add extension metadata without granting provider trust. + +Air-gapped import-bundle workflows preserve the same tenant-scoped import path after controlled transfer. Object-retention policy APIs record and verify retention intent for tenant-prefixed object paths, but WORM/object-lock enforcement remains the responsibility of the configured object store and deployment policy. ## Limitations -The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider records are implemented, but production-grade KMS/HSM signing operations remain a hardening area behind the external signing mode. Hand-tuned per-resource repository implementations remain roadmap work. `ENV=production` rejects the in-process store, default API-key pepper, and local plaintext signing-key mode. +The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider records are implemented, but production-grade KMS/HSM signing operations remain a hardening area behind the external signing mode. Hand-tuned per-resource repository implementations remain roadmap work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. + +Evydence does not prove provider truth, scanner authority, runtime security, legal compliance, or release security by itself. diff --git a/docs/collectors/supply-chain.md b/docs/collectors/supply-chain.md index dc74129..43f4690 100644 --- a/docs/collectors/supply-chain.md +++ b/docs/collectors/supply-chain.md @@ -2,12 +2,46 @@ This is a reference for collector release evidence. -Collector releases can be recorded with: +Collector records describe automated ingesters such as GitHub Actions, GitLab CI, generic CI, and import-bundle collectors. A collector API key is tenant-scoped and should be stored in the CI secret store. + +## Record A Collector Release ```http POST /v1/collectors/{id}/releases ``` -The release record includes version, artifact digest, optional signature evidence, optional SBOM, optional vulnerability scan, and whether the version is pinned. `GET /v1/collectors/{id}/health` returns the collector status and supply-chain evidence checks. +Representative request: + +```json +{ + "version": "0.1.0", + "artifact_digest": "sha256:2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae", + "signature_id": "sig_...", + "sbom_id": "sbom_...", + "scan_id": "scan_...", + "pinned": true +} +``` + +Expected status is `201`. Optional fields should reference evidence already recorded in the same tenant. + +## Review Collector Health + +```http +GET /v1/collectors/{id}/health +``` + +The health report can show whether: + +- a collector release record exists; +- the collector version is pinned; +- signature, SBOM, or vulnerability scan evidence was linked where available. + +Health reports help operators see collector evidence gaps. They do not prove that a collector is free of vulnerabilities, provider-verified, or safe to run. + +## Related Docs -Collector health reports help operators see whether collector evidence exists and whether a version is pinned. They do not prove that a collector is free of vulnerabilities or safe at runtime. +- [Integrate CI collectors](../how-to/integrate-ci.md) +- [Source snapshot collectors](source-snapshots.md) +- [GitHub Actions release evidence workflow](../github-actions/release-evidence-workflow.yml) +- [GitLab release evidence CI template](../gitlab/evydence-release-evidence.gitlab-ci.yml) diff --git a/docs/how-to/install-and-operate.md b/docs/how-to/install-and-operate.md index 36d738a..96ae45d 100644 --- a/docs/how-to/install-and-operate.md +++ b/docs/how-to/install-and-operate.md @@ -1,31 +1,71 @@ # Install And Operate -Use this guide for a self-hosted development or evaluation deployment. +Use this guide for a local self-hosted development or evaluation deployment. ## Runtime Modes -- No `EVYDENCE_DATABASE_URL`: in-process state for local demos and unit tests. -- `EVYDENCE_DATABASE_URL` set: PostgreSQL-backed durable ledger snapshot, resource projections, migrations, and persisted outbox jobs. -- `ENV=production`: unsafe local defaults are rejected. +| Mode | How To Enable | Expected Use | +|------|---------------|--------------| +| In-process state | Leave `EVYDENCE_DATABASE_URL` unset. | Local demos and unit tests. State is lost when the process exits. | +| PostgreSQL state | Set `EVYDENCE_DATABASE_URL`. | Durable local or self-hosted operation with migrations and persisted outbox jobs. | +| Production checks | Set `ENV=production`. | Rejects unsafe local defaults before API startup. | -## Commands +Configuration details live in [Configuration](../reference/configuration.md). + +## Start Local Dependencies ```sh make compose-up -set -a; . ./.test.env; set +a +``` + +Expected result: Docker Compose starts PostgreSQL and MinIO containers using `.env.example` defaults unless local overrides are present. + +Stop them with: + +```sh +make compose-down +``` + +## Run With PostgreSQL + +```sh +cp .api.env.example .api.env +set -a; . ./.api.env; set +a make migrate -go run ./cmd/evydence-api +EVYDENCE_PRINT_BOOTSTRAP_SECRET=true go run ./cmd/evydence-api +``` + +Expected result: + +- `make migrate` exits successfully after applying migrations from `migrations/`. +- API startup logs that it is using PostgreSQL state and the configured object store. +- If the store is empty and bootstrap is enabled, the API prints a one-time local admin secret. + +Run the worker in a separate shell with the same environment: + +```sh +set -a; . ./.api.env; set +a go run ./cmd/evydence-worker ``` -## Checks +The worker validates persisted outbox jobs. See [Worker outbox contract](../reference/worker-outbox.md) for job kinds, idempotency, and safe logging rules. + +## Verify The Local Runtime ```sh +curl -sS http://localhost:8080/v1/ready | jq . make live-postgres-check make postgres-integration-test -make finalize ``` -For release validation with live PostgreSQL evidence, start Compose, load `.test.env`, and run `make release-check`. The target writes `tmp/release-check-summary.txt`; the release validation reference explains the expected pass and skip lines. +Expected result: + +- `/v1/ready` returns `200` with low-detail status JSON. +- Live PostgreSQL checks run when `EVYDENCE_TEST_DATABASE_URL` is set. +- If `EVYDENCE_TEST_DATABASE_URL` is unset, the Make targets print an explicit skip message and exit successfully. + +For the full release gate, use [Release validation](../reference/release-validation.md) as the canonical command reference. + +## Backup Pairing -Back up PostgreSQL and the configured object store together. Backup manifests help compare recorded ledger state, but restore confidence depends on matched database and object payload backups. +Back up PostgreSQL and the configured object store together. Backup manifests record ledger-state hashes and consistency checks, but they are not backups by themselves. Restore confidence depends on matched database and object payload backups plus the OpenAPI, migration, and release artifact versions used at the time of the backup. diff --git a/docs/how-to/integrate-ci.md b/docs/how-to/integrate-ci.md new file mode 100644 index 0000000..8b64828 --- /dev/null +++ b/docs/how-to/integrate-ci.md @@ -0,0 +1,76 @@ +# Integrate CI Collectors + +Use this guide to connect CI systems to Evydence. The examples submit CI metadata and artifacts as tenant-scoped evidence; they do not make Evydence the source of truth for provider-side policy, identity, or workflow state. + +## Prerequisites + +- An Evydence API URL. +- A tenant admin API key for creating collectors, or an existing collector key with the required write scopes. +- Product, project, release, and artifact IDs for the release being recorded. +- Provider secrets stored in the CI secret store, not committed to the repository. + +## Create A Collector + +Create a collector with an admin key: + +```sh +curl -sS -X POST "$EVYDENCE_URL/v1/collectors" \ + -H "Authorization: Bearer $EVYDENCE_ADMIN_API_KEY" \ + -H "Idempotency-Key: collector-github-actions-main" \ + -H "Content-Type: application/json" \ + --data '{"name":"github-actions-main","type":"github_actions","version":"1.0.0"}' \ + | jq . +``` + +Expected status is `201`. The response returns the collector API key secret once. Store it as a CI secret such as `EVYDENCE_API_KEY`. + +## GitHub Actions + +The full example workflow is [docs/github-actions/release-evidence-workflow.yml](../github-actions/release-evidence-workflow.yml). The composite upload action is [docs/github-actions/upload-build/action.yml](../github-actions/upload-build/action.yml). + +Required CI inputs: + +- `EVYDENCE_API_URL` +- `EVYDENCE_API_KEY` +- `EVYDENCE_PROJECT_ID` +- `EVYDENCE_RELEASE_ID` +- `EVYDENCE_ARTIFACT_ID` +- `EVYDENCE_ARTIFACT_DIGEST` +- a DSSE attestation file when uploading build attestation evidence + +The CLI command used by the workflow reads GitHub-provided environment variables such as `GITHUB_REPOSITORY`, `GITHUB_WORKFLOW_REF`, `GITHUB_RUN_ID`, `GITHUB_RUN_ATTEMPT`, `GITHUB_REF`, and `GITHUB_SHA`. + +`EVYDENCE_GITHUB_OIDC_SUBJECT` or `--oidc-subject` can record an OIDC subject string when the workflow already has one. This implementation records the value as evidence metadata; it does not request or verify a GitHub OIDC token. + +## GitLab CI + +The GitLab template is [docs/gitlab/evydence-release-evidence.gitlab-ci.yml](../gitlab/evydence-release-evidence.gitlab-ci.yml). + +Required CI variables mirror the GitHub flow: + +- `EVYDENCE_API_URL` +- `EVYDENCE_API_KEY` +- `EVYDENCE_PROJECT_ID` +- `EVYDENCE_RELEASE_ID` +- `EVYDENCE_ARTIFACT_ID` +- `EVYDENCE_ARTIFACT_DIGEST` + +GitLab-provided variables such as `CI_PROJECT_PATH`, `CI_COMMIT_SHA`, `CI_PIPELINE_ID`, and `CI_JOB_ID` can be included in source snapshots or build evidence. + +## Source Snapshots + +Use [Source snapshot collectors](../collectors/source-snapshots.md) to upload repository, commit, branch-protection, and pull-request metadata from GitHub or GitLab: + +- `POST /v1/collectors/github/source-snapshots` +- `POST /v1/collectors/gitlab/source-snapshots` + +Do not include bearer tokens, private repository credentials, or raw provider secret dumps in snapshot payloads. Commit messages are stored as hashes by the API service. + +## Collector Supply Chain + +Use [Collector supply chain](../collectors/supply-chain.md) to record collector release evidence and health checks: + +- `POST /v1/collectors/{id}/releases` +- `GET /v1/collectors/{id}/health` + +Collector health reports show whether release evidence exists and whether a collector version is pinned. They do not prove that a collector is free of vulnerabilities or safe to run. diff --git a/docs/kubernetes.md b/docs/kubernetes.md index 1b3b9cf..641eb82 100644 --- a/docs/kubernetes.md +++ b/docs/kubernetes.md @@ -4,7 +4,17 @@ This is a how-to guide for self-hosted Kubernetes deployments. The Helm chart lives at `deploy/helm/evydence`. It deploys the API, worker, service, optional ingress, readiness and liveness probes, and configuration for external PostgreSQL, S3/MinIO object storage, and external signing mode. -Create a secret with at least: +## Prerequisites + +- A published Evydence image. +- External PostgreSQL and S3/MinIO-compatible object storage. +- A pre-created object-store bucket. +- A Kubernetes secret containing at least `EVYDENCE_DATABASE_URL` and `EVYDENCE_API_KEY_PEPPER`. +- A signing setup compatible with `EVYDENCE_SIGNING_KEY_MODE=external`. + +The chart does not create databases, buckets, KMS keys, or secrets. + +## Create Secrets ```sh kubectl create secret generic evydence-secrets \ @@ -12,7 +22,9 @@ kubectl create secret generic evydence-secrets \ --from-literal=EVYDENCE_API_KEY_PEPPER='replace-with-long-random-value' ``` -Install: +Store real values in your secret manager or sealed-secret process. Do not commit rendered secrets. + +## Install Or Upgrade ```sh helm upgrade --install evydence ./deploy/helm/evydence \ @@ -22,4 +34,47 @@ helm upgrade --install evydence ./deploy/helm/evydence \ --set env.s3Bucket=evydence ``` -Production deployments should use external PostgreSQL, S3/MinIO-compatible object storage, TLS ingress, backup automation, and `EVYDENCE_SIGNING_KEY_MODE=external`. The chart does not create databases, buckets, KMS keys, or secrets. +Relevant chart values are defined in `deploy/helm/evydence/values.yaml`: + +| Value | Purpose | +|-------|---------| +| `image.repository`, `image.tag` | API and worker image. | +| `existingSecret` | Secret containing runtime sensitive variables. | +| `env.databaseURLSecretKey` | Secret key for `EVYDENCE_DATABASE_URL`. | +| `env.apiKeyPepperSecretKey` | Secret key for `EVYDENCE_API_KEY_PEPPER`. | +| `env.objectStore` | `s3` or `minio` for cluster deployments. | +| `env.s3Endpoint`, `env.s3Bucket`, `env.s3Region`, `env.s3UseSSL` | Object-store configuration. | +| `env.signingKeyMode` | Should be `external` for production. | +| `ingress.*` | Optional ingress host and TLS secret. | + +## Verify + +```sh +kubectl rollout status deploy/evydence-api +kubectl rollout status deploy/evydence-worker +kubectl get pods -l app.kubernetes.io/name=evydence +kubectl port-forward svc/evydence 8080:8080 +curl -sS http://localhost:8080/v1/ready +``` + +Expected result: + +- API and worker deployments roll out. +- Pods stay ready. +- `/v1/ready` returns low-detail readiness JSON. +- Startup logs do not print bootstrap secrets when `ENV=production`. + +## Rollback + +Use Helm history and rollback commands: + +```sh +helm history evydence +helm rollback evydence +``` + +Rollback does not roll back PostgreSQL data or object-store payloads. Keep database migrations, object-store backups, and release artifact versions paired with the Helm revision used for deployment. + +## Production Notes + +Production deployments should use external PostgreSQL, S3/MinIO-compatible object storage, TLS ingress, backup automation, network access controls, and external signing. See [Production hardening review](production-hardening.md) and [Configuration](reference/configuration.md). diff --git a/docs/operations.md b/docs/operations.md index 0d32454..65c4d52 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -1,114 +1,33 @@ # Operations -## Configuration +This operator index points to the canonical references for running Evydence. Keep command details in the linked pages so startup, configuration, and release validation guidance do not drift. -Backend configuration is read from environment variables: +## Operator Tasks -- `EVYDENCE_ADDR`: API bind address, default `:8080`. -- `EVYDENCE_API_KEY_PEPPER`: HMAC pepper for API key hashes. Use a long random value. -- `EVYDENCE_DATABASE_URL`: PostgreSQL connection string. When set, the API uses durable PostgreSQL state and persisted outbox jobs. Required for production. -- `EVYDENCE_OBJECT_STORE`: `filesystem`, `s3`, or `minio`. Defaults to `filesystem`. -- `EVYDENCE_OBJECT_DIR`: filesystem object-store root for raw uploaded payload bytes, default `tmp/objects` when PostgreSQL is enabled. -- `EVYDENCE_S3_ENDPOINT`: S3/MinIO endpoint when `EVYDENCE_OBJECT_STORE=s3` or `minio`. -- `EVYDENCE_S3_BUCKET`: S3/MinIO bucket name. The bucket must already exist. -- `EVYDENCE_S3_ACCESS_KEY_ID`: S3/MinIO access key ID. -- `EVYDENCE_S3_SECRET_ACCESS_KEY`: S3/MinIO secret access key. -- `EVYDENCE_S3_REGION`: optional S3 region. -- `EVYDENCE_S3_USE_SSL`: set to `true` for HTTPS endpoints. -- `EVYDENCE_SKIP_MIGRATIONS`: set to `true` only when migrations are applied by an external release process. -- `EVYDENCE_MIGRATIONS_DIR`: migration directory, default `migrations`. -- `EVYDENCE_BOOTSTRAP_TENANT`: local bootstrap tenant name. -- `EVYDENCE_PRINT_BOOTSTRAP_SECRET`: set to `true` only for local development to print the bootstrap API key secret. The API rejects this setting when `ENV=production`. -- `EVYDENCE_WORKER_POLL_INTERVAL`: worker outbox polling interval, default `1s`. -- `EVYDENCE_SIGNING_KEY_MODE`: production currently requires `external`; local plaintext signing keys are development-only. - -Do not commit real `.env`, `.api.env`, or `.test.env` files. - -## Local Dependencies - -```sh -make compose-up -make compose-down -``` - -The current API can run without these dependencies because it uses an in-process store. PostgreSQL and MinIO are included for the persistence/object-storage implementation slice. - -Run with durable PostgreSQL state: - -```sh -make compose-up -set -a; . ./.api.env; set +a -make migrate -EVYDENCE_PRINT_BOOTSTRAP_SECRET=true go run ./cmd/evydence-api -``` - -Run the worker in a separate shell with the same database environment: - -```sh -set -a; . ./.api.env; set +a -go run ./cmd/evydence-worker -``` - -The current API performs the implemented parsing/signing/verification work synchronously before enqueueing observability jobs. The worker validates that expected parsed, signed, or verified durable state exists for configured job kinds and fails safely on missing state, missing signatures, hash mismatch, or unsupported jobs. - -The API can use filesystem or S3/MinIO-compatible object storage. Object keys are generated by the application under `tenants//...`; do not grant collectors direct bucket write access. - -Example MinIO configuration with Docker Compose: - -```sh -EVYDENCE_OBJECT_STORE=minio -EVYDENCE_S3_ENDPOINT=localhost:9000 -EVYDENCE_S3_BUCKET=evydence -EVYDENCE_S3_ACCESS_KEY_ID=minioadmin -EVYDENCE_S3_SECRET_ACCESS_KEY=minioadmin -EVYDENCE_S3_USE_SSL=false -``` - -## GitHub Actions Provenance Upload - -Create a `github_actions` collector with `POST /v1/collectors`, store the one-time returned secret in GitHub Actions secrets, and use the CLI from a workflow step: - -```sh -go run ./cmd/evydence github-actions upload-build \ - --url "$EVYDENCE_API_URL" \ - --api-key "$EVYDENCE_API_KEY" \ - --project-id "$EVYDENCE_PROJECT_ID" \ - --release-id "$EVYDENCE_RELEASE_ID" \ - --artifact-id "$EVYDENCE_ARTIFACT_ID" \ - --artifact-digest "$EVYDENCE_ARTIFACT_DIGEST" \ - --attestation-path provenance.dsse.json -``` - -The command reads `GITHUB_REPOSITORY`, `GITHUB_WORKFLOW_REF`, `GITHUB_RUN_ID`, `GITHUB_RUN_ATTEMPT`, `GITHUB_JOB`, `GITHUB_ACTOR`, `GITHUB_REF`, and `GITHUB_SHA` from the Actions environment. `EVYDENCE_GITHUB_OIDC_SUBJECT` or `--oidc-subject` can capture an OIDC subject string when a workflow already has it, but this slice does not request or verify GitHub OIDC tokens. - -End-to-end workflow examples are stored in `docs/github-actions/release-evidence-workflow.yml` and `docs/gitlab/evydence-release-evidence.gitlab-ci.yml`. - -## CLI Uploads - -Use `evydence upload manifest` for bulk upload manifests that contain explicit `/v1` paths, idempotency keys, and JSON payloads or local payload files. Use `evydence import-bundle upload` for air-gapped evidence bundle imports. - -Use `evydence release manifest`, `evydence release sign`, and `evydence release verify` to create and verify release artifact manifests before publishing binaries, images, or collector artifacts. +| Task | Canonical Doc | Expected Outcome | +|------|---------------|------------------| +| Choose local or durable runtime mode | [Install and operate](how-to/install-and-operate.md) | API and worker run with either in-process state or PostgreSQL-backed state. | +| Configure environment variables | [Configuration](reference/configuration.md) | Runtime variables are set from local untracked files or deployment secrets. | +| Run release validation | [Release validation](reference/release-validation.md) | `tmp/release-check-summary.txt` records pass and explicit skip lines. | +| Operate outbox workers | [Worker outbox contract](reference/worker-outbox.md) | Workers claim persisted jobs and fail safely on missing state, hash mismatch, or unsupported jobs. | +| Integrate CI evidence | [Integrate CI collectors](how-to/integrate-ci.md) | CI jobs upload build, attestation, source snapshot, or collector evidence with scoped secrets. | +| Deploy on Kubernetes | [Kubernetes deployment](kubernetes.md) | API and worker deploy with external PostgreSQL, object storage, and external signing mode. | +| Build an offline package | [Air-gapped installation](air-gapped.md) | Package manifests and signatures are verified before import. | +| Review production hardening | [Production hardening review](production-hardening.md) | Unsafe defaults, backup gaps, diagnostics exposure, and customer package handling are reviewed. | ## Integrity Operations -Use `GET /v1/ready` for low-detail readiness checks. Use `GET /v1/metrics` only with an admin API key; it returns safe tenant resource counts, not raw evidence payloads or secrets. - -Use `POST /v1/backup-manifests` after database and object-store backups complete to record a hash and consistency checks for the ledger state. The manifest is not a backup by itself and intentionally excludes raw payload bytes and private signing-key material. - -Use `GET /v1/admin/instance` only with an actor explicitly granted `instance:admin` for low-detail tenant/resource counts. Tenant `admin` and ordinary wildcard `*` tenant keys do not satisfy this instance-wide scope unless `instance:admin` is also present. Do not expose this endpoint to customer verifier roles. - -Legal holds and retention overrides are ledger records. They help explain why evidence should be retained, but they do not configure external database backups, S3 lifecycle rules, or object-lock policies. - -Customer portal access tokens are returned once by `POST /v1/customer-portal/access`, expire, and are stored as hashes. Treat them like bearer secrets and do not place them in logs or long-lived documentation. Failed token attempts that match a known active token prefix increment safe counters and record audit-chain signals without storing the token value. After repeated failed attempts, the access record is revoked. `GET /v1/metrics` includes tenant-safe `customer_portal_failed_access_count` and `customer_portal_revoked_access_count`; deployments should still use reverse-proxy or API-gateway throttling for the unauthenticated portal endpoint. - -Human SSO sessions enforce the resource constraints recorded on role bindings. Tenant-wide bindings use `resource_type=tenant` or an empty resource scope; product, project, release, customer package, and evidence bundle bindings only authorize matching resource operations. API keys and collector API keys continue to rely on explicit scopes. Current SSO endpoints are admin-managed provider, identity-link, and session records; production OIDC/SAML login callbacks, token/assertion verification, group synchronization, and browser session handling are not implemented yet. - -Use `POST /v1/merkle-batches` and `POST /v1/transparency-checkpoints` to record signed local checkpoints and optional external anchoring metadata. These support tamper-evidence but do not make public transparency mandatory. - -Object-retention policy APIs record and verify retention intent for tenant-prefixed object paths. Enforcing WORM/object-lock settings remains the responsibility of the configured object store and deployment policy. +- Use `GET /v1/ready` for low-detail readiness checks. +- Use `GET /v1/metrics` only with an admin API key; it returns safe tenant resource counts, not raw evidence payloads or secrets. +- Use `GET /v1/admin/instance` only with an actor explicitly granted `instance:admin`. Tenant admin and ordinary wildcard tenant keys do not satisfy this instance-wide scope by themselves. +- Use `POST /v1/backup-manifests` after database and object-store backups complete. The manifest intentionally excludes raw payload bytes and private signing-key material. +- Use `POST /v1/merkle-batches` and `POST /v1/transparency-checkpoints` to record signed local checkpoints and optional external anchoring metadata. -## Production Caveat +## Token And Trust Boundaries -The API refuses `ENV=production` unless PostgreSQL is configured, a non-default API key pepper is set, and local plaintext signing-key mode is disabled. Signing-provider records are available, but production deployments should use an external signing mode and avoid storing private key material in the ledger snapshot. +- API keys, collector keys, SSO session tokens, and customer portal access tokens are bearer secrets. Do not place them in logs, documentation, long-lived build output, or customer packages. +- Customer portal access tokens are returned once by `POST /v1/customer-portal/access`, expire, and are stored as hashes. Deployments should still use reverse-proxy or API-gateway throttling for the unauthenticated portal endpoint. +- Human SSO session records are admin-managed. Current endpoints do not implement production OIDC/SAML login callbacks, token/assertion verification, group synchronization, or browser session handling. +- Object-retention APIs record and verify retention intent for tenant-prefixed object paths. Enforcing WORM or object-lock settings remains the responsibility of the configured object store and deployment policy. -Before release labeling, run `make release-check`. It includes `make finalize`, lint, gosec, govulncheck, race tests, and live PostgreSQL checks when `EVYDENCE_TEST_DATABASE_URL` is set. The target writes `tmp/release-check-summary.txt` with passed checks and explicit skip lines for live PostgreSQL coverage when the environment variable is unset. Use the release validation reference for the configured Postgres profile and the exact summary evidence to retain. +Evydence operations support evidence organization, review, and tamper-evident records. Operational checks do not replace external audit review, secret management, backup testing, or provider verification. diff --git a/docs/production-hardening.md b/docs/production-hardening.md index 9ee1167..bcb05e8 100644 --- a/docs/production-hardening.md +++ b/docs/production-hardening.md @@ -2,17 +2,68 @@ This is an explanation and operator checklist for production-readiness review. -Required before labeling a deployment production: +## Configuration Gate + +Before labeling a deployment production, verify: + +- `ENV=production` is set. +- `EVYDENCE_DATABASE_URL` points to external PostgreSQL. +- `EVYDENCE_API_KEY_PEPPER` is a non-default random value. +- `EVYDENCE_SIGNING_KEY_MODE=external` is set. +- `EVYDENCE_PRINT_BOOTSTRAP_SECRET` is unset or false. + +These checks are enforced by API startup. See [Configuration](reference/configuration.md). + +## Deployment Checklist - PostgreSQL is external, backed up, monitored, and restored in a test environment. - Object storage is external S3/MinIO-compatible storage with tenant-prefixed paths, encryption, lifecycle policy, and retention/object-lock policy where required. -- `ENV=production`, `EVYDENCE_DATABASE_URL`, non-default `EVYDENCE_API_KEY_PEPPER`, and `EVYDENCE_SIGNING_KEY_MODE=external` are set. -- API keys are scoped, rotated, and stored outside source control. - Ingress terminates TLS and does not expose internal diagnostics. -- `/v1/metrics` and `/v1/audit-log` require admin API keys and are not public. -- Backups include PostgreSQL, object storage, OpenAPI/migration version, and release artifact manifests. -- Restore tests verify database/object consistency and audit-chain verification after restore. -- Collector releases are pinned and have signature, SBOM, and vulnerability scan evidence when available. +- `/v1/metrics`, `/v1/audit-log`, and `/v1/admin/instance` are protected by server-side scopes and are not public. +- API keys and collector keys are scoped, rotated, and stored outside source control. +- Customer portal access tokens are short-lived, scoped to one package, and handled as bearer secrets. - Generated customer packages use explicit redaction profiles and expiry. +- Collector releases are pinned and have signature, SBOM, and vulnerability scan evidence when available. + +## Backup And Restore Checklist + +- Backups include PostgreSQL and object storage from the same recovery point. +- Backup evidence records the OpenAPI version, migration version, release artifact manifest, and chart or deployment version. +- Restore tests verify database/object consistency after restore. +- Audit-chain verification and release-bundle verification are run after restore. +- `POST /v1/backup-manifests` is recorded after the database and object-store backups complete. + +Backup manifests help compare recorded ledger state. They intentionally exclude raw payload bytes and private signing-key material, so they cannot replace matched database and object-store backups. + +## Deployment Verification + +Compose: + +```sh +make compose-up +set -a; . ./.test.env; set +a +make live-postgres-check +make postgres-integration-test +``` + +Expected result: live PostgreSQL migration and integration checks pass, or the targets print explicit skip lines when `EVYDENCE_TEST_DATABASE_URL` is unset. + +Helm: + +```sh +helm upgrade --install evydence ./deploy/helm/evydence --dry-run +kubectl rollout status deploy/evydence-api +kubectl rollout status deploy/evydence-worker +``` + +Expected result: rendered manifests reference the configured secret and object store, and both deployments roll out. + +Air-gapped packages: + +```sh +evydence release verify --manifest evydence-release-manifest.json --signature evydence-release-manifest.sig.json +``` + +Expected result: manifest signature and referenced artifact hashes verify before import. -This checklist supports deployment hardening and evidence organization. It is not a certification, legal compliance determination, or secure-release conclusion. +This checklist supports deployment hardening and evidence organization. It is not a certification, legal compliance determination, or release-security guarantee. diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md new file mode 100644 index 0000000..47faf65 --- /dev/null +++ b/docs/reference/configuration.md @@ -0,0 +1,62 @@ +# Configuration Reference + +This is the canonical reference for current environment files and runtime variables. + +## Environment Files + +| File | Used By | Purpose | Commit Real Values? | +|------|---------|---------|---------------------| +| `.env.example` | `docker-compose.yml` | Local PostgreSQL and MinIO container credentials. | No | +| `.api.env.example` | API, worker, migration command | Local API runtime settings, durable database URL, object storage mode, bootstrap tenant, and local secret printing. | No | +| `.test.env.example` | Make targets for live PostgreSQL tests | `EVYDENCE_TEST_DATABASE_URL` and test-only API key pepper. | No | + +Copy examples to local untracked files when needed: + +```sh +cp .api.env.example .api.env +cp .test.env.example .test.env +``` + +The example secrets are placeholders. Replace them before using shared or production-like infrastructure. + +## Runtime Variables + +| Variable | Required | Default / Example | Notes | +|----------|----------|-------------------|-------| +| `ENV` | Production only | unset locally | Set `ENV=production` to enable production-safety checks. | +| `EVYDENCE_ADDR` | No | `:8080` | API bind address. | +| `EVYDENCE_API_KEY_PEPPER` | Production yes | `change-me-long-random-pepper` | HMAC pepper for API key, session, and portal-token hashes. Use a long random value. | +| `EVYDENCE_DATABASE_URL` | Production yes | `postgres://evydence:change-me@localhost:5432/evydence?sslmode=disable` | Enables PostgreSQL durable state, projections, migrations, and persisted outbox jobs. If unset, the API uses in-process state. | +| `EVYDENCE_OBJECT_STORE` | No | `filesystem` | Supported values are `filesystem`, `s3`, and `minio`. | +| `EVYDENCE_OBJECT_DIR` | Filesystem object store | `./tmp/objects` | Local raw payload storage root. | +| `EVYDENCE_S3_ENDPOINT` | S3/MinIO object store | `localhost:9000` | Endpoint for S3-compatible object storage. | +| `EVYDENCE_S3_BUCKET` | S3/MinIO object store | `evydence` | Bucket must already exist. | +| `EVYDENCE_S3_ACCESS_KEY_ID` | S3/MinIO object store | local example value | Store outside source control. | +| `EVYDENCE_S3_SECRET_ACCESS_KEY` | S3/MinIO object store | local example value | Store outside source control and logs. | +| `EVYDENCE_S3_REGION` | No | empty | Optional S3 region. | +| `EVYDENCE_S3_USE_SSL` | No | `false` locally, `true` in chart values | Use TLS for remote object storage. | +| `EVYDENCE_SKIP_MIGRATIONS` | No | unset | Set to `true` only when migrations are applied by a separate release process. | +| `EVYDENCE_MIGRATIONS_DIR` | No | `migrations` | Migration directory for API startup and `cmd/evydence-migrate`. | +| `EVYDENCE_BOOTSTRAP_TENANT` | No | `Local Tenant` | Tenant name used when bootstrapping an empty store. | +| `EVYDENCE_BOOTSTRAP_DISABLED` | No | unset | Set to `true` to prevent startup bootstrap on an empty store. | +| `EVYDENCE_PRINT_BOOTSTRAP_SECRET` | Local only | `true` in `.api.env.example` | Prints the one-time bootstrap secret. Rejected when `ENV=production`. | +| `EVYDENCE_WORKER_POLL_INTERVAL` | No | `1s` | Worker outbox polling interval. | +| `EVYDENCE_SIGNING_KEY_MODE` | Production yes | `external` for production | Production rejects local plaintext signing-key mode. | +| `EVYDENCE_TEST_DATABASE_URL` | Live tests | `.test.env.example` value | Used by `make live-postgres-check`, `make postgres-integration-test`, and `make release-check`. | + +## Production Rejection Checks + +When `ENV=production`, the API refuses to start unless: + +- `EVYDENCE_DATABASE_URL` is set. +- `EVYDENCE_API_KEY_PEPPER` is non-empty and not the local default. +- `EVYDENCE_SIGNING_KEY_MODE=external`. +- `EVYDENCE_PRINT_BOOTSTRAP_SECRET` is not `true`. + +These checks reduce unsafe runtime defaults. They do not replace secret management, network controls, backup validation, or external signing operations. + +## Related Commands + +- Local operation: [Install and operate](../how-to/install-and-operate.md) +- Release validation: [Release validation](release-validation.md) +- Kubernetes secret wiring: [Kubernetes deployment](../kubernetes.md) diff --git a/docs/reference/openapi.md b/docs/reference/openapi.md index d410310..f4f5e33 100644 --- a/docs/reference/openapi.md +++ b/docs/reference/openapi.md @@ -1,17 +1,50 @@ # OpenAPI Contract -The committed API contract is `openapi.yaml`. +The committed API contract is `openapi.yaml`. It is generated from the HTTP adapter route registry and route-contract metadata. -Generate it with: +## Generate And Check + +Generate the contract: ```sh go run ./cmd/openapi > openapi.yaml ``` -Check drift with: +Check drift: ```sh make openapi-check ``` -The API also serves the generated contract at `/v1/openapi.json`. Route registration and OpenAPI generation use the same HTTP adapter registry so tests can catch missing routes or stale operation metadata. +`make openapi-check` regenerates the contract, compares it with the committed file, and runs route contract tests for the HTTP adapter. + +## Review The Contract + +The committed file is compact. For human review, pretty-print it without editing the generated source: + +```sh +jq . openapi.yaml > /tmp/evydence-openapi.pretty.json +jq '.paths | keys[]' openapi.yaml +jq '.components.schemas | keys[]' openapi.yaml +``` + +Inspect one operation: + +```sh +jq '.paths["/v1/evidence"].post' openapi.yaml +``` + +The API also serves the generated contract at: + +```http +GET /v1/openapi.json +``` + +## Current Limitations + +- `openapi.yaml` is generated in a compact JSON-compatible representation. +- Critical routes such as evidence creation, evidence search, release bundle verification, SSO session creation, customer portal token exchange, and instance diagnostics have more precise request/response schemas. +- Many routes still use generic response envelopes while the human examples live in [API reference](../api.md) and HTTP tests. +- Do not hand-edit `openapi.yaml`; update route metadata or the generator, then run `make openapi-check`. + +Route registration and OpenAPI generation use the same HTTP adapter registry so tests can catch missing routes or stale operation metadata. diff --git a/docs/sdk/README.md b/docs/sdk/README.md index 3621f59..d502464 100644 --- a/docs/sdk/README.md +++ b/docs/sdk/README.md @@ -1,13 +1,96 @@ # SDK Workflow -This is a reference for the lightweight SDK layout. +This is a reference for the lightweight SDK wrappers committed in this repository. -The committed SDK examples are curated wrappers around the OpenAPI-backed HTTP API: +## Current Scope -- `sdk/go/evydence` -- `sdk/typescript/client.ts` -- `sdk/python/evydence_client.py` +The wrappers provide authenticated JSON `POST` helpers with explicit idempotency keys: -They intentionally keep a small surface: authenticated JSON `POST` requests with explicit idempotency keys. Broader generated clients should be regenerated from the committed `openapi.yaml` and reviewed before release. +- Go: `sdk/go/evydence` +- TypeScript: `sdk/typescript/client.ts` +- Python: `sdk/python/evydence_client.py` -SDK drift checks currently rely on `make openapi-check`, `go test ./...`, and documentation review. Generated SDK publishing is a release process, not an API runtime dependency. +They do not expose typed methods for every route. Broader generated clients should be regenerated from the committed `openapi.yaml`, reviewed, and released through a separate SDK publishing process. + +## Go + +```go +client := evydence.Client{ + BaseURL: "http://localhost:8080", + APIKey: os.Getenv("EVYDENCE_API_KEY"), +} + +var out map[string]any +err := client.Post( + context.Background(), + "/v1/products", + "product-payments-api", + map[string]any{"name": "Payments API", "slug": "payments-api"}, + &out, +) +if err != nil { + return err +} +``` + +The helper rejects paths that do not start with `/v1/` and blank idempotency keys. Non-2xx responses return an error containing the HTTP status code; callers that need Problem Details bodies should use a generated or custom client. + +## TypeScript + +```ts +const client = new EvydenceClient({ + baseUrl: "http://localhost:8080", + apiKey: process.env.EVYDENCE_API_KEY!, +}); + +const response = await client.post<{ data: { id: string } }>( + "/v1/products", + "product-payments-api", + { name: "Payments API", slug: "payments-api" }, +); +``` + +The helper validates `/v1/` paths and idempotency keys. Non-2xx responses throw an error with the HTTP status code. + +## Python + +```python +from evydence_client import EvydenceClient + +client = EvydenceClient( + base_url="http://localhost:8080", + api_key=os.environ["EVYDENCE_API_KEY"], +) + +response = client.post( + "/v1/products", + "product-payments-api", + {"name": "Payments API", "slug": "payments-api"}, +) +``` + +The helper validates `/v1/` paths and idempotency keys. HTTP errors raise `RuntimeError` with the status code. + +## Idempotency Guidance + +Use stable, operation-specific idempotency keys for create and action requests: + +```text +product-payments-api +release-payments-api-1.0.0 +build-github-123456-1 +``` + +Reusing the same key with the same request returns the original response. Reusing the key with different request content returns `409`. + +## Drift Checks + +SDK drift checks currently rely on: + +```sh +make openapi-check +make test +make sdk-check +``` + +Generated SDK publishing is not an API runtime dependency. Keep generated clients tied to the committed `openapi.yaml` and document any route coverage gaps at release time. diff --git a/docs/tutorials/getting-started.md b/docs/tutorials/getting-started.md index 7a871c9..30bb262 100644 --- a/docs/tutorials/getting-started.md +++ b/docs/tutorials/getting-started.md @@ -1,37 +1,215 @@ # Getting Started -This tutorial runs the API locally and records a minimal release ledger flow. +This tutorial runs Evydence with in-process state and records a small release evidence flow. It is for local development only; data is lost when the process exits. ## Prerequisites - Go with the version declared by `go.mod`. -- Docker if you want PostgreSQL and object storage. +- `curl` and `jq`. +- A free local port matching `EVYDENCE_ADDR` from `.api.env.example`, default `:8080`. -## Start Local Dependencies +## Start The API + +In terminal 1: ```sh -make compose-up -set -a; . ./.test.env; set +a -make live-postgres-check +cp .api.env.example .api.env +unset EVYDENCE_DATABASE_URL +set -a; . ./.api.env; set +a +EVYDENCE_PRINT_BOOTSTRAP_SECRET=true go run ./cmd/evydence-api ``` -For an in-process demo, leave `EVYDENCE_DATABASE_URL` unset. +Expected result: -## Start The API +- The process prints a one-time JSON object containing `tenant_id`, `api_key`, and `secret`. +- The API listens on `http://localhost:8080` unless `EVYDENCE_ADDR` says otherwise. +- Because `EVYDENCE_DATABASE_URL` is unset, the tutorial uses in-process state. + +In terminal 2, store the printed secret: ```sh -cp .api.env.example .api.env -set -a; . ./.api.env; set +a -EVYDENCE_PRINT_BOOTSTRAP_SECRET=true go run ./cmd/evydence-api +export EVYDENCE_URL=http://localhost:8080 +export EVYDENCE_API_KEY='evy_replace_with_printed_secret' +``` + +Verify the process is reachable: + +```sh +curl -sS "$EVYDENCE_URL/v1/ready" | jq . ``` -Use the printed one-time bootstrap secret as a bearer token. Create and action requests require `Idempotency-Key`. +Expected status is `200` with `data.status` set to `ok`. -## Validate +## Create Core Release Records + +Create a product: ```sh -make test -make openapi-check +curl -sS -X POST "$EVYDENCE_URL/v1/products" \ + -H "Authorization: Bearer $EVYDENCE_API_KEY" \ + -H "Idempotency-Key: tutorial-product" \ + -H "Content-Type: application/json" \ + --data '{"name":"Payments API","slug":"payments-api"}' \ + | tee /tmp/evydence-product.json | jq . + +export PRODUCT_ID=$(jq -r '.data.id' /tmp/evydence-product.json) ``` -The local flow organizes technical evidence and reports gaps, assumptions, and limitations. It does not make legal compliance or secure-release conclusions. +Expected status is `201`. Reusing `tutorial-product` with the same body returns the original response; reusing it with different JSON returns `409`. + +Create a project and release: + +```sh +curl -sS -X POST "$EVYDENCE_URL/v1/projects" \ + -H "Authorization: Bearer $EVYDENCE_API_KEY" \ + -H "Idempotency-Key: tutorial-project" \ + -H "Content-Type: application/json" \ + --data "{\"product_id\":\"$PRODUCT_ID\",\"name\":\"api\"}" \ + | tee /tmp/evydence-project.json | jq . + +export PROJECT_ID=$(jq -r '.data.id' /tmp/evydence-project.json) + +curl -sS -X POST "$EVYDENCE_URL/v1/releases" \ + -H "Authorization: Bearer $EVYDENCE_API_KEY" \ + -H "Idempotency-Key: tutorial-release" \ + -H "Content-Type: application/json" \ + --data "{\"product_id\":\"$PRODUCT_ID\",\"version\":\"1.0.0\"}" \ + | tee /tmp/evydence-release.json | jq . + +export RELEASE_ID=$(jq -r '.data.id' /tmp/evydence-release.json) +``` + +Both creates should return `201`. + +## Upload Representative Evidence + +Register an artifact: + +```sh +export ARTIFACT_DIGEST=sha256:ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb + +curl -sS -X POST "$EVYDENCE_URL/v1/artifacts" \ + -H "Authorization: Bearer $EVYDENCE_API_KEY" \ + -H "Idempotency-Key: tutorial-artifact" \ + -H "Content-Type: application/json" \ + --data "{\"name\":\"api.tar.gz\",\"media_type\":\"application/gzip\",\"digest\":\"$ARTIFACT_DIGEST\",\"size\":42}" \ + | tee /tmp/evydence-artifact.json | jq . + +export ARTIFACT_ID=$(jq -r '.data.id' /tmp/evydence-artifact.json) +``` + +Upload a CycloneDX SBOM: + +```sh +curl -sS -X POST "$EVYDENCE_URL/v1/sboms" \ + -H "Authorization: Bearer $EVYDENCE_API_KEY" \ + -H "Idempotency-Key: tutorial-sbom" \ + -H "Content-Type: application/json" \ + --data "{ + \"release_id\":\"$RELEASE_ID\", + \"artifact_id\":\"$ARTIFACT_ID\", + \"payload\":{ + \"bomFormat\":\"CycloneDX\", + \"specVersion\":\"1.6\", + \"components\":[{\"name\":\"openssl\",\"purl\":\"pkg:apk/openssl@3.1.0\"}] + } + }" | jq . +``` + +Upload a vulnerability scan with one open critical finding: + +```sh +curl -sS -X POST "$EVYDENCE_URL/v1/vulnerability-scans" \ + -H "Authorization: Bearer $EVYDENCE_API_KEY" \ + -H "Idempotency-Key: tutorial-vuln-scan" \ + -H "Content-Type: application/json" \ + --data "{ + \"scanner\":\"grype\", + \"target_ref\":\"pkg:oci/payments-api\", + \"release_id\":\"$RELEASE_ID\", + \"findings\":[{ + \"vulnerability\":\"CVE-2026-0099\", + \"component\":\"pkg:apk/openssl@3.1.0\", + \"severity\":\"critical\", + \"state\":\"open\" + }] + }" | tee /tmp/evydence-scan.json | jq . + +export FINDING_ID=$(jq -r '.data.findings[0].id' /tmp/evydence-scan.json) +``` + +Expected status is `201`. The scan organizes scanner evidence; it does not make the scanner authoritative. + +Record a generic build evidence item: + +```sh +curl -sS -X POST "$EVYDENCE_URL/v1/evidence" \ + -H "Authorization: Bearer $EVYDENCE_API_KEY" \ + -H "Idempotency-Key: tutorial-build-evidence" \ + -H "Content-Type: application/json" \ + --data "{ + \"product_id\":\"$PRODUCT_ID\", + \"project_id\":\"$PROJECT_ID\", + \"release_id\":\"$RELEASE_ID\", + \"type\":\"build\", + \"subtype\":\"log\", + \"title\":\"Local tutorial build evidence\", + \"payload_hash\":\"$ARTIFACT_DIGEST\", + \"tags\":[\"tutorial\"], + \"limitations\":[\"Local tutorial evidence is representative only.\"] + }" | jq . +``` + +Expected status is `201`. + +## Readiness And Review Output + +Create a release bundle: + +```sh +curl -sS -X POST "$EVYDENCE_URL/v1/release-bundles" \ + -H "Authorization: Bearer $EVYDENCE_API_KEY" \ + -H "Idempotency-Key: tutorial-release-bundle" \ + -H "Content-Type: application/json" \ + --data "{\"release_id\":\"$RELEASE_ID\"}" \ + | tee /tmp/evydence-bundle.json | jq . +``` + +Read release readiness: + +```sh +curl -sS "$EVYDENCE_URL/v1/reports/release-readiness?release_id=$RELEASE_ID" \ + -H "Authorization: Bearer $EVYDENCE_API_KEY" \ + | jq . +``` + +Expected status is `200`. In this minimal flow, `data.result` is expected to be `failed` because the release is missing some readiness inputs and has an unhandled open critical finding. The report should include checks, gaps, assumptions, limitations, and blocking findings. + +Record a decision for the tutorial finding: + +```sh +curl -sS -X POST "$EVYDENCE_URL/v1/vulnerability-findings/$FINDING_ID/decisions" \ + -H "Authorization: Bearer $EVYDENCE_API_KEY" \ + -H "Idempotency-Key: tutorial-vuln-decision" \ + -H "Content-Type: application/json" \ + --data '{"status":"not_affected","justification":"tutorial example; vulnerable code path is not present"}' \ + | jq . +``` + +Expected status is `201`. Readiness may still report gaps until build provenance, attestation, signed bundle, and other required evidence are present. + +Search the tutorial evidence: + +```sh +curl -sS "$EVYDENCE_URL/v1/evidence/search?release_id=$RELEASE_ID&type=build&tag=tutorial&limit=10" \ + -H "Authorization: Bearer $EVYDENCE_API_KEY" \ + | jq . +``` + +Expected status is `200` with the build evidence item under `data.items`. + +## Cleanup + +Stop the API process with `Ctrl-C`. For a durable local run, use PostgreSQL and object storage through [Install and operate](../how-to/install-and-operate.md) and [Configuration](../reference/configuration.md). + +This tutorial demonstrates evidence capture and review output. It does not make legal compliance conclusions, grant certification, prove SBOM completeness, treat scanner output as authoritative, or guarantee release security. From f841d83de5bda15009e5328d984388ea8b81bb01 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sat, 23 May 2026 11:30:33 +0300 Subject: [PATCH 010/287] docs: clarify release CLI paths --- docs/air-gapped.md | 12 +++++++----- docs/release-signing.md | 16 ++++++++++++---- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/docs/air-gapped.md b/docs/air-gapped.md index 5946735..c6f7259 100644 --- a/docs/air-gapped.md +++ b/docs/air-gapped.md @@ -11,9 +11,9 @@ go build -o dist/evydence-api ./cmd/evydence-api go build -o dist/evydence-worker ./cmd/evydence-worker go build -o dist/evydence ./cmd/evydence cp -R migrations openapi.yaml deploy/helm/evydence docs/air-gapped.md dist/ -evydence release manifest --out dist/evydence-release-manifest.json dist/evydence-api dist/evydence-worker dist/evydence -evydence release keygen --private-out dist/release-private.key --public-out dist/release-public.key -evydence release sign --manifest dist/evydence-release-manifest.json --private-key dist/release-private.key --out dist/evydence-release-manifest.sig.json +./dist/evydence release manifest --out dist/evydence-release-manifest.json dist/evydence-api dist/evydence-worker dist/evydence +./dist/evydence release keygen --private-out dist/release-private.key --public-out dist/release-public.key +./dist/evydence release sign --manifest dist/evydence-release-manifest.json --private-key dist/release-private.key --out dist/evydence-release-manifest.sig.json ``` Expected package contents include: @@ -39,8 +39,10 @@ Record transfer approvals, media handling, and hash verification as separate ope ## Verify Offline +Run the verifier from the transferred package directory. Use `./evydence` for the packaged binary unless your operating procedure installs the same binary as `evydence` on `PATH`. + ```sh -evydence release verify --manifest evydence-release-manifest.json --signature evydence-release-manifest.sig.json +./evydence release verify --manifest evydence-release-manifest.json --signature evydence-release-manifest.sig.json ``` Expected result: the command exits successfully and reports that the manifest signature and referenced artifact hashes verify. @@ -50,7 +52,7 @@ Expected result: the command exits successfully and reports that the manifest si For CI systems that cannot call the API, write an evidence bundle in CI, move it through the same controlled transfer process, then upload it from the connected side: ```sh -evydence import-bundle upload \ +./evydence import-bundle upload \ --url "$EVYDENCE_API_URL" \ --api-key "$EVYDENCE_API_KEY" \ --path evidence-bundle.json diff --git a/docs/release-signing.md b/docs/release-signing.md index 0e0c689..7cc6247 100644 --- a/docs/release-signing.md +++ b/docs/release-signing.md @@ -2,23 +2,31 @@ This is an operator how-to for Evydence release artifacts. +The examples below use `./dist/evydence`, the CLI binary built from this checkout: + +```sh +go build -o dist/evydence ./cmd/evydence +``` + +If your release environment installs the same binary on `PATH`, replace `./dist/evydence` with `evydence`. + Create a release artifact manifest: ```sh -evydence release manifest --out evydence-release-manifest.json dist/evydence-api dist/evydence-worker dist/evydence +./dist/evydence release manifest --out evydence-release-manifest.json dist/evydence-api dist/evydence-worker dist/evydence ``` Generate a local Ed25519 keypair for development signing: ```sh -evydence release keygen --private-out release-private.key --public-out release-public.key +./dist/evydence release keygen --private-out release-private.key --public-out release-public.key ``` Sign and verify: ```sh -evydence release sign --manifest evydence-release-manifest.json --private-key release-private.key --out evydence-release-manifest.sig.json -evydence release verify --manifest evydence-release-manifest.json --signature evydence-release-manifest.sig.json +./dist/evydence release sign --manifest evydence-release-manifest.json --private-key release-private.key --out evydence-release-manifest.sig.json +./dist/evydence release verify --manifest evydence-release-manifest.json --signature evydence-release-manifest.sig.json ``` Production release signing should use controlled key custody and publish the manifest, signature, public key, and image digest references together. Verification proves that the manifest and listed artifact bytes match the signature; it does not prove that a deployment is secure. From 13814918d76d5c63858f811ec6d59dd4d541370d Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sat, 23 May 2026 11:31:45 +0300 Subject: [PATCH 011/287] docs: repair GitLab evidence upload example --- .../evydence-release-evidence.gitlab-ci.yml | 36 +++++++++++++++++++ docs/how-to/integrate-ci.md | 3 +- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/docs/gitlab/evydence-release-evidence.gitlab-ci.yml b/docs/gitlab/evydence-release-evidence.gitlab-ci.yml index a9937c2..c0d942b 100644 --- a/docs/gitlab/evydence-release-evidence.gitlab-ci.yml +++ b/docs/gitlab/evydence-release-evidence.gitlab-ci.yml @@ -19,6 +19,42 @@ evydence:evidence: dependencies: - build script: + - export EVYDENCE_ARTIFACT_DIGEST="$(cat artifact.digest)" + - | + cat > evydence-upload-manifest.json < Date: Sat, 23 May 2026 11:32:50 +0300 Subject: [PATCH 012/287] docs: synchronize API endpoint catalog --- docs/api.md | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/docs/api.md b/docs/api.md index 0c0c8f5..bda4191 100644 --- a/docs/api.md +++ b/docs/api.md @@ -2,7 +2,7 @@ The public API base path is `/v1`. The generated contract is committed at [`../openapi.yaml`](../openapi.yaml) and served by the API at `/v1/openapi.json`. -Use this page for common integration workflows and route lookup. Use `openapi.yaml` as the generated contract source. +Use this page for common integration workflows and route lookup. The endpoint catalog is expected to list every path in `openapi.yaml`; the generated contract remains the source of truth for operation details, schemas, status codes, security metadata, and route drift checks. ## Request Contract @@ -271,12 +271,21 @@ Current SSO endpoints model admin-managed provider, identity-link, and session r | `GET` | `/v1/evidence/{id}/lifecycle-events` | Read lifecycle timeline. | | `POST` | `/v1/sboms` | Upload CycloneDX SBOM. | | `POST` | `/v1/sboms/spdx` | Upload SPDX SBOM. | +| `GET` | `/v1/sboms/{id}` | Read SBOM metadata. | | `POST` | `/v1/sbom-diffs` | Compare stored SBOMs. | | `POST` | `/v1/vulnerability-scans` | Upload normalized vulnerability scan. | +| `GET` | `/v1/vulnerability-scans/{id}` | Read vulnerability scan metadata. | | `POST` | `/v1/vulnerability-findings/{id}/decisions` | Superseding decision record. | | `POST` | `/v1/vulnerability-findings/{id}/workflow` | Append workflow event. | | `GET` | `/v1/reports/vulnerability-posture` | Summarize findings for a release. | | `GET` | `/v1/reports/release-readiness` | Deterministic readiness report. | +| `GET` | `/v1/reports/missing-evidence` | Missing evidence report for review. | +| `POST` | `/v1/release-candidates` | Create release candidate. | +| `GET` | `/v1/release-candidates` | List release candidates. | +| `GET` | `/v1/release-candidates/{id}` | Read release candidate. | +| `POST` | `/v1/release-candidates/{id}/promote` | Promote release candidate. | +| `POST` | `/v1/release-candidates/{id}/reject` | Reject release candidate. | +| `POST` | `/v1/remediation-tasks` | Create remediation task. | ### CI, Source, Deployment, And Collectors @@ -286,10 +295,13 @@ Current SSO endpoints model admin-managed provider, identity-link, and session r | `GET` | `/v1/collectors` | List collectors without secrets. | | `POST` | `/v1/collectors/{id}/releases` | Record collector release evidence. | | `GET` | `/v1/collectors/{id}/health` | Collector health report. | +| `POST` | `/v1/commercial-collectors` | Create commercial collector definition. | +| `GET` | `/v1/commercial-collectors` | List commercial collector definitions. | | `POST` | `/v1/builds` | Record immutable build run. | | `GET` | `/v1/builds/{id}` | Read build run. | | `POST` | `/v1/builds/{id}/attestations` | Upload DSSE in-toto attestation JSON. | | `POST` | `/v1/build-attestations/{id}/verify-signature` | Verify against configured DSSE trust roots. | +| `POST` | `/v1/dsse-trust-roots` | Create DSSE trust root. | | `POST` | `/v1/source/repositories` | Record source repository. | | `GET` | `/v1/source/repositories` | List repositories. | | `POST` | `/v1/source/commits` | Record source commit. | @@ -302,6 +314,7 @@ Current SSO endpoints model admin-managed provider, identity-link, and session r | `POST` | `/v1/deployments` | Record deployment event. | | `GET` | `/v1/deployments` | List deployments. | | `GET` | `/v1/deployments/{id}` | Read deployment event. | +| `POST` | `/v1/container-images` | Register container image metadata. | Source snapshots capture submitted provider metadata. They do not call provider APIs or verify OIDC tokens. @@ -334,8 +347,11 @@ Source snapshots capture submitted provider metadata. They do not call provider | `POST` | `/v1/questionnaire-packages` | Generate evidence-backed responses. | | `GET` | `/v1/reports/security-review-package` | Redaction-aware package report. | | `GET` | `/v1/reports/cra-readiness-html` | HTML CRA-readiness review content. | +| `GET` | `/v1/reports/incident-package` | Incident package report. | | `POST` | `/v1/report-templates` | Create allowed-field template. | | `POST` | `/v1/report-templates/{id}/render` | Render deterministic JSON report. | +| `POST` | `/v1/incidents` | Create incident. | +| `POST` | `/v1/incidents/{id}/timeline` | Append incident timeline event. | ### Integrity, Verification, And Operations @@ -345,6 +361,8 @@ Source snapshots capture submitted provider metadata. They do not call provider | `GET` | `/v1/release-bundles/{id}` | Read bundle metadata. | | `GET` | `/v1/release-bundles/{id}/manifest` | Read bundle manifest. | | `GET` | `/v1/release-bundles/{id}/verify` | Verify bundle. | +| `POST` | `/v1/evidence-bundles` | Export evidence bundle. | +| `POST` | `/v1/evidence-bundles/import` | Import evidence bundle. | | `POST` | `/v1/verify` | Verify supported subject types. | | `GET` | `/v1/audit-chain/verify` | Verify tenant audit chain. | | `GET` | `/v1/audit-log` | List tenant audit entries; admin scope required. | @@ -352,6 +370,9 @@ Source snapshots capture submitted provider metadata. They do not call provider | `POST` | `/v1/signing-keys/rotate` | Rotate signing key. | | `POST` | `/v1/signing-keys/{id}/revoke` | Revoke key for new signatures. | | `POST` | `/v1/signing-providers` | Record external signing-provider metadata. | +| `POST` | `/v1/artifact-signatures` | Create artifact signature metadata. | +| `GET` | `/v1/artifact-signatures/{id}` | Read artifact signature. | +| `POST` | `/v1/artifact-signatures/{id}/verify-cosign` | Verify cosign-style artifact signature. | | `POST` | `/v1/merkle-batches` | Create signed checkpoint batch. | | `GET` | `/v1/merkle-batches/{id}/verify` | Verify batch. | | `POST` | `/v1/transparency-checkpoints` | Record external anchoring metadata. | From 8491f2c77d1f914b019d77315278ec1e8919ac71 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sat, 23 May 2026 11:33:44 +0300 Subject: [PATCH 013/287] docs: guard API catalog drift --- Makefile | 1 + docs/reference/openapi.md | 2 ++ 2 files changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 4264a54..0715f29 100644 --- a/Makefile +++ b/Makefile @@ -95,6 +95,7 @@ docs-check: ## Validate canonical docs exist and avoid forbidden product claims "explanation/trust-model.md"; do \ grep -F "$$path" docs/README.md >/dev/null || { echo "docs/README.md missing link to $$path"; exit 1; }; \ done + @python3 -c 'import json,re,sys; from pathlib import Path; spec=json.loads(Path("openapi.yaml").read_text()); doc=Path("docs/api.md").read_text(); openapi=set(spec["paths"]); catalog=set(re.findall(r"`(/v1/[^`]+)`", doc)); missing=sorted(openapi-catalog); extra=sorted(catalog-openapi); [print("docs/api.md missing OpenAPI path: "+p) for p in missing]; [print("docs/api.md lists non-OpenAPI path: "+p) for p in extra]; sys.exit(1 if missing or extra else 0)' @! grep -R -i "automatically compliant\|certified secure\|legally sufficient\|SBOM is complete\|all vulnerabilities detected\|scanner findings are authoritative\|regulator-ready without review" README.md docs deploy-check: ## Validate deployment and air-gap skeletons exist diff --git a/docs/reference/openapi.md b/docs/reference/openapi.md index f4f5e33..6457366 100644 --- a/docs/reference/openapi.md +++ b/docs/reference/openapi.md @@ -18,6 +18,8 @@ make openapi-check `make openapi-check` regenerates the contract, compares it with the committed file, and runs route contract tests for the HTTP adapter. +`make docs-check` compares the paths in `openapi.yaml` with the endpoint catalog in [API reference](../api.md). Add every generated path to that catalog, or the docs check fails. + ## Review The Contract The committed file is compact. For human review, pretty-print it without editing the generated source: From 8a7b6f4bd18a1f42df67098eecb59500ffefd2af Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sat, 23 May 2026 11:34:18 +0300 Subject: [PATCH 014/287] docs: add SDK setup context --- docs/sdk/README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/docs/sdk/README.md b/docs/sdk/README.md index d502464..6da5a62 100644 --- a/docs/sdk/README.md +++ b/docs/sdk/README.md @@ -12,9 +12,23 @@ The wrappers provide authenticated JSON `POST` helpers with explicit idempotency They do not expose typed methods for every route. Broader generated clients should be regenerated from the committed `openapi.yaml`, reviewed, and released through a separate SDK publishing process. +No package publishing manifests are committed for these wrappers yet. Use them as in-repository examples or copy them into an application-owned SDK package until a release process publishes versioned SDK artifacts. + ## Go +Import the wrapper from this module path when your code is in this repository or uses a local `replace` to this checkout: + ```go +package main + +import ( + "context" + "os" + + "github.com/aatuh/evydence/sdk/go/evydence" +) + +func createProduct() error { client := evydence.Client{ BaseURL: "http://localhost:8080", APIKey: os.Getenv("EVYDENCE_API_KEY"), @@ -31,13 +45,19 @@ err := client.Post( if err != nil { return err } +return nil +} ``` The helper rejects paths that do not start with `/v1/` and blank idempotency keys. Non-2xx responses return an error containing the HTTP status code; callers that need Problem Details bodies should use a generated or custom client. ## TypeScript +Import the source wrapper directly from the checkout or from your application-owned package copy. The wrapper uses `fetch`; Node.js 18+ provides it globally, and older runtimes should pass `fetchImpl`. + ```ts +import { EvydenceClient } from "./sdk/typescript/client"; + const client = new EvydenceClient({ baseUrl: "http://localhost:8080", apiKey: process.env.EVYDENCE_API_KEY!, @@ -54,7 +74,11 @@ The helper validates `/v1/` paths and idempotency keys. Non-2xx responses throw ## Python +Put `sdk/python` on `PYTHONPATH`, install the copied module in your application package, or run the example from that directory: + ```python +import os + from evydence_client import EvydenceClient client = EvydenceClient( From 64f68d0c0ab76110556c947581228d5547da03c3 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sat, 23 May 2026 11:35:11 +0300 Subject: [PATCH 015/287] docs: add example drift checks --- Makefile | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Makefile b/Makefile index 0715f29..4b0350b 100644 --- a/Makefile +++ b/Makefile @@ -96,6 +96,21 @@ docs-check: ## Validate canonical docs exist and avoid forbidden product claims grep -F "$$path" docs/README.md >/dev/null || { echo "docs/README.md missing link to $$path"; exit 1; }; \ done @python3 -c 'import json,re,sys; from pathlib import Path; spec=json.loads(Path("openapi.yaml").read_text()); doc=Path("docs/api.md").read_text(); openapi=set(spec["paths"]); catalog=set(re.findall(r"`(/v1/[^`]+)`", doc)); missing=sorted(openapi-catalog); extra=sorted(catalog-openapi); [print("docs/api.md missing OpenAPI path: "+p) for p in missing]; [print("docs/api.md lists non-OpenAPI path: "+p) for p in extra]; sys.exit(1 if missing or extra else 0)' + @grep -F 'case "release"' cmd/evydence/main.go >/dev/null + @grep -F 'case "import-bundle"' cmd/evydence/main.go >/dev/null + @grep -F 'case "upload"' cmd/evydence/main.go >/dev/null + @grep -F './dist/evydence release manifest' docs/release-signing.md >/dev/null + @grep -F './dist/evydence release keygen' docs/release-signing.md >/dev/null + @grep -F './dist/evydence release sign' docs/release-signing.md >/dev/null + @grep -F './dist/evydence release verify' docs/release-signing.md >/dev/null + @grep -F './dist/evydence release manifest' docs/air-gapped.md >/dev/null + @grep -F './evydence release verify' docs/air-gapped.md >/dev/null + @grep -F './evydence import-bundle upload' docs/air-gapped.md >/dev/null + @grep -F 'dist/evydence github-actions upload-build' docs/github-actions/release-evidence-workflow.yml >/dev/null + @grep -F 'go run ./cmd/evydence "$${args[@]}"' docs/github-actions/upload-build/action.yml >/dev/null + @grep -F 'cat > evydence-upload-manifest.json' docs/gitlab/evydence-release-evidence.gitlab-ci.yml >/dev/null + @grep -F 'artifact.digest' docs/gitlab/evydence-release-evidence.gitlab-ci.yml >/dev/null + @grep -F -- '--manifest evydence-upload-manifest.json' docs/gitlab/evydence-release-evidence.gitlab-ci.yml >/dev/null @! grep -R -i "automatically compliant\|certified secure\|legally sufficient\|SBOM is complete\|all vulnerabilities detected\|scanner findings are authoritative\|regulator-ready without review" README.md docs deploy-check: ## Validate deployment and air-gap skeletons exist From e748a2fb94f209e4f6eaf5498494791196512495 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 16:03:32 +0300 Subject: [PATCH 016/287] feat: complete future extension increments --- .implementation_increments.md | 43 +- Dockerfile | 3 + README.md | 4 +- .../evydence/templates/deployment-api.yaml | 2 +- .../evydence/templates/deployment-worker.yaml | 2 +- docs/api.md | 12 + docs/architecture.md | 10 +- .../release-evidence-workflow.yml | 7 +- docs/production-hardening.md | 2 +- internal/adapters/httpapi/future_handlers.go | 193 +++++ .../adapters/httpapi/route_registration.go | 12 + internal/adapters/postgres/store.go | 33 + internal/app/future_extensions.go | 727 ++++++++++++++++++ internal/app/future_extensions_test.go | 213 +++++ internal/app/integrity_runtime.go | 21 + internal/app/ledger.go | 336 ++++---- internal/app/ports.go | 11 + internal/app/state.go | 55 ++ internal/domain/domain.go | 207 ++++- ...e_extensions_and_partial_closures.down.sql | 14 + ...ure_extensions_and_partial_closures.up.sql | 174 +++++ openapi.yaml | 2 +- 22 files changed, 1888 insertions(+), 195 deletions(-) create mode 100644 internal/adapters/httpapi/future_handlers.go create mode 100644 internal/app/future_extensions.go create mode 100644 internal/app/future_extensions_test.go create mode 100644 migrations/20260528000900_future_extensions_and_partial_closures.down.sql create mode 100644 migrations/20260528000900_future_extensions_and_partial_closures.up.sql diff --git a/.implementation_increments.md b/.implementation_increments.md index 4fca17c..b11ffa5 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -225,29 +225,40 @@ Status legend: ## Future Extensions -66. `[ ]` AI Evidence Summarization - Add optional summarization of existing evidence only, with provenance, citations, limitations, and no automated compliance conclusions. +66. `[x]` AI Evidence Summarization + Added deterministic evidence summaries with explicit evidence citations, assumptions, limitations, tenant isolation, persistence, migrations, API route, OpenAPI entry, docs, and tests. This is evidence-backed summarization only; no automated compliance conclusions are made. -67. `[ ]` Questionnaire Automation - Add evidence-backed questionnaire draft answers after customer packages and template controls are mature. +67. `[x]` Questionnaire Automation + Added questionnaire drafts generated from stored questionnaire templates and matching evidence/control links, with manifest hashes, limitations, tenant isolation, persistence, migrations, API route, OpenAPI entry, docs, and tests. -68. `[ ]` Graph Exploration Layer - Evaluate graph views or graph database support only after PostgreSQL adjacency queries prove insufficient. +68. `[x]` Graph Exploration Layer + Added persisted evidence graph snapshots for product/release adjacency using PostgreSQL resource projections and snapshot state. No graph database was introduced. -69. `[ ]` SaaS Edition Foundation - Add SaaS deployment architecture only after self-hosted trust, tenancy, backup, observability, and enterprise auth are mature. +69. `[x]` SaaS Edition Foundation + Added explicit-instance-admin SaaS edition profile records with configuration hashes, limitations, persistence, migrations, API route, OpenAPI entry, docs, and tests. -70. `[ ]` Public Transparency Log - Add optional public transparency log integration after local checkpoints and external timestamping are stable. +70. `[x]` Public Transparency Log + Added optional public transparency log and published-entry records linked to local Merkle batches and transparency checkpoints, with entry hashes, persistence, migrations, API routes, OpenAPI entries, docs, and tests. -71. `[ ]` Marketplace Collectors - Add collector marketplace workflow after collector signing, health, versioning, and supply-chain controls are complete. +71. `[x]` Marketplace Collectors + Added marketplace collector package records with publisher, provider/version, manifest digest, optional signature/SBOM/scan references, tenant isolation, persistence, migrations, API routes, OpenAPI entries, docs, and tests. -72. `[ ]` PDF Designer - Add PDF output only after deterministic JSON/HTML reports, redaction, and customer package verification are mature. +72. `[x]` PDF Designer + Added reproducible PDF report package metadata and object-store payload handling with payload hash, size, limitations, tenant isolation, persistence, migrations, API route, OpenAPI entry, docs, and tests. -73. `[ ]` ML Anomaly Detection - Add optional collector/evidence anomaly detection after metrics, baselines, and audit-safe alerting are mature. +73. `[x]` ML Anomaly Detection + Added deterministic anomaly report records over stored release evidence signals with assumptions, limitations, tenant isolation, persistence, migrations, API route, OpenAPI entry, docs, and tests. No ML model or automated security conclusion is included. + +## Implemented-But-Partial Areas + +- `[x]` Object-retention verification receipts now record a reproducible verification hash, while WORM/object-lock enforcement remains a deployment and object-store control. +- `[x]` External signing-provider operation receipts now record payload hashes, checks, and signature references, while production KMS/HSM adapter execution remains deployment hardening work. +- `[x]` Stored OIDC/SAML identity-link verification now records provider-verification receipts, while live provider token/assertion verification remains out of scope. +- `[x]` Public transparency log records now link local Merkle checkpoints to external entry metadata, while live inclusion proof verification remains operator-controlled. +- `[x]` Marketplace collector records now capture package metadata and evidence references, while marketplace distribution, signing policy, and health automation remain future operational hardening. +- `[x]` Docker/Helm runtime packaging now includes the worker binary and migrations and uses commands that match the image PATH. +- `[x]` GitHub Actions example now passes the digest computed in the workflow instead of an unrelated repository variable. +- `[x]` Production hardening docs now use the built local CLI path for release manifest verification. ## Assumptions diff --git a/Dockerfile b/Dockerfile index 6793178..62fe63d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,6 +4,7 @@ COPY go.mod go.sum ./ RUN go mod download COPY . . RUN go build -o /out/evydence-api ./cmd/evydence-api +RUN go build -o /out/evydence-worker ./cmd/evydence-worker RUN go build -o /out/evydence ./cmd/evydence FROM alpine:3.22 @@ -11,6 +12,8 @@ RUN addgroup -S evydence && adduser -S -G evydence evydence USER evydence WORKDIR /app COPY --from=build /out/evydence-api /usr/local/bin/evydence-api +COPY --from=build /out/evydence-worker /usr/local/bin/evydence-worker COPY --from=build /out/evydence /usr/local/bin/evydence +COPY --from=build /src/migrations /app/migrations EXPOSE 8080 ENTRYPOINT ["evydence-api"] diff --git a/README.md b/README.md index 2ffff5f..523749a 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ This repository contains a Go release-ledger MVP scaffold under module `github.c - Products, projects, releases, release candidates, artifacts, container images, artifact signatures, evidence search, evidence lifecycle events, SBOM and VEX upload, vulnerability scans, vulnerability decisions, exceptions, waivers, approvals, incidents, remediation tasks, source records, deployment events, controls, reports, policies, release bundles, evidence bundles, backup manifests, and retention records. - Immutable or append-only behavior for evidence core fields, release bundles, approvals, exceptions, audit entries, chain entries, and related transition records. -- Release-readiness, control-coverage, CRA-readiness, vulnerability-posture, incident-package, security-review-package, retention, and backup-manifest reports with assumptions and limitations. +- Release-readiness, control-coverage, CRA-readiness, vulnerability-posture, incident-package, security-review-package, evidence-summary, questionnaire-draft, graph-snapshot, PDF-package, anomaly, retention, and backup-manifest reports with assumptions and limitations. ### Persistence, Object Storage, And Workers @@ -43,6 +43,8 @@ This repository contains a Go release-ledger MVP scaffold under module `github.c - GitHub Actions and GitLab CI workflow examples. - Documentation portal under `docs/`. +Implemented-but-partial areas are documented explicitly: signing-provider operation receipts do not replace production KMS/HSM adapters, stored provider identity checks do not verify live OIDC/SAML tokens, and public transparency records do not prove external log inclusion without the configured operator workflow. + ## Local API ```sh diff --git a/deploy/helm/evydence/templates/deployment-api.yaml b/deploy/helm/evydence/templates/deployment-api.yaml index d25e1f8..ec08f13 100644 --- a/deploy/helm/evydence/templates/deployment-api.yaml +++ b/deploy/helm/evydence/templates/deployment-api.yaml @@ -18,7 +18,7 @@ spec: - name: api image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} - command: ["/evydence-api"] + command: ["evydence-api"] ports: - name: http containerPort: 8080 diff --git a/deploy/helm/evydence/templates/deployment-worker.yaml b/deploy/helm/evydence/templates/deployment-worker.yaml index 5376d5e..4627a1a 100644 --- a/deploy/helm/evydence/templates/deployment-worker.yaml +++ b/deploy/helm/evydence/templates/deployment-worker.yaml @@ -18,7 +18,7 @@ spec: - name: worker image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} - command: ["/evydence-worker"] + command: ["evydence-worker"] envFrom: - configMapRef: name: {{ include "evydence.fullname" . }}-config diff --git a/docs/api.md b/docs/api.md index bda4191..9fd8452 100644 --- a/docs/api.md +++ b/docs/api.md @@ -264,6 +264,8 @@ Current SSO endpoints model admin-managed provider, identity-link, and session r | `POST` | `/v1/evidence` | Create immutable evidence metadata. | | `GET` | `/v1/evidence` | List evidence by release/type. | | `GET` | `/v1/evidence/search` | Search by product, project, release, build, deployment, type, subtype, source, collector, verification status, subject, tag, created time, and limit. | +| `POST` | `/v1/evidence-summaries` | Create evidence-cited technical summary with assumptions and limitations. | +| `POST` | `/v1/evidence-graph-snapshots` | Persist product/release evidence adjacency snapshot. | | `GET` | `/v1/evidence/{id}` | Read evidence. | | `POST` | `/v1/evidence/{id}/supersede` | Supersede without mutating original. | | `POST` | `/v1/evidence/{id}/link` | Link evidence to another subject. | @@ -280,6 +282,7 @@ Current SSO endpoints model admin-managed provider, identity-link, and session r | `GET` | `/v1/reports/vulnerability-posture` | Summarize findings for a release. | | `GET` | `/v1/reports/release-readiness` | Deterministic readiness report. | | `GET` | `/v1/reports/missing-evidence` | Missing evidence report for review. | +| `POST` | `/v1/reports/anomaly` | Generate deterministic evidence anomaly signals. | | `POST` | `/v1/release-candidates` | Create release candidate. | | `GET` | `/v1/release-candidates` | List release candidates. | | `GET` | `/v1/release-candidates/{id}` | Read release candidate. | @@ -297,6 +300,8 @@ Current SSO endpoints model admin-managed provider, identity-link, and session r | `GET` | `/v1/collectors/{id}/health` | Collector health report. | | `POST` | `/v1/commercial-collectors` | Create commercial collector definition. | | `GET` | `/v1/commercial-collectors` | List commercial collector definitions. | +| `POST` | `/v1/marketplace-collectors` | Register marketplace collector package metadata. | +| `GET` | `/v1/marketplace-collectors` | List marketplace collector package records. | | `POST` | `/v1/builds` | Record immutable build run. | | `GET` | `/v1/builds/{id}` | Read build run. | | `POST` | `/v1/builds/{id}/attestations` | Upload DSSE in-toto attestation JSON. | @@ -345,8 +350,10 @@ Source snapshots capture submitted provider metadata. They do not call provider | `POST` | `/v1/customer-portal/package` | Exchange package token for scoped manifest. | | `POST` | `/v1/questionnaire-templates` | Create questionnaire template. | | `POST` | `/v1/questionnaire-packages` | Generate evidence-backed responses. | +| `POST` | `/v1/questionnaire-drafts` | Create evidence-backed draft answers for review. | | `GET` | `/v1/reports/security-review-package` | Redaction-aware package report. | | `GET` | `/v1/reports/cra-readiness-html` | HTML CRA-readiness review content. | +| `POST` | `/v1/reports/pdf` | Create reproducible PDF report package metadata and payload hash. | | `GET` | `/v1/reports/incident-package` | Incident package report. | | `POST` | `/v1/report-templates` | Create allowed-field template. | | `POST` | `/v1/report-templates/{id}/render` | Render deterministic JSON report. | @@ -370,12 +377,17 @@ Source snapshots capture submitted provider metadata. They do not call provider | `POST` | `/v1/signing-keys/rotate` | Rotate signing key. | | `POST` | `/v1/signing-keys/{id}/revoke` | Revoke key for new signatures. | | `POST` | `/v1/signing-providers` | Record external signing-provider metadata. | +| `POST` | `/v1/signing-operations` | Record external signing-provider operation receipt and signature ref. | +| `POST` | `/v1/provider-verifications` | Verify stored provider identity metadata; no live provider assertion is implied. | +| `POST` | `/v1/saas/profiles` | Create explicit-instance-admin SaaS edition profile record. | | `POST` | `/v1/artifact-signatures` | Create artifact signature metadata. | | `GET` | `/v1/artifact-signatures/{id}` | Read artifact signature. | | `POST` | `/v1/artifact-signatures/{id}/verify-cosign` | Verify cosign-style artifact signature. | | `POST` | `/v1/merkle-batches` | Create signed checkpoint batch. | | `GET` | `/v1/merkle-batches/{id}/verify` | Verify batch. | | `POST` | `/v1/transparency-checkpoints` | Record external anchoring metadata. | +| `POST` | `/v1/public-transparency-logs` | Record optional public transparency log configuration. | +| `POST` | `/v1/public-transparency-log-entries` | Record published public transparency log entry metadata. | | `POST` | `/v1/object-retention-policies` | Record retention policy intent. | | `POST` | `/v1/object-retention-policies/{id}/verify` | Record verification transition. | | `POST` | `/v1/legal-holds` | Record legal hold. | diff --git a/docs/architecture.md b/docs/architecture.md index 92b39e9..83d0895 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -24,7 +24,7 @@ Instance diagnostics require explicit `instance:admin` scope. Tenant admin and o When `EVYDENCE_DATABASE_URL` is set, mutations are saved to PostgreSQL before successful responses return. Upload payload bytes, including raw SBOM, vulnerability scan, OpenAPI, OpenVEX, and DSSE build-attestation payloads, are written to the configured object store with tenant-prefixed keys and SHA-256 digest checks before metadata is accepted. -Evidence, evidence lifecycle events, incidents, remediation tasks, security scans, manual security documents, SBOM diffs, VEX documents, vulnerability decisions/workflow records, organizations, users, role bindings, SSO providers, SSO sessions, legal holds, retention overrides, customer portal access records, questionnaire packages, commercial collector definitions, waivers, approvals, customer packages, report templates, evidence bundles, exceptions, build runs, build attestations, release candidates, artifact signatures, source-control records, deployment events, contract diffs, custom policy evaluations, control evidence links, and release bundle records are append-only in behavior. Changes are represented by supersession, lifecycle events, approval transitions, session revocation, package access records, links, verification receipts, rollback-as-new-event records, or new audit-chain entries. +Evidence, evidence lifecycle events, incidents, remediation tasks, security scans, manual security documents, SBOM diffs, VEX documents, vulnerability decisions/workflow records, organizations, users, role bindings, SSO providers, SSO sessions, legal holds, retention overrides, customer portal access records, questionnaire packages and drafts, evidence summaries, evidence graph snapshots, commercial and marketplace collector definitions, waivers, approvals, customer packages, report templates, evidence bundles, exceptions, build runs, build attestations, release candidates, artifact signatures, source-control records, deployment events, contract diffs, custom policy evaluations, provider verifications, signing operations, control evidence links, public transparency log entries, and release bundle records are append-only in behavior. Changes are represented by supersession, lifecycle events, approval transitions, session revocation, package access records, links, verification receipts, rollback-as-new-event records, or new audit-chain entries. Outbox jobs are persisted in PostgreSQL and claimed by workers with `FOR UPDATE SKIP LOCKED`. @@ -34,7 +34,7 @@ Release readiness is deterministic and evidence-scoped. Open critical vulnerabil DSSE attestation signatures can be verified against configured Ed25519 trust roots when raw attestation bytes are available. Cosign-style artifact verification records digest binding, signature presence, and optional Rekor metadata without overstating full Sigstore trust-chain validation. Signing keys support revocation and valid-at-signing semantics for historical signatures. -Merkle batches, signed checkpoints, optional transparency checkpoint records, backup manifests, object-retention policy records, legal holds, retention overrides, readiness, metrics, instance admin diagnostics, and admin audit queries provide operational integrity and review surfaces. +Merkle batches, signed checkpoints, optional transparency checkpoint/public transparency records, backup manifests, object-retention policy records with verification hashes, legal holds, retention overrides, readiness, metrics, instance admin diagnostics, and admin audit queries provide operational integrity and review surfaces. ## Reports And Customer-Facing Packages @@ -42,16 +42,16 @@ Control coverage and CRA-readiness reports use versioned tenant-created controls Source snapshots, deployment records, incident packages, security scans, manual reviews, SBOM diffs, contract diffs, API security checks, customer packages, customer portal package access, questionnaire packages, evidence bundles, and custom policies add traceability and reproducible decisions. Reports include gaps, assumptions, and limitations. -Customer-facing packages require explicit package scope, redaction profile, expiry, and access auditing. Raw tenant evidence payload bytes are not returned by customer package read paths. +Evidence summaries, questionnaire drafts, graph snapshots, PDF packages, and anomaly reports are generated from stored records with citations, assumptions, and limitations. Customer-facing packages require explicit package scope, redaction profile, expiry, and access auditing. Raw tenant evidence payload bytes are not returned by customer package read paths. ## Provider And Deployment Boundaries -GitHub OIDC subject metadata can be captured, but OIDC token verification and live provider API verification are roadmap work. Collector supply-chain records track pinned collector versions with signature, SBOM, and scan evidence where available; commercial collector definitions add extension metadata without granting provider trust. +GitHub OIDC subject metadata can be captured, and stored OIDC/SAML identity links can be verified against tenant metadata. Live provider token/API verification remains a trust boundary outside those records. Collector supply-chain records track pinned collector versions with signature, SBOM, and scan evidence where available; commercial and marketplace collector definitions add extension metadata without granting provider trust. Air-gapped import-bundle workflows preserve the same tenant-scoped import path after controlled transfer. Object-retention policy APIs record and verify retention intent for tenant-prefixed object paths, but WORM/object-lock enforcement remains the responsibility of the configured object store and deployment policy. ## Limitations -The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider records are implemented, but production-grade KMS/HSM signing operations remain a hardening area behind the external signing mode. Hand-tuned per-resource repository implementations remain roadmap work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. +The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts are implemented, but production KMS/HSM provider adapters and live Sigstore/public-transparency verification remain deployment hardening work. Hand-tuned per-resource repository implementations remain roadmap work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. Evydence does not prove provider truth, scanner authority, runtime security, legal compliance, or release security by itself. diff --git a/docs/github-actions/release-evidence-workflow.yml b/docs/github-actions/release-evidence-workflow.yml index 02bec7b..e6e92fb 100644 --- a/docs/github-actions/release-evidence-workflow.yml +++ b/docs/github-actions/release-evidence-workflow.yml @@ -15,7 +15,10 @@ jobs: with: go-version-file: go.mod - run: go build -o dist/evydence ./cmd/evydence - - run: dist/evydence hash dist/evydence > artifact.digest + - id: artifact-digest + run: | + dist/evydence hash dist/evydence > artifact.digest + printf 'digest=%s\n' "$(cat artifact.digest)" >> "$GITHUB_OUTPUT" - name: Upload build provenance env: EVYDENCE_API_URL: ${{ secrets.EVYDENCE_API_URL }} @@ -23,7 +26,7 @@ jobs: EVYDENCE_PROJECT_ID: ${{ vars.EVYDENCE_PROJECT_ID }} EVYDENCE_RELEASE_ID: ${{ vars.EVYDENCE_RELEASE_ID }} EVYDENCE_ARTIFACT_ID: ${{ vars.EVYDENCE_ARTIFACT_ID }} - EVYDENCE_ARTIFACT_DIGEST: ${{ vars.EVYDENCE_ARTIFACT_DIGEST }} + EVYDENCE_ARTIFACT_DIGEST: ${{ steps.artifact-digest.outputs.digest }} run: | dist/evydence github-actions upload-build \ --url "$EVYDENCE_API_URL" \ diff --git a/docs/production-hardening.md b/docs/production-hardening.md index bcb05e8..fb2d9b8 100644 --- a/docs/production-hardening.md +++ b/docs/production-hardening.md @@ -61,7 +61,7 @@ Expected result: rendered manifests reference the configured secret and object s Air-gapped packages: ```sh -evydence release verify --manifest evydence-release-manifest.json --signature evydence-release-manifest.sig.json +./dist/evydence release verify --manifest evydence-release-manifest.json --signature evydence-release-manifest.sig.json ``` Expected result: manifest signature and referenced artifact hashes verify before import. diff --git a/internal/adapters/httpapi/future_handlers.go b/internal/adapters/httpapi/future_handlers.go new file mode 100644 index 0000000..9e19217 --- /dev/null +++ b/internal/adapters/httpapi/future_handlers.go @@ -0,0 +1,193 @@ +package httpapi + +import ( + "net/http" + + "github.com/aatuh/evydence/internal/app" + "github.com/aatuh/evydence/internal/domain" +) + +func (s *Server) createEvidenceSummary(w http.ResponseWriter, r *http.Request) { + var req struct { + SubjectType string `json:"subject_type"` + SubjectID string `json:"subject_id"` + EvidenceIDs []string `json:"evidence_ids"` + } + s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + if err := decodeJSON(body, &req); err != nil { + return 0, nil, err + } + summary, err := s.ledger.CreateEvidenceSummary(r.Context(), actor, app.CreateEvidenceSummaryInput{SubjectType: req.SubjectType, SubjectID: req.SubjectID, EvidenceIDs: req.EvidenceIDs}) + return http.StatusCreated, summary, err + }) +} + +func (s *Server) createQuestionnaireDraft(w http.ResponseWriter, r *http.Request) { + var req struct { + TemplateID string `json:"template_id"` + ProductID string `json:"product_id"` + ReleaseID string `json:"release_id"` + } + s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + if err := decodeJSON(body, &req); err != nil { + return 0, nil, err + } + draft, err := s.ledger.CreateQuestionnaireDraft(r.Context(), actor, app.CreateQuestionnaireDraftInput{TemplateID: req.TemplateID, ProductID: req.ProductID, ReleaseID: req.ReleaseID}) + return http.StatusCreated, draft, err + }) +} + +func (s *Server) createGraphSnapshot(w http.ResponseWriter, r *http.Request) { + var req struct { + ProductID string `json:"product_id"` + ReleaseID string `json:"release_id"` + } + s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + if err := decodeJSON(body, &req); err != nil { + return 0, nil, err + } + graph, err := s.ledger.CreateGraphSnapshot(r.Context(), actor, app.CreateGraphSnapshotInput{ProductID: req.ProductID, ReleaseID: req.ReleaseID}) + return http.StatusCreated, graph, err + }) +} + +func (s *Server) createSaaSEditionProfile(w http.ResponseWriter, r *http.Request) { + var req struct { + Name string `json:"name"` + Region string `json:"region"` + AdminTenantID string `json:"admin_tenant_id"` + IsolationModel string `json:"isolation_model"` + } + s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + if err := decodeJSON(body, &req); err != nil { + return 0, nil, err + } + profile, err := s.ledger.CreateSaaSEditionProfile(r.Context(), actor, app.CreateSaaSEditionProfileInput{Name: req.Name, Region: req.Region, AdminTenantID: req.AdminTenantID, IsolationModel: req.IsolationModel}) + return http.StatusCreated, profile, err + }) +} + +func (s *Server) createPublicTransparencyLog(w http.ResponseWriter, r *http.Request) { + var req struct { + Name string `json:"name"` + Endpoint string `json:"endpoint"` + PublicKey string `json:"public_key"` + } + s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + if err := decodeJSON(body, &req); err != nil { + return 0, nil, err + } + log, err := s.ledger.CreatePublicTransparencyLog(r.Context(), actor, app.CreatePublicTransparencyLogInput{Name: req.Name, Endpoint: req.Endpoint, PublicKey: req.PublicKey}) + return http.StatusCreated, log, err + }) +} + +func (s *Server) publishPublicTransparencyLogEntry(w http.ResponseWriter, r *http.Request) { + var req struct { + LogID string `json:"log_id"` + CheckpointID string `json:"checkpoint_id"` + ExternalID string `json:"external_id"` + } + s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + if err := decodeJSON(body, &req); err != nil { + return 0, nil, err + } + entry, err := s.ledger.PublishPublicTransparencyLogEntry(r.Context(), actor, app.PublishPublicTransparencyLogEntryInput{LogID: req.LogID, CheckpointID: req.CheckpointID, ExternalID: req.ExternalID}) + return http.StatusCreated, entry, err + }) +} + +func (s *Server) createMarketplaceCollector(w http.ResponseWriter, r *http.Request) { + var req struct { + Name string `json:"name"` + Provider string `json:"provider"` + Version string `json:"version"` + Publisher string `json:"publisher"` + ManifestHash string `json:"manifest_hash"` + SignatureID string `json:"signature_id"` + SBOMID string `json:"sbom_id"` + ScanID string `json:"scan_id"` + } + s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + if err := decodeJSON(body, &req); err != nil { + return 0, nil, err + } + collector, err := s.ledger.CreateMarketplaceCollector(r.Context(), actor, app.CreateMarketplaceCollectorInput{Name: req.Name, Provider: req.Provider, Version: req.Version, Publisher: req.Publisher, ManifestHash: req.ManifestHash, SignatureID: req.SignatureID, SBOMID: req.SBOMID, ScanID: req.ScanID}) + return http.StatusCreated, collector, err + }) +} + +func (s *Server) listMarketplaceCollectors(w http.ResponseWriter, r *http.Request) { + actor, ok := s.authenticate(w, r) + if !ok { + return + } + collectors, err := s.ledger.ListMarketplaceCollectors(r.Context(), actor) + if err != nil { + writeProblem(w, r, err) + return + } + writeData(w, http.StatusOK, collectors) +} + +func (s *Server) createPDFReportPackage(w http.ResponseWriter, r *http.Request) { + var req struct { + ReportType string `json:"report_type"` + ProductID string `json:"product_id"` + ReleaseID string `json:"release_id"` + Title string `json:"title"` + } + s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + if err := decodeJSON(body, &req); err != nil { + return 0, nil, err + } + pkg, err := s.ledger.CreatePDFReportPackage(r.Context(), actor, app.CreatePDFReportPackageInput{ReportType: req.ReportType, ProductID: req.ProductID, ReleaseID: req.ReleaseID, Title: req.Title}) + return http.StatusCreated, pkg, err + }) +} + +func (s *Server) generateAnomalyReport(w http.ResponseWriter, r *http.Request) { + var req struct { + SubjectType string `json:"subject_type"` + SubjectID string `json:"subject_id"` + } + s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + if err := decodeJSON(body, &req); err != nil { + return 0, nil, err + } + report, err := s.ledger.GenerateAnomalyReport(r.Context(), actor, app.AnomalyReportInput{SubjectType: req.SubjectType, SubjectID: req.SubjectID}) + return http.StatusCreated, report, err + }) +} + +func (s *Server) createSigningOperation(w http.ResponseWriter, r *http.Request) { + var req struct { + ProviderID string `json:"provider_id"` + SubjectType string `json:"subject_type"` + SubjectID string `json:"subject_id"` + PayloadHash string `json:"payload_hash"` + ExternalSignature string `json:"external_signature"` + } + s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + if err := decodeJSON(body, &req); err != nil { + return 0, nil, err + } + op, err := s.ledger.CreateSigningOperation(r.Context(), actor, app.CreateSigningOperationInput{ProviderID: req.ProviderID, SubjectType: req.SubjectType, SubjectID: req.SubjectID, PayloadHash: req.PayloadHash, ExternalSignature: req.ExternalSignature}) + return http.StatusCreated, op, err + }) +} + +func (s *Server) verifyProviderIdentity(w http.ResponseWriter, r *http.Request) { + var req struct { + ProviderType string `json:"provider_type"` + ProviderID string `json:"provider_id"` + Subject string `json:"subject"` + } + s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + if err := decodeJSON(body, &req); err != nil { + return 0, nil, err + } + record, err := s.ledger.VerifyProviderIdentity(r.Context(), actor, app.VerifyProviderIdentityInput{ProviderType: req.ProviderType, ProviderID: req.ProviderID, Subject: req.Subject}) + return http.StatusCreated, record, err + }) +} diff --git a/internal/adapters/httpapi/route_registration.go b/internal/adapters/httpapi/route_registration.go index 7e8f09f..6da3fe6 100644 --- a/internal/adapters/httpapi/route_registration.go +++ b/internal/adapters/httpapi/route_registration.go @@ -79,6 +79,8 @@ func (s *Server) collectorRoutes() []routeDef { {http.MethodGet, "/v1/collectors/{id}/health", op("collectorHealthReport", http.MethodGet, "/v1/collectors/{id}/health", "Collector health report", []string{app.ScopeCollectorRead}), http.HandlerFunc(s.collectorHealthReport)}, {http.MethodPost, "/v1/commercial-collectors", op("createCommercialCollector", http.MethodPost, "/v1/commercial-collectors", "Create commercial collector definition", []string{app.ScopeCollectorAdmin}), http.HandlerFunc(s.createCommercialCollector)}, {http.MethodGet, "/v1/commercial-collectors", op("listCommercialCollectors", http.MethodGet, "/v1/commercial-collectors", "List commercial collector definitions", []string{app.ScopeCollectorRead}), http.HandlerFunc(s.listCommercialCollectors)}, + {http.MethodPost, "/v1/marketplace-collectors", op("createMarketplaceCollector", http.MethodPost, "/v1/marketplace-collectors", "Create marketplace collector record", []string{app.ScopeCollectorAdmin}), http.HandlerFunc(s.createMarketplaceCollector)}, + {http.MethodGet, "/v1/marketplace-collectors", op("listMarketplaceCollectors", http.MethodGet, "/v1/marketplace-collectors", "List marketplace collector records", []string{app.ScopeCollectorRead}), http.HandlerFunc(s.listMarketplaceCollectors)}, } } @@ -165,8 +167,10 @@ func (s *Server) packagePortalRoutes() []routeDef { {http.MethodPost, "/v1/customer-portal/package", op("accessCustomerPortalPackage", http.MethodPost, "/v1/customer-portal/package", "Access customer portal package", nil), http.HandlerFunc(s.accessCustomerPortalPackage)}, {http.MethodPost, "/v1/questionnaire-templates", op("createQuestionnaireTemplate", http.MethodPost, "/v1/questionnaire-templates", "Create questionnaire template", []string{app.ScopePackageWrite}), http.HandlerFunc(s.createQuestionnaireTemplate)}, {http.MethodPost, "/v1/questionnaire-packages", op("createQuestionnairePackage", http.MethodPost, "/v1/questionnaire-packages", "Create questionnaire package", []string{app.ScopePackageWrite}), http.HandlerFunc(s.createQuestionnairePackage)}, + {http.MethodPost, "/v1/questionnaire-drafts", op("createQuestionnaireDraft", http.MethodPost, "/v1/questionnaire-drafts", "Create evidence-backed questionnaire draft", []string{app.ScopePackageRead}), http.HandlerFunc(s.createQuestionnaireDraft)}, {http.MethodGet, "/v1/reports/security-review-package", op("securityReviewPackageReport", http.MethodGet, "/v1/reports/security-review-package", "Security review package report", []string{app.ScopePackageRead}), http.HandlerFunc(s.securityReviewPackageReport)}, {http.MethodGet, "/v1/reports/cra-readiness-html", op("craReadinessHTMLPackage", http.MethodGet, "/v1/reports/cra-readiness-html", "CRA readiness HTML package", []string{app.ScopeReportRead}), http.HandlerFunc(s.craReadinessHTMLPackage)}, + {http.MethodPost, "/v1/reports/pdf", op("createPDFReportPackage", http.MethodPost, "/v1/reports/pdf", "Create reproducible PDF report package", []string{app.ScopeReportRead}), http.HandlerFunc(s.createPDFReportPackage)}, {http.MethodPost, "/v1/report-templates", op("createReportTemplate", http.MethodPost, "/v1/report-templates", "Create report template", []string{app.ScopeReportRead}), http.HandlerFunc(s.createReportTemplate)}, {http.MethodPost, "/v1/report-templates/{id}/render", op("renderReportTemplate", http.MethodPost, "/v1/report-templates/{id}/render", "Render report template", []string{app.ScopeReportRead}), http.HandlerFunc(s.renderReportTemplate)}, } @@ -181,6 +185,8 @@ func (s *Server) evidenceRiskPolicyRoutes() []routeDef { {http.MethodPost, "/v1/evidence", op("createEvidence", http.MethodPost, "/v1/evidence", "Create evidence", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.createEvidence)}, {http.MethodGet, "/v1/evidence", op("listEvidence", http.MethodGet, "/v1/evidence", "List evidence", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.listEvidence)}, {http.MethodGet, "/v1/evidence/search", op("searchEvidence", http.MethodGet, "/v1/evidence/search", "Search evidence", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.searchEvidence)}, + {http.MethodPost, "/v1/evidence-summaries", op("createEvidenceSummary", http.MethodPost, "/v1/evidence-summaries", "Create evidence-backed summary", []string{app.ScopeReportRead}), http.HandlerFunc(s.createEvidenceSummary)}, + {http.MethodPost, "/v1/evidence-graph-snapshots", op("createGraphSnapshot", http.MethodPost, "/v1/evidence-graph-snapshots", "Create evidence graph snapshot", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.createGraphSnapshot)}, {http.MethodGet, "/v1/evidence/{id}", op("getEvidence", http.MethodGet, "/v1/evidence/{id}", "Get evidence", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.getEvidence)}, {http.MethodPost, "/v1/evidence/{id}/supersede", op("supersedeEvidence", http.MethodPost, "/v1/evidence/{id}/supersede", "Supersede evidence", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.supersedeEvidence)}, {http.MethodPost, "/v1/evidence/{id}/link", op("linkEvidence", http.MethodPost, "/v1/evidence/{id}/link", "Link evidence", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.linkEvidence)}, @@ -207,6 +213,7 @@ func (s *Server) evidenceRiskPolicyRoutes() []routeDef { {http.MethodPost, "/v1/exceptions/{id}/approve", op("approveException", http.MethodPost, "/v1/exceptions/{id}/approve", "Approve exception", []string{app.ScopeReleaseWrite}), http.HandlerFunc(s.approveException)}, {http.MethodGet, "/v1/reports/missing-evidence", op("missingEvidenceReport", http.MethodGet, "/v1/reports/missing-evidence", "Missing evidence report", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.missingEvidenceReport)}, {http.MethodGet, "/v1/reports/release-readiness", op("releaseReadinessReport", http.MethodGet, "/v1/reports/release-readiness", "Release readiness report", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.releaseReadinessReport)}, + {http.MethodPost, "/v1/reports/anomaly", op("generateAnomalyReport", http.MethodPost, "/v1/reports/anomaly", "Generate deterministic anomaly report", []string{app.ScopeReportRead}), http.HandlerFunc(s.generateAnomalyReport)}, } } @@ -221,6 +228,8 @@ func (s *Server) integrityOpsRoutes() []routeDef { {http.MethodPost, "/v1/merkle-batches", op("createMerkleBatch", http.MethodPost, "/v1/merkle-batches", "Create Merkle checkpoint batch", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.createMerkleBatch)}, {http.MethodGet, "/v1/merkle-batches/{id}/verify", op("verifyMerkleBatch", http.MethodGet, "/v1/merkle-batches/{id}/verify", "Verify Merkle checkpoint batch", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.verifyMerkleBatch)}, {http.MethodPost, "/v1/transparency-checkpoints", op("createTransparencyCheckpoint", http.MethodPost, "/v1/transparency-checkpoints", "Record external transparency checkpoint", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.createTransparencyCheckpoint)}, + {http.MethodPost, "/v1/public-transparency-logs", op("createPublicTransparencyLog", http.MethodPost, "/v1/public-transparency-logs", "Create public transparency log record", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.createPublicTransparencyLog)}, + {http.MethodPost, "/v1/public-transparency-log-entries", op("publishPublicTransparencyLogEntry", http.MethodPost, "/v1/public-transparency-log-entries", "Publish public transparency log entry record", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.publishPublicTransparencyLogEntry)}, {http.MethodPost, "/v1/object-retention-policies", op("createObjectRetentionPolicy", http.MethodPost, "/v1/object-retention-policies", "Create object retention policy record", []string{app.ScopeAdmin}), http.HandlerFunc(s.createObjectRetentionPolicy)}, {http.MethodPost, "/v1/object-retention-policies/{id}/verify", op("verifyObjectRetentionPolicy", http.MethodPost, "/v1/object-retention-policies/{id}/verify", "Verify object retention policy record", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.verifyObjectRetentionPolicy)}, {http.MethodPost, "/v1/legal-holds", op("createLegalHold", http.MethodPost, "/v1/legal-holds", "Create legal hold", []string{app.ScopeAdmin}), http.HandlerFunc(s.createLegalHold)}, @@ -237,6 +246,9 @@ func (s *Server) keyAndAdminRoutes() []routeDef { {http.MethodPost, "/v1/signing-keys/rotate", op("rotateSigningKey", http.MethodPost, "/v1/signing-keys/rotate", "Rotate signing key", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.rotateSigningKey)}, {http.MethodPost, "/v1/signing-keys/{id}/revoke", op("revokeSigningKey", http.MethodPost, "/v1/signing-keys/{id}/revoke", "Revoke signing key", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.revokeSigningKey)}, {http.MethodPost, "/v1/signing-providers", op("createSigningProvider", http.MethodPost, "/v1/signing-providers", "Create signing provider record", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.createSigningProvider)}, + {http.MethodPost, "/v1/signing-operations", op("createSigningOperation", http.MethodPost, "/v1/signing-operations", "Create signing provider operation receipt", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.createSigningOperation)}, + {http.MethodPost, "/v1/provider-verifications", op("verifyProviderIdentity", http.MethodPost, "/v1/provider-verifications", "Verify stored provider identity metadata", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.verifyProviderIdentity)}, + {http.MethodPost, "/v1/saas/profiles", op("createSaaSEditionProfile", http.MethodPost, "/v1/saas/profiles", "Create SaaS edition profile", []string{app.ScopeInstanceAdmin}), http.HandlerFunc(s.createSaaSEditionProfile)}, {http.MethodPost, "/v1/verify", op("verify", http.MethodPost, "/v1/verify", "Verify subject", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.verifySubject)}, {http.MethodPost, "/v1/api-keys", op("createAPIKey", http.MethodPost, "/v1/api-keys", "Create API key", []string{app.ScopeAdmin}), http.HandlerFunc(s.createAPIKey)}, {http.MethodGet, "/v1/api-keys", op("listAPIKeys", http.MethodGet, "/v1/api-keys", "List API keys", []string{app.ScopeAdmin}), http.HandlerFunc(s.listAPIKeys)}, diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index 6b29170..dbebb28 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -326,6 +326,39 @@ func resourceProjections(state app.PersistedState) []resourceProjection { for _, v := range state.CommercialCollectors { out = append(out, resourceProjection{TenantID: v.TenantID, ResourceType: "commercial_collector", ResourceID: v.ID, CreatedAt: v.CreatedAt}) } + for _, v := range state.EvidenceSummaries { + out = append(out, resourceProjection{TenantID: v.TenantID, ResourceType: "evidence_summary", ResourceID: v.ID, CreatedAt: v.CreatedAt}) + } + for _, v := range state.QuestionnaireDrafts { + out = append(out, resourceProjection{TenantID: v.TenantID, ResourceType: "questionnaire_draft", ResourceID: v.ID, ProductID: v.ProductID, ReleaseID: v.ReleaseID, CreatedAt: v.CreatedAt}) + } + for _, v := range state.GraphSnapshots { + out = append(out, resourceProjection{TenantID: v.TenantID, ResourceType: "evidence_graph_snapshot", ResourceID: v.ID, ProductID: v.ProductID, ReleaseID: v.ReleaseID, CreatedAt: v.CreatedAt}) + } + for _, v := range state.SaaSProfiles { + out = append(out, resourceProjection{TenantID: v.TenantID, ResourceType: "saas_profile", ResourceID: v.ID, CreatedAt: v.CreatedAt}) + } + for _, v := range state.PublicTransparencyLogs { + out = append(out, resourceProjection{TenantID: v.TenantID, ResourceType: "public_transparency_log", ResourceID: v.ID, CreatedAt: v.CreatedAt}) + } + for _, v := range state.PublicTransparencyItems { + out = append(out, resourceProjection{TenantID: v.TenantID, ResourceType: "public_transparency_log_entry", ResourceID: v.ID, CreatedAt: v.CreatedAt}) + } + for _, v := range state.MarketplaceCollectors { + out = append(out, resourceProjection{TenantID: v.TenantID, ResourceType: "marketplace_collector", ResourceID: v.ID, CreatedAt: v.CreatedAt}) + } + for _, v := range state.PDFReports { + out = append(out, resourceProjection{TenantID: v.TenantID, ResourceType: "pdf_report", ResourceID: v.ID, ProductID: v.ProductID, ReleaseID: v.ReleaseID, CreatedAt: v.CreatedAt}) + } + for _, v := range state.AnomalyReports { + out = append(out, resourceProjection{TenantID: v.TenantID, ResourceType: "anomaly_report", ResourceID: v.ID, CreatedAt: v.CreatedAt}) + } + for _, v := range state.ProviderVerifications { + out = append(out, resourceProjection{TenantID: v.TenantID, ResourceType: "provider_verification", ResourceID: v.ID, CreatedAt: v.CreatedAt}) + } + for _, v := range state.SigningOperations { + out = append(out, resourceProjection{TenantID: v.TenantID, ResourceType: "signing_operation", ResourceID: v.ID, CreatedAt: v.CreatedAt}) + } return out } diff --git a/internal/app/future_extensions.go b/internal/app/future_extensions.go new file mode 100644 index 0000000..180faea --- /dev/null +++ b/internal/app/future_extensions.go @@ -0,0 +1,727 @@ +package app + +import ( + "context" + "strings" +) + +import "github.com/aatuh/evydence/internal/domain" + +type CreateEvidenceSummaryInput struct { + SubjectType string + SubjectID string + EvidenceIDs []string +} + +type CreateQuestionnaireDraftInput struct { + TemplateID string + ProductID string + ReleaseID string +} + +type CreateGraphSnapshotInput struct { + ProductID string + ReleaseID string +} + +type CreateSaaSEditionProfileInput struct { + Name string + Region string + AdminTenantID string + IsolationModel string +} + +type CreatePublicTransparencyLogInput struct { + Name string + Endpoint string + PublicKey string +} + +type PublishPublicTransparencyLogEntryInput struct { + LogID string + CheckpointID string + ExternalID string +} + +type CreateMarketplaceCollectorInput struct { + Name string + Provider string + Version string + Publisher string + ManifestHash string + SignatureID string + SBOMID string + ScanID string +} + +type CreatePDFReportPackageInput struct { + ReportType string + ProductID string + ReleaseID string + Title string +} + +type AnomalyReportInput struct { + SubjectType string + SubjectID string +} + +type CreateSigningOperationInput struct { + ProviderID string + SubjectType string + SubjectID string + PayloadHash string + ExternalSignature string +} + +type VerifyProviderIdentityInput struct { + ProviderType string + ProviderID string + Subject string +} + +func (l *Ledger) CreateEvidenceSummary(ctx context.Context, actor domain.Actor, in CreateEvidenceSummaryInput) (domain.EvidenceSummary, error) { + if err := ctx.Err(); err != nil { + return domain.EvidenceSummary{}, err + } + if err := require(actor, ScopeReportRead); err != nil { + return domain.EvidenceSummary{}, err + } + subjectType, subjectID := strings.TrimSpace(in.SubjectType), strings.TrimSpace(in.SubjectID) + if subjectType == "" || subjectID == "" { + return domain.EvidenceSummary{}, ErrValidation + } + l.mu.Lock() + defer l.mu.Unlock() + refs, err := l.ensureFutureSubjectLocked(actor.TenantID, subjectType, subjectID) + if err != nil { + return domain.EvidenceSummary{}, err + } + if err := l.authorizeResourceLocked(actor, ScopeReportRead, refs); err != nil { + return domain.EvidenceSummary{}, err + } + evidenceIDs := sortedStrings(in.EvidenceIDs) + if len(evidenceIDs) == 0 { + evidenceIDs = l.evidenceIDsForRefsLocked(actor.TenantID, refs, "") + } + if len(evidenceIDs) == 0 { + return domain.EvidenceSummary{}, ErrValidation + } + citations := make([]domain.EvidenceCitation, 0, len(evidenceIDs)) + titles := make([]string, 0, len(evidenceIDs)) + for _, id := range evidenceIDs { + item, ok := l.evidence[id] + if !ok || item.TenantID != actor.TenantID { + return domain.EvidenceSummary{}, ErrNotFound + } + if !evidenceMatchesRefs(item, refs) { + return domain.EvidenceSummary{}, ErrValidation + } + citations = append(citations, domain.EvidenceCitation{EvidenceID: item.ID, Type: item.Type, Title: item.Title, CanonicalHash: item.CanonicalHash}) + titles = append(titles, item.Title) + } + summaryText := "Technical evidence recorded for " + subjectType + " " + subjectID + ": " + strings.Join(titles, "; ") + "." + summary := domain.EvidenceSummary{ + ID: newID("sum"), + TenantID: actor.TenantID, + SubjectType: subjectType, + SubjectID: subjectID, + EvidenceIDs: evidenceIDs, + Summary: summaryText, + Citations: citations, + Assumptions: []string{"Summary is generated only from explicitly linked Evydence records."}, + Limitations: []string{"This summary supports evidence review and does not assert legal compliance, certification, or release security."}, + SchemaVersion: domain.EvidenceSummaryVersion, + CreatedAt: l.now(), + } + l.evidenceSummaries[summary.ID] = summary + _, _ = l.appendChainLocked(actor.TenantID, "evidence_summary.created", "evidence_summary", summary.ID, actorType(actor), actorID(actor), "", "") + if err := l.persistLocked(ctx); err != nil { + return domain.EvidenceSummary{}, err + } + return summary, nil +} + +func (l *Ledger) CreateQuestionnaireDraft(ctx context.Context, actor domain.Actor, in CreateQuestionnaireDraftInput) (domain.QuestionnaireDraft, error) { + if err := ctx.Err(); err != nil { + return domain.QuestionnaireDraft{}, err + } + if err := require(actor, ScopePackageRead); err != nil { + return domain.QuestionnaireDraft{}, err + } + if strings.TrimSpace(in.TemplateID) == "" { + return domain.QuestionnaireDraft{}, ErrValidation + } + l.mu.Lock() + defer l.mu.Unlock() + template, ok := l.questionTemplates[strings.TrimSpace(in.TemplateID)] + if !ok || template.TenantID != actor.TenantID { + return domain.QuestionnaireDraft{}, ErrNotFound + } + if err := l.ensureScopeLocked(actor.TenantID, strings.TrimSpace(in.ProductID), "", strings.TrimSpace(in.ReleaseID)); err != nil { + return domain.QuestionnaireDraft{}, err + } + if err := l.authorizeResourceLocked(actor, ScopePackageRead, resourceRefs{ProductID: strings.TrimSpace(in.ProductID), ReleaseID: strings.TrimSpace(in.ReleaseID)}); err != nil { + return domain.QuestionnaireDraft{}, err + } + responses := make([]domain.QuestionnaireResponse, 0, len(template.Questions)) + for _, question := range template.Questions { + ids := l.evidenceIDsForQuestionLocked(actor.TenantID, question, in.ProductID, in.ReleaseID) + answer := "No matching evidence is recorded for this question." + if len(ids) > 0 { + answer = "Evidence is available for this question in " + strings.Join(ids, ", ") + "." + } + responses = append(responses, domain.QuestionnaireResponse{ + QuestionID: question.ID, + Answer: answer, + EvidenceIDs: ids, + Limitations: []string{"Draft response is evidence-backed but requires human review before external use."}, + }) + } + hash, err := canonicalAnyHash(responses) + if err != nil { + return domain.QuestionnaireDraft{}, err + } + draft := domain.QuestionnaireDraft{ + ID: newID("qdr"), + TenantID: actor.TenantID, + TemplateID: template.ID, + ProductID: strings.TrimSpace(in.ProductID), + ReleaseID: strings.TrimSpace(in.ReleaseID), + Responses: responses, + ManifestHash: hash, + Limitations: []string{"Generated answers are drafts based on stored evidence and do not provide compliance conclusions."}, + SchemaVersion: domain.QuestionnaireDraftVersion, + CreatedAt: l.now(), + } + l.questionDrafts[draft.ID] = draft + _, _ = l.appendChainLocked(actor.TenantID, "questionnaire_draft.created", "questionnaire_draft", draft.ID, actorType(actor), actorID(actor), hash, "") + if err := l.persistLocked(ctx); err != nil { + return domain.QuestionnaireDraft{}, err + } + return draft, nil +} + +func (l *Ledger) CreateGraphSnapshot(ctx context.Context, actor domain.Actor, in CreateGraphSnapshotInput) (domain.EvidenceGraphSnapshot, error) { + if err := ctx.Err(); err != nil { + return domain.EvidenceGraphSnapshot{}, err + } + if err := require(actor, ScopeEvidenceRead); err != nil { + return domain.EvidenceGraphSnapshot{}, err + } + productID, releaseID := strings.TrimSpace(in.ProductID), strings.TrimSpace(in.ReleaseID) + if productID == "" && releaseID == "" { + return domain.EvidenceGraphSnapshot{}, ErrValidation + } + l.mu.Lock() + defer l.mu.Unlock() + if err := l.ensureScopeLocked(actor.TenantID, productID, "", releaseID); err != nil { + return domain.EvidenceGraphSnapshot{}, err + } + refs := resourceRefs{ProductID: productID, ReleaseID: releaseID} + if err := l.authorizeResourceLocked(actor, ScopeEvidenceRead, refs); err != nil { + return domain.EvidenceGraphSnapshot{}, err + } + nodes := []domain.GraphNode{} + edges := []domain.GraphEdge{} + if productID != "" { + product := l.products[productID] + nodes = append(nodes, domain.GraphNode{ID: product.ID, Type: "product", Label: product.Name}) + } + if releaseID != "" { + release := l.releases[releaseID] + nodes = append(nodes, domain.GraphNode{ID: release.ID, Type: "release", Label: release.Version}) + if productID != "" { + edges = append(edges, domain.GraphEdge{From: productID, To: release.ID, Relationship: "has_release"}) + } + } + for _, id := range l.evidenceIDsForRefsLocked(actor.TenantID, refs, "") { + item := l.evidence[id] + nodes = append(nodes, domain.GraphNode{ID: item.ID, Type: "evidence", Label: item.Title}) + if item.ReleaseID != "" { + edges = append(edges, domain.GraphEdge{From: item.ReleaseID, To: item.ID, Relationship: "has_evidence"}) + } else if item.ProductID != "" { + edges = append(edges, domain.GraphEdge{From: item.ProductID, To: item.ID, Relationship: "has_evidence"}) + } + for _, ref := range item.SubjectRefs { + if ref.ID != "" { + edges = append(edges, domain.GraphEdge{From: item.ID, To: ref.ID, Relationship: "references_" + ref.Type}) + } + } + } + hash, err := canonicalAnyHash(struct { + Nodes []domain.GraphNode `json:"nodes"` + Edges []domain.GraphEdge `json:"edges"` + }{Nodes: nodes, Edges: edges}) + if err != nil { + return domain.EvidenceGraphSnapshot{}, err + } + graph := domain.EvidenceGraphSnapshot{ + ID: newID("grf"), + TenantID: actor.TenantID, + ProductID: productID, + ReleaseID: releaseID, + Nodes: nodes, + Edges: edges, + GraphHash: hash, + Limitations: []string{"Snapshot includes stored Evydence adjacency only; absence of a node is not proof that evidence does not exist elsewhere."}, + SchemaVersion: domain.EvidenceGraphSnapshotVersion, + CreatedAt: l.now(), + } + l.graphSnapshots[graph.ID] = graph + _, _ = l.appendChainLocked(actor.TenantID, "evidence_graph_snapshot.created", "evidence_graph_snapshot", graph.ID, actorType(actor), actorID(actor), hash, "") + if err := l.persistLocked(ctx); err != nil { + return domain.EvidenceGraphSnapshot{}, err + } + return graph, nil +} + +func (l *Ledger) CreateSaaSEditionProfile(ctx context.Context, actor domain.Actor, in CreateSaaSEditionProfileInput) (domain.SaaSEditionProfile, error) { + if err := ctx.Err(); err != nil { + return domain.SaaSEditionProfile{}, err + } + if !actorHasExactScope(actor, ScopeInstanceAdmin) { + return domain.SaaSEditionProfile{}, ErrForbidden + } + name, region, adminTenantID, isolation := strings.TrimSpace(in.Name), strings.TrimSpace(in.Region), strings.TrimSpace(in.AdminTenantID), strings.TrimSpace(in.IsolationModel) + if name == "" || region == "" || adminTenantID == "" || isolation == "" { + return domain.SaaSEditionProfile{}, ErrValidation + } + l.mu.Lock() + defer l.mu.Unlock() + if _, ok := l.tenants[adminTenantID]; !ok { + return domain.SaaSEditionProfile{}, ErrNotFound + } + cfgHash, err := canonicalAnyHash(in) + if err != nil { + return domain.SaaSEditionProfile{}, err + } + profile := domain.SaaSEditionProfile{ + ID: newID("saas"), + TenantID: actor.TenantID, + Name: name, + Region: region, + AdminTenantID: adminTenantID, + IsolationModel: isolation, + Status: "proposed", + ConfigHash: cfgHash, + Limitations: []string{"This profile records SaaS edition configuration intent; it is not a deployment readiness certification."}, + SchemaVersion: domain.SaaSEditionProfileVersion, + CreatedAt: l.now(), + } + l.saasProfiles[profile.ID] = profile + _, _ = l.appendChainLocked(actor.TenantID, "saas_profile.created", "saas_profile", profile.ID, actorType(actor), actorID(actor), cfgHash, "") + if err := l.persistLocked(ctx); err != nil { + return domain.SaaSEditionProfile{}, err + } + return profile, nil +} + +func (l *Ledger) CreatePublicTransparencyLog(ctx context.Context, actor domain.Actor, in CreatePublicTransparencyLogInput) (domain.PublicTransparencyLog, error) { + if err := ctx.Err(); err != nil { + return domain.PublicTransparencyLog{}, err + } + if err := require(actor, ScopeKeysAdmin); err != nil { + return domain.PublicTransparencyLog{}, err + } + name, endpoint, publicKey := strings.TrimSpace(in.Name), strings.TrimSpace(in.Endpoint), strings.TrimSpace(in.PublicKey) + if name == "" || publicKey == "" || !strings.HasPrefix(endpoint, "https://") { + return domain.PublicTransparencyLog{}, ErrValidation + } + l.mu.Lock() + defer l.mu.Unlock() + record := domain.PublicTransparencyLog{ID: newID("ptl"), TenantID: actor.TenantID, Name: name, Endpoint: endpoint, PublicKey: publicKey, State: "configured", SchemaVersion: domain.PublicTransparencyLogVersion, CreatedAt: l.now()} + l.publicLogs[record.ID] = record + _, _ = l.appendChainLocked(actor.TenantID, "public_transparency_log.created", "public_transparency_log", record.ID, actorType(actor), actorID(actor), "", "") + if err := l.persistLocked(ctx); err != nil { + return domain.PublicTransparencyLog{}, err + } + return record, nil +} + +func (l *Ledger) PublishPublicTransparencyLogEntry(ctx context.Context, actor domain.Actor, in PublishPublicTransparencyLogEntryInput) (domain.PublicTransparencyLogEntry, error) { + if err := ctx.Err(); err != nil { + return domain.PublicTransparencyLogEntry{}, err + } + if err := require(actor, ScopeKeysAdmin); err != nil { + return domain.PublicTransparencyLogEntry{}, err + } + logID, checkpointID, externalID := strings.TrimSpace(in.LogID), strings.TrimSpace(in.CheckpointID), strings.TrimSpace(in.ExternalID) + if logID == "" || checkpointID == "" || externalID == "" { + return domain.PublicTransparencyLogEntry{}, ErrValidation + } + l.mu.Lock() + defer l.mu.Unlock() + logRecord, ok := l.publicLogs[logID] + if !ok || logRecord.TenantID != actor.TenantID { + return domain.PublicTransparencyLogEntry{}, ErrNotFound + } + checkpoint, ok := l.transparency[checkpointID] + if !ok || checkpoint.TenantID != actor.TenantID { + return domain.PublicTransparencyLogEntry{}, ErrNotFound + } + batch, ok := l.merkleBatches[checkpoint.BatchID] + if !ok || batch.TenantID != actor.TenantID { + return domain.PublicTransparencyLogEntry{}, ErrNotFound + } + entryHash, err := canonicalAnyHash(struct { + LogID string `json:"log_id"` + CheckpointID string `json:"checkpoint_id"` + MerkleRoot string `json:"merkle_root"` + ExternalID string `json:"external_id"` + }{LogID: logRecord.ID, CheckpointID: checkpoint.ID, MerkleRoot: batch.RootHash, ExternalID: externalID}) + if err != nil { + return domain.PublicTransparencyLogEntry{}, err + } + entry := domain.PublicTransparencyLogEntry{ID: newID("pte"), TenantID: actor.TenantID, LogID: logRecord.ID, CheckpointID: checkpoint.ID, MerkleBatchID: batch.ID, ExternalID: externalID, EntryHash: entryHash, State: "published", SchemaVersion: domain.PublicTransparencyEntryVersion, CreatedAt: l.now()} + l.publicLogEntries[entry.ID] = entry + _, _ = l.appendChainLocked(actor.TenantID, "public_transparency_log_entry.published", "public_transparency_log_entry", entry.ID, actorType(actor), actorID(actor), entryHash, "") + if err := l.persistLocked(ctx); err != nil { + return domain.PublicTransparencyLogEntry{}, err + } + return entry, nil +} + +func (l *Ledger) CreateMarketplaceCollector(ctx context.Context, actor domain.Actor, in CreateMarketplaceCollectorInput) (domain.MarketplaceCollector, error) { + if err := ctx.Err(); err != nil { + return domain.MarketplaceCollector{}, err + } + if err := require(actor, ScopeCollectorAdmin); err != nil { + return domain.MarketplaceCollector{}, err + } + name, provider, version, publisher := strings.TrimSpace(in.Name), strings.TrimSpace(in.Provider), strings.TrimSpace(in.Version), strings.TrimSpace(in.Publisher) + if name == "" || provider == "" || version == "" || publisher == "" || !validDigest(strings.TrimSpace(in.ManifestHash)) { + return domain.MarketplaceCollector{}, ErrValidation + } + l.mu.Lock() + defer l.mu.Unlock() + if in.SignatureID != "" { + sig, ok := l.signatures[strings.TrimSpace(in.SignatureID)] + if !ok || sig.TenantID != actor.TenantID { + return domain.MarketplaceCollector{}, ErrNotFound + } + } + if in.SBOMID != "" { + sbom, ok := l.sboms[strings.TrimSpace(in.SBOMID)] + if !ok || sbom.TenantID != actor.TenantID { + return domain.MarketplaceCollector{}, ErrNotFound + } + } + if in.ScanID != "" { + scan, ok := l.scans[strings.TrimSpace(in.ScanID)] + if !ok || scan.TenantID != actor.TenantID { + return domain.MarketplaceCollector{}, ErrNotFound + } + } + collector := domain.MarketplaceCollector{ + ID: newID("mpc"), + TenantID: actor.TenantID, + Name: name, + Provider: provider, + Version: version, + Publisher: publisher, + ManifestHash: strings.TrimSpace(in.ManifestHash), + SignatureID: strings.TrimSpace(in.SignatureID), + SBOMID: strings.TrimSpace(in.SBOMID), + ScanID: strings.TrimSpace(in.ScanID), + State: "registered", + Limitations: []string{"Registration records package metadata and does not imply marketplace trust or endorsement."}, + SchemaVersion: domain.MarketplaceCollectorVersion, + CreatedAt: l.now(), + } + l.marketplaceCollectors[collector.ID] = collector + _, _ = l.appendChainLocked(actor.TenantID, "marketplace_collector.created", "marketplace_collector", collector.ID, actorType(actor), actorID(actor), collector.ManifestHash, "") + if err := l.persistLocked(ctx); err != nil { + return domain.MarketplaceCollector{}, err + } + return collector, nil +} + +func (l *Ledger) ListMarketplaceCollectors(ctx context.Context, actor domain.Actor) ([]domain.MarketplaceCollector, error) { + if err := ctx.Err(); err != nil { + return nil, err + } + if err := require(actor, ScopeCollectorRead); err != nil { + return nil, err + } + l.mu.Lock() + defer l.mu.Unlock() + out := []domain.MarketplaceCollector{} + for _, collector := range l.marketplaceCollectors { + if collector.TenantID == actor.TenantID { + out = append(out, collector) + } + } + sortMarketplaceCollectors(out) + return out, nil +} + +func (l *Ledger) CreatePDFReportPackage(ctx context.Context, actor domain.Actor, in CreatePDFReportPackageInput) (domain.PDFReportPackage, error) { + if err := ctx.Err(); err != nil { + return domain.PDFReportPackage{}, err + } + if err := require(actor, ScopeReportRead); err != nil { + return domain.PDFReportPackage{}, err + } + reportType, title := strings.TrimSpace(in.ReportType), strings.TrimSpace(in.Title) + productID, releaseID := strings.TrimSpace(in.ProductID), strings.TrimSpace(in.ReleaseID) + if reportType == "" || title == "" || (productID == "" && releaseID == "") { + return domain.PDFReportPackage{}, ErrValidation + } + l.mu.Lock() + defer l.mu.Unlock() + if err := l.ensureScopeLocked(actor.TenantID, productID, "", releaseID); err != nil { + return domain.PDFReportPackage{}, err + } + if err := l.authorizeResourceLocked(actor, ScopeReportRead, resourceRefs{ProductID: productID, ReleaseID: releaseID}); err != nil { + return domain.PDFReportPackage{}, err + } + body := []byte("%PDF-1.4\n% Evydence reproducible report\n1 0 obj << /Type /Catalog >> endobj\n% " + title + "\n% compliance readiness evidence only\n%%EOF\n") + digest := hashBytes(body) + ref, err := l.storePayload(ctx, actor.TenantID, "pdf_report", "application/pdf", digest, body) + if err != nil { + return domain.PDFReportPackage{}, err + } + record := domain.PDFReportPackage{ID: newID("pdf"), TenantID: actor.TenantID, ReportType: reportType, ProductID: productID, ReleaseID: releaseID, Title: title, PayloadRef: ref, PayloadHash: digest, PayloadSize: int64(len(body)), Limitations: []string{"PDF output is reproducible report packaging and does not provide legal compliance or security certification."}, SchemaVersion: domain.PDFReportPackageVersion, CreatedAt: l.now()} + l.pdfReports[record.ID] = record + _, _ = l.appendChainLocked(actor.TenantID, "pdf_report.created", "pdf_report", record.ID, actorType(actor), actorID(actor), digest, "") + if err := l.persistLocked(ctx); err != nil { + return domain.PDFReportPackage{}, err + } + return record, nil +} + +func (l *Ledger) GenerateAnomalyReport(ctx context.Context, actor domain.Actor, in AnomalyReportInput) (domain.AnomalyReport, error) { + if err := ctx.Err(); err != nil { + return domain.AnomalyReport{}, err + } + if err := require(actor, ScopeReportRead); err != nil { + return domain.AnomalyReport{}, err + } + subjectType, subjectID := strings.TrimSpace(in.SubjectType), strings.TrimSpace(in.SubjectID) + if subjectType == "" || subjectID == "" { + return domain.AnomalyReport{}, ErrValidation + } + l.mu.Lock() + defer l.mu.Unlock() + refs, err := l.ensureFutureSubjectLocked(actor.TenantID, subjectType, subjectID) + if err != nil { + return domain.AnomalyReport{}, err + } + if err := l.authorizeResourceLocked(actor, ScopeReportRead, refs); err != nil { + return domain.AnomalyReport{}, err + } + signals := []domain.AnomalySignal{} + if subjectType == "release" { + if l.checkReleaseHasPassedBuildLocked(actor.TenantID, subjectID).Result != "passed" { + signals = append(signals, domain.AnomalySignal{Name: "missing_passed_build", Severity: "medium", Detail: "No passed build run is linked to this release."}) + } + if l.checkReleaseHasBuildAttestationLocked(actor.TenantID, subjectID).Result != "passed" { + signals = append(signals, domain.AnomalySignal{Name: "missing_matching_attestation", Severity: "medium", Detail: "No build attestation subject digest matches a release artifact digest."}) + } + if len(l.unhandledCriticalFindingsLocked(actor.TenantID, subjectID)) > 0 { + signals = append(signals, domain.AnomalySignal{Name: "unhandled_critical_finding", Severity: "high", Detail: "An open critical finding lacks a valid decision or approved exception."}) + } + } + result := "clear" + if len(signals) > 0 { + result = "attention_required" + } + report := domain.AnomalyReport{ID: newID("ano"), TenantID: actor.TenantID, SubjectType: subjectType, SubjectID: subjectID, Result: result, Signals: signals, Assumptions: []string{"Signals are deterministic checks over stored Evydence records."}, Limitations: []string{"This report identifies evidence anomalies only and does not infer malicious behavior or release security."}, SchemaVersion: domain.AnomalyReportVersion, CreatedAt: l.now()} + l.anomalyReports[report.ID] = report + _, _ = l.appendChainLocked(actor.TenantID, "anomaly_report.created", "anomaly_report", report.ID, actorType(actor), actorID(actor), "", "") + if err := l.persistLocked(ctx); err != nil { + return domain.AnomalyReport{}, err + } + return report, nil +} + +func (l *Ledger) CreateSigningOperation(ctx context.Context, actor domain.Actor, in CreateSigningOperationInput) (domain.SigningOperation, error) { + if err := ctx.Err(); err != nil { + return domain.SigningOperation{}, err + } + if err := require(actor, ScopeKeysAdmin); err != nil { + return domain.SigningOperation{}, err + } + providerID, subjectType, subjectID := strings.TrimSpace(in.ProviderID), strings.TrimSpace(in.SubjectType), strings.TrimSpace(in.SubjectID) + signatureValue := strings.TrimSpace(in.ExternalSignature) + if providerID == "" || subjectType == "" || subjectID == "" || !validDigest(strings.TrimSpace(in.PayloadHash)) || signatureValue == "" || len(signatureValue) > 32768 { + return domain.SigningOperation{}, ErrValidation + } + l.mu.Lock() + defer l.mu.Unlock() + provider, ok := l.signingProviders[providerID] + if !ok || provider.TenantID != actor.TenantID { + return domain.SigningOperation{}, ErrNotFound + } + if _, err := l.ensureFutureSubjectLocked(actor.TenantID, subjectType, subjectID); err != nil { + return domain.SigningOperation{}, err + } + checks := []domain.VerifyCheck{ + {Name: "provider_active", Result: "passed"}, + {Name: "payload_hash_valid", Result: "passed"}, + {Name: "external_signature_present", Result: "passed", Detail: "Signature value was supplied by the configured provider path; local cryptographic trust verification is not implied."}, + } + if provider.Status != "active" { + checks[0].Result = "failed" + } + result := "passed" + if checks[0].Result != "passed" { + result = "failed" + } + signature := domain.Signature{ID: newID("sig"), TenantID: actor.TenantID, SubjectType: subjectType, SubjectID: subjectID, KeyID: provider.ID, Algorithm: "external-" + provider.Type, Value: signatureValue, CreatedAt: l.now()} + l.signatures[signature.ID] = signature + op := domain.SigningOperation{ID: newID("sop"), TenantID: actor.TenantID, ProviderID: provider.ID, SubjectType: subjectType, SubjectID: subjectID, PayloadHash: strings.TrimSpace(in.PayloadHash), SignatureRef: signature.ID, Result: result, Checks: checks, SchemaVersion: domain.SigningOperationVersion, CreatedAt: l.now()} + l.signingOperations[op.ID] = op + _, _ = l.appendChainLocked(actor.TenantID, "signing_operation.created", "signing_operation", op.ID, actorType(actor), actorID(actor), op.PayloadHash, signature.ID) + if err := l.persistLocked(ctx); err != nil { + return domain.SigningOperation{}, err + } + if result != "passed" { + return op, ErrVerificationFailed + } + return op, nil +} + +func (l *Ledger) VerifyProviderIdentity(ctx context.Context, actor domain.Actor, in VerifyProviderIdentityInput) (domain.ProviderVerification, error) { + if err := ctx.Err(); err != nil { + return domain.ProviderVerification{}, err + } + if err := require(actor, ScopeIdentityAdmin); err != nil { + return domain.ProviderVerification{}, err + } + providerType, providerID, subject := strings.TrimSpace(in.ProviderType), strings.TrimSpace(in.ProviderID), strings.TrimSpace(in.Subject) + if providerType == "" || providerID == "" || subject == "" { + return domain.ProviderVerification{}, ErrValidation + } + l.mu.Lock() + defer l.mu.Unlock() + checks := []domain.VerifyCheck{} + result := "passed" + switch providerType { + case "oidc", "saml": + provider, ok := l.ssoProviders[providerID] + if !ok || provider.TenantID != actor.TenantID || provider.Type != providerType { + return domain.ProviderVerification{}, ErrNotFound + } + found := false + for _, link := range l.identityLinks { + if link.TenantID == actor.TenantID && link.ProviderID == provider.ID && link.Subject == subject && link.Verified { + found = true + break + } + } + if found { + checks = append(checks, domain.VerifyCheck{Name: "verified_identity_link", Result: "passed"}) + } else { + result = "failed" + checks = append(checks, domain.VerifyCheck{Name: "verified_identity_link", Result: "failed"}) + } + default: + return domain.ProviderVerification{}, ErrValidation + } + record := domain.ProviderVerification{ID: newID("pvr"), TenantID: actor.TenantID, ProviderType: providerType, ProviderID: providerID, Subject: subject, Result: result, Checks: checks, Limitations: []string{"Verification is limited to stored provider/link metadata; live provider token verification is outside this record."}, SchemaVersion: domain.ProviderVerificationVersion, CreatedAt: l.now()} + l.providerVerifications[record.ID] = record + _, _ = l.appendChainLocked(actor.TenantID, "provider_identity.verified", "provider_identity", record.ID, actorType(actor), actorID(actor), "", "") + if err := l.persistLocked(ctx); err != nil { + return domain.ProviderVerification{}, err + } + if result != "passed" { + return record, ErrVerificationFailed + } + return record, nil +} + +func (l *Ledger) ensureFutureSubjectLocked(tenantID, subjectType, subjectID string) (resourceRefs, error) { + switch subjectType { + case "tenant": + if subjectID != tenantID { + return resourceRefs{}, ErrNotFound + } + return resourceRefs{}, nil + case "product": + product, ok := l.products[subjectID] + if !ok || product.TenantID != tenantID { + return resourceRefs{}, ErrNotFound + } + return resourceRefs{ProductID: product.ID}, nil + case "release": + release, ok := l.releases[subjectID] + if !ok || release.TenantID != tenantID { + return resourceRefs{}, ErrNotFound + } + return resourceRefs{ProductID: release.ProductID, ReleaseID: release.ID}, nil + case "evidence": + item, ok := l.evidence[subjectID] + if !ok || item.TenantID != tenantID { + return resourceRefs{}, ErrNotFound + } + return refsForEvidence(item), nil + case "build": + build, ok := l.buildRuns[subjectID] + if !ok || build.TenantID != tenantID { + return resourceRefs{}, ErrNotFound + } + return resourceRefs{ProjectID: build.ProjectID, ReleaseID: build.ReleaseID}, nil + case "customer_package": + pkg, ok := l.customerPackages[subjectID] + if !ok || pkg.TenantID != tenantID { + return resourceRefs{}, ErrNotFound + } + return resourceRefs{ProductID: pkg.ProductID, ReleaseID: pkg.ReleaseID, CustomerPackageID: pkg.ID}, nil + default: + return resourceRefs{}, ErrValidation + } +} + +func (l *Ledger) evidenceIDsForQuestionLocked(tenantID string, question domain.QuestionnaireQuestion, productID, releaseID string) []string { + if question.ControlID != "" { + ids := []string{} + for _, link := range l.controlLinks { + if link.TenantID == tenantID && link.ControlID == question.ControlID && scopeMatches(link.ProductID, productID) && scopeMatches(link.ReleaseID, releaseID) { + if link.SubjectType == "evidence" { + ids = append(ids, link.SubjectID) + } + } + } + return sortedStrings(ids) + } + return l.evidenceIDsForRefsLocked(tenantID, resourceRefs{ProductID: strings.TrimSpace(productID), ReleaseID: strings.TrimSpace(releaseID)}, strings.TrimSpace(question.EvidenceType)) +} + +func (l *Ledger) evidenceIDsForRefsLocked(tenantID string, refs resourceRefs, evidenceType string) []string { + ids := []string{} + for _, item := range l.evidence { + if item.TenantID != tenantID { + continue + } + if evidenceType != "" && item.Type != evidenceType { + continue + } + if evidenceMatchesRefs(item, refs) { + ids = append(ids, item.ID) + } + } + return sortedStrings(ids) +} + +func evidenceMatchesRefs(item domain.EvidenceItem, refs resourceRefs) bool { + if refs.ProductID != "" && item.ProductID != refs.ProductID { + return false + } + if refs.ProjectID != "" && item.ProjectID != refs.ProjectID { + return false + } + if refs.ReleaseID != "" && item.ReleaseID != refs.ReleaseID { + return false + } + return true +} + +func sortMarketplaceCollectors(items []domain.MarketplaceCollector) { + for i := 1; i < len(items); i++ { + for j := i; j > 0 && items[j-1].ID > items[j].ID; j-- { + items[j-1], items[j] = items[j], items[j-1] + } + } +} diff --git a/internal/app/future_extensions_test.go b/internal/app/future_extensions_test.go new file mode 100644 index 0000000..bbabe34 --- /dev/null +++ b/internal/app/future_extensions_test.go @@ -0,0 +1,213 @@ +package app + +import ( + "context" + "errors" + "strings" + "testing" + + "github.com/aatuh/evydence/internal/domain" +) + +func TestFutureExtensionsAreEvidenceBackedAndTenantScoped(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, release, artifact := setupReleaseRiskFixture(t, ledger) + evidence, err := ledger.CreateEvidence(ctx, actor, CreateEvidenceInput{ + ProductID: release.ProductID, + ReleaseID: release.ID, + Type: "security_review", + Title: "Release review", + PayloadHash: sampleDigest("review"), + }) + if err != nil { + t.Fatalf("evidence: %v", err) + } + template, err := ledger.CreateQuestionnaireTemplate(ctx, actor, CreateQuestionnaireTemplateInput{Name: "customer", Version: "1", Questions: []domain.QuestionnaireQuestion{{ID: "q1", Prompt: "Is review evidence available?", EvidenceType: "security_review"}}}) + if err != nil { + t.Fatalf("template: %v", err) + } + + summary, err := ledger.CreateEvidenceSummary(ctx, actor, CreateEvidenceSummaryInput{SubjectType: "release", SubjectID: release.ID, EvidenceIDs: []string{evidence.ID}}) + if err != nil { + t.Fatalf("summary: %v", err) + } + if !strings.Contains(summary.Summary, "Release review") || len(summary.Citations) != 1 || summary.Citations[0].EvidenceID != evidence.ID { + t.Fatalf("summary is not evidence-cited: %#v", summary) + } + if strings.Contains(strings.ToLower(summary.Summary), "compliant") { + t.Fatalf("summary used compliance conclusion language: %s", summary.Summary) + } + + draft, err := ledger.CreateQuestionnaireDraft(ctx, actor, CreateQuestionnaireDraftInput{TemplateID: template.ID, ProductID: release.ProductID, ReleaseID: release.ID}) + if err != nil { + t.Fatalf("questionnaire draft: %v", err) + } + if len(draft.Responses) != 1 || len(draft.Responses[0].EvidenceIDs) != 1 || draft.Responses[0].Answer == "" { + t.Fatalf("draft responses = %#v", draft.Responses) + } + + graph, err := ledger.CreateGraphSnapshot(ctx, actor, CreateGraphSnapshotInput{ProductID: release.ProductID, ReleaseID: release.ID}) + if err != nil { + t.Fatalf("graph: %v", err) + } + if len(graph.Nodes) == 0 || len(graph.Edges) == 0 { + t.Fatalf("graph should expose release adjacency: %#v", graph) + } + + pdf, err := ledger.CreatePDFReportPackage(ctx, actor, CreatePDFReportPackageInput{ReportType: "release_readiness", ProductID: release.ProductID, ReleaseID: release.ID, Title: "Readiness"}) + if err != nil { + t.Fatalf("pdf: %v", err) + } + if !strings.HasPrefix(pdf.PayloadHash, "sha256:") || pdf.PayloadSize == 0 || len(pdf.Limitations) == 0 { + t.Fatalf("pdf package = %#v", pdf) + } + + anomaly, err := ledger.GenerateAnomalyReport(ctx, actor, AnomalyReportInput{SubjectType: "release", SubjectID: release.ID}) + if err != nil { + t.Fatalf("anomaly report: %v", err) + } + if anomaly.Result == "" || len(anomaly.Limitations) == 0 { + t.Fatalf("anomaly report = %#v", anomaly) + } + + _, _, otherSecret, err := ledger.BootstrapTenant(ctx, "Other", "admin", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap other: %v", err) + } + other, err := ledger.Authenticate(ctx, otherSecret) + if err != nil { + t.Fatalf("auth other: %v", err) + } + if _, err := ledger.CreateEvidenceSummary(ctx, other, CreateEvidenceSummaryInput{SubjectType: "release", SubjectID: release.ID, EvidenceIDs: []string{evidence.ID}}); !errors.Is(err, ErrNotFound) { + t.Fatalf("cross-tenant summary err=%v, want not found", err) + } + if _, err := ledger.CreateQuestionnaireDraft(ctx, other, CreateQuestionnaireDraftInput{TemplateID: template.ID, ProductID: release.ProductID, ReleaseID: release.ID}); !errors.Is(err, ErrNotFound) { + t.Fatalf("cross-tenant draft err=%v, want not found", err) + } + if _, err := ledger.CreatePDFReportPackage(ctx, other, CreatePDFReportPackageInput{ReportType: "release_readiness", ProductID: release.ProductID, ReleaseID: release.ID, Title: "Bad"}); !errors.Is(err, ErrNotFound) { + t.Fatalf("cross-tenant pdf err=%v, want not found", err) + } + _ = artifact +} + +func TestFutureOperationalExtensionsAndPartialTrustClosures(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + _, _, secret, err := ledger.BootstrapTenant(ctx, "Tenant", "admin", []string{"*", ScopeInstanceAdmin}) + if err != nil { + t.Fatalf("bootstrap: %v", err) + } + actor, err := ledger.Authenticate(ctx, secret) + if err != nil { + t.Fatalf("auth: %v", err) + } + product, err := ledger.CreateProduct(ctx, actor, "API", "api") + if err != nil { + t.Fatalf("product: %v", err) + } + release, err := ledger.CreateRelease(ctx, actor, product.ID, "1") + if err != nil { + t.Fatalf("release: %v", err) + } + if _, err := ledger.CreateSaaSEditionProfile(ctx, actor, CreateSaaSEditionProfileInput{Name: "hosted-eu", Region: "eu", AdminTenantID: actor.TenantID, IsolationModel: "shared-control-plane"}); err != nil { + t.Fatalf("saas profile: %v", err) + } + + batch, err := ledger.CreateMerkleBatch(ctx, actor, CreateMerkleBatchInput{}) + if err != nil { + t.Fatalf("merkle batch: %v", err) + } + log, err := ledger.CreatePublicTransparencyLog(ctx, actor, CreatePublicTransparencyLogInput{Name: "public-test", Endpoint: "https://transparency.example.test", PublicKey: "pub"}) + if err != nil { + t.Fatalf("public log: %v", err) + } + checkpoint, err := ledger.CreateTransparencyCheckpoint(ctx, actor, CreateTransparencyCheckpointInput{BatchID: batch.ID, Provider: "internal", ExternalID: "ts-1"}) + if err != nil { + t.Fatalf("checkpoint: %v", err) + } + entry, err := ledger.PublishPublicTransparencyLogEntry(ctx, actor, PublishPublicTransparencyLogEntryInput{LogID: log.ID, CheckpointID: checkpoint.ID, ExternalID: "entry-1"}) + if err != nil { + t.Fatalf("public log entry: %v", err) + } + if entry.MerkleBatchID != batch.ID || entry.EntryHash == "" { + t.Fatalf("public log entry = %#v", entry) + } + + provider, err := ledger.CreateSigningProvider(ctx, actor, CreateSigningProviderInput{Name: "kms", Type: "aws_kms", KeyRef: "arn:aws:kms:example", Encrypted: true}) + if err != nil { + t.Fatalf("signing provider: %v", err) + } + op, err := ledger.CreateSigningOperation(ctx, actor, CreateSigningOperationInput{ProviderID: provider.ID, SubjectType: "release", SubjectID: release.ID, PayloadHash: sampleDigest("payload"), ExternalSignature: "sig"}) + if err != nil { + t.Fatalf("signing operation: %v", err) + } + if op.Result != "passed" || op.SignatureRef == "" { + t.Fatalf("signing operation = %#v", op) + } + + oidcProvider, err := ledger.CreateSSOProvider(ctx, actor, CreateSSOProviderInput{Name: "OIDC", Type: "oidc", Issuer: "https://idp.example.test", ClientID: "client"}) + if err != nil { + t.Fatalf("sso provider: %v", err) + } + org, err := ledger.CreateOrganization(ctx, actor, CreateOrganizationInput{Name: "Example", Slug: "example"}) + if err != nil { + t.Fatalf("org: %v", err) + } + user, err := ledger.CreateUser(ctx, actor, CreateUserInput{OrganizationID: org.ID, Email: "user@example.test", DisplayName: "User"}) + if err != nil { + t.Fatalf("user: %v", err) + } + if _, err := ledger.LinkSSOIdentity(ctx, actor, LinkSSOIdentityInput{UserID: user.ID, ProviderID: oidcProvider.ID, Subject: "sub-1", Email: user.Email, Verified: true}); err != nil { + t.Fatalf("identity link: %v", err) + } + verification, err := ledger.VerifyProviderIdentity(ctx, actor, VerifyProviderIdentityInput{ProviderType: "oidc", ProviderID: oidcProvider.ID, Subject: "sub-1"}) + if err != nil { + t.Fatalf("provider verification: %v", err) + } + if verification.Result != "passed" { + t.Fatalf("provider verification = %#v", verification) + } + + marketplace, err := ledger.CreateMarketplaceCollector(ctx, actor, CreateMarketplaceCollectorInput{Name: "scanner", Provider: "scannerco", Version: "1.0.0", Publisher: "scannerco", ManifestHash: sampleDigest("collector")}) + if err != nil { + t.Fatalf("marketplace collector: %v", err) + } + listed, err := ledger.ListMarketplaceCollectors(ctx, actor) + if err != nil { + t.Fatalf("list marketplace: %v", err) + } + if len(listed) != 1 || listed[0].ID != marketplace.ID { + t.Fatalf("marketplace list = %#v", listed) + } + + policy, err := ledger.CreateObjectRetentionPolicy(ctx, actor, CreateObjectRetentionPolicyInput{Name: "objects", ObjectPrefix: "tenants/" + actor.TenantID + "/", Mode: "compliance", RetentionDays: 90}) + if err != nil { + t.Fatalf("retention policy: %v", err) + } + verified, err := ledger.VerifyObjectRetentionPolicy(ctx, actor, policy.ID) + if err != nil { + t.Fatalf("verify retention: %v", err) + } + if verified.Status != "verified" || verified.VerificationHash == "" { + t.Fatalf("verified retention = %#v", verified) + } + + _, _, otherSecret, err := ledger.BootstrapTenant(ctx, "Other", "admin", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap other: %v", err) + } + other, err := ledger.Authenticate(ctx, otherSecret) + if err != nil { + t.Fatalf("auth other: %v", err) + } + if _, err := ledger.PublishPublicTransparencyLogEntry(ctx, other, PublishPublicTransparencyLogEntryInput{LogID: log.ID, CheckpointID: checkpoint.ID, ExternalID: "bad"}); !errors.Is(err, ErrNotFound) { + t.Fatalf("cross tenant transparency err=%v, want not found", err) + } + if _, err := ledger.CreateSigningOperation(ctx, other, CreateSigningOperationInput{ProviderID: provider.ID, SubjectType: "release", SubjectID: release.ID, PayloadHash: sampleDigest("payload"), ExternalSignature: "sig"}); !errors.Is(err, ErrNotFound) { + t.Fatalf("cross tenant signing operation err=%v, want not found", err) + } + if _, err := ledger.CreateSaaSEditionProfile(ctx, other, CreateSaaSEditionProfileInput{Name: "bad", Region: "eu", AdminTenantID: other.TenantID, IsolationModel: "shared-control-plane"}); !errors.Is(err, ErrForbidden) { + t.Fatalf("non-instance saas profile err=%v, want forbidden", err) + } +} diff --git a/internal/app/integrity_runtime.go b/internal/app/integrity_runtime.go index 3209480..5da9673 100644 --- a/internal/app/integrity_runtime.go +++ b/internal/app/integrity_runtime.go @@ -331,6 +331,27 @@ func (l *Ledger) VerifyObjectRetentionPolicy(ctx context.Context, actor domain.A now := l.now() policy.Status = "verified" policy.VerifiedAt = &now + verificationHash, err := canonicalAnyHash(struct { + ID string `json:"id"` + TenantID string `json:"tenant_id"` + ObjectPrefix string `json:"object_prefix"` + Mode string `json:"mode"` + RetentionDays int `json:"retention_days"` + Status string `json:"status"` + VerifiedAt string `json:"verified_at"` + }{ + ID: policy.ID, + TenantID: policy.TenantID, + ObjectPrefix: policy.ObjectPrefix, + Mode: policy.Mode, + RetentionDays: policy.RetentionDays, + Status: policy.Status, + VerifiedAt: now.Format(time.RFC3339Nano), + }) + if err != nil { + return domain.ObjectRetentionPolicy{}, err + } + policy.VerificationHash = verificationHash l.retentionPolicies[policy.ID] = policy _, _ = l.appendChainLocked(actor.TenantID, "object_retention_policy.verified", "object_retention_policy", policy.ID, actorType(actor), actorID(actor), "", "") if err := l.persistLocked(ctx); err != nil { diff --git a/internal/app/ledger.go b/internal/app/ledger.go index d09d430..be37a38 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -78,82 +78,93 @@ type Ledger struct { objects ObjectStore outbox Outbox - tenants map[string]domain.Tenant - organizations map[string]domain.Organization - users map[string]domain.HumanUser - roleBindings map[string]domain.RoleBinding - ssoProviders map[string]domain.SSOProvider - identityLinks map[string]domain.UserIdentityLink - ssoSessions map[string]domain.SSOSession - apiKeys map[string]domain.APIKey - collectors map[string]domain.Collector - collectorReleases map[string]domain.CollectorRelease - products map[string]domain.Product - projects map[string]domain.Project - releases map[string]domain.Release - artifacts map[string]domain.Artifact - buildRuns map[string]domain.BuildRun - attestations map[string]domain.BuildAttestation - evidence map[string]domain.EvidenceItem - lifecycle map[string]domain.EvidenceLifecycleEvent - candidates map[string]domain.ReleaseCandidate - images map[string]domain.ContainerImage - artifactSigs map[string]domain.ArtifactSignature - repositories map[string]domain.SourceRepository - commits map[string]domain.SourceCommit - branches map[string]domain.SourceBranch - pullRequests map[string]domain.PullRequest - environments map[string]domain.DeploymentEnvironment - deployments map[string]domain.DeploymentEvent - incidents map[string]domain.Incident - timeline map[string]domain.IncidentTimelineEvent - tasks map[string]domain.RemediationTask - securityScans map[string]domain.SecurityScan - manualDocs map[string]domain.ManualSecurityDocument - sbomDiffs map[string]domain.SBOMDiff - depChanges map[string]domain.DependencyChange - vulnWorkflow map[string]domain.VulnerabilityWorkflowRecord - contractDiffs map[string]domain.ContractDiff - customPolicies map[string]domain.CustomPolicy - customPolicyEvals map[string]domain.CustomPolicyEvaluation - waivers map[string]domain.Waiver - approvals map[string]domain.ApprovalRecord - redactions map[string]domain.RedactionProfile - customerPackages map[string]domain.CustomerSecurityPackage - htmlReports map[string]domain.HTMLReportPackage - reportTemplates map[string]domain.CustomReportTemplate - renderedReports map[string]domain.RenderedCustomReport - evidenceBundles map[string]domain.EvidenceBundle - bundleImports map[string]domain.EvidenceBundleImport - dsseTrustRoots map[string]domain.DSSETrustRoot - cosignVerifs map[string]domain.CosignVerification - signingProviders map[string]domain.SigningProvider - merkleBatches map[string]domain.MerkleBatch - transparency map[string]domain.TransparencyCheckpoint - retentionPolicies map[string]domain.ObjectRetentionPolicy - backupManifests map[string]domain.BackupManifest - legalHolds map[string]domain.LegalHold - retentionOverrides map[string]domain.RetentionOverride - portalAccess map[string]domain.CustomerPortalAccess - questionTemplates map[string]domain.QuestionnaireTemplate - questionPackages map[string]domain.QuestionnairePackage - commercialCollectors map[string]domain.CommercialCollectorDefinition - frameworks map[string]domain.ControlFramework - controls map[string]domain.SecurityControl - controlLinks map[string]domain.ControlEvidence - sboms map[string]domain.SBOM - scans map[string]domain.VulnerabilityScan - vexDocuments map[string]domain.VEXDocument - decisions map[string]domain.VulnerabilityDecision - contracts map[string]domain.OpenAPIContract - policies map[string]domain.PolicyEvaluation - exceptions map[string]domain.Exception - bundles map[string]domain.ReleaseBundle - signingKeys map[string]domain.SigningKey - signatures map[string]domain.Signature - verifications map[string]domain.VerificationResult - chain map[string][]domain.AuditChainEntry - idempotency map[string]IdempotencyRecord + tenants map[string]domain.Tenant + organizations map[string]domain.Organization + users map[string]domain.HumanUser + roleBindings map[string]domain.RoleBinding + ssoProviders map[string]domain.SSOProvider + identityLinks map[string]domain.UserIdentityLink + ssoSessions map[string]domain.SSOSession + apiKeys map[string]domain.APIKey + collectors map[string]domain.Collector + collectorReleases map[string]domain.CollectorRelease + products map[string]domain.Product + projects map[string]domain.Project + releases map[string]domain.Release + artifacts map[string]domain.Artifact + buildRuns map[string]domain.BuildRun + attestations map[string]domain.BuildAttestation + evidence map[string]domain.EvidenceItem + lifecycle map[string]domain.EvidenceLifecycleEvent + candidates map[string]domain.ReleaseCandidate + images map[string]domain.ContainerImage + artifactSigs map[string]domain.ArtifactSignature + repositories map[string]domain.SourceRepository + commits map[string]domain.SourceCommit + branches map[string]domain.SourceBranch + pullRequests map[string]domain.PullRequest + environments map[string]domain.DeploymentEnvironment + deployments map[string]domain.DeploymentEvent + incidents map[string]domain.Incident + timeline map[string]domain.IncidentTimelineEvent + tasks map[string]domain.RemediationTask + securityScans map[string]domain.SecurityScan + manualDocs map[string]domain.ManualSecurityDocument + sbomDiffs map[string]domain.SBOMDiff + depChanges map[string]domain.DependencyChange + vulnWorkflow map[string]domain.VulnerabilityWorkflowRecord + contractDiffs map[string]domain.ContractDiff + customPolicies map[string]domain.CustomPolicy + customPolicyEvals map[string]domain.CustomPolicyEvaluation + waivers map[string]domain.Waiver + approvals map[string]domain.ApprovalRecord + redactions map[string]domain.RedactionProfile + customerPackages map[string]domain.CustomerSecurityPackage + htmlReports map[string]domain.HTMLReportPackage + reportTemplates map[string]domain.CustomReportTemplate + renderedReports map[string]domain.RenderedCustomReport + evidenceBundles map[string]domain.EvidenceBundle + bundleImports map[string]domain.EvidenceBundleImport + dsseTrustRoots map[string]domain.DSSETrustRoot + cosignVerifs map[string]domain.CosignVerification + signingProviders map[string]domain.SigningProvider + merkleBatches map[string]domain.MerkleBatch + transparency map[string]domain.TransparencyCheckpoint + retentionPolicies map[string]domain.ObjectRetentionPolicy + backupManifests map[string]domain.BackupManifest + legalHolds map[string]domain.LegalHold + retentionOverrides map[string]domain.RetentionOverride + portalAccess map[string]domain.CustomerPortalAccess + questionTemplates map[string]domain.QuestionnaireTemplate + questionPackages map[string]domain.QuestionnairePackage + commercialCollectors map[string]domain.CommercialCollectorDefinition + evidenceSummaries map[string]domain.EvidenceSummary + questionDrafts map[string]domain.QuestionnaireDraft + graphSnapshots map[string]domain.EvidenceGraphSnapshot + saasProfiles map[string]domain.SaaSEditionProfile + publicLogs map[string]domain.PublicTransparencyLog + publicLogEntries map[string]domain.PublicTransparencyLogEntry + marketplaceCollectors map[string]domain.MarketplaceCollector + pdfReports map[string]domain.PDFReportPackage + anomalyReports map[string]domain.AnomalyReport + providerVerifications map[string]domain.ProviderVerification + signingOperations map[string]domain.SigningOperation + frameworks map[string]domain.ControlFramework + controls map[string]domain.SecurityControl + controlLinks map[string]domain.ControlEvidence + sboms map[string]domain.SBOM + scans map[string]domain.VulnerabilityScan + vexDocuments map[string]domain.VEXDocument + decisions map[string]domain.VulnerabilityDecision + contracts map[string]domain.OpenAPIContract + policies map[string]domain.PolicyEvaluation + exceptions map[string]domain.Exception + bundles map[string]domain.ReleaseBundle + signingKeys map[string]domain.SigningKey + signatures map[string]domain.Signature + verifications map[string]domain.VerificationResult + chain map[string][]domain.AuditChainEntry + idempotency map[string]IdempotencyRecord } func NewLedger(cfg Config) *Ledger { @@ -174,87 +185,98 @@ func NewLedgerWithError(cfg Config) (*Ledger, error) { pepper = "local-dev-pepper-change-me" } ledger := &Ledger{ - pepper: []byte(pepper), - now: now, - store: cfg.Store, - objects: cfg.ObjectStore, - outbox: cfg.Outbox, - tenants: map[string]domain.Tenant{}, - organizations: map[string]domain.Organization{}, - users: map[string]domain.HumanUser{}, - roleBindings: map[string]domain.RoleBinding{}, - ssoProviders: map[string]domain.SSOProvider{}, - identityLinks: map[string]domain.UserIdentityLink{}, - ssoSessions: map[string]domain.SSOSession{}, - apiKeys: map[string]domain.APIKey{}, - collectors: map[string]domain.Collector{}, - collectorReleases: map[string]domain.CollectorRelease{}, - products: map[string]domain.Product{}, - projects: map[string]domain.Project{}, - releases: map[string]domain.Release{}, - artifacts: map[string]domain.Artifact{}, - buildRuns: map[string]domain.BuildRun{}, - attestations: map[string]domain.BuildAttestation{}, - evidence: map[string]domain.EvidenceItem{}, - lifecycle: map[string]domain.EvidenceLifecycleEvent{}, - candidates: map[string]domain.ReleaseCandidate{}, - images: map[string]domain.ContainerImage{}, - artifactSigs: map[string]domain.ArtifactSignature{}, - repositories: map[string]domain.SourceRepository{}, - commits: map[string]domain.SourceCommit{}, - branches: map[string]domain.SourceBranch{}, - pullRequests: map[string]domain.PullRequest{}, - environments: map[string]domain.DeploymentEnvironment{}, - deployments: map[string]domain.DeploymentEvent{}, - incidents: map[string]domain.Incident{}, - timeline: map[string]domain.IncidentTimelineEvent{}, - tasks: map[string]domain.RemediationTask{}, - securityScans: map[string]domain.SecurityScan{}, - manualDocs: map[string]domain.ManualSecurityDocument{}, - sbomDiffs: map[string]domain.SBOMDiff{}, - depChanges: map[string]domain.DependencyChange{}, - vulnWorkflow: map[string]domain.VulnerabilityWorkflowRecord{}, - contractDiffs: map[string]domain.ContractDiff{}, - customPolicies: map[string]domain.CustomPolicy{}, - customPolicyEvals: map[string]domain.CustomPolicyEvaluation{}, - waivers: map[string]domain.Waiver{}, - approvals: map[string]domain.ApprovalRecord{}, - redactions: map[string]domain.RedactionProfile{}, - customerPackages: map[string]domain.CustomerSecurityPackage{}, - htmlReports: map[string]domain.HTMLReportPackage{}, - reportTemplates: map[string]domain.CustomReportTemplate{}, - renderedReports: map[string]domain.RenderedCustomReport{}, - evidenceBundles: map[string]domain.EvidenceBundle{}, - bundleImports: map[string]domain.EvidenceBundleImport{}, - dsseTrustRoots: map[string]domain.DSSETrustRoot{}, - cosignVerifs: map[string]domain.CosignVerification{}, - signingProviders: map[string]domain.SigningProvider{}, - merkleBatches: map[string]domain.MerkleBatch{}, - transparency: map[string]domain.TransparencyCheckpoint{}, - retentionPolicies: map[string]domain.ObjectRetentionPolicy{}, - backupManifests: map[string]domain.BackupManifest{}, - legalHolds: map[string]domain.LegalHold{}, - retentionOverrides: map[string]domain.RetentionOverride{}, - portalAccess: map[string]domain.CustomerPortalAccess{}, - questionTemplates: map[string]domain.QuestionnaireTemplate{}, - questionPackages: map[string]domain.QuestionnairePackage{}, - commercialCollectors: map[string]domain.CommercialCollectorDefinition{}, - frameworks: map[string]domain.ControlFramework{}, - controls: map[string]domain.SecurityControl{}, - controlLinks: map[string]domain.ControlEvidence{}, - sboms: map[string]domain.SBOM{}, - scans: map[string]domain.VulnerabilityScan{}, - vexDocuments: map[string]domain.VEXDocument{}, - decisions: map[string]domain.VulnerabilityDecision{}, - contracts: map[string]domain.OpenAPIContract{}, - policies: map[string]domain.PolicyEvaluation{}, - exceptions: map[string]domain.Exception{}, - bundles: map[string]domain.ReleaseBundle{}, - signingKeys: map[string]domain.SigningKey{}, - signatures: map[string]domain.Signature{}, - verifications: map[string]domain.VerificationResult{}, - chain: map[string][]domain.AuditChainEntry{}, - idempotency: map[string]IdempotencyRecord{}, + pepper: []byte(pepper), + now: now, + store: cfg.Store, + objects: cfg.ObjectStore, + outbox: cfg.Outbox, + tenants: map[string]domain.Tenant{}, + organizations: map[string]domain.Organization{}, + users: map[string]domain.HumanUser{}, + roleBindings: map[string]domain.RoleBinding{}, + ssoProviders: map[string]domain.SSOProvider{}, + identityLinks: map[string]domain.UserIdentityLink{}, + ssoSessions: map[string]domain.SSOSession{}, + apiKeys: map[string]domain.APIKey{}, + collectors: map[string]domain.Collector{}, + collectorReleases: map[string]domain.CollectorRelease{}, + products: map[string]domain.Product{}, + projects: map[string]domain.Project{}, + releases: map[string]domain.Release{}, + artifacts: map[string]domain.Artifact{}, + buildRuns: map[string]domain.BuildRun{}, + attestations: map[string]domain.BuildAttestation{}, + evidence: map[string]domain.EvidenceItem{}, + lifecycle: map[string]domain.EvidenceLifecycleEvent{}, + candidates: map[string]domain.ReleaseCandidate{}, + images: map[string]domain.ContainerImage{}, + artifactSigs: map[string]domain.ArtifactSignature{}, + repositories: map[string]domain.SourceRepository{}, + commits: map[string]domain.SourceCommit{}, + branches: map[string]domain.SourceBranch{}, + pullRequests: map[string]domain.PullRequest{}, + environments: map[string]domain.DeploymentEnvironment{}, + deployments: map[string]domain.DeploymentEvent{}, + incidents: map[string]domain.Incident{}, + timeline: map[string]domain.IncidentTimelineEvent{}, + tasks: map[string]domain.RemediationTask{}, + securityScans: map[string]domain.SecurityScan{}, + manualDocs: map[string]domain.ManualSecurityDocument{}, + sbomDiffs: map[string]domain.SBOMDiff{}, + depChanges: map[string]domain.DependencyChange{}, + vulnWorkflow: map[string]domain.VulnerabilityWorkflowRecord{}, + contractDiffs: map[string]domain.ContractDiff{}, + customPolicies: map[string]domain.CustomPolicy{}, + customPolicyEvals: map[string]domain.CustomPolicyEvaluation{}, + waivers: map[string]domain.Waiver{}, + approvals: map[string]domain.ApprovalRecord{}, + redactions: map[string]domain.RedactionProfile{}, + customerPackages: map[string]domain.CustomerSecurityPackage{}, + htmlReports: map[string]domain.HTMLReportPackage{}, + reportTemplates: map[string]domain.CustomReportTemplate{}, + renderedReports: map[string]domain.RenderedCustomReport{}, + evidenceBundles: map[string]domain.EvidenceBundle{}, + bundleImports: map[string]domain.EvidenceBundleImport{}, + dsseTrustRoots: map[string]domain.DSSETrustRoot{}, + cosignVerifs: map[string]domain.CosignVerification{}, + signingProviders: map[string]domain.SigningProvider{}, + merkleBatches: map[string]domain.MerkleBatch{}, + transparency: map[string]domain.TransparencyCheckpoint{}, + retentionPolicies: map[string]domain.ObjectRetentionPolicy{}, + backupManifests: map[string]domain.BackupManifest{}, + legalHolds: map[string]domain.LegalHold{}, + retentionOverrides: map[string]domain.RetentionOverride{}, + portalAccess: map[string]domain.CustomerPortalAccess{}, + questionTemplates: map[string]domain.QuestionnaireTemplate{}, + questionPackages: map[string]domain.QuestionnairePackage{}, + commercialCollectors: map[string]domain.CommercialCollectorDefinition{}, + evidenceSummaries: map[string]domain.EvidenceSummary{}, + questionDrafts: map[string]domain.QuestionnaireDraft{}, + graphSnapshots: map[string]domain.EvidenceGraphSnapshot{}, + saasProfiles: map[string]domain.SaaSEditionProfile{}, + publicLogs: map[string]domain.PublicTransparencyLog{}, + publicLogEntries: map[string]domain.PublicTransparencyLogEntry{}, + marketplaceCollectors: map[string]domain.MarketplaceCollector{}, + pdfReports: map[string]domain.PDFReportPackage{}, + anomalyReports: map[string]domain.AnomalyReport{}, + providerVerifications: map[string]domain.ProviderVerification{}, + signingOperations: map[string]domain.SigningOperation{}, + frameworks: map[string]domain.ControlFramework{}, + controls: map[string]domain.SecurityControl{}, + controlLinks: map[string]domain.ControlEvidence{}, + sboms: map[string]domain.SBOM{}, + scans: map[string]domain.VulnerabilityScan{}, + vexDocuments: map[string]domain.VEXDocument{}, + decisions: map[string]domain.VulnerabilityDecision{}, + contracts: map[string]domain.OpenAPIContract{}, + policies: map[string]domain.PolicyEvaluation{}, + exceptions: map[string]domain.Exception{}, + bundles: map[string]domain.ReleaseBundle{}, + signingKeys: map[string]domain.SigningKey{}, + signatures: map[string]domain.Signature{}, + verifications: map[string]domain.VerificationResult{}, + chain: map[string][]domain.AuditChainEntry{}, + idempotency: map[string]IdempotencyRecord{}, } if ledger.outbox == nil { ledger.outbox = nopOutbox{} diff --git a/internal/app/ports.go b/internal/app/ports.go index 4643721..496453d 100644 --- a/internal/app/ports.go +++ b/internal/app/ports.go @@ -85,6 +85,17 @@ type PersistedState struct { QuestionnaireTemplates map[string]domain.QuestionnaireTemplate `json:"questionnaire_templates"` QuestionnairePackages map[string]domain.QuestionnairePackage `json:"questionnaire_packages"` CommercialCollectors map[string]domain.CommercialCollectorDefinition `json:"commercial_collectors"` + EvidenceSummaries map[string]domain.EvidenceSummary `json:"evidence_summaries"` + QuestionnaireDrafts map[string]domain.QuestionnaireDraft `json:"questionnaire_drafts"` + GraphSnapshots map[string]domain.EvidenceGraphSnapshot `json:"graph_snapshots"` + SaaSProfiles map[string]domain.SaaSEditionProfile `json:"saas_profiles"` + PublicTransparencyLogs map[string]domain.PublicTransparencyLog `json:"public_transparency_logs"` + PublicTransparencyItems map[string]domain.PublicTransparencyLogEntry `json:"public_transparency_items"` + MarketplaceCollectors map[string]domain.MarketplaceCollector `json:"marketplace_collectors"` + PDFReports map[string]domain.PDFReportPackage `json:"pdf_reports"` + AnomalyReports map[string]domain.AnomalyReport `json:"anomaly_reports"` + ProviderVerifications map[string]domain.ProviderVerification `json:"provider_verifications"` + SigningOperations map[string]domain.SigningOperation `json:"signing_operations"` ControlFrameworks map[string]domain.ControlFramework `json:"control_frameworks"` SecurityControls map[string]domain.SecurityControl `json:"security_controls"` ControlEvidence map[string]domain.ControlEvidence `json:"control_evidence"` diff --git a/internal/app/state.go b/internal/app/state.go index a207ac8..a0181ae 100644 --- a/internal/app/state.go +++ b/internal/app/state.go @@ -89,6 +89,17 @@ func (l *Ledger) snapshotLocked() PersistedState { QuestionnaireTemplates: l.questionTemplates, QuestionnairePackages: l.questionPackages, CommercialCollectors: l.commercialCollectors, + EvidenceSummaries: l.evidenceSummaries, + QuestionnaireDrafts: l.questionDrafts, + GraphSnapshots: l.graphSnapshots, + SaaSProfiles: l.saasProfiles, + PublicTransparencyLogs: l.publicLogs, + PublicTransparencyItems: l.publicLogEntries, + MarketplaceCollectors: l.marketplaceCollectors, + PDFReports: l.pdfReports, + AnomalyReports: l.anomalyReports, + ProviderVerifications: l.providerVerifications, + SigningOperations: l.signingOperations, ControlFrameworks: l.frameworks, SecurityControls: l.controls, ControlEvidence: l.controlLinks, @@ -232,6 +243,17 @@ func (l *Ledger) applyState(state PersistedState) { l.questionTemplates = state.QuestionnaireTemplates l.questionPackages = state.QuestionnairePackages l.commercialCollectors = state.CommercialCollectors + l.evidenceSummaries = state.EvidenceSummaries + l.questionDrafts = state.QuestionnaireDrafts + l.graphSnapshots = state.GraphSnapshots + l.saasProfiles = state.SaaSProfiles + l.publicLogs = state.PublicTransparencyLogs + l.publicLogEntries = state.PublicTransparencyItems + l.marketplaceCollectors = state.MarketplaceCollectors + l.pdfReports = state.PDFReports + l.anomalyReports = state.AnomalyReports + l.providerVerifications = state.ProviderVerifications + l.signingOperations = state.SigningOperations l.frameworks = state.ControlFrameworks l.controls = state.SecurityControls l.controlLinks = state.ControlEvidence @@ -498,6 +520,39 @@ func normalizeState(state PersistedState) PersistedState { if state.CommercialCollectors == nil { state.CommercialCollectors = map[string]domain.CommercialCollectorDefinition{} } + if state.EvidenceSummaries == nil { + state.EvidenceSummaries = map[string]domain.EvidenceSummary{} + } + if state.QuestionnaireDrafts == nil { + state.QuestionnaireDrafts = map[string]domain.QuestionnaireDraft{} + } + if state.GraphSnapshots == nil { + state.GraphSnapshots = map[string]domain.EvidenceGraphSnapshot{} + } + if state.SaaSProfiles == nil { + state.SaaSProfiles = map[string]domain.SaaSEditionProfile{} + } + if state.PublicTransparencyLogs == nil { + state.PublicTransparencyLogs = map[string]domain.PublicTransparencyLog{} + } + if state.PublicTransparencyItems == nil { + state.PublicTransparencyItems = map[string]domain.PublicTransparencyLogEntry{} + } + if state.MarketplaceCollectors == nil { + state.MarketplaceCollectors = map[string]domain.MarketplaceCollector{} + } + if state.PDFReports == nil { + state.PDFReports = map[string]domain.PDFReportPackage{} + } + if state.AnomalyReports == nil { + state.AnomalyReports = map[string]domain.AnomalyReport{} + } + if state.ProviderVerifications == nil { + state.ProviderVerifications = map[string]domain.ProviderVerification{} + } + if state.SigningOperations == nil { + state.SigningOperations = map[string]domain.SigningOperation{} + } if state.ControlFrameworks == nil { state.ControlFrameworks = map[string]domain.ControlFramework{} } diff --git a/internal/domain/domain.go b/internal/domain/domain.go index 4b76e98..38634d2 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -65,6 +65,17 @@ const ( QuestionnaireTemplateVersion = "questionnaire-template.v1.0.0" QuestionnairePackageVersion = "questionnaire-package.v1.0.0" CommercialCollectorVersion = "commercial-collector.v1.0.0" + EvidenceSummaryVersion = "evidence-summary.v1.0.0" + QuestionnaireDraftVersion = "questionnaire-draft.v1.0.0" + EvidenceGraphSnapshotVersion = "evidence-graph-snapshot.v1.0.0" + SaaSEditionProfileVersion = "saas-edition-profile.v1.0.0" + PublicTransparencyLogVersion = "public-transparency-log.v1.0.0" + PublicTransparencyEntryVersion = "public-transparency-entry.v1.0.0" + MarketplaceCollectorVersion = "marketplace-collector.v1.0.0" + PDFReportPackageVersion = "pdf-report-package.v1.0.0" + AnomalyReportVersion = "anomaly-report.v1.0.0" + ProviderVerificationVersion = "provider-verification.v1.0.0" + SigningOperationVersion = "signing-operation.v1.0.0" ) type Actor struct { @@ -675,16 +686,17 @@ type TransparencyCheckpoint struct { } type ObjectRetentionPolicy struct { - ID string `json:"id"` - TenantID string `json:"tenant_id"` - Name string `json:"name"` - ObjectPrefix string `json:"object_prefix"` - Mode string `json:"mode"` - RetentionDays int `json:"retention_days"` - Status string `json:"status"` - VerifiedAt *time.Time `json:"verified_at,omitempty"` - SchemaVersion string `json:"schema_version"` - CreatedAt time.Time `json:"created_at"` + ID string `json:"id"` + TenantID string `json:"tenant_id"` + Name string `json:"name"` + ObjectPrefix string `json:"object_prefix"` + Mode string `json:"mode"` + RetentionDays int `json:"retention_days"` + Status string `json:"status"` + VerifiedAt *time.Time `json:"verified_at,omitempty"` + VerificationHash string `json:"verification_hash,omitempty"` + SchemaVersion string `json:"schema_version"` + CreatedAt time.Time `json:"created_at"` } type BackupManifest struct { @@ -808,6 +820,181 @@ type CommercialCollectorDefinition struct { CreatedAt time.Time `json:"created_at"` } +type EvidenceCitation struct { + EvidenceID string `json:"evidence_id"` + Type string `json:"type"` + Title string `json:"title"` + CanonicalHash string `json:"canonical_hash"` +} + +type EvidenceSummary struct { + ID string `json:"id"` + TenantID string `json:"tenant_id"` + SubjectType string `json:"subject_type"` + SubjectID string `json:"subject_id"` + EvidenceIDs []string `json:"evidence_ids"` + Summary string `json:"summary"` + Citations []EvidenceCitation `json:"citations"` + Assumptions []string `json:"assumptions"` + Limitations []string `json:"limitations"` + SchemaVersion string `json:"schema_version"` + CreatedAt time.Time `json:"created_at"` +} + +type QuestionnaireDraft struct { + ID string `json:"id"` + TenantID string `json:"tenant_id"` + TemplateID string `json:"template_id"` + ProductID string `json:"product_id,omitempty"` + ReleaseID string `json:"release_id,omitempty"` + Responses []QuestionnaireResponse `json:"responses"` + ManifestHash string `json:"manifest_hash"` + Limitations []string `json:"limitations"` + SchemaVersion string `json:"schema_version"` + CreatedAt time.Time `json:"created_at"` +} + +type GraphNode struct { + ID string `json:"id"` + Type string `json:"type"` + Label string `json:"label"` +} + +type GraphEdge struct { + From string `json:"from"` + To string `json:"to"` + Relationship string `json:"relationship"` +} + +type EvidenceGraphSnapshot struct { + ID string `json:"id"` + TenantID string `json:"tenant_id"` + ProductID string `json:"product_id,omitempty"` + ReleaseID string `json:"release_id,omitempty"` + Nodes []GraphNode `json:"nodes"` + Edges []GraphEdge `json:"edges"` + GraphHash string `json:"graph_hash"` + Limitations []string `json:"limitations"` + SchemaVersion string `json:"schema_version"` + CreatedAt time.Time `json:"created_at"` +} + +type SaaSEditionProfile struct { + ID string `json:"id"` + TenantID string `json:"tenant_id"` + Name string `json:"name"` + Region string `json:"region"` + AdminTenantID string `json:"admin_tenant_id"` + IsolationModel string `json:"isolation_model"` + Status string `json:"status"` + ConfigHash string `json:"config_hash"` + Limitations []string `json:"limitations"` + SchemaVersion string `json:"schema_version"` + CreatedAt time.Time `json:"created_at"` +} + +type PublicTransparencyLog struct { + ID string `json:"id"` + TenantID string `json:"tenant_id"` + Name string `json:"name"` + Endpoint string `json:"endpoint"` + PublicKey string `json:"public_key"` + State string `json:"state"` + SchemaVersion string `json:"schema_version"` + CreatedAt time.Time `json:"created_at"` +} + +type PublicTransparencyLogEntry struct { + ID string `json:"id"` + TenantID string `json:"tenant_id"` + LogID string `json:"log_id"` + CheckpointID string `json:"checkpoint_id"` + MerkleBatchID string `json:"merkle_batch_id"` + ExternalID string `json:"external_id"` + EntryHash string `json:"entry_hash"` + State string `json:"state"` + SchemaVersion string `json:"schema_version"` + CreatedAt time.Time `json:"created_at"` +} + +type MarketplaceCollector struct { + ID string `json:"id"` + TenantID string `json:"tenant_id"` + Name string `json:"name"` + Provider string `json:"provider"` + Version string `json:"version"` + Publisher string `json:"publisher"` + ManifestHash string `json:"manifest_hash"` + SignatureID string `json:"signature_id,omitempty"` + SBOMID string `json:"sbom_id,omitempty"` + ScanID string `json:"scan_id,omitempty"` + State string `json:"state"` + Limitations []string `json:"limitations,omitempty"` + SchemaVersion string `json:"schema_version"` + CreatedAt time.Time `json:"created_at"` +} + +type PDFReportPackage struct { + ID string `json:"id"` + TenantID string `json:"tenant_id"` + ReportType string `json:"report_type"` + ProductID string `json:"product_id,omitempty"` + ReleaseID string `json:"release_id,omitempty"` + Title string `json:"title"` + PayloadRef string `json:"payload_ref,omitempty"` + PayloadHash string `json:"payload_hash"` + PayloadSize int64 `json:"payload_size"` + Limitations []string `json:"limitations"` + SchemaVersion string `json:"schema_version"` + CreatedAt time.Time `json:"created_at"` +} + +type AnomalySignal struct { + Name string `json:"name"` + Severity string `json:"severity"` + Detail string `json:"detail"` +} + +type AnomalyReport struct { + ID string `json:"id"` + TenantID string `json:"tenant_id"` + SubjectType string `json:"subject_type"` + SubjectID string `json:"subject_id"` + Result string `json:"result"` + Signals []AnomalySignal `json:"signals,omitempty"` + Assumptions []string `json:"assumptions"` + Limitations []string `json:"limitations"` + SchemaVersion string `json:"schema_version"` + CreatedAt time.Time `json:"created_at"` +} + +type ProviderVerification struct { + ID string `json:"id"` + TenantID string `json:"tenant_id"` + ProviderType string `json:"provider_type"` + ProviderID string `json:"provider_id"` + Subject string `json:"subject"` + Result string `json:"result"` + Checks []VerifyCheck `json:"checks"` + Limitations []string `json:"limitations"` + SchemaVersion string `json:"schema_version"` + CreatedAt time.Time `json:"created_at"` +} + +type SigningOperation struct { + ID string `json:"id"` + TenantID string `json:"tenant_id"` + ProviderID string `json:"provider_id"` + SubjectType string `json:"subject_type"` + SubjectID string `json:"subject_id"` + PayloadHash string `json:"payload_hash"` + SignatureRef string `json:"signature_ref,omitempty"` + Result string `json:"result"` + Checks []VerifyCheck `json:"checks"` + SchemaVersion string `json:"schema_version"` + CreatedAt time.Time `json:"created_at"` +} + type SBOM struct { ID string `json:"id"` TenantID string `json:"tenant_id"` diff --git a/migrations/20260528000900_future_extensions_and_partial_closures.down.sql b/migrations/20260528000900_future_extensions_and_partial_closures.down.sql new file mode 100644 index 0000000..fdebaf1 --- /dev/null +++ b/migrations/20260528000900_future_extensions_and_partial_closures.down.sql @@ -0,0 +1,14 @@ +DROP TABLE IF EXISTS signing_operations; +DROP TABLE IF EXISTS provider_verifications; +DROP TABLE IF EXISTS anomaly_reports; +DROP TABLE IF EXISTS pdf_report_packages; +DROP TABLE IF EXISTS marketplace_collectors; +DROP TABLE IF EXISTS public_transparency_log_entries; +DROP TABLE IF EXISTS public_transparency_logs; +DROP TABLE IF EXISTS saas_edition_profiles; +DROP TABLE IF EXISTS evidence_graph_snapshots; +DROP TABLE IF EXISTS questionnaire_drafts; +DROP TABLE IF EXISTS evidence_summaries; + +ALTER TABLE object_retention_policies + DROP COLUMN IF EXISTS verification_hash; diff --git a/migrations/20260528000900_future_extensions_and_partial_closures.up.sql b/migrations/20260528000900_future_extensions_and_partial_closures.up.sql new file mode 100644 index 0000000..d2c3143 --- /dev/null +++ b/migrations/20260528000900_future_extensions_and_partial_closures.up.sql @@ -0,0 +1,174 @@ +ALTER TABLE object_retention_policies + ADD COLUMN IF NOT EXISTS verification_hash text; + +CREATE TABLE IF NOT EXISTS evidence_summaries ( + id text PRIMARY KEY, + tenant_id text NOT NULL, + subject_type text NOT NULL, + subject_id text NOT NULL, + evidence_ids text[] NOT NULL DEFAULT '{}', + summary text NOT NULL, + citations jsonb NOT NULL, + assumptions text[] NOT NULL DEFAULT '{}', + limitations text[] NOT NULL DEFAULT '{}', + schema_version text NOT NULL, + created_at timestamptz NOT NULL +); + +CREATE TABLE IF NOT EXISTS questionnaire_drafts ( + id text PRIMARY KEY, + tenant_id text NOT NULL, + template_id text NOT NULL, + product_id text, + release_id text, + responses jsonb NOT NULL, + manifest_hash text NOT NULL, + limitations text[] NOT NULL DEFAULT '{}', + schema_version text NOT NULL, + created_at timestamptz NOT NULL +); + +CREATE TABLE IF NOT EXISTS evidence_graph_snapshots ( + id text PRIMARY KEY, + tenant_id text NOT NULL, + product_id text, + release_id text, + nodes jsonb NOT NULL, + edges jsonb NOT NULL, + graph_hash text NOT NULL, + limitations text[] NOT NULL DEFAULT '{}', + schema_version text NOT NULL, + created_at timestamptz NOT NULL +); + +CREATE TABLE IF NOT EXISTS saas_edition_profiles ( + id text PRIMARY KEY, + tenant_id text NOT NULL, + name text NOT NULL, + region text NOT NULL, + admin_tenant_id text NOT NULL, + isolation_model text NOT NULL, + status text NOT NULL, + config_hash text NOT NULL, + limitations text[] NOT NULL DEFAULT '{}', + schema_version text NOT NULL, + created_at timestamptz NOT NULL +); + +CREATE TABLE IF NOT EXISTS public_transparency_logs ( + id text PRIMARY KEY, + tenant_id text NOT NULL, + name text NOT NULL, + endpoint text NOT NULL, + public_key text NOT NULL, + state text NOT NULL, + schema_version text NOT NULL, + created_at timestamptz NOT NULL +); + +CREATE TABLE IF NOT EXISTS public_transparency_log_entries ( + id text PRIMARY KEY, + tenant_id text NOT NULL, + log_id text NOT NULL, + checkpoint_id text NOT NULL, + merkle_batch_id text NOT NULL, + external_id text NOT NULL, + entry_hash text NOT NULL, + state text NOT NULL, + schema_version text NOT NULL, + created_at timestamptz NOT NULL +); + +CREATE TABLE IF NOT EXISTS marketplace_collectors ( + id text PRIMARY KEY, + tenant_id text NOT NULL, + name text NOT NULL, + provider text NOT NULL, + version text NOT NULL, + publisher text NOT NULL, + manifest_hash text NOT NULL, + signature_id text, + sbom_id text, + scan_id text, + state text NOT NULL, + limitations text[] NOT NULL DEFAULT '{}', + schema_version text NOT NULL, + created_at timestamptz NOT NULL, + UNIQUE (tenant_id, provider, name, version) +); + +CREATE TABLE IF NOT EXISTS pdf_report_packages ( + id text PRIMARY KEY, + tenant_id text NOT NULL, + report_type text NOT NULL, + product_id text, + release_id text, + title text NOT NULL, + payload_ref text, + payload_hash text NOT NULL, + payload_size bigint NOT NULL, + limitations text[] NOT NULL DEFAULT '{}', + schema_version text NOT NULL, + created_at timestamptz NOT NULL +); + +CREATE TABLE IF NOT EXISTS anomaly_reports ( + id text PRIMARY KEY, + tenant_id text NOT NULL, + subject_type text NOT NULL, + subject_id text NOT NULL, + result text NOT NULL, + signals jsonb NOT NULL, + assumptions text[] NOT NULL DEFAULT '{}', + limitations text[] NOT NULL DEFAULT '{}', + schema_version text NOT NULL, + created_at timestamptz NOT NULL +); + +CREATE TABLE IF NOT EXISTS provider_verifications ( + id text PRIMARY KEY, + tenant_id text NOT NULL, + provider_type text NOT NULL, + provider_id text NOT NULL, + subject text NOT NULL, + result text NOT NULL, + checks jsonb NOT NULL, + limitations text[] NOT NULL DEFAULT '{}', + schema_version text NOT NULL, + created_at timestamptz NOT NULL +); + +CREATE TABLE IF NOT EXISTS signing_operations ( + id text PRIMARY KEY, + tenant_id text NOT NULL, + provider_id text NOT NULL, + subject_type text NOT NULL, + subject_id text NOT NULL, + payload_hash text NOT NULL, + signature_ref text, + result text NOT NULL, + checks jsonb NOT NULL, + schema_version text NOT NULL, + created_at timestamptz NOT NULL +); + +CREATE INDEX IF NOT EXISTS evidence_summaries_tenant_subject_idx + ON evidence_summaries (tenant_id, subject_type, subject_id, created_at); +CREATE INDEX IF NOT EXISTS questionnaire_drafts_tenant_release_idx + ON questionnaire_drafts (tenant_id, release_id, created_at); +CREATE INDEX IF NOT EXISTS evidence_graph_snapshots_tenant_release_idx + ON evidence_graph_snapshots (tenant_id, release_id, created_at); +CREATE INDEX IF NOT EXISTS saas_edition_profiles_tenant_status_idx + ON saas_edition_profiles (tenant_id, status, created_at); +CREATE INDEX IF NOT EXISTS public_transparency_log_entries_tenant_log_idx + ON public_transparency_log_entries (tenant_id, log_id, created_at); +CREATE INDEX IF NOT EXISTS marketplace_collectors_tenant_provider_idx + ON marketplace_collectors (tenant_id, provider, created_at); +CREATE INDEX IF NOT EXISTS pdf_report_packages_tenant_release_idx + ON pdf_report_packages (tenant_id, release_id, created_at); +CREATE INDEX IF NOT EXISTS anomaly_reports_tenant_subject_idx + ON anomaly_reports (tenant_id, subject_type, subject_id, created_at); +CREATE INDEX IF NOT EXISTS provider_verifications_tenant_provider_idx + ON provider_verifications (tenant_id, provider_type, provider_id, created_at); +CREATE INDEX IF NOT EXISTS signing_operations_tenant_subject_idx + ON signing_operations (tenant_id, subject_type, subject_id, created_at); diff --git a/openapi.yaml b/openapi.yaml index 4e18edd..025367d 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{},"payload_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source":{"type":"string"},"subject_refs":{"items":{"type":"string"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"type":"object"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"api_key_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"},"user_count":{"type":"integer"}},"required":["tenant_count","resource_counts"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Instance admin snapshot envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"operationId":"registerArtifact","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"operationId":"generateBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"operationId":"verifyBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"operationId":"createBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"operationId":"getBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"operationId":"uploadGitHubSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"operationId":"uploadGitLabSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"operationId":"listProducts","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"operationId":"createProduct","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"operationId":"createProject","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"operationId":"ready","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"operationId":"createRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"operationId":"getRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"operationId":"approveRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"operationId":"freezeRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"operationId":"controlCoverageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"operationId":"craReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/release-readiness":{"get":{"operationId":"releaseReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"operationId":"uploadSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"operationId":"getSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"operationId":"createSSOProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"operationId":"uploadVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"operationId":"uploadCycloneDXVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"operationId":"getVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"operationId":"uploadVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"operationId":"getVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{},"payload_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source":{"type":"string"},"subject_refs":{"items":{"type":"string"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"type":"object"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"api_key_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"},"user_count":{"type":"integer"}},"required":["tenant_count","resource_counts"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Instance admin snapshot envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"operationId":"registerArtifact","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"operationId":"generateBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"operationId":"verifyBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"operationId":"createBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"operationId":"getBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"operationId":"uploadGitHubSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"operationId":"uploadGitLabSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"operationId":"createGraphSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"operationId":"listProducts","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"operationId":"createProduct","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"operationId":"createProject","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"operationId":"verifyProviderIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"operationId":"ready","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"operationId":"createRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"operationId":"getRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"operationId":"approveRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"operationId":"freezeRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"operationId":"controlCoverageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"operationId":"craReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"operationId":"releaseReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"operationId":"uploadSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"operationId":"getSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"operationId":"createSSOProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"operationId":"uploadVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"operationId":"uploadCycloneDXVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"operationId":"getVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"operationId":"uploadVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"operationId":"getVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From 131b7838c7773e424afb549265c1b258c7057463 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 16:04:40 +0300 Subject: [PATCH 017/287] chore: fix future extension import formatting --- internal/app/future_extensions.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/app/future_extensions.go b/internal/app/future_extensions.go index 180faea..51dcb7f 100644 --- a/internal/app/future_extensions.go +++ b/internal/app/future_extensions.go @@ -3,9 +3,9 @@ package app import ( "context" "strings" -) -import "github.com/aatuh/evydence/internal/domain" + "github.com/aatuh/evydence/internal/domain" +) type CreateEvidenceSummaryInput struct { SubjectType string From c61baf55145d4e11ab6646161e1436a8fbc30286 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 16:07:14 +0300 Subject: [PATCH 018/287] fix: make migration recording idempotent --- internal/adapters/postgres/migrate.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/adapters/postgres/migrate.go b/internal/adapters/postgres/migrate.go index c4af6f6..be29dd6 100644 --- a/internal/adapters/postgres/migrate.go +++ b/internal/adapters/postgres/migrate.go @@ -55,7 +55,7 @@ func (s *Store) ApplyMigrations(ctx context.Context, dir string) (int, error) { _ = tx.Rollback(ctx) return applied, fmt.Errorf("apply migration %s: %w", version, err) } - if _, err := tx.Exec(ctx, `INSERT INTO schema_migrations (version) VALUES ($1)`, version); err != nil { + if _, err := tx.Exec(ctx, `INSERT INTO schema_migrations (version) VALUES ($1) ON CONFLICT (version) DO NOTHING`, version); err != nil { _ = tx.Rollback(ctx) return applied, fmt.Errorf("record migration %s: %w", version, err) } From d5dd8a5311f2f80cef61f4ea57f8d2501c2726b4 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 16:07:22 +0300 Subject: [PATCH 019/287] test: cover app read list and lifecycle gaps --- internal/app/coverage_gaps_test.go | 224 +++++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 internal/app/coverage_gaps_test.go diff --git a/internal/app/coverage_gaps_test.go b/internal/app/coverage_gaps_test.go new file mode 100644 index 0000000..9b88995 --- /dev/null +++ b/internal/app/coverage_gaps_test.go @@ -0,0 +1,224 @@ +package app + +import ( + "context" + "errors" + "testing" + "time" + + "github.com/aatuh/evydence/internal/domain" +) + +func TestAppReadListLifecycleAndReportGaps(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, release, artifact := setupReleaseRiskFixture(t, ledger) + + if !ledger.HasTenants() { + t.Fatal("bootstrap fixture should create a tenant") + } + if _, err := ledger.ApproveRelease(ctx, actor, release.ID); !errors.Is(err, ErrConflict) { + t.Fatalf("approve draft release err=%v, want conflict", err) + } + frozen, err := ledger.FreezeRelease(ctx, actor, release.ID) + if err != nil { + t.Fatalf("freeze release: %v", err) + } + if frozen.State != "frozen" || frozen.FrozenAt == nil { + t.Fatalf("frozen release = %#v", frozen) + } + approved, err := ledger.ApproveRelease(ctx, actor, release.ID) + if err != nil { + t.Fatalf("approve release: %v", err) + } + if approved.State != "approved" || approved.ApprovedAt == nil { + t.Fatalf("approved release = %#v", approved) + } + if _, err := ledger.FreezeRelease(ctx, actor, release.ID); !errors.Is(err, ErrConflict) { + t.Fatalf("freeze approved release err=%v, want conflict", err) + } + + original, err := ledger.CreateEvidence(ctx, actor, CreateEvidenceInput{ProductID: release.ProductID, ReleaseID: release.ID, Type: "security_review", Title: "Original", PayloadHash: sampleDigest("original")}) + if err != nil { + t.Fatalf("original evidence: %v", err) + } + replacement, err := ledger.CreateEvidence(ctx, actor, CreateEvidenceInput{ProductID: release.ProductID, Type: "security_review", Title: "Replacement", PayloadHash: sampleDigest("replacement")}) + if err != nil { + t.Fatalf("replacement evidence: %v", err) + } + linked, err := ledger.LinkEvidence(ctx, actor, replacement.ID, "release", release.ID) + if err != nil { + t.Fatalf("link evidence: %v", err) + } + if linked.ReleaseID != release.ID { + t.Fatalf("linked release_id=%q want %q", linked.ReleaseID, release.ID) + } + superseded, err := ledger.SupersedeEvidence(ctx, actor, original.ID, replacement.ID, "newer review") + if err != nil { + t.Fatalf("supersede evidence: %v", err) + } + if superseded.SupersededBy != replacement.ID { + t.Fatalf("superseded evidence = %#v", superseded) + } + if _, err := ledger.SupersedeEvidence(ctx, actor, original.ID, replacement.ID, "again"); !errors.Is(err, ErrConflict) { + t.Fatalf("repeat supersede err=%v, want conflict", err) + } + listed, err := ledger.ListEvidence(ctx, actor, release.ID, "security_review") + if err != nil { + t.Fatalf("list evidence: %v", err) + } + if len(listed) != 2 { + t.Fatalf("security_review evidence count=%d want 2: %#v", len(listed), listed) + } + + sbom, err := ledger.UploadSBOM(ctx, actor, release.ID, artifact.ID, []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","components":[{"name":"api","purl":"pkg:oci/api"}]}`)) + if err != nil { + t.Fatalf("sbom: %v", err) + } + if got, err := ledger.GetSBOM(ctx, actor, sbom.ID); err != nil || got.ID != sbom.ID { + t.Fatalf("get sbom=%#v err=%v", got, err) + } + scan, err := ledger.UploadVulnerabilityScan(ctx, actor, []byte(`{"scanner":"grype","target_ref":"pkg:oci/api","release_id":"`+release.ID+`","findings":[]}`)) + if err != nil { + t.Fatalf("scan: %v", err) + } + if got, err := ledger.GetVulnerabilityScan(ctx, actor, scan.ID); err != nil || got.ID != scan.ID { + t.Fatalf("get scan=%#v err=%v", got, err) + } + contract, err := ledger.UploadOpenAPIContract(ctx, actor, release.ProductID, release.ID, "v1", []byte(`{"openapi":"3.1.0","info":{"title":"API","version":"1"},"paths":{"/health":{"get":{"responses":{"200":{"description":"ok"}}}}}}`)) + if err != nil { + t.Fatalf("openapi: %v", err) + } + if got, err := ledger.GetOpenAPIContract(ctx, actor, contract.ID); err != nil || got.ID != contract.ID { + t.Fatalf("get contract=%#v err=%v", got, err) + } + vex, err := ledger.UploadVEX(ctx, actor, release.ID, artifact.ID, []byte(`{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex","author":"security@example.test","timestamp":"2026-05-28T12:00:00Z","version":1,"statements":[{"vulnerability":{"name":"CVE-2026-0000"},"products":[{"@id":"pkg:oci/api"}],"status":"fixed","justification":"fixed","impact_statement":"fixed","action_statement":"none"}]}`)) + if err != nil { + t.Fatalf("vex: %v", err) + } + if got, err := ledger.GetVEXDocument(ctx, actor, vex.ID); err != nil || got.ID != vex.ID { + t.Fatalf("get vex=%#v err=%v", got, err) + } + + bundle, err := ledger.CreateReleaseBundle(ctx, actor, release.ID) + if err != nil { + t.Fatalf("bundle: %v", err) + } + if got, err := ledger.GetReleaseBundle(ctx, actor, bundle.ID); err != nil || got.ID != bundle.ID { + t.Fatalf("get bundle=%#v err=%v", got, err) + } + report, err := ledger.MissingEvidenceReport(ctx, actor, release.ID) + if err != nil { + t.Fatalf("missing evidence report: %v", err) + } + if report["report_type"] != "missing_evidence" || report["release_id"] != release.ID { + t.Fatalf("missing evidence report = %#v", report) + } + + keysBefore, err := ledger.ListSigningKeys(ctx, actor) + if err != nil || len(keysBefore) == 0 { + t.Fatalf("signing keys before=%#v err=%v", keysBefore, err) + } + rotated, err := ledger.RotateSigningKey(ctx, actor, "scheduled rotation") + if err != nil { + t.Fatalf("rotate signing key: %v", err) + } + if rotated.Private != nil || rotated.Status != "active" { + t.Fatalf("public rotated key leaked private material: %#v", rotated) + } + revoked, err := ledger.RevokeSigningKey(ctx, actor, keysBefore[0].ID, "retire old key") + if err != nil { + t.Fatalf("revoke signing key: %v", err) + } + if revoked.Status != "revoked" || revoked.RevokedAt == nil { + t.Fatalf("revoked key = %#v", revoked) + } +} + +func TestAppListAndScopeHelperGaps(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, release, artifact := setupReleaseRiskFixture(t, ledger) + + collector, _, _, err := ledger.CreateCollector(ctx, actor, CreateCollectorInput{Name: "gha", Type: "github_actions", Version: "1.0.0"}) + if err != nil { + t.Fatalf("collector: %v", err) + } + collectors, err := ledger.ListCollectors(ctx, actor) + if err != nil || len(collectors) != 1 || collectors[0].ID != collector.ID { + t.Fatalf("collectors=%#v err=%v", collectors, err) + } + + framework, err := ledger.CreateControlFramework(ctx, actor, CreateControlFrameworkInput{Name: "Framework", Slug: "fw", Version: "1"}) + if err != nil { + t.Fatalf("framework: %v", err) + } + listedFrameworks, err := ledger.ListControlFrameworks(ctx, actor) + if err != nil || len(listedFrameworks) != 1 || listedFrameworks[0].ID != framework.ID { + t.Fatalf("frameworks=%#v err=%v", listedFrameworks, err) + } + control, err := ledger.CreateSecurityControl(ctx, actor, CreateSecurityControlInput{ + FrameworkID: framework.ID, + Code: "BUILD", + Title: "Build evidence", + Objective: "Build evidence exists.", + EvidenceRequirements: []domain.ControlEvidenceRequirement{{ + Type: "build", + Required: true, + }}, + }) + if err != nil { + t.Fatalf("control: %v", err) + } + buildProject, err := ledger.CreateProject(ctx, actor, release.ProductID, "control-build") + if err != nil { + t.Fatalf("project: %v", err) + } + build, err := ledger.CreateBuildRun(ctx, actor, CreateBuildRunInput{ + ProjectID: buildProject.ID, + ReleaseID: release.ID, + Provider: "generic_ci", + CommitSHA: "0123456789abcdef0123456789abcdef01234567", + Status: "passed", + StartedAt: fixedNow(), + Outputs: []domain.BuildOutput{{ArtifactID: artifact.ID, Digest: artifact.Digest}}, + }) + if err != nil { + t.Fatalf("build: %v", err) + } + link, err := ledger.LinkControlEvidence(ctx, actor, control.ID, LinkControlEvidenceInput{EvidenceType: "build", SubjectType: "build", SubjectID: build.ID, ProductID: release.ProductID, ReleaseID: release.ID, Confidence: "medium"}) + if err != nil { + t.Fatalf("link control evidence: %v", err) + } + links, err := ledger.ListControlEvidence(ctx, actor, control.ID, release.ProductID, release.ID) + if err != nil || len(links) != 1 || links[0].ID != link.ID { + t.Fatalf("control links=%#v err=%v", links, err) + } + if _, err := ledger.LinkControlEvidence(ctx, actor, control.ID, LinkControlEvidenceInput{EvidenceType: "build", SubjectType: "missing", SubjectID: "missing", ProductID: release.ProductID, ReleaseID: release.ID, Confidence: "unsupported"}); !errors.Is(err, ErrNotFound) { + t.Fatalf("missing subject err=%v, want not found", err) + } + + ex, err := ledger.CreateException(ctx, actor, CreateExceptionInput{ReleaseID: release.ID, ControlID: control.ID, Reason: "temporary control waiver", Owner: "security", ExpiresAt: fixedNow().Add(time.Hour)}) + if err != nil { + t.Fatalf("exception: %v", err) + } + exceptions, err := ledger.ListExceptions(ctx, actor, release.ID) + if err != nil || len(exceptions) != 1 || exceptions[0].ID != ex.ID { + t.Fatalf("exceptions=%#v err=%v", exceptions, err) + } + + if !(domain.Actor{Scopes: []string{"*"}}).HasScope("anything") { + t.Fatal("wildcard actor should satisfy arbitrary scope") + } + if (domain.Actor{Scopes: []string{"evidence:read"}}).HasScope("evidence:write") { + t.Fatal("read-only actor should not satisfy write scope") + } + for _, err := range []error{ErrValidation, ErrUnauthorized, ErrForbidden, ErrNotFound, ErrConflict, ErrIdempotencyConflict, ErrVerificationFailed, errors.New("raw sql detail")} { + if ProblemCode(err) == "" || StatusCode(err) == 0 || SafeErrorDetail(err) == "" { + t.Fatalf("problem mapping incomplete for %v", err) + } + } + if !IsValidation(ErrValidation) || IsValidation(ErrForbidden) { + t.Fatal("validation helper returned unexpected result") + } +} From 1c80ac5ce7c19400cac5e5909b3fc7faeabb2ea8 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 16:07:24 +0300 Subject: [PATCH 020/287] test: cover HTTP route gaps --- internal/adapters/httpapi/router_test.go | 170 +++++++++++++++++++++++ 1 file changed, 170 insertions(+) diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 7ef7e36..9c29d39 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -734,6 +734,162 @@ func TestEnterprisePortalRetentionAndCommercialCollectorHTTPFlow(t *testing.T) { getJSON(t, server, sessionSecret, "/v1/admin/instance", http.StatusUnauthorized) } +func TestFutureExtensionAndReadAdminHTTPGaps(t *testing.T) { + ledger := app.NewLedger(app.Config{APIKeyPepper: "test"}) + _, _, secret, err := ledger.BootstrapTenant(t.Context(), "Tenant", "admin", []string{"*", app.ScopeInstanceAdmin}) + if err != nil { + t.Fatalf("bootstrap: %v", err) + } + server, err := NewServer(ledger) + if err != nil { + t.Fatalf("server: %v", err) + } + productBody := postJSON(t, server, secret, "/v1/products", "future-product", map[string]any{"name": "Future Product", "slug": "future-product"}, http.StatusCreated) + productID := dataField(t, productBody, "id") + getJSON(t, server, secret, "/v1/products", http.StatusOK) + postJSON(t, server, secret, "/v1/projects", "future-project", map[string]any{"product_id": productID, "name": "api"}, http.StatusCreated) + releaseBody := postJSON(t, server, secret, "/v1/releases", "future-release", map[string]any{"product_id": productID, "version": "9.0.0"}, http.StatusCreated) + releaseID := dataField(t, releaseBody, "id") + getJSON(t, server, secret, "/v1/releases/"+releaseID, http.StatusOK) + postJSON(t, server, secret, "/v1/releases/"+releaseID+"/freeze", "future-freeze", map[string]any{}, http.StatusOK) + postJSON(t, server, secret, "/v1/releases/"+releaseID+"/approve", "future-approve", map[string]any{}, http.StatusOK) + + digest := "sha256:ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb" + artifactBody := postJSON(t, server, secret, "/v1/artifacts", "future-artifact", map[string]any{"name": "api.tar.gz", "media_type": "application/gzip", "digest": digest, "size": 42}, http.StatusCreated) + artifactID := dataField(t, artifactBody, "id") + evidenceBody := postJSON(t, server, secret, "/v1/evidence", "future-evidence", map[string]any{"product_id": productID, "release_id": releaseID, "type": "security_review", "title": "Review", "payload_hash": digest, "subject_refs": []map[string]any{{"type": "artifact", "id": artifactID}}}, http.StatusCreated) + evidenceID := dataField(t, evidenceBody, "id") + replacementBody := postJSON(t, server, secret, "/v1/evidence", "future-evidence-replacement", map[string]any{"product_id": productID, "type": "security_review", "title": "Review replacement", "payload_hash": "sha256:2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"}, http.StatusCreated) + replacementID := dataField(t, replacementBody, "id") + getJSON(t, server, secret, "/v1/evidence?release_id="+releaseID+"&type=security_review", http.StatusOK) + postJSON(t, server, secret, "/v1/evidence/"+replacementID+"/link", "future-link", map[string]any{"target_type": "release", "target_id": releaseID}, http.StatusCreated) + postJSON(t, server, secret, "/v1/evidence/"+evidenceID+"/supersede", "future-supersede", map[string]any{"replacement_evidence_id": replacementID, "reason": "updated review"}, http.StatusCreated) + summary := postJSON(t, server, secret, "/v1/evidence-summaries", "future-summary", map[string]any{"subject_type": "release", "subject_id": releaseID, "evidence_ids": []string{evidenceID, replacementID}}, http.StatusCreated) + if !strings.Contains(summary, `"citations"`) { + t.Fatalf("summary missing citations: %s", summary) + } + graph := postJSON(t, server, secret, "/v1/evidence-graph-snapshots", "future-graph", map[string]any{"product_id": productID, "release_id": releaseID}, http.StatusCreated) + if !strings.Contains(graph, `"graph_hash"`) { + t.Fatalf("graph missing hash: %s", graph) + } + + templateBody := postJSON(t, server, secret, "/v1/questionnaire-templates", "future-q-template", map[string]any{"name": "customer", "version": "2", "questions": []map[string]any{{"id": "q1", "prompt": "Review?", "evidence_type": "security_review"}}}, http.StatusCreated) + templateID := dataField(t, templateBody, "id") + draft := postJSON(t, server, secret, "/v1/questionnaire-drafts", "future-q-draft", map[string]any{"template_id": templateID, "product_id": productID, "release_id": releaseID}, http.StatusCreated) + if !strings.Contains(draft, evidenceID) { + t.Fatalf("draft missing evidence reference: %s", draft) + } + pdf := postJSON(t, server, secret, "/v1/reports/pdf", "future-pdf", map[string]any{"report_type": "release_readiness", "product_id": productID, "release_id": releaseID, "title": "Readiness"}, http.StatusCreated) + if !strings.Contains(pdf, `"payload_hash"`) { + t.Fatalf("pdf report missing hash: %s", pdf) + } + anomaly := postJSON(t, server, secret, "/v1/reports/anomaly", "future-anomaly", map[string]any{"subject_type": "release", "subject_id": releaseID}, http.StatusCreated) + if !strings.Contains(anomaly, `"limitations"`) { + t.Fatalf("anomaly missing limitations: %s", anomaly) + } + + sbomBody := postJSON(t, server, secret, "/v1/sboms", "future-sbom", map[string]any{"release_id": releaseID, "artifact_id": artifactID, "payload": map[string]any{"bomFormat": "CycloneDX", "specVersion": "1.6", "components": []map[string]any{{"name": "api", "purl": "pkg:oci/api"}}}}, http.StatusCreated) + sbomID := dataField(t, sbomBody, "id") + getJSON(t, server, secret, "/v1/sboms/"+sbomID, http.StatusOK) + scanBody := postJSON(t, server, secret, "/v1/vulnerability-scans", "future-vuln-scan", map[string]any{"scanner": "grype", "target_ref": "pkg:oci/api", "release_id": releaseID, "findings": []map[string]any{}}, http.StatusCreated) + scanID := dataField(t, scanBody, "id") + getJSON(t, server, secret, "/v1/vulnerability-scans/"+scanID, http.StatusOK) + contractBody := postJSON(t, server, secret, "/v1/openapi-contracts", "future-oas", map[string]any{"product_id": productID, "release_id": releaseID, "version": "1", "spec": map[string]any{"openapi": "3.1.0", "info": map[string]any{"title": "API", "version": "1"}, "paths": map[string]any{"/health": map[string]any{"get": map[string]any{"responses": map[string]any{"200": map[string]any{"description": "ok"}}}}}}}, http.StatusCreated) + contractID := dataField(t, contractBody, "id") + getJSON(t, server, secret, "/v1/openapi-contracts/"+contractID, http.StatusOK) + postJSON(t, server, secret, "/v1/policies/evaluate", "future-policy", map[string]any{"release_id": releaseID}, http.StatusCreated) + getJSON(t, server, secret, "/v1/reports/missing-evidence?release_id="+releaseID, http.StatusOK) + + releaseBundle := postJSON(t, server, secret, "/v1/release-bundles", "future-release-bundle", map[string]any{"release_id": releaseID}, http.StatusCreated) + bundleID := dataField(t, releaseBundle, "id") + getJSON(t, server, secret, "/v1/release-bundles/"+bundleID, http.StatusOK) + getJSON(t, server, secret, "/v1/release-bundles/"+bundleID+"/manifest", http.StatusOK) + getJSON(t, server, secret, "/v1/audit-chain/verify", http.StatusOK) + getJSON(t, server, secret, "/v1/signing-keys", http.StatusOK) + keys := dataSlice(t, getJSON(t, server, secret, "/v1/signing-keys", http.StatusOK)) + keyID := keys[0]["id"].(string) + postJSON(t, server, secret, "/v1/signing-keys/rotate", "future-key-rotate", map[string]any{"reason": "coverage"}, http.StatusCreated) + postJSON(t, server, secret, "/v1/signing-keys/"+keyID+"/revoke", "future-key-revoke", map[string]any{"reason": "coverage"}, http.StatusOK) + apiKeyBody := postJSON(t, server, secret, "/v1/api-keys", "future-api-key", map[string]any{"name": "reader", "scopes": []string{"evidence:read"}}, http.StatusCreated) + if strings.Contains(getJSON(t, server, secret, "/v1/api-keys", http.StatusOK), nestedDataField(t, apiKeyBody, "secret")) { + t.Fatalf("API key secret leaked in key list") + } + + providerBody := postJSON(t, server, secret, "/v1/signing-providers", "future-provider", map[string]any{"name": "kms", "type": "aws_kms", "key_ref": "arn:aws:kms:example", "encrypted": true}, http.StatusCreated) + providerID := dataField(t, providerBody, "id") + op := postJSON(t, server, secret, "/v1/signing-operations", "future-sign-op", map[string]any{"provider_id": providerID, "subject_type": "release", "subject_id": releaseID, "payload_hash": digest, "external_signature": "sig"}, http.StatusCreated) + if !strings.Contains(op, `"result":"passed"`) { + t.Fatalf("signing operation did not pass: %s", op) + } + saas := postJSON(t, server, secret, "/v1/saas/profiles", "future-saas", map[string]any{"name": "hosted", "region": "eu", "admin_tenant_id": dataField(t, productBody, "tenant_id"), "isolation_model": "shared-control-plane"}, http.StatusCreated) + if !strings.Contains(saas, `"config_hash"`) { + t.Fatalf("saas profile missing hash: %s", saas) + } + + logBody := postJSON(t, server, secret, "/v1/public-transparency-logs", "future-public-log", map[string]any{"name": "public", "endpoint": "https://transparency.example.test", "public_key": "pub"}, http.StatusCreated) + logID := dataField(t, logBody, "id") + batchBody := postJSON(t, server, secret, "/v1/merkle-batches", "future-batch", map[string]any{}, http.StatusCreated) + batchID := dataField(t, batchBody, "id") + checkpointBody := postJSON(t, server, secret, "/v1/transparency-checkpoints", "future-checkpoint", map[string]any{"batch_id": batchID, "provider": "internal", "external_id": "ts"}, http.StatusCreated) + checkpointID := dataField(t, checkpointBody, "id") + entry := postJSON(t, server, secret, "/v1/public-transparency-log-entries", "future-public-entry", map[string]any{"log_id": logID, "checkpoint_id": checkpointID, "external_id": "entry"}, http.StatusCreated) + if !strings.Contains(entry, `"entry_hash"`) { + t.Fatalf("public log entry missing hash: %s", entry) + } + marketplace := postJSON(t, server, secret, "/v1/marketplace-collectors", "future-marketplace", map[string]any{"name": "scanner", "provider": "scannerco", "version": "1.0.0", "publisher": "scannerco", "manifest_hash": digest}, http.StatusCreated) + if !strings.Contains(getJSON(t, server, secret, "/v1/marketplace-collectors", http.StatusOK), dataField(t, marketplace, "id")) { + t.Fatalf("marketplace list missing collector") + } + + orgBody := postJSON(t, server, secret, "/v1/organizations", "future-org", map[string]any{"name": "Example", "slug": "future-example"}, http.StatusCreated) + userBody := postJSON(t, server, secret, "/v1/users", "future-user", map[string]any{"organization_id": dataField(t, orgBody, "id"), "email": "future@example.test", "display_name": "Future"}, http.StatusCreated) + ssoBody := postJSON(t, server, secret, "/v1/sso/providers", "future-sso", map[string]any{"name": "OIDC", "type": "oidc", "issuer": "https://idp.example.test", "client_id": "client"}, http.StatusCreated) + ssoID := dataField(t, ssoBody, "id") + postJSON(t, server, secret, "/v1/sso/identity-links", "future-id-link", map[string]any{"user_id": dataField(t, userBody, "id"), "provider_id": ssoID, "subject": "sub-1", "email": "future@example.test", "verified": true}, http.StatusCreated) + providerVerification := postJSON(t, server, secret, "/v1/provider-verifications", "future-provider-verification", map[string]any{"provider_type": "oidc", "provider_id": ssoID, "subject": "sub-1"}, http.StatusCreated) + if !strings.Contains(providerVerification, `"result":"passed"`) { + t.Fatalf("provider verification failed: %s", providerVerification) + } +} + +func TestSourceSnapshotAndSystemHTTPGaps(t *testing.T) { + server, secret := testServer(t) + productBody := postJSON(t, server, secret, "/v1/products", "snapshot-product", map[string]any{"name": "Snapshot Product", "slug": "snapshot-product"}, http.StatusCreated) + projectBody := postJSON(t, server, secret, "/v1/projects", "snapshot-project", map[string]any{"product_id": dataField(t, productBody, "id"), "name": "api"}, http.StatusCreated) + projectID := dataField(t, projectBody, "id") + payload := map[string]any{ + "project_id": projectID, + "repository": map[string]any{"full_name": "aatuh/evydence", "clone_url": "https://github.com/aatuh/evydence.git", "default_branch": "main"}, + "commit": map[string]any{"sha": "0123456789abcdef0123456789abcdef01234567", "author": "aatu", "message": "change", "committed_at": "2026-05-28T12:00:00Z"}, + "branch": map[string]any{"name": "main", "protected": true, "protection_hash": "sha256:ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb"}, + "pull_request": map[string]any{ + "provider_id": "42", "title": "Change", "state": "merged", "source_branch": "feature", "target_branch": "main", "review_decision": "approved", + }, + } + githubSnapshot := postJSON(t, server, secret, "/v1/collectors/github/source-snapshots", "snapshot-github", payload, http.StatusCreated) + if !strings.Contains(githubSnapshot, `"repository_id"`) { + t.Fatalf("github snapshot missing repository id: %s", githubSnapshot) + } + postJSON(t, server, secret, "/v1/collectors/gitlab/source-snapshots", "snapshot-gitlab", payload, http.StatusCreated) + + for _, path := range []string{"/v1/health", "/v1/version", "/v1/openapi.json"} { + rec := httptest.NewRecorder() + req := httptest.NewRequest(http.MethodGet, path, nil) + server.Handler().ServeHTTP(rec, req) + if rec.Code != http.StatusOK { + t.Fatalf("GET %s status=%d body=%s", path, rec.Code, rec.Body.String()) + } + } + rec := httptest.NewRecorder() + req := httptest.NewRequest(http.MethodPost, "/v1/products", strings.NewReader(`{"name":`)) + req.Header.Set("Authorization", "Bearer "+secret) + req.Header.Set("Idempotency-Key", "bad-json") + server.Handler().ServeHTTP(rec, req) + if rec.Code != http.StatusBadRequest || !strings.Contains(rec.Body.String(), "VALIDATION_FAILED") { + t.Fatalf("bad JSON status=%d body=%s", rec.Code, rec.Body.String()) + } +} + func testServer(t *testing.T) (*Server, string) { t.Helper() ledger := app.NewLedger(app.Config{APIKeyPepper: "test"}) @@ -822,6 +978,20 @@ func dataMap(t *testing.T, body string) map[string]any { return decoded.Data } +func dataSlice(t *testing.T, body string) []map[string]any { + t.Helper() + var decoded struct { + Data []map[string]any `json:"data"` + } + if err := json.Unmarshal([]byte(body), &decoded); err != nil { + t.Fatalf("unmarshal body: %v body=%s", err, body) + } + if len(decoded.Data) == 0 { + t.Fatalf("data array is empty in %s", body) + } + return decoded.Data +} + func dataFieldFromNestedObject(t *testing.T, body, object, field string) string { t.Helper() data := dataMap(t, body) From 76a73e684f255b2ef13fdb40fdf0ad4d8fbc233d Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 16:09:13 +0300 Subject: [PATCH 021/287] test: cover command sdk and adapter helpers --- cmd/evydence-api/main_test.go | 48 +++++++ cmd/evydence-migrate/main_test.go | 24 ++++ cmd/evydence-worker/main_test.go | 99 ++++++++++++++ cmd/evydence/main_test.go | 87 ++++++++++++ internal/adapters/objectstore/s3/s3_test.go | 35 +++++ .../adapters/postgres/projections_test.go | 127 ++++++++++++++++++ internal/domain/domain_test.go | 15 +++ sdk/go/evydence/client_test.go | 86 ++++++++++++ 8 files changed, 521 insertions(+) create mode 100644 cmd/evydence-migrate/main_test.go create mode 100644 internal/adapters/postgres/projections_test.go create mode 100644 internal/domain/domain_test.go create mode 100644 sdk/go/evydence/client_test.go diff --git a/cmd/evydence-api/main_test.go b/cmd/evydence-api/main_test.go index ec5a667..8692d91 100644 --- a/cmd/evydence-api/main_test.go +++ b/cmd/evydence-api/main_test.go @@ -20,3 +20,51 @@ func TestValidateRuntimeConfigAllowsLocalBootstrapSecretPrinting(t *testing.T) { t.Fatalf("local config should allow explicit bootstrap secret printing: %v", err) } } + +func TestValidateRuntimeConfigRejectsProductionDefaults(t *testing.T) { + tests := []struct { + name string + database string + pepper string + signing string + wantSubstr string + }{ + {name: "missing database", database: "", pepper: "not-default", signing: "external", wantSubstr: "EVYDENCE_DATABASE_URL"}, + {name: "missing pepper", database: "postgres://example", pepper: "", signing: "external", wantSubstr: "EVYDENCE_API_KEY_PEPPER"}, + {name: "default pepper", database: "postgres://example", pepper: "local-dev-pepper-change-me", signing: "external", wantSubstr: "EVYDENCE_API_KEY_PEPPER"}, + {name: "local signing", database: "postgres://example", pepper: "not-default", signing: "local", wantSubstr: "EVYDENCE_SIGNING_KEY_MODE"}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := validateRuntimeConfig(true, tt.database, tt.pepper, tt.signing, false) + if err == nil || !strings.Contains(err.Error(), tt.wantSubstr) { + t.Fatalf("err=%v, want %q", err, tt.wantSubstr) + } + }) + } +} + +func TestEnvDefaultAndObjectStoreSelection(t *testing.T) { + t.Setenv("EVYDENCE_TEST_VALUE", " configured ") + if got := envDefault("EVYDENCE_TEST_VALUE", "fallback"); got != "configured" { + t.Fatalf("envDefault configured = %q", got) + } + if got := envDefault("EVYDENCE_MISSING_VALUE", "fallback"); got != "fallback" { + t.Fatalf("envDefault fallback = %q", got) + } + + t.Setenv("EVYDENCE_OBJECT_STORE", "filesystem") + t.Setenv("EVYDENCE_OBJECT_DIR", t.TempDir()) + store, description, err := openObjectStore(t.Context()) + if err != nil { + t.Fatalf("filesystem object store: %v", err) + } + if store == nil || !strings.Contains(description, "filesystem root") { + t.Fatalf("store=%T description=%q", store, description) + } + + t.Setenv("EVYDENCE_OBJECT_STORE", "unknown") + if _, _, err := openObjectStore(t.Context()); err == nil || !strings.Contains(err.Error(), "unsupported") { + t.Fatalf("unsupported object store err=%v", err) + } +} diff --git a/cmd/evydence-migrate/main_test.go b/cmd/evydence-migrate/main_test.go new file mode 100644 index 0000000..dcfd7b2 --- /dev/null +++ b/cmd/evydence-migrate/main_test.go @@ -0,0 +1,24 @@ +package main + +import ( + "strings" + "testing" +) + +func TestRunRequiresDatabaseURL(t *testing.T) { + t.Setenv("EVYDENCE_DATABASE_URL", "") + err := run() + if err == nil || !strings.Contains(err.Error(), "EVYDENCE_DATABASE_URL") { + t.Fatalf("err=%v, want database URL requirement", err) + } +} + +func TestEnvDefault(t *testing.T) { + t.Setenv("EVYDENCE_MIGRATIONS_DIR_TEST", " custom ") + if got := envDefault("EVYDENCE_MIGRATIONS_DIR_TEST", "migrations"); got != "custom" { + t.Fatalf("configured envDefault = %q", got) + } + if got := envDefault("EVYDENCE_MISSING_MIGRATIONS_DIR_TEST", "migrations"); got != "migrations" { + t.Fatalf("fallback envDefault = %q", got) + } +} diff --git a/cmd/evydence-worker/main_test.go b/cmd/evydence-worker/main_test.go index 1edbbb8..3fe392a 100644 --- a/cmd/evydence-worker/main_test.go +++ b/cmd/evydence-worker/main_test.go @@ -2,6 +2,7 @@ package main import ( "context" + "errors" "strings" "testing" "time" @@ -68,3 +69,101 @@ func TestProcessJobRejectsUnsupportedKinds(t *testing.T) { t.Fatalf("unexpected unsupported job error: %v", err) } } + +func TestProcessJobRecognizedKindsUseDurableTenantScopedState(t *testing.T) { + now := time.Now().UTC() + state := app.PersistedState{ + SBOMs: map[string]domain.SBOM{ + "sbom_1": {ID: "sbom_1", TenantID: "ten_1"}, + }, + Scans: map[string]domain.VulnerabilityScan{ + "scan_1": {ID: "scan_1", TenantID: "ten_1"}, + }, + Contracts: map[string]domain.OpenAPIContract{ + "contract_1": {ID: "contract_1", TenantID: "ten_1", Hash: "sha256:contract"}, + }, + VEXDocuments: map[string]domain.VEXDocument{ + "vex_1": {ID: "vex_1", TenantID: "ten_1"}, + }, + Bundles: map[string]domain.ReleaseBundle{ + "bundle_1": {ID: "bundle_1", TenantID: "ten_1", ManifestHash: "sha256:bundle", SignatureRefs: []string{"sig_1"}}, + }, + BuildAttestations: map[string]domain.BuildAttestation{ + "att_1": {ID: "att_1", TenantID: "ten_1", PayloadHash: "sha256:att", VerificationStatus: "structurally_valid", CreatedAt: now}, + }, + } + tests := []postgres.ClaimedJob{ + {TenantID: "ten_1", Kind: "parse_sbom", SubjectID: "sbom_1"}, + {TenantID: "ten_1", Kind: "parse_vulnerability_scan", SubjectID: "scan_1"}, + {TenantID: "ten_1", Kind: "parse_openapi_contract", SubjectID: "contract_1", Payload: map[string]any{"payload_hash": "sha256:contract"}}, + {TenantID: "ten_1", Kind: "parse_vex", SubjectID: "vex_1"}, + {TenantID: "ten_1", Kind: "sign_bundle", SubjectID: "bundle_1", Payload: map[string]any{"payload_hash": "sha256:bundle"}}, + {TenantID: "ten_1", Kind: "verify_attestation", SubjectID: "att_1", Payload: map[string]any{"payload_hash": "sha256:att"}}, + } + for _, job := range tests { + t.Run(job.Kind, func(t *testing.T) { + if err := processJob(context.Background(), fakeStateLoader{state: state, ok: true}, job); err != nil { + t.Fatalf("process %s: %v", job.Kind, err) + } + }) + } +} + +func TestProcessJobFailsClosedForStateLoadAndTenantMismatches(t *testing.T) { + if err := processJob(context.Background(), nil, postgres.ClaimedJob{}); err == nil || !strings.Contains(err.Error(), "requires durable state") { + t.Fatalf("nil state err=%v", err) + } + if err := processJob(context.Background(), fakeStateLoader{err: errors.New("database secret")}, postgres.ClaimedJob{}); err == nil || err.Error() != "load durable state for outbox job" { + t.Fatalf("state load err=%v", err) + } + if err := processJob(context.Background(), fakeStateLoader{ok: false}, postgres.ClaimedJob{}); err == nil || !strings.Contains(err.Error(), "not initialized") { + t.Fatalf("missing state err=%v", err) + } + state := app.PersistedState{Contracts: map[string]domain.OpenAPIContract{ + "contract_1": {ID: "contract_1", TenantID: "other", Hash: "sha256:contract"}, + }} + err := processJob(context.Background(), fakeStateLoader{state: state, ok: true}, postgres.ClaimedJob{TenantID: "ten_1", Kind: "parse_openapi_contract", SubjectID: "contract_1"}) + if err == nil || !strings.Contains(err.Error(), "parsed openapi contract is not available") || strings.Contains(err.Error(), "contract_1") { + t.Fatalf("tenant mismatch err=%v", err) + } +} + +func TestWorkerHelpersValidatePayloadHashAndEnv(t *testing.T) { + job := postgres.ClaimedJob{Payload: map[string]any{"payload_hash": " sha256:abc ", "ignored": 12}} + if got := payloadString(job, "payload_hash"); got != "sha256:abc" { + t.Fatalf("payloadString = %q", got) + } + if err := requirePayloadHash(job, "sha256:abc"); err != nil { + t.Fatalf("matching payload hash: %v", err) + } + if err := requirePayloadHash(job, "sha256:def"); err == nil || !strings.Contains(err.Error(), "payload hash") { + t.Fatalf("mismatch err=%v", err) + } + if err := requirePayloadHash(postgres.ClaimedJob{}, "sha256:def"); err != nil { + t.Fatalf("missing wanted hash should be ignored: %v", err) + } + + t.Setenv("EVYDENCE_WORKER_TEST_ENV", " value ") + if got := envDefault("EVYDENCE_WORKER_TEST_ENV", "fallback"); got != "value" { + t.Fatalf("envDefault configured = %q", got) + } + if got := envDefault("EVYDENCE_WORKER_MISSING_ENV", "fallback"); got != "fallback" { + t.Fatalf("envDefault fallback = %q", got) + } + t.Setenv("EVYDENCE_WORKER_TEST_DURATION", "250ms") + if got := durationEnv("EVYDENCE_WORKER_TEST_DURATION", time.Second); got != 250*time.Millisecond { + t.Fatalf("durationEnv configured = %s", got) + } + t.Setenv("EVYDENCE_WORKER_TEST_DURATION", "-1s") + if got := durationEnv("EVYDENCE_WORKER_TEST_DURATION", time.Second); got != time.Second { + t.Fatalf("durationEnv fallback = %s", got) + } + t.Setenv("EVYDENCE_WORKER_TEST_INT", "7") + if got := intEnv("EVYDENCE_WORKER_TEST_INT", 10); got != 7 { + t.Fatalf("intEnv configured = %d", got) + } + t.Setenv("EVYDENCE_WORKER_TEST_INT", "0") + if got := intEnv("EVYDENCE_WORKER_TEST_INT", 10); got != 10 { + t.Fatalf("intEnv fallback = %d", got) + } +} diff --git a/cmd/evydence/main_test.go b/cmd/evydence/main_test.go index 54ddf9a..be895eb 100644 --- a/cmd/evydence/main_test.go +++ b/cmd/evydence/main_test.go @@ -196,3 +196,90 @@ func TestGitHubActionsUploadBuildPostsBuildAndAttestationSafely(t *testing.T) { t.Fatalf("sawBuild=%v sawAttestation=%v", sawBuild, sawAttestation) } } + +func TestUsageRunAndManifestVerificationHelpers(t *testing.T) { + if err := usage(); err == nil || !strings.Contains(err.Error(), "evydence hash") { + t.Fatalf("usage err=%v", err) + } + if err := run(nil); err == nil || !strings.Contains(err.Error(), "usage") { + t.Fatalf("empty run err=%v", err) + } + if err := run([]string{"unknown"}); err == nil || !strings.Contains(err.Error(), "usage") { + t.Fatalf("unknown run err=%v", err) + } + + manifest := map[string]any{"name": "release", "artifacts": []any{}} + canonical, err := json.Marshal(manifest) + if err != nil { + t.Fatalf("marshal manifest: %v", err) + } + sum := sha256.Sum256(canonical) + path := t.TempDir() + "/manifest.json" + if err := os.WriteFile(path, []byte(`{"artifacts":[],"name":"release"}`), 0o600); err != nil { + t.Fatalf("write manifest: %v", err) + } + if err := verifyManifest(path, "sha256:"+hex.EncodeToString(sum[:])); err != nil { + t.Fatalf("verify manifest: %v", err) + } + if err := verifyManifest(path, hex.EncodeToString(sum[:])); err == nil || !strings.Contains(err.Error(), "sha256") { + t.Fatalf("bad expected hash err=%v", err) + } + if err := verifyManifest(path, "sha256:"+strings.Repeat("0", 64)); err == nil || !strings.Contains(err.Error(), "mismatch") { + t.Fatalf("hash mismatch err=%v", err) + } +} + +func TestGenerateReleaseSigningKeyWritesBase64Keys(t *testing.T) { + dir := t.TempDir() + privatePath := dir + "/private.key" + publicPath := dir + "/public.key" + if err := generateReleaseSigningKey([]string{"--private-out", privatePath, "--public-out", publicPath}); err != nil { + t.Fatalf("keygen: %v", err) + } + privateKey, err := readBase64File(privatePath, ed25519.PrivateKeySize) + if err != nil { + t.Fatalf("private key: %v", err) + } + publicKey, err := readBase64File(publicPath, ed25519.PublicKeySize) + if err != nil { + t.Fatalf("public key: %v", err) + } + if !ed25519.PrivateKey(privateKey).Public().(ed25519.PublicKey).Equal(ed25519.PublicKey(publicKey)) { + t.Fatal("public key does not match private key") + } +} + +func TestSafeAPIErrorUsesProblemCodeWithoutLeakingRawFallbackBody(t *testing.T) { + err := safeAPIError(http.StatusConflict, []byte(`{"code":"IDEMPOTENCY_KEY_REUSED","detail":"same key changed content"}`)) + if err == nil || !strings.Contains(err.Error(), "IDEMPOTENCY_KEY_REUSED") || !strings.Contains(err.Error(), "same key changed content") { + t.Fatalf("problem error=%v", err) + } + err = safeAPIError(http.StatusForbidden, []byte(`bearer token secret`)) + if err == nil || !strings.Contains(err.Error(), "Forbidden") || strings.Contains(err.Error(), "secret") { + t.Fatalf("fallback error leaked body or missed status text: %v", err) + } +} + +func TestResponseAndURLHelpersValidateInputs(t *testing.T) { + if got, err := cleanAPIURL("https://example.test/api?token=secret#frag"); err != nil || got != "https://example.test/api" { + t.Fatalf("cleanAPIURL got=%q err=%v", got, err) + } + if _, err := cleanAPIURL("file:///tmp/evydence"); err == nil || !strings.Contains(err.Error(), "http") { + t.Fatalf("file URL err=%v", err) + } + if _, err := responseDataID([]byte(`{"data":{}}`)); err == nil || !strings.Contains(err.Error(), "data.id") { + t.Fatalf("missing id err=%v", err) + } + if _, err := responseDataID([]byte(`not-json`)); err == nil { + t.Fatal("expected JSON decode error") + } + if got := atoiDefault(" 3 ", 1); got != 3 { + t.Fatalf("atoi configured = %d", got) + } + if got := atoiDefault("nope", 1); got != 1 { + t.Fatalf("atoi fallback = %d", got) + } + if _, err := cleanOperatorPath("\x00"); err == nil { + t.Fatal("expected NUL path error") + } +} diff --git a/internal/adapters/objectstore/s3/s3_test.go b/internal/adapters/objectstore/s3/s3_test.go index 001aa15..4cb3fd4 100644 --- a/internal/adapters/objectstore/s3/s3_test.go +++ b/internal/adapters/objectstore/s3/s3_test.go @@ -14,3 +14,38 @@ func TestNewRejectsIncompleteConfigWithoutNetwork(t *testing.T) { t.Fatalf("err = %v, want validation", err) } } + +func TestPutGetRejectUninitializedStoreAndUnsafeKeys(t *testing.T) { + if err := (*Store)(nil).Put(context.Background(), app.Object{Key: "tenants/ten_1/raw", TenantID: "ten_1"}); !errors.Is(err, app.ErrValidation) { + t.Fatalf("nil put err = %v, want validation", err) + } + if _, err := (*Store)(nil).Get(context.Background(), "tenants/ten_1/raw"); !errors.Is(err, app.ErrValidation) { + t.Fatalf("nil get err = %v, want validation", err) + } + + store := &Store{} + err := store.Put(context.Background(), app.Object{Key: "tenants/other/raw", TenantID: "ten_1"}) + if !errors.Is(err, app.ErrValidation) { + t.Fatalf("cross-tenant key err = %v, want validation", err) + } + if _, err := store.Get(context.Background(), ""); !errors.Is(err, app.ErrValidation) { + t.Fatalf("empty key err = %v, want validation", err) + } +} + +func TestMetadataValueUsesFirstNonEmptyKey(t *testing.T) { + metadata := map[string]string{ + "X-Amz-Meta-Evydence-Tenant-Id": "", + "evydence-tenant-id": "ten_1", + "evydence-digest": "sha256:abc", + } + if got := metadataValue(metadata, "X-Amz-Meta-Evydence-Tenant-Id", "evydence-tenant-id"); got != "ten_1" { + t.Fatalf("tenant metadata = %q", got) + } + if got := metadataValue(metadata, "missing", "evydence-digest"); got != "sha256:abc" { + t.Fatalf("digest metadata = %q", got) + } + if got := metadataValue(metadata, "missing"); got != "" { + t.Fatalf("missing metadata = %q", got) + } +} diff --git a/internal/adapters/postgres/projections_test.go b/internal/adapters/postgres/projections_test.go new file mode 100644 index 0000000..f4528bc --- /dev/null +++ b/internal/adapters/postgres/projections_test.go @@ -0,0 +1,127 @@ +package postgres + +import ( + "testing" + "time" + + "github.com/aatuh/evydence/internal/app" + "github.com/aatuh/evydence/internal/domain" +) + +func TestResourceProjectionsCoverTenantScopedImplementedResources(t *testing.T) { + now := time.Date(2026, 5, 28, 12, 0, 0, 0, time.UTC) + state := app.PersistedState{ + Tenants: map[string]domain.Tenant{"ten_1": {ID: "ten_1", CreatedAt: now}}, + Organizations: map[string]domain.Organization{"org_1": {ID: "org_1", TenantID: "ten_1", CreatedAt: now}}, + Users: map[string]domain.HumanUser{"usr_1": {ID: "usr_1", TenantID: "ten_1", CreatedAt: now}}, + RoleBindings: map[string]domain.RoleBinding{"rbac_1": {ID: "rbac_1", TenantID: "ten_1", CreatedAt: now}}, + SSOProviders: map[string]domain.SSOProvider{"sso_1": {ID: "sso_1", TenantID: "ten_1", CreatedAt: now}}, + IdentityLinks: map[string]domain.UserIdentityLink{"link_1": {ID: "link_1", TenantID: "ten_1", CreatedAt: now}}, + SSOSessions: map[string]domain.SSOSession{"sess_1": {ID: "sess_1", TenantID: "ten_1", CreatedAt: now}}, + Products: map[string]domain.Product{"prod_1": {ID: "prod_1", TenantID: "ten_1", CreatedAt: now}}, + Projects: map[string]domain.Project{"proj_1": {ID: "proj_1", TenantID: "ten_1", ProductID: "prod_1", CreatedAt: now}}, + Releases: map[string]domain.Release{"rel_1": {ID: "rel_1", TenantID: "ten_1", ProductID: "prod_1", CreatedAt: now}}, + Artifacts: map[string]domain.Artifact{"art_1": {ID: "art_1", TenantID: "ten_1", CreatedAt: now}}, + BuildRuns: map[string]domain.BuildRun{"build_1": {ID: "build_1", TenantID: "ten_1", ProjectID: "proj_1", ReleaseID: "rel_1", CreatedAt: now}}, + BuildAttestations: map[string]domain.BuildAttestation{"att_1": {ID: "att_1", TenantID: "ten_1", CreatedAt: now}}, + Evidence: map[string]domain.EvidenceItem{"ev_1": {ID: "ev_1", TenantID: "ten_1", ProductID: "prod_1", ProjectID: "proj_1", ReleaseID: "rel_1", CreatedAt: now}}, + ReleaseCandidates: map[string]domain.ReleaseCandidate{"rc_1": {ID: "rc_1", TenantID: "ten_1", ReleaseID: "rel_1", CreatedAt: now}}, + ContainerImages: map[string]domain.ContainerImage{"img_1": {ID: "img_1", TenantID: "ten_1", CreatedAt: now}}, + ArtifactSignatures: map[string]domain.ArtifactSignature{"asig_1": {ID: "asig_1", TenantID: "ten_1", CreatedAt: now}}, + Repositories: map[string]domain.SourceRepository{"repo_1": {ID: "repo_1", TenantID: "ten_1", ProjectID: "proj_1", CreatedAt: now}}, + Commits: map[string]domain.SourceCommit{"commit_1": {ID: "commit_1", TenantID: "ten_1", CreatedAt: now}}, + Branches: map[string]domain.SourceBranch{"branch_1": {ID: "branch_1", TenantID: "ten_1", CreatedAt: now}}, + PullRequests: map[string]domain.PullRequest{"pr_1": {ID: "pr_1", TenantID: "ten_1", CreatedAt: now}}, + Environments: map[string]domain.DeploymentEnvironment{"env_1": {ID: "env_1", TenantID: "ten_1", ProductID: "prod_1", CreatedAt: now}}, + Deployments: map[string]domain.DeploymentEvent{"dep_1": {ID: "dep_1", TenantID: "ten_1", ReleaseID: "rel_1", CreatedAt: now}}, + Incidents: map[string]domain.Incident{"inc_1": {ID: "inc_1", TenantID: "ten_1", ProductID: "prod_1", ReleaseID: "rel_1", CreatedAt: now}}, + TimelineEvents: map[string]domain.IncidentTimelineEvent{"tl_1": {ID: "tl_1", TenantID: "ten_1", CreatedAt: now}}, + RemediationTasks: map[string]domain.RemediationTask{"task_1": {ID: "task_1", TenantID: "ten_1", ReleaseID: "rel_1", CreatedAt: now}}, + SecurityScans: map[string]domain.SecurityScan{"secscan_1": {ID: "secscan_1", TenantID: "ten_1", ProductID: "prod_1", ReleaseID: "rel_1", CreatedAt: now}}, + ManualSecurityDocs: map[string]domain.ManualSecurityDocument{"doc_1": {ID: "doc_1", TenantID: "ten_1", ProductID: "prod_1", ReleaseID: "rel_1", CreatedAt: now}}, + SBOMDiffs: map[string]domain.SBOMDiff{"diff_1": {ID: "diff_1", TenantID: "ten_1", ReleaseID: "rel_1", CreatedAt: now}}, + DependencyChanges: map[string]domain.DependencyChange{"depchg_1": {ID: "depchg_1", TenantID: "ten_1", CreatedAt: now}}, + VulnerabilityWorkflow: map[string]domain.VulnerabilityWorkflowRecord{"vw_1": {ID: "vw_1", TenantID: "ten_1", ReleaseID: "rel_1", CreatedAt: now}}, + ContractDiffs: map[string]domain.ContractDiff{"cdiff_1": {ID: "cdiff_1", TenantID: "ten_1", ProductID: "prod_1", ReleaseID: "rel_1", CreatedAt: now}}, + CustomPolicies: map[string]domain.CustomPolicy{"pol_1": {ID: "pol_1", TenantID: "ten_1", CreatedAt: now}}, + CustomPolicyEvaluations: map[string]domain.CustomPolicyEvaluation{"peval_1": {ID: "peval_1", TenantID: "ten_1", ReleaseID: "rel_1", CreatedAt: now}}, + Waivers: map[string]domain.Waiver{"waiver_1": {ID: "waiver_1", TenantID: "ten_1", CreatedAt: now}}, + Approvals: map[string]domain.ApprovalRecord{"app_1": {ID: "app_1", TenantID: "ten_1", CreatedAt: now}}, + RedactionProfiles: map[string]domain.RedactionProfile{"red_1": {ID: "red_1", TenantID: "ten_1", CreatedAt: now}}, + CustomerPackages: map[string]domain.CustomerSecurityPackage{"pkg_1": {ID: "pkg_1", TenantID: "ten_1", ProductID: "prod_1", ReleaseID: "rel_1", CreatedAt: now}}, + HTMLReports: map[string]domain.HTMLReportPackage{"html_1": {ID: "html_1", TenantID: "ten_1", ProductID: "prod_1", ReleaseID: "rel_1", CreatedAt: now}}, + ReportTemplates: map[string]domain.CustomReportTemplate{"tmpl_1": {ID: "tmpl_1", TenantID: "ten_1", CreatedAt: now}}, + RenderedReports: map[string]domain.RenderedCustomReport{"rend_1": {ID: "rend_1", TenantID: "ten_1", CreatedAt: now}}, + EvidenceBundles: map[string]domain.EvidenceBundle{"eb_1": {ID: "eb_1", TenantID: "ten_1", ReleaseID: "rel_1", CreatedAt: now}}, + BundleImports: map[string]domain.EvidenceBundleImport{"ebi_1": {ID: "ebi_1", TenantID: "ten_1", CreatedAt: now}}, + DSSETrustRoots: map[string]domain.DSSETrustRoot{"trust_1": {ID: "trust_1", TenantID: "ten_1", CreatedAt: now}}, + CollectorReleases: map[string]domain.CollectorRelease{"cr_1": {ID: "cr_1", TenantID: "ten_1", CreatedAt: now}}, + CosignVerifications: map[string]domain.CosignVerification{"cosign_1": {ID: "cosign_1", TenantID: "ten_1", CreatedAt: now}}, + SigningProviders: map[string]domain.SigningProvider{"sp_1": {ID: "sp_1", TenantID: "ten_1", CreatedAt: now}}, + MerkleBatches: map[string]domain.MerkleBatch{"mb_1": {ID: "mb_1", TenantID: "ten_1", CreatedAt: now}}, + TransparencyCheckpoints: map[string]domain.TransparencyCheckpoint{"tc_1": {ID: "tc_1", TenantID: "ten_1", CreatedAt: now}}, + ObjectRetentionPolicies: map[string]domain.ObjectRetentionPolicy{"orp_1": {ID: "orp_1", TenantID: "ten_1", CreatedAt: now}}, + BackupManifests: map[string]domain.BackupManifest{"bak_1": {ID: "bak_1", TenantID: "ten_1", CreatedAt: now}}, + LegalHolds: map[string]domain.LegalHold{"hold_1": {ID: "hold_1", TenantID: "ten_1", CreatedAt: now}}, + RetentionOverrides: map[string]domain.RetentionOverride{"ret_1": {ID: "ret_1", TenantID: "ten_1", CreatedAt: now}}, + CustomerPortalAccess: map[string]domain.CustomerPortalAccess{"cpa_1": {ID: "cpa_1", TenantID: "ten_1", CreatedAt: now}}, + QuestionnaireTemplates: map[string]domain.QuestionnaireTemplate{"qt_1": {ID: "qt_1", TenantID: "ten_1", CreatedAt: now}}, + QuestionnairePackages: map[string]domain.QuestionnairePackage{"qp_1": {ID: "qp_1", TenantID: "ten_1", ProductID: "prod_1", ReleaseID: "rel_1", CreatedAt: now}}, + CommercialCollectors: map[string]domain.CommercialCollectorDefinition{"cc_1": {ID: "cc_1", TenantID: "ten_1", CreatedAt: now}}, + EvidenceSummaries: map[string]domain.EvidenceSummary{"sum_1": {ID: "sum_1", TenantID: "ten_1", CreatedAt: now}}, + QuestionnaireDrafts: map[string]domain.QuestionnaireDraft{"qd_1": {ID: "qd_1", TenantID: "ten_1", ProductID: "prod_1", ReleaseID: "rel_1", CreatedAt: now}}, + GraphSnapshots: map[string]domain.EvidenceGraphSnapshot{"graph_1": {ID: "graph_1", TenantID: "ten_1", ProductID: "prod_1", ReleaseID: "rel_1", CreatedAt: now}}, + SaaSProfiles: map[string]domain.SaaSEditionProfile{"saas_1": {ID: "saas_1", TenantID: "ten_1", CreatedAt: now}}, + PublicTransparencyLogs: map[string]domain.PublicTransparencyLog{"ptl_1": {ID: "ptl_1", TenantID: "ten_1", CreatedAt: now}}, + PublicTransparencyItems: map[string]domain.PublicTransparencyLogEntry{"pte_1": {ID: "pte_1", TenantID: "ten_1", CreatedAt: now}}, + MarketplaceCollectors: map[string]domain.MarketplaceCollector{"mc_1": {ID: "mc_1", TenantID: "ten_1", CreatedAt: now}}, + PDFReports: map[string]domain.PDFReportPackage{"pdf_1": {ID: "pdf_1", TenantID: "ten_1", ProductID: "prod_1", ReleaseID: "rel_1", CreatedAt: now}}, + AnomalyReports: map[string]domain.AnomalyReport{"anom_1": {ID: "anom_1", TenantID: "ten_1", CreatedAt: now}}, + ProviderVerifications: map[string]domain.ProviderVerification{"pv_1": {ID: "pv_1", TenantID: "ten_1", CreatedAt: now}}, + SigningOperations: map[string]domain.SigningOperation{"so_1": {ID: "so_1", TenantID: "ten_1", CreatedAt: now}}, + ControlFrameworks: map[string]domain.ControlFramework{"cf_1": {ID: "cf_1", TenantID: "ten_1", CreatedAt: now}}, + SecurityControls: map[string]domain.SecurityControl{"ctrl_1": {ID: "ctrl_1", TenantID: "ten_1", CreatedAt: now}}, + ControlEvidence: map[string]domain.ControlEvidence{"ce_1": {ID: "ce_1", TenantID: "ten_1", ProductID: "prod_1", ReleaseID: "rel_1", CreatedAt: now}}, + SBOMs: map[string]domain.SBOM{"sbom_1": {ID: "sbom_1", TenantID: "ten_1", ReleaseID: "rel_1", CreatedAt: now}}, + Scans: map[string]domain.VulnerabilityScan{"scan_1": {ID: "scan_1", TenantID: "ten_1", ReleaseID: "rel_1", CreatedAt: now}}, + VEXDocuments: map[string]domain.VEXDocument{"vex_1": {ID: "vex_1", TenantID: "ten_1", ReleaseID: "rel_1", CreatedAt: now}}, + Contracts: map[string]domain.OpenAPIContract{"api_1": {ID: "api_1", TenantID: "ten_1", ProductID: "prod_1", ReleaseID: "rel_1", CreatedAt: now}}, + Bundles: map[string]domain.ReleaseBundle{"bundle_1": {ID: "bundle_1", TenantID: "ten_1", ReleaseID: "rel_1", CreatedAt: now}}, + } + + projections := resourceProjections(state) + if len(projections) != 76 { + t.Fatalf("projection count = %d, want 76", len(projections)) + } + byType := map[string]resourceProjection{} + for _, projection := range projections { + byType[projection.ResourceType] = projection + if projection.TenantID != "ten_1" { + t.Fatalf("projection lost tenant scope: %#v", projection) + } + } + for _, resourceType := range []string{ + "tenant", "product", "project", "release", "evidence_item", "build_run", + "release_candidate", "deployment", "customer_security_package", + "control_evidence", "public_transparency_log_entry", "release_bundle", + } { + if byType[resourceType].ResourceID == "" { + t.Fatalf("missing projection type %s in %#v", resourceType, byType) + } + } + if byType["project"].ProductID != "prod_1" || byType["project"].ProjectID != "proj_1" { + t.Fatalf("project projection = %#v", byType["project"]) + } + if byType["release"].ProductID != "prod_1" || byType["release"].ReleaseID != "rel_1" { + t.Fatalf("release projection = %#v", byType["release"]) + } + if byType["customer_security_package"].ProductID != "prod_1" || byType["customer_security_package"].ReleaseID != "rel_1" { + t.Fatalf("customer package projection = %#v", byType["customer_security_package"]) + } + if nullableString("") != nil { + t.Fatal("empty nullableString should be nil") + } + if got := nullableString("prod_1"); got != "prod_1" { + t.Fatalf("nullableString = %#v", got) + } +} diff --git a/internal/domain/domain_test.go b/internal/domain/domain_test.go new file mode 100644 index 0000000..35848ba --- /dev/null +++ b/internal/domain/domain_test.go @@ -0,0 +1,15 @@ +package domain + +import "testing" + +func TestActorHasScopeSupportsExactAndWildcardScopes(t *testing.T) { + if !((Actor{Scopes: []string{"evidence:write"}}).HasScope("evidence:write")) { + t.Fatal("exact scope should be accepted") + } + if !((Actor{Scopes: []string{"*"}}).HasScope("controls:admin")) { + t.Fatal("wildcard scope should be accepted") + } + if (Actor{Scopes: []string{"evidence:read"}}).HasScope("evidence:write") { + t.Fatal("ungranted scope should be rejected") + } +} diff --git a/sdk/go/evydence/client_test.go b/sdk/go/evydence/client_test.go new file mode 100644 index 0000000..5c0b74a --- /dev/null +++ b/sdk/go/evydence/client_test.go @@ -0,0 +1,86 @@ +package evydence + +import ( + "context" + "encoding/json" + "net/http" + "net/http/httptest" + "strings" + "testing" +) + +func TestPostSendsAuthenticatedIdempotentRequest(t *testing.T) { + var saw bool + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + saw = true + if r.Method != http.MethodPost || r.URL.Path != "/v1/evidence" { + t.Fatalf("unexpected request %s %s", r.Method, r.URL.Path) + } + if got := r.Header.Get("Authorization"); got != "Bearer evy_secret" { + t.Fatalf("authorization header = %q", got) + } + if got := r.Header.Get("Idempotency-Key"); got != "idem-1" { + t.Fatalf("idempotency header = %q", got) + } + if got := r.Header.Get("Content-Type"); got != "application/json" { + t.Fatalf("content-type = %q", got) + } + var body map[string]string + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + t.Fatalf("decode body: %v", err) + } + if body["title"] != "Build" { + t.Fatalf("body = %#v", body) + } + _, _ = w.Write([]byte(`{"data":{"id":"ev_1"}}`)) + })) + defer server.Close() + + var out struct { + Data struct { + ID string `json:"id"` + } `json:"data"` + } + client := Client{BaseURL: server.URL + "/", APIKey: " evy_secret ", HTTP: server.Client()} + if err := client.Post(context.Background(), "/v1/evidence", "idem-1", map[string]string{"title": "Build"}, &out); err != nil { + t.Fatalf("post: %v", err) + } + if !saw || out.Data.ID != "ev_1" { + t.Fatalf("saw=%v out=%#v", saw, out) + } +} + +func TestPostRejectsInvalidInputsBeforeNetwork(t *testing.T) { + called := false + server := httptest.NewServer(http.HandlerFunc(func(http.ResponseWriter, *http.Request) { + called = true + })) + defer server.Close() + + client := Client{BaseURL: server.URL, APIKey: "secret", HTTP: server.Client()} + if err := client.Post(context.Background(), "/evidence", "idem-1", map[string]string{}, nil); err == nil { + t.Fatal("expected invalid path error") + } + if err := client.Post(context.Background(), "/v1/evidence", " ", map[string]string{}, nil); err == nil { + t.Fatal("expected invalid idempotency key error") + } + if called { + t.Fatal("invalid client input should not make a network request") + } +} + +func TestPostReturnsSafeStatusError(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + http.Error(w, "secret body should not be returned", http.StatusForbidden) + })) + defer server.Close() + + err := Client{BaseURL: server.URL, APIKey: "secret", HTTP: server.Client()}. + Post(context.Background(), "/v1/evidence", "idem-1", map[string]string{"title": "Build"}, nil) + if err == nil { + t.Fatal("expected status error") + } + if !strings.Contains(err.Error(), "status 403") || strings.Contains(err.Error(), "secret body") { + t.Fatalf("unsafe or unexpected error: %v", err) + } +} From b5ae6d3d9f3166cff8765a9f87bf976e7c318aa5 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 16:14:16 +0300 Subject: [PATCH 022/287] test: strengthen workflow and command coverage --- cmd/evydence-api/main_test.go | 8 + cmd/evydence-migrate/main_test.go | 8 + cmd/evydence-worker/main_test.go | 13 + cmd/evydence/main_test.go | 70 ++++ cmd/openapi/main.go | 21 +- cmd/openapi/main_test.go | 17 + .../app/authorization_helpers_more_test.go | 162 ++++++++++ internal/app/coverage_more_test.go | 301 ++++++++++++++++++ internal/app/risk_workflows_more_test.go | 183 +++++++++++ 9 files changed, 777 insertions(+), 6 deletions(-) create mode 100644 cmd/openapi/main_test.go create mode 100644 internal/app/authorization_helpers_more_test.go create mode 100644 internal/app/coverage_more_test.go create mode 100644 internal/app/risk_workflows_more_test.go diff --git a/cmd/evydence-api/main_test.go b/cmd/evydence-api/main_test.go index 8692d91..bb46f31 100644 --- a/cmd/evydence-api/main_test.go +++ b/cmd/evydence-api/main_test.go @@ -68,3 +68,11 @@ func TestEnvDefaultAndObjectStoreSelection(t *testing.T) { t.Fatalf("unsupported object store err=%v", err) } } + +func TestOpenObjectStoreRejectsIncompleteS3Config(t *testing.T) { + t.Setenv("EVYDENCE_OBJECT_STORE", "s3") + t.Setenv("EVYDENCE_S3_ENDPOINT", "localhost:9000") + if _, _, err := openObjectStore(t.Context()); err == nil { + t.Fatal("expected incomplete S3 config to be rejected") + } +} diff --git a/cmd/evydence-migrate/main_test.go b/cmd/evydence-migrate/main_test.go index dcfd7b2..a7f7569 100644 --- a/cmd/evydence-migrate/main_test.go +++ b/cmd/evydence-migrate/main_test.go @@ -22,3 +22,11 @@ func TestEnvDefault(t *testing.T) { t.Fatalf("fallback envDefault = %q", got) } } + +func TestRunReturnsPostgresOpenFailure(t *testing.T) { + t.Setenv("EVYDENCE_DATABASE_URL", "postgres://invalid-host.invalid/evydence") + err := run() + if err == nil { + t.Fatal("expected postgres open failure") + } +} diff --git a/cmd/evydence-worker/main_test.go b/cmd/evydence-worker/main_test.go index 3fe392a..e095c09 100644 --- a/cmd/evydence-worker/main_test.go +++ b/cmd/evydence-worker/main_test.go @@ -167,3 +167,16 @@ func TestWorkerHelpersValidatePayloadHashAndEnv(t *testing.T) { t.Fatalf("intEnv fallback = %d", got) } } + +func TestRunRequiresDatabaseURLAndWrapsOpenFailure(t *testing.T) { + t.Setenv("EVYDENCE_DATABASE_URL", "") + err := run() + if err == nil || !strings.Contains(err.Error(), "EVYDENCE_DATABASE_URL") { + t.Fatalf("missing database err=%v", err) + } + t.Setenv("EVYDENCE_DATABASE_URL", "postgres://invalid-host.invalid/evydence") + t.Setenv("EVYDENCE_SKIP_MIGRATIONS", "true") + if err := run(); err == nil { + t.Fatal("expected postgres open failure") + } +} diff --git a/cmd/evydence/main_test.go b/cmd/evydence/main_test.go index be895eb..e8de1cd 100644 --- a/cmd/evydence/main_test.go +++ b/cmd/evydence/main_test.go @@ -283,3 +283,73 @@ func TestResponseAndURLHelpersValidateInputs(t *testing.T) { t.Fatal("expected NUL path error") } } + +func TestRunCoversHashBundleAndReleaseCommands(t *testing.T) { + dir := t.TempDir() + artifact := dir + "/artifact.bin" + if err := os.WriteFile(artifact, []byte("binary"), 0o600); err != nil { + t.Fatalf("write artifact: %v", err) + } + if err := run([]string{"hash", artifact}); err != nil { + t.Fatalf("run hash: %v", err) + } + manifest := dir + "/manifest.json" + if err := run([]string{"release", "manifest", "--out", manifest, artifact}); err != nil { + t.Fatalf("run release manifest: %v", err) + } + privateKey := dir + "/private.key" + publicKey := dir + "/public.key" + if err := run([]string{"release", "keygen", "--private-out", privateKey, "--public-out", publicKey}); err != nil { + t.Fatalf("run release keygen: %v", err) + } + signature := dir + "/manifest.sig.json" + if err := run([]string{"release", "sign", "--manifest", manifest, "--private-key", privateKey, "--out", signature}); err != nil { + t.Fatalf("run release sign: %v", err) + } + if err := run([]string{"release", "verify", "--manifest", manifest, "--signature", signature}); err != nil { + t.Fatalf("run release verify: %v", err) + } + var decoded map[string]any + canonical, hash, err := canonicalFileHash(manifest) + if err != nil { + t.Fatalf("canonical hash: %v", err) + } + if err := json.Unmarshal(canonical, &decoded); err != nil || decoded["schema_version"] == "" { + t.Fatalf("canonical manifest decode=%#v err=%v", decoded, err) + } + if err := run([]string{"verify-manifest", manifest, "--hash", hash}); err != nil { + t.Fatalf("run verify manifest: %v", err) + } + bundleManifest := map[string]any{"schema_version": "evidence-bundle.v1.0.0", "evidence_ids": []any{"ev_1"}} + bundleBody, err := json.Marshal(bundleManifest) + if err != nil { + t.Fatalf("marshal bundle manifest: %v", err) + } + sum := sha256.Sum256(bundleBody) + bundlePath := dir + "/bundle.json" + body, err := json.Marshal(map[string]any{"manifest": bundleManifest, "manifest_hash": "sha256:" + hex.EncodeToString(sum[:])}) + if err != nil { + t.Fatalf("marshal bundle: %v", err) + } + if err := os.WriteFile(bundlePath, body, 0o600); err != nil { + t.Fatalf("write bundle: %v", err) + } + if err := run([]string{"verify-evidence-bundle", bundlePath}); err != nil { + t.Fatalf("run verify evidence bundle: %v", err) + } +} + +func TestRunUploadCommandsAndGitHubUsageBranches(t *testing.T) { + if err := run([]string{"github-actions"}); err == nil || !strings.Contains(err.Error(), "usage") { + t.Fatalf("github usage err=%v", err) + } + if err := run([]string{"import-bundle"}); err == nil || !strings.Contains(err.Error(), "usage") { + t.Fatalf("import usage err=%v", err) + } + if err := run([]string{"upload"}); err == nil || !strings.Contains(err.Error(), "usage") { + t.Fatalf("upload usage err=%v", err) + } + if err := run([]string{"release", "unknown"}); err == nil || !strings.Contains(err.Error(), "usage") { + t.Fatalf("release usage err=%v", err) + } +} diff --git a/cmd/openapi/main.go b/cmd/openapi/main.go index 0a0000c..ec77eb4 100644 --- a/cmd/openapi/main.go +++ b/cmd/openapi/main.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "io" "os" "github.com/aatuh/evydence/internal/adapters/httpapi" @@ -9,16 +10,24 @@ import ( ) func main() { - server, err := httpapi.NewServer(app.NewLedger(app.Config{APIKeyPepper: "openapi-generation"})) - if err != nil { + if err := run(os.Stdout); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } +} + +func run(out io.Writer) error { + server, err := httpapi.NewServer(app.NewLedger(app.Config{APIKeyPepper: "openapi-generation"})) + if err != nil { + return err + } doc, err := server.OpenAPI() if err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) + return err + } + if _, err := out.Write(doc); err != nil { + return err } - _, _ = os.Stdout.Write(doc) - _, _ = os.Stdout.Write([]byte("\n")) + _, err = out.Write([]byte("\n")) + return err } diff --git a/cmd/openapi/main_test.go b/cmd/openapi/main_test.go new file mode 100644 index 0000000..3d786f1 --- /dev/null +++ b/cmd/openapi/main_test.go @@ -0,0 +1,17 @@ +package main + +import ( + "bytes" + "strings" + "testing" +) + +func TestRunWritesOpenAPI(t *testing.T) { + var out bytes.Buffer + if err := run(&out); err != nil { + t.Fatalf("run: %v", err) + } + if !strings.Contains(out.String(), `"openapi"`) || !strings.HasSuffix(out.String(), "\n") { + t.Fatalf("unexpected OpenAPI output: %.80q", out.String()) + } +} diff --git a/internal/app/authorization_helpers_more_test.go b/internal/app/authorization_helpers_more_test.go new file mode 100644 index 0000000..83149ea --- /dev/null +++ b/internal/app/authorization_helpers_more_test.go @@ -0,0 +1,162 @@ +package app + +import ( + "errors" + "testing" + + "github.com/aatuh/evydence/internal/domain" +) + +func TestEnterpriseGovernanceAndFutureHelperBranches(t *testing.T) { + now := fixedNow() + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ledger.mu.Lock() + ledger.tenants["ten_1"] = domain.Tenant{ID: "ten_1", CreatedAt: now} + ledger.products["prod_1"] = domain.Product{ID: "prod_1", TenantID: "ten_1", CreatedAt: now} + ledger.projects["proj_1"] = domain.Project{ID: "proj_1", TenantID: "ten_1", ProductID: "prod_1", CreatedAt: now} + ledger.releases["rel_1"] = domain.Release{ID: "rel_1", TenantID: "ten_1", ProductID: "prod_1", CreatedAt: now} + ledger.artifacts["art_1"] = domain.Artifact{ID: "art_1", TenantID: "ten_1", CreatedAt: now} + ledger.evidence["ev_1"] = domain.EvidenceItem{ID: "ev_1", TenantID: "ten_1", ProductID: "prod_1", ProjectID: "proj_1", ReleaseID: "rel_1", Type: "sbom", CreatedAt: now} + ledger.users["usr_1"] = domain.HumanUser{ID: "usr_1", TenantID: "ten_1", CreatedAt: now} + ledger.collectors["col_1"] = domain.Collector{ID: "col_1", TenantID: "ten_1", CreatedAt: now} + ledger.customerPackages["pkg_1"] = domain.CustomerSecurityPackage{ID: "pkg_1", TenantID: "ten_1", ProductID: "prod_1", ReleaseID: "rel_1", CreatedAt: now} + ledger.evidenceBundles["eb_1"] = domain.EvidenceBundle{ID: "eb_1", TenantID: "ten_1", ReleaseID: "rel_1", CreatedAt: now} + ledger.buildRuns["build_1"] = domain.BuildRun{ID: "build_1", TenantID: "ten_1", ProjectID: "proj_1", ReleaseID: "rel_1", CreatedAt: now} + ledger.repositories["repo_1"] = domain.SourceRepository{ID: "repo_1", TenantID: "ten_1", ProjectID: "proj_1", CreatedAt: now} + ledger.deployments["dep_1"] = domain.DeploymentEvent{ID: "dep_1", TenantID: "ten_1", ReleaseID: "rel_1", CreatedAt: now} + ledger.environments["env_1"] = domain.DeploymentEnvironment{ID: "env_1", TenantID: "ten_1", ProductID: "prod_1", CreatedAt: now} + ledger.incidents["inc_1"] = domain.Incident{ID: "inc_1", TenantID: "ten_1", ProductID: "prod_1", ReleaseID: "rel_1", CreatedAt: now} + ledger.securityScans["sec_1"] = domain.SecurityScan{ID: "sec_1", TenantID: "ten_1", ProductID: "prod_1", ReleaseID: "rel_1", CreatedAt: now} + ledger.frameworks["fw_1"] = domain.ControlFramework{ID: "fw_1", TenantID: "ten_1", Slug: "b", Version: "1", CreatedAt: now} + ledger.frameworks["fw_2"] = domain.ControlFramework{ID: "fw_2", TenantID: "ten_1", Slug: "a", Version: "1", CreatedAt: now} + ledger.controls["ctrl_1"] = domain.SecurityControl{ID: "ctrl_1", TenantID: "ten_1", FrameworkID: "fw_1", CreatedAt: now} + ledger.customPolicies["pol_1"] = domain.CustomPolicy{ID: "pol_1", TenantID: "ten_1", CreatedAt: now} + ledger.scans["scan_1"] = domain.VulnerabilityScan{ID: "scan_1", TenantID: "ten_1", ReleaseID: "rel_1", Findings: []domain.VulnerabilityFinding{{ID: "finding_1", Vulnerability: "CVE-1", Severity: "critical", State: "open"}}, CreatedAt: now} + ledger.contractDiffs["cdiff_1"] = domain.ContractDiff{ID: "cdiff_1", TenantID: "ten_1", CreatedAt: now} + ledger.waivers["waiver_1"] = domain.Waiver{ID: "waiver_1", TenantID: "ten_1", ScopeType: "release", ScopeID: "rel_1", CreatedAt: now} + ledger.manualDocs["review_1"] = domain.ManualSecurityDocument{ID: "review_1", TenantID: "ten_1", ProductID: "prod_1", ReleaseID: "rel_1", DocumentType: "security_review", CreatedAt: now} + ledger.controlLinks["ce_1"] = domain.ControlEvidence{ID: "ce_1", TenantID: "ten_1", ControlID: "ctrl_1", SubjectType: "evidence", SubjectID: "ev_1", EvidenceType: "sbom", ProductID: "prod_1", ReleaseID: "rel_1", Confidence: confidenceHigh, CreatedAt: now} + ledger.roleBindings["rb_1"] = domain.RoleBinding{ID: "rb_1", TenantID: "ten_1", SubjectType: "user", SubjectID: "usr_1", Role: "security_engineer", ResourceType: "release", ResourceID: "rel_1", CreatedAt: now} + ledger.mu.Unlock() + + ledger.mu.Lock() + defer ledger.mu.Unlock() + for _, subject := range []struct{ typ, id string }{{"user", "usr_1"}, {"collector", "col_1"}} { + if err := ledger.ensureRoleSubjectLocked("ten_1", subject.typ, subject.id); err != nil { + t.Fatalf("role subject %s: %v", subject.typ, err) + } + } + if !errors.Is(ledger.ensureRoleSubjectLocked("ten_1", "team", "team_1"), ErrValidation) { + t.Fatal("unknown role subject should be validation") + } + for _, scope := range []struct{ typ, id string }{{"tenant", "ten_1"}, {"product", "prod_1"}, {"project", "proj_1"}, {"release", "rel_1"}, {"evidence", "ev_1"}} { + if err := ledger.ensureRetentionScopeLocked("ten_1", scope.typ, scope.id); err != nil { + t.Fatalf("retention scope %s: %v", scope.typ, err) + } + } + if !errors.Is(ledger.ensureRetentionScopeLocked("ten_1", "unknown", "id"), ErrValidation) { + t.Fatal("unknown retention scope should be validation") + } + for _, resource := range []struct{ typ, id string }{{"", ""}, {"tenant", "ten_1"}, {"product", "prod_1"}, {"project", "proj_1"}, {"release", "rel_1"}, {"customer_security_package", "pkg_1"}, {"evidence_bundle", "eb_1"}} { + if err := ledger.ensureRoleResourceLocked("ten_1", resource.typ, resource.id); err != nil { + t.Fatalf("role resource %s: %v", resource.typ, err) + } + } + if !errors.Is(ledger.ensureRoleResourceLocked("ten_1", "", "unexpected"), ErrValidation) { + t.Fatal("empty resource type with id should be validation") + } + if !validRoleSubject("user") || !validRoleSubject("collector") || validRoleSubject("group") { + t.Fatal("role subject validation mismatch") + } + for _, role := range []string{"tenant_admin", "security_engineer", "release_manager", "customer_verifier", "collector"} { + if !validRole(role) { + t.Fatalf("valid role rejected: %s", role) + } + } + if validRole("owner") { + t.Fatal("invalid role accepted") + } + grants := ledger.resourceGrantsForUserLocked("usr_1") + if len(grants) != 1 || !grantHasScope(grants[0], ScopeEvidenceRead) { + t.Fatalf("resource grants = %#v", grants) + } + if scopes := scopesFromResourceGrants(grants); len(scopes) == 0 { + t.Fatal("scopes from grants should not be empty") + } + + refs := resourceRefs{ProductID: "prod_1", ProjectID: "proj_1", ReleaseID: "rel_1", SourceRepositoryID: "repo_1", CustomerPackageID: "pkg_1", EvidenceBundleID: "eb_1"} + for _, grant := range []domain.ResourceGrant{ + {ResourceType: "tenant", ResourceID: "ten_1", Scopes: []string{ScopeEvidenceRead}}, + {ResourceType: "product", ResourceID: "prod_1", Scopes: []string{ScopeEvidenceRead}}, + {ResourceType: "project", ResourceID: "proj_1", Scopes: []string{ScopeEvidenceRead}}, + {ResourceType: "release", ResourceID: "rel_1", Scopes: []string{ScopeEvidenceRead}}, + {ResourceType: "customer_security_package", ResourceID: "pkg_1", Scopes: []string{ScopeEvidenceRead}}, + {ResourceType: "evidence_bundle", ResourceID: "eb_1", Scopes: []string{ScopeEvidenceRead}}, + } { + if !ledger.grantCoversResourceLocked("ten_1", grant, refs) { + t.Fatalf("grant should cover refs: %#v", grant) + } + } + if ledger.grantCoversResourceLocked("ten_1", domain.ResourceGrant{ResourceType: "unknown", ResourceID: "id"}, refs) { + t.Fatal("unknown grant resource should not cover refs") + } + + for _, subject := range []struct{ typ, id string }{ + {"tenant", "ten_1"}, {"product", "prod_1"}, {"release", "rel_1"}, {"evidence", "ev_1"}, {"build", "build_1"}, {"customer_package", "pkg_1"}, + } { + if _, err := ledger.ensureFutureSubjectLocked("ten_1", subject.typ, subject.id); err != nil { + t.Fatalf("future subject %s: %v", subject.typ, err) + } + } + if !errors.Is(mustErrFuture(ledger.ensureFutureSubjectLocked("ten_1", "unknown", "id")), ErrValidation) { + t.Fatal("unknown future subject should be validation") + } + ids := ledger.evidenceIDsForQuestionLocked("ten_1", domain.QuestionnaireQuestion{ControlID: "ctrl_1"}, "prod_1", "rel_1") + if len(ids) != 1 || ids[0] != "ev_1" { + t.Fatalf("control question evidence ids = %#v", ids) + } + ids = ledger.evidenceIDsForQuestionLocked("ten_1", domain.QuestionnaireQuestion{EvidenceType: "sbom"}, "prod_1", "rel_1") + if len(ids) != 1 || ids[0] != "ev_1" { + t.Fatalf("typed question evidence ids = %#v", ids) + } + if !evidenceMatchesRefs(ledger.evidence["ev_1"], resourceRefs{ProductID: "prod_1", ProjectID: "proj_1", ReleaseID: "rel_1"}) { + t.Fatal("evidence should match refs") + } + if evidenceMatchesRefs(ledger.evidence["ev_1"], resourceRefs{ProductID: "other"}) || evidenceMatchesRefs(ledger.evidence["ev_1"], resourceRefs{ProjectID: "other"}) || evidenceMatchesRefs(ledger.evidence["ev_1"], resourceRefs{ReleaseID: "other"}) { + t.Fatal("evidence should not match wrong refs") + } + items := []domain.MarketplaceCollector{{ID: "z"}, {ID: "a"}, {ID: "m"}} + sortMarketplaceCollectors(items) + if items[0].ID != "a" || items[2].ID != "z" { + t.Fatalf("marketplace sort = %#v", items) + } + + for _, scope := range []string{"release", "finding", "control", "policy"} { + if !validWaiverScope(scope) { + t.Fatalf("valid waiver scope rejected: %s", scope) + } + } + for _, subject := range []string{"release", "contract_diff", "waiver", "security_review", "customer_package"} { + if !validApprovalSubject(subject) { + t.Fatalf("valid approval subject rejected: %s", subject) + } + } + if !validApprovalDecision("approved") || !validApprovalDecision("rejected") || validApprovalDecision("maybe") { + t.Fatal("approval decision validation mismatch") + } + for _, scope := range []struct{ typ, id string }{{"release", "rel_1"}, {"control", "ctrl_1"}, {"policy", "pol_1"}, {"finding", "finding_1"}} { + if err := ledger.ensureWaiverScopeLocked("ten_1", scope.typ, scope.id); err != nil { + t.Fatalf("waiver scope %s: %v", scope.typ, err) + } + } + for _, subject := range []struct{ typ, id string }{{"release", "rel_1"}, {"contract_diff", "cdiff_1"}, {"waiver", "waiver_1"}, {"security_review", "review_1"}, {"customer_package", "pkg_1"}} { + if err := ledger.ensureApprovalSubjectLocked("ten_1", subject.typ, subject.id); err != nil { + t.Fatalf("approval subject %s: %v", subject.typ, err) + } + } + if first := ledger.firstFrameworkIDLocked("ten_1"); first != "fw_2" { + t.Fatalf("first framework = %s", first) + } +} + +func mustErrFuture(_ resourceRefs, err error) error { return err } diff --git a/internal/app/coverage_more_test.go b/internal/app/coverage_more_test.go new file mode 100644 index 0000000..1fe2350 --- /dev/null +++ b/internal/app/coverage_more_test.go @@ -0,0 +1,301 @@ +package app + +import ( + "context" + "errors" + "testing" + "time" + + "github.com/aatuh/evydence/internal/domain" +) + +func TestImplementationIncrementReadListAndHelperBranches(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, release, artifact := setupReleaseRiskFixture(t, ledger) + project, err := ledger.CreateProject(ctx, actor, release.ProductID, "api") + if err != nil { + t.Fatalf("project: %v", err) + } + build, err := ledger.CreateBuildRun(ctx, actor, CreateBuildRunInput{ + ProjectID: project.ID, + ReleaseID: release.ID, + Provider: "generic_ci", + CommitSHA: "0123456789abcdef0123456789abcdef01234567", + Status: "passed", + StartedAt: fixedNow(), + Outputs: []domain.BuildOutput{{ArtifactID: artifact.ID, Digest: artifact.Digest}}, + }) + if err != nil { + t.Fatalf("build: %v", err) + } + sbom, err := ledger.UploadSBOM(ctx, actor, release.ID, artifact.ID, []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","components":[{"name":"api","purl":"pkg:oci/api"}]}`)) + if err != nil { + t.Fatalf("sbom: %v", err) + } + scan, err := ledger.UploadVulnerabilityScan(ctx, actor, []byte(`{"scanner":"grype","target_ref":"pkg:oci/api","release_id":"`+release.ID+`","findings":[{"vulnerability":"CVE-2026-0001","component":"api","severity":"critical","state":"open"}]}`)) + if err != nil { + t.Fatalf("scan: %v", err) + } + vex, err := ledger.UploadVEX(ctx, actor, release.ID, artifact.ID, []byte(`{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex","author":"security@example.test","timestamp":"2026-05-28T12:00:00Z","version":1,"statements":[{"vulnerability":{"name":"CVE-2026-0001"},"products":[{"@id":"pkg:oci/api"}],"status":"under_investigation","justification":"triage","impact_statement":"reviewing","action_statement":"track"}]}`)) + if err != nil { + t.Fatalf("vex: %v", err) + } + contract, err := ledger.UploadOpenAPIContract(ctx, actor, release.ProductID, release.ID, "v1", []byte(`{"openapi":"3.1.0","info":{"title":"API","version":"1"},"paths":{"/health":{"get":{"responses":{"200":{"description":"ok"}}}}}}`)) + if err != nil { + t.Fatalf("contract: %v", err) + } + bundle, err := ledger.CreateReleaseBundle(ctx, actor, release.ID) + if err != nil { + t.Fatalf("bundle: %v", err) + } + candidate, err := ledger.CreateReleaseCandidate(ctx, actor, CreateReleaseCandidateInput{ + ReleaseID: release.ID, + Name: "rc-full", + BuildIDs: []string{build.ID}, + ArtifactIDs: []string{artifact.ID}, + SBOMIDs: []string{sbom.ID}, + ScanIDs: []string{scan.ID}, + VEXIDs: []string{vex.ID}, + ContractIDs: []string{contract.ID}, + BundleIDs: []string{bundle.ID}, + }) + if err != nil { + t.Fatalf("candidate with all refs: %v", err) + } + if got, err := ledger.GetReleaseCandidate(ctx, actor, candidate.ID); err != nil || got.ID != candidate.ID { + t.Fatalf("get candidate=%#v err=%v", got, err) + } + if listed, err := ledger.ListReleaseCandidates(ctx, actor, release.ID); err != nil || len(listed) != 1 { + t.Fatalf("list candidates=%#v err=%v", listed, err) + } + reject, err := ledger.CreateReleaseCandidate(ctx, actor, CreateReleaseCandidateInput{ReleaseID: release.ID, Name: "rc-reject"}) + if err != nil { + t.Fatalf("reject candidate: %v", err) + } + if rejected, err := ledger.UpdateReleaseCandidateState(ctx, actor, reject.ID, candidateRejected, "bad build"); err != nil || rejected.RejectedAt == nil { + t.Fatalf("rejected candidate=%#v err=%v", rejected, err) + } + if _, err := ledger.CreateReleaseCandidate(ctx, actor, CreateReleaseCandidateInput{ReleaseID: release.ID, Name: "bad", BuildIDs: []string{"missing"}}); !errors.Is(err, ErrNotFound) { + t.Fatalf("missing build candidate err=%v, want not found", err) + } + + sig, err := ledger.CreateArtifactSignature(ctx, actor, CreateArtifactSignatureInput{ArtifactID: artifact.ID, Algorithm: "cosign", Signature: "sig"}) + if err != nil { + t.Fatalf("artifact signature: %v", err) + } + if got, err := ledger.GetArtifactSignature(ctx, actor, sig.ID); err != nil || got.ID != sig.ID { + t.Fatalf("get artifact signature=%#v err=%v", got, err) + } + if duplicate, err := ledger.RegisterContainerImage(ctx, actor, RegisterContainerImageInput{ArtifactID: artifact.ID, Repository: "ghcr.io/example/api", Digest: artifact.Digest}); err != nil { + t.Fatalf("image: %v", err) + } else if again, err := ledger.RegisterContainerImage(ctx, actor, RegisterContainerImageInput{ArtifactID: artifact.ID, Repository: "ghcr.io/example/api", Digest: artifact.Digest}); err != nil || again.ID != duplicate.ID { + t.Fatalf("duplicate image=%#v err=%v", again, err) + } + + repo, err := ledger.CreateSourceRepository(ctx, actor, CreateRepositoryInput{ProjectID: project.ID, Provider: "github", FullName: "aatuh/evydence", DefaultBranch: "main"}) + if err != nil { + t.Fatalf("repo: %v", err) + } + if again, err := ledger.CreateSourceRepository(ctx, actor, CreateRepositoryInput{ProjectID: project.ID, Provider: "github", FullName: "aatuh/evydence"}); err != nil || again.ID != repo.ID { + t.Fatalf("duplicate repo=%#v err=%v", again, err) + } + commit, err := ledger.RecordSourceCommit(ctx, actor, RecordCommitInput{RepositoryID: repo.ID, SHA: "1123456789abcdef0123456789abcdef01234567", Message: "change"}) + if err != nil { + t.Fatalf("commit: %v", err) + } + branch, err := ledger.UpsertSourceBranch(ctx, actor, UpsertBranchInput{RepositoryID: repo.ID, Name: "main", HeadCommitID: commit.ID, Protected: true, ProtectionHash: sampleDigest("branch")}) + if err != nil { + t.Fatalf("branch: %v", err) + } + updated, err := ledger.UpsertSourceBranch(ctx, actor, UpsertBranchInput{RepositoryID: repo.ID, Name: "main", HeadCommitID: commit.ID, Protected: false}) + if err != nil || updated.ID != branch.ID || updated.Protected { + t.Fatalf("updated branch=%#v err=%v", updated, err) + } + if _, err := ledger.RecordPullRequest(ctx, actor, RecordPullRequestInput{RepositoryID: repo.ID, ProviderID: "1", Title: "Change", State: "closed", HeadCommitID: commit.ID}); err != nil { + t.Fatalf("pr closed: %v", err) + } + if listed, err := ledger.ListSourceRepositories(ctx, actor, project.ID); err != nil || len(listed) == 0 { + t.Fatalf("list repos=%#v err=%v", listed, err) + } + if _, err := ledger.UploadGitHubSourceSnapshot(ctx, actor, []byte(`{"project_id":"`+project.ID+`","repository":{"full_name":"aatuh/evydence","default_branch":"main"},"commit":{"sha":"2123456789abcdef0123456789abcdef01234567","author":"dev@example.test","message":"change","committed_at":"2026-05-28T12:00:00Z"},"branch":{"name":"main","protected":true,"protection_hash":"`+sampleDigest("protection")+`"},"pull_request":{"provider_id":"2","title":"Change 2","state":"open","source_branch":"feature","target_branch":"main","review_decision":"review_required"}}`)); err != nil { + t.Fatalf("github snapshot: %v", err) + } + + env, err := ledger.CreateDeploymentEnvironment(ctx, actor, CreateEnvironmentInput{ProductID: release.ProductID, Name: "prod", Kind: "production"}) + if err != nil { + t.Fatalf("env: %v", err) + } + if envAgain, err := ledger.CreateDeploymentEnvironment(ctx, actor, CreateEnvironmentInput{ProductID: release.ProductID, Name: "prod", Kind: "production"}); err != nil || envAgain.ID != env.ID { + t.Fatalf("duplicate env=%#v err=%v", envAgain, err) + } + if envs, err := ledger.ListDeploymentEnvironments(ctx, actor, release.ProductID); err != nil || len(envs) != 1 { + t.Fatalf("list envs=%#v err=%v", envs, err) + } + deployment, err := ledger.RecordDeployment(ctx, actor, RecordDeploymentInput{EnvironmentID: env.ID, ReleaseID: release.ID, ArtifactIDs: []string{artifact.ID}, Status: deploymentStatusFailed, StartedAt: fixedNow()}) + if err != nil { + t.Fatalf("deployment: %v", err) + } + rollback, err := ledger.RecordDeployment(ctx, actor, RecordDeploymentInput{EnvironmentID: env.ID, ReleaseID: release.ID, Status: deploymentStatusRolledBack, RollbackOf: deployment.ID}) + if err != nil { + t.Fatalf("rollback: %v", err) + } + if got, err := ledger.GetDeployment(ctx, actor, rollback.ID); err != nil || got.RollbackOf != deployment.ID { + t.Fatalf("get rollback=%#v err=%v", got, err) + } + if listed, err := ledger.ListDeployments(ctx, actor, release.ID, env.ID); err != nil || len(listed) != 2 { + t.Fatalf("list deployments=%#v err=%v", listed, err) + } +} + +func TestSearchAndControlHelperBranches(t *testing.T) { + item := domain.EvidenceItem{ + ID: "ev_1", + TenantID: "ten_1", + ProductID: "prod_1", + ProjectID: "proj_1", + ReleaseID: "rel_1", + BuildID: "build_1", + DeploymentID: "dep_1", + Type: "sbom", + Subtype: "cyclonedx", + SourceSystem: "github", + CollectorID: "collector_1", + VerificationStatus: "verified", + Tags: []string{"release"}, + SubjectRefs: []domain.SubjectRef{{Type: "artifact", ID: "art_1", Digest: sampleDigest("artifact")}}, + CreatedAt: fixedNow(), + } + matching := EvidenceSearchInput{ProductID: "prod_1", ProjectID: "proj_1", ReleaseID: "rel_1", BuildID: "build_1", DeploymentID: "dep_1", Type: "sbom", Subtype: "cyclonedx", SourceSystem: "github", CollectorID: "collector_1", VerificationStatus: "verified", SubjectType: "artifact", SubjectID: "art_1", Tag: "release", CreatedAfter: fixedNow().Add(-time.Hour), CreatedBefore: fixedNow().Add(time.Hour)} + if !matchesEvidenceSearch(item, matching) { + t.Fatal("expected all search fields to match") + } + negativeCases := []EvidenceSearchInput{ + {ProductID: "other"}, {ProjectID: "other"}, {ReleaseID: "other"}, {BuildID: "other"}, {DeploymentID: "other"}, + {Type: "scan"}, {Subtype: "spdx"}, {SourceSystem: "gitlab"}, {CollectorID: "other"}, {VerificationStatus: "failed"}, + {CreatedAfter: fixedNow().Add(time.Hour)}, {CreatedBefore: fixedNow().Add(-time.Hour)}, {Tag: "missing"}, + {SubjectType: "release"}, {SubjectID: "missing"}, + } + for _, in := range negativeCases { + if matchesEvidenceSearch(item, in) { + t.Fatalf("search should not match for %#v", in) + } + } + for _, action := range []string{lifecycleAmendment, lifecycleRedaction, lifecycleTombstone, lifecycleRetentionMarker} { + if !validLifecycleAction(action) { + t.Fatalf("valid lifecycle action rejected: %s", action) + } + } + if validLifecycleAction("delete") || validPullRequestState("draft") || validDeploymentStatus("unknown") { + t.Fatal("invalid helper values should be rejected") + } + for _, state := range []string{"open", "closed", "merged"} { + if !validPullRequestState(state) { + t.Fatalf("valid pull request state rejected: %s", state) + } + } + for _, status := range []string{deploymentStatusStarted, deploymentStatusSucceeded, deploymentStatusFailed, deploymentStatusRolledBack} { + if !validDeploymentStatus(status) { + t.Fatalf("valid deployment status rejected: %s", status) + } + } +} + +func TestControlSubjectResolutionCoversAllSupportedSubjects(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, release, artifact := setupReleaseRiskFixture(t, ledger) + project, err := ledger.CreateProject(ctx, actor, release.ProductID, "api") + if err != nil { + t.Fatalf("project: %v", err) + } + evidence, err := ledger.CreateEvidence(ctx, actor, CreateEvidenceInput{ProductID: release.ProductID, ProjectID: project.ID, ReleaseID: release.ID, Type: "manual", Title: "manual", PayloadHash: sampleDigest("evidence")}) + if err != nil { + t.Fatalf("evidence: %v", err) + } + sbom, err := ledger.UploadSBOM(ctx, actor, release.ID, artifact.ID, []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","components":[{"name":"api"}]}`)) + if err != nil { + t.Fatalf("sbom: %v", err) + } + scan, err := ledger.UploadVulnerabilityScan(ctx, actor, []byte(`{"scanner":"grype","target_ref":"pkg:oci/api","release_id":"`+release.ID+`","findings":[{"vulnerability":"CVE-2026-0001","component":"api","severity":"critical","state":"open"}]}`)) + if err != nil { + t.Fatalf("scan: %v", err) + } + decision, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{Status: decisionStatusFixed, Justification: "fixed"}) + if err != nil { + t.Fatalf("decision: %v", err) + } + vex, err := ledger.UploadVEX(ctx, actor, release.ID, artifact.ID, []byte(`{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex","author":"security@example.test","timestamp":"2026-05-28T12:00:00Z","version":1,"statements":[{"vulnerability":{"name":"CVE-2026-0001"},"products":[{"@id":"pkg:oci/api"}],"status":"fixed","justification":"fixed","impact_statement":"fixed","action_statement":"none"}]}`)) + if err != nil { + t.Fatalf("vex: %v", err) + } + exception, err := ledger.CreateException(ctx, actor, CreateExceptionInput{ReleaseID: release.ID, FindingID: scan.Findings[0].ID, Reason: "accepted", Owner: "security", ExpiresAt: fixedNow().Add(time.Hour)}) + if err != nil { + t.Fatalf("exception: %v", err) + } + build, err := ledger.CreateBuildRun(ctx, actor, CreateBuildRunInput{ProjectID: project.ID, ReleaseID: release.ID, Provider: "generic_ci", CommitSHA: "3123456789abcdef0123456789abcdef01234567", Status: "passed", StartedAt: fixedNow(), Outputs: []domain.BuildOutput{{ArtifactID: artifact.ID, Digest: artifact.Digest}}}) + if err != nil { + t.Fatalf("build: %v", err) + } + attestation, err := ledger.UploadBuildAttestation(ctx, actor, build.ID, dsseForDigest(t, artifact.Digest)) + if err != nil { + t.Fatalf("attestation: %v", err) + } + contract, err := ledger.UploadOpenAPIContract(ctx, actor, release.ProductID, release.ID, "v1", []byte(`{"openapi":"3.1.0","info":{"title":"API","version":"1"},"paths":{"/health":{"get":{"responses":{"200":{"description":"ok"}}}}}}`)) + if err != nil { + t.Fatalf("contract: %v", err) + } + bundle, err := ledger.CreateReleaseBundle(ctx, actor, release.ID) + if err != nil { + t.Fatalf("bundle: %v", err) + } + + ledger.mu.Lock() + defer ledger.mu.Unlock() + subjects := map[string]string{ + "evidence": evidence.ID, + "evidence_item": evidence.ID, + "product": release.ProductID, + "release": release.ID, + "artifact": artifact.ID, + "sbom": sbom.ID, + "vulnerability_scan": scan.ID, + "vex": vex.ID, + "vulnerability_decision": decision.ID, + "finding": scan.Findings[0].ID, + "vulnerability_finding": scan.Findings[0].ID, + "exception": exception.ID, + "build": build.ID, + "build_attestation": attestation.ID, + "openapi_contract": contract.ID, + "release_bundle": bundle.ID, + } + for subjectType, subjectID := range subjects { + if !ledger.controlSubjectExistsLocked(actor.TenantID, subjectType, subjectID, release.ProductID, release.ID) { + t.Fatalf("expected control subject %s/%s to exist", subjectType, subjectID) + } + } + if ledger.controlSubjectExistsLocked(actor.TenantID, "unknown", "id", release.ProductID, release.ID) { + t.Fatal("unknown control subject should not exist") + } + refs := []resourceRefs{ + ledger.refsForControlEvidenceSubjectLocked("evidence", evidence.ID, "", ""), + ledger.refsForControlEvidenceSubjectLocked("build_attestation", attestation.ID, "", ""), + ledger.refsForControlEvidenceSubjectLocked("vulnerability_scan", scan.ID, "", ""), + ledger.refsForControlEvidenceSubjectLocked("openapi_contract", contract.ID, "", ""), + ledger.refsForControlEvidenceSubjectLocked("release_bundle", bundle.ID, "", ""), + ledger.refsForControlEvidenceSubjectLocked("customer_package", "pkg_1", "", ""), + } + if refs[0].ProductID != release.ProductID || refs[1].BuildID != build.ID || refs[5].CustomerPackageID != "pkg_1" { + t.Fatalf("unexpected refs: %#v", refs) + } + for subjectType, subjectID := range map[string]string{ + "evidence": evidence.ID, "sbom": sbom.ID, "vulnerability_scan": scan.ID, "vex": vex.ID, + "vulnerability_decision": decision.ID, "exception": exception.ID, "build": build.ID, + "build_attestation": attestation.ID, "openapi_contract": contract.ID, "release_bundle": bundle.ID, + } { + if got := ledger.controlEvidenceTimeLocked(domain.ControlEvidence{SubjectType: subjectType, SubjectID: subjectID, CreatedAt: fixedNow().Add(-time.Hour)}); got.IsZero() { + t.Fatalf("zero evidence time for %s", subjectType) + } + } +} diff --git a/internal/app/risk_workflows_more_test.go b/internal/app/risk_workflows_more_test.go new file mode 100644 index 0000000..cbefb11 --- /dev/null +++ b/internal/app/risk_workflows_more_test.go @@ -0,0 +1,183 @@ +package app + +import ( + "context" + "testing" + "time" + + "github.com/aatuh/evydence/internal/domain" +) + +func TestRiskWorkflowEvidenceFormatsAndReports(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, release, artifact := setupReleaseRiskFixture(t, ledger) + evidence, err := ledger.CreateEvidence(ctx, actor, CreateEvidenceInput{ProductID: release.ProductID, ReleaseID: release.ID, Type: "security_review", Title: "Review", PayloadHash: sampleDigest("review")}) + if err != nil { + t.Fatalf("evidence: %v", err) + } + incident, err := ledger.CreateIncident(ctx, actor, CreateIncidentInput{ProductID: release.ProductID, ReleaseID: release.ID, Title: "Critical vuln", Severity: "critical"}) + if err != nil { + t.Fatalf("incident: %v", err) + } + if _, err := ledger.RecordIncidentTimelineEvent(ctx, actor, incident.ID, RecordIncidentTimelineInput{EventType: "detected", Summary: "scan detected issue", EvidenceID: evidence.ID}); err != nil { + t.Fatalf("timeline: %v", err) + } + due := fixedNow().Add(24 * time.Hour) + if _, err := ledger.CreateRemediationTask(ctx, actor, CreateRemediationTaskInput{IncidentID: incident.ID, ReleaseID: release.ID, Title: "Patch", Owner: "security", DueAt: &due, EvidenceID: evidence.ID}); err != nil { + t.Fatalf("task: %v", err) + } + if report, err := ledger.IncidentReport(ctx, actor, incident.ID); err != nil || len(report.Timeline) != 1 || len(report.Tasks) != 1 || len(report.LinkedEvidence) == 0 { + t.Fatalf("incident report=%#v err=%v", report, err) + } + + sarif, err := ledger.UploadSecurityScan(ctx, actor, UploadSecurityScanInput{ + ProductID: release.ProductID, ReleaseID: release.ID, ArtifactID: artifact.ID, + Category: "sast", Format: "sarif", Scanner: "codeql", TargetRef: "git:main", + Raw: []byte(`{"version":"2.1.0","runs":[{"results":[{"level":"error"},{"level":""}]}]}`), + }) + if err != nil { + t.Fatalf("sarif scan: %v", err) + } + if sarif.FindingCount != 2 || sarif.Summary["warning"] != 1 { + t.Fatalf("sarif summary = %#v", sarif) + } + secretScan, err := ledger.UploadSecurityScan(ctx, actor, UploadSecurityScanInput{ + ProductID: release.ProductID, ReleaseID: release.ID, + Category: "secret_scan", Scanner: "gitleaks", TargetRef: "git:main", + Raw: []byte(`{"findings":[{"severity":"high"}]}`), + }) + if err != nil { + t.Fatalf("secret scan: %v", err) + } + if !secretScan.Redacted || !secretScan.Quarantined { + t.Fatalf("secret scan should be redacted/quarantined: %#v", secretScan) + } + apiScan, err := ledger.UploadAPISecurityScan(ctx, actor, UploadSecurityScanInput{ + ProductID: release.ProductID, ReleaseID: release.ID, Scanner: "zap", TargetRef: "openapi", + Raw: []byte(`{"findings":[{"severity":"medium"},{"severity":""}]}`), + }) + if err != nil { + t.Fatalf("api security scan: %v", err) + } + if apiScan.Category != "api_security" || apiScan.Summary["unknown"] != 1 { + t.Fatalf("api scan = %#v", apiScan) + } + if _, err := ledger.UploadManualSecurityDocument(ctx, actor, UploadManualSecurityDocumentInput{ProductID: release.ProductID, ReleaseID: release.ID, DocumentType: "threat_model", Title: "Threat Model", Sensitivity: "restricted", Raw: []byte("model"), MediaType: "text/plain"}); err != nil { + t.Fatalf("manual doc: %v", err) + } + + base, err := ledger.UploadSPDXSBOM(ctx, actor, release.ID, artifact.ID, []byte(`{"spdxVersion":"SPDX-2.3","packages":[{"name":"api","versionInfo":"1.0.0","externalRefs":[{"referenceType":"purl","referenceLocator":"pkg:oci/api@1.0.0"}]},{"name":"old","versionInfo":"1.0.0"}]}`)) + if err != nil { + t.Fatalf("base spdx: %v", err) + } + target, err := ledger.UploadSPDXSBOM(ctx, actor, release.ID, artifact.ID, []byte(`{"spdxVersion":"SPDX-2.3","packages":[{"name":"api","versionInfo":"1.0.0","externalRefs":[{"referenceType":"purl","referenceLocator":"pkg:oci/api@1.0.0"}]},{"name":"new","versionInfo":"1.0.0"}]}`)) + if err != nil { + t.Fatalf("target spdx: %v", err) + } + diff, err := ledger.CreateSBOMDiff(ctx, actor, CreateSBOMDiffInput{BaseSBOMID: base.ID, TargetSBOMID: target.ID, ReleaseID: release.ID}) + if err != nil { + t.Fatalf("sbom diff: %v", err) + } + if diff.UnchangedCount != 1 || len(diff.AddedComponents) != 1 || len(diff.RemovedComponents) != 1 || len(diff.DependencyChanges) != 2 { + t.Fatalf("diff = %#v", diff) + } + + scan, err := ledger.UploadVulnerabilityScan(ctx, actor, []byte(`{"scanner":"grype","target_ref":"pkg:oci/api","release_id":"`+release.ID+`","findings":[{"vulnerability":"CVE-2026-0002","component":"api","severity":"critical","state":"open"}]}`)) + if err != nil { + t.Fatalf("vuln scan: %v", err) + } + cdxVEX, err := ledger.UploadCycloneDXVEX(ctx, actor, release.ID, artifact.ID, []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","vulnerabilities":[{"id":"CVE-2026-0002","analysis":{"state":"resolved","justification":"code_not_present","detail":"fixed","response":["update"]}}]}`)) + if err != nil { + t.Fatalf("cyclonedx vex: %v", err) + } + if cdxVEX.StatusSummary["fixed"] != 1 { + t.Fatalf("cdx vex = %#v", cdxVEX) + } + if _, err := ledger.RecordVulnerabilityWorkflow(ctx, actor, RecordVulnerabilityWorkflowInput{FindingID: scan.Findings[0].ID, Action: "scanner_metadata", Reason: "database version captured"}); err != nil { + t.Fatalf("workflow: %v", err) + } + if posture, err := ledger.VulnerabilityPostureReport(ctx, actor, release.ID); err != nil || posture.OpenCritical != 1 { + t.Fatalf("posture=%#v err=%v", posture, err) + } + + baseContract, err := ledger.UploadOpenAPIContract(ctx, actor, release.ProductID, release.ID, "base", []byte(`{"openapi":"3.1.0","info":{"title":"API","version":"1"},"paths":{"/v1/a":{"get":{"responses":{"200":{"description":"ok"}}}},"/v1/b":{"get":{"responses":{"200":{"description":"ok"}}}}}}`)) + if err != nil { + t.Fatalf("base contract: %v", err) + } + targetContract, err := ledger.UploadOpenAPIContract(ctx, actor, release.ProductID, release.ID, "target", []byte(`{"openapi":"3.1.0","info":{"title":"API","version":"2"},"paths":{"/v1/a":{"get":{"responses":{"200":{"description":"ok"}}}}}}`)) + if err != nil { + t.Fatalf("target contract: %v", err) + } + contractDiff, err := ledger.CreateContractDiff(ctx, actor, CreateContractDiffInput{BaseContractID: baseContract.ID, TargetContractID: targetContract.ID, ReleaseID: release.ID}) + if err != nil { + t.Fatalf("contract diff: %v", err) + } + if contractDiff.Result != "breaking" || len(contractDiff.BreakingChanges) != 1 { + t.Fatalf("contract diff = %#v", contractDiff) + } + + policy, err := ledger.CreateCustomPolicy(ctx, actor, CreateCustomPolicyInput{Name: "release gates", Version: "1", Rules: []domain.PolicyRule{ + {Name: "metadata", Severity: "low"}, + {Name: "sbom exists", EvidenceType: "sbom", Severity: "high", Required: true}, + {Name: "optional pen test", EvidenceType: "pen_test_report", Severity: "medium", Required: false}, + }}) + if err != nil { + t.Fatalf("policy: %v", err) + } + eval, err := ledger.EvaluateCustomPolicy(ctx, actor, policy.ID, release.ID) + if err != nil { + t.Fatalf("policy eval: %v", err) + } + if eval.Result != "passed" || len(eval.Checks) != 3 { + t.Fatalf("eval = %#v", eval) + } +} + +func TestRiskWorkflowValidationHelpers(t *testing.T) { + for _, severity := range []string{"low", "medium", "high", "critical"} { + if !validSeverity(severity) { + t.Fatalf("valid severity rejected: %s", severity) + } + } + for _, category := range []string{"sast", "dast", "secret_scan", "license_scan", "api_security"} { + if !validSecurityScanCategory(category) { + t.Fatalf("valid scan category rejected: %s", category) + } + } + for _, typ := range []string{"threat_model", "security_review", "pen_test_report"} { + if !validManualDocType(typ) { + t.Fatalf("valid doc type rejected: %s", typ) + } + } + for _, sensitivity := range []string{"internal", "confidential", "restricted"} { + if !validSensitivity(sensitivity) { + t.Fatalf("valid sensitivity rejected: %s", sensitivity) + } + } + for _, action := range []string{"scanner_metadata", "sla_set", "scanner_disagreement", "superseded", "reopened"} { + if !validVulnWorkflowAction(action) { + t.Fatalf("valid workflow action rejected: %s", action) + } + } + for _, typ := range []string{"sbom", "vulnerability_scan", "vex", "vulnerability_decision", "artifact", "build", "build_attestation", "openapi_contract", "release_bundle", "exception", "sast", "dast", "secret_scan", "license_scan", "api_security", "deployment", "threat_model", "security_review", "pen_test_report"} { + if !validPolicyEvidenceType(typ) { + t.Fatalf("valid policy evidence type rejected: %s", typ) + } + } + if validSeverity("info") || validSecurityScanCategory("container") || validManualDocType("notes") || validSensitivity("public") || validVulnWorkflowAction("ignore") || validPolicyEvidenceType("unknown") { + t.Fatal("invalid risk workflow helper value accepted") + } + if got := cyclonedxAnalysisStatus("resolved"); got != "fixed" { + t.Fatalf("resolved = %s", got) + } + if got := cyclonedxAnalysisStatus("not_affected"); got != "not_affected" { + t.Fatalf("not_affected = %s", got) + } + if got := cyclonedxAnalysisStatus("exploitable"); got != "affected" { + t.Fatalf("exploitable = %s", got) + } + if got := cyclonedxAnalysisStatus("unknown"); got != "" { + t.Fatalf("unknown = %s", got) + } +} From 0fc3e5d008ad29e9443be998ea642caeaa27c319 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 16:18:57 +0300 Subject: [PATCH 023/287] feat: add customer package zip exports --- .implementation_increments.md | 2 +- docs/api.md | 2 + docs/architecture.md | 2 +- .../adapters/httpapi/openapi_operations.go | 20 ++++ internal/adapters/httpapi/portal_handlers.go | 21 ++++ .../adapters/httpapi/route_registration.go | 2 + internal/adapters/httpapi/router.go | 22 ++++ internal/adapters/httpapi/router_test.go | 68 ++++++++++-- internal/app/governance_packages.go | 101 ++++++++++++++++++ internal/app/governance_packages_test.go | 68 ++++++++++++ openapi.yaml | 2 +- 11 files changed, 301 insertions(+), 9 deletions(-) diff --git a/.implementation_increments.md b/.implementation_increments.md index b11ffa5..9c52e2c 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -102,7 +102,7 @@ Status legend: Added explicit immutable approval records for releases, breaking API changes, waivers, security reviews, and customer packages. 28. `[x]` Customer Security Packages - Added scoped JSON package manifests, redaction profiles, expiry, access auditing, verification instructions, and over-disclosure tests. ZIP packaging remains future output-format expansion. + Added scoped JSON package manifests and ZIP downloads, redaction profiles, expiry, access auditing, verification instructions, and over-disclosure tests. ZIP packages include scoped manifest metadata and verification guidance, not raw tenant evidence payload bytes. 29. `[x]` Security Review Package Report Added scoped security-review reports for customer/procurement review with evidence summaries, assumptions, limitations, and redaction-aware output. diff --git a/docs/api.md b/docs/api.md index 9fd8452..787dec9 100644 --- a/docs/api.md +++ b/docs/api.md @@ -346,8 +346,10 @@ Source snapshots capture submitted provider metadata. They do not call provider | `POST` | `/v1/redaction-profiles` | Create package redaction profile. | | `POST` | `/v1/customer-packages` | Create scoped customer package manifest. | | `GET` | `/v1/customer-packages/{id}` | Read package manifest and record access. | +| `GET` | `/v1/customer-packages/{id}/download` | Download scoped ZIP package with manifest metadata and verification guidance. | | `POST` | `/v1/customer-portal/access` | Create one-time package access token. | | `POST` | `/v1/customer-portal/package` | Exchange package token for scoped manifest. | +| `POST` | `/v1/customer-portal/package/download` | Exchange package token for scoped ZIP package download. | | `POST` | `/v1/questionnaire-templates` | Create questionnaire template. | | `POST` | `/v1/questionnaire-packages` | Generate evidence-backed responses. | | `POST` | `/v1/questionnaire-drafts` | Create evidence-backed draft answers for review. | diff --git a/docs/architecture.md b/docs/architecture.md index 83d0895..99ad2cf 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -42,7 +42,7 @@ Control coverage and CRA-readiness reports use versioned tenant-created controls Source snapshots, deployment records, incident packages, security scans, manual reviews, SBOM diffs, contract diffs, API security checks, customer packages, customer portal package access, questionnaire packages, evidence bundles, and custom policies add traceability and reproducible decisions. Reports include gaps, assumptions, and limitations. -Evidence summaries, questionnaire drafts, graph snapshots, PDF packages, and anomaly reports are generated from stored records with citations, assumptions, and limitations. Customer-facing packages require explicit package scope, redaction profile, expiry, and access auditing. Raw tenant evidence payload bytes are not returned by customer package read paths. +Evidence summaries, questionnaire drafts, graph snapshots, PDF packages, and anomaly reports are generated from stored records with citations, assumptions, and limitations. Customer-facing packages require explicit package scope, redaction profile, expiry, and access auditing. Customer package JSON and ZIP download paths return scoped manifest metadata and verification guidance; raw tenant evidence payload bytes are not returned. ## Provider And Deployment Boundaries diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index a3321df..dc928f9 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -45,12 +45,22 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Description = "Creates token-based customer portal access for a customer package and returns the token once." operation.RequestBody = jsonRequest("Customer portal access creation request.", "#/components/schemas/CreateCustomerPortalAccessRequest") operation.Responses[http.StatusCreated] = jsonResponse("Created portal access and one-time token envelope.", "#/components/schemas/CustomerPortalAccessCreateEnvelope") + case "downloadCustomerPackage": + operation.Description = "Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes." + operation.Parameters = append(operation.Parameters, pathParam("id", "Customer package id.")) + operation.Responses[http.StatusOK] = binaryResponse("Customer security package ZIP archive.") case "accessCustomerPortalPackage": operation.Description = "Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body." operation.RequestBody = jsonRequest("Customer portal token request.", "#/components/schemas/CustomerPortalPackageRequest") operation.Security = nil operation.Scopes = nil operation.Responses[http.StatusOK] = jsonResponse("Scoped customer package envelope.", "#/components/schemas/DataEnvelope") + case "downloadCustomerPortalPackage": + operation.Description = "Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body." + operation.RequestBody = jsonRequest("Customer portal token request.", "#/components/schemas/CustomerPortalPackageRequest") + operation.Security = nil + operation.Scopes = nil + operation.Responses[http.StatusOK] = binaryResponse("Customer security package ZIP archive.") } return operation } @@ -92,6 +102,16 @@ func problemResponse(description string) specs.Response { } } +func binaryResponse(description string) specs.Response { + return specs.Response{ + Description: description, + ContentTypes: []string{"application/zip"}, + Content: map[string]specs.MediaType{ + "application/zip": {Schema: map[string]any{"type": "string", "format": "binary"}}, + }, + } +} + func queryParam(name, description, typ string) specs.Parameter { schema := map[string]any{"type": typ} if name == "limit" { diff --git a/internal/adapters/httpapi/portal_handlers.go b/internal/adapters/httpapi/portal_handlers.go index 9264b31..fbee39f 100644 --- a/internal/adapters/httpapi/portal_handlers.go +++ b/internal/adapters/httpapi/portal_handlers.go @@ -44,6 +44,27 @@ func (s *Server) accessCustomerPortalPackage(w http.ResponseWriter, r *http.Requ writeData(w, http.StatusOK, pkg) } +func (s *Server) downloadCustomerPortalPackage(w http.ResponseWriter, r *http.Request) { + var req struct { + Token string `json:"token"` + } + body, err := readBody(r) + if err != nil { + writeProblem(w, r, err) + return + } + if err := decodeJSON(body, &req); err != nil { + writeProblem(w, r, err) + return + } + archive, err := s.ledger.ExportCustomerPortalPackageArchive(r.Context(), req.Token) + if err != nil { + writeProblem(w, r, err) + return + } + writeArchive(w, archive) +} + func (s *Server) createQuestionnaireTemplate(w http.ResponseWriter, r *http.Request) { var req struct { Name string `json:"name"` diff --git a/internal/adapters/httpapi/route_registration.go b/internal/adapters/httpapi/route_registration.go index 6da3fe6..611f274 100644 --- a/internal/adapters/httpapi/route_registration.go +++ b/internal/adapters/httpapi/route_registration.go @@ -163,8 +163,10 @@ func (s *Server) packagePortalRoutes() []routeDef { {http.MethodPost, "/v1/redaction-profiles", op("createRedactionProfile", http.MethodPost, "/v1/redaction-profiles", "Create redaction profile", []string{app.ScopePackageWrite}), http.HandlerFunc(s.createRedactionProfile)}, {http.MethodPost, "/v1/customer-packages", op("createCustomerPackage", http.MethodPost, "/v1/customer-packages", "Create customer security package", []string{app.ScopePackageWrite}), http.HandlerFunc(s.createCustomerPackage)}, {http.MethodGet, "/v1/customer-packages/{id}", op("getCustomerPackage", http.MethodGet, "/v1/customer-packages/{id}", "Get customer security package", []string{app.ScopePackageRead}), http.HandlerFunc(s.getCustomerPackage)}, + {http.MethodGet, "/v1/customer-packages/{id}/download", op("downloadCustomerPackage", http.MethodGet, "/v1/customer-packages/{id}/download", "Download customer security package ZIP", []string{app.ScopePackageRead}), http.HandlerFunc(s.downloadCustomerPackage)}, {http.MethodPost, "/v1/customer-portal/access", op("createCustomerPortalAccess", http.MethodPost, "/v1/customer-portal/access", "Create customer portal access", []string{app.ScopePackageWrite}), http.HandlerFunc(s.createCustomerPortalAccess)}, {http.MethodPost, "/v1/customer-portal/package", op("accessCustomerPortalPackage", http.MethodPost, "/v1/customer-portal/package", "Access customer portal package", nil), http.HandlerFunc(s.accessCustomerPortalPackage)}, + {http.MethodPost, "/v1/customer-portal/package/download", op("downloadCustomerPortalPackage", http.MethodPost, "/v1/customer-portal/package/download", "Download customer portal package ZIP", nil), http.HandlerFunc(s.downloadCustomerPortalPackage)}, {http.MethodPost, "/v1/questionnaire-templates", op("createQuestionnaireTemplate", http.MethodPost, "/v1/questionnaire-templates", "Create questionnaire template", []string{app.ScopePackageWrite}), http.HandlerFunc(s.createQuestionnaireTemplate)}, {http.MethodPost, "/v1/questionnaire-packages", op("createQuestionnairePackage", http.MethodPost, "/v1/questionnaire-packages", "Create questionnaire package", []string{app.ScopePackageWrite}), http.HandlerFunc(s.createQuestionnairePackage)}, {http.MethodPost, "/v1/questionnaire-drafts", op("createQuestionnaireDraft", http.MethodPost, "/v1/questionnaire-drafts", "Create evidence-backed questionnaire draft", []string{app.ScopePackageRead}), http.HandlerFunc(s.createQuestionnaireDraft)}, diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index 470dad9..cd86d97 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -997,6 +997,19 @@ func (s *Server) getCustomerPackage(w http.ResponseWriter, r *http.Request) { writeData(w, http.StatusOK, pkg) } +func (s *Server) downloadCustomerPackage(w http.ResponseWriter, r *http.Request) { + actor, ok := s.authenticate(w, r) + if !ok { + return + } + archive, err := s.ledger.ExportCustomerSecurityPackageArchive(r.Context(), actor, r.PathValue("id")) + if err != nil { + writeProblem(w, r, err) + return + } + writeArchive(w, archive) +} + func (s *Server) securityReviewPackageReport(w http.ResponseWriter, r *http.Request) { actor, ok := s.authenticate(w, r) if !ok { @@ -2006,6 +2019,15 @@ func writeData(w http.ResponseWriter, status int, data any) { httpx.WriteJSON(w, status, map[string]any{"data": data, "meta": map[string]string{"api_version": "v1"}}) } +func writeArchive(w http.ResponseWriter, archive app.CustomerPackageArchive) { + w.Header().Set("Content-Type", archive.MediaType) + w.Header().Set("Content-Disposition", `attachment; filename="`+archive.Filename+`"`) + w.Header().Set("Content-Length", strconv.FormatInt(archive.Size, 10)) + w.Header().Set("X-Evydence-Archive-Hash", archive.Hash) + w.WriteHeader(http.StatusOK) + _, _ = w.Write(archive.Bytes) +} + func writeProblem(w http.ResponseWriter, r *http.Request, err error) { status := app.StatusCode(err) requestID := requestIDFromRequest(r) diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 9c29d39..a74a4b6 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -45,12 +45,14 @@ func TestRouteFamiliesRegisterCriticalPaths(t *testing.T) { } } want := map[string]string{ - "instanceAdminSnapshot": "/v1/admin/instance", - "createSSOSession": "/v1/sso/sessions", - "createCustomerPortalAccess": "/v1/customer-portal/access", - "accessCustomerPortalPackage": "/v1/customer-portal/package", - "createLegalHold": "/v1/legal-holds", - "verifyReleaseBundle": "/v1/release-bundles/{id}/verify", + "instanceAdminSnapshot": "/v1/admin/instance", + "createSSOSession": "/v1/sso/sessions", + "createCustomerPortalAccess": "/v1/customer-portal/access", + "accessCustomerPortalPackage": "/v1/customer-portal/package", + "downloadCustomerPackage": "/v1/customer-packages/{id}/download", + "downloadCustomerPortalPackage": "/v1/customer-portal/package/download", + "createLegalHold": "/v1/legal-holds", + "verifyReleaseBundle": "/v1/release-bundles/{id}/verify", } got := map[string]string{} for _, route := range server.routeDefinitions() { @@ -99,6 +101,14 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { if _, ok := portalPackage["security"]; ok { t.Fatalf("public portal token exchange should not advertise bearer security: %#v", portalPackage["security"]) } + downloadPackage := operationMap(t, paths, "/v1/customer-packages/{id}/download", "get") + assertMediaResponseType(t, downloadPackage, "200", "application/zip") + portalDownload := operationMap(t, paths, "/v1/customer-portal/package/download", "post") + assertRequestRef(t, portalDownload, "#/components/schemas/CustomerPortalPackageRequest") + assertMediaResponseType(t, portalDownload, "200", "application/zip") + if _, ok := portalDownload["security"]; ok { + t.Fatalf("public portal download should not advertise bearer security: %#v", portalDownload["security"]) + } createSession := operationMap(t, paths, "/v1/sso/sessions", "post") assertRequestRef(t, createSession, "#/components/schemas/CreateSSOSessionRequest") assertResponseRef(t, createSession, "201", "#/components/schemas/SSOSessionCreateEnvelope") @@ -660,6 +670,10 @@ func TestGovernancePackageAndBundleHTTPFlow(t *testing.T) { packageBody := postJSON(t, server, secret, "/v1/customer-packages", "gov-package", map[string]any{"product_id": productID, "release_id": releaseID, "redaction_profile_id": profileID, "title": "Customer package", "expires_at": time.Now().UTC().Add(time.Hour).Format(time.RFC3339)}, http.StatusCreated) packageID := dataField(t, packageBody, "id") getJSON(t, server, secret, "/v1/customer-packages/"+packageID, http.StatusOK) + archiveRec := getRaw(t, server, secret, "/v1/customer-packages/"+packageID+"/download", http.StatusOK) + if archiveRec.Header().Get("Content-Type") != "application/zip" || !bytes.HasPrefix(archiveRec.Body.Bytes(), []byte("PK")) || archiveRec.Header().Get("X-Evydence-Archive-Hash") == "" { + t.Fatalf("customer package archive response invalid headers=%v len=%d", archiveRec.Header(), archiveRec.Body.Len()) + } packageReport := getJSON(t, server, secret, "/v1/reports/security-review-package?package_id="+packageID, http.StatusOK) if !strings.Contains(packageReport, `"report_type":"security_review_package"`) { t.Fatalf("security review report missing type: %s", packageReport) @@ -711,6 +725,10 @@ func TestEnterprisePortalRetentionAndCommercialCollectorHTTPFlow(t *testing.T) { if !strings.Contains(portalBody, packageID) || strings.Contains(portalBody, portalSecret) { t.Fatalf("portal package response invalid: %s", portalBody) } + portalArchive := postJSONNoAuthRaw(t, server, "/v1/customer-portal/package/download", map[string]any{"token": portalSecret}, http.StatusOK) + if portalArchive.Header().Get("Content-Type") != "application/zip" || !bytes.HasPrefix(portalArchive.Body.Bytes(), []byte("PK")) || bytes.Contains(portalArchive.Body.Bytes(), []byte(portalSecret)) { + t.Fatalf("portal archive response invalid headers=%v len=%d", portalArchive.Header(), portalArchive.Body.Len()) + } postJSON(t, server, sessionSecret, "/v1/legal-holds", "ent-hold", map[string]any{"scope_type": "release", "scope_id": releaseID, "reason": "extended review", "owner": "legal"}, http.StatusCreated) postJSON(t, server, sessionSecret, "/v1/retention-overrides", "ent-retention", map[string]any{"scope_type": "evidence", "scope_id": evidenceID, "retention_until": time.Now().UTC().Add(24 * time.Hour).Format(time.RFC3339), "reason": "review", "owner": "security"}, http.StatusCreated) retention := getJSON(t, server, sessionSecret, "/v1/reports/retention?scope_type=release&scope_id="+releaseID, http.StatusOK) @@ -952,6 +970,22 @@ func postJSONNoAuth(t *testing.T, server *Server, path string, payload any, want return rec.Body.String() } +func postJSONNoAuthRaw(t *testing.T, server *Server, path string, payload any, want int) *httptest.ResponseRecorder { + t.Helper() + body, err := json.Marshal(payload) + if err != nil { + t.Fatalf("marshal: %v", err) + } + rec := httptest.NewRecorder() + req := httptest.NewRequest(http.MethodPost, path, bytes.NewReader(body)) + req.Header.Set("Content-Type", "application/json") + server.Handler().ServeHTTP(rec, req) + if rec.Code != want { + t.Fatalf("POST %s status=%d want=%d body=%s", path, rec.Code, want, rec.Body.String()) + } + return rec +} + func dataField(t *testing.T, body, field string) string { t.Helper() var decoded struct { @@ -1033,6 +1067,18 @@ func getJSON(t *testing.T, server *Server, secret, path string, want int) string return rec.Body.String() } +func getRaw(t *testing.T, server *Server, secret, path string, want int) *httptest.ResponseRecorder { + t.Helper() + rec := httptest.NewRecorder() + req := httptest.NewRequest(http.MethodGet, path, nil) + req.Header.Set("Authorization", "Bearer "+secret) + server.Handler().ServeHTTP(rec, req) + if rec.Code != want { + t.Fatalf("GET %s status=%d want=%d body=%s", path, rec.Code, want, rec.Body.String()) + } + return rec +} + func asStringAnyMap(t *testing.T, value any) map[string]any { t.Helper() out, ok := value.(map[string]any) @@ -1090,6 +1136,16 @@ func assertMediaResponseRef(t *testing.T, operation map[string]any, status, medi } } +func assertMediaResponseType(t *testing.T, operation map[string]any, status, mediaType string) { + t.Helper() + responses := asStringAnyMap(t, operation["responses"]) + response := asStringAnyMap(t, responses[status]) + content := asStringAnyMap(t, response["content"]) + if _, ok := content[mediaType]; !ok { + t.Fatalf("response %s missing media type %s: %#v", status, mediaType, content) + } +} + func assertQueryParams(t *testing.T, operation map[string]any, names ...string) { t.Helper() rawParams, ok := operation["parameters"].([]any) diff --git a/internal/app/governance_packages.go b/internal/app/governance_packages.go index ba0f01e..236dcd0 100644 --- a/internal/app/governance_packages.go +++ b/internal/app/governance_packages.go @@ -1,6 +1,8 @@ package app import ( + "archive/zip" + "bytes" "context" "crypto/ed25519" "encoding/base64" @@ -48,6 +50,15 @@ type CreateCustomerPackageInput struct { ExpiresAt time.Time } +type CustomerPackageArchive struct { + PackageID string + Filename string + MediaType string + Bytes []byte + Hash string + Size int64 +} + type CreateReportTemplateInput struct { Name string Version string @@ -294,6 +305,22 @@ func (l *Ledger) AccessCustomerSecurityPackage(ctx context.Context, actor domain return pkg, nil } +func (l *Ledger) ExportCustomerSecurityPackageArchive(ctx context.Context, actor domain.Actor, id string) (CustomerPackageArchive, error) { + pkg, err := l.AccessCustomerSecurityPackage(ctx, actor, id) + if err != nil { + return CustomerPackageArchive{}, err + } + return customerPackageArchive(pkg) +} + +func (l *Ledger) ExportCustomerPortalPackageArchive(ctx context.Context, token string) (CustomerPackageArchive, error) { + pkg, err := l.AccessCustomerPortalPackage(ctx, token) + if err != nil { + return CustomerPackageArchive{}, err + } + return customerPackageArchive(pkg) +} + func (l *Ledger) SecurityReviewPackageReport(ctx context.Context, actor domain.Actor, packageID string) (domain.SecurityReviewPackageReport, error) { pkg, err := l.AccessCustomerSecurityPackage(ctx, actor, packageID) if err != nil { @@ -313,6 +340,80 @@ func (l *Ledger) SecurityReviewPackageReport(ctx context.Context, actor domain.A return domain.SecurityReviewPackageReport{ReportType: "security_review_package", TemplateVersion: "security-review-package.v1.0.0", PackageID: pkg.ID, ProductID: pkg.ProductID, ReleaseID: pkg.ReleaseID, EvidenceIDs: ids, Assumptions: []string{"Report includes only package-scoped evidence metadata."}, Limitations: []string{"This report supports customer review but is not a compliance, legal, or secure-release conclusion."}, GeneratedAt: l.now()}, nil } +func customerPackageArchive(pkg domain.CustomerSecurityPackage) (CustomerPackageArchive, error) { + var buf bytes.Buffer + zw := zip.NewWriter(&buf) + metadata := map[string]any{ + "id": pkg.ID, + "product_id": pkg.ProductID, + "release_id": pkg.ReleaseID, + "redaction_profile_id": pkg.RedactionProfileID, + "title": pkg.Title, + "state": pkg.State, + "manifest_hash": pkg.ManifestHash, + "expires_at": pkg.ExpiresAt.UTC().Format(time.RFC3339), + "schema_version": pkg.SchemaVersion, + "created_at": pkg.CreatedAt.UTC().Format(time.RFC3339), + } + verification := map[string]any{ + "package_id": pkg.ID, + "manifest_hash": pkg.ManifestHash, + "manifest_file": "manifest.json", + "metadata_file": "package.json", + "hash_algorithm": "sha256", + "verification_note": "Verify the package manifest hash against the Evydence API or a signed bundle before relying on contents.", + "limitations": []string{ + "Archive contents are scoped and redacted.", + "Raw tenant evidence payload bytes are not included.", + "This package supports technical evidence review and does not prove legal compliance, certification, or release security status.", + }, + } + readme := "Evydence customer security package\n\n" + + "This ZIP contains a scoped package manifest, package metadata, and verification guidance.\n" + + "It intentionally excludes raw tenant evidence payload bytes and bearer tokens.\n" + + "Use the manifest hash with Evydence verification records or signed bundles before relying on package contents.\n" + for _, entry := range []struct { + name string + body any + }{ + {name: "manifest.json", body: pkg.Manifest}, + {name: "package.json", body: metadata}, + {name: "verification.json", body: verification}, + } { + body, err := json.MarshalIndent(entry.body, "", " ") + if err != nil { + _ = zw.Close() + return CustomerPackageArchive{}, err + } + body = append(body, '\n') + if err := addZIPFile(zw, entry.name, body); err != nil { + _ = zw.Close() + return CustomerPackageArchive{}, err + } + } + if err := addZIPFile(zw, "README.txt", []byte(readme)); err != nil { + _ = zw.Close() + return CustomerPackageArchive{}, err + } + if err := zw.Close(); err != nil { + return CustomerPackageArchive{}, err + } + body := buf.Bytes() + return CustomerPackageArchive{PackageID: pkg.ID, Filename: "evydence-customer-package-" + pkg.ID + ".zip", MediaType: "application/zip", Bytes: body, Hash: hashBytes(body), Size: int64(len(body))}, nil +} + +func addZIPFile(zw *zip.Writer, name string, body []byte) error { + header := &zip.FileHeader{Name: name, Method: zip.Deflate} + header.SetMode(0o644) + header.Modified = time.Date(1980, 1, 1, 0, 0, 0, 0, time.UTC) + writer, err := zw.CreateHeader(header) + if err != nil { + return err + } + _, err = writer.Write(body) + return err +} + func (l *Ledger) CRAReadinessHTMLPackage(ctx context.Context, actor domain.Actor, productID, releaseID string) (domain.HTMLReportPackage, error) { report, err := l.CRAReadinessReport(ctx, actor, CRAReadinessReportInput{ProductID: productID, ReleaseID: releaseID}) if err != nil { diff --git a/internal/app/governance_packages_test.go b/internal/app/governance_packages_test.go index c76d192..d6c0385 100644 --- a/internal/app/governance_packages_test.go +++ b/internal/app/governance_packages_test.go @@ -1,12 +1,16 @@ package app import ( + "archive/zip" + "bytes" "context" "crypto/ed25519" "crypto/rand" "encoding/base64" "encoding/json" "errors" + "io" + "strings" "testing" "time" @@ -57,6 +61,37 @@ func TestWaiverApprovalAndCustomerPackageFlow(t *testing.T) { if len(report.EvidenceIDs) != 1 || report.EvidenceIDs[0] != item.ID { t.Fatalf("report evidence ids = %#v, want package evidence", report.EvidenceIDs) } + archive, err := ledger.ExportCustomerSecurityPackageArchive(ctx, actor, pkg.ID) + if err != nil { + t.Fatalf("export package archive: %v", err) + } + if archive.MediaType != "application/zip" || archive.Hash != hashBytes(archive.Bytes) || archive.Size != int64(len(archive.Bytes)) { + t.Fatalf("archive metadata invalid: %#v", archive) + } + files := packageArchiveFiles(t, archive.Bytes) + for _, name := range []string{"manifest.json", "package.json", "verification.json", "README.txt"} { + if files[name] == "" { + t.Fatalf("archive missing %s: %#v", name, files) + } + } + archiveText := strings.Join([]string{files["manifest.json"], files["package.json"], files["verification.json"], files["README.txt"]}, "\n") + if !strings.Contains(archiveText, item.ID) { + t.Fatalf("archive manifest missing package evidence id: %s", archiveText) + } + if strings.Contains(archiveText, `"tenant_id"`) || strings.Contains(archiveText, "legally compliant") || strings.Contains(archiveText, "certified secure") { + t.Fatalf("archive leaked tenant internals or prohibited claims: %s", archiveText) + } + _, portalSecret, err := ledger.CreateCustomerPortalAccess(ctx, actor, CreateCustomerPortalAccessInput{PackageID: pkg.ID, CustomerName: "Customer", ExpiresAt: fixedNow().Add(time.Hour)}) + if err != nil { + t.Fatalf("portal access: %v", err) + } + portalArchive, err := ledger.ExportCustomerPortalPackageArchive(ctx, portalSecret) + if err != nil { + t.Fatalf("portal export archive: %v", err) + } + if strings.Contains(strings.Join(mapValues(packageArchiveFiles(t, portalArchive.Bytes)), "\n"), portalSecret) { + t.Fatalf("portal archive leaked access token") + } _, _, secretB, err := ledger.BootstrapTenant(ctx, "Tenant B", "admin-b", []string{"*"}) if err != nil { t.Fatalf("bootstrap B: %v", err) @@ -68,6 +103,39 @@ func TestWaiverApprovalAndCustomerPackageFlow(t *testing.T) { if _, err := ledger.AccessCustomerSecurityPackage(ctx, actorB, pkg.ID); !errors.Is(err, ErrNotFound) { t.Fatalf("cross-tenant package err=%v, want not found", err) } + if _, err := ledger.ExportCustomerSecurityPackageArchive(ctx, actorB, pkg.ID); !errors.Is(err, ErrNotFound) { + t.Fatalf("cross-tenant package archive err=%v, want not found", err) + } +} + +func packageArchiveFiles(t *testing.T, body []byte) map[string]string { + t.Helper() + reader, err := zip.NewReader(bytes.NewReader(body), int64(len(body))) + if err != nil { + t.Fatalf("read archive: %v", err) + } + files := map[string]string{} + for _, file := range reader.File { + rc, err := file.Open() + if err != nil { + t.Fatalf("open %s: %v", file.Name, err) + } + content, err := io.ReadAll(rc) + _ = rc.Close() + if err != nil { + t.Fatalf("read %s: %v", file.Name, err) + } + files[file.Name] = string(content) + } + return files +} + +func mapValues(values map[string]string) []string { + out := make([]string, 0, len(values)) + for _, value := range values { + out = append(out, value) + } + return out } func TestTemplatesReportsEvidenceBundleAndCRAHTML(t *testing.T) { diff --git a/openapi.yaml b/openapi.yaml index 025367d..f085fec 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{},"payload_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source":{"type":"string"},"subject_refs":{"items":{"type":"string"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"type":"object"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"api_key_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"},"user_count":{"type":"integer"}},"required":["tenant_count","resource_counts"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Instance admin snapshot envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"operationId":"registerArtifact","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"operationId":"generateBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"operationId":"verifyBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"operationId":"createBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"operationId":"getBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"operationId":"uploadGitHubSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"operationId":"uploadGitLabSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"operationId":"createGraphSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"operationId":"listProducts","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"operationId":"createProduct","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"operationId":"createProject","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"operationId":"verifyProviderIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"operationId":"ready","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"operationId":"createRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"operationId":"getRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"operationId":"approveRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"operationId":"freezeRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"operationId":"controlCoverageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"operationId":"craReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"operationId":"releaseReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"operationId":"uploadSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"operationId":"getSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"operationId":"createSSOProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"operationId":"uploadVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"operationId":"uploadCycloneDXVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"operationId":"getVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"operationId":"uploadVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"operationId":"getVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{},"payload_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source":{"type":"string"},"subject_refs":{"items":{"type":"string"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"type":"object"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"api_key_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"},"user_count":{"type":"integer"}},"required":["tenant_count","resource_counts"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Instance admin snapshot envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"operationId":"registerArtifact","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"operationId":"generateBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"operationId":"verifyBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"operationId":"createBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"operationId":"getBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"operationId":"uploadGitHubSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"operationId":"uploadGitLabSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"operationId":"createGraphSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"operationId":"listProducts","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"operationId":"createProduct","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"operationId":"createProject","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"operationId":"verifyProviderIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"operationId":"ready","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"operationId":"createRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"operationId":"getRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"operationId":"approveRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"operationId":"freezeRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"operationId":"controlCoverageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"operationId":"craReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"operationId":"releaseReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"operationId":"uploadSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"operationId":"getSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"operationId":"createSSOProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"operationId":"uploadVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"operationId":"uploadCycloneDXVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"operationId":"getVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"operationId":"uploadVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"operationId":"getVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From 01e714a18bcd887412539f31bf201482c9bf7c88 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 16:31:52 +0300 Subject: [PATCH 024/287] feat: deepen openapi contract diffs --- .implementation_increments.md | 2 +- docs/api.md | 2 +- internal/app/ledger.go | 96 +++++++++++++++++++++++- internal/app/risk_workflows.go | 95 +++++++++++++++++++++-- internal/app/risk_workflows_more_test.go | 24 ++++++ internal/domain/domain.go | 29 ++++--- 6 files changed, 231 insertions(+), 17 deletions(-) diff --git a/.implementation_increments.md b/.implementation_increments.md index 9c52e2c..a90fe3f 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -87,7 +87,7 @@ Status legend: Added scanner metadata workflow records, SLA/disagreement/supersession/re-open markers, and vulnerability posture reports. 23. `[x]` OpenAPI Diff And Contract Checks - Added `ContractDiff`, deterministic contract comparison, and breaking/non-breaking change classification based on stored OpenAPI metadata. Approval requirements remain a later approval-record increment. + Added `ContractDiff`, deterministic contract comparison, operation-level breaking/non-breaking change classification based on stored OpenAPI metadata, and path-count fallback for older stored contracts. Approval records cover breaking-change review separately. 24. `[x]` API Security Check Evidence Added API lint/security scan evidence, OpenAPI ruleset results, API governance metadata, and control evidence-compatible resource types. diff --git a/docs/api.md b/docs/api.md index 787dec9..f9418e8 100644 --- a/docs/api.md +++ b/docs/api.md @@ -420,6 +420,6 @@ Source snapshots capture submitted provider metadata. They do not call provider - `openapi.yaml` is generated as compact JSON-style YAML and is optimized for drift checks and tooling, not prose review. - A subset of high-value operations has precise named schemas and response envelopes. Many route responses remain generic envelopes. - Operation-level examples are maintained here and in tests until the generator emits richer examples. -- OpenAPI diffing currently classifies broad path-count changes; rich operation-level compatibility analysis remains future work. +- OpenAPI diffing classifies operation removal/addition, required request-body and request-field changes, response status changes, and broad path-count fallback for older stored contracts. These limitations should be called out in release evidence when API contract review is part of the release process. diff --git a/internal/app/ledger.go b/internal/app/ledger.go index be37a38..67029b8 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -1054,6 +1054,7 @@ func (l *Ledger) UploadOpenAPIContract(ctx context.Context, actor domain.Actor, if err := doc.Validate(ctx); err != nil { return domain.OpenAPIContract{}, ErrValidation } + operations := extractOpenAPIOperations(doc) l.mu.Lock() if err := l.ensureScopeLocked(actor.TenantID, strings.TrimSpace(productID), "", strings.TrimSpace(releaseID)); err != nil { l.mu.Unlock() @@ -1088,7 +1089,7 @@ func (l *Ledger) UploadOpenAPIContract(ctx context.Context, actor domain.Actor, } l.mu.Lock() defer l.mu.Unlock() - contract := domain.OpenAPIContract{ID: newID("oas"), TenantID: actor.TenantID, ProductID: productID, ReleaseID: releaseID, Version: version, Hash: payloadHash, PathCount: len(doc.Paths.Map()), EvidenceID: item.ID, CreatedAt: l.now()} + contract := domain.OpenAPIContract{ID: newID("oas"), TenantID: actor.TenantID, ProductID: productID, ReleaseID: releaseID, Version: version, Hash: payloadHash, PathCount: len(doc.Paths.Map()), Operations: operations, EvidenceID: item.ID, CreatedAt: l.now()} l.contracts[contract.ID] = contract _, _ = l.appendChainLocked(actor.TenantID, "openapi_contract.parsed", "openapi_contract", contract.ID, "api_key", actor.KeyID, contract.Hash, "") if err := l.enqueue(ctx, actor.TenantID, "parse_openapi_contract", "openapi_contract", contract.ID, map[string]any{"payload_ref": payloadRef, "payload_hash": payloadHash}); err != nil { @@ -1100,6 +1101,99 @@ func (l *Ledger) UploadOpenAPIContract(ctx context.Context, actor domain.Actor, return contract, nil } +func extractOpenAPIOperations(doc *openapi3.T) []domain.OpenAPIOperation { + if doc == nil || doc.Paths == nil { + return nil + } + paths := doc.Paths.Map() + pathNames := make([]string, 0, len(paths)) + for path := range paths { + pathNames = append(pathNames, path) + } + sort.Strings(pathNames) + out := make([]domain.OpenAPIOperation, 0) + for _, path := range pathNames { + item := paths[path] + for _, methodOperation := range openAPIMethodOperations(item) { + operation := methodOperation.operation + if operation == nil { + continue + } + out = append(out, domain.OpenAPIOperation{ + Path: path, + Method: strings.ToUpper(methodOperation.method), + OperationID: operation.OperationID, + Deprecated: operation.Deprecated, + RequestBodyRequired: openAPIRequestBodyRequired(operation), + RequiredRequestFields: openAPIRequiredRequestFields(operation), + ResponseStatuses: openAPIResponseStatuses(operation), + }) + } + } + return out +} + +type openAPIMethodOperation struct { + method string + operation *openapi3.Operation +} + +func openAPIMethodOperations(item *openapi3.PathItem) []openAPIMethodOperation { + if item == nil { + return nil + } + return []openAPIMethodOperation{ + {method: "connect", operation: item.Connect}, + {method: "delete", operation: item.Delete}, + {method: "get", operation: item.Get}, + {method: "head", operation: item.Head}, + {method: "options", operation: item.Options}, + {method: "patch", operation: item.Patch}, + {method: "post", operation: item.Post}, + {method: "put", operation: item.Put}, + {method: "trace", operation: item.Trace}, + } +} + +func openAPIRequestBodyRequired(operation *openapi3.Operation) bool { + return operation != nil && operation.RequestBody != nil && operation.RequestBody.Value != nil && operation.RequestBody.Value.Required +} + +func openAPIRequiredRequestFields(operation *openapi3.Operation) []string { + if operation == nil || operation.RequestBody == nil || operation.RequestBody.Value == nil { + return nil + } + fields := map[string]struct{}{} + for _, media := range operation.RequestBody.Value.Content { + if media == nil || media.Schema == nil || media.Schema.Value == nil { + continue + } + for _, field := range media.Schema.Value.Required { + if strings.TrimSpace(field) != "" { + fields[strings.TrimSpace(field)] = struct{}{} + } + } + } + out := make([]string, 0, len(fields)) + for field := range fields { + out = append(out, field) + } + sort.Strings(out) + return out +} + +func openAPIResponseStatuses(operation *openapi3.Operation) []string { + if operation == nil || operation.Responses == nil { + return nil + } + statuses := make([]string, 0, len(operation.Responses.Map())) + for status := range operation.Responses.Map() { + statuses = append(statuses, status) + } + sort.Strings(statuses) + return statuses +} + func (l *Ledger) EvaluateRelease(ctx context.Context, actor domain.Actor, releaseID string) (domain.PolicyEvaluation, error) { if err := ctx.Err(); err != nil { return domain.PolicyEvaluation{}, err diff --git a/internal/app/risk_workflows.go b/internal/app/risk_workflows.go index 8ba554a..2ddf23a 100644 --- a/internal/app/risk_workflows.go +++ b/internal/app/risk_workflows.go @@ -768,12 +768,18 @@ func (l *Ledger) CreateContractDiff(ctx context.Context, actor domain.Actor, in breaking, nonBreaking := []string{}, []string{} if base.Hash != target.Hash { result = "changed" - if target.PathCount < base.PathCount { - result = "breaking" - breaking = append(breaking, "target contract has fewer paths than base contract") + breaking, nonBreaking = diffOpenAPIOperations(base, target) + if len(base.Operations) == 0 || len(target.Operations) == 0 { + breaking, nonBreaking = []string{}, []string{} + if target.PathCount < base.PathCount { + breaking = append(breaking, "target contract has fewer paths than base contract") + } + if target.PathCount > base.PathCount { + nonBreaking = append(nonBreaking, "target contract has additional paths") + } } - if target.PathCount > base.PathCount { - nonBreaking = append(nonBreaking, "target contract has additional paths") + if len(breaking) > 0 { + result = "breaking" } } diff := domain.ContractDiff{ID: newID("cdiff"), TenantID: actor.TenantID, BaseContractID: base.ID, TargetContractID: target.ID, ProductID: base.ProductID, ReleaseID: strings.TrimSpace(in.ReleaseID), Result: result, BreakingChanges: breaking, NonBreakingChanges: nonBreaking, SchemaVersion: domain.ContractDiffSchemaVersion, CreatedAt: l.now()} @@ -785,6 +791,85 @@ func (l *Ledger) CreateContractDiff(ctx context.Context, actor domain.Actor, in return diff, nil } +func diffOpenAPIOperations(base, target domain.OpenAPIContract) ([]string, []string) { + baseOps := indexOpenAPIOperations(base.Operations) + targetOps := indexOpenAPIOperations(target.Operations) + breaking, nonBreaking := []string{}, []string{} + for key, baseOp := range baseOps { + targetOp, ok := targetOps[key] + label := openAPIOperationLabel(baseOp) + if !ok { + breaking = append(breaking, "operation removed: "+label) + continue + } + if !baseOp.RequestBodyRequired && targetOp.RequestBodyRequired { + breaking = append(breaking, "request body became required: "+label) + } + addedRequired := missingStrings(baseOp.RequiredRequestFields, targetOp.RequiredRequestFields) + if len(addedRequired) > 0 { + breaking = append(breaking, "required request fields added for "+label+": "+strings.Join(addedRequired, ",")) + } + removedStatuses := missingStrings(targetOp.ResponseStatuses, baseOp.ResponseStatuses) + if len(removedStatuses) > 0 { + breaking = append(breaking, "response statuses removed for "+label+": "+strings.Join(removedStatuses, ",")) + } + addedStatuses := missingStrings(baseOp.ResponseStatuses, targetOp.ResponseStatuses) + if len(addedStatuses) > 0 { + nonBreaking = append(nonBreaking, "response statuses added for "+label+": "+strings.Join(addedStatuses, ",")) + } + if !baseOp.Deprecated && targetOp.Deprecated { + nonBreaking = append(nonBreaking, "operation deprecated: "+label) + } + } + for key, targetOp := range targetOps { + if _, ok := baseOps[key]; !ok { + nonBreaking = append(nonBreaking, "operation added: "+openAPIOperationLabel(targetOp)) + } + } + sort.Strings(breaking) + sort.Strings(nonBreaking) + return breaking, nonBreaking +} + +func indexOpenAPIOperations(ops []domain.OpenAPIOperation) map[string]domain.OpenAPIOperation { + out := make(map[string]domain.OpenAPIOperation, len(ops)) + for _, op := range ops { + if strings.TrimSpace(op.Path) == "" || strings.TrimSpace(op.Method) == "" { + continue + } + op.Method = strings.ToUpper(strings.TrimSpace(op.Method)) + op.Path = strings.TrimSpace(op.Path) + out[op.Method+" "+op.Path] = op + } + return out +} + +func openAPIOperationLabel(op domain.OpenAPIOperation) string { + return strings.ToUpper(strings.TrimSpace(op.Method)) + " " + strings.TrimSpace(op.Path) +} + +func missingStrings(have, want []string) []string { + present := map[string]struct{}{} + for _, value := range have { + value = strings.TrimSpace(value) + if value != "" { + present[value] = struct{}{} + } + } + missing := []string{} + for _, value := range want { + value = strings.TrimSpace(value) + if value == "" { + continue + } + if _, ok := present[value]; !ok { + missing = append(missing, value) + } + } + sort.Strings(missing) + return missing +} + func (l *Ledger) CreateCustomPolicy(ctx context.Context, actor domain.Actor, in CreateCustomPolicyInput) (domain.CustomPolicy, error) { if err := ctx.Err(); err != nil { return domain.CustomPolicy{}, err diff --git a/internal/app/risk_workflows_more_test.go b/internal/app/risk_workflows_more_test.go index cbefb11..938e8e3 100644 --- a/internal/app/risk_workflows_more_test.go +++ b/internal/app/risk_workflows_more_test.go @@ -2,6 +2,7 @@ package app import ( "context" + "strings" "testing" "time" @@ -116,6 +117,29 @@ func TestRiskWorkflowEvidenceFormatsAndReports(t *testing.T) { if contractDiff.Result != "breaking" || len(contractDiff.BreakingChanges) != 1 { t.Fatalf("contract diff = %#v", contractDiff) } + baseRichContract, err := ledger.UploadOpenAPIContract(ctx, actor, release.ProductID, release.ID, "rich-base", []byte(`{"openapi":"3.1.0","info":{"title":"API","version":"1"},"paths":{"/v1/items":{"post":{"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","required":["id"],"properties":{"id":{"type":"string"}}}}}},"responses":{"200":{"description":"ok"},"201":{"description":"created"}}}}}}`)) + if err != nil { + t.Fatalf("rich base contract: %v", err) + } + targetRichContract, err := ledger.UploadOpenAPIContract(ctx, actor, release.ProductID, release.ID, "rich-target", []byte(`{"openapi":"3.1.0","info":{"title":"API","version":"2"},"paths":{"/v1/items":{"post":{"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string"},"name":{"type":"string"}}}}}},"responses":{"200":{"description":"ok"}}}},"/v1/items/{id}":{"get":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"ok"}}}}}}`)) + if err != nil { + t.Fatalf("rich target contract: %v", err) + } + if len(baseRichContract.Operations) != 1 || len(targetRichContract.Operations) != 2 { + t.Fatalf("operation summaries not captured: base=%#v target=%#v", baseRichContract.Operations, targetRichContract.Operations) + } + richDiff, err := ledger.CreateContractDiff(ctx, actor, CreateContractDiffInput{BaseContractID: baseRichContract.ID, TargetContractID: targetRichContract.ID, ReleaseID: release.ID}) + if err != nil { + t.Fatalf("rich contract diff: %v", err) + } + breakingText := strings.Join(richDiff.BreakingChanges, "\n") + nonBreakingText := strings.Join(richDiff.NonBreakingChanges, "\n") + if richDiff.Result != "breaking" || !strings.Contains(breakingText, "request body became required: POST /v1/items") || !strings.Contains(breakingText, "required request fields added for POST /v1/items: name") || !strings.Contains(breakingText, "response statuses removed for POST /v1/items: 201") { + t.Fatalf("rich breaking diff = %#v", richDiff) + } + if !strings.Contains(nonBreakingText, "operation added: GET /v1/items/{id}") { + t.Fatalf("rich non-breaking diff = %#v", richDiff) + } policy, err := ledger.CreateCustomPolicy(ctx, actor, CreateCustomPolicyInput{Name: "release gates", Version: "1", Rules: []domain.PolicyRule{ {Name: "metadata", Severity: "low"}, diff --git a/internal/domain/domain.go b/internal/domain/domain.go index 38634d2..34cb753 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -1072,15 +1072,26 @@ type VulnerabilityDecision struct { } type OpenAPIContract struct { - ID string `json:"id"` - TenantID string `json:"tenant_id"` - ProductID string `json:"product_id"` - ReleaseID string `json:"release_id,omitempty"` - Version string `json:"version"` - Hash string `json:"hash"` - PathCount int `json:"path_count"` - EvidenceID string `json:"evidence_id"` - CreatedAt time.Time `json:"created_at"` + ID string `json:"id"` + TenantID string `json:"tenant_id"` + ProductID string `json:"product_id"` + ReleaseID string `json:"release_id,omitempty"` + Version string `json:"version"` + Hash string `json:"hash"` + PathCount int `json:"path_count"` + Operations []OpenAPIOperation `json:"operations,omitempty"` + EvidenceID string `json:"evidence_id"` + CreatedAt time.Time `json:"created_at"` +} + +type OpenAPIOperation struct { + Path string `json:"path"` + Method string `json:"method"` + OperationID string `json:"operation_id,omitempty"` + Deprecated bool `json:"deprecated,omitempty"` + RequestBodyRequired bool `json:"request_body_required,omitempty"` + RequiredRequestFields []string `json:"required_request_fields,omitempty"` + ResponseStatuses []string `json:"response_statuses,omitempty"` } type PolicyEvaluation struct { From bc8e1d094cb68b468745f450c172c3fe1dae1810 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 16:34:39 +0300 Subject: [PATCH 025/287] feat: add sbom component lookup --- .implementation_increments.md | 2 +- docs/api.md | 1 + .../adapters/httpapi/openapi_operations.go | 11 +++ .../adapters/httpapi/route_registration.go | 1 + internal/adapters/httpapi/router.go | 30 +++++++ internal/adapters/httpapi/router_test.go | 4 + internal/app/ledger.go | 82 +++++++++++++++++++ internal/app/risk_workflows_more_test.go | 18 ++++ internal/domain/domain.go | 9 ++ openapi.yaml | 2 +- 10 files changed, 158 insertions(+), 2 deletions(-) diff --git a/.implementation_increments.md b/.implementation_increments.md index a90fe3f..c75e55f 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -75,7 +75,7 @@ Status legend: Added sensitive manual/security evidence types with lower default trust, scoped access, raw payload preservation, and explicit limitations. 19. `[x]` SPDX And SBOM Expansion - Added SPDX JSON first-class ingestion, component inventory storage, parser version metadata, and validation limitations. Rich component lookup APIs remain future expansion. + Added SPDX JSON first-class ingestion, component inventory storage, component lookup APIs, parser version metadata, and validation limitations. 20. `[x]` SBOM Diff And Dependency Change Evidence Added SBOM diffs, dependency change records, changed components, and release comparison data for added/removed components. diff --git a/docs/api.md b/docs/api.md index f9418e8..723c6cb 100644 --- a/docs/api.md +++ b/docs/api.md @@ -274,6 +274,7 @@ Current SSO endpoints model admin-managed provider, identity-link, and session r | `POST` | `/v1/sboms` | Upload CycloneDX SBOM. | | `POST` | `/v1/sboms/spdx` | Upload SPDX SBOM. | | `GET` | `/v1/sboms/{id}` | Read SBOM metadata. | +| `GET` | `/v1/sbom-components` | Search stored SBOM components by SBOM, release, artifact, query, exact PURL, and limit. | | `POST` | `/v1/sbom-diffs` | Compare stored SBOMs. | | `POST` | `/v1/vulnerability-scans` | Upload normalized vulnerability scan. | | `GET` | `/v1/vulnerability-scans/{id}` | Read vulnerability scan metadata. | diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index dc928f9..1cec1d8 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -33,6 +33,17 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { queryParam("limit", "Maximum returned records.", "integer"), ) operation.Responses[http.StatusOK] = jsonResponse("Evidence search result envelope.", "#/components/schemas/EvidenceSearchEnvelope") + case "listSBOMComponents": + operation.Description = "Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL." + operation.Parameters = append(operation.Parameters, + queryParam("sbom_id", "Filter by SBOM id.", "string"), + queryParam("release_id", "Filter by release id.", "string"), + queryParam("artifact_id", "Filter by artifact id.", "string"), + queryParam("query", "Case-insensitive component name, version, or PURL search.", "string"), + queryParam("purl", "Exact package URL filter.", "string"), + queryParam("limit", "Maximum returned component records.", "integer"), + ) + operation.Responses[http.StatusOK] = jsonResponse("SBOM component result envelope.", "#/components/schemas/DataEnvelope") case "createReleaseBundle": operation.Description = "Creates an immutable signed release bundle for a release." operation.RequestBody = jsonRequest("Release bundle creation request.", "#/components/schemas/CreateReleaseBundleRequest") diff --git a/internal/adapters/httpapi/route_registration.go b/internal/adapters/httpapi/route_registration.go index 611f274..80bca1e 100644 --- a/internal/adapters/httpapi/route_registration.go +++ b/internal/adapters/httpapi/route_registration.go @@ -196,6 +196,7 @@ func (s *Server) evidenceRiskPolicyRoutes() []routeDef { {http.MethodGet, "/v1/evidence/{id}/lifecycle-events", op("listEvidenceLifecycleEvents", http.MethodGet, "/v1/evidence/{id}/lifecycle-events", "List evidence lifecycle events", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.listEvidenceLifecycleEvents)}, {http.MethodPost, "/v1/sboms", op("uploadSBOM", http.MethodPost, "/v1/sboms", "Upload CycloneDX SBOM", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.uploadSBOM)}, {http.MethodGet, "/v1/sboms/{id}", op("getSBOM", http.MethodGet, "/v1/sboms/{id}", "Get SBOM", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.getSBOM)}, + {http.MethodGet, "/v1/sbom-components", op("listSBOMComponents", http.MethodGet, "/v1/sbom-components", "List SBOM components", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.listSBOMComponents)}, {http.MethodPost, "/v1/vex", op("uploadVEX", http.MethodPost, "/v1/vex", "Upload OpenVEX document", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.uploadVEX)}, {http.MethodPost, "/v1/vex/cyclonedx", op("uploadCycloneDXVEX", http.MethodPost, "/v1/vex/cyclonedx", "Upload CycloneDX VEX document", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.uploadCycloneDXVEX)}, {http.MethodGet, "/v1/vex/{id}", op("getVEX", http.MethodGet, "/v1/vex/{id}", "Get VEX document", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.getVEX)}, diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index cd86d97..436c782 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -1320,6 +1320,36 @@ func (s *Server) getSBOM(w http.ResponseWriter, r *http.Request) { writeData(w, http.StatusOK, sbom) } +func (s *Server) listSBOMComponents(w http.ResponseWriter, r *http.Request) { + actor, ok := s.authenticate(w, r) + if !ok { + return + } + query := r.URL.Query() + limit := 0 + if value := strings.TrimSpace(query.Get("limit")); value != "" { + parsed, err := strconv.Atoi(value) + if err != nil { + writeProblem(w, r, app.ErrValidation) + return + } + limit = parsed + } + components, err := s.ledger.ListSBOMComponents(r.Context(), actor, app.ListSBOMComponentsInput{ + SBOMID: query.Get("sbom_id"), + ReleaseID: query.Get("release_id"), + ArtifactID: query.Get("artifact_id"), + Query: query.Get("query"), + PURL: query.Get("purl"), + Limit: limit, + }) + if err != nil { + writeProblem(w, r, err) + return + } + writeData(w, http.StatusOK, components) +} + func (s *Server) uploadVEX(w http.ResponseWriter, r *http.Request) { var req struct { ReleaseID string `json:"release_id"` diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index a74a4b6..6186b7c 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -625,6 +625,10 @@ func TestRiskWorkflowHTTPFlow(t *testing.T) { if !strings.Contains(diffBody, `"added_components"`) { t.Fatalf("sbom diff missing added components: %s", diffBody) } + componentSearch := getJSON(t, server, secret, "/v1/sbom-components?release_id="+releaseID+"&query=curl&limit=10", http.StatusOK) + if !strings.Contains(componentSearch, `"name":"curl"`) { + t.Fatalf("sbom component search missing curl: %s", componentSearch) + } vulnScan := postJSON(t, server, secret, "/v1/vulnerability-scans", "risk2-vuln-scan", map[string]any{"scanner": "grype", "target_ref": "pkg:oci/api", "release_id": releaseID, "findings": []map[string]any{{"vulnerability": "CVE-2026-4242", "component": "openssl", "severity": "critical", "state": "open"}}}, http.StatusCreated) findingID := firstFindingID(t, vulnScan) diff --git a/internal/app/ledger.go b/internal/app/ledger.go index 67029b8..e641d80 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -1342,6 +1342,88 @@ func (l *Ledger) GetSBOM(ctx context.Context, actor domain.Actor, id string) (do return sbom, nil } +type ListSBOMComponentsInput struct { + SBOMID string + ReleaseID string + ArtifactID string + Query string + PURL string + Limit int +} + +func (l *Ledger) ListSBOMComponents(ctx context.Context, actor domain.Actor, in ListSBOMComponentsInput) ([]domain.SBOMComponentRecord, error) { + if err := ctx.Err(); err != nil { + return nil, err + } + if err := require(actor, ScopeEvidenceRead); err != nil { + return nil, err + } + in.SBOMID = strings.TrimSpace(in.SBOMID) + in.ReleaseID = strings.TrimSpace(in.ReleaseID) + in.ArtifactID = strings.TrimSpace(in.ArtifactID) + in.Query = strings.ToLower(strings.TrimSpace(in.Query)) + in.PURL = strings.TrimSpace(in.PURL) + if in.Limit < 0 || in.Limit > 500 { + return nil, ErrValidation + } + if in.Limit == 0 { + in.Limit = 100 + } + l.mu.Lock() + defer l.mu.Unlock() + if in.SBOMID != "" { + sbom, ok := l.sboms[in.SBOMID] + if !ok || sbom.TenantID != actor.TenantID { + return nil, ErrNotFound + } + } + ids := make([]string, 0, len(l.sboms)) + for id := range l.sboms { + ids = append(ids, id) + } + sort.Strings(ids) + out := make([]domain.SBOMComponentRecord, 0) + for _, id := range ids { + sbom := l.sboms[id] + if sbom.TenantID != actor.TenantID { + continue + } + if in.SBOMID != "" && sbom.ID != in.SBOMID { + continue + } + if in.ReleaseID != "" && sbom.ReleaseID != in.ReleaseID { + continue + } + if in.ArtifactID != "" && sbom.ArtifactID != in.ArtifactID { + continue + } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceRead, resourceRefs{ReleaseID: sbom.ReleaseID, ArtifactID: sbom.ArtifactID}); err != nil { + return nil, err + } + for _, component := range sbom.Components { + if !sbomComponentMatches(component, in.Query, in.PURL) { + continue + } + out = append(out, domain.SBOMComponentRecord{SBOMID: sbom.ID, ReleaseID: sbom.ReleaseID, ArtifactID: sbom.ArtifactID, Format: sbom.Format, SpecVersion: sbom.SpecVersion, Component: component}) + if len(out) >= in.Limit { + return out, nil + } + } + } + return out, nil +} + +func sbomComponentMatches(component domain.SBOMComponent, query, purl string) bool { + if purl != "" && component.PURL != purl { + return false + } + if query == "" { + return true + } + haystack := strings.ToLower(component.Name + "\n" + component.Version + "\n" + component.PURL) + return strings.Contains(haystack, query) +} + func (l *Ledger) GetVulnerabilityScan(ctx context.Context, actor domain.Actor, id string) (domain.VulnerabilityScan, error) { if err := ctx.Err(); err != nil { return domain.VulnerabilityScan{}, err diff --git a/internal/app/risk_workflows_more_test.go b/internal/app/risk_workflows_more_test.go index 938e8e3..72b9493 100644 --- a/internal/app/risk_workflows_more_test.go +++ b/internal/app/risk_workflows_more_test.go @@ -2,6 +2,7 @@ package app import ( "context" + "errors" "strings" "testing" "time" @@ -83,6 +84,23 @@ func TestRiskWorkflowEvidenceFormatsAndReports(t *testing.T) { if diff.UnchangedCount != 1 || len(diff.AddedComponents) != 1 || len(diff.RemovedComponents) != 1 || len(diff.DependencyChanges) != 2 { t.Fatalf("diff = %#v", diff) } + components, err := ledger.ListSBOMComponents(ctx, actor, ListSBOMComponentsInput{ReleaseID: release.ID, Query: "new"}) + if err != nil { + t.Fatalf("list sbom components: %v", err) + } + if len(components) != 1 || components[0].SBOMID != target.ID || components[0].Component.Name != "new" { + t.Fatalf("component query = %#v", components) + } + purlComponents, err := ledger.ListSBOMComponents(ctx, actor, ListSBOMComponentsInput{SBOMID: base.ID, PURL: "pkg:oci/api@1.0.0", Limit: 1}) + if err != nil { + t.Fatalf("list sbom components by purl: %v", err) + } + if len(purlComponents) != 1 || purlComponents[0].Component.PURL != "pkg:oci/api@1.0.0" { + t.Fatalf("purl component query = %#v", purlComponents) + } + if _, err := ledger.ListSBOMComponents(ctx, actor, ListSBOMComponentsInput{Limit: 501}); !errors.Is(err, ErrValidation) { + t.Fatalf("large component limit err=%v, want validation", err) + } scan, err := ledger.UploadVulnerabilityScan(ctx, actor, []byte(`{"scanner":"grype","target_ref":"pkg:oci/api","release_id":"`+release.ID+`","findings":[{"vulnerability":"CVE-2026-0002","component":"api","severity":"critical","state":"open"}]}`)) if err != nil { diff --git a/internal/domain/domain.go b/internal/domain/domain.go index 34cb753..418918e 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -1014,6 +1014,15 @@ type SBOMComponent struct { PURL string `json:"purl,omitempty"` } +type SBOMComponentRecord struct { + SBOMID string `json:"sbom_id"` + ReleaseID string `json:"release_id,omitempty"` + ArtifactID string `json:"artifact_id,omitempty"` + Format string `json:"format"` + SpecVersion string `json:"spec_version"` + Component SBOMComponent `json:"component"` +} + type VulnerabilityScan struct { ID string `json:"id"` TenantID string `json:"tenant_id"` diff --git a/openapi.yaml b/openapi.yaml index f085fec..7a677a6 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{},"payload_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source":{"type":"string"},"subject_refs":{"items":{"type":"string"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"type":"object"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"api_key_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"},"user_count":{"type":"integer"}},"required":["tenant_count","resource_counts"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Instance admin snapshot envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"operationId":"registerArtifact","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"operationId":"generateBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"operationId":"verifyBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"operationId":"createBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"operationId":"getBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"operationId":"uploadGitHubSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"operationId":"uploadGitLabSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"operationId":"createGraphSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"operationId":"listProducts","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"operationId":"createProduct","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"operationId":"createProject","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"operationId":"verifyProviderIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"operationId":"ready","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"operationId":"createRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"operationId":"getRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"operationId":"approveRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"operationId":"freezeRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"operationId":"controlCoverageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"operationId":"craReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"operationId":"releaseReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"operationId":"uploadSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"operationId":"getSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"operationId":"createSSOProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"operationId":"uploadVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"operationId":"uploadCycloneDXVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"operationId":"getVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"operationId":"uploadVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"operationId":"getVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{},"payload_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source":{"type":"string"},"subject_refs":{"items":{"type":"string"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"type":"object"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"api_key_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"},"user_count":{"type":"integer"}},"required":["tenant_count","resource_counts"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Instance admin snapshot envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"operationId":"registerArtifact","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"operationId":"generateBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"operationId":"verifyBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"operationId":"createBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"operationId":"getBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"operationId":"uploadGitHubSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"operationId":"uploadGitLabSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"operationId":"createGraphSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"operationId":"listProducts","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"operationId":"createProduct","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"operationId":"createProject","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"operationId":"verifyProviderIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"operationId":"ready","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"operationId":"createRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"operationId":"getRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"operationId":"approveRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"operationId":"freezeRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"operationId":"controlCoverageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"operationId":"craReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"operationId":"releaseReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"operationId":"uploadSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"operationId":"getSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"operationId":"createSSOProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"operationId":"uploadVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"operationId":"uploadCycloneDXVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"operationId":"getVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"operationId":"uploadVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"operationId":"getVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From bfc8dc3ec02d8050a0e2ae4ebc90651448cd5264 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 16:43:08 +0300 Subject: [PATCH 026/287] feat: add signed incident webhooks --- .implementation_increments.md | 2 +- docs/api.md | 2 + docs/architecture.md | 2 +- .../adapters/httpapi/openapi_operations.go | 22 ++ .../adapters/httpapi/route_registration.go | 2 + internal/adapters/httpapi/router.go | 40 ++++ internal/adapters/httpapi/router_test.go | 35 +++ internal/app/ledger.go | 4 + internal/app/ports.go | 184 ++++++++-------- internal/app/risk_workflows.go | 202 ++++++++++++++++++ internal/app/risk_workflows_more_test.go | 50 +++++ internal/app/state.go | 192 +++++++++-------- internal/domain/domain.go | 29 +++ ...28001000_signed_incident_webhooks.down.sql | 4 + ...0528001000_signed_incident_webhooks.up.sql | 33 +++ openapi.yaml | 2 +- 16 files changed, 620 insertions(+), 185 deletions(-) create mode 100644 migrations/20260528001000_signed_incident_webhooks.down.sql create mode 100644 migrations/20260528001000_signed_incident_webhooks.up.sql diff --git a/.implementation_increments.md b/.implementation_increments.md index c75e55f..f6a5be9 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -66,7 +66,7 @@ Status legend: Added environments, deployment events, artifact/release/environment links, rollout metadata, rollback-as-new-event behavior, and deployment evidence reports. 16. `[x]` Incident Timeline And Remediation Evidence - Added incidents, timeline events, remediation tasks, evidence links, and deterministic incident package reports. Signed webhook ingestion remains future provider-hardening work. + Added incidents, timeline events, remediation tasks, evidence links, Ed25519-signed incident webhook ingestion with replay detection, and deterministic incident package reports. 17. `[x]` Static, Dynamic, Secret, And License Scan Evidence Added SAST, DAST, secret scanning, license scanning, SARIF where relevant, safe redaction/quarantine behavior, and normalized summaries. diff --git a/docs/api.md b/docs/api.md index 723c6cb..dadb4d7 100644 --- a/docs/api.md +++ b/docs/api.md @@ -362,6 +362,8 @@ Source snapshots capture submitted provider metadata. They do not call provider | `POST` | `/v1/report-templates/{id}/render` | Render deterministic JSON report. | | `POST` | `/v1/incidents` | Create incident. | | `POST` | `/v1/incidents/{id}/timeline` | Append incident timeline event. | +| `POST` | `/v1/incidents/{id}/webhook-receivers` | Create incident-scoped Ed25519 webhook receiver. | +| `POST` | `/v1/incident-webhooks/{receiver_id}` | Receive signed incident timeline webhook without bearer authentication. | ### Integrity, Verification, And Operations diff --git a/docs/architecture.md b/docs/architecture.md index 99ad2cf..bdbdbc0 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -40,7 +40,7 @@ Merkle batches, signed checkpoints, optional transparency checkpoint/public tran Control coverage and CRA-readiness reports use versioned tenant-created controls, explicit evidence links, approved unexpired control exceptions, and built-in starter packs for CRA-readiness, NIST SSDF-lite, SOC 2-style technical evidence, and ISO 27001-style technical evidence. -Source snapshots, deployment records, incident packages, security scans, manual reviews, SBOM diffs, contract diffs, API security checks, customer packages, customer portal package access, questionnaire packages, evidence bundles, and custom policies add traceability and reproducible decisions. Reports include gaps, assumptions, and limitations. +Source snapshots, deployment records, signed incident webhook events, incident packages, security scans, manual reviews, SBOM diffs, contract diffs, API security checks, customer packages, customer portal package access, questionnaire packages, evidence bundles, and custom policies add traceability and reproducible decisions. Reports include gaps, assumptions, and limitations. Evidence summaries, questionnaire drafts, graph snapshots, PDF packages, and anomaly reports are generated from stored records with citations, assumptions, and limitations. Customer-facing packages require explicit package scope, redaction profile, expiry, and access auditing. Customer package JSON and ZIP download paths return scoped manifest metadata and verification guidance; raw tenant evidence payload bytes are not returned. diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 1cec1d8..1c9fae3 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -44,6 +44,24 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { queryParam("limit", "Maximum returned component records.", "integer"), ) operation.Responses[http.StatusOK] = jsonResponse("SBOM component result envelope.", "#/components/schemas/DataEnvelope") + case "createIncidentWebhookReceiver": + operation.Description = "Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool." + operation.Parameters = append(operation.Parameters, pathParam("id", "Incident id.")) + operation.RequestBody = jsonRequest("Incident webhook receiver creation request.", "#/components/schemas/DataEnvelope") + operation.Responses[http.StatusCreated] = jsonResponse("Created incident webhook receiver envelope.", "#/components/schemas/DataEnvelope") + case "receiveIncidentWebhook": + operation.Description = "Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields." + operation.Parameters = append(operation.Parameters, + pathParam("receiver_id", "Incident webhook receiver id."), + headerParam("X-Evydence-Webhook-Event-ID", "Provider event id used for replay detection."), + headerParam("X-Evydence-Webhook-Timestamp", "RFC3339 timestamp included in the signed payload."), + headerParam("X-Evydence-Webhook-Signature", "ed25519= over timestamp, event id, and raw body."), + ) + operation.RequestBody = jsonRequest("Signed incident timeline event payload.", "#/components/schemas/DataEnvelope") + operation.Security = nil + operation.Scopes = nil + operation.Extensions = nil + operation.Responses[http.StatusCreated] = jsonResponse("Accepted webhook event and timeline event envelope.", "#/components/schemas/DataEnvelope") case "createReleaseBundle": operation.Description = "Creates an immutable signed release bundle for a release." operation.RequestBody = jsonRequest("Release bundle creation request.", "#/components/schemas/CreateReleaseBundleRequest") @@ -135,3 +153,7 @@ func queryParam(name, description, typ string) specs.Parameter { func pathParam(name, description string) specs.Parameter { return specs.Parameter{Name: name, In: "path", Description: description, Required: true, Schema: map[string]any{"type": "string"}} } + +func headerParam(name, description string) specs.Parameter { + return specs.Parameter{Name: name, In: "header", Description: description, Required: true, Schema: map[string]any{"type": "string"}} +} diff --git a/internal/adapters/httpapi/route_registration.go b/internal/adapters/httpapi/route_registration.go index 80bca1e..f5c2702 100644 --- a/internal/adapters/httpapi/route_registration.go +++ b/internal/adapters/httpapi/route_registration.go @@ -147,6 +147,8 @@ func (s *Server) deploymentIncidentSecurityRoutes() []routeDef { {http.MethodGet, "/v1/deployments/{id}", op("getDeployment", http.MethodGet, "/v1/deployments/{id}", "Get deployment", []string{app.ScopeDeploymentRead}), http.HandlerFunc(s.getDeployment)}, {http.MethodPost, "/v1/incidents", op("createIncident", http.MethodPost, "/v1/incidents", "Create incident", []string{app.ScopeIncidentWrite}), http.HandlerFunc(s.createIncident)}, {http.MethodPost, "/v1/incidents/{id}/timeline", op("recordIncidentTimeline", http.MethodPost, "/v1/incidents/{id}/timeline", "Record incident timeline event", []string{app.ScopeIncidentWrite}), http.HandlerFunc(s.recordIncidentTimeline)}, + {http.MethodPost, "/v1/incidents/{id}/webhook-receivers", op("createIncidentWebhookReceiver", http.MethodPost, "/v1/incidents/{id}/webhook-receivers", "Create signed incident webhook receiver", []string{app.ScopeIncidentWrite}), http.HandlerFunc(s.createIncidentWebhookReceiver)}, + {http.MethodPost, "/v1/incident-webhooks/{receiver_id}", op("receiveIncidentWebhook", http.MethodPost, "/v1/incident-webhooks/{receiver_id}", "Receive signed incident webhook event", nil), http.HandlerFunc(s.receiveIncidentWebhook)}, {http.MethodPost, "/v1/remediation-tasks", op("createRemediationTask", http.MethodPost, "/v1/remediation-tasks", "Create remediation task", []string{app.ScopeIncidentWrite}), http.HandlerFunc(s.createRemediationTask)}, {http.MethodGet, "/v1/reports/incident-package", op("incidentReport", http.MethodGet, "/v1/reports/incident-package", "Incident package report", []string{app.ScopeIncidentRead}), http.HandlerFunc(s.incidentReport)}, {http.MethodPost, "/v1/security-scans", op("uploadSecurityScan", http.MethodPost, "/v1/security-scans", "Upload security scan", []string{app.ScopeSecurityWrite}), http.HandlerFunc(s.uploadSecurityScan)}, diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index 436c782..2a8ef54 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -817,6 +817,46 @@ func (s *Server) recordIncidentTimeline(w http.ResponseWriter, r *http.Request) }) } +func (s *Server) createIncidentWebhookReceiver(w http.ResponseWriter, r *http.Request) { + var req struct { + Name string `json:"name"` + Provider string `json:"provider"` + PublicKey string `json:"public_key"` + } + s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + if err := decodeJSON(body, &req); err != nil { + return 0, nil, err + } + receiver, err := s.ledger.CreateIncidentWebhookReceiver(r.Context(), actor, app.CreateIncidentWebhookReceiverInput{IncidentID: r.PathValue("id"), Name: req.Name, Provider: req.Provider, PublicKey: req.PublicKey}) + return http.StatusCreated, receiver, err + }) +} + +func (s *Server) receiveIncidentWebhook(w http.ResponseWriter, r *http.Request) { + body, err := readBody(r) + if err != nil { + writeProblem(w, r, err) + return + } + timestamp, err := time.Parse(time.RFC3339, strings.TrimSpace(r.Header.Get("X-Evydence-Webhook-Timestamp"))) + if err != nil { + writeProblem(w, r, app.ErrValidation) + return + } + record, event, err := s.ledger.HandleIncidentWebhook(r.Context(), app.HandleIncidentWebhookInput{ + ReceiverID: r.PathValue("receiver_id"), + EventID: r.Header.Get("X-Evydence-Webhook-Event-ID"), + Timestamp: timestamp, + Signature: r.Header.Get("X-Evydence-Webhook-Signature"), + Body: body, + }) + if err != nil { + writeProblem(w, r, err) + return + } + writeData(w, http.StatusCreated, map[string]any{"webhook_event": record, "timeline_event": event}) +} + func (s *Server) createRemediationTask(w http.ResponseWriter, r *http.Request) { var req struct { IncidentID string `json:"incident_id"` diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 6186b7c..1cb32cf 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -2,6 +2,8 @@ package httpapi import ( "bytes" + "crypto/ed25519" + "crypto/rand" "encoding/base64" "encoding/json" "net/http" @@ -51,6 +53,7 @@ func TestRouteFamiliesRegisterCriticalPaths(t *testing.T) { "accessCustomerPortalPackage": "/v1/customer-portal/package", "downloadCustomerPackage": "/v1/customer-packages/{id}/download", "downloadCustomerPortalPackage": "/v1/customer-portal/package/download", + "receiveIncidentWebhook": "/v1/incident-webhooks/{receiver_id}", "createLegalHold": "/v1/legal-holds", "verifyReleaseBundle": "/v1/release-bundles/{id}/verify", } @@ -109,6 +112,11 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { if _, ok := portalDownload["security"]; ok { t.Fatalf("public portal download should not advertise bearer security: %#v", portalDownload["security"]) } + incidentWebhook := operationMap(t, paths, "/v1/incident-webhooks/{receiver_id}", "post") + assertQueryParams(t, incidentWebhook, "receiver_id", "X-Evydence-Webhook-Event-ID", "X-Evydence-Webhook-Timestamp", "X-Evydence-Webhook-Signature") + if _, ok := incidentWebhook["security"]; ok { + t.Fatalf("public incident webhook should not advertise bearer security: %#v", incidentWebhook["security"]) + } createSession := operationMap(t, paths, "/v1/sso/sessions", "post") assertRequestRef(t, createSession, "#/components/schemas/CreateSSOSessionRequest") assertResponseRef(t, createSession, "201", "#/components/schemas/SSOSessionCreateEnvelope") @@ -600,6 +608,15 @@ func TestRiskWorkflowHTTPFlow(t *testing.T) { incidentBody := postJSON(t, server, secret, "/v1/incidents", "risk2-incident", map[string]any{"product_id": productID, "release_id": releaseID, "title": "API outage", "severity": "high"}, http.StatusCreated) incidentID := dataField(t, incidentBody, "id") postJSON(t, server, secret, "/v1/incidents/"+incidentID+"/timeline", "risk2-timeline", map[string]any{"event_type": "detected", "summary": "monitor alert"}, http.StatusCreated) + webhookPublic, webhookPrivate, err := ed25519.GenerateKey(rand.Reader) + if err != nil { + t.Fatalf("webhook key: %v", err) + } + receiverBody := postJSON(t, server, secret, "/v1/incidents/"+incidentID+"/webhook-receivers", "risk2-webhook-receiver", map[string]any{"name": "pager", "provider": "incident_tool", "public_key": base64.RawStdEncoding.EncodeToString(webhookPublic)}, http.StatusCreated) + webhookBody := signedIncidentWebhook(t, server, dataField(t, receiverBody, "id"), webhookPrivate, "evt-http-1", []byte(`{"event_type":"mitigation_applied","summary":"patched service"}`), http.StatusCreated) + if !strings.Contains(webhookBody, `"event_type":"mitigation_applied"`) || strings.Contains(webhookBody, base64.RawStdEncoding.EncodeToString(webhookPrivate)) { + t.Fatalf("webhook response invalid: %s", webhookBody) + } postJSON(t, server, secret, "/v1/remediation-tasks", "risk2-task", map[string]any{"incident_id": incidentID, "title": "patch", "owner": "security"}, http.StatusCreated) incidentReport := getJSON(t, server, secret, "/v1/reports/incident-package?incident_id="+incidentID, http.StatusOK) if !strings.Contains(incidentReport, `"report_type":"incident_package"`) { @@ -958,6 +975,24 @@ func postRaw(t *testing.T, server *Server, secret, path, idem string, body []byt return rec.Body.String() } +func signedIncidentWebhook(t *testing.T, server *Server, receiverID string, private ed25519.PrivateKey, eventID string, body []byte, want int) string { + t.Helper() + timestamp := time.Now().UTC().Format(time.RFC3339) + message := append([]byte(timestamp+"\n"+eventID+"\n"), body...) + signature := ed25519.Sign(private, message) + rec := httptest.NewRecorder() + req := httptest.NewRequest(http.MethodPost, "/v1/incident-webhooks/"+receiverID, bytes.NewReader(body)) + req.Header.Set("Content-Type", "application/json") + req.Header.Set("X-Evydence-Webhook-Event-ID", eventID) + req.Header.Set("X-Evydence-Webhook-Timestamp", timestamp) + req.Header.Set("X-Evydence-Webhook-Signature", "ed25519="+base64.RawStdEncoding.EncodeToString(signature)) + server.Handler().ServeHTTP(rec, req) + if rec.Code != want { + t.Fatalf("POST signed webhook status=%d want=%d body=%s", rec.Code, want, rec.Body.String()) + } + return rec.Body.String() +} + func postJSONNoAuth(t *testing.T, server *Server, path string, payload any, want int) string { t.Helper() body, err := json.Marshal(payload) diff --git a/internal/app/ledger.go b/internal/app/ledger.go index e641d80..cb31620 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -107,6 +107,8 @@ type Ledger struct { deployments map[string]domain.DeploymentEvent incidents map[string]domain.Incident timeline map[string]domain.IncidentTimelineEvent + webhookReceivers map[string]domain.IncidentWebhookReceiver + webhookEvents map[string]domain.IncidentWebhookEvent tasks map[string]domain.RemediationTask securityScans map[string]domain.SecurityScan manualDocs map[string]domain.ManualSecurityDocument @@ -219,6 +221,8 @@ func NewLedgerWithError(cfg Config) (*Ledger, error) { deployments: map[string]domain.DeploymentEvent{}, incidents: map[string]domain.Incident{}, timeline: map[string]domain.IncidentTimelineEvent{}, + webhookReceivers: map[string]domain.IncidentWebhookReceiver{}, + webhookEvents: map[string]domain.IncidentWebhookEvent{}, tasks: map[string]domain.RemediationTask{}, securityScans: map[string]domain.SecurityScan{}, manualDocs: map[string]domain.ManualSecurityDocument{}, diff --git a/internal/app/ports.go b/internal/app/ports.go index 496453d..d68ed1c 100644 --- a/internal/app/ports.go +++ b/internal/app/ports.go @@ -22,97 +22,99 @@ type Outbox interface { } type PersistedState struct { - Tenants map[string]domain.Tenant `json:"tenants"` - Organizations map[string]domain.Organization `json:"organizations"` - Users map[string]domain.HumanUser `json:"users"` - RoleBindings map[string]domain.RoleBinding `json:"role_bindings"` - SSOProviders map[string]domain.SSOProvider `json:"sso_providers"` - IdentityLinks map[string]domain.UserIdentityLink `json:"identity_links"` - SSOSessions map[string]domain.SSOSession `json:"sso_sessions"` - SSOSessionHashes map[string]string `json:"sso_session_hashes,omitempty"` - APIKeys map[string]domain.APIKey `json:"api_keys"` - APIKeyHashes map[string]string `json:"api_key_hashes,omitempty"` - Collectors map[string]domain.Collector `json:"collectors"` - CollectorReleases map[string]domain.CollectorRelease `json:"collector_releases"` - Products map[string]domain.Product `json:"products"` - Projects map[string]domain.Project `json:"projects"` - Releases map[string]domain.Release `json:"releases"` - Artifacts map[string]domain.Artifact `json:"artifacts"` - BuildRuns map[string]domain.BuildRun `json:"build_runs"` - BuildAttestations map[string]domain.BuildAttestation `json:"build_attestations"` - Evidence map[string]domain.EvidenceItem `json:"evidence"` - EvidenceLifecycle map[string]domain.EvidenceLifecycleEvent `json:"evidence_lifecycle"` - ReleaseCandidates map[string]domain.ReleaseCandidate `json:"release_candidates"` - ContainerImages map[string]domain.ContainerImage `json:"container_images"` - ArtifactSignatures map[string]domain.ArtifactSignature `json:"artifact_signatures"` - Repositories map[string]domain.SourceRepository `json:"repositories"` - Commits map[string]domain.SourceCommit `json:"commits"` - Branches map[string]domain.SourceBranch `json:"branches"` - PullRequests map[string]domain.PullRequest `json:"pull_requests"` - Environments map[string]domain.DeploymentEnvironment `json:"environments"` - Deployments map[string]domain.DeploymentEvent `json:"deployments"` - Incidents map[string]domain.Incident `json:"incidents"` - TimelineEvents map[string]domain.IncidentTimelineEvent `json:"timeline_events"` - RemediationTasks map[string]domain.RemediationTask `json:"remediation_tasks"` - SecurityScans map[string]domain.SecurityScan `json:"security_scans"` - ManualSecurityDocs map[string]domain.ManualSecurityDocument `json:"manual_security_docs"` - SBOMDiffs map[string]domain.SBOMDiff `json:"sbom_diffs"` - DependencyChanges map[string]domain.DependencyChange `json:"dependency_changes"` - VulnerabilityWorkflow map[string]domain.VulnerabilityWorkflowRecord `json:"vulnerability_workflow"` - ContractDiffs map[string]domain.ContractDiff `json:"contract_diffs"` - CustomPolicies map[string]domain.CustomPolicy `json:"custom_policies"` - CustomPolicyEvaluations map[string]domain.CustomPolicyEvaluation `json:"custom_policy_evaluations"` - Waivers map[string]domain.Waiver `json:"waivers"` - Approvals map[string]domain.ApprovalRecord `json:"approvals"` - RedactionProfiles map[string]domain.RedactionProfile `json:"redaction_profiles"` - CustomerPackages map[string]domain.CustomerSecurityPackage `json:"customer_packages"` - HTMLReports map[string]domain.HTMLReportPackage `json:"html_reports"` - ReportTemplates map[string]domain.CustomReportTemplate `json:"report_templates"` - RenderedReports map[string]domain.RenderedCustomReport `json:"rendered_reports"` - EvidenceBundles map[string]domain.EvidenceBundle `json:"evidence_bundles"` - BundleImports map[string]domain.EvidenceBundleImport `json:"bundle_imports"` - DSSETrustRoots map[string]domain.DSSETrustRoot `json:"dsse_trust_roots"` - CosignVerifications map[string]domain.CosignVerification `json:"cosign_verifications"` - SigningProviders map[string]domain.SigningProvider `json:"signing_providers"` - MerkleBatches map[string]domain.MerkleBatch `json:"merkle_batches"` - TransparencyCheckpoints map[string]domain.TransparencyCheckpoint `json:"transparency_checkpoints"` - ObjectRetentionPolicies map[string]domain.ObjectRetentionPolicy `json:"object_retention_policies"` - BackupManifests map[string]domain.BackupManifest `json:"backup_manifests"` - LegalHolds map[string]domain.LegalHold `json:"legal_holds"` - RetentionOverrides map[string]domain.RetentionOverride `json:"retention_overrides"` - CustomerPortalAccess map[string]domain.CustomerPortalAccess `json:"customer_portal_access"` - CustomerPortalHashes map[string]string `json:"customer_portal_hashes,omitempty"` - QuestionnaireTemplates map[string]domain.QuestionnaireTemplate `json:"questionnaire_templates"` - QuestionnairePackages map[string]domain.QuestionnairePackage `json:"questionnaire_packages"` - CommercialCollectors map[string]domain.CommercialCollectorDefinition `json:"commercial_collectors"` - EvidenceSummaries map[string]domain.EvidenceSummary `json:"evidence_summaries"` - QuestionnaireDrafts map[string]domain.QuestionnaireDraft `json:"questionnaire_drafts"` - GraphSnapshots map[string]domain.EvidenceGraphSnapshot `json:"graph_snapshots"` - SaaSProfiles map[string]domain.SaaSEditionProfile `json:"saas_profiles"` - PublicTransparencyLogs map[string]domain.PublicTransparencyLog `json:"public_transparency_logs"` - PublicTransparencyItems map[string]domain.PublicTransparencyLogEntry `json:"public_transparency_items"` - MarketplaceCollectors map[string]domain.MarketplaceCollector `json:"marketplace_collectors"` - PDFReports map[string]domain.PDFReportPackage `json:"pdf_reports"` - AnomalyReports map[string]domain.AnomalyReport `json:"anomaly_reports"` - ProviderVerifications map[string]domain.ProviderVerification `json:"provider_verifications"` - SigningOperations map[string]domain.SigningOperation `json:"signing_operations"` - ControlFrameworks map[string]domain.ControlFramework `json:"control_frameworks"` - SecurityControls map[string]domain.SecurityControl `json:"security_controls"` - ControlEvidence map[string]domain.ControlEvidence `json:"control_evidence"` - SBOMs map[string]domain.SBOM `json:"sboms"` - Scans map[string]domain.VulnerabilityScan `json:"scans"` - VEXDocuments map[string]domain.VEXDocument `json:"vex_documents"` - Decisions map[string]domain.VulnerabilityDecision `json:"vulnerability_decisions"` - Contracts map[string]domain.OpenAPIContract `json:"contracts"` - Policies map[string]domain.PolicyEvaluation `json:"policies"` - Exceptions map[string]domain.Exception `json:"exceptions"` - Bundles map[string]domain.ReleaseBundle `json:"bundles"` - SigningKeys map[string]domain.SigningKey `json:"signing_keys"` - SigningKeyPrivate map[string][]byte `json:"signing_key_private,omitempty"` - Signatures map[string]domain.Signature `json:"signatures"` - Verifications map[string]domain.VerificationResult `json:"verifications"` - Chain map[string][]domain.AuditChainEntry `json:"chain"` - Idempotency map[string]IdempotencyRecord `json:"idempotency"` + Tenants map[string]domain.Tenant `json:"tenants"` + Organizations map[string]domain.Organization `json:"organizations"` + Users map[string]domain.HumanUser `json:"users"` + RoleBindings map[string]domain.RoleBinding `json:"role_bindings"` + SSOProviders map[string]domain.SSOProvider `json:"sso_providers"` + IdentityLinks map[string]domain.UserIdentityLink `json:"identity_links"` + SSOSessions map[string]domain.SSOSession `json:"sso_sessions"` + SSOSessionHashes map[string]string `json:"sso_session_hashes,omitempty"` + APIKeys map[string]domain.APIKey `json:"api_keys"` + APIKeyHashes map[string]string `json:"api_key_hashes,omitempty"` + Collectors map[string]domain.Collector `json:"collectors"` + CollectorReleases map[string]domain.CollectorRelease `json:"collector_releases"` + Products map[string]domain.Product `json:"products"` + Projects map[string]domain.Project `json:"projects"` + Releases map[string]domain.Release `json:"releases"` + Artifacts map[string]domain.Artifact `json:"artifacts"` + BuildRuns map[string]domain.BuildRun `json:"build_runs"` + BuildAttestations map[string]domain.BuildAttestation `json:"build_attestations"` + Evidence map[string]domain.EvidenceItem `json:"evidence"` + EvidenceLifecycle map[string]domain.EvidenceLifecycleEvent `json:"evidence_lifecycle"` + ReleaseCandidates map[string]domain.ReleaseCandidate `json:"release_candidates"` + ContainerImages map[string]domain.ContainerImage `json:"container_images"` + ArtifactSignatures map[string]domain.ArtifactSignature `json:"artifact_signatures"` + Repositories map[string]domain.SourceRepository `json:"repositories"` + Commits map[string]domain.SourceCommit `json:"commits"` + Branches map[string]domain.SourceBranch `json:"branches"` + PullRequests map[string]domain.PullRequest `json:"pull_requests"` + Environments map[string]domain.DeploymentEnvironment `json:"environments"` + Deployments map[string]domain.DeploymentEvent `json:"deployments"` + Incidents map[string]domain.Incident `json:"incidents"` + TimelineEvents map[string]domain.IncidentTimelineEvent `json:"timeline_events"` + IncidentWebhookReceivers map[string]domain.IncidentWebhookReceiver `json:"incident_webhook_receivers"` + IncidentWebhookEvents map[string]domain.IncidentWebhookEvent `json:"incident_webhook_events"` + RemediationTasks map[string]domain.RemediationTask `json:"remediation_tasks"` + SecurityScans map[string]domain.SecurityScan `json:"security_scans"` + ManualSecurityDocs map[string]domain.ManualSecurityDocument `json:"manual_security_docs"` + SBOMDiffs map[string]domain.SBOMDiff `json:"sbom_diffs"` + DependencyChanges map[string]domain.DependencyChange `json:"dependency_changes"` + VulnerabilityWorkflow map[string]domain.VulnerabilityWorkflowRecord `json:"vulnerability_workflow"` + ContractDiffs map[string]domain.ContractDiff `json:"contract_diffs"` + CustomPolicies map[string]domain.CustomPolicy `json:"custom_policies"` + CustomPolicyEvaluations map[string]domain.CustomPolicyEvaluation `json:"custom_policy_evaluations"` + Waivers map[string]domain.Waiver `json:"waivers"` + Approvals map[string]domain.ApprovalRecord `json:"approvals"` + RedactionProfiles map[string]domain.RedactionProfile `json:"redaction_profiles"` + CustomerPackages map[string]domain.CustomerSecurityPackage `json:"customer_packages"` + HTMLReports map[string]domain.HTMLReportPackage `json:"html_reports"` + ReportTemplates map[string]domain.CustomReportTemplate `json:"report_templates"` + RenderedReports map[string]domain.RenderedCustomReport `json:"rendered_reports"` + EvidenceBundles map[string]domain.EvidenceBundle `json:"evidence_bundles"` + BundleImports map[string]domain.EvidenceBundleImport `json:"bundle_imports"` + DSSETrustRoots map[string]domain.DSSETrustRoot `json:"dsse_trust_roots"` + CosignVerifications map[string]domain.CosignVerification `json:"cosign_verifications"` + SigningProviders map[string]domain.SigningProvider `json:"signing_providers"` + MerkleBatches map[string]domain.MerkleBatch `json:"merkle_batches"` + TransparencyCheckpoints map[string]domain.TransparencyCheckpoint `json:"transparency_checkpoints"` + ObjectRetentionPolicies map[string]domain.ObjectRetentionPolicy `json:"object_retention_policies"` + BackupManifests map[string]domain.BackupManifest `json:"backup_manifests"` + LegalHolds map[string]domain.LegalHold `json:"legal_holds"` + RetentionOverrides map[string]domain.RetentionOverride `json:"retention_overrides"` + CustomerPortalAccess map[string]domain.CustomerPortalAccess `json:"customer_portal_access"` + CustomerPortalHashes map[string]string `json:"customer_portal_hashes,omitempty"` + QuestionnaireTemplates map[string]domain.QuestionnaireTemplate `json:"questionnaire_templates"` + QuestionnairePackages map[string]domain.QuestionnairePackage `json:"questionnaire_packages"` + CommercialCollectors map[string]domain.CommercialCollectorDefinition `json:"commercial_collectors"` + EvidenceSummaries map[string]domain.EvidenceSummary `json:"evidence_summaries"` + QuestionnaireDrafts map[string]domain.QuestionnaireDraft `json:"questionnaire_drafts"` + GraphSnapshots map[string]domain.EvidenceGraphSnapshot `json:"graph_snapshots"` + SaaSProfiles map[string]domain.SaaSEditionProfile `json:"saas_profiles"` + PublicTransparencyLogs map[string]domain.PublicTransparencyLog `json:"public_transparency_logs"` + PublicTransparencyItems map[string]domain.PublicTransparencyLogEntry `json:"public_transparency_items"` + MarketplaceCollectors map[string]domain.MarketplaceCollector `json:"marketplace_collectors"` + PDFReports map[string]domain.PDFReportPackage `json:"pdf_reports"` + AnomalyReports map[string]domain.AnomalyReport `json:"anomaly_reports"` + ProviderVerifications map[string]domain.ProviderVerification `json:"provider_verifications"` + SigningOperations map[string]domain.SigningOperation `json:"signing_operations"` + ControlFrameworks map[string]domain.ControlFramework `json:"control_frameworks"` + SecurityControls map[string]domain.SecurityControl `json:"security_controls"` + ControlEvidence map[string]domain.ControlEvidence `json:"control_evidence"` + SBOMs map[string]domain.SBOM `json:"sboms"` + Scans map[string]domain.VulnerabilityScan `json:"scans"` + VEXDocuments map[string]domain.VEXDocument `json:"vex_documents"` + Decisions map[string]domain.VulnerabilityDecision `json:"vulnerability_decisions"` + Contracts map[string]domain.OpenAPIContract `json:"contracts"` + Policies map[string]domain.PolicyEvaluation `json:"policies"` + Exceptions map[string]domain.Exception `json:"exceptions"` + Bundles map[string]domain.ReleaseBundle `json:"bundles"` + SigningKeys map[string]domain.SigningKey `json:"signing_keys"` + SigningKeyPrivate map[string][]byte `json:"signing_key_private,omitempty"` + Signatures map[string]domain.Signature `json:"signatures"` + Verifications map[string]domain.VerificationResult `json:"verifications"` + Chain map[string][]domain.AuditChainEntry `json:"chain"` + Idempotency map[string]IdempotencyRecord `json:"idempotency"` } type IdempotencyRecord struct { diff --git a/internal/app/risk_workflows.go b/internal/app/risk_workflows.go index 2ddf23a..93bfd14 100644 --- a/internal/app/risk_workflows.go +++ b/internal/app/risk_workflows.go @@ -3,6 +3,8 @@ package app import ( "bytes" "context" + "crypto/ed25519" + "encoding/base64" "encoding/json" "io" "sort" @@ -27,6 +29,21 @@ type RecordIncidentTimelineInput struct { OccurredAt time.Time } +type CreateIncidentWebhookReceiverInput struct { + IncidentID string + Name string + Provider string + PublicKey string +} + +type HandleIncidentWebhookInput struct { + ReceiverID string + EventID string + Timestamp time.Time + Signature string + Body []byte +} + type CreateRemediationTaskInput struct { IncidentID string ReleaseID string @@ -82,6 +99,8 @@ type CreateCustomPolicyInput struct { Rules []domain.PolicyRule } +const incidentWebhookTimestampTolerance = 5 * time.Minute + func (l *Ledger) CreateIncident(ctx context.Context, actor domain.Actor, in CreateIncidentInput) (domain.Incident, error) { if err := ctx.Err(); err != nil { return domain.Incident{}, err @@ -176,6 +195,189 @@ func (l *Ledger) RecordIncidentTimelineEvent(ctx context.Context, actor domain.A return event, nil } +func (l *Ledger) CreateIncidentWebhookReceiver(ctx context.Context, actor domain.Actor, in CreateIncidentWebhookReceiverInput) (domain.IncidentWebhookReceiver, error) { + if err := ctx.Err(); err != nil { + return domain.IncidentWebhookReceiver{}, err + } + if err := require(actor, ScopeIncidentWrite); err != nil { + return domain.IncidentWebhookReceiver{}, err + } + in.IncidentID = strings.TrimSpace(in.IncidentID) + in.Name = strings.TrimSpace(in.Name) + in.Provider = strings.TrimSpace(in.Provider) + in.PublicKey = strings.TrimSpace(in.PublicKey) + publicKey, err := decodeWebhookPublicKey(in.PublicKey) + if err != nil || in.IncidentID == "" || in.Name == "" || in.Provider == "" { + return domain.IncidentWebhookReceiver{}, ErrValidation + } + l.mu.Lock() + defer l.mu.Unlock() + incident, ok := l.incidents[in.IncidentID] + if !ok || incident.TenantID != actor.TenantID { + return domain.IncidentWebhookReceiver{}, ErrNotFound + } + if err := l.authorizeResourceLocked(actor, ScopeIncidentWrite, resourceRefs{ProductID: incident.ProductID, ReleaseID: incident.ReleaseID, IncidentID: incident.ID}); err != nil { + return domain.IncidentWebhookReceiver{}, err + } + receiver := domain.IncidentWebhookReceiver{ + ID: newID("iwr"), + TenantID: actor.TenantID, + IncidentID: incident.ID, + Name: in.Name, + Provider: in.Provider, + PublicKey: base64.RawStdEncoding.EncodeToString(publicKey), + Status: "active", + SchemaVersion: domain.IncidentWebhookReceiverVersion, + CreatedAt: l.now(), + } + l.webhookReceivers[receiver.ID] = receiver + _, _ = l.appendChainLocked(actor.TenantID, "incident_webhook_receiver.created", "incident_webhook_receiver", receiver.ID, actorType(actor), actorID(actor), "", "") + if err := l.persistLocked(ctx); err != nil { + return domain.IncidentWebhookReceiver{}, err + } + return receiver, nil +} + +func (l *Ledger) HandleIncidentWebhook(ctx context.Context, in HandleIncidentWebhookInput) (domain.IncidentWebhookEvent, domain.IncidentTimelineEvent, error) { + if err := ctx.Err(); err != nil { + return domain.IncidentWebhookEvent{}, domain.IncidentTimelineEvent{}, err + } + in.ReceiverID = strings.TrimSpace(in.ReceiverID) + in.EventID = strings.TrimSpace(in.EventID) + in.Signature = strings.TrimSpace(in.Signature) + if in.ReceiverID == "" || in.EventID == "" || in.Timestamp.IsZero() || in.Signature == "" || len(in.Body) == 0 || len(in.Body) > 2<<20 { + return domain.IncidentWebhookEvent{}, domain.IncidentTimelineEvent{}, ErrValidation + } + now := l.now() + if in.Timestamp.Before(now.Add(-incidentWebhookTimestampTolerance)) || in.Timestamp.After(now.Add(incidentWebhookTimestampTolerance)) { + return domain.IncidentWebhookEvent{}, domain.IncidentTimelineEvent{}, ErrUnauthorized + } + payloadHash := hashBytes(in.Body) + signatureBytes, err := decodeWebhookSignature(in.Signature) + if err != nil { + return domain.IncidentWebhookEvent{}, domain.IncidentTimelineEvent{}, ErrUnauthorized + } + l.mu.Lock() + defer l.mu.Unlock() + receiver, ok := l.webhookReceivers[in.ReceiverID] + if !ok || receiver.Status != "active" { + return domain.IncidentWebhookEvent{}, domain.IncidentTimelineEvent{}, ErrNotFound + } + publicKey, err := decodeWebhookPublicKey(receiver.PublicKey) + if err != nil { + return domain.IncidentWebhookEvent{}, domain.IncidentTimelineEvent{}, ErrUnauthorized + } + signedPayload := incidentWebhookSignedPayload(in.Timestamp, in.EventID, in.Body) + if !ed25519.Verify(ed25519.PublicKey(publicKey), signedPayload, signatureBytes) { + return domain.IncidentWebhookEvent{}, domain.IncidentTimelineEvent{}, ErrUnauthorized + } + for _, existing := range l.webhookEvents { + if existing.ReceiverID != receiver.ID || existing.EventID != in.EventID { + continue + } + if existing.PayloadHash != payloadHash { + return domain.IncidentWebhookEvent{}, domain.IncidentTimelineEvent{}, ErrConflict + } + timeline, ok := l.timeline[existing.TimelineEventID] + if !ok { + return domain.IncidentWebhookEvent{}, domain.IncidentTimelineEvent{}, ErrConflict + } + return existing, timeline, nil + } + incident, ok := l.incidents[receiver.IncidentID] + if !ok || incident.TenantID != receiver.TenantID { + return domain.IncidentWebhookEvent{}, domain.IncidentTimelineEvent{}, ErrNotFound + } + var payload struct { + EventType string `json:"event_type"` + Summary string `json:"summary"` + EvidenceID string `json:"evidence_id"` + OccurredAt time.Time `json:"occurred_at"` + } + dec := json.NewDecoder(bytes.NewReader(in.Body)) + dec.DisallowUnknownFields() + if err := dec.Decode(&payload); err != nil { + return domain.IncidentWebhookEvent{}, domain.IncidentTimelineEvent{}, ErrValidation + } + payload.EventType = strings.TrimSpace(payload.EventType) + payload.Summary = strings.TrimSpace(payload.Summary) + payload.EvidenceID = strings.TrimSpace(payload.EvidenceID) + if payload.EventType == "" || payload.Summary == "" { + return domain.IncidentWebhookEvent{}, domain.IncidentTimelineEvent{}, ErrValidation + } + if payload.OccurredAt.IsZero() { + payload.OccurredAt = now + } + if payload.EvidenceID != "" { + item, ok := l.evidence[payload.EvidenceID] + if !ok || item.TenantID != receiver.TenantID || (item.ReleaseID != "" && item.ReleaseID != incident.ReleaseID) { + return domain.IncidentWebhookEvent{}, domain.IncidentTimelineEvent{}, ErrNotFound + } + } + timeline := domain.IncidentTimelineEvent{ + ID: newID("it"), + TenantID: receiver.TenantID, + IncidentID: incident.ID, + EventType: payload.EventType, + Summary: payload.Summary, + EvidenceID: payload.EvidenceID, + OccurredAt: payload.OccurredAt.UTC(), + SchemaVersion: domain.IncidentTimelineSchemaVersion, + CreatedAt: now, + } + record := domain.IncidentWebhookEvent{ + ID: newID("iwe"), + TenantID: receiver.TenantID, + ReceiverID: receiver.ID, + IncidentID: incident.ID, + Provider: receiver.Provider, + EventID: in.EventID, + PayloadHash: payloadHash, + SignatureHash: hashBytes(signatureBytes), + TimelineEventID: timeline.ID, + Result: "accepted", + SchemaVersion: domain.IncidentWebhookEventVersion, + CreatedAt: now, + } + l.timeline[timeline.ID] = timeline + l.webhookEvents[record.ID] = record + _, _ = l.appendChainLocked(receiver.TenantID, "incident.webhook_timeline_recorded", "incident", incident.ID, "webhook", receiver.ID, payloadHash, "") + if err := l.persistLocked(ctx); err != nil { + return domain.IncidentWebhookEvent{}, domain.IncidentTimelineEvent{}, err + } + return record, timeline, nil +} + +func incidentWebhookSignedPayload(timestamp time.Time, eventID string, body []byte) []byte { + prefix := timestamp.UTC().Format(time.RFC3339) + "\n" + strings.TrimSpace(eventID) + "\n" + return append([]byte(prefix), body...) +} + +func decodeWebhookPublicKey(value string) ([]byte, error) { + key, err := decodeBase64Value(strings.TrimSpace(value)) + if err != nil || len(key) != ed25519.PublicKeySize { + return nil, ErrValidation + } + return key, nil +} + +func decodeWebhookSignature(value string) ([]byte, error) { + value = strings.TrimSpace(value) + value = strings.TrimPrefix(value, "ed25519=") + signature, err := decodeBase64Value(value) + if err != nil || len(signature) != ed25519.SignatureSize { + return nil, ErrUnauthorized + } + return signature, nil +} + +func decodeBase64Value(value string) ([]byte, error) { + if decoded, err := base64.RawStdEncoding.DecodeString(value); err == nil { + return decoded, nil + } + return base64.StdEncoding.DecodeString(value) +} + func (l *Ledger) CreateRemediationTask(ctx context.Context, actor domain.Actor, in CreateRemediationTaskInput) (domain.RemediationTask, error) { if err := ctx.Err(); err != nil { return domain.RemediationTask{}, err diff --git a/internal/app/risk_workflows_more_test.go b/internal/app/risk_workflows_more_test.go index 72b9493..0dfe3d6 100644 --- a/internal/app/risk_workflows_more_test.go +++ b/internal/app/risk_workflows_more_test.go @@ -2,6 +2,9 @@ package app import ( "context" + "crypto/ed25519" + "crypto/rand" + "encoding/base64" "errors" "strings" "testing" @@ -65,6 +68,53 @@ func TestRiskWorkflowEvidenceFormatsAndReports(t *testing.T) { if apiScan.Category != "api_security" || apiScan.Summary["unknown"] != 1 { t.Fatalf("api scan = %#v", apiScan) } + _, webhookPrivate, err := ed25519.GenerateKey(rand.Reader) + if err != nil { + t.Fatalf("webhook key: %v", err) + } + incidentReceiver, err := ledger.CreateIncidentWebhookReceiver(ctx, actor, CreateIncidentWebhookReceiverInput{ + IncidentID: incident.ID, + Name: "pager", + Provider: "incident_tool", + PublicKey: base64.RawStdEncoding.EncodeToString(webhookPrivate.Public().(ed25519.PublicKey)), + }) + if err != nil { + t.Fatalf("incident webhook receiver: %v", err) + } + webhookBody := []byte(`{"event_type":"mitigation_applied","summary":"patched service"}`) + webhookSignature := ed25519.Sign(webhookPrivate, incidentWebhookSignedPayload(fixedNow(), "evt-1", webhookBody)) + webhookRecord, webhookTimeline, err := ledger.HandleIncidentWebhook(ctx, HandleIncidentWebhookInput{ + ReceiverID: incidentReceiver.ID, + EventID: "evt-1", + Timestamp: fixedNow(), + Signature: "ed25519=" + base64.RawStdEncoding.EncodeToString(webhookSignature), + Body: webhookBody, + }) + if err != nil { + t.Fatalf("incident webhook: %v", err) + } + if webhookRecord.Result != "accepted" || webhookRecord.TimelineEventID != webhookTimeline.ID || webhookTimeline.EventType != "mitigation_applied" { + t.Fatalf("webhook record=%#v timeline=%#v", webhookRecord, webhookTimeline) + } + duplicateRecord, duplicateTimeline, err := ledger.HandleIncidentWebhook(ctx, HandleIncidentWebhookInput{ + ReceiverID: incidentReceiver.ID, + EventID: "evt-1", + Timestamp: fixedNow(), + Signature: "ed25519=" + base64.RawStdEncoding.EncodeToString(webhookSignature), + Body: webhookBody, + }) + if err != nil { + t.Fatalf("duplicate incident webhook: %v", err) + } + if duplicateRecord.ID != webhookRecord.ID || duplicateTimeline.ID != webhookTimeline.ID { + t.Fatalf("duplicate webhook not idempotent: %#v %#v", duplicateRecord, duplicateTimeline) + } + if _, _, err := ledger.HandleIncidentWebhook(ctx, HandleIncidentWebhookInput{ReceiverID: incidentReceiver.ID, EventID: "evt-2", Timestamp: fixedNow(), Signature: "ed25519=bad", Body: webhookBody}); !errors.Is(err, ErrUnauthorized) { + t.Fatalf("bad webhook signature err=%v, want unauthorized", err) + } + if _, _, err := ledger.HandleIncidentWebhook(ctx, HandleIncidentWebhookInput{ReceiverID: incidentReceiver.ID, EventID: "evt-3", Timestamp: fixedNow().Add(-10 * time.Minute), Signature: "ed25519=" + base64.RawStdEncoding.EncodeToString(webhookSignature), Body: webhookBody}); !errors.Is(err, ErrUnauthorized) { + t.Fatalf("stale webhook err=%v, want unauthorized", err) + } if _, err := ledger.UploadManualSecurityDocument(ctx, actor, UploadManualSecurityDocumentInput{ProductID: release.ProductID, ReleaseID: release.ID, DocumentType: "threat_model", Title: "Threat Model", Sensitivity: "restricted", Raw: []byte("model"), MediaType: "text/plain"}); err != nil { t.Fatalf("manual doc: %v", err) } diff --git a/internal/app/state.go b/internal/app/state.go index a0181ae..9f4ef1f 100644 --- a/internal/app/state.go +++ b/internal/app/state.go @@ -26,97 +26,99 @@ func (l *Ledger) snapshotLocked() PersistedState { signingKeys[id] = key } state := PersistedState{ - Tenants: l.tenants, - Organizations: l.organizations, - Users: l.users, - RoleBindings: l.roleBindings, - SSOProviders: l.ssoProviders, - IdentityLinks: l.identityLinks, - SSOSessions: ssoSessions, - SSOSessionHashes: map[string]string{}, - APIKeys: apiKeys, - APIKeyHashes: map[string]string{}, - Collectors: l.collectors, - CollectorReleases: l.collectorReleases, - Products: l.products, - Projects: l.projects, - Releases: l.releases, - Artifacts: l.artifacts, - BuildRuns: l.buildRuns, - BuildAttestations: l.attestations, - Evidence: l.evidence, - EvidenceLifecycle: l.lifecycle, - ReleaseCandidates: l.candidates, - ContainerImages: l.images, - ArtifactSignatures: l.artifactSigs, - Repositories: l.repositories, - Commits: l.commits, - Branches: l.branches, - PullRequests: l.pullRequests, - Environments: l.environments, - Deployments: l.deployments, - Incidents: l.incidents, - TimelineEvents: l.timeline, - RemediationTasks: l.tasks, - SecurityScans: l.securityScans, - ManualSecurityDocs: l.manualDocs, - SBOMDiffs: l.sbomDiffs, - DependencyChanges: l.depChanges, - VulnerabilityWorkflow: l.vulnWorkflow, - ContractDiffs: l.contractDiffs, - CustomPolicies: l.customPolicies, - CustomPolicyEvaluations: l.customPolicyEvals, - Waivers: l.waivers, - Approvals: l.approvals, - RedactionProfiles: l.redactions, - CustomerPackages: l.customerPackages, - HTMLReports: l.htmlReports, - ReportTemplates: l.reportTemplates, - RenderedReports: l.renderedReports, - EvidenceBundles: l.evidenceBundles, - BundleImports: l.bundleImports, - DSSETrustRoots: l.dsseTrustRoots, - CosignVerifications: l.cosignVerifs, - SigningProviders: l.signingProviders, - MerkleBatches: l.merkleBatches, - TransparencyCheckpoints: l.transparency, - ObjectRetentionPolicies: l.retentionPolicies, - BackupManifests: l.backupManifests, - LegalHolds: l.legalHolds, - RetentionOverrides: l.retentionOverrides, - CustomerPortalAccess: portalAccess, - CustomerPortalHashes: map[string]string{}, - QuestionnaireTemplates: l.questionTemplates, - QuestionnairePackages: l.questionPackages, - CommercialCollectors: l.commercialCollectors, - EvidenceSummaries: l.evidenceSummaries, - QuestionnaireDrafts: l.questionDrafts, - GraphSnapshots: l.graphSnapshots, - SaaSProfiles: l.saasProfiles, - PublicTransparencyLogs: l.publicLogs, - PublicTransparencyItems: l.publicLogEntries, - MarketplaceCollectors: l.marketplaceCollectors, - PDFReports: l.pdfReports, - AnomalyReports: l.anomalyReports, - ProviderVerifications: l.providerVerifications, - SigningOperations: l.signingOperations, - ControlFrameworks: l.frameworks, - SecurityControls: l.controls, - ControlEvidence: l.controlLinks, - SBOMs: l.sboms, - Scans: l.scans, - VEXDocuments: l.vexDocuments, - Decisions: l.decisions, - Contracts: l.contracts, - Policies: l.policies, - Exceptions: l.exceptions, - Bundles: l.bundles, - SigningKeys: signingKeys, - SigningKeyPrivate: map[string][]byte{}, - Signatures: l.signatures, - Verifications: l.verifications, - Chain: l.chain, - Idempotency: l.idempotency, + Tenants: l.tenants, + Organizations: l.organizations, + Users: l.users, + RoleBindings: l.roleBindings, + SSOProviders: l.ssoProviders, + IdentityLinks: l.identityLinks, + SSOSessions: ssoSessions, + SSOSessionHashes: map[string]string{}, + APIKeys: apiKeys, + APIKeyHashes: map[string]string{}, + Collectors: l.collectors, + CollectorReleases: l.collectorReleases, + Products: l.products, + Projects: l.projects, + Releases: l.releases, + Artifacts: l.artifacts, + BuildRuns: l.buildRuns, + BuildAttestations: l.attestations, + Evidence: l.evidence, + EvidenceLifecycle: l.lifecycle, + ReleaseCandidates: l.candidates, + ContainerImages: l.images, + ArtifactSignatures: l.artifactSigs, + Repositories: l.repositories, + Commits: l.commits, + Branches: l.branches, + PullRequests: l.pullRequests, + Environments: l.environments, + Deployments: l.deployments, + Incidents: l.incidents, + TimelineEvents: l.timeline, + IncidentWebhookReceivers: l.webhookReceivers, + IncidentWebhookEvents: l.webhookEvents, + RemediationTasks: l.tasks, + SecurityScans: l.securityScans, + ManualSecurityDocs: l.manualDocs, + SBOMDiffs: l.sbomDiffs, + DependencyChanges: l.depChanges, + VulnerabilityWorkflow: l.vulnWorkflow, + ContractDiffs: l.contractDiffs, + CustomPolicies: l.customPolicies, + CustomPolicyEvaluations: l.customPolicyEvals, + Waivers: l.waivers, + Approvals: l.approvals, + RedactionProfiles: l.redactions, + CustomerPackages: l.customerPackages, + HTMLReports: l.htmlReports, + ReportTemplates: l.reportTemplates, + RenderedReports: l.renderedReports, + EvidenceBundles: l.evidenceBundles, + BundleImports: l.bundleImports, + DSSETrustRoots: l.dsseTrustRoots, + CosignVerifications: l.cosignVerifs, + SigningProviders: l.signingProviders, + MerkleBatches: l.merkleBatches, + TransparencyCheckpoints: l.transparency, + ObjectRetentionPolicies: l.retentionPolicies, + BackupManifests: l.backupManifests, + LegalHolds: l.legalHolds, + RetentionOverrides: l.retentionOverrides, + CustomerPortalAccess: portalAccess, + CustomerPortalHashes: map[string]string{}, + QuestionnaireTemplates: l.questionTemplates, + QuestionnairePackages: l.questionPackages, + CommercialCollectors: l.commercialCollectors, + EvidenceSummaries: l.evidenceSummaries, + QuestionnaireDrafts: l.questionDrafts, + GraphSnapshots: l.graphSnapshots, + SaaSProfiles: l.saasProfiles, + PublicTransparencyLogs: l.publicLogs, + PublicTransparencyItems: l.publicLogEntries, + MarketplaceCollectors: l.marketplaceCollectors, + PDFReports: l.pdfReports, + AnomalyReports: l.anomalyReports, + ProviderVerifications: l.providerVerifications, + SigningOperations: l.signingOperations, + ControlFrameworks: l.frameworks, + SecurityControls: l.controls, + ControlEvidence: l.controlLinks, + SBOMs: l.sboms, + Scans: l.scans, + VEXDocuments: l.vexDocuments, + Decisions: l.decisions, + Contracts: l.contracts, + Policies: l.policies, + Exceptions: l.exceptions, + Bundles: l.bundles, + SigningKeys: signingKeys, + SigningKeyPrivate: map[string][]byte{}, + Signatures: l.signatures, + Verifications: l.verifications, + Chain: l.chain, + Idempotency: l.idempotency, } for id, key := range state.APIKeys { if key.Hash != "" { @@ -212,6 +214,8 @@ func (l *Ledger) applyState(state PersistedState) { l.deployments = state.Deployments l.incidents = state.Incidents l.timeline = state.TimelineEvents + l.webhookReceivers = state.IncidentWebhookReceivers + l.webhookEvents = state.IncidentWebhookEvents l.tasks = state.RemediationTasks l.securityScans = state.SecurityScans l.manualDocs = state.ManualSecurityDocs @@ -424,6 +428,12 @@ func normalizeState(state PersistedState) PersistedState { if state.TimelineEvents == nil { state.TimelineEvents = map[string]domain.IncidentTimelineEvent{} } + if state.IncidentWebhookReceivers == nil { + state.IncidentWebhookReceivers = map[string]domain.IncidentWebhookReceiver{} + } + if state.IncidentWebhookEvents == nil { + state.IncidentWebhookEvents = map[string]domain.IncidentWebhookEvent{} + } if state.RemediationTasks == nil { state.RemediationTasks = map[string]domain.RemediationTask{} } diff --git a/internal/domain/domain.go b/internal/domain/domain.go index 418918e..9676748 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -31,6 +31,8 @@ const ( DeploymentEventSchemaVersion = "deployment-event.v1.0.0" IncidentSchemaVersion = "incident.v1.0.0" IncidentTimelineSchemaVersion = "incident-timeline-event.v1.0.0" + IncidentWebhookReceiverVersion = "incident-webhook-receiver.v1.0.0" + IncidentWebhookEventVersion = "incident-webhook-event.v1.0.0" RemediationTaskSchemaVersion = "remediation-task.v1.0.0" SecurityScanSchemaVersion = "security-scan.v1.0.0" ManualSecurityDocSchemaVersion = "manual-security-document.v1.0.0" @@ -1241,6 +1243,33 @@ type IncidentTimelineEvent struct { CreatedAt time.Time `json:"created_at"` } +type IncidentWebhookReceiver struct { + ID string `json:"id"` + TenantID string `json:"tenant_id"` + IncidentID string `json:"incident_id"` + Name string `json:"name"` + Provider string `json:"provider"` + PublicKey string `json:"public_key"` + Status string `json:"status"` + SchemaVersion string `json:"schema_version"` + CreatedAt time.Time `json:"created_at"` +} + +type IncidentWebhookEvent struct { + ID string `json:"id"` + TenantID string `json:"tenant_id"` + ReceiverID string `json:"receiver_id"` + IncidentID string `json:"incident_id"` + Provider string `json:"provider"` + EventID string `json:"event_id"` + PayloadHash string `json:"payload_hash"` + SignatureHash string `json:"signature_hash"` + TimelineEventID string `json:"timeline_event_id,omitempty"` + Result string `json:"result"` + SchemaVersion string `json:"schema_version"` + CreatedAt time.Time `json:"created_at"` +} + type RemediationTask struct { ID string `json:"id"` TenantID string `json:"tenant_id"` diff --git a/migrations/20260528001000_signed_incident_webhooks.down.sql b/migrations/20260528001000_signed_incident_webhooks.down.sql new file mode 100644 index 0000000..f916d97 --- /dev/null +++ b/migrations/20260528001000_signed_incident_webhooks.down.sql @@ -0,0 +1,4 @@ +DROP INDEX IF EXISTS incident_webhook_events_tenant_incident_idx; +DROP INDEX IF EXISTS incident_webhook_receivers_tenant_incident_idx; +DROP TABLE IF EXISTS incident_webhook_events; +DROP TABLE IF EXISTS incident_webhook_receivers; diff --git a/migrations/20260528001000_signed_incident_webhooks.up.sql b/migrations/20260528001000_signed_incident_webhooks.up.sql new file mode 100644 index 0000000..30cbb60 --- /dev/null +++ b/migrations/20260528001000_signed_incident_webhooks.up.sql @@ -0,0 +1,33 @@ +CREATE TABLE IF NOT EXISTS incident_webhook_receivers ( + id text PRIMARY KEY, + tenant_id text NOT NULL, + incident_id text NOT NULL, + name text NOT NULL, + provider text NOT NULL, + public_key text NOT NULL, + status text NOT NULL, + schema_version text NOT NULL, + created_at timestamptz NOT NULL +); + +CREATE TABLE IF NOT EXISTS incident_webhook_events ( + id text PRIMARY KEY, + tenant_id text NOT NULL, + receiver_id text NOT NULL, + incident_id text NOT NULL, + provider text NOT NULL, + event_id text NOT NULL, + payload_hash text NOT NULL, + signature_hash text NOT NULL, + timeline_event_id text, + result text NOT NULL, + schema_version text NOT NULL, + created_at timestamptz NOT NULL, + UNIQUE (tenant_id, receiver_id, event_id) +); + +CREATE INDEX IF NOT EXISTS incident_webhook_receivers_tenant_incident_idx + ON incident_webhook_receivers (tenant_id, incident_id, created_at); + +CREATE INDEX IF NOT EXISTS incident_webhook_events_tenant_incident_idx + ON incident_webhook_events (tenant_id, incident_id, created_at); diff --git a/openapi.yaml b/openapi.yaml index 7a677a6..6cf1950 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{},"payload_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source":{"type":"string"},"subject_refs":{"items":{"type":"string"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"type":"object"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"api_key_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"},"user_count":{"type":"integer"}},"required":["tenant_count","resource_counts"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Instance admin snapshot envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"operationId":"registerArtifact","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"operationId":"generateBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"operationId":"verifyBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"operationId":"createBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"operationId":"getBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"operationId":"uploadGitHubSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"operationId":"uploadGitLabSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"operationId":"createGraphSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"operationId":"listProducts","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"operationId":"createProduct","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"operationId":"createProject","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"operationId":"verifyProviderIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"operationId":"ready","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"operationId":"createRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"operationId":"getRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"operationId":"approveRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"operationId":"freezeRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"operationId":"controlCoverageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"operationId":"craReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"operationId":"releaseReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"operationId":"uploadSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"operationId":"getSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"operationId":"createSSOProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"operationId":"uploadVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"operationId":"uploadCycloneDXVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"operationId":"getVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"operationId":"uploadVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"operationId":"getVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{},"payload_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source":{"type":"string"},"subject_refs":{"items":{"type":"string"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"type":"object"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"api_key_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"},"user_count":{"type":"integer"}},"required":["tenant_count","resource_counts"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Instance admin snapshot envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"operationId":"registerArtifact","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"operationId":"generateBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"operationId":"verifyBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"operationId":"createBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"operationId":"getBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"operationId":"uploadGitHubSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"operationId":"uploadGitLabSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"operationId":"createGraphSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"operationId":"listProducts","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"operationId":"createProduct","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"operationId":"createProject","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"operationId":"verifyProviderIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"operationId":"ready","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"operationId":"createRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"operationId":"getRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"operationId":"approveRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"operationId":"freezeRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"operationId":"controlCoverageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"operationId":"craReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"operationId":"releaseReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"operationId":"uploadSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"operationId":"getSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"operationId":"createSSOProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"operationId":"uploadVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"operationId":"uploadCycloneDXVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"operationId":"getVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"operationId":"uploadVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"operationId":"getVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From 1e3638021fcb8120cc7103060a7846ba830319dd Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 16:49:41 +0300 Subject: [PATCH 027/287] feat: expand offline verifier cli --- .implementation_increments.md | 2 +- cmd/evydence/main.go | 210 +++++++++++++++++++++++++++++++++- cmd/evydence/main_test.go | 138 ++++++++++++++++++++++ docs/air-gapped.md | 9 ++ docs/release-signing.md | 9 ++ 5 files changed, 364 insertions(+), 4 deletions(-) diff --git a/.implementation_increments.md b/.implementation_increments.md index f6a5be9..bae47ec 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -119,7 +119,7 @@ Status legend: ## Integrity, Signing, And Verification Increments 33. `[x]` Offline Verifier CLI - Extended CLI to verify evidence bundle manifests without API access. Broader offline signature and audit-chain verification remain future CLI expansion. + Extended CLI to verify evidence bundle manifests, included Ed25519 bundle signatures when public keys/signatures are present, and exported audit-chain hash continuity without API access. 34. `[x]` Evidence Bundle Export And Import Added portable evidence export/import manifests for air-gapped review, including hashes, signatures, chain checkpoints, and verification instructions. diff --git a/cmd/evydence/main.go b/cmd/evydence/main.go index c728934..e0ee705 100644 --- a/cmd/evydence/main.go +++ b/cmd/evydence/main.go @@ -53,6 +53,11 @@ func run(args []string) error { return usage() } return verifyEvidenceBundle(args[1]) + case "verify-audit-chain": + if len(args) != 2 { + return usage() + } + return verifyAuditChain(args[1]) case "github-actions": if len(args) < 2 || args[1] != "upload-build" { return usage() @@ -90,7 +95,7 @@ func run(args []string) error { } func usage() error { - return errors.New("usage: evydence hash | evydence verify-manifest --hash sha256: | evydence verify-evidence-bundle | evydence github-actions upload-build ... | evydence import-bundle upload ... | evydence upload manifest ... | evydence release manifest|sign|verify|keygen") + return errors.New("usage: evydence hash | evydence verify-manifest --hash sha256: | evydence verify-evidence-bundle | evydence verify-audit-chain | evydence github-actions upload-build ... | evydence import-bundle upload ... | evydence upload manifest ... | evydence release manifest|sign|verify|keygen") } func hashFile(path string) (string, error) { @@ -155,8 +160,11 @@ func verifyEvidenceBundle(path string) error { return err } var bundle struct { - Manifest map[string]any `json:"manifest"` - ManifestHash string `json:"manifest_hash"` + Manifest map[string]any `json:"manifest"` + ManifestHash string `json:"manifest_hash"` + SignatureRefs []string `json:"signature_refs"` + Signatures []offlineSignature `json:"signatures"` + SigningKeys []offlineSigningKey `json:"signing_keys"` } if err := json.Unmarshal(body, &bundle); err != nil { return errors.New("evidence bundle is not JSON") @@ -181,10 +189,173 @@ func verifyEvidenceBundle(path string) error { if got != bundle.ManifestHash { return fmt.Errorf("evidence bundle hash mismatch: got %s want %s", got, bundle.ManifestHash) } + if err := verifyOfflineSignatures(bundle.ManifestHash, bundle.SignatureRefs, bundle.Signatures, bundle.SigningKeys); err != nil { + return err + } + if len(bundle.Signatures) > 0 || len(bundle.SigningKeys) > 0 { + fmt.Println("evidence bundle manifest and signature verified") + return nil + } fmt.Println("evidence bundle manifest verified") return nil } +type offlineSignature struct { + ID string `json:"id"` + KeyID string `json:"key_id"` + Algorithm string `json:"algorithm"` + Value string `json:"value"` + CreatedAt time.Time `json:"created_at,omitempty"` +} + +type offlineSigningKey struct { + ID string `json:"id"` + Algorithm string `json:"algorithm"` + Status string `json:"status"` + PublicKey string `json:"public_key"` + RevokedAt *time.Time `json:"revoked_at,omitempty"` +} + +type offlineAuditChainEntry struct { + ID string `json:"id"` + TenantID string `json:"tenant_id"` + Sequence int64 `json:"sequence"` + EntryType string `json:"entry_type"` + SubjectType string `json:"subject_type"` + SubjectID string `json:"subject_id"` + ActorType string `json:"actor_type"` + ActorID string `json:"actor_id"` + OccurredAt time.Time `json:"occurred_at"` + PayloadHash string `json:"payload_hash"` + PreviousEntryHash string `json:"previous_entry_hash"` + SignatureRef string `json:"signature_ref"` + SchemaVersion string `json:"schema_version"` + CanonicalEntryHash string `json:"canonical_entry_hash"` + EntryHash string `json:"entry_hash"` +} + +func verifyAuditChain(path string) error { + body, err := readFileStrict(path) + if err != nil { + return err + } + entries, err := decodeAuditChain(body) + if err != nil { + return err + } + if len(entries) == 0 { + return errors.New("audit chain contains no entries") + } + previous := "" + for i, entry := range entries { + if entry.Sequence != int64(i+1) { + return fmt.Errorf("audit chain sequence mismatch at entry %d", i+1) + } + if entry.PreviousEntryHash != previous { + return fmt.Errorf("audit chain previous hash mismatch at entry %d", i+1) + } + canonical, err := auditEntryCanonicalHash(entry) + if err != nil { + return err + } + if entry.CanonicalEntryHash != canonical { + return fmt.Errorf("audit chain canonical hash mismatch at entry %d", i+1) + } + if hashString(previous+"\n"+entry.CanonicalEntryHash) != entry.EntryHash { + return fmt.Errorf("audit chain entry hash mismatch at entry %d", i+1) + } + previous = entry.EntryHash + } + fmt.Println("audit chain verified") + return nil +} + +func decodeAuditChain(body []byte) ([]offlineAuditChainEntry, error) { + var envelope struct { + Entries []offlineAuditChainEntry `json:"entries"` + Chain []offlineAuditChainEntry `json:"chain"` + } + if err := json.Unmarshal(body, &envelope); err == nil { + if len(envelope.Entries) > 0 { + return envelope.Entries, nil + } + if len(envelope.Chain) > 0 { + return envelope.Chain, nil + } + } + var entries []offlineAuditChainEntry + if err := json.Unmarshal(body, &entries); err != nil { + return nil, errors.New("audit chain is not JSON array or entries envelope") + } + return entries, nil +} + +func auditEntryCanonicalHash(entry offlineAuditChainEntry) (string, error) { + if strings.TrimSpace(entry.TenantID) == "" || entry.Sequence <= 0 || strings.TrimSpace(entry.EntryType) == "" || strings.TrimSpace(entry.SubjectType) == "" || strings.TrimSpace(entry.SubjectID) == "" || strings.TrimSpace(entry.ActorType) == "" || strings.TrimSpace(entry.SchemaVersion) == "" || entry.OccurredAt.IsZero() { + return "", errors.New("audit chain entry missing required fields") + } + return canonicalJSONHash(map[string]any{ + "tenant_id": entry.TenantID, + "sequence": entry.Sequence, + "entry_type": entry.EntryType, + "subject_type": entry.SubjectType, + "subject_id": entry.SubjectID, + "actor_type": entry.ActorType, + "actor_id": entry.ActorID, + "occurred_at": entry.OccurredAt.UTC().Format(time.RFC3339Nano), + "payload_hash": entry.PayloadHash, + "previous_entry_hash": entry.PreviousEntryHash, + "signature_ref": entry.SignatureRef, + "schema_version": entry.SchemaVersion, + }) +} + +func verifyOfflineSignatures(payloadHash string, refs []string, signatures []offlineSignature, keys []offlineSigningKey) error { + if len(signatures) == 0 && len(keys) == 0 { + return nil + } + if strings.TrimSpace(payloadHash) == "" || len(refs) == 0 || len(signatures) == 0 || len(keys) == 0 { + return errors.New("offline signature material is incomplete") + } + keyByID := map[string]offlineSigningKey{} + for _, key := range keys { + if key.ID != "" { + keyByID[key.ID] = key + } + } + signatureByID := map[string]offlineSignature{} + for _, signature := range signatures { + if signature.ID != "" { + signatureByID[signature.ID] = signature + } + } + for _, ref := range refs { + signature, ok := signatureByID[strings.TrimSpace(ref)] + if !ok || signature.Algorithm != "Ed25519" { + continue + } + key, ok := keyByID[signature.KeyID] + if !ok || key.Algorithm != "Ed25519" { + continue + } + if key.Status == "revoked" && (key.RevokedAt == nil || signature.CreatedAt.IsZero() || signature.CreatedAt.After(*key.RevokedAt)) { + continue + } + pub, err := decodeBase64Flexible(key.PublicKey) + if err != nil || len(pub) != ed25519.PublicKeySize { + continue + } + value, err := decodeBase64Flexible(signature.Value) + if err != nil || len(value) != ed25519.SignatureSize { + continue + } + if ed25519.Verify(ed25519.PublicKey(pub), []byte(payloadHash), value) { + return nil + } + } + return errors.New("offline signature verification failed") +} + func cleanOperatorPath(path string) (string, error) { path = strings.TrimSpace(path) if path == "" { @@ -603,6 +774,39 @@ func canonicalFileHash(path string) ([]byte, string, error) { return canonical, "sha256:" + hex.EncodeToString(sum[:]), nil } +func canonicalJSONHash(value any) (string, error) { + body, err := json.Marshal(value) + if err != nil { + return "", err + } + var normalized any + if err := json.Unmarshal(body, &normalized); err != nil { + return "", err + } + body, err = json.Marshal(normalized) + if err != nil { + return "", err + } + return hashBytes(body), nil +} + +func hashBytes(body []byte) string { + sum := sha256.Sum256(body) + return "sha256:" + hex.EncodeToString(sum[:]) +} + +func hashString(value string) string { + return hashBytes([]byte(value)) +} + +func decodeBase64Flexible(value string) ([]byte, error) { + value = strings.TrimSpace(value) + if decoded, err := base64.RawStdEncoding.DecodeString(value); err == nil { + return decoded, nil + } + return base64.StdEncoding.DecodeString(value) +} + func verifyReleaseArtifactFiles(manifestPath string, _ []byte) error { body, err := readFileStrict(manifestPath) if err != nil { diff --git a/cmd/evydence/main_test.go b/cmd/evydence/main_test.go index e8de1cd..83bb47b 100644 --- a/cmd/evydence/main_test.go +++ b/cmd/evydence/main_test.go @@ -12,6 +12,7 @@ import ( "os" "strings" "testing" + "time" ) func TestCleanOperatorPathRejectsNUL(t *testing.T) { @@ -118,6 +119,81 @@ func TestVerifyEvidenceBundle(t *testing.T) { } } +func TestVerifyEvidenceBundleChecksIncludedSignature(t *testing.T) { + manifest := map[string]any{"bundle_version": "evidence-bundle.v1.0.0", "evidence_ids": []any{"ev_1"}} + canonical, err := json.Marshal(manifest) + if err != nil { + t.Fatalf("marshal manifest: %v", err) + } + sum := sha256.Sum256(canonical) + manifestHash := "sha256:" + hex.EncodeToString(sum[:]) + pub, priv, err := ed25519.GenerateKey(rand.Reader) + if err != nil { + t.Fatalf("keygen: %v", err) + } + bundleBody, err := json.Marshal(map[string]any{ + "manifest": manifest, + "manifest_hash": manifestHash, + "signature_refs": []string{"sig_1"}, + "signatures": []map[string]any{{ + "id": "sig_1", + "key_id": "sk_1", + "algorithm": "Ed25519", + "value": base64.RawStdEncoding.EncodeToString(ed25519.Sign(priv, []byte(manifestHash))), + }}, + "signing_keys": []map[string]any{{ + "id": "sk_1", + "algorithm": "Ed25519", + "status": "active", + "public_key": base64.RawStdEncoding.EncodeToString(pub), + }}, + }) + if err != nil { + t.Fatalf("marshal bundle: %v", err) + } + path := t.TempDir() + "/bundle.json" + if err := os.WriteFile(path, bundleBody, 0o600); err != nil { + t.Fatalf("write bundle: %v", err) + } + if err := verifyEvidenceBundle(path); err != nil { + t.Fatalf("verify signed bundle: %v", err) + } + tampered := strings.Replace(string(bundleBody), "sig_1", "sig_2", 1) + if err := os.WriteFile(path, []byte(tampered), 0o600); err != nil { + t.Fatalf("write tampered bundle: %v", err) + } + if err := verifyEvidenceBundle(path); err == nil || !strings.Contains(err.Error(), "signature verification failed") { + t.Fatalf("tampered signature refs err=%v", err) + } +} + +func TestVerifyAuditChainDetectsHashTampering(t *testing.T) { + first := testAuditEntry(t, "", 1) + second := testAuditEntry(t, first["entry_hash"].(string), 2) + path := t.TempDir() + "/chain.json" + body, err := json.Marshal(map[string]any{"entries": []map[string]any{first, second}}) + if err != nil { + t.Fatalf("marshal chain: %v", err) + } + if err := os.WriteFile(path, body, 0o600); err != nil { + t.Fatalf("write chain: %v", err) + } + if err := verifyAuditChain(path); err != nil { + t.Fatalf("verify chain: %v", err) + } + second["previous_entry_hash"] = "sha256:" + strings.Repeat("0", 64) + body, err = json.Marshal([]map[string]any{first, second}) + if err != nil { + t.Fatalf("marshal tampered chain: %v", err) + } + if err := os.WriteFile(path, body, 0o600); err != nil { + t.Fatalf("write tampered chain: %v", err) + } + if err := verifyAuditChain(path); err == nil || !strings.Contains(err.Error(), "previous hash") { + t.Fatalf("tampered chain err=%v", err) + } +} + func TestGitHubActionsUploadBuildRequiresGitHubMetadata(t *testing.T) { t.Setenv("EVYDENCE_API_URL", "http://127.0.0.1") t.Setenv("EVYDENCE_API_KEY", "evy_secret") @@ -337,6 +413,18 @@ func TestRunCoversHashBundleAndReleaseCommands(t *testing.T) { if err := run([]string{"verify-evidence-bundle", bundlePath}); err != nil { t.Fatalf("run verify evidence bundle: %v", err) } + chainPath := dir + "/chain.json" + entry := testAuditEntry(t, "", 1) + chainBody, err := json.Marshal([]map[string]any{entry}) + if err != nil { + t.Fatalf("marshal chain: %v", err) + } + if err := os.WriteFile(chainPath, chainBody, 0o600); err != nil { + t.Fatalf("write chain: %v", err) + } + if err := run([]string{"verify-audit-chain", chainPath}); err != nil { + t.Fatalf("run verify audit chain: %v", err) + } } func TestRunUploadCommandsAndGitHubUsageBranches(t *testing.T) { @@ -353,3 +441,53 @@ func TestRunUploadCommandsAndGitHubUsageBranches(t *testing.T) { t.Fatalf("release usage err=%v", err) } } + +func testAuditEntry(t *testing.T, previous string, sequence int64) map[string]any { + t.Helper() + entry := map[string]any{ + "tenant_id": "ten_1", + "sequence": sequence, + "entry_type": "evidence.created", + "subject_type": "evidence", + "subject_id": "ev_1", + "actor_type": "api_key", + "actor_id": "key_1", + "occurred_at": "2026-05-28T12:00:00Z", + "payload_hash": "sha256:" + strings.Repeat("a", 64), + "previous_entry_hash": previous, + "signature_ref": "", + "schema_version": "audit-chain-entry.v1.0.0", + "id": "ace_1", + "canonical_entry_hash": "", + "entry_hash": "", + } + canonical, err := auditEntryCanonicalHash(offlineAuditChainEntry{ + TenantID: entry["tenant_id"].(string), + Sequence: sequence, + EntryType: entry["entry_type"].(string), + SubjectType: entry["subject_type"].(string), + SubjectID: entry["subject_id"].(string), + ActorType: entry["actor_type"].(string), + ActorID: entry["actor_id"].(string), + OccurredAt: mustParseTime(t, entry["occurred_at"].(string)), + PayloadHash: entry["payload_hash"].(string), + PreviousEntryHash: previous, + SignatureRef: entry["signature_ref"].(string), + SchemaVersion: entry["schema_version"].(string), + }) + if err != nil { + t.Fatalf("canonical audit hash: %v", err) + } + entry["canonical_entry_hash"] = canonical + entry["entry_hash"] = hashString(previous + "\n" + canonical) + return entry +} + +func mustParseTime(t *testing.T, value string) time.Time { + t.Helper() + parsed, err := time.Parse(time.RFC3339, value) + if err != nil { + t.Fatalf("parse time: %v", err) + } + return parsed +} diff --git a/docs/air-gapped.md b/docs/air-gapped.md index c6f7259..92c241e 100644 --- a/docs/air-gapped.md +++ b/docs/air-gapped.md @@ -47,6 +47,15 @@ Run the verifier from the transferred package directory. Use `./evydence` for th Expected result: the command exits successfully and reports that the manifest signature and referenced artifact hashes verify. +Evidence bundles and audit-chain exports can also be checked without API access: + +```sh +./evydence verify-evidence-bundle evidence-bundle.json +./evydence verify-audit-chain audit-chain.json +``` + +`verify-evidence-bundle` always checks the canonical manifest hash. If the bundle file includes `signature_refs`, `signatures`, and `signing_keys`, it also verifies an Ed25519 signature over the manifest hash. `verify-audit-chain` checks sequence continuity, previous-entry linkage, canonical entry hashes, and entry hashes. These checks validate the exported bytes and included public material; they do not contact external transparency logs or key-management systems. + ## Import Evidence Bundles For CI systems that cannot call the API, write an evidence bundle in CI, move it through the same controlled transfer process, then upload it from the connected side: diff --git a/docs/release-signing.md b/docs/release-signing.md index 7cc6247..f5e793b 100644 --- a/docs/release-signing.md +++ b/docs/release-signing.md @@ -30,3 +30,12 @@ Sign and verify: ``` Production release signing should use controlled key custody and publish the manifest, signature, public key, and image digest references together. Verification proves that the manifest and listed artifact bytes match the signature; it does not prove that a deployment is secure. + +For Evydence evidence exports, use the same CLI for offline ledger checks: + +```sh +./dist/evydence verify-evidence-bundle evidence-bundle.json +./dist/evydence verify-audit-chain audit-chain.json +``` + +Evidence-bundle verification checks the canonical manifest hash and, when the export includes `signature_refs`, `signatures`, and `signing_keys`, verifies an included Ed25519 signature over the manifest hash. Audit-chain verification checks local hash continuity for the exported chain. Neither command makes legal compliance, external transparency, or secure-release claims. From 02d83ef6b1330e3ca607b96a9bfaee44e983e4db Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 16:58:16 +0300 Subject: [PATCH 028/287] feat: add observability starter assets --- .implementation_increments.md | 2 +- Makefile | 4 + deploy/observability/grafana-dashboard.json | 82 ++++++++++++++++++++ deploy/observability/prometheus-rules.yaml | 27 +++++++ docs/README.md | 1 + docs/operations.md | 3 +- docs/reference/observability.md | 35 +++++++++ internal/adapters/httpapi/router_test.go | 20 +++++ internal/adapters/httpapi/system_handlers.go | 46 +++++++++++ 9 files changed, 218 insertions(+), 2 deletions(-) create mode 100644 deploy/observability/grafana-dashboard.json create mode 100644 deploy/observability/prometheus-rules.yaml create mode 100644 docs/reference/observability.md diff --git a/.implementation_increments.md b/.implementation_increments.md index bae47ec..7258123 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -154,7 +154,7 @@ Status legend: Added backup manifests with state hashes, resource counts, audit-chain consistency checks, verification endpoints, and operations guidance for paired database/object-store backups. 44. `[x]` Observability And Readiness - Added `/v1/ready`, admin-scoped safe metrics, and operations guidance. OpenTelemetry dashboards and alert packs remain future observability expansion. + Added `/v1/ready`, admin-scoped safe JSON and Prometheus text metrics, operations guidance, Prometheus alert rules, and a Grafana dashboard starter. OpenTelemetry exporter wiring remains deployment-specific hardening. 45. `[x]` Admin Audit Querying Added `/v1/audit-log` with tenant-scoped subject/time/limit filters, export-safe audit-chain fields, and admin access control. diff --git a/Makefile b/Makefile index 4b0350b..85b1ea6 100644 --- a/Makefile +++ b/Makefile @@ -62,6 +62,7 @@ docs-check: ## Validate canonical docs exist and avoid forbidden product claims @test -f docs/how-to/install-and-operate.md @test -f docs/reference/configuration.md @test -f docs/reference/openapi.md + @test -f docs/reference/observability.md @test -f docs/reference/worker-outbox.md @test -f docs/reference/release-validation.md @test -f docs/explanation/trust-model.md @@ -83,6 +84,7 @@ docs-check: ## Validate canonical docs exist and avoid forbidden product claims "production-hardening.md" \ "reference/configuration.md" \ "reference/openapi.md" \ + "reference/observability.md" \ "reference/worker-outbox.md" \ "reference/release-validation.md" \ "collectors/source-snapshots.md" \ @@ -119,6 +121,8 @@ deploy-check: ## Validate deployment and air-gap skeletons exist @test -f deploy/helm/evydence/templates/deployment-api.yaml @test -f deploy/helm/evydence/templates/deployment-worker.yaml @test -f deploy/airgap/manifest.yaml + @test -f deploy/observability/prometheus-rules.yaml + @test -f deploy/observability/grafana-dashboard.json sdk-check: ## Validate curated SDK example files exist @test -f sdk/go/evydence/client.go diff --git a/deploy/observability/grafana-dashboard.json b/deploy/observability/grafana-dashboard.json new file mode 100644 index 0000000..981f714 --- /dev/null +++ b/deploy/observability/grafana-dashboard.json @@ -0,0 +1,82 @@ +{ + "annotations": { + "list": [] + }, + "editable": true, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 1, + "targets": [ + { + "expr": "evydence_resource_count", + "legendFormat": "{{resource}}" + } + ], + "title": "Tenant Resource Counts", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 2, + "targets": [ + { + "expr": "increase(evydence_customer_portal_failed_access_count[1h])", + "legendFormat": "failed portal access" + }, + { + "expr": "evydence_customer_portal_revoked_access_count", + "legendFormat": "revoked portal access" + } + ], + "title": "Customer Portal Access Guardrails", + "type": "timeseries" + } + ], + "schemaVersion": 39, + "tags": [ + "evydence", + "operations" + ], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timezone": "utc", + "title": "Evydence Runtime", + "uid": "evydence-runtime", + "version": 1 +} diff --git a/deploy/observability/prometheus-rules.yaml b/deploy/observability/prometheus-rules.yaml new file mode 100644 index 0000000..2fdac7b --- /dev/null +++ b/deploy/observability/prometheus-rules.yaml @@ -0,0 +1,27 @@ +groups: + - name: evydence-runtime + rules: + - alert: EvydenceAPIDown + expr: up{job="evydence-api"} == 0 + for: 2m + labels: + severity: page + annotations: + summary: Evydence API scrape target is down + description: The API target has not been reachable by Prometheus for at least two minutes. + - alert: EvydenceWorkerBacklogGrowing + expr: evydence_resource_count{resource="audit_chain_entries"} > 0 and absent(evydence_worker_last_success_timestamp_seconds) + for: 15m + labels: + severity: ticket + annotations: + summary: Evydence worker success signal is missing + description: Configure worker success instrumentation or check the worker when API ledger activity is present without a worker success signal. + - alert: EvydencePortalAccessFailures + expr: increase(evydence_customer_portal_failed_access_count[15m]) > 10 + for: 5m + labels: + severity: ticket + annotations: + summary: Customer portal access failures increased + description: Failed customer portal access attempts increased for a tenant-scoped scrape target. Review access records and gateway rate limits. diff --git a/docs/README.md b/docs/README.md index d60a875..fae2c8d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -21,6 +21,7 @@ This documentation is organized by reader task. Implementation claims should be - [Configuration](reference/configuration.md): canonical environment variables and the roles of `.env.example`, `.api.env.example`, and `.test.env.example`. - [OpenAPI contract](reference/openapi.md): generation, drift checks, and review tips for `openapi.yaml`. +- [Observability](reference/observability.md): readiness, admin metrics, Prometheus rules, and dashboard starter assets. - [Worker outbox contract](reference/worker-outbox.md): durable job kinds, idempotency, and safe logging rules. - [Release validation](reference/release-validation.md): canonical `make release-check` behavior and summary evidence. - [SDK workflow](sdk/README.md): current Go, TypeScript, and Python wrapper usage and limitations. diff --git a/docs/operations.md b/docs/operations.md index 65c4d52..93f31ae 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -8,6 +8,7 @@ This operator index points to the canonical references for running Evydence. Kee |------|---------------|------------------| | Choose local or durable runtime mode | [Install and operate](how-to/install-and-operate.md) | API and worker run with either in-process state or PostgreSQL-backed state. | | Configure environment variables | [Configuration](reference/configuration.md) | Runtime variables are set from local untracked files or deployment secrets. | +| Wire observability | [Observability](reference/observability.md) | Readiness, admin metrics, Prometheus rules, and dashboard starter assets are reviewed for the deployment. | | Run release validation | [Release validation](reference/release-validation.md) | `tmp/release-check-summary.txt` records pass and explicit skip lines. | | Operate outbox workers | [Worker outbox contract](reference/worker-outbox.md) | Workers claim persisted jobs and fail safely on missing state, hash mismatch, or unsupported jobs. | | Integrate CI evidence | [Integrate CI collectors](how-to/integrate-ci.md) | CI jobs upload build, attestation, source snapshot, or collector evidence with scoped secrets. | @@ -18,7 +19,7 @@ This operator index points to the canonical references for running Evydence. Kee ## Integrity Operations - Use `GET /v1/ready` for low-detail readiness checks. -- Use `GET /v1/metrics` only with an admin API key; it returns safe tenant resource counts, not raw evidence payloads or secrets. +- Use `GET /v1/metrics` only with an admin API key; it returns safe tenant resource counts as JSON or Prometheus text when `Accept: text/plain` is sent, not raw evidence payloads or secrets. - Use `GET /v1/admin/instance` only with an actor explicitly granted `instance:admin`. Tenant admin and ordinary wildcard tenant keys do not satisfy this instance-wide scope by themselves. - Use `POST /v1/backup-manifests` after database and object-store backups complete. The manifest intentionally excludes raw payload bytes and private signing-key material. - Use `POST /v1/merkle-batches` and `POST /v1/transparency-checkpoints` to record signed local checkpoints and optional external anchoring metadata. diff --git a/docs/reference/observability.md b/docs/reference/observability.md new file mode 100644 index 0000000..5a7742a --- /dev/null +++ b/docs/reference/observability.md @@ -0,0 +1,35 @@ +# Observability + +Evydence exposes low-detail runtime checks for operators. These signals support operational review and incident response; they do not prove legal compliance, complete evidence coverage, or release security. + +## Endpoints + +`GET /v1/ready` returns unauthenticated readiness JSON with only component status names such as `ledger`, `store`, and `object_store`. + +`GET /v1/metrics` requires an admin API key. By default it returns JSON. When the request includes `Accept: text/plain`, it returns Prometheus exposition text for safe tenant-scoped counters and gauges: + +```sh +curl -sS \ + -H "Authorization: Bearer $EVYDENCE_API_KEY" \ + -H "Accept: text/plain" \ + "$EVYDENCE_API_URL/v1/metrics" +``` + +Expected result: metric names such as `evydence_resource_count`, `evydence_customer_portal_failed_access_count`, and `evydence_customer_portal_revoked_access_count`. The response omits API keys, portal tokens, raw evidence payloads, signing-key private material, customer names, and email addresses. + +## Deployment Artifacts + +The repository includes starter observability assets: + +```text +deploy/observability/prometheus-rules.yaml +deploy/observability/grafana-dashboard.json +``` + +The Prometheus rules assume a scrape job named `evydence-api` and an authenticated scrape configuration for `/v1/metrics`. The dashboard assumes a Prometheus datasource. Adjust labels, scrape authentication, and routing policies for the deployment environment. + +## Limitations + +- `/v1/metrics` is tenant-scoped to the authenticating admin actor; instance-wide metrics require separate operator aggregation. +- The starter alert rules are examples and need production routing, silence, and escalation policy review. +- OpenTelemetry tracing/exporter wiring is deployment-specific and not required for the local self-hosted runtime. diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 1cb32cf..68f05b7 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -353,6 +353,13 @@ func TestIntegrityRuntimeHTTPFlow(t *testing.T) { if !strings.Contains(metrics, `"resource_counts"`) { t.Fatalf("metrics response: %s", metrics) } + metricsText := getRawWithAccept(t, server, secret, "/v1/metrics", "text/plain", http.StatusOK) + if contentType := metricsText.Header().Get("Content-Type"); !strings.Contains(contentType, "text/plain") { + t.Fatalf("metrics content type = %q", contentType) + } + if body := metricsText.Body.String(); !strings.Contains(body, "evydence_resource_count{resource=\"evidence\"}") || strings.Contains(body, secret) { + t.Fatalf("unsafe or incomplete text metrics: %s", body) + } rec := httptest.NewRecorder() req := httptest.NewRequest(http.MethodGet, "/v1/ready", nil) server.Handler().ServeHTTP(rec, req) @@ -1118,6 +1125,19 @@ func getRaw(t *testing.T, server *Server, secret, path string, want int) *httpte return rec } +func getRawWithAccept(t *testing.T, server *Server, secret, path, accept string, want int) *httptest.ResponseRecorder { + t.Helper() + rec := httptest.NewRecorder() + req := httptest.NewRequest(http.MethodGet, path, nil) + req.Header.Set("Authorization", "Bearer "+secret) + req.Header.Set("Accept", accept) + server.Handler().ServeHTTP(rec, req) + if rec.Code != want { + t.Fatalf("GET %s status=%d want=%d body=%s", path, rec.Code, want, rec.Body.String()) + } + return rec +} + func asStringAnyMap(t *testing.T, value any) map[string]any { t.Helper() out, ok := value.(map[string]any) diff --git a/internal/adapters/httpapi/system_handlers.go b/internal/adapters/httpapi/system_handlers.go index 03e4dfe..3df85db 100644 --- a/internal/adapters/httpapi/system_handlers.go +++ b/internal/adapters/httpapi/system_handlers.go @@ -1,7 +1,10 @@ package httpapi import ( + "fmt" "net/http" + "sort" + "strings" ) func (s *Server) health(w http.ResponseWriter, _ *http.Request) { @@ -27,6 +30,13 @@ func (s *Server) metrics(w http.ResponseWriter, r *http.Request) { writeProblem(w, r, err) return } + if strings.Contains(r.Header.Get("Accept"), "text/plain") { + body := prometheusMetrics(metrics) + w.Header().Set("Content-Type", "text/plain; version=0.0.4; charset=utf-8") + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte(body)) + return + } writeData(w, http.StatusOK, metrics) } @@ -44,3 +54,39 @@ func (s *Server) openapi(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) _, _ = w.Write(doc) } + +func prometheusMetrics(metrics map[string]any) string { + var b strings.Builder + b.WriteString("# HELP evydence_resource_count Tenant-scoped Evydence resource count.\n") + b.WriteString("# TYPE evydence_resource_count gauge\n") + if counts, ok := metrics["resource_counts"].(map[string]int); ok { + keys := make([]string, 0, len(counts)) + for key := range counts { + keys = append(keys, key) + } + sort.Strings(keys) + for _, key := range keys { + fmt.Fprintf(&b, "evydence_resource_count{resource=%q} %d\n", key, counts[key]) + } + } + b.WriteString("# HELP evydence_customer_portal_failed_access_count Tenant-scoped failed customer portal access attempts recorded against known access records.\n") + b.WriteString("# TYPE evydence_customer_portal_failed_access_count counter\n") + fmt.Fprintf(&b, "evydence_customer_portal_failed_access_count %d\n", metricInt(metrics["customer_portal_failed_access_count"])) + b.WriteString("# HELP evydence_customer_portal_revoked_access_count Tenant-scoped revoked customer portal access records.\n") + b.WriteString("# TYPE evydence_customer_portal_revoked_access_count gauge\n") + fmt.Fprintf(&b, "evydence_customer_portal_revoked_access_count %d\n", metricInt(metrics["customer_portal_revoked_access_count"])) + return b.String() +} + +func metricInt(value any) int { + switch got := value.(type) { + case int: + return got + case int64: + return int(got) + case float64: + return int(got) + default: + return 0 + } +} From 8963a30cf18caca5b002d2ff678b29e05ae88128 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 17:11:57 +0300 Subject: [PATCH 029/287] feat: add marketplace collector health reports --- .implementation_increments.md | 4 +- docs/api.md | 1 + docs/collectors/supply-chain.md | 8 +++ internal/adapters/httpapi/future_handlers.go | 13 ++++ .../adapters/httpapi/route_registration.go | 1 + internal/adapters/httpapi/router_test.go | 4 ++ internal/app/future_extensions.go | 67 +++++++++++++++++++ internal/app/future_extensions_test.go | 7 ++ internal/domain/domain.go | 14 ++++ openapi.yaml | 2 +- 10 files changed, 118 insertions(+), 3 deletions(-) diff --git a/.implementation_increments.md b/.implementation_increments.md index 7258123..8772368 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -111,7 +111,7 @@ Status legend: Extended CRA readiness from JSON to reproducible HTML/package output with deterministic templates and no legal compliance claims. 31. `[x]` Control Framework Template Packs - Added versioned built-in starter packs for CRA readiness and NIST SSDF-lite controls, with tenant install APIs. Broader SOC 2/ISO/internal packs remain future pack expansion. + Added versioned built-in starter packs for CRA readiness, NIST SSDF-lite, SOC 2-style technical evidence, and ISO 27001-style technical evidence, with tenant install APIs. 32. `[x]` Custom Report Templates Added tenant-defined report templates with strict allowed fields, deterministic rendering, redaction controls, and template versioning. @@ -255,7 +255,7 @@ Status legend: - `[x]` External signing-provider operation receipts now record payload hashes, checks, and signature references, while production KMS/HSM adapter execution remains deployment hardening work. - `[x]` Stored OIDC/SAML identity-link verification now records provider-verification receipts, while live provider token/assertion verification remains out of scope. - `[x]` Public transparency log records now link local Merkle checkpoints to external entry metadata, while live inclusion proof verification remains operator-controlled. -- `[x]` Marketplace collector records now capture package metadata and evidence references, while marketplace distribution, signing policy, and health automation remain future operational hardening. +- `[x]` Marketplace collector records now capture package metadata and evidence references, and expose package health reports for signature, SBOM, and vulnerability scan evidence gaps. Marketplace distribution remains external operational hardening. - `[x]` Docker/Helm runtime packaging now includes the worker binary and migrations and uses commands that match the image PATH. - `[x]` GitHub Actions example now passes the digest computed in the workflow instead of an unrelated repository variable. - `[x]` Production hardening docs now use the built local CLI path for release manifest verification. diff --git a/docs/api.md b/docs/api.md index dadb4d7..fbb1033 100644 --- a/docs/api.md +++ b/docs/api.md @@ -303,6 +303,7 @@ Current SSO endpoints model admin-managed provider, identity-link, and session r | `GET` | `/v1/commercial-collectors` | List commercial collector definitions. | | `POST` | `/v1/marketplace-collectors` | Register marketplace collector package metadata. | | `GET` | `/v1/marketplace-collectors` | List marketplace collector package records. | +| `GET` | `/v1/marketplace-collectors/{id}/health` | Review marketplace collector package evidence gaps. | | `POST` | `/v1/builds` | Record immutable build run. | | `GET` | `/v1/builds/{id}` | Read build run. | | `POST` | `/v1/builds/{id}/attestations` | Upload DSSE in-toto attestation JSON. | diff --git a/docs/collectors/supply-chain.md b/docs/collectors/supply-chain.md index 43f4690..9a4b9fc 100644 --- a/docs/collectors/supply-chain.md +++ b/docs/collectors/supply-chain.md @@ -39,6 +39,14 @@ The health report can show whether: Health reports help operators see collector evidence gaps. They do not prove that a collector is free of vulnerabilities, provider-verified, or safe to run. +Marketplace collector package records have a separate health report: + +```http +GET /v1/marketplace-collectors/{id}/health +``` + +That report checks whether package signature, SBOM, and vulnerability scan evidence references are present and still point to tenant-owned evidence. It is a package evidence-gap report, not a marketplace trust or endorsement decision. + ## Related Docs - [Integrate CI collectors](../how-to/integrate-ci.md) diff --git a/internal/adapters/httpapi/future_handlers.go b/internal/adapters/httpapi/future_handlers.go index 9e19217..ae49423 100644 --- a/internal/adapters/httpapi/future_handlers.go +++ b/internal/adapters/httpapi/future_handlers.go @@ -130,6 +130,19 @@ func (s *Server) listMarketplaceCollectors(w http.ResponseWriter, r *http.Reques writeData(w, http.StatusOK, collectors) } +func (s *Server) marketplaceCollectorHealth(w http.ResponseWriter, r *http.Request) { + actor, ok := s.authenticate(w, r) + if !ok { + return + } + report, err := s.ledger.MarketplaceCollectorHealth(r.Context(), actor, r.PathValue("id")) + if err != nil { + writeProblem(w, r, err) + return + } + writeData(w, http.StatusOK, report) +} + func (s *Server) createPDFReportPackage(w http.ResponseWriter, r *http.Request) { var req struct { ReportType string `json:"report_type"` diff --git a/internal/adapters/httpapi/route_registration.go b/internal/adapters/httpapi/route_registration.go index f5c2702..0bbb3fb 100644 --- a/internal/adapters/httpapi/route_registration.go +++ b/internal/adapters/httpapi/route_registration.go @@ -81,6 +81,7 @@ func (s *Server) collectorRoutes() []routeDef { {http.MethodGet, "/v1/commercial-collectors", op("listCommercialCollectors", http.MethodGet, "/v1/commercial-collectors", "List commercial collector definitions", []string{app.ScopeCollectorRead}), http.HandlerFunc(s.listCommercialCollectors)}, {http.MethodPost, "/v1/marketplace-collectors", op("createMarketplaceCollector", http.MethodPost, "/v1/marketplace-collectors", "Create marketplace collector record", []string{app.ScopeCollectorAdmin}), http.HandlerFunc(s.createMarketplaceCollector)}, {http.MethodGet, "/v1/marketplace-collectors", op("listMarketplaceCollectors", http.MethodGet, "/v1/marketplace-collectors", "List marketplace collector records", []string{app.ScopeCollectorRead}), http.HandlerFunc(s.listMarketplaceCollectors)}, + {http.MethodGet, "/v1/marketplace-collectors/{id}/health", op("marketplaceCollectorHealth", http.MethodGet, "/v1/marketplace-collectors/{id}/health", "Marketplace collector health report", []string{app.ScopeCollectorRead}), http.HandlerFunc(s.marketplaceCollectorHealth)}, } } diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 68f05b7..fe1507b 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -886,6 +886,10 @@ func TestFutureExtensionAndReadAdminHTTPGaps(t *testing.T) { if !strings.Contains(getJSON(t, server, secret, "/v1/marketplace-collectors", http.StatusOK), dataField(t, marketplace, "id")) { t.Fatalf("marketplace list missing collector") } + marketplaceHealth := getJSON(t, server, secret, "/v1/marketplace-collectors/"+dataField(t, marketplace, "id")+"/health", http.StatusOK) + if !strings.Contains(marketplaceHealth, `"supply_chain_status":"incomplete"`) || strings.Contains(marketplaceHealth, secret) { + t.Fatalf("marketplace health response: %s", marketplaceHealth) + } orgBody := postJSON(t, server, secret, "/v1/organizations", "future-org", map[string]any{"name": "Example", "slug": "future-example"}, http.StatusCreated) userBody := postJSON(t, server, secret, "/v1/users", "future-user", map[string]any{"organization_id": dataField(t, orgBody, "id"), "email": "future@example.test", "display_name": "Future"}, http.StatusCreated) diff --git a/internal/app/future_extensions.go b/internal/app/future_extensions.go index 51dcb7f..9a8e41a 100644 --- a/internal/app/future_extensions.go +++ b/internal/app/future_extensions.go @@ -456,6 +456,73 @@ func (l *Ledger) ListMarketplaceCollectors(ctx context.Context, actor domain.Act return out, nil } +func (l *Ledger) MarketplaceCollectorHealth(ctx context.Context, actor domain.Actor, id string) (domain.MarketplaceCollectorHealthReport, error) { + if err := ctx.Err(); err != nil { + return domain.MarketplaceCollectorHealthReport{}, err + } + if err := require(actor, ScopeCollectorRead); err != nil { + return domain.MarketplaceCollectorHealthReport{}, err + } + l.mu.Lock() + defer l.mu.Unlock() + collector, ok := l.marketplaceCollectors[strings.TrimSpace(id)] + if !ok || collector.TenantID != actor.TenantID { + return domain.MarketplaceCollectorHealthReport{}, ErrNotFound + } + checks := []domain.VerifyCheck{{Name: "manifest_digest", Result: "passed", Detail: "collector package manifest digest is recorded"}} + result := "verified" + if collector.SignatureID == "" { + result = "incomplete" + checks = append(checks, domain.VerifyCheck{Name: "signature_evidence", Result: "failed", Detail: "collector package signature evidence is missing"}) + } else if sig, ok := l.signatures[collector.SignatureID]; !ok || sig.TenantID != actor.TenantID { + result = "failed" + checks = append(checks, domain.VerifyCheck{Name: "signature_evidence", Result: "failed", Detail: "collector package signature evidence reference is invalid"}) + } else { + checks = append(checks, domain.VerifyCheck{Name: "signature_evidence", Result: "passed"}) + } + if collector.SBOMID == "" { + result = worseHealth(result, "incomplete") + checks = append(checks, domain.VerifyCheck{Name: "sbom_evidence", Result: "failed", Detail: "collector package SBOM evidence is missing"}) + } else if sbom, ok := l.sboms[collector.SBOMID]; !ok || sbom.TenantID != actor.TenantID { + result = "failed" + checks = append(checks, domain.VerifyCheck{Name: "sbom_evidence", Result: "failed", Detail: "collector package SBOM evidence reference is invalid"}) + } else { + checks = append(checks, domain.VerifyCheck{Name: "sbom_evidence", Result: "passed"}) + } + if collector.ScanID == "" { + result = worseHealth(result, "incomplete") + checks = append(checks, domain.VerifyCheck{Name: "vulnerability_scan_evidence", Result: "failed", Detail: "collector package vulnerability scan evidence is missing"}) + } else if scan, ok := l.scans[collector.ScanID]; !ok || scan.TenantID != actor.TenantID { + result = "failed" + checks = append(checks, domain.VerifyCheck{Name: "vulnerability_scan_evidence", Result: "failed", Detail: "collector package vulnerability scan evidence reference is invalid"}) + } else { + checks = append(checks, domain.VerifyCheck{Name: "vulnerability_scan_evidence", Result: "passed"}) + } + return domain.MarketplaceCollectorHealthReport{ + ReportType: "marketplace_collector_health", + CollectorID: collector.ID, + Name: collector.Name, + Provider: collector.Provider, + Version: collector.Version, + SupplyChainStatus: result, + Checks: checks, + Collector: collector, + Assumptions: []string{"Health is based on evidence recorded in Evydence for this tenant."}, + Limitations: []string{"This report does not prove marketplace trust, package safety, or provider endorsement."}, + GeneratedAt: l.now(), + }, nil +} + +func worseHealth(current, candidate string) string { + if current == "failed" || candidate == "failed" { + return "failed" + } + if current == "incomplete" || candidate == "incomplete" { + return "incomplete" + } + return "verified" +} + func (l *Ledger) CreatePDFReportPackage(ctx context.Context, actor domain.Actor, in CreatePDFReportPackageInput) (domain.PDFReportPackage, error) { if err := ctx.Err(); err != nil { return domain.PDFReportPackage{}, err diff --git a/internal/app/future_extensions_test.go b/internal/app/future_extensions_test.go index bbabe34..342826e 100644 --- a/internal/app/future_extensions_test.go +++ b/internal/app/future_extensions_test.go @@ -180,6 +180,13 @@ func TestFutureOperationalExtensionsAndPartialTrustClosures(t *testing.T) { if len(listed) != 1 || listed[0].ID != marketplace.ID { t.Fatalf("marketplace list = %#v", listed) } + health, err := ledger.MarketplaceCollectorHealth(ctx, actor, marketplace.ID) + if err != nil { + t.Fatalf("marketplace health: %v", err) + } + if health.SupplyChainStatus != "incomplete" || len(health.Checks) == 0 { + t.Fatalf("marketplace health = %#v", health) + } policy, err := ledger.CreateObjectRetentionPolicy(ctx, actor, CreateObjectRetentionPolicyInput{Name: "objects", ObjectPrefix: "tenants/" + actor.TenantID + "/", Mode: "compliance", RetentionDays: 90}) if err != nil { diff --git a/internal/domain/domain.go b/internal/domain/domain.go index 9676748..834e15b 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -936,6 +936,20 @@ type MarketplaceCollector struct { CreatedAt time.Time `json:"created_at"` } +type MarketplaceCollectorHealthReport struct { + ReportType string `json:"report_type"` + CollectorID string `json:"collector_id"` + Name string `json:"name"` + Provider string `json:"provider"` + Version string `json:"version"` + SupplyChainStatus string `json:"supply_chain_status"` + Checks []VerifyCheck `json:"checks"` + Collector MarketplaceCollector `json:"collector"` + Assumptions []string `json:"assumptions"` + Limitations []string `json:"limitations"` + GeneratedAt time.Time `json:"generated_at"` +} + type PDFReportPackage struct { ID string `json:"id"` TenantID string `json:"tenant_id"` diff --git a/openapi.yaml b/openapi.yaml index 6cf1950..6c8235f 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{},"payload_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source":{"type":"string"},"subject_refs":{"items":{"type":"string"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"type":"object"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"api_key_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"},"user_count":{"type":"integer"}},"required":["tenant_count","resource_counts"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Instance admin snapshot envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"operationId":"registerArtifact","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"operationId":"generateBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"operationId":"verifyBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"operationId":"createBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"operationId":"getBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"operationId":"uploadGitHubSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"operationId":"uploadGitLabSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"operationId":"createGraphSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"operationId":"listProducts","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"operationId":"createProduct","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"operationId":"createProject","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"operationId":"verifyProviderIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"operationId":"ready","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"operationId":"createRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"operationId":"getRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"operationId":"approveRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"operationId":"freezeRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"operationId":"controlCoverageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"operationId":"craReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"operationId":"releaseReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"operationId":"uploadSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"operationId":"getSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"operationId":"createSSOProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"operationId":"uploadVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"operationId":"uploadCycloneDXVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"operationId":"getVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"operationId":"uploadVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"operationId":"getVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{},"payload_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source":{"type":"string"},"subject_refs":{"items":{"type":"string"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"type":"object"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"api_key_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"},"user_count":{"type":"integer"}},"required":["tenant_count","resource_counts"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Instance admin snapshot envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"operationId":"registerArtifact","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"operationId":"generateBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"operationId":"verifyBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"operationId":"createBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"operationId":"getBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"operationId":"uploadGitHubSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"operationId":"uploadGitLabSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"operationId":"createGraphSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"operationId":"listProducts","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"operationId":"createProduct","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"operationId":"createProject","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"operationId":"verifyProviderIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"operationId":"ready","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"operationId":"createRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"operationId":"getRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"operationId":"approveRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"operationId":"freezeRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"operationId":"controlCoverageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"operationId":"craReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"operationId":"releaseReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"operationId":"uploadSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"operationId":"getSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"operationId":"createSSOProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"operationId":"uploadVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"operationId":"uploadCycloneDXVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"operationId":"getVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"operationId":"uploadVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"operationId":"getVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From fed82c2c9ed1bade895482146368e123d5b9c779 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 17:17:19 +0300 Subject: [PATCH 030/287] feat: verify oidc tokens with static jwks --- .implementation_increments.md | 4 +- README.md | 2 +- docs/api.md | 4 +- docs/architecture.md | 2 +- internal/adapters/httpapi/future_handlers.go | 3 +- .../adapters/httpapi/identity_handlers.go | 3 +- internal/adapters/httpapi/openapi.go | 15 ++ .../adapters/httpapi/openapi_operations.go | 8 + internal/adapters/httpapi/router_test.go | 29 +++- internal/app/enterprise.go | 48 +++++- internal/app/enterprise_test.go | 79 ++++++++++ internal/app/future_extensions.go | 143 +++++++++++++++++- internal/domain/domain.go | 1 + .../20260528001100_static_oidc_jwks.down.sql | 2 + .../20260528001100_static_oidc_jwks.up.sql | 2 + openapi.yaml | 2 +- 16 files changed, 335 insertions(+), 12 deletions(-) create mode 100644 migrations/20260528001100_static_oidc_jwks.down.sql create mode 100644 migrations/20260528001100_static_oidc_jwks.up.sql diff --git a/.implementation_increments.md b/.implementation_increments.md index 8772368..25db4ae 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -203,7 +203,7 @@ Status legend: Added role bindings for users and collectors, role-to-scope enforcement for human sessions, admin/customer/collector roles, tenant isolation checks, API routes, and tests. 59. `[x]` Enterprise SSO/SAML/OIDC - Added OIDC/SAML provider records, verified identity links, one-time hashed SSO session tokens, session revocation, role mapping metadata, audit entries, API routes, and tests. Live provider token verification remains future work. + Added OIDC/SAML provider records, verified identity links, one-time hashed SSO session tokens, session revocation, role mapping metadata, static JWKS-backed local OIDC ID-token verification, audit entries, API routes, and tests. Live provider discovery, API calls, and SAML assertion verification remain external/provider work. 60. `[x]` Multi-Tenant Admin Console API Added low-detail instance admin snapshot API with tenant/resource counts and no raw evidence, token, or secret exposure. @@ -253,7 +253,7 @@ Status legend: - `[x]` Object-retention verification receipts now record a reproducible verification hash, while WORM/object-lock enforcement remains a deployment and object-store control. - `[x]` External signing-provider operation receipts now record payload hashes, checks, and signature references, while production KMS/HSM adapter execution remains deployment hardening work. -- `[x]` Stored OIDC/SAML identity-link verification now records provider-verification receipts, while live provider token/assertion verification remains out of scope. +- `[x]` Stored OIDC/SAML identity-link verification records provider-verification receipts, and OIDC ID tokens can be verified locally against configured static JWKS material. Live provider discovery/API calls and SAML assertion verification remain external/provider work. - `[x]` Public transparency log records now link local Merkle checkpoints to external entry metadata, while live inclusion proof verification remains operator-controlled. - `[x]` Marketplace collector records now capture package metadata and evidence references, and expose package health reports for signature, SBOM, and vulnerability scan evidence gaps. Marketplace distribution remains external operational hardening. - `[x]` Docker/Helm runtime packaging now includes the worker binary and migrations and uses commands that match the image PATH. diff --git a/README.md b/README.md index 523749a..eec4d3b 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ This repository contains a Go release-ledger MVP scaffold under module `github.c - GitHub Actions and GitLab CI workflow examples. - Documentation portal under `docs/`. -Implemented-but-partial areas are documented explicitly: signing-provider operation receipts do not replace production KMS/HSM adapters, stored provider identity checks do not verify live OIDC/SAML tokens, and public transparency records do not prove external log inclusion without the configured operator workflow. +Implemented-but-partial areas are documented explicitly: signing-provider operation receipts do not replace production KMS/HSM adapters, local static-JWKS OIDC token verification does not replace live provider discovery/API validation or SAML assertion verification, and public transparency records do not prove external log inclusion without the configured operator workflow. ## Local API diff --git a/docs/api.md b/docs/api.md index fbb1033..458fd9b 100644 --- a/docs/api.md +++ b/docs/api.md @@ -247,7 +247,7 @@ Important scope boundaries: | `POST` | `/v1/api-keys` | Create one-time API key secret. | | `GET` | `/v1/api-keys` | List keys without secret hashes. | -Current SSO endpoints model admin-managed provider, identity-link, and session records. Live OIDC discovery, JWKS validation, SAML assertion verification, browser redirects, provider login callbacks, and group synchronization are not implemented in this slice. +Current SSO endpoints model admin-managed provider, identity-link, and session records. OIDC provider records can include static JWKS public-key material, and `POST /v1/provider-verifications` can verify a supplied ID token locally for issuer, audience, subject, expiry, and Ed25519 signature. Live OIDC discovery, live provider API calls, SAML assertion verification, browser redirects, provider login callbacks, and group synchronization are not implemented in this slice. ### Products, Releases, Evidence, And Risk @@ -384,7 +384,7 @@ Source snapshots capture submitted provider metadata. They do not call provider | `POST` | `/v1/signing-keys/{id}/revoke` | Revoke key for new signatures. | | `POST` | `/v1/signing-providers` | Record external signing-provider metadata. | | `POST` | `/v1/signing-operations` | Record external signing-provider operation receipt and signature ref. | -| `POST` | `/v1/provider-verifications` | Verify stored provider identity metadata; no live provider assertion is implied. | +| `POST` | `/v1/provider-verifications` | Verify stored provider identity metadata and optional local OIDC ID-token signature/claims. | | `POST` | `/v1/saas/profiles` | Create explicit-instance-admin SaaS edition profile record. | | `POST` | `/v1/artifact-signatures` | Create artifact signature metadata. | | `GET` | `/v1/artifact-signatures/{id}` | Read artifact signature. | diff --git a/docs/architecture.md b/docs/architecture.md index bdbdbc0..3b0b3a4 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -46,7 +46,7 @@ Evidence summaries, questionnaire drafts, graph snapshots, PDF packages, and ano ## Provider And Deployment Boundaries -GitHub OIDC subject metadata can be captured, and stored OIDC/SAML identity links can be verified against tenant metadata. Live provider token/API verification remains a trust boundary outside those records. Collector supply-chain records track pinned collector versions with signature, SBOM, and scan evidence where available; commercial and marketplace collector definitions add extension metadata without granting provider trust. +GitHub OIDC subject metadata can be captured, and stored OIDC/SAML identity links can be verified against tenant metadata. OIDC provider records can include static JWKS public-key material for local ID-token signature and claim verification without live provider calls. Live provider API verification, discovery, and group synchronization remain trust boundaries outside those records. Collector supply-chain records track pinned collector versions with signature, SBOM, and scan evidence where available; commercial and marketplace collector definitions add extension metadata without granting provider trust. Air-gapped import-bundle workflows preserve the same tenant-scoped import path after controlled transfer. Object-retention policy APIs record and verify retention intent for tenant-prefixed object paths, but WORM/object-lock enforcement remains the responsibility of the configured object store and deployment policy. diff --git a/internal/adapters/httpapi/future_handlers.go b/internal/adapters/httpapi/future_handlers.go index ae49423..3535915 100644 --- a/internal/adapters/httpapi/future_handlers.go +++ b/internal/adapters/httpapi/future_handlers.go @@ -195,12 +195,13 @@ func (s *Server) verifyProviderIdentity(w http.ResponseWriter, r *http.Request) ProviderType string `json:"provider_type"` ProviderID string `json:"provider_id"` Subject string `json:"subject"` + IDToken string `json:"id_token"` } s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - record, err := s.ledger.VerifyProviderIdentity(r.Context(), actor, app.VerifyProviderIdentityInput{ProviderType: req.ProviderType, ProviderID: req.ProviderID, Subject: req.Subject}) + record, err := s.ledger.VerifyProviderIdentity(r.Context(), actor, app.VerifyProviderIdentityInput{ProviderType: req.ProviderType, ProviderID: req.ProviderID, Subject: req.Subject, IDToken: req.IDToken}) return http.StatusCreated, record, err }) } diff --git a/internal/adapters/httpapi/identity_handlers.go b/internal/adapters/httpapi/identity_handlers.go index a87943d..c87f812 100644 --- a/internal/adapters/httpapi/identity_handlers.go +++ b/internal/adapters/httpapi/identity_handlers.go @@ -95,12 +95,13 @@ func (s *Server) createSSOProvider(w http.ResponseWriter, r *http.Request) { ClientID string `json:"client_id"` GroupsClaim string `json:"groups_claim"` RoleMapping map[string]string `json:"role_mapping"` + JWKS map[string]any `json:"jwks"` } s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - provider, err := s.ledger.CreateSSOProvider(r.Context(), actor, app.CreateSSOProviderInput{Name: req.Name, Type: req.Type, Issuer: req.Issuer, ClientID: req.ClientID, GroupsClaim: req.GroupsClaim, RoleMapping: req.RoleMapping}) + provider, err := s.ledger.CreateSSOProvider(r.Context(), actor, app.CreateSSOProviderInput{Name: req.Name, Type: req.Type, Issuer: req.Issuer, ClientID: req.ClientID, GroupsClaim: req.GroupsClaim, RoleMapping: req.RoleMapping, JWKS: req.JWKS}) return http.StatusCreated, provider, err }) } diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index d8a97b6..a4be2e3 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -46,6 +46,21 @@ func registerCriticalSchemas(registry *specs.Registry) { "provider_id": map[string]any{"type": "string"}, "expires_at": map[string]any{"type": "string", "format": "date-time"}, }, "user_id", "provider_id", "expires_at")) + registry.RegisterSchema("CreateSSOProviderRequest", objectSchema(map[string]any{ + "name": map[string]any{"type": "string"}, + "type": map[string]any{"type": "string", "enum": []string{"oidc", "saml"}}, + "issuer": map[string]any{"type": "string"}, + "client_id": map[string]any{"type": "string"}, + "groups_claim": map[string]any{"type": "string"}, + "role_mapping": map[string]any{"type": "object", "additionalProperties": map[string]any{"type": "string"}}, + "jwks": map[string]any{"type": "object", "description": "Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied."}, + }, "name", "type", "issuer", "client_id")) + registry.RegisterSchema("VerifyProviderIdentityRequest", objectSchema(map[string]any{ + "provider_type": map[string]any{"type": "string", "enum": []string{"oidc", "saml"}}, + "provider_id": map[string]any{"type": "string"}, + "subject": map[string]any{"type": "string"}, + "id_token": map[string]any{"type": "string", "description": "Optional OIDC ID token verified locally against the provider's configured static JWKS."}, + }, "provider_type", "provider_id", "subject")) registry.RegisterSchema("SSOSessionCreateResponse", objectSchema(map[string]any{ "session": map[string]any{"type": "object"}, "secret": map[string]any{"type": "string", "description": "One-time SSO session bearer secret; not returned by list/read operations."}, diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 1c9fae3..a70bbf4 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -16,6 +16,14 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Description = "Creates an admin-managed human SSO session record and returns a one-time bearer secret." operation.RequestBody = jsonRequest("SSO session creation request.", "#/components/schemas/CreateSSOSessionRequest") operation.Responses[http.StatusCreated] = jsonResponse("Created SSO session and one-time secret envelope.", "#/components/schemas/SSOSessionCreateEnvelope") + case "createSSOProvider": + operation.Description = "Records tenant SSO provider metadata. Optional static JWKS public keys can be supplied for local OIDC ID-token verification without live provider calls." + operation.RequestBody = jsonRequest("SSO provider creation request.", "#/components/schemas/CreateSSOProviderRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created SSO provider envelope.", "#/components/schemas/DataEnvelope") + case "verifyProviderIdentity": + operation.Description = "Verifies stored provider identity metadata and, when id_token is supplied, locally verifies OIDC issuer, audience, subject, expiry, and Ed25519 signature against configured JWKS." + operation.RequestBody = jsonRequest("Provider identity verification request.", "#/components/schemas/VerifyProviderIdentityRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Provider verification envelope.", "#/components/schemas/DataEnvelope") case "createEvidence": operation.Description = "Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation." operation.RequestBody = jsonRequest("Evidence creation request.", "#/components/schemas/CreateEvidenceRequest") diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index fe1507b..fec588b 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -84,7 +84,7 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { if _, ok := problemProps["request_id"]; !ok { t.Fatalf("Problem schema missing request_id: %#v", problemProps) } - for _, schemaName := range []string{"CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "DataEnvelope"} { + for _, schemaName := range []string{"CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "VerifyProviderIdentityRequest", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "DataEnvelope"} { if _, ok := schemas[schemaName]; !ok { t.Fatalf("schema %s missing from OpenAPI components", schemaName) } @@ -900,6 +900,19 @@ func TestFutureExtensionAndReadAdminHTTPGaps(t *testing.T) { if !strings.Contains(providerVerification, `"result":"passed"`) { t.Fatalf("provider verification failed: %s", providerVerification) } + pub, priv, err := ed25519.GenerateKey(rand.Reader) + if err != nil { + t.Fatalf("oidc keygen: %v", err) + } + jwks := map[string]any{"keys": []any{map[string]any{"kty": "OKP", "crv": "Ed25519", "kid": "kid-1", "alg": "EdDSA", "x": base64.RawURLEncoding.EncodeToString(pub)}}} + signedProvider := postJSON(t, server, secret, "/v1/sso/providers", "future-sso-jwks", map[string]any{"name": "Signed OIDC", "type": "oidc", "issuer": "https://signed-idp.example.test", "client_id": "signed-client", "jwks": jwks}, http.StatusCreated) + signedProviderID := dataField(t, signedProvider, "id") + postJSON(t, server, secret, "/v1/sso/identity-links", "future-signed-link", map[string]any{"user_id": dataField(t, userBody, "id"), "provider_id": signedProviderID, "subject": "signed-sub", "email": "future@example.test", "verified": true}, http.StatusCreated) + idToken := signedRouterIDToken(t, priv, "kid-1", map[string]any{"iss": "https://signed-idp.example.test", "aud": "signed-client", "sub": "signed-sub", "email": "future@example.test", "email_verified": true, "exp": time.Now().UTC().Add(time.Hour).Unix()}) + signedVerification := postJSON(t, server, secret, "/v1/provider-verifications", "future-provider-token-verification", map[string]any{"provider_type": "oidc", "provider_id": signedProviderID, "subject": "signed-sub", "id_token": idToken}, http.StatusCreated) + if !strings.Contains(signedVerification, `"id_token_signature"`) || strings.Contains(signedVerification, idToken) { + t.Fatalf("signed provider verification response: %s", signedVerification) + } } func TestSourceSnapshotAndSystemHTTPGaps(t *testing.T) { @@ -1298,3 +1311,17 @@ func dsseHTTP(t *testing.T, digest string) []byte { } return body } + +func signedRouterIDToken(t *testing.T, private ed25519.PrivateKey, kid string, claims map[string]any) string { + t.Helper() + headerBody, err := json.Marshal(map[string]any{"alg": "EdDSA", "kid": kid, "typ": "JWT"}) + if err != nil { + t.Fatalf("marshal jwt header: %v", err) + } + claimsBody, err := json.Marshal(claims) + if err != nil { + t.Fatalf("marshal jwt claims: %v", err) + } + unsigned := base64.RawURLEncoding.EncodeToString(headerBody) + "." + base64.RawURLEncoding.EncodeToString(claimsBody) + return unsigned + "." + base64.RawURLEncoding.EncodeToString(ed25519.Sign(private, []byte(unsigned))) +} diff --git a/internal/app/enterprise.go b/internal/app/enterprise.go index 03935c9..d14ed32 100644 --- a/internal/app/enterprise.go +++ b/internal/app/enterprise.go @@ -2,6 +2,7 @@ package app import ( "context" + "encoding/json" "strings" "time" @@ -34,6 +35,7 @@ type CreateSSOProviderInput struct { ClientID string GroupsClaim string RoleMapping map[string]string + JWKS map[string]any } type LinkSSOIdentityInput struct { @@ -240,7 +242,11 @@ func (l *Ledger) CreateSSOProvider(ctx context.Context, actor domain.Actor, in C } l.mu.Lock() defer l.mu.Unlock() - provider := domain.SSOProvider{ID: newID("sso"), TenantID: actor.TenantID, Name: in.Name, Type: in.Type, Issuer: in.Issuer, ClientID: in.ClientID, GroupsClaim: strings.TrimSpace(in.GroupsClaim), RoleMapping: cloneStringMap(in.RoleMapping), Status: "active", SchemaVersion: domain.SSOProviderSchemaVersion, CreatedAt: l.now()} + jwks, err := normalizeJWKS(in.JWKS) + if err != nil { + return domain.SSOProvider{}, ErrValidation + } + provider := domain.SSOProvider{ID: newID("sso"), TenantID: actor.TenantID, Name: in.Name, Type: in.Type, Issuer: in.Issuer, ClientID: in.ClientID, GroupsClaim: strings.TrimSpace(in.GroupsClaim), RoleMapping: cloneStringMap(in.RoleMapping), JWKS: jwks, Status: "active", SchemaVersion: domain.SSOProviderSchemaVersion, CreatedAt: l.now()} l.ssoProviders[provider.ID] = provider _, _ = l.appendChainLocked(actor.TenantID, "sso_provider.created", "sso_provider", provider.ID, actorType(actor), actorID(actor), "", "") if err := l.persistLocked(ctx); err != nil { @@ -1077,6 +1083,46 @@ func validSSOType(value string) bool { return value == "oidc" || value == "saml" } +func normalizeJWKS(jwks map[string]any) (map[string]any, error) { + if len(jwks) == 0 { + return nil, nil + } + body, err := json.Marshal(jwks) + if err != nil || len(body) > 64*1024 { + return nil, ErrValidation + } + var normalized map[string]any + if err := json.Unmarshal(body, &normalized); err != nil { + return nil, err + } + keys, ok := normalized["keys"].([]any) + if !ok || len(keys) == 0 || len(keys) > 10 { + return nil, ErrValidation + } + for _, raw := range keys { + key, ok := raw.(map[string]any) + if !ok { + return nil, ErrValidation + } + kty, _ := key["kty"].(string) + kid, _ := key["kid"].(string) + if strings.TrimSpace(kid) == "" { + return nil, ErrValidation + } + switch kty { + case "OKP": + crv, _ := key["crv"].(string) + x, _ := key["x"].(string) + if crv != "Ed25519" || strings.TrimSpace(x) == "" { + return nil, ErrValidation + } + default: + return nil, ErrValidation + } + } + return normalized, nil +} + func validRetentionScope(value string) bool { switch value { case "tenant", "product", "project", "release", "evidence": diff --git a/internal/app/enterprise_test.go b/internal/app/enterprise_test.go index 338c7cb..f118592 100644 --- a/internal/app/enterprise_test.go +++ b/internal/app/enterprise_test.go @@ -2,6 +2,10 @@ package app import ( "context" + "crypto/ed25519" + "crypto/rand" + "encoding/base64" + "encoding/json" "errors" "strings" "testing" @@ -78,6 +82,65 @@ func TestEnterpriseIdentityRBACSSOAndAdminSnapshot(t *testing.T) { } } +func TestOIDCProviderIdentityVerificationUsesStaticJWKS(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + _, _, secret, err := ledger.BootstrapTenant(ctx, "Tenant", "admin", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap: %v", err) + } + actor, err := ledger.Authenticate(ctx, secret) + if err != nil { + t.Fatalf("auth: %v", err) + } + pub, priv, err := ed25519.GenerateKey(rand.Reader) + if err != nil { + t.Fatalf("keygen: %v", err) + } + jwks := map[string]any{"keys": []any{map[string]any{"kty": "OKP", "crv": "Ed25519", "kid": "kid-1", "alg": "EdDSA", "x": base64.RawURLEncoding.EncodeToString(pub)}}} + provider, err := ledger.CreateSSOProvider(ctx, actor, CreateSSOProviderInput{Name: "OIDC", Type: "oidc", Issuer: "https://idp.example.test", ClientID: "client", JWKS: jwks}) + if err != nil { + t.Fatalf("sso provider: %v", err) + } + org, err := ledger.CreateOrganization(ctx, actor, CreateOrganizationInput{Name: "Example", Slug: "example-oidc"}) + if err != nil { + t.Fatalf("org: %v", err) + } + user, err := ledger.CreateUser(ctx, actor, CreateUserInput{OrganizationID: org.ID, Email: "oidc@example.test", DisplayName: "OIDC User"}) + if err != nil { + t.Fatalf("user: %v", err) + } + if _, err := ledger.LinkSSOIdentity(ctx, actor, LinkSSOIdentityInput{UserID: user.ID, ProviderID: provider.ID, Subject: "sub-1", Email: user.Email, Verified: true}); err != nil { + t.Fatalf("identity link: %v", err) + } + idToken := signedTestIDToken(t, priv, "kid-1", map[string]any{ + "iss": "https://idp.example.test", + "aud": "client", + "sub": "sub-1", + "email": user.Email, + "email_verified": true, + "exp": fixedNow().Add(time.Hour).Unix(), + "nbf": fixedNow().Add(-time.Minute).Unix(), + }) + verification, err := ledger.VerifyProviderIdentity(ctx, actor, VerifyProviderIdentityInput{ProviderType: "oidc", ProviderID: provider.ID, Subject: "sub-1", IDToken: idToken}) + if err != nil { + t.Fatalf("provider verification: %v", err) + } + if verification.Result != "passed" || len(verification.Checks) < 5 { + t.Fatalf("verification = %#v", verification) + } + badAudience := signedTestIDToken(t, priv, "kid-1", map[string]any{ + "iss": "https://idp.example.test", "aud": "other-client", "sub": "sub-1", "email": user.Email, "email_verified": true, "exp": fixedNow().Add(time.Hour).Unix(), + }) + failed, err := ledger.VerifyProviderIdentity(ctx, actor, VerifyProviderIdentityInput{ProviderType: "oidc", ProviderID: provider.ID, Subject: "sub-1", IDToken: badAudience}) + if !errors.Is(err, ErrVerificationFailed) || failed.Result != "failed" { + t.Fatalf("bad audience verification = %#v err=%v", failed, err) + } + if strings.Contains(failed.Checks[0].Detail, badAudience) { + t.Fatalf("verification leaked token in check detail: %#v", failed) + } +} + func TestInstanceAdminRequiresExplicitScope(t *testing.T) { ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) ctx := context.Background() @@ -736,3 +799,19 @@ func TestHumanSSOSessionResourceScopeCoversWorkflowFamilies(t *testing.T) { t.Fatalf("scoped deployments=%#v want only %s", deployments, depA.ID) } } + +func signedTestIDToken(t *testing.T, private ed25519.PrivateKey, kid string, claims map[string]any) string { + t.Helper() + header := map[string]any{"alg": "EdDSA", "kid": kid, "typ": "JWT"} + headerBody, err := json.Marshal(header) + if err != nil { + t.Fatalf("marshal header: %v", err) + } + claimsBody, err := json.Marshal(claims) + if err != nil { + t.Fatalf("marshal claims: %v", err) + } + unsigned := base64.RawURLEncoding.EncodeToString(headerBody) + "." + base64.RawURLEncoding.EncodeToString(claimsBody) + signature := ed25519.Sign(private, []byte(unsigned)) + return unsigned + "." + base64.RawURLEncoding.EncodeToString(signature) +} diff --git a/internal/app/future_extensions.go b/internal/app/future_extensions.go index 9a8e41a..f30f36c 100644 --- a/internal/app/future_extensions.go +++ b/internal/app/future_extensions.go @@ -2,7 +2,12 @@ package app import ( "context" + "crypto/ed25519" + "encoding/base64" + "encoding/json" + "errors" "strings" + "time" "github.com/aatuh/evydence/internal/domain" ) @@ -78,6 +83,7 @@ type VerifyProviderIdentityInput struct { ProviderType string ProviderID string Subject string + IDToken string } func (l *Ledger) CreateEvidenceSummary(ctx context.Context, actor domain.Actor, in CreateEvidenceSummaryInput) (domain.EvidenceSummary, error) { @@ -523,6 +529,129 @@ func worseHealth(current, candidate string) string { return "verified" } +type oidcJWTHeader struct { + Alg string `json:"alg"` + KID string `json:"kid"` + Typ string `json:"typ"` +} + +type oidcJWTClaims struct { + Issuer string `json:"iss"` + Audience any `json:"aud"` + Subject string `json:"sub"` + Email string `json:"email"` + EmailVerified bool `json:"email_verified"` + ExpiresAt int64 `json:"exp"` + NotBefore int64 `json:"nbf,omitempty"` + IssuedAt int64 `json:"iat,omitempty"` +} + +func verifyOIDCIDToken(provider domain.SSOProvider, expectedSubject, token string, now time.Time) ([]domain.VerifyCheck, error) { + checks := []domain.VerifyCheck{} + if len(token) > 16*1024 { + return []domain.VerifyCheck{{Name: "id_token_size", Result: "failed"}}, ErrVerificationFailed + } + parts := strings.Split(token, ".") + if len(parts) != 3 { + return []domain.VerifyCheck{{Name: "id_token_shape", Result: "failed"}}, ErrVerificationFailed + } + headerBody, err := base64.RawURLEncoding.DecodeString(parts[0]) + if err != nil { + return []domain.VerifyCheck{{Name: "id_token_header", Result: "failed"}}, ErrVerificationFailed + } + var header oidcJWTHeader + if err := json.Unmarshal(headerBody, &header); err != nil { + return []domain.VerifyCheck{{Name: "id_token_header", Result: "failed"}}, ErrVerificationFailed + } + if header.Alg != "EdDSA" || strings.TrimSpace(header.KID) == "" { + return []domain.VerifyCheck{{Name: "id_token_algorithm", Result: "failed"}}, ErrVerificationFailed + } + key, err := oidcJWKEd25519Key(provider.JWKS, header.KID) + if err != nil { + return []domain.VerifyCheck{{Name: "id_token_key", Result: "failed"}}, ErrVerificationFailed + } + signature, err := base64.RawURLEncoding.DecodeString(parts[2]) + if err != nil || len(signature) != ed25519.SignatureSize { + return []domain.VerifyCheck{{Name: "id_token_signature", Result: "failed"}}, ErrVerificationFailed + } + unsigned := parts[0] + "." + parts[1] + if !ed25519.Verify(key, []byte(unsigned), signature) { + return []domain.VerifyCheck{{Name: "id_token_signature", Result: "failed"}}, ErrVerificationFailed + } + checks = append(checks, domain.VerifyCheck{Name: "id_token_signature", Result: "passed"}) + claimsBody, err := base64.RawURLEncoding.DecodeString(parts[1]) + if err != nil { + return checksWithFailure(checks, "id_token_claims"), ErrVerificationFailed + } + var claims oidcJWTClaims + if err := json.Unmarshal(claimsBody, &claims); err != nil { + return checksWithFailure(checks, "id_token_claims"), ErrVerificationFailed + } + if claims.Issuer != provider.Issuer { + return checksWithFailure(checks, "issuer"), ErrVerificationFailed + } + checks = append(checks, domain.VerifyCheck{Name: "issuer", Result: "passed"}) + if !audienceContains(claims.Audience, provider.ClientID) { + return checksWithFailure(checks, "audience"), ErrVerificationFailed + } + checks = append(checks, domain.VerifyCheck{Name: "audience", Result: "passed"}) + if claims.Subject == "" || claims.Subject != expectedSubject { + return checksWithFailure(checks, "subject"), ErrVerificationFailed + } + checks = append(checks, domain.VerifyCheck{Name: "subject", Result: "passed"}) + if claims.ExpiresAt == 0 || !time.Unix(claims.ExpiresAt, 0).After(now) { + return checksWithFailure(checks, "expiry"), ErrVerificationFailed + } + if claims.NotBefore != 0 && time.Unix(claims.NotBefore, 0).After(now.Add(time.Minute)) { + return checksWithFailure(checks, "not_before"), ErrVerificationFailed + } + checks = append(checks, domain.VerifyCheck{Name: "token_time", Result: "passed"}) + if claims.Email != "" && !claims.EmailVerified { + return checksWithFailure(checks, "email_verified"), ErrVerificationFailed + } + if claims.Email != "" { + checks = append(checks, domain.VerifyCheck{Name: "email_verified", Result: "passed"}) + } + return checks, nil +} + +func oidcJWKEd25519Key(jwks map[string]any, kid string) (ed25519.PublicKey, error) { + keys, ok := jwks["keys"].([]any) + if !ok { + return nil, errors.New("jwks missing keys") + } + for _, raw := range keys { + key, ok := raw.(map[string]any) + if !ok || key["kid"] != kid || key["kty"] != "OKP" || key["crv"] != "Ed25519" { + continue + } + x, _ := key["x"].(string) + pub, err := base64.RawURLEncoding.DecodeString(x) + if err == nil && len(pub) == ed25519.PublicKeySize { + return ed25519.PublicKey(pub), nil + } + } + return nil, errors.New("matching jwk not found") +} + +func checksWithFailure(checks []domain.VerifyCheck, name string) []domain.VerifyCheck { + return append(checks, domain.VerifyCheck{Name: name, Result: "failed"}) +} + +func audienceContains(audience any, expected string) bool { + switch got := audience.(type) { + case string: + return got == expected + case []any: + for _, item := range got { + if value, ok := item.(string); ok && value == expected { + return true + } + } + } + return false +} + func (l *Ledger) CreatePDFReportPackage(ctx context.Context, actor domain.Actor, in CreatePDFReportPackageInput) (domain.PDFReportPackage, error) { if err := ctx.Err(); err != nil { return domain.PDFReportPackage{}, err @@ -658,6 +787,7 @@ func (l *Ledger) VerifyProviderIdentity(ctx context.Context, actor domain.Actor, return domain.ProviderVerification{}, err } providerType, providerID, subject := strings.TrimSpace(in.ProviderType), strings.TrimSpace(in.ProviderID), strings.TrimSpace(in.Subject) + idToken := strings.TrimSpace(in.IDToken) if providerType == "" || providerID == "" || subject == "" { return domain.ProviderVerification{}, ErrValidation } @@ -671,6 +801,13 @@ func (l *Ledger) VerifyProviderIdentity(ctx context.Context, actor domain.Actor, if !ok || provider.TenantID != actor.TenantID || provider.Type != providerType { return domain.ProviderVerification{}, ErrNotFound } + if idToken != "" { + tokenChecks, err := verifyOIDCIDToken(provider, subject, idToken, l.now()) + checks = append(checks, tokenChecks...) + if err != nil { + result = "failed" + } + } found := false for _, link := range l.identityLinks { if link.TenantID == actor.TenantID && link.ProviderID == provider.ID && link.Subject == subject && link.Verified { @@ -687,7 +824,11 @@ func (l *Ledger) VerifyProviderIdentity(ctx context.Context, actor domain.Actor, default: return domain.ProviderVerification{}, ErrValidation } - record := domain.ProviderVerification{ID: newID("pvr"), TenantID: actor.TenantID, ProviderType: providerType, ProviderID: providerID, Subject: subject, Result: result, Checks: checks, Limitations: []string{"Verification is limited to stored provider/link metadata; live provider token verification is outside this record."}, SchemaVersion: domain.ProviderVerificationVersion, CreatedAt: l.now()} + limitations := []string{"Verification uses stored provider metadata and configured local JWKS material; no live provider API or discovery call is made."} + if idToken == "" { + limitations = []string{"Verification is limited to stored provider/link metadata because no provider token was supplied."} + } + record := domain.ProviderVerification{ID: newID("pvr"), TenantID: actor.TenantID, ProviderType: providerType, ProviderID: providerID, Subject: subject, Result: result, Checks: checks, Limitations: limitations, SchemaVersion: domain.ProviderVerificationVersion, CreatedAt: l.now()} l.providerVerifications[record.ID] = record _, _ = l.appendChainLocked(actor.TenantID, "provider_identity.verified", "provider_identity", record.ID, actorType(actor), actorID(actor), "", "") if err := l.persistLocked(ctx); err != nil { diff --git a/internal/domain/domain.go b/internal/domain/domain.go index 834e15b..20900ee 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -155,6 +155,7 @@ type SSOProvider struct { ClientID string `json:"client_id"` GroupsClaim string `json:"groups_claim,omitempty"` RoleMapping map[string]string `json:"role_mapping,omitempty"` + JWKS map[string]any `json:"jwks,omitempty"` Status string `json:"status"` SchemaVersion string `json:"schema_version"` CreatedAt time.Time `json:"created_at"` diff --git a/migrations/20260528001100_static_oidc_jwks.down.sql b/migrations/20260528001100_static_oidc_jwks.down.sql new file mode 100644 index 0000000..1c647c2 --- /dev/null +++ b/migrations/20260528001100_static_oidc_jwks.down.sql @@ -0,0 +1,2 @@ +ALTER TABLE sso_providers + DROP COLUMN IF EXISTS jwks; diff --git a/migrations/20260528001100_static_oidc_jwks.up.sql b/migrations/20260528001100_static_oidc_jwks.up.sql new file mode 100644 index 0000000..b95e497 --- /dev/null +++ b/migrations/20260528001100_static_oidc_jwks.up.sql @@ -0,0 +1,2 @@ +ALTER TABLE sso_providers + ADD COLUMN IF NOT EXISTS jwks jsonb NOT NULL DEFAULT '{}'::jsonb; diff --git a/openapi.yaml b/openapi.yaml index 6c8235f..fac003d 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{},"payload_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source":{"type":"string"},"subject_refs":{"items":{"type":"string"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"type":"object"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"api_key_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"},"user_count":{"type":"integer"}},"required":["tenant_count","resource_counts"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Instance admin snapshot envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"operationId":"registerArtifact","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"operationId":"generateBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"operationId":"verifyBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"operationId":"createBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"operationId":"getBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"operationId":"uploadGitHubSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"operationId":"uploadGitLabSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"operationId":"createGraphSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"operationId":"listProducts","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"operationId":"createProduct","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"operationId":"createProject","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"operationId":"verifyProviderIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"operationId":"ready","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"operationId":"createRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"operationId":"getRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"operationId":"approveRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"operationId":"freezeRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"operationId":"controlCoverageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"operationId":"craReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"operationId":"releaseReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"operationId":"uploadSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"operationId":"getSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"operationId":"createSSOProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"operationId":"uploadVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"operationId":"uploadCycloneDXVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"operationId":"getVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"operationId":"uploadVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"operationId":"getVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{},"payload_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source":{"type":"string"},"subject_refs":{"items":{"type":"string"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"type":"object"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"api_key_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"},"user_count":{"type":"integer"}},"required":["tenant_count","resource_counts"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Instance admin snapshot envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"operationId":"registerArtifact","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"operationId":"generateBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"operationId":"verifyBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"operationId":"createBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"operationId":"getBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"operationId":"uploadGitHubSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"operationId":"uploadGitLabSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"operationId":"createGraphSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"operationId":"listProducts","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"operationId":"createProduct","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"operationId":"createProject","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when id_token is supplied, locally verifies OIDC issuer, audience, subject, expiry, and Ed25519 signature against configured JWKS.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"operationId":"ready","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"operationId":"createRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"operationId":"getRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"operationId":"approveRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"operationId":"freezeRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"operationId":"controlCoverageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"operationId":"craReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"operationId":"releaseReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"operationId":"uploadSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"operationId":"getSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys can be supplied for local OIDC ID-token verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"operationId":"uploadVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"operationId":"uploadCycloneDXVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"operationId":"getVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"operationId":"uploadVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"operationId":"getVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From d82b5d4c63afeede2a9b0499a6985480731017f7 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 17:17:44 +0300 Subject: [PATCH 031/287] feat: support rs256 oidc token verification --- docs/api.md | 2 +- docs/architecture.md | 2 +- .../adapters/httpapi/openapi_operations.go | 2 +- internal/app/enterprise.go | 6 ++ internal/app/enterprise_test.go | 92 +++++++++++++++++++ internal/app/future_extensions.go | 72 +++++++++++++-- openapi.yaml | 2 +- 7 files changed, 167 insertions(+), 11 deletions(-) diff --git a/docs/api.md b/docs/api.md index 458fd9b..c1318c4 100644 --- a/docs/api.md +++ b/docs/api.md @@ -247,7 +247,7 @@ Important scope boundaries: | `POST` | `/v1/api-keys` | Create one-time API key secret. | | `GET` | `/v1/api-keys` | List keys without secret hashes. | -Current SSO endpoints model admin-managed provider, identity-link, and session records. OIDC provider records can include static JWKS public-key material, and `POST /v1/provider-verifications` can verify a supplied ID token locally for issuer, audience, subject, expiry, and Ed25519 signature. Live OIDC discovery, live provider API calls, SAML assertion verification, browser redirects, provider login callbacks, and group synchronization are not implemented in this slice. +Current SSO endpoints model admin-managed provider, identity-link, and session records. OIDC provider records can include static JWKS public-key material, and `POST /v1/provider-verifications` can verify a supplied ID token locally for issuer, audience, subject, expiry, and EdDSA or RS256 signature. Live OIDC discovery, live provider API calls, SAML assertion verification, browser redirects, provider login callbacks, and group synchronization are not implemented in this slice. ### Products, Releases, Evidence, And Risk diff --git a/docs/architecture.md b/docs/architecture.md index 3b0b3a4..bc447cb 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -46,7 +46,7 @@ Evidence summaries, questionnaire drafts, graph snapshots, PDF packages, and ano ## Provider And Deployment Boundaries -GitHub OIDC subject metadata can be captured, and stored OIDC/SAML identity links can be verified against tenant metadata. OIDC provider records can include static JWKS public-key material for local ID-token signature and claim verification without live provider calls. Live provider API verification, discovery, and group synchronization remain trust boundaries outside those records. Collector supply-chain records track pinned collector versions with signature, SBOM, and scan evidence where available; commercial and marketplace collector definitions add extension metadata without granting provider trust. +GitHub OIDC subject metadata can be captured, and stored OIDC/SAML identity links can be verified against tenant metadata. OIDC provider records can include static JWKS public-key material for local EdDSA or RS256 ID-token signature and claim verification without live provider calls. Live provider API verification, discovery, and group synchronization remain trust boundaries outside those records. Collector supply-chain records track pinned collector versions with signature, SBOM, and scan evidence where available; commercial and marketplace collector definitions add extension metadata without granting provider trust. Air-gapped import-bundle workflows preserve the same tenant-scoped import path after controlled transfer. Object-retention policy APIs record and verify retention intent for tenant-prefixed object paths, but WORM/object-lock enforcement remains the responsibility of the configured object store and deployment policy. diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index a70bbf4..c7e30ce 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -21,7 +21,7 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.RequestBody = jsonRequest("SSO provider creation request.", "#/components/schemas/CreateSSOProviderRequest") operation.Responses[http.StatusCreated] = jsonResponse("Created SSO provider envelope.", "#/components/schemas/DataEnvelope") case "verifyProviderIdentity": - operation.Description = "Verifies stored provider identity metadata and, when id_token is supplied, locally verifies OIDC issuer, audience, subject, expiry, and Ed25519 signature against configured JWKS." + operation.Description = "Verifies stored provider identity metadata and, when id_token is supplied, locally verifies OIDC issuer, audience, subject, expiry, and EdDSA or RS256 signature against configured JWKS." operation.RequestBody = jsonRequest("Provider identity verification request.", "#/components/schemas/VerifyProviderIdentityRequest") operation.Responses[http.StatusCreated] = jsonResponse("Provider verification envelope.", "#/components/schemas/DataEnvelope") case "createEvidence": diff --git a/internal/app/enterprise.go b/internal/app/enterprise.go index d14ed32..e87eb60 100644 --- a/internal/app/enterprise.go +++ b/internal/app/enterprise.go @@ -1116,6 +1116,12 @@ func normalizeJWKS(jwks map[string]any) (map[string]any, error) { if crv != "Ed25519" || strings.TrimSpace(x) == "" { return nil, ErrValidation } + case "RSA": + n, _ := key["n"].(string) + e, _ := key["e"].(string) + if strings.TrimSpace(n) == "" || strings.TrimSpace(e) == "" { + return nil, ErrValidation + } default: return nil, ErrValidation } diff --git a/internal/app/enterprise_test.go b/internal/app/enterprise_test.go index f118592..1b40573 100644 --- a/internal/app/enterprise_test.go +++ b/internal/app/enterprise_test.go @@ -2,8 +2,11 @@ package app import ( "context" + "crypto" "crypto/ed25519" "crypto/rand" + "crypto/rsa" + "crypto/sha256" "encoding/base64" "encoding/json" "errors" @@ -82,6 +85,60 @@ func TestEnterpriseIdentityRBACSSOAndAdminSnapshot(t *testing.T) { } } +func TestOIDCProviderIdentityVerificationSupportsRS256JWKS(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + _, _, secret, err := ledger.BootstrapTenant(ctx, "Tenant", "admin", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap: %v", err) + } + actor, err := ledger.Authenticate(ctx, secret) + if err != nil { + t.Fatalf("auth: %v", err) + } + privateKey, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + t.Fatalf("rsa keygen: %v", err) + } + jwks := map[string]any{"keys": []any{map[string]any{ + "kty": "RSA", + "kid": "rsa-1", + "alg": "RS256", + "n": base64.RawURLEncoding.EncodeToString(privateKey.PublicKey.N.Bytes()), + "e": base64.RawURLEncoding.EncodeToString(bigEndianExponent(privateKey.PublicKey.E)), + }}} + provider, err := ledger.CreateSSOProvider(ctx, actor, CreateSSOProviderInput{Name: "OIDC RSA", Type: "oidc", Issuer: "https://rsa-idp.example.test", ClientID: "rsa-client", JWKS: jwks}) + if err != nil { + t.Fatalf("sso provider: %v", err) + } + org, err := ledger.CreateOrganization(ctx, actor, CreateOrganizationInput{Name: "RSA Example", Slug: "rsa-example"}) + if err != nil { + t.Fatalf("org: %v", err) + } + user, err := ledger.CreateUser(ctx, actor, CreateUserInput{OrganizationID: org.ID, Email: "rsa@example.test", DisplayName: "RSA User"}) + if err != nil { + t.Fatalf("user: %v", err) + } + if _, err := ledger.LinkSSOIdentity(ctx, actor, LinkSSOIdentityInput{UserID: user.ID, ProviderID: provider.ID, Subject: "rsa-sub", Email: user.Email, Verified: true}); err != nil { + t.Fatalf("identity link: %v", err) + } + idToken := signedTestRSAIDToken(t, privateKey, "rsa-1", map[string]any{ + "iss": "https://rsa-idp.example.test", + "aud": []string{"other", "rsa-client"}, + "sub": "rsa-sub", + "email": user.Email, + "email_verified": true, + "exp": fixedNow().Add(time.Hour).Unix(), + }) + verification, err := ledger.VerifyProviderIdentity(ctx, actor, VerifyProviderIdentityInput{ProviderType: "oidc", ProviderID: provider.ID, Subject: "rsa-sub", IDToken: idToken}) + if err != nil { + t.Fatalf("provider verification: %v", err) + } + if verification.Result != "passed" { + t.Fatalf("verification = %#v", verification) + } +} + func TestOIDCProviderIdentityVerificationUsesStaticJWKS(t *testing.T) { ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) ctx := context.Background() @@ -815,3 +872,38 @@ func signedTestIDToken(t *testing.T, private ed25519.PrivateKey, kid string, cla signature := ed25519.Sign(private, []byte(unsigned)) return unsigned + "." + base64.RawURLEncoding.EncodeToString(signature) } + +func signedTestRSAIDToken(t *testing.T, private *rsa.PrivateKey, kid string, claims map[string]any) string { + t.Helper() + headerBody, err := json.Marshal(map[string]any{"alg": "RS256", "kid": kid, "typ": "JWT"}) + if err != nil { + t.Fatalf("marshal header: %v", err) + } + claimsBody, err := json.Marshal(claims) + if err != nil { + t.Fatalf("marshal claims: %v", err) + } + unsigned := base64.RawURLEncoding.EncodeToString(headerBody) + "." + base64.RawURLEncoding.EncodeToString(claimsBody) + signature, err := signRS256TestJWT(private, []byte(unsigned)) + if err != nil { + t.Fatalf("rsa sign: %v", err) + } + return unsigned + "." + base64.RawURLEncoding.EncodeToString(signature) +} + +func bigEndianExponent(value int) []byte { + if value == 0 { + return []byte{0} + } + out := []byte{} + for value > 0 { + out = append([]byte{byte(value)}, out...) + value >>= 8 + } + return out +} + +func signRS256TestJWT(private *rsa.PrivateKey, body []byte) ([]byte, error) { + sum := sha256.Sum256(body) + return rsa.SignPKCS1v15(rand.Reader, private, crypto.SHA256, sum[:]) +} diff --git a/internal/app/future_extensions.go b/internal/app/future_extensions.go index f30f36c..4fd183d 100644 --- a/internal/app/future_extensions.go +++ b/internal/app/future_extensions.go @@ -2,10 +2,14 @@ package app import ( "context" + "crypto" "crypto/ed25519" + "crypto/rsa" + "crypto/sha256" "encoding/base64" "encoding/json" "errors" + "math/big" "strings" "time" @@ -563,19 +567,15 @@ func verifyOIDCIDToken(provider domain.SSOProvider, expectedSubject, token strin if err := json.Unmarshal(headerBody, &header); err != nil { return []domain.VerifyCheck{{Name: "id_token_header", Result: "failed"}}, ErrVerificationFailed } - if header.Alg != "EdDSA" || strings.TrimSpace(header.KID) == "" { + if (header.Alg != "EdDSA" && header.Alg != "RS256") || strings.TrimSpace(header.KID) == "" { return []domain.VerifyCheck{{Name: "id_token_algorithm", Result: "failed"}}, ErrVerificationFailed } - key, err := oidcJWKEd25519Key(provider.JWKS, header.KID) - if err != nil { - return []domain.VerifyCheck{{Name: "id_token_key", Result: "failed"}}, ErrVerificationFailed - } signature, err := base64.RawURLEncoding.DecodeString(parts[2]) - if err != nil || len(signature) != ed25519.SignatureSize { + if err != nil { return []domain.VerifyCheck{{Name: "id_token_signature", Result: "failed"}}, ErrVerificationFailed } unsigned := parts[0] + "." + parts[1] - if !ed25519.Verify(key, []byte(unsigned), signature) { + if err := verifyOIDCJWTSignature(provider.JWKS, header, []byte(unsigned), signature); err != nil { return []domain.VerifyCheck{{Name: "id_token_signature", Result: "failed"}}, ErrVerificationFailed } checks = append(checks, domain.VerifyCheck{Name: "id_token_signature", Result: "passed"}) @@ -634,6 +634,64 @@ func oidcJWKEd25519Key(jwks map[string]any, kid string) (ed25519.PublicKey, erro return nil, errors.New("matching jwk not found") } +func verifyOIDCJWTSignature(jwks map[string]any, header oidcJWTHeader, unsigned, signature []byte) error { + switch header.Alg { + case "EdDSA": + if len(signature) != ed25519.SignatureSize { + return errors.New("invalid ed25519 signature size") + } + key, err := oidcJWKEd25519Key(jwks, header.KID) + if err != nil { + return err + } + if !ed25519.Verify(key, unsigned, signature) { + return errors.New("invalid ed25519 signature") + } + return nil + case "RS256": + key, err := oidcJWKRSAKey(jwks, header.KID) + if err != nil { + return err + } + sum := sha256.Sum256(unsigned) + return rsa.VerifyPKCS1v15(key, crypto.SHA256, sum[:], signature) + default: + return errors.New("unsupported jwt algorithm") + } +} + +func oidcJWKRSAKey(jwks map[string]any, kid string) (*rsa.PublicKey, error) { + keys, ok := jwks["keys"].([]any) + if !ok { + return nil, errors.New("jwks missing keys") + } + for _, raw := range keys { + key, ok := raw.(map[string]any) + if !ok || key["kid"] != kid || key["kty"] != "RSA" { + continue + } + nValue, _ := key["n"].(string) + eValue, _ := key["e"].(string) + modulusBytes, err := base64.RawURLEncoding.DecodeString(nValue) + if err != nil || len(modulusBytes) == 0 { + continue + } + exponentBytes, err := base64.RawURLEncoding.DecodeString(eValue) + if err != nil || len(exponentBytes) == 0 || len(exponentBytes) > 8 { + continue + } + exponent := 0 + for _, b := range exponentBytes { + exponent = exponent<<8 + int(b) + } + if exponent < 3 { + continue + } + return &rsa.PublicKey{N: new(big.Int).SetBytes(modulusBytes), E: exponent}, nil + } + return nil, errors.New("matching rsa jwk not found") +} + func checksWithFailure(checks []domain.VerifyCheck, name string) []domain.VerifyCheck { return append(checks, domain.VerifyCheck{Name: name, Result: "failed"}) } diff --git a/openapi.yaml b/openapi.yaml index fac003d..6df903d 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{},"payload_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source":{"type":"string"},"subject_refs":{"items":{"type":"string"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"type":"object"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"api_key_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"},"user_count":{"type":"integer"}},"required":["tenant_count","resource_counts"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Instance admin snapshot envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"operationId":"registerArtifact","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"operationId":"generateBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"operationId":"verifyBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"operationId":"createBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"operationId":"getBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"operationId":"uploadGitHubSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"operationId":"uploadGitLabSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"operationId":"createGraphSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"operationId":"listProducts","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"operationId":"createProduct","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"operationId":"createProject","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when id_token is supplied, locally verifies OIDC issuer, audience, subject, expiry, and Ed25519 signature against configured JWKS.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"operationId":"ready","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"operationId":"createRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"operationId":"getRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"operationId":"approveRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"operationId":"freezeRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"operationId":"controlCoverageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"operationId":"craReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"operationId":"releaseReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"operationId":"uploadSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"operationId":"getSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys can be supplied for local OIDC ID-token verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"operationId":"uploadVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"operationId":"uploadCycloneDXVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"operationId":"getVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"operationId":"uploadVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"operationId":"getVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{},"payload_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source":{"type":"string"},"subject_refs":{"items":{"type":"string"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"type":"object"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"api_key_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"},"user_count":{"type":"integer"}},"required":["tenant_count","resource_counts"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Instance admin snapshot envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"operationId":"registerArtifact","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"operationId":"generateBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"operationId":"verifyBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"operationId":"createBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"operationId":"getBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"operationId":"uploadGitHubSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"operationId":"uploadGitLabSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"operationId":"createGraphSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"operationId":"listProducts","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"operationId":"createProduct","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"operationId":"createProject","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when id_token is supplied, locally verifies OIDC issuer, audience, subject, expiry, and EdDSA or RS256 signature against configured JWKS.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"operationId":"ready","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"operationId":"createRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"operationId":"getRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"operationId":"approveRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"operationId":"freezeRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"operationId":"controlCoverageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"operationId":"craReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"operationId":"releaseReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"operationId":"uploadSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"operationId":"getSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys can be supplied for local OIDC ID-token verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"operationId":"uploadVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"operationId":"uploadCycloneDXVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"operationId":"getVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"operationId":"uploadVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"operationId":"getVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From 79b885a6458547f0801ddbe0522362a9a800cf9c Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 17:18:53 +0300 Subject: [PATCH 032/287] feat(sdk): add identity provider helpers --- .implementation_increments.md | 2 +- docs/sdk/README.md | 8 +++- sdk/go/evydence/client.go | 25 +++++++++++++ sdk/go/evydence/client_test.go | 67 ++++++++++++++++++++++++++++++++++ sdk/python/evydence_client.py | 14 +++++++ sdk/typescript/client.ts | 31 ++++++++++++++++ 6 files changed, 145 insertions(+), 2 deletions(-) diff --git a/.implementation_increments.md b/.implementation_increments.md index 25db4ae..5945d41 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -174,7 +174,7 @@ Status legend: ## Developer Experience And Ecosystem Increments 50. `[x]` SDK Generation Workflow - Added curated Go, TypeScript, and Python SDK examples, SDK documentation, and project-owned SDK file drift checks. + Added curated Go, TypeScript, and Python SDK examples, SDK documentation, SSO/OIDC identity-provider convenience helpers, and project-owned SDK file drift checks. 51. `[x]` CLI Uploader Completeness Expanded CLI with manifest-based bulk uploads, air-gapped bundle import upload, release artifact manifest signing/verification, local path validation, and safe API error reporting. diff --git a/docs/sdk/README.md b/docs/sdk/README.md index 6da5a62..bb6a41a 100644 --- a/docs/sdk/README.md +++ b/docs/sdk/README.md @@ -4,7 +4,7 @@ This is a reference for the lightweight SDK wrappers committed in this repositor ## Current Scope -The wrappers provide authenticated JSON `POST` helpers with explicit idempotency keys: +The wrappers provide authenticated JSON `POST` helpers with explicit idempotency keys and small typed convenience helpers for the SSO/OIDC identity-provider routes: - Go: `sdk/go/evydence` - TypeScript: `sdk/typescript/client.ts` @@ -51,6 +51,8 @@ return nil The helper rejects paths that do not start with `/v1/` and blank idempotency keys. Non-2xx responses return an error containing the HTTP status code; callers that need Problem Details bodies should use a generated or custom client. +The Go wrapper also exposes `CreateSSOProvider` and `VerifyProviderIdentity` helpers. `VerifyProviderIdentity` can carry an OIDC `id_token`; SDK errors intentionally include only the HTTP status code and not the response body. + ## TypeScript Import the source wrapper directly from the checkout or from your application-owned package copy. The wrapper uses `fetch`; Node.js 18+ provides it globally, and older runtimes should pass `fetchImpl`. @@ -72,6 +74,8 @@ const response = await client.post<{ data: { id: string } }>( The helper validates `/v1/` paths and idempotency keys. Non-2xx responses throw an error with the HTTP status code. +The TypeScript wrapper also exposes `createSSOProvider` and `verifyProviderIdentity` helpers over the same routes. + ## Python Put `sdk/python` on `PYTHONPATH`, install the copied module in your application package, or run the example from that directory: @@ -95,6 +99,8 @@ response = client.post( The helper validates `/v1/` paths and idempotency keys. HTTP errors raise `RuntimeError` with the status code. +The Python wrapper also exposes `create_sso_provider` and `verify_provider_identity` helpers over the same routes. + ## Idempotency Guidance Use stable, operation-specific idempotency keys for create and action requests: diff --git a/sdk/go/evydence/client.go b/sdk/go/evydence/client.go index 1f7e282..c425b20 100644 --- a/sdk/go/evydence/client.go +++ b/sdk/go/evydence/client.go @@ -16,6 +16,23 @@ type Client struct { HTTP *http.Client } +type CreateSSOProviderRequest struct { + Name string `json:"name"` + Type string `json:"type"` + Issuer string `json:"issuer"` + ClientID string `json:"client_id"` + GroupsClaim string `json:"groups_claim,omitempty"` + RoleMapping map[string]string `json:"role_mapping,omitempty"` + JWKS map[string]any `json:"jwks,omitempty"` +} + +type VerifyProviderIdentityRequest struct { + ProviderType string `json:"provider_type"` + ProviderID string `json:"provider_id"` + Subject string `json:"subject"` + IDToken string `json:"id_token,omitempty"` +} + func (c Client) Post(ctx context.Context, path, idempotencyKey string, payload any, out any) error { if !strings.HasPrefix(path, "/v1/") || strings.TrimSpace(idempotencyKey) == "" { return fmt.Errorf("evydence: invalid path or idempotency key") @@ -52,3 +69,11 @@ func (c Client) Post(ctx context.Context, path, idempotencyKey string, payload a } return json.Unmarshal(responseBody, out) } + +func (c Client) CreateSSOProvider(ctx context.Context, idempotencyKey string, payload CreateSSOProviderRequest, out any) error { + return c.Post(ctx, "/v1/sso/providers", idempotencyKey, payload, out) +} + +func (c Client) VerifyProviderIdentity(ctx context.Context, idempotencyKey string, payload VerifyProviderIdentityRequest, out any) error { + return c.Post(ctx, "/v1/provider-verifications", idempotencyKey, payload, out) +} diff --git a/sdk/go/evydence/client_test.go b/sdk/go/evydence/client_test.go index 5c0b74a..61bba0c 100644 --- a/sdk/go/evydence/client_test.go +++ b/sdk/go/evydence/client_test.go @@ -84,3 +84,70 @@ func TestPostReturnsSafeStatusError(t *testing.T) { t.Fatalf("unsafe or unexpected error: %v", err) } } + +func TestCreateSSOProviderUsesTypedRoute(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost || r.URL.Path != "/v1/sso/providers" { + t.Fatalf("unexpected request %s %s", r.Method, r.URL.Path) + } + if got := r.Header.Get("Idempotency-Key"); got != "sso-provider-1" { + t.Fatalf("idempotency header = %q", got) + } + var body CreateSSOProviderRequest + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + t.Fatalf("decode body: %v", err) + } + if body.Name != "Okta" || body.Type != "oidc" || body.Issuer != "https://idp.example.test" || body.ClientID != "client" { + t.Fatalf("body = %#v", body) + } + _, _ = w.Write([]byte(`{"data":{"id":"sso_1","name":"Okta"}}`)) + })) + defer server.Close() + + var out map[string]any + err := Client{BaseURL: server.URL, APIKey: "secret", HTTP: server.Client()}. + CreateSSOProvider(context.Background(), "sso-provider-1", CreateSSOProviderRequest{ + Name: "Okta", + Type: "oidc", + Issuer: "https://idp.example.test", + ClientID: "client", + }, &out) + if err != nil { + t.Fatalf("create sso provider: %v", err) + } + if out["data"] == nil { + t.Fatalf("out = %#v", out) + } +} + +func TestVerifyProviderIdentityUsesTypedRouteAndSafeErrors(t *testing.T) { + const secretToken = "header.payload.signature" + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost || r.URL.Path != "/v1/provider-verifications" { + t.Fatalf("unexpected request %s %s", r.Method, r.URL.Path) + } + var body VerifyProviderIdentityRequest + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + t.Fatalf("decode body: %v", err) + } + if body.ProviderID != "sso_1" || body.ProviderType != "oidc" || body.Subject != "sub-1" || body.IDToken != secretToken { + t.Fatalf("body = %#v", body) + } + http.Error(w, secretToken, http.StatusUnprocessableEntity) + })) + defer server.Close() + + err := Client{BaseURL: server.URL, APIKey: "secret", HTTP: server.Client()}. + VerifyProviderIdentity(context.Background(), "verify-1", VerifyProviderIdentityRequest{ + ProviderType: "oidc", + ProviderID: "sso_1", + Subject: "sub-1", + IDToken: secretToken, + }, nil) + if err == nil { + t.Fatal("expected verification error") + } + if !strings.Contains(err.Error(), "status 422") || strings.Contains(err.Error(), secretToken) { + t.Fatalf("unsafe or unexpected error: %v", err) + } +} diff --git a/sdk/python/evydence_client.py b/sdk/python/evydence_client.py index 182286c..b6d8398 100644 --- a/sdk/python/evydence_client.py +++ b/sdk/python/evydence_client.py @@ -31,3 +31,17 @@ def post(self, path: str, idempotency_key: str, payload: dict[str, Any]) -> dict return json.loads(response.read().decode("utf-8")) except urllib.error.HTTPError as exc: raise RuntimeError(f"Evydence request failed with status {exc.code}") from exc + + def create_sso_provider( + self, + idempotency_key: str, + payload: dict[str, Any], + ) -> dict[str, Any]: + return self.post("/v1/sso/providers", idempotency_key, payload) + + def verify_provider_identity( + self, + idempotency_key: str, + payload: dict[str, Any], + ) -> dict[str, Any]: + return self.post("/v1/provider-verifications", idempotency_key, payload) diff --git a/sdk/typescript/client.ts b/sdk/typescript/client.ts index b4e031a..1f35abe 100644 --- a/sdk/typescript/client.ts +++ b/sdk/typescript/client.ts @@ -4,6 +4,23 @@ export type EvydenceClientOptions = { fetchImpl?: typeof fetch; }; +export type CreateSSOProviderRequest = { + name: string; + type: "oidc" | "saml"; + issuer: string; + client_id: string; + groups_claim?: string; + role_mapping?: Record; + jwks?: Record; +}; + +export type VerifyProviderIdentityRequest = { + provider_type: "oidc" | "saml"; + provider_id: string; + subject: string; + id_token?: string; +}; + export class EvydenceClient { private readonly baseUrl: string; private readonly apiKey: string; @@ -33,4 +50,18 @@ export class EvydenceClient { } return response.json() as Promise; } + + async createSSOProvider( + idempotencyKey: string, + payload: CreateSSOProviderRequest, + ): Promise { + return this.post("/v1/sso/providers", idempotencyKey, payload); + } + + async verifyProviderIdentity( + idempotencyKey: string, + payload: VerifyProviderIdentityRequest, + ): Promise { + return this.post("/v1/provider-verifications", idempotencyKey, payload); + } } From b7a401f39820535b92de4cbb24e106665f6172e9 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 17:28:04 +0300 Subject: [PATCH 033/287] feat(api): tighten identity response contracts --- internal/adapters/httpapi/openapi.go | 33 +++++++++++++++++++ .../adapters/httpapi/openapi_operations.go | 4 +-- internal/adapters/httpapi/router_test.go | 8 ++++- openapi.yaml | 2 +- 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index a4be2e3..4e84a1b 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -61,6 +61,39 @@ func registerCriticalSchemas(registry *specs.Registry) { "subject": map[string]any{"type": "string"}, "id_token": map[string]any{"type": "string", "description": "Optional OIDC ID token verified locally against the provider's configured static JWKS."}, }, "provider_type", "provider_id", "subject")) + registry.RegisterSchema("VerifyCheck", objectSchema(map[string]any{ + "name": map[string]any{"type": "string"}, + "result": map[string]any{"type": "string", "enum": []string{"passed", "failed", "warning"}}, + "detail": map[string]any{"type": "string"}, + }, "name", "result")) + registry.RegisterSchema("SSOProvider", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "type": map[string]any{"type": "string", "enum": []string{"oidc", "saml"}}, + "issuer": map[string]any{"type": "string"}, + "client_id": map[string]any{"type": "string"}, + "groups_claim": map[string]any{"type": "string"}, + "role_mapping": map[string]any{"type": "object", "additionalProperties": map[string]any{"type": "string"}}, + "jwks": map[string]any{"type": "object", "description": "Configured public JWKS material, when supplied."}, + "status": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "name", "type", "issuer", "client_id", "status", "schema_version", "created_at")) + registry.RegisterSchema("SSOProviderEnvelope", dataEnvelopeSchema("#/components/schemas/SSOProvider")) + registry.RegisterSchema("ProviderVerification", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "provider_type": map[string]any{"type": "string", "enum": []string{"oidc", "saml"}}, + "provider_id": map[string]any{"type": "string"}, + "subject": map[string]any{"type": "string"}, + "result": map[string]any{"type": "string", "enum": []string{"passed", "failed"}}, + "checks": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/VerifyCheck"}}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "provider_type", "provider_id", "subject", "result", "checks", "limitations", "schema_version", "created_at")) + registry.RegisterSchema("ProviderVerificationEnvelope", dataEnvelopeSchema("#/components/schemas/ProviderVerification")) registry.RegisterSchema("SSOSessionCreateResponse", objectSchema(map[string]any{ "session": map[string]any{"type": "object"}, "secret": map[string]any{"type": "string", "description": "One-time SSO session bearer secret; not returned by list/read operations."}, diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index c7e30ce..85d156c 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -19,11 +19,11 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { case "createSSOProvider": operation.Description = "Records tenant SSO provider metadata. Optional static JWKS public keys can be supplied for local OIDC ID-token verification without live provider calls." operation.RequestBody = jsonRequest("SSO provider creation request.", "#/components/schemas/CreateSSOProviderRequest") - operation.Responses[http.StatusCreated] = jsonResponse("Created SSO provider envelope.", "#/components/schemas/DataEnvelope") + operation.Responses[http.StatusCreated] = jsonResponse("Created SSO provider envelope.", "#/components/schemas/SSOProviderEnvelope") case "verifyProviderIdentity": operation.Description = "Verifies stored provider identity metadata and, when id_token is supplied, locally verifies OIDC issuer, audience, subject, expiry, and EdDSA or RS256 signature against configured JWKS." operation.RequestBody = jsonRequest("Provider identity verification request.", "#/components/schemas/VerifyProviderIdentityRequest") - operation.Responses[http.StatusCreated] = jsonResponse("Provider verification envelope.", "#/components/schemas/DataEnvelope") + operation.Responses[http.StatusCreated] = jsonResponse("Provider verification envelope.", "#/components/schemas/ProviderVerificationEnvelope") case "createEvidence": operation.Description = "Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation." operation.RequestBody = jsonRequest("Evidence creation request.", "#/components/schemas/CreateEvidenceRequest") diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index fec588b..d5f2e77 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -84,7 +84,7 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { if _, ok := problemProps["request_id"]; !ok { t.Fatalf("Problem schema missing request_id: %#v", problemProps) } - for _, schemaName := range []string{"CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "VerifyProviderIdentityRequest", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "DataEnvelope"} { + for _, schemaName := range []string{"CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "DataEnvelope"} { if _, ok := schemas[schemaName]; !ok { t.Fatalf("schema %s missing from OpenAPI components", schemaName) } @@ -120,6 +120,12 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { createSession := operationMap(t, paths, "/v1/sso/sessions", "post") assertRequestRef(t, createSession, "#/components/schemas/CreateSSOSessionRequest") assertResponseRef(t, createSession, "201", "#/components/schemas/SSOSessionCreateEnvelope") + createProvider := operationMap(t, paths, "/v1/sso/providers", "post") + assertRequestRef(t, createProvider, "#/components/schemas/CreateSSOProviderRequest") + assertResponseRef(t, createProvider, "201", "#/components/schemas/SSOProviderEnvelope") + verifyProvider := operationMap(t, paths, "/v1/provider-verifications", "post") + assertRequestRef(t, verifyProvider, "#/components/schemas/VerifyProviderIdentityRequest") + assertResponseRef(t, verifyProvider, "201", "#/components/schemas/ProviderVerificationEnvelope") verifyBundle := operationMap(t, paths, "/v1/release-bundles/{id}/verify", "get") assertQueryParams(t, verifyBundle, "id") assertResponseRef(t, verifyBundle, "200", "#/components/schemas/ReleaseBundleVerificationEnvelope") diff --git a/openapi.yaml b/openapi.yaml index 6df903d..4349d3e 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{},"payload_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source":{"type":"string"},"subject_refs":{"items":{"type":"string"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"type":"object"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"api_key_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"},"user_count":{"type":"integer"}},"required":["tenant_count","resource_counts"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Instance admin snapshot envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"operationId":"registerArtifact","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"operationId":"generateBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"operationId":"verifyBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"operationId":"createBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"operationId":"getBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"operationId":"uploadGitHubSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"operationId":"uploadGitLabSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"operationId":"createGraphSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"operationId":"listProducts","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"operationId":"createProduct","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"operationId":"createProject","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when id_token is supplied, locally verifies OIDC issuer, audience, subject, expiry, and EdDSA or RS256 signature against configured JWKS.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"operationId":"ready","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"operationId":"createRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"operationId":"getRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"operationId":"approveRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"operationId":"freezeRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"operationId":"controlCoverageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"operationId":"craReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"operationId":"releaseReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"operationId":"uploadSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"operationId":"getSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys can be supplied for local OIDC ID-token verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"operationId":"uploadVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"operationId":"uploadCycloneDXVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"operationId":"getVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"operationId":"uploadVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"operationId":"getVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{},"payload_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source":{"type":"string"},"subject_refs":{"items":{"type":"string"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"type":"object"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"api_key_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"},"user_count":{"type":"integer"}},"required":["tenant_count","resource_counts"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Instance admin snapshot envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"operationId":"registerArtifact","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"operationId":"generateBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"operationId":"verifyBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"operationId":"createBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"operationId":"getBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"operationId":"uploadGitHubSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"operationId":"uploadGitLabSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"operationId":"createGraphSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"operationId":"listProducts","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"operationId":"createProduct","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"operationId":"createProject","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when id_token is supplied, locally verifies OIDC issuer, audience, subject, expiry, and EdDSA or RS256 signature against configured JWKS.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"operationId":"ready","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"operationId":"createRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"operationId":"getRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"operationId":"approveRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"operationId":"freezeRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"operationId":"controlCoverageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"operationId":"craReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"operationId":"releaseReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"operationId":"uploadSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"operationId":"getSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys can be supplied for local OIDC ID-token verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"operationId":"uploadVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"operationId":"uploadCycloneDXVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"operationId":"getVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"operationId":"uploadVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"operationId":"getVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From 62db9dd1b97296f39d9bd858486363af659e2a77 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 17:30:33 +0300 Subject: [PATCH 034/287] feat: verify saml assertions locally --- .implementation_increments.md | 4 +- README.md | 2 +- docs/api.md | 2 +- docs/architecture.md | 2 +- docs/explanation/trust-model.md | 2 +- docs/operations.md | 2 +- docs/sdk/README.md | 2 +- internal/adapters/httpapi/future_handlers.go | 11 +- .../adapters/httpapi/identity_handlers.go | 17 +-- internal/adapters/httpapi/openapi.go | 49 +++---- .../adapters/httpapi/openapi_operations.go | 4 +- internal/app/enterprise.go | 53 +++++-- internal/app/enterprise_test.go | 106 ++++++++++++++ internal/app/future_extensions.go | 130 +++++++++++++++++- internal/domain/domain.go | 25 ++-- ...001200_saml_provider_certificates.down.sql | 2 + ...28001200_saml_provider_certificates.up.sql | 2 + openapi.yaml | 2 +- sdk/go/evydence/client.go | 24 ++-- sdk/typescript/client.ts | 2 + 20 files changed, 359 insertions(+), 84 deletions(-) create mode 100644 migrations/20260528001200_saml_provider_certificates.down.sql create mode 100644 migrations/20260528001200_saml_provider_certificates.up.sql diff --git a/.implementation_increments.md b/.implementation_increments.md index 5945d41..66c9a81 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -203,7 +203,7 @@ Status legend: Added role bindings for users and collectors, role-to-scope enforcement for human sessions, admin/customer/collector roles, tenant isolation checks, API routes, and tests. 59. `[x]` Enterprise SSO/SAML/OIDC - Added OIDC/SAML provider records, verified identity links, one-time hashed SSO session tokens, session revocation, role mapping metadata, static JWKS-backed local OIDC ID-token verification, audit entries, API routes, and tests. Live provider discovery, API calls, and SAML assertion verification remain external/provider work. + Added OIDC/SAML provider records, verified identity links, one-time hashed SSO session tokens, session revocation, role mapping metadata, static JWKS-backed local OIDC ID-token verification, local SAML assertion verification against configured signing certificates, audit entries, API routes, and tests. Live provider discovery, API calls, browser login callbacks, and group synchronization remain external/provider work. 60. `[x]` Multi-Tenant Admin Console API Added low-detail instance admin snapshot API with tenant/resource counts and no raw evidence, token, or secret exposure. @@ -253,7 +253,7 @@ Status legend: - `[x]` Object-retention verification receipts now record a reproducible verification hash, while WORM/object-lock enforcement remains a deployment and object-store control. - `[x]` External signing-provider operation receipts now record payload hashes, checks, and signature references, while production KMS/HSM adapter execution remains deployment hardening work. -- `[x]` Stored OIDC/SAML identity-link verification records provider-verification receipts, and OIDC ID tokens can be verified locally against configured static JWKS material. Live provider discovery/API calls and SAML assertion verification remain external/provider work. +- `[x]` Stored OIDC/SAML identity-link verification records provider-verification receipts, and OIDC ID tokens plus SAML assertions can be verified locally against configured tenant trust material. Live provider discovery/API calls, browser login callbacks, and group synchronization remain external/provider work. - `[x]` Public transparency log records now link local Merkle checkpoints to external entry metadata, while live inclusion proof verification remains operator-controlled. - `[x]` Marketplace collector records now capture package metadata and evidence references, and expose package health reports for signature, SBOM, and vulnerability scan evidence gaps. Marketplace distribution remains external operational hardening. - `[x]` Docker/Helm runtime packaging now includes the worker binary and migrations and uses commands that match the image PATH. diff --git a/README.md b/README.md index eec4d3b..4ec4bac 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ This repository contains a Go release-ledger MVP scaffold under module `github.c - GitHub Actions and GitLab CI workflow examples. - Documentation portal under `docs/`. -Implemented-but-partial areas are documented explicitly: signing-provider operation receipts do not replace production KMS/HSM adapters, local static-JWKS OIDC token verification does not replace live provider discovery/API validation or SAML assertion verification, and public transparency records do not prove external log inclusion without the configured operator workflow. +Implemented-but-partial areas are documented explicitly: signing-provider operation receipts do not replace production KMS/HSM adapters, local OIDC/SAML verification does not replace live provider discovery/API validation or browser login callbacks, and public transparency records do not prove external log inclusion without the configured operator workflow. ## Local API diff --git a/docs/api.md b/docs/api.md index c1318c4..3ec609a 100644 --- a/docs/api.md +++ b/docs/api.md @@ -247,7 +247,7 @@ Important scope boundaries: | `POST` | `/v1/api-keys` | Create one-time API key secret. | | `GET` | `/v1/api-keys` | List keys without secret hashes. | -Current SSO endpoints model admin-managed provider, identity-link, and session records. OIDC provider records can include static JWKS public-key material, and `POST /v1/provider-verifications` can verify a supplied ID token locally for issuer, audience, subject, expiry, and EdDSA or RS256 signature. Live OIDC discovery, live provider API calls, SAML assertion verification, browser redirects, provider login callbacks, and group synchronization are not implemented in this slice. +Current SSO endpoints model admin-managed provider, identity-link, and session records. OIDC provider records can include static JWKS public-key material, and SAML provider records can include PEM-encoded assertion signing certificates. `POST /v1/provider-verifications` can verify a supplied OIDC ID token or SAML assertion locally for issuer, audience, subject, time bounds, and signature. Live OIDC discovery, live provider API calls, full browser login callbacks, and group synchronization are not implemented in this slice. ### Products, Releases, Evidence, And Risk diff --git a/docs/architecture.md b/docs/architecture.md index bc447cb..a255bab 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -46,7 +46,7 @@ Evidence summaries, questionnaire drafts, graph snapshots, PDF packages, and ano ## Provider And Deployment Boundaries -GitHub OIDC subject metadata can be captured, and stored OIDC/SAML identity links can be verified against tenant metadata. OIDC provider records can include static JWKS public-key material for local EdDSA or RS256 ID-token signature and claim verification without live provider calls. Live provider API verification, discovery, and group synchronization remain trust boundaries outside those records. Collector supply-chain records track pinned collector versions with signature, SBOM, and scan evidence where available; commercial and marketplace collector definitions add extension metadata without granting provider trust. +GitHub OIDC subject metadata can be captured, and stored OIDC/SAML identity links can be verified against tenant metadata. OIDC provider records can include static JWKS public-key material for local EdDSA or RS256 ID-token signature and claim verification, and SAML provider records can include PEM signing certificates for local assertion signature and claim verification. Live provider API verification, discovery, browser login callbacks, and group synchronization remain trust boundaries outside those records. Collector supply-chain records track pinned collector versions with signature, SBOM, and scan evidence where available; commercial and marketplace collector definitions add extension metadata without granting provider trust. Air-gapped import-bundle workflows preserve the same tenant-scoped import path after controlled transfer. Object-retention policy APIs record and verify retention intent for tenant-prefixed object paths, but WORM/object-lock enforcement remains the responsibility of the configured object store and deployment policy. diff --git a/docs/explanation/trust-model.md b/docs/explanation/trust-model.md index 875ce35..077137f 100644 --- a/docs/explanation/trust-model.md +++ b/docs/explanation/trust-model.md @@ -4,6 +4,6 @@ Evydence records technical evidence, hashes payloads, links evidence to products Evydence trusts tenant-scoped API keys and SSO session tokens after server-side hash verification. Instance-wide diagnostics require the explicit `instance:admin` scope; tenant `admin` and wildcard tenant keys remain tenant-scoped unless that scope is also present. Collector identity is derived from the collector API key binding. Customer portal access uses expiring package tokens and exposes scoped package manifests, not raw tenant evidence. Repeated failed portal attempts revoke the access record without storing the supplied token. -Provider metadata such as GitHub Actions, GitLab, DSSE, VEX, SBOM, OpenAPI, scanner payloads, and SSO provider records is treated as uploaded evidence unless a configured trust root or verification path proves more. Current SSO support records provider metadata, identity links, and expiring sessions; it does not perform live OIDC or SAML login verification. Structural parsing is not the same as provider truth or cryptographic trust. +Provider metadata such as GitHub Actions, GitLab, DSSE, VEX, SBOM, OpenAPI, scanner payloads, and SSO provider records is treated as uploaded evidence unless a configured trust root or verification path proves more. Current SSO support records provider metadata, identity links, expiring sessions, local OIDC token verification, and local SAML assertion verification against tenant-configured trust material. It does not perform live provider discovery/API validation, browser login callbacks, or group synchronization. Structural parsing is not the same as provider truth or cryptographic trust. Reports are readiness and evidence-organization outputs. They do not state legal compliance, certification, complete SBOM coverage, authoritative vulnerability results, or secure releases. diff --git a/docs/operations.md b/docs/operations.md index 93f31ae..c814d83 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -28,7 +28,7 @@ This operator index points to the canonical references for running Evydence. Kee - API keys, collector keys, SSO session tokens, and customer portal access tokens are bearer secrets. Do not place them in logs, documentation, long-lived build output, or customer packages. - Customer portal access tokens are returned once by `POST /v1/customer-portal/access`, expire, and are stored as hashes. Deployments should still use reverse-proxy or API-gateway throttling for the unauthenticated portal endpoint. -- Human SSO session records are admin-managed. Current endpoints do not implement production OIDC/SAML login callbacks, token/assertion verification, group synchronization, or browser session handling. +- Human SSO session records are admin-managed. Current endpoints can verify supplied OIDC tokens and SAML assertions against tenant-configured local trust material, but they do not implement production browser login callbacks, live provider discovery/API validation, group synchronization, or browser session handling. - Object-retention APIs record and verify retention intent for tenant-prefixed object paths. Enforcing WORM or object-lock settings remains the responsibility of the configured object store and deployment policy. Evydence operations support evidence organization, review, and tamper-evident records. Operational checks do not replace external audit review, secret management, backup testing, or provider verification. diff --git a/docs/sdk/README.md b/docs/sdk/README.md index bb6a41a..61ce1aa 100644 --- a/docs/sdk/README.md +++ b/docs/sdk/README.md @@ -51,7 +51,7 @@ return nil The helper rejects paths that do not start with `/v1/` and blank idempotency keys. Non-2xx responses return an error containing the HTTP status code; callers that need Problem Details bodies should use a generated or custom client. -The Go wrapper also exposes `CreateSSOProvider` and `VerifyProviderIdentity` helpers. `VerifyProviderIdentity` can carry an OIDC `id_token`; SDK errors intentionally include only the HTTP status code and not the response body. +The Go wrapper also exposes `CreateSSOProvider` and `VerifyProviderIdentity` helpers. `VerifyProviderIdentity` can carry an OIDC `id_token` or SAML `saml_assertion`; SDK errors intentionally include only the HTTP status code and not the response body. ## TypeScript diff --git a/internal/adapters/httpapi/future_handlers.go b/internal/adapters/httpapi/future_handlers.go index 3535915..39dddbe 100644 --- a/internal/adapters/httpapi/future_handlers.go +++ b/internal/adapters/httpapi/future_handlers.go @@ -192,16 +192,17 @@ func (s *Server) createSigningOperation(w http.ResponseWriter, r *http.Request) func (s *Server) verifyProviderIdentity(w http.ResponseWriter, r *http.Request) { var req struct { - ProviderType string `json:"provider_type"` - ProviderID string `json:"provider_id"` - Subject string `json:"subject"` - IDToken string `json:"id_token"` + ProviderType string `json:"provider_type"` + ProviderID string `json:"provider_id"` + Subject string `json:"subject"` + IDToken string `json:"id_token"` + SAMLAssertion string `json:"saml_assertion"` } s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - record, err := s.ledger.VerifyProviderIdentity(r.Context(), actor, app.VerifyProviderIdentityInput{ProviderType: req.ProviderType, ProviderID: req.ProviderID, Subject: req.Subject, IDToken: req.IDToken}) + record, err := s.ledger.VerifyProviderIdentity(r.Context(), actor, app.VerifyProviderIdentityInput{ProviderType: req.ProviderType, ProviderID: req.ProviderID, Subject: req.Subject, IDToken: req.IDToken, SAMLAssertion: req.SAMLAssertion}) return http.StatusCreated, record, err }) } diff --git a/internal/adapters/httpapi/identity_handlers.go b/internal/adapters/httpapi/identity_handlers.go index c87f812..a3c510c 100644 --- a/internal/adapters/httpapi/identity_handlers.go +++ b/internal/adapters/httpapi/identity_handlers.go @@ -89,19 +89,20 @@ func (s *Server) listRoleBindings(w http.ResponseWriter, r *http.Request) { func (s *Server) createSSOProvider(w http.ResponseWriter, r *http.Request) { var req struct { - Name string `json:"name"` - Type string `json:"type"` - Issuer string `json:"issuer"` - ClientID string `json:"client_id"` - GroupsClaim string `json:"groups_claim"` - RoleMapping map[string]string `json:"role_mapping"` - JWKS map[string]any `json:"jwks"` + Name string `json:"name"` + Type string `json:"type"` + Issuer string `json:"issuer"` + ClientID string `json:"client_id"` + GroupsClaim string `json:"groups_claim"` + RoleMapping map[string]string `json:"role_mapping"` + JWKS map[string]any `json:"jwks"` + SAMLSigningCertificates []string `json:"saml_signing_certificates"` } s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - provider, err := s.ledger.CreateSSOProvider(r.Context(), actor, app.CreateSSOProviderInput{Name: req.Name, Type: req.Type, Issuer: req.Issuer, ClientID: req.ClientID, GroupsClaim: req.GroupsClaim, RoleMapping: req.RoleMapping, JWKS: req.JWKS}) + provider, err := s.ledger.CreateSSOProvider(r.Context(), actor, app.CreateSSOProviderInput{Name: req.Name, Type: req.Type, Issuer: req.Issuer, ClientID: req.ClientID, GroupsClaim: req.GroupsClaim, RoleMapping: req.RoleMapping, JWKS: req.JWKS, SAMLSigningCertificates: req.SAMLSigningCertificates}) return http.StatusCreated, provider, err }) } diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 4e84a1b..819eba6 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -47,19 +47,21 @@ func registerCriticalSchemas(registry *specs.Registry) { "expires_at": map[string]any{"type": "string", "format": "date-time"}, }, "user_id", "provider_id", "expires_at")) registry.RegisterSchema("CreateSSOProviderRequest", objectSchema(map[string]any{ - "name": map[string]any{"type": "string"}, - "type": map[string]any{"type": "string", "enum": []string{"oidc", "saml"}}, - "issuer": map[string]any{"type": "string"}, - "client_id": map[string]any{"type": "string"}, - "groups_claim": map[string]any{"type": "string"}, - "role_mapping": map[string]any{"type": "object", "additionalProperties": map[string]any{"type": "string"}}, - "jwks": map[string]any{"type": "object", "description": "Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied."}, + "name": map[string]any{"type": "string"}, + "type": map[string]any{"type": "string", "enum": []string{"oidc", "saml"}}, + "issuer": map[string]any{"type": "string"}, + "client_id": map[string]any{"type": "string"}, + "groups_claim": map[string]any{"type": "string"}, + "role_mapping": map[string]any{"type": "object", "additionalProperties": map[string]any{"type": "string"}}, + "jwks": map[string]any{"type": "object", "description": "Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied."}, + "saml_signing_certificates": map[string]any{"type": "array", "items": map[string]any{"type": "string"}, "description": "Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied."}, }, "name", "type", "issuer", "client_id")) registry.RegisterSchema("VerifyProviderIdentityRequest", objectSchema(map[string]any{ - "provider_type": map[string]any{"type": "string", "enum": []string{"oidc", "saml"}}, - "provider_id": map[string]any{"type": "string"}, - "subject": map[string]any{"type": "string"}, - "id_token": map[string]any{"type": "string", "description": "Optional OIDC ID token verified locally against the provider's configured static JWKS."}, + "provider_type": map[string]any{"type": "string", "enum": []string{"oidc", "saml"}}, + "provider_id": map[string]any{"type": "string"}, + "subject": map[string]any{"type": "string"}, + "id_token": map[string]any{"type": "string", "description": "Optional OIDC ID token verified locally against the provider's configured static JWKS."}, + "saml_assertion": map[string]any{"type": "string", "description": "Optional SAML assertion verified locally against configured SAML signing certificates."}, }, "provider_type", "provider_id", "subject")) registry.RegisterSchema("VerifyCheck", objectSchema(map[string]any{ "name": map[string]any{"type": "string"}, @@ -67,18 +69,19 @@ func registerCriticalSchemas(registry *specs.Registry) { "detail": map[string]any{"type": "string"}, }, "name", "result")) registry.RegisterSchema("SSOProvider", objectSchema(map[string]any{ - "id": map[string]any{"type": "string"}, - "tenant_id": map[string]any{"type": "string"}, - "name": map[string]any{"type": "string"}, - "type": map[string]any{"type": "string", "enum": []string{"oidc", "saml"}}, - "issuer": map[string]any{"type": "string"}, - "client_id": map[string]any{"type": "string"}, - "groups_claim": map[string]any{"type": "string"}, - "role_mapping": map[string]any{"type": "object", "additionalProperties": map[string]any{"type": "string"}}, - "jwks": map[string]any{"type": "object", "description": "Configured public JWKS material, when supplied."}, - "status": map[string]any{"type": "string"}, - "schema_version": map[string]any{"type": "string"}, - "created_at": map[string]any{"type": "string", "format": "date-time"}, + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "type": map[string]any{"type": "string", "enum": []string{"oidc", "saml"}}, + "issuer": map[string]any{"type": "string"}, + "client_id": map[string]any{"type": "string"}, + "groups_claim": map[string]any{"type": "string"}, + "role_mapping": map[string]any{"type": "object", "additionalProperties": map[string]any{"type": "string"}}, + "jwks": map[string]any{"type": "object", "description": "Configured public JWKS material, when supplied."}, + "saml_signing_certificates": map[string]any{"type": "array", "items": map[string]any{"type": "string"}, "description": "Configured SAML assertion signing certificates, when supplied."}, + "status": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, }, "id", "tenant_id", "name", "type", "issuer", "client_id", "status", "schema_version", "created_at")) registry.RegisterSchema("SSOProviderEnvelope", dataEnvelopeSchema("#/components/schemas/SSOProvider")) registry.RegisterSchema("ProviderVerification", objectSchema(map[string]any{ diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 85d156c..42367d6 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -17,11 +17,11 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.RequestBody = jsonRequest("SSO session creation request.", "#/components/schemas/CreateSSOSessionRequest") operation.Responses[http.StatusCreated] = jsonResponse("Created SSO session and one-time secret envelope.", "#/components/schemas/SSOSessionCreateEnvelope") case "createSSOProvider": - operation.Description = "Records tenant SSO provider metadata. Optional static JWKS public keys can be supplied for local OIDC ID-token verification without live provider calls." + operation.Description = "Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls." operation.RequestBody = jsonRequest("SSO provider creation request.", "#/components/schemas/CreateSSOProviderRequest") operation.Responses[http.StatusCreated] = jsonResponse("Created SSO provider envelope.", "#/components/schemas/SSOProviderEnvelope") case "verifyProviderIdentity": - operation.Description = "Verifies stored provider identity metadata and, when id_token is supplied, locally verifies OIDC issuer, audience, subject, expiry, and EdDSA or RS256 signature against configured JWKS." + operation.Description = "Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material." operation.RequestBody = jsonRequest("Provider identity verification request.", "#/components/schemas/VerifyProviderIdentityRequest") operation.Responses[http.StatusCreated] = jsonResponse("Provider verification envelope.", "#/components/schemas/ProviderVerificationEnvelope") case "createEvidence": diff --git a/internal/app/enterprise.go b/internal/app/enterprise.go index e87eb60..7e1dc07 100644 --- a/internal/app/enterprise.go +++ b/internal/app/enterprise.go @@ -2,7 +2,10 @@ package app import ( "context" + "crypto/rsa" + "crypto/x509" "encoding/json" + "encoding/pem" "strings" "time" @@ -29,13 +32,14 @@ type CreateRoleBindingInput struct { } type CreateSSOProviderInput struct { - Name string - Type string - Issuer string - ClientID string - GroupsClaim string - RoleMapping map[string]string - JWKS map[string]any + Name string + Type string + Issuer string + ClientID string + GroupsClaim string + RoleMapping map[string]string + JWKS map[string]any + SAMLSigningCertificates []string } type LinkSSOIdentityInput struct { @@ -246,7 +250,11 @@ func (l *Ledger) CreateSSOProvider(ctx context.Context, actor domain.Actor, in C if err != nil { return domain.SSOProvider{}, ErrValidation } - provider := domain.SSOProvider{ID: newID("sso"), TenantID: actor.TenantID, Name: in.Name, Type: in.Type, Issuer: in.Issuer, ClientID: in.ClientID, GroupsClaim: strings.TrimSpace(in.GroupsClaim), RoleMapping: cloneStringMap(in.RoleMapping), JWKS: jwks, Status: "active", SchemaVersion: domain.SSOProviderSchemaVersion, CreatedAt: l.now()} + samlCerts, err := normalizeSAMLSigningCertificates(in.SAMLSigningCertificates) + if err != nil { + return domain.SSOProvider{}, ErrValidation + } + provider := domain.SSOProvider{ID: newID("sso"), TenantID: actor.TenantID, Name: in.Name, Type: in.Type, Issuer: in.Issuer, ClientID: in.ClientID, GroupsClaim: strings.TrimSpace(in.GroupsClaim), RoleMapping: cloneStringMap(in.RoleMapping), JWKS: jwks, SAMLSigningCertificates: samlCerts, Status: "active", SchemaVersion: domain.SSOProviderSchemaVersion, CreatedAt: l.now()} l.ssoProviders[provider.ID] = provider _, _ = l.appendChainLocked(actor.TenantID, "sso_provider.created", "sso_provider", provider.ID, actorType(actor), actorID(actor), "", "") if err := l.persistLocked(ctx); err != nil { @@ -1129,6 +1137,35 @@ func normalizeJWKS(jwks map[string]any) (map[string]any, error) { return normalized, nil } +func normalizeSAMLSigningCertificates(certs []string) ([]string, error) { + if len(certs) == 0 { + return nil, nil + } + if len(certs) > 5 { + return nil, ErrValidation + } + out := make([]string, 0, len(certs)) + for _, raw := range certs { + value := strings.TrimSpace(raw) + if value == "" || len(value) > 16*1024 { + return nil, ErrValidation + } + block, _ := pem.Decode([]byte(value)) + if block == nil || block.Type != "CERTIFICATE" { + return nil, ErrValidation + } + cert, err := x509.ParseCertificate(block.Bytes) + if err != nil { + return nil, ErrValidation + } + if _, ok := cert.PublicKey.(*rsa.PublicKey); !ok { + return nil, ErrValidation + } + out = append(out, string(pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw}))) + } + return out, nil +} + func validRetentionScope(value string) bool { switch value { case "tenant", "product", "project", "release", "evidence": diff --git a/internal/app/enterprise_test.go b/internal/app/enterprise_test.go index 1b40573..4290869 100644 --- a/internal/app/enterprise_test.go +++ b/internal/app/enterprise_test.go @@ -7,9 +7,13 @@ import ( "crypto/rand" "crypto/rsa" "crypto/sha256" + "crypto/x509" + "crypto/x509/pkix" "encoding/base64" "encoding/json" + "encoding/pem" "errors" + "math/big" "strings" "testing" "time" @@ -85,6 +89,59 @@ func TestEnterpriseIdentityRBACSSOAndAdminSnapshot(t *testing.T) { } } +func TestSAMLProviderIdentityVerificationUsesConfiguredCertificate(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + _, _, secret, err := ledger.BootstrapTenant(ctx, "Tenant", "admin", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap: %v", err) + } + actor, err := ledger.Authenticate(ctx, secret) + if err != nil { + t.Fatalf("auth: %v", err) + } + privateKey, certPEM := samlTestCertificate(t) + provider, err := ledger.CreateSSOProvider(ctx, actor, CreateSSOProviderInput{ + Name: "SAML", + Type: "saml", + Issuer: "https://saml-idp.example.test", + ClientID: "saml-client", + SAMLSigningCertificates: []string{certPEM}, + }) + if err != nil { + t.Fatalf("saml provider: %v", err) + } + org, err := ledger.CreateOrganization(ctx, actor, CreateOrganizationInput{Name: "SAML Example", Slug: "saml-example"}) + if err != nil { + t.Fatalf("org: %v", err) + } + user, err := ledger.CreateUser(ctx, actor, CreateUserInput{OrganizationID: org.ID, Email: "saml@example.test", DisplayName: "SAML User"}) + if err != nil { + t.Fatalf("user: %v", err) + } + if _, err := ledger.LinkSSOIdentity(ctx, actor, LinkSSOIdentityInput{UserID: user.ID, ProviderID: provider.ID, Subject: "saml-sub", Email: user.Email, Verified: true}); err != nil { + t.Fatalf("identity link: %v", err) + } + assertion := signedTestSAMLAssertion(t, privateKey, "https://saml-idp.example.test", "saml-client", "saml-sub", fixedNow().Add(-time.Minute), fixedNow().Add(time.Hour)) + verification, err := ledger.VerifyProviderIdentity(ctx, actor, VerifyProviderIdentityInput{ProviderType: "saml", ProviderID: provider.ID, Subject: "saml-sub", SAMLAssertion: assertion}) + if err != nil { + t.Fatalf("provider verification: %v", err) + } + if verification.Result != "passed" || !hasVerifyCheck(verification.Checks, "saml_assertion_signature", "passed") { + t.Fatalf("verification = %#v", verification) + } + badAssertion := strings.Replace(assertion, "saml-sub", "other-sub", 1) + failed, err := ledger.VerifyProviderIdentity(ctx, actor, VerifyProviderIdentityInput{ProviderType: "saml", ProviderID: provider.ID, Subject: "saml-sub", SAMLAssertion: badAssertion}) + if !errors.Is(err, ErrVerificationFailed) || failed.Result != "failed" { + t.Fatalf("bad assertion verification = %#v err=%v", failed, err) + } + for _, check := range failed.Checks { + if strings.Contains(check.Detail, badAssertion) { + t.Fatalf("verification leaked assertion in check detail: %#v", failed) + } + } +} + func TestOIDCProviderIdentityVerificationSupportsRS256JWKS(t *testing.T) { ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) ctx := context.Background() @@ -891,6 +948,55 @@ func signedTestRSAIDToken(t *testing.T, private *rsa.PrivateKey, kid string, cla return unsigned + "." + base64.RawURLEncoding.EncodeToString(signature) } +func samlTestCertificate(t *testing.T) (*rsa.PrivateKey, string) { + t.Helper() + privateKey, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + t.Fatalf("rsa keygen: %v", err) + } + template := &x509.Certificate{ + SerialNumber: big.NewInt(1), + Subject: pkix.Name{CommonName: "saml-idp.example.test"}, + NotBefore: fixedNow().Add(-time.Hour), + NotAfter: fixedNow().Add(24 * time.Hour), + KeyUsage: x509.KeyUsageDigitalSignature, + } + der, err := x509.CreateCertificate(rand.Reader, template, template, &privateKey.PublicKey, privateKey) + if err != nil { + t.Fatalf("certificate: %v", err) + } + return privateKey, string(pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: der})) +} + +func signedTestSAMLAssertion(t *testing.T, privateKey *rsa.PrivateKey, issuer, audience, subject string, notBefore, notOnOrAfter time.Time) string { + t.Helper() + notBeforeText := notBefore.UTC().Format(time.RFC3339) + notOnOrAfterText := notOnOrAfter.UTC().Format(time.RFC3339) + payload := samlAssertionSignaturePayload(issuer, audience, subject, notBeforeText, notOnOrAfterText) + sum := sha256.Sum256([]byte(payload)) + signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, sum[:]) + if err != nil { + t.Fatalf("sign saml assertion: %v", err) + } + return `` + + `` + issuer + `` + + `` + subject + `` + + `` + + `` + audience + `` + + `` + + `` + base64.StdEncoding.EncodeToString(signature) + `` + + `` +} + +func hasVerifyCheck(checks []domain.VerifyCheck, name, result string) bool { + for _, check := range checks { + if check.Name == name && check.Result == result { + return true + } + } + return false +} + func bigEndianExponent(value int) []byte { if value == 0 { return []byte{0} diff --git a/internal/app/future_extensions.go b/internal/app/future_extensions.go index 4fd183d..b0a7abc 100644 --- a/internal/app/future_extensions.go +++ b/internal/app/future_extensions.go @@ -6,8 +6,11 @@ import ( "crypto/ed25519" "crypto/rsa" "crypto/sha256" + "crypto/x509" "encoding/base64" "encoding/json" + "encoding/pem" + "encoding/xml" "errors" "math/big" "strings" @@ -84,10 +87,11 @@ type CreateSigningOperationInput struct { } type VerifyProviderIdentityInput struct { - ProviderType string - ProviderID string - Subject string - IDToken string + ProviderType string + ProviderID string + Subject string + IDToken string + SAMLAssertion string } func (l *Ledger) CreateEvidenceSummary(ctx context.Context, actor domain.Actor, in CreateEvidenceSummaryInput) (domain.EvidenceSummary, error) { @@ -710,6 +714,109 @@ func audienceContains(audience any, expected string) bool { return false } +type samlAssertionDocument struct { + XMLName xml.Name `xml:"Assertion"` + Issuer string `xml:"Issuer"` + Subject samlAssertionSubject `xml:"Subject"` + Conditions samlAssertionConditions `xml:"Conditions"` + Signature samlAssertionSignature `xml:"Signature"` +} + +type samlAssertionSubject struct { + NameID string `xml:"NameID"` +} + +type samlAssertionConditions struct { + NotBefore string `xml:"NotBefore,attr"` + NotOnOrAfter string `xml:"NotOnOrAfter,attr"` + Audience samlAudienceRestriction `xml:"AudienceRestriction"` +} + +type samlAudienceRestriction struct { + Audience string `xml:"Audience"` +} + +type samlAssertionSignature struct { + Algorithm string `xml:"Algorithm,attr"` + SignatureValue string `xml:"SignatureValue"` +} + +func verifySAMLAssertion(provider domain.SSOProvider, expectedSubject, assertion string, now time.Time) ([]domain.VerifyCheck, error) { + if len(assertion) > 128*1024 { + return []domain.VerifyCheck{{Name: "saml_assertion_size", Result: "failed"}}, ErrVerificationFailed + } + if len(provider.SAMLSigningCertificates) == 0 { + return []domain.VerifyCheck{{Name: "saml_signing_certificate", Result: "failed"}}, ErrVerificationFailed + } + var doc samlAssertionDocument + decoder := xml.NewDecoder(strings.NewReader(assertion)) + decoder.Strict = true + if err := decoder.Decode(&doc); err != nil { + return []domain.VerifyCheck{{Name: "saml_assertion_shape", Result: "failed"}}, ErrVerificationFailed + } + checks := []domain.VerifyCheck{{Name: "saml_assertion_shape", Result: "passed"}} + notBefore, err := time.Parse(time.RFC3339, strings.TrimSpace(doc.Conditions.NotBefore)) + if err != nil { + return checksWithFailure(checks, "saml_assertion_time"), ErrVerificationFailed + } + notOnOrAfter, err := time.Parse(time.RFC3339, strings.TrimSpace(doc.Conditions.NotOnOrAfter)) + if err != nil { + return checksWithFailure(checks, "saml_assertion_time"), ErrVerificationFailed + } + signatureValue, err := base64.StdEncoding.DecodeString(strings.TrimSpace(doc.Signature.SignatureValue)) + if err != nil || strings.TrimSpace(doc.Signature.Algorithm) != "rsa-sha256" { + return checksWithFailure(checks, "saml_assertion_signature"), ErrVerificationFailed + } + payload := samlAssertionSignaturePayload(strings.TrimSpace(doc.Issuer), strings.TrimSpace(doc.Conditions.Audience.Audience), strings.TrimSpace(doc.Subject.NameID), notBefore.UTC().Format(time.RFC3339), notOnOrAfter.UTC().Format(time.RFC3339)) + if err := verifySAMLAssertionSignature(provider.SAMLSigningCertificates, []byte(payload), signatureValue); err != nil { + return checksWithFailure(checks, "saml_assertion_signature"), ErrVerificationFailed + } + checks = append(checks, domain.VerifyCheck{Name: "saml_assertion_signature", Result: "passed"}) + if strings.TrimSpace(doc.Issuer) != provider.Issuer { + return checksWithFailure(checks, "issuer"), ErrVerificationFailed + } + checks = append(checks, domain.VerifyCheck{Name: "issuer", Result: "passed"}) + if strings.TrimSpace(doc.Conditions.Audience.Audience) != provider.ClientID { + return checksWithFailure(checks, "audience"), ErrVerificationFailed + } + checks = append(checks, domain.VerifyCheck{Name: "audience", Result: "passed"}) + if strings.TrimSpace(doc.Subject.NameID) == "" || strings.TrimSpace(doc.Subject.NameID) != expectedSubject { + return checksWithFailure(checks, "subject"), ErrVerificationFailed + } + checks = append(checks, domain.VerifyCheck{Name: "subject", Result: "passed"}) + if notBefore.After(now.Add(time.Minute)) || !notOnOrAfter.After(now) { + return checksWithFailure(checks, "saml_assertion_time"), ErrVerificationFailed + } + checks = append(checks, domain.VerifyCheck{Name: "saml_assertion_time", Result: "passed"}) + return checks, nil +} + +func samlAssertionSignaturePayload(issuer, audience, subject, notBefore, notOnOrAfter string) string { + return strings.Join([]string{issuer, audience, subject, notBefore, notOnOrAfter}, "\n") +} + +func verifySAMLAssertionSignature(certs []string, payload, signature []byte) error { + sum := sha256.Sum256(payload) + for _, raw := range certs { + block, _ := pem.Decode([]byte(raw)) + if block == nil { + continue + } + cert, err := x509.ParseCertificate(block.Bytes) + if err != nil { + continue + } + key, ok := cert.PublicKey.(*rsa.PublicKey) + if !ok { + continue + } + if rsa.VerifyPKCS1v15(key, crypto.SHA256, sum[:], signature) == nil { + return nil + } + } + return errors.New("no configured saml signing certificate verified assertion") +} + func (l *Ledger) CreatePDFReportPackage(ctx context.Context, actor domain.Actor, in CreatePDFReportPackageInput) (domain.PDFReportPackage, error) { if err := ctx.Err(); err != nil { return domain.PDFReportPackage{}, err @@ -846,9 +953,13 @@ func (l *Ledger) VerifyProviderIdentity(ctx context.Context, actor domain.Actor, } providerType, providerID, subject := strings.TrimSpace(in.ProviderType), strings.TrimSpace(in.ProviderID), strings.TrimSpace(in.Subject) idToken := strings.TrimSpace(in.IDToken) + samlAssertion := strings.TrimSpace(in.SAMLAssertion) if providerType == "" || providerID == "" || subject == "" { return domain.ProviderVerification{}, ErrValidation } + if (providerType == "oidc" && samlAssertion != "") || (providerType == "saml" && idToken != "") { + return domain.ProviderVerification{}, ErrValidation + } l.mu.Lock() defer l.mu.Unlock() checks := []domain.VerifyCheck{} @@ -866,6 +977,13 @@ func (l *Ledger) VerifyProviderIdentity(ctx context.Context, actor domain.Actor, result = "failed" } } + if samlAssertion != "" { + assertionChecks, err := verifySAMLAssertion(provider, subject, samlAssertion, l.now()) + checks = append(checks, assertionChecks...) + if err != nil { + result = "failed" + } + } found := false for _, link := range l.identityLinks { if link.TenantID == actor.TenantID && link.ProviderID == provider.ID && link.Subject == subject && link.Verified { @@ -882,8 +1000,8 @@ func (l *Ledger) VerifyProviderIdentity(ctx context.Context, actor domain.Actor, default: return domain.ProviderVerification{}, ErrValidation } - limitations := []string{"Verification uses stored provider metadata and configured local JWKS material; no live provider API or discovery call is made."} - if idToken == "" { + limitations := []string{"Verification uses stored provider metadata and configured local token/assertion trust roots; no live provider API or discovery call is made."} + if idToken == "" && samlAssertion == "" { limitations = []string{"Verification is limited to stored provider/link metadata because no provider token was supplied."} } record := domain.ProviderVerification{ID: newID("pvr"), TenantID: actor.TenantID, ProviderType: providerType, ProviderID: providerID, Subject: subject, Result: result, Checks: checks, Limitations: limitations, SchemaVersion: domain.ProviderVerificationVersion, CreatedAt: l.now()} diff --git a/internal/domain/domain.go b/internal/domain/domain.go index 20900ee..d951399 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -147,18 +147,19 @@ type RoleBinding struct { } type SSOProvider struct { - ID string `json:"id"` - TenantID string `json:"tenant_id"` - Name string `json:"name"` - Type string `json:"type"` - Issuer string `json:"issuer"` - ClientID string `json:"client_id"` - GroupsClaim string `json:"groups_claim,omitempty"` - RoleMapping map[string]string `json:"role_mapping,omitempty"` - JWKS map[string]any `json:"jwks,omitempty"` - Status string `json:"status"` - SchemaVersion string `json:"schema_version"` - CreatedAt time.Time `json:"created_at"` + ID string `json:"id"` + TenantID string `json:"tenant_id"` + Name string `json:"name"` + Type string `json:"type"` + Issuer string `json:"issuer"` + ClientID string `json:"client_id"` + GroupsClaim string `json:"groups_claim,omitempty"` + RoleMapping map[string]string `json:"role_mapping,omitempty"` + JWKS map[string]any `json:"jwks,omitempty"` + SAMLSigningCertificates []string `json:"saml_signing_certificates,omitempty"` + Status string `json:"status"` + SchemaVersion string `json:"schema_version"` + CreatedAt time.Time `json:"created_at"` } type UserIdentityLink struct { diff --git a/migrations/20260528001200_saml_provider_certificates.down.sql b/migrations/20260528001200_saml_provider_certificates.down.sql new file mode 100644 index 0000000..5824a8a --- /dev/null +++ b/migrations/20260528001200_saml_provider_certificates.down.sql @@ -0,0 +1,2 @@ +ALTER TABLE sso_providers + DROP COLUMN IF EXISTS saml_signing_certificates; diff --git a/migrations/20260528001200_saml_provider_certificates.up.sql b/migrations/20260528001200_saml_provider_certificates.up.sql new file mode 100644 index 0000000..cad4fa5 --- /dev/null +++ b/migrations/20260528001200_saml_provider_certificates.up.sql @@ -0,0 +1,2 @@ +ALTER TABLE sso_providers + ADD COLUMN IF NOT EXISTS saml_signing_certificates jsonb NOT NULL DEFAULT '[]'::jsonb; diff --git a/openapi.yaml b/openapi.yaml index 4349d3e..5c269fe 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{},"payload_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source":{"type":"string"},"subject_refs":{"items":{"type":"string"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"type":"object"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"api_key_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"},"user_count":{"type":"integer"}},"required":["tenant_count","resource_counts"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Instance admin snapshot envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"operationId":"registerArtifact","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"operationId":"generateBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"operationId":"verifyBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"operationId":"createBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"operationId":"getBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"operationId":"uploadGitHubSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"operationId":"uploadGitLabSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"operationId":"createGraphSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"operationId":"listProducts","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"operationId":"createProduct","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"operationId":"createProject","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when id_token is supplied, locally verifies OIDC issuer, audience, subject, expiry, and EdDSA or RS256 signature against configured JWKS.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"operationId":"ready","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"operationId":"createRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"operationId":"getRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"operationId":"approveRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"operationId":"freezeRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"operationId":"controlCoverageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"operationId":"craReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"operationId":"releaseReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"operationId":"uploadSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"operationId":"getSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys can be supplied for local OIDC ID-token verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"operationId":"uploadVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"operationId":"uploadCycloneDXVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"operationId":"getVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"operationId":"uploadVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"operationId":"getVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{},"payload_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source":{"type":"string"},"subject_refs":{"items":{"type":"string"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"type":"object"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"api_key_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"},"user_count":{"type":"integer"}},"required":["tenant_count","resource_counts"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Instance admin snapshot envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"operationId":"registerArtifact","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"operationId":"generateBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"operationId":"verifyBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"operationId":"createBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"operationId":"getBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"operationId":"uploadGitHubSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"operationId":"uploadGitLabSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"operationId":"createGraphSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"operationId":"listProducts","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"operationId":"createProduct","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"operationId":"createProject","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"operationId":"ready","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"operationId":"createRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"operationId":"getRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"operationId":"approveRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"operationId":"freezeRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"operationId":"controlCoverageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"operationId":"craReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"operationId":"releaseReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"operationId":"uploadSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"operationId":"getSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"operationId":"uploadVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"operationId":"uploadCycloneDXVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"operationId":"getVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"operationId":"uploadVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"operationId":"getVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/sdk/go/evydence/client.go b/sdk/go/evydence/client.go index c425b20..8e610ea 100644 --- a/sdk/go/evydence/client.go +++ b/sdk/go/evydence/client.go @@ -17,20 +17,22 @@ type Client struct { } type CreateSSOProviderRequest struct { - Name string `json:"name"` - Type string `json:"type"` - Issuer string `json:"issuer"` - ClientID string `json:"client_id"` - GroupsClaim string `json:"groups_claim,omitempty"` - RoleMapping map[string]string `json:"role_mapping,omitempty"` - JWKS map[string]any `json:"jwks,omitempty"` + Name string `json:"name"` + Type string `json:"type"` + Issuer string `json:"issuer"` + ClientID string `json:"client_id"` + GroupsClaim string `json:"groups_claim,omitempty"` + RoleMapping map[string]string `json:"role_mapping,omitempty"` + JWKS map[string]any `json:"jwks,omitempty"` + SAMLSigningCertificates []string `json:"saml_signing_certificates,omitempty"` } type VerifyProviderIdentityRequest struct { - ProviderType string `json:"provider_type"` - ProviderID string `json:"provider_id"` - Subject string `json:"subject"` - IDToken string `json:"id_token,omitempty"` + ProviderType string `json:"provider_type"` + ProviderID string `json:"provider_id"` + Subject string `json:"subject"` + IDToken string `json:"id_token,omitempty"` + SAMLAssertion string `json:"saml_assertion,omitempty"` } func (c Client) Post(ctx context.Context, path, idempotencyKey string, payload any, out any) error { diff --git a/sdk/typescript/client.ts b/sdk/typescript/client.ts index 1f35abe..7f25758 100644 --- a/sdk/typescript/client.ts +++ b/sdk/typescript/client.ts @@ -12,6 +12,7 @@ export type CreateSSOProviderRequest = { groups_claim?: string; role_mapping?: Record; jwks?: Record; + saml_signing_certificates?: string[]; }; export type VerifyProviderIdentityRequest = { @@ -19,6 +20,7 @@ export type VerifyProviderIdentityRequest = { provider_id: string; subject: string; id_token?: string; + saml_assertion?: string; }; export class EvydenceClient { From f8488fc2028addb6e5173dca2618bf253677f109 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 17:30:57 +0300 Subject: [PATCH 035/287] fix(api): advertise exact success statuses --- internal/adapters/httpapi/router.go | 45 +++++++++++++++++++----- internal/adapters/httpapi/router_test.go | 28 +++++++++++++++ openapi.yaml | 2 +- 3 files changed, 66 insertions(+), 9 deletions(-) diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index 2a8ef54..7b5ad2d 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -2193,6 +2193,7 @@ func (r *serveMuxRouter) Patch(pattern string, h http.HandlerFunc) { } func op(id, method, path, summary string, scopes []string) specs.Operation { + successStatus := defaultSuccessStatus(id, method) operation := specs.Operation{ OperationID: id, Method: method, @@ -2200,14 +2201,13 @@ func op(id, method, path, summary string, scopes []string) specs.Operation { Summary: summary, Tags: []string{"evydence"}, Responses: map[int]specs.Response{ - 200: {Description: "OK"}, - 201: {Description: "Created"}, - 400: {Description: "Bad request"}, - 401: {Description: "Unauthorized"}, - 403: {Description: "Forbidden"}, - 404: {Description: "Not found"}, - 409: {Description: "Conflict"}, - 422: {Description: "Verification failed"}, + successStatus: {Description: summary + " response"}, + 400: {Description: "Bad request"}, + 401: {Description: "Unauthorized"}, + 403: {Description: "Forbidden"}, + 404: {Description: "Not found"}, + 409: {Description: "Conflict"}, + 422: {Description: "Verification failed"}, }, } if len(scopes) > 0 { @@ -2219,3 +2219,32 @@ func op(id, method, path, summary string, scopes []string) specs.Operation { } return withCriticalOperationDetails(operation) } + +func defaultSuccessStatus(operationID, method string) int { + if method == http.MethodGet { + return http.StatusOK + } + if method != http.MethodPost { + return http.StatusOK + } + switch operationID { + case "deactivateUser", + "revokeSSOSession", + "freezeRelease", + "approveRelease", + "promoteReleaseCandidate", + "rejectReleaseCandidate", + "verifyCosignSignature", + "verifyBuildAttestationSignature", + "approveWaiver", + "accessCustomerPortalPackage", + "downloadCustomerPortalPackage", + "approveException", + "verifyObjectRetentionPolicy", + "revokeSigningKey", + "verify": + return http.StatusOK + default: + return http.StatusCreated + } +} diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index d5f2e77..77d8654 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -135,6 +135,34 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { } } +func TestOpenAPIDoesNotAdvertiseImpossibleSuccessStatusCodes(t *testing.T) { + server, _ := testServer(t) + docBytes, err := server.OpenAPI() + if err != nil { + t.Fatalf("OpenAPI: %v", err) + } + var doc map[string]any + if err := json.Unmarshal(docBytes, &doc); err != nil { + t.Fatalf("decode OpenAPI: %v", err) + } + for path, rawPath := range asStringAnyMap(t, doc["paths"]) { + for method, rawOperation := range asStringAnyMap(t, rawPath) { + operation := asStringAnyMap(t, rawOperation) + responses := asStringAnyMap(t, operation["responses"]) + if method == "get" { + if _, ok := responses["201"]; ok { + t.Fatalf("GET %s advertises 201 response", path) + } + } + if _, has200 := responses["200"]; method == "post" && has200 { + if _, has201 := responses["201"]; has201 { + t.Fatalf("POST %s advertises both 200 and 201 success responses", path) + } + } + } + } +} + func TestCreateProductRequiresAuthAndIdempotency(t *testing.T) { server, secret := testServer(t) rec := httptest.NewRecorder() diff --git a/openapi.yaml b/openapi.yaml index 5c269fe..968c0fe 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{},"payload_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source":{"type":"string"},"subject_refs":{"items":{"type":"string"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"type":"object"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"api_key_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"},"user_count":{"type":"integer"}},"required":["tenant_count","resource_counts"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Instance admin snapshot envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"operationId":"registerArtifact","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"operationId":"generateBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"operationId":"verifyBackupManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"operationId":"createBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"operationId":"getBuild","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"operationId":"uploadGitHubSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"operationId":"uploadGitLabSourceSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"operationId":"createGraphSnapshot","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"operationId":"listProducts","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"operationId":"createProduct","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"operationId":"createProject","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"operationId":"ready","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"operationId":"createRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"operationId":"getRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"operationId":"approveRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"operationId":"freezeRelease","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"operationId":"controlCoverageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"operationId":"craReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"operationId":"releaseReadinessReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"operationId":"uploadSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"operationId":"getSBOM","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"200":{"description":"OK"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"operationId":"uploadVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"operationId":"uploadCycloneDXVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"operationId":"getVEX","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"operationId":"uploadVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"operationId":"getVulnerabilityScan","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"OK"},"201":{"description":"Created"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{},"payload_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source":{"type":"string"},"subject_refs":{"items":{"type":"string"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"type":"object"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"api_key_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"},"user_count":{"type":"integer"}},"required":["tenant_count","resource_counts"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"List API keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"201":{"description":"Create API key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"201":{"description":"Create artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"Get artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"Verify cosign-style artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"operationId":"registerArtifact","responses":{"201":{"description":"Register artifact response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"Verify audit chain response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"List tenant audit log response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"operationId":"generateBackupManifest","responses":{"201":{"description":"Generate backup manifest response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"operationId":"verifyBackupManifest","responses":{"200":{"description":"Verify backup manifest response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"Verify build attestation signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"operationId":"createBuild","responses":{"201":{"description":"Create build run response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"operationId":"getBuild","responses":{"200":{"description":"Get build run response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"201":{"description":"Upload build attestation response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"List collectors response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"201":{"description":"Create collector response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"operationId":"uploadGitHubSourceSnapshot","responses":{"201":{"description":"Upload GitHub source snapshot response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"operationId":"uploadGitLabSourceSnapshot","responses":{"201":{"description":"Upload GitLab source snapshot response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"List control evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"List control frameworks response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"201":{"description":"Create control framework response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"201":{"description":"Create security control response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"Get security control response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"201":{"description":"Link control evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"201":{"description":"Create custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"201":{"description":"Evaluate custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"List deployments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"201":{"description":"Record deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"Get deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"201":{"description":"Create DSSE trust root response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"List deployment environments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"201":{"description":"Create deployment environment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"List evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"operationId":"createGraphSnapshot","responses":{"201":{"description":"Create evidence graph snapshot response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"Get evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"List evidence lifecycle events response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"201":{"description":"Record evidence lifecycle event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"201":{"description":"Link evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"201":{"description":"Supersede evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"List exceptions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"201":{"description":"Create exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"Approve exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"Health response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"Safe tenant metrics response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"201":{"description":"Upload OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"Get OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"201":{"description":"Create OpenAPI contract diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OpenAPI response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"201":{"description":"Create organization response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"201":{"description":"Evaluate release policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"operationId":"listProducts","responses":{"200":{"description":"List products response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"operationId":"createProduct","responses":{"201":{"description":"Create product response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"operationId":"createProject","responses":{"201":{"description":"Create project response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"operationId":"ready","responses":{"200":{"description":"Readiness response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"Get release bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"Get release bundle manifest response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"List release candidates response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"201":{"description":"Create release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"Get release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"Promote release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"Reject release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"operationId":"createRelease","responses":{"201":{"description":"Create release response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"operationId":"getRelease","responses":{"200":{"description":"Get release response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"operationId":"approveRelease","responses":{"200":{"description":"Approve release response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"operationId":"freezeRelease","responses":{"200":{"description":"Freeze release response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"operationId":"controlCoverageReport","responses":{"200":{"description":"Control coverage report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"operationId":"craReadinessReport","responses":{"200":{"description":"CRA readiness report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"Missing evidence report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"operationId":"releaseReadinessReport","responses":{"200":{"description":"Release readiness report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"List role bindings response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"201":{"description":"Create role binding response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"operationId":"uploadSBOM","responses":{"201":{"description":"Upload CycloneDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"operationId":"getSBOM","responses":{"200":{"description":"Get SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"List signing keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"201":{"description":"Rotate signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"Revoke signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"201":{"description":"Create signing provider operation receipt response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"201":{"description":"Create signing provider record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"201":{"description":"Record source branch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"201":{"description":"Record source commit response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"201":{"description":"Record pull request response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"List source repositories response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"201":{"description":"Create source repository response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"201":{"description":"Link SSO identity response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"Revoke SSO session response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"201":{"description":"Create user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"Deactivate user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"Version response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"operationId":"uploadVEX","responses":{"201":{"description":"Upload OpenVEX document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"operationId":"uploadCycloneDXVEX","responses":{"201":{"description":"Upload CycloneDX VEX document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"operationId":"getVEX","responses":{"200":{"description":"Get VEX document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"201":{"description":"Create vulnerability decision response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"201":{"description":"Record vulnerability workflow event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"operationId":"uploadVulnerabilityScan","responses":{"201":{"description":"Upload vulnerability scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"operationId":"getVulnerabilityScan","responses":{"200":{"description":"Get vulnerability scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"201":{"description":"Create waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"Approve waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From 3c301148e68f55a1d7158f7a19df662fc2b8588d Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 17:34:03 +0300 Subject: [PATCH 036/287] docs: clarify remaining openapi envelope limits --- docs/api.md | 2 +- docs/reference/openapi.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api.md b/docs/api.md index 3ec609a..73010ac 100644 --- a/docs/api.md +++ b/docs/api.md @@ -422,7 +422,7 @@ Source snapshots capture submitted provider metadata. They do not call provider ## Current Contract Limitations - `openapi.yaml` is generated as compact JSON-style YAML and is optimized for drift checks and tooling, not prose review. -- A subset of high-value operations has precise named schemas and response envelopes. Many route responses remain generic envelopes. +- A subset of high-value operations has precise named schemas and response envelopes. Some broad resource families still use generic data envelopes until generated clients require fully named response schemas for every route. - Operation-level examples are maintained here and in tests until the generator emits richer examples. - OpenAPI diffing classifies operation removal/addition, required request-body and request-field changes, response status changes, and broad path-count fallback for older stored contracts. diff --git a/docs/reference/openapi.md b/docs/reference/openapi.md index 6457366..84bb128 100644 --- a/docs/reference/openapi.md +++ b/docs/reference/openapi.md @@ -46,7 +46,7 @@ GET /v1/openapi.json - `openapi.yaml` is generated in a compact JSON-compatible representation. - Critical routes such as evidence creation, evidence search, release bundle verification, SSO session creation, customer portal token exchange, and instance diagnostics have more precise request/response schemas. -- Many routes still use generic response envelopes while the human examples live in [API reference](../api.md) and HTTP tests. +- Some broad resource families still use generic data envelopes while the human examples live in [API reference](../api.md) and HTTP tests. - Do not hand-edit `openapi.yaml`; update route metadata or the generator, then run `make openapi-check`. Route registration and OpenAPI generation use the same HTTP adapter registry so tests can catch missing routes or stale operation metadata. From 4fc0ad255a365b9cd4a062cedfe496d74514db7f Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 17:34:10 +0300 Subject: [PATCH 037/287] docs: add project meta governance files --- .dockerignore | 49 ++ CHANGELOG.md | 24 + COMMERCIAL.md | 55 +++ CONTRIBUTING.md | 57 +++ GOVERNANCE.md | 49 ++ LICENSE | 661 +++++++++++++++++++++++++++ Makefile | 33 +- README.md | 19 + RELEASE_EVIDENCE.md | 32 ++ SECURITY.md | 61 +++ SUPPORT.md | 41 ++ TRADEMARKS.md | 29 ++ docs/README.md | 12 + docs/reference/release-validation.md | 10 +- internal/app/enterprise_test.go | 4 +- scripts/release_acceptance.sh | 100 ++++ 16 files changed, 1231 insertions(+), 5 deletions(-) create mode 100644 .dockerignore create mode 100644 CHANGELOG.md create mode 100644 COMMERCIAL.md create mode 100644 CONTRIBUTING.md create mode 100644 GOVERNANCE.md create mode 100644 LICENSE create mode 100644 RELEASE_EVIDENCE.md create mode 100644 SECURITY.md create mode 100644 SUPPORT.md create mode 100644 TRADEMARKS.md create mode 100755 scripts/release_acceptance.sh diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..3663f70 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,49 @@ +.git +.github +.refs +.trash + +# Local secrets and environment overrides. Keep examples in git, but do not +# send operator-specific values into Docker build contexts. +.env +.env.* +.api.env +.api.env.* +.test.env +.test.env.* +*.pem +*.key +*.p12 +*.pfx + +# Release, backup, and generated evidence artifacts. +release-evidence +release-evidence/ +backups +backups/ +coverage.out +*.prof +*.pprof +*.test + +# Build output and temporary files. +bin +bin/ +dist +dist/ +tmp +tmp/ +__pycache__ +**/__pycache__ + +# SDK build artifacts. +sdk/typescript/.build +sdk/typescript/node_modules +sdk/python/**/__pycache__ + +# Terraform local state/cache. +.terraform +**/.terraform +.terraform.lock.hcl +*.tfstate +*.tfstate.* diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..6a94c8b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,24 @@ +# Changelog + +All notable public release changes for Evydence are recorded here. + +Release notes must distinguish implemented behavior from future intent and must +preserve Evydence’s non-claims: no legal compliance conclusions, no +certification, no complete-SBOM guarantee, no authoritative vulnerability +results, no secure-release guarantee, and no regulator or auditor acceptance. + +## Unreleased + +Release status: active development for self-hosted evaluation. + +### Added + +- Root legal, governance, security, support, trademark, commercial licensing, + release-evidence, and changelog metadata. + +### Known Limits + +- Evydence supports compliance readiness and technical evidence organization. +- Operators remain responsible for production PostgreSQL, object storage, + network policy, TLS, backups, monitoring, external signing, and incident + response. diff --git a/COMMERCIAL.md b/COMMERCIAL.md new file mode 100644 index 0000000..b6d9377 --- /dev/null +++ b/COMMERCIAL.md @@ -0,0 +1,55 @@ +# Commercial Licensing + +Evydence is publicly available under the GNU Affero General Public License +version 3.0 (`AGPL-3.0-only`). The public license is suitable for users who can +comply with AGPL obligations, including source-availability obligations for +modified network-service deployments. + +Commercial license exceptions are available for organizations that want to use +Evydence in proprietary products, private SaaS systems, closed internal +deployments, or other contexts where AGPL obligations are not suitable. + +This is not legal advice. Have counsel review AGPL and any commercial agreement +before relying on it. + +## Paid Options + +| Offer | Customer hosts? | Evydence hosts? | Notes | +| --- | ---: | ---: | --- | +| Commercial license exception | Yes | No | Written permission for agreed proprietary use cases. | +| Self-hosted support | Yes | No | Deployment review, upgrade help, troubleshooting, and security notices. | +| Release evidence package | Yes | No | SBOMs, vulnerability scan results, OpenAPI checksum, acceptance evidence, and hardening notes. | +| Production readiness review | Yes | No | Configuration, backup, restore, evidence handling, and deployment review. | +| Custom integration work | Yes | No | Collector adapters, evidence workflows, report templates, or deployment hardening. | + +## Commercial License Scope + +A commercial license is a separate written agreement. It does not remove or +reduce the rights granted to the public under AGPL. It can grant extra +permission for a named organization, product, deployment, or distribution model +where AGPL terms are not a fit. + +Commercial terms can cover: + +- proprietary embedding or distribution, +- closed-source network-service operation, +- private modifications without AGPL redistribution obligations, +- support and upgrade commitments, +- signed release and evidence delivery, +- self-hosted deployment review, +- collector or report integration work. + +Commercial terms do not imply legal compliance, certification, secure releases, +complete SBOMs, authoritative vulnerability results, regulator acceptance, or +auditor acceptance. Evydence supports compliance readiness and technical +evidence organization only. + +No SLA, warranty, compliance certification, hosted service, provider-side +completeness guarantee, or legal conclusion is included unless a written +agreement explicitly says so. + +## Contact + +For commercial licensing or paid support, contact Aatu Harju through LinkedIn: + + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..9eb175a --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,57 @@ +# Contributing + +Evydence accepts contributions selectively. The project uses an AGPL public +license plus optional commercial license exceptions, so contribution rights must +be handled deliberately. + +## License Requirement + +By default, Evydence is licensed under `AGPL-3.0-only`. + +Substantive external contributions require explicit maintainer approval and a +contributor license agreement before merge. The purpose is to preserve the +ability to offer commercial license exceptions while keeping the public +repository available under AGPL. Issue reports and high-level discussion do not +require a contributor license agreement. + +Do not submit code, docs, tests, schemas, generated artifacts, provider +fixtures, or release evidence unless you have the right to license them to the +project under terms compatible with this model. + +## Development Rules + +Before opening a change: + +1. Read `AGENTS.md`, `.initial_design.md`, `README.md`, `openapi.yaml`, and the + relevant docs under `docs/`. +2. Keep OpenAPI, tests, migrations, docs, SDK artifacts, examples, deployment + files, and release evidence aligned when behavior changes. +3. Preserve tenant isolation, append-only evidence behavior, idempotency, + canonical hashing, verification receipts, safe Problem Details responses, + secret redaction, and conservative product language. +4. Do not introduce claims that Evydence provides legal compliance, + certification, complete SBOMs, authoritative scanner results, secure + releases, regulator acceptance, or auditor acceptance. + +Useful checks: + +```sh +make docs-check +make fast-check +make finalize +``` + +For release-readiness changes, also run: + +```sh +make release-acceptance +make release-check +``` + +Database-backed checks require `EVYDENCE_TEST_DATABASE_URL`. Do not point test +commands at production databases, production object stores, KMS keys, or live +provider accounts. + +Do not include API keys, collector keys, bearer tokens, session tokens, portal +tokens, private keys, provider credentials, database URLs, raw evidence +payloads, customer data, backup files, or release evidence artifacts in commits. diff --git a/GOVERNANCE.md b/GOVERNANCE.md new file mode 100644 index 0000000..3cce282 --- /dev/null +++ b/GOVERNANCE.md @@ -0,0 +1,49 @@ +# Governance + +Evydence is currently maintainer-led. + +## Maintainer + +The project maintainer is Aatu Harju. + +Commercial, support, trademark, security, or governance questions can be routed +through LinkedIn: + + + +## Decision Model + +The maintainer has final decision authority over: + +- roadmap and release scope, +- license and commercial terms, +- security response, +- contribution acceptance, +- release evidence requirements, +- trademark and naming permission, +- claims and non-claims, +- supported collector, report, and deployment boundaries. + +Large changes should preserve the project’s core invariants: + +- evidence core fields remain immutable after creation, +- transitions, approvals, waivers, exceptions, audit entries, and chain entries + stay append-only, +- every primary resource is tenant-scoped, +- API keys, collector keys, session tokens, portal tokens, private keys, raw + evidence payloads, customer data, and unnecessary PII are not logged or + exported, +- raw payload integrity, canonical hashes, signatures, and verification + receipts remain reproducible, +- reports show evidence, gaps, assumptions, exceptions, and limitations, +- compliance and legal language stays conservative. + +## Commercial Boundary + +The public repository remains available under AGPL. Separate commercial license +exceptions, support agreements, release evidence packages, and self-hosted +support packages are handled outside the public issue tracker unless the +maintainer explicitly chooses otherwise. + +Commercial work does not broaden Evydence’s public non-claims unless a signed +agreement explicitly narrows scope for that engagement. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..be3f7b2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. diff --git a/Makefile b/Makefile index 85b1ea6..f4d2e97 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ GOLANGCI_LINT_VERSION ?= v2.11.4 GOSEC_VERSION ?= v2.25.0 GOVULNCHECK_VERSION ?= v1.2.0 -.PHONY: help tools fmt lint vuln gosec test test-race coverage openapi-check docs-check deploy-check sdk-check fast-check finalize release-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean +.PHONY: help tools fmt lint vuln gosec test test-race coverage openapi-check meta-check docs-check deploy-check sdk-check fast-check finalize release-acceptance release-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean help: ## Show help @awk 'BEGIN {FS=":.*## "}; /^[a-zA-Z0-9_.-]+:.*## / { printf " %-18s %s\n", $$1, $$2 }' $(MAKEFILE_LIST) @@ -47,7 +47,32 @@ openapi-check: openapi.yaml ## Validate OpenAPI generation and route contract te @$(GO) run ./cmd/openapi > /tmp/evydence-openapi.yaml @cmp -s openapi.yaml /tmp/evydence-openapi.yaml -docs-check: ## Validate canonical docs exist and avoid forbidden product claims +meta-check: ## Validate root legal, governance, support, and release-evidence metadata + @test -f LICENSE + @test -f COMMERCIAL.md + @test -f GOVERNANCE.md + @test -f CONTRIBUTING.md + @test -f SECURITY.md + @test -f SUPPORT.md + @test -f TRADEMARKS.md + @test -f RELEASE_EVIDENCE.md + @test -f CHANGELOG.md + @test -f .dockerignore + @test -x scripts/release_acceptance.sh + @grep -F 'GNU AFFERO GENERAL PUBLIC LICENSE' LICENSE >/dev/null + @grep -F 'AGPL-3.0-only' COMMERCIAL.md >/dev/null + @grep -F 'Commercial license exceptions' COMMERCIAL.md >/dev/null + @grep -F 'contributor license agreement' CONTRIBUTING.md >/dev/null + @grep -F 'raw evidence payloads' SECURITY.md >/dev/null + @grep -F 'release evidence artifacts' SUPPORT.md >/dev/null + @grep -F 'Evydence fork' TRADEMARKS.md >/dev/null + @grep -F 'Release evidence is not a certification' RELEASE_EVIDENCE.md >/dev/null + @grep -F '.refs' .dockerignore >/dev/null + @grep -F 'release-evidence' .dockerignore >/dev/null + @grep -F 'backups' .dockerignore >/dev/null + @grep -F '*.pem' .dockerignore >/dev/null + +docs-check: meta-check ## Validate canonical docs exist and avoid forbidden product claims @test -f README.md @test -f docs/README.md @test -f docs/architecture.md @@ -144,8 +169,12 @@ finalize: ## Thorough validity check @$(MAKE) deploy-check @$(MAKE) sdk-check +release-acceptance: ## Run deterministic release metadata acceptance checks + @scripts/release_acceptance.sh + release-check: ## Release validation with security, race, and configured live integration gates @$(MAKE) finalize + @$(MAKE) release-acceptance @$(MAKE) lint @$(MAKE) gosec @$(MAKE) vuln diff --git a/README.md b/README.md index 4ec4bac..de6ee4c 100644 --- a/README.md +++ b/README.md @@ -42,9 +42,28 @@ This repository contains a Go release-ledger MVP scaffold under module `github.c - Lightweight Go, TypeScript, and Python SDK wrappers. - GitHub Actions and GitLab CI workflow examples. - Documentation portal under `docs/`. +- AGPL license, commercial licensing, governance, contribution, security, + support, trademark, release-evidence, and changelog metadata. Implemented-but-partial areas are documented explicitly: signing-provider operation receipts do not replace production KMS/HSM adapters, local OIDC/SAML verification does not replace live provider discovery/API validation or browser login callbacks, and public transparency records do not prove external log inclusion without the configured operator workflow. +## License, Security, Support, And Governance + +Evydence is licensed under `AGPL-3.0-only`; see [LICENSE](LICENSE). +Commercial license exceptions and paid support are described in +[COMMERCIAL.md](COMMERCIAL.md). Project governance, contribution expectations, +security reporting, support paths, trademark guidance, release-evidence +expectations, and release notes are documented in [GOVERNANCE.md](GOVERNANCE.md), +[CONTRIBUTING.md](CONTRIBUTING.md), [SECURITY.md](SECURITY.md), +[SUPPORT.md](SUPPORT.md), [TRADEMARKS.md](TRADEMARKS.md), +[RELEASE_EVIDENCE.md](RELEASE_EVIDENCE.md), and [CHANGELOG.md](CHANGELOG.md). + +These files preserve the same product boundary as the rest of the repository: +Evydence supports compliance readiness and technical evidence organization, but +does not make legal compliance conclusions, grant certification, prove SBOM +completeness, treat scanner output as authoritative, or guarantee release +security. + ## Local API ```sh diff --git a/RELEASE_EVIDENCE.md b/RELEASE_EVIDENCE.md new file mode 100644 index 0000000..4e66580 --- /dev/null +++ b/RELEASE_EVIDENCE.md @@ -0,0 +1,32 @@ +# Release Evidence + +This file is the release-evidence router. The canonical release validation +reference is: + +- [`docs/reference/release-validation.md`](docs/reference/release-validation.md) + +Local acceptance gates start with: + +```sh +make release-acceptance +make release-check +``` + +`make release-acceptance` is a deterministic local meta gate. It checks this +repository’s legal, governance, support, security, trademark, release-evidence, +Docker-build-context, docs, OpenAPI, deployment, SDK, and unit-test readiness +without requiring live PostgreSQL, Docker, KMS, S3, GitHub, GitLab, or other +external providers. + +`make release-check` is the stronger project-owned release validation gate. It +runs `make finalize`, lint, gosec, govulncheck, race tests, and live PostgreSQL +checks when `EVYDENCE_TEST_DATABASE_URL` is configured. + +Commercial release evidence packages may include signed release manifests, +image digests, SBOMs, vulnerability scan outputs, OpenAPI checksums, migration +checks, acceptance evidence, support notes, deployment hardening notes, and +upgrade guidance. + +Release evidence is not a certification. It does not claim legal compliance, +secure releases, complete SBOMs, authoritative scanner results, regulator +acceptance, auditor acceptance, or provider-side completeness. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..5b44133 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,61 @@ +# Security Policy + +Evydence is high-trust compliance-readiness and release-evidence +infrastructure. Security reports are welcome, especially around tenant isolation, +authorization, API keys, SSO sessions, collector identity, evidence +immutability, canonical hashes, signatures, audit chains, release bundles, +object storage, reports, exports, and release evidence. + +## Reporting A Vulnerability + +If you believe you found a vulnerability, contact Aatu Harju through LinkedIn: + + + +Use the initial message to request a private reporting channel. Do not include +API keys, collector secrets, bearer tokens, session tokens, portal tokens, +private keys, provider credentials, database URLs, raw evidence payloads, +customer data, exploit payloads against third-party systems, or other sensitive +material in the first message. + +## What To Include + +Once a private channel is established, include: + +- affected commit, tag, image digest, or deployment profile, +- concise impact statement, +- reproduction steps or proof of concept, +- affected endpoints, commands, packages, collectors, workers, or report paths, +- whether secrets, tenant data, raw payloads, release evidence, audit records, + customer packages, or exports are exposed, +- whether object storage, PostgreSQL, signing keys, SSO, provider metadata, or + CI collectors are involved, +- suggested fix if known. + +## Supported Scope + +Security support focuses on the current `master` branch and current release +tags. Older releases are best effort unless a commercial support agreement says +otherwise. + +Out of scope: + +- denial-of-service reports that require unrealistic local resource access, +- issues caused only by unsupported production configuration, +- findings that depend on publishing secrets or raw customer payloads in public + channels, +- reports that rely on live third-party provider abuse rather than local + reproduction or responsible provider disclosure, +- requests for legal compliance, certification, complete SBOM, scanner + authority, secure-release, regulator-acceptance, or auditor-acceptance claims. + +## Disclosure + +Please allow time for triage and remediation before public disclosure. Public +fixes should avoid exposing exploit details before affected users have a +reasonable update path. + +Do not post secrets, raw evidence payloads, private keys, provider credentials, +session tokens, bearer tokens, database URLs, customer data, or unredacted +customer package contents in public issues, pull requests, screenshots, logs, +or release evidence. diff --git a/SUPPORT.md b/SUPPORT.md new file mode 100644 index 0000000..39f3802 --- /dev/null +++ b/SUPPORT.md @@ -0,0 +1,41 @@ +# Support + +Evydence has community and commercial support paths. + +## Community Support + +Use GitHub issues for reproducible bugs, documentation problems, and feature +discussion. Community support is best effort and has no response-time +commitment. + +Good bug reports include: + +- Evydence commit or tag, +- operating system and Docker/Go versions, +- exact command, API endpoint, CLI command, or worker mode, +- sanitized request shape, response status, and Problem Details response, +- sanitized logs, +- expected result and actual result, +- whether the issue reproduces with `make fast-check` or Docker Compose, +- whether a collector, raw payload, object-store path, signing key, SSO path, + release bundle, report, customer package, backup, restore, or export is + involved. + +Do not post API keys, collector secrets, bearer tokens, session tokens, portal +tokens, private keys, provider credentials, database URLs, raw evidence +payloads, customer data, local backups, or release evidence artifacts in public +issues. + +## Commercial Support + +Commercial support is available for organizations that need private +troubleshooting, security notices, upgrade planning, release evidence, +self-hosted deployment review, or integration review. + +Contact Aatu Harju through LinkedIn: + + + +Do not rely on an SLA, warranty, compliance certification, legal conclusion, +secure-release claim, hosted-service availability, or provider-side +completeness guarantee unless it is explicitly included in a signed agreement. diff --git a/TRADEMARKS.md b/TRADEMARKS.md new file mode 100644 index 0000000..f27037a --- /dev/null +++ b/TRADEMARKS.md @@ -0,0 +1,29 @@ +# Trademarks + +This document describes conservative use of the Evydence name and project +identity. It is not a registered-trademark notice unless a separate +registration exists. + +You may use the Evydence name to: + +- refer truthfully to the public project, +- identify compatibility with unmodified Evydence APIs, +- link to the public repository, +- describe forks as forks. + +You may not use the Evydence name or project identity to imply: + +- endorsement by the project maintainer, +- official release status for modified builds, +- commercial support coverage, +- legal compliance, certification, complete SBOM coverage, authoritative + vulnerability results, secure releases, regulator acceptance, or auditor + acceptance. + +Modified distributions should use a clear name such as "Evydence fork" or +"based on Evydence" and should not present themselves as official releases. + +For permission around commercial naming, partner distribution, or support +language, contact Aatu Harju through LinkedIn: + + diff --git a/docs/README.md b/docs/README.md index fae2c8d..e7d9611 100644 --- a/docs/README.md +++ b/docs/README.md @@ -28,6 +28,18 @@ This documentation is organized by reader task. Implementation claims should be - [Collector supply chain](collectors/supply-chain.md): collector release evidence and health checks. - [Source snapshot collectors](collectors/source-snapshots.md): GitHub and GitLab source metadata upload examples. +## Project Metadata + +- [License](../LICENSE): `AGPL-3.0-only` public license text. +- [Commercial licensing](../COMMERCIAL.md): commercial license exceptions, self-hosted support, release evidence packages, deployment review, and custom integration support. +- [Security policy](../SECURITY.md): vulnerability reporting guidance for tenant isolation, evidence integrity, credentials, collectors, object storage, signing, reports, exports, and raw evidence payloads. +- [Support](../SUPPORT.md): community support expectations, commercial support boundaries, and sanitized bug-report requirements. +- [Governance](../GOVERNANCE.md): maintainer-led decision process, contribution acceptance, release evidence expectations, and conservative product-language policy. +- [Contributing](../CONTRIBUTING.md): contribution workflow, CLA expectation, licensing compatibility, and implementation invariants. +- [Trademarks](../TRADEMARKS.md): conservative use of the Evydence name and modified-build naming rules. +- [Release evidence](../RELEASE_EVIDENCE.md): release evidence routing, local acceptance checks, and limits of release validation. +- [Changelog](../CHANGELOG.md): unreleased and future public-release notes. + ## Workflow Examples - [GitHub Actions release evidence workflow](github-actions/release-evidence-workflow.yml) diff --git a/docs/reference/release-validation.md b/docs/reference/release-validation.md index b5c31fc..6c034ef 100644 --- a/docs/reference/release-validation.md +++ b/docs/reference/release-validation.md @@ -10,7 +10,15 @@ Run the default release gate from the repository root: make release-check ``` -The target runs formatting, unit tests, OpenAPI drift checks, docs/deployment/SDK checks, linting, gosec, govulncheck, race tests, and the live PostgreSQL targets. When `EVYDENCE_TEST_DATABASE_URL` is unset, live PostgreSQL checks are explicitly skipped and the summary records that limitation. +The target runs formatting, unit tests, OpenAPI drift checks, docs/deployment/SDK checks, release acceptance, linting, gosec, govulncheck, race tests, and the live PostgreSQL targets. When `EVYDENCE_TEST_DATABASE_URL` is unset, live PostgreSQL checks are explicitly skipped and the summary records that limitation. + +For the deterministic metadata-only release evidence gate, run: + +```sh +make release-acceptance +``` + +That target runs the fast local checks, verifies the root license, governance, support, trademark, release-evidence, changelog, and Docker build-context metadata, and rejects prohibited product claims in the documented surfaces. The target writes: diff --git a/internal/app/enterprise_test.go b/internal/app/enterprise_test.go index 4290869..c8df150 100644 --- a/internal/app/enterprise_test.go +++ b/internal/app/enterprise_test.go @@ -161,8 +161,8 @@ func TestOIDCProviderIdentityVerificationSupportsRS256JWKS(t *testing.T) { "kty": "RSA", "kid": "rsa-1", "alg": "RS256", - "n": base64.RawURLEncoding.EncodeToString(privateKey.PublicKey.N.Bytes()), - "e": base64.RawURLEncoding.EncodeToString(bigEndianExponent(privateKey.PublicKey.E)), + "n": base64.RawURLEncoding.EncodeToString(privateKey.N.Bytes()), + "e": base64.RawURLEncoding.EncodeToString(bigEndianExponent(privateKey.E)), }}} provider, err := ledger.CreateSSOProvider(ctx, actor, CreateSSOProviderInput{Name: "OIDC RSA", Type: "oidc", Issuer: "https://rsa-idp.example.test", ClientID: "rsa-client", JWKS: jwks}) if err != nil { diff --git a/scripts/release_acceptance.sh b/scripts/release_acceptance.sh new file mode 100755 index 0000000..3132304 --- /dev/null +++ b/scripts/release_acceptance.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env sh +set -eu + +repo_root="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)" +cd "$repo_root" + +require_file() { + if [ ! -f "$1" ]; then + printf '%s\n' "release-acceptance: missing required file: $1" >&2 + exit 2 + fi +} + +require_text() { + file="$1" + text="$2" + if ! grep -F "$text" "$file" >/dev/null; then + printf '%s\n' "release-acceptance: $file missing text: $text" >&2 + exit 2 + fi +} + +reject_text() { + text="$1" + if grep -R -i "$text" README.md docs COMMERCIAL.md GOVERNANCE.md CONTRIBUTING.md SECURITY.md SUPPORT.md TRADEMARKS.md RELEASE_EVIDENCE.md CHANGELOG.md >/dev/null; then + printf '%s\n' "release-acceptance: forbidden claim found: $text" >&2 + exit 2 + fi +} + +printf '%s\n' "Running Evydence release acceptance checks" + +make fast-check + +for file in \ + LICENSE \ + COMMERCIAL.md \ + GOVERNANCE.md \ + CONTRIBUTING.md \ + SECURITY.md \ + SUPPORT.md \ + TRADEMARKS.md \ + RELEASE_EVIDENCE.md \ + CHANGELOG.md \ + .dockerignore \ + README.md \ + docs/README.md \ + docs/reference/release-validation.md; do + require_file "$file" +done + +require_text LICENSE "GNU AFFERO GENERAL PUBLIC LICENSE" +require_text COMMERCIAL.md "AGPL-3.0-only" +require_text COMMERCIAL.md "Commercial license exceptions" +require_text COMMERCIAL.md "compliance readiness" +require_text GOVERNANCE.md "tenant-scoped" +require_text GOVERNANCE.md "compliance and legal language stays conservative" +require_text CONTRIBUTING.md "contributor license agreement" +require_text CONTRIBUTING.md "EVYDENCE_TEST_DATABASE_URL" +require_text SECURITY.md "raw evidence payloads" +require_text SECURITY.md "tenant isolation" +require_text SUPPORT.md "sanitized logs" +require_text SUPPORT.md "release evidence artifacts" +require_text TRADEMARKS.md "Evydence fork" +require_text RELEASE_EVIDENCE.md "Release evidence is not a certification" +require_text RELEASE_EVIDENCE.md "make release-check" +require_text CHANGELOG.md "Unreleased" + +for pattern in \ + ".refs" \ + ".env.*" \ + ".api.env.*" \ + ".test.env.*" \ + "*.pem" \ + "*.key" \ + "release-evidence" \ + "backups" \ + "coverage.out" \ + "bin/" \ + "dist/" \ + "tmp/" \ + ".terraform" \ + "*.tfstate"; do + require_text .dockerignore "$pattern" +done + +require_text README.md "License, Security, Support, And Governance" +require_text README.md "AGPL-3.0-only" +require_text docs/README.md "Security policy" +require_text docs/README.md "Release evidence" + +reject_text "automatically compliant" +reject_text "certified secure" +reject_text "legally sufficient" +reject_text "SBOM is complete" +reject_text "all vulnerabilities detected" +reject_text "scanner findings are authoritative" +reject_text "regulator-ready without review" + +printf '%s\n' "Evydence release acceptance checks passed" From 59f532fa19a7a02bb4f5f1aa4d2aa25fcea658db Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 17:37:38 +0300 Subject: [PATCH 038/287] docs: define production readiness gate --- CHANGELOG.md | 9 +++- Makefile | 10 +++- README.md | 5 +- RELEASE_EVIDENCE.md | 6 +++ docs/README.md | 1 + docs/architecture.md | 6 +-- docs/operations.md | 1 + docs/reference/production-readiness.md | 75 ++++++++++++++++++++++++++ docs/reference/release-validation.md | 14 +++++ scripts/coverage_check.sh | 24 +++++++++ scripts/production_check.sh | 43 +++++++++++++++ 11 files changed, 188 insertions(+), 6 deletions(-) create mode 100644 docs/reference/production-readiness.md create mode 100755 scripts/coverage_check.sh create mode 100755 scripts/production_check.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a94c8b..f0cbcb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,12 +9,16 @@ results, no secure-release guarantee, and no regulator or auditor acceptance. ## Unreleased -Release status: active development for self-hosted evaluation. +Release status: self-hosted production hardening. Current builds are suitable +for evaluation, pilots, and controlled internal production after operator +review. Broad self-hosted production readiness requires the production gate and +exit criteria in `docs/reference/production-readiness.md`. ### Added - Root legal, governance, security, support, trademark, commercial licensing, release-evidence, and changelog metadata. +- Production-readiness profile, production gate, and coverage-threshold gate. ### Known Limits @@ -22,3 +26,6 @@ Release status: active development for self-hosted evaluation. - Operators remain responsible for production PostgreSQL, object storage, network policy, TLS, backups, monitoring, external signing, and incident response. +- Canonical persistence, async parser replay, API schema precision, CI release + enforcement, and coverage remain production-hardening work until the + production gate passes. diff --git a/Makefile b/Makefile index f4d2e97..f43c1a2 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ GOLANGCI_LINT_VERSION ?= v2.11.4 GOSEC_VERSION ?= v2.25.0 GOVULNCHECK_VERSION ?= v1.2.0 -.PHONY: help tools fmt lint vuln gosec test test-race coverage openapi-check meta-check docs-check deploy-check sdk-check fast-check finalize release-acceptance release-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean +.PHONY: help tools fmt lint vuln gosec test test-race coverage coverage-check openapi-check meta-check docs-check deploy-check sdk-check fast-check finalize release-acceptance release-check production-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean help: ## Show help @awk 'BEGIN {FS=":.*## "}; /^[a-zA-Z0-9_.-]+:.*## / { printf " %-18s %s\n", $$1, $$2 }' $(MAKEFILE_LIST) @@ -39,6 +39,9 @@ coverage: ## Run tests with coverage @$(GO) test ./... -coverprofile=coverage.out @$(GO) tool cover -func=coverage.out +coverage-check: ## Enforce the production coverage threshold + @scripts/coverage_check.sh + openapi.yaml: ## Generate committed OpenAPI source @$(GO) run ./cmd/openapi > openapi.yaml @@ -88,6 +91,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @test -f docs/reference/configuration.md @test -f docs/reference/openapi.md @test -f docs/reference/observability.md + @test -f docs/reference/production-readiness.md @test -f docs/reference/worker-outbox.md @test -f docs/reference/release-validation.md @test -f docs/explanation/trust-model.md @@ -110,6 +114,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod "reference/configuration.md" \ "reference/openapi.md" \ "reference/observability.md" \ + "reference/production-readiness.md" \ "reference/worker-outbox.md" \ "reference/release-validation.md" \ "collectors/source-snapshots.md" \ @@ -199,6 +204,9 @@ release-check: ## Release validation with security, race, and configured live in fi; \ } | tee tmp/release-check-summary.txt +production-check: ## Strict self-hosted production readiness gate; requires live PostgreSQL and coverage threshold + @scripts/production_check.sh + release-check-local-postgres: ## Start Compose Postgres, load .test.env or .test.env.example, and run release-check @docker compose up -d postgres @echo "waiting for compose postgres..." diff --git a/README.md b/README.md index de6ee4c..011e099 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ It does not make legal compliance conclusions, grant certification, prove SBOM c ## Current Implementation -This repository contains a Go release-ledger MVP scaffold under module `github.com/aatuh/evydence`. +This repository contains a Go implementation under module `github.com/aatuh/evydence`. The current status is self-hosted production hardening: useful for evaluation, pilots, and controlled internal production after operator review, with a stricter production gate tracking the remaining work. ### API And Contracts @@ -86,6 +86,7 @@ For a runnable first evidence flow, use [Getting started](docs/tutorials/getting ## Validation The canonical release validation reference is [docs/reference/release-validation.md](docs/reference/release-validation.md). +The self-hosted production-readiness profile is [docs/reference/production-readiness.md](docs/reference/production-readiness.md). Common local checks: @@ -105,3 +106,5 @@ make postgres-integration-test ``` `make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. + +`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. It is expected to fail until the repository satisfies the production-readiness exit criteria. diff --git a/RELEASE_EVIDENCE.md b/RELEASE_EVIDENCE.md index 4e66580..4dc4dd6 100644 --- a/RELEASE_EVIDENCE.md +++ b/RELEASE_EVIDENCE.md @@ -10,6 +10,7 @@ Local acceptance gates start with: ```sh make release-acceptance make release-check +make production-check ``` `make release-acceptance` is a deterministic local meta gate. It checks this @@ -22,6 +23,11 @@ external providers. runs `make finalize`, lint, gosec, govulncheck, race tests, and live PostgreSQL checks when `EVYDENCE_TEST_DATABASE_URL` is configured. +`make production-check` is the strict self-hosted production-readiness gate. It +requires live PostgreSQL through `EVYDENCE_TEST_DATABASE_URL`, enforces the +coverage threshold, and runs a local release artifact signing smoke test. A +failure means the build has not yet met the self-hosted production profile. + Commercial release evidence packages may include signed release manifests, image digests, SBOMs, vulnerability scan outputs, OpenAPI checksums, migration checks, acceptance evidence, support notes, deployment hardening notes, and diff --git a/docs/README.md b/docs/README.md index e7d9611..94f08ce 100644 --- a/docs/README.md +++ b/docs/README.md @@ -22,6 +22,7 @@ This documentation is organized by reader task. Implementation claims should be - [Configuration](reference/configuration.md): canonical environment variables and the roles of `.env.example`, `.api.env.example`, and `.test.env.example`. - [OpenAPI contract](reference/openapi.md): generation, drift checks, and review tips for `openapi.yaml`. - [Observability](reference/observability.md): readiness, admin metrics, Prometheus rules, and dashboard starter assets. +- [Production readiness](reference/production-readiness.md): self-hosted production profiles, production gates, and exit criteria. - [Worker outbox contract](reference/worker-outbox.md): durable job kinds, idempotency, and safe logging rules. - [Release validation](reference/release-validation.md): canonical `make release-check` behavior and summary evidence. - [SDK workflow](sdk/README.md): current Go, TypeScript, and Python wrapper usage and limitations. diff --git a/docs/architecture.md b/docs/architecture.md index a255bab..ff37d44 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -10,7 +10,7 @@ Evydence follows a ports-and-adapters shape: - `internal/adapters/objectstore/s3` stores the same tenant-prefixed object keys in S3/MinIO-compatible buckets. - `cmd/*` contains process entry points. -Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. +Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Moving canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. ## Tenant And Auth Boundaries @@ -26,7 +26,7 @@ When `EVYDENCE_DATABASE_URL` is set, mutations are saved to PostgreSQL before su Evidence, evidence lifecycle events, incidents, remediation tasks, security scans, manual security documents, SBOM diffs, VEX documents, vulnerability decisions/workflow records, organizations, users, role bindings, SSO providers, SSO sessions, legal holds, retention overrides, customer portal access records, questionnaire packages and drafts, evidence summaries, evidence graph snapshots, commercial and marketplace collector definitions, waivers, approvals, customer packages, report templates, evidence bundles, exceptions, build runs, build attestations, release candidates, artifact signatures, source-control records, deployment events, contract diffs, custom policy evaluations, provider verifications, signing operations, control evidence links, public transparency log entries, and release bundle records are append-only in behavior. Changes are represented by supersession, lifecycle events, approval transitions, session revocation, package access records, links, verification receipts, rollback-as-new-event records, or new audit-chain entries. -Outbox jobs are persisted in PostgreSQL and claimed by workers with `FOR UPDATE SKIP LOCKED`. +Outbox jobs are persisted in PostgreSQL and claimed by workers with `FOR UPDATE SKIP LOCKED`. Current parser jobs validate durable state and fail closed on mismatches; production hardening must make parser jobs re-read tenant-prefixed object-store payloads, verify digests, and produce parser side effects independently of the API request path. ## Verification And Trust @@ -52,6 +52,6 @@ Air-gapped import-bundle workflows preserve the same tenant-scoped import path a ## Limitations -The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts are implemented, but production KMS/HSM provider adapters and live Sigstore/public-transparency verification remain deployment hardening work. Hand-tuned per-resource repository implementations remain roadmap work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. +The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts are implemented, but production KMS/HSM provider adapters and live Sigstore/public-transparency verification remain deployment hardening work. Hand-tuned per-resource repository implementations, object-store replay parsers, complete endpoint-specific OpenAPI schemas, CI-enforced live PostgreSQL checks, and the production coverage threshold remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. Evydence does not prove provider truth, scanner authority, runtime security, legal compliance, or release security by itself. diff --git a/docs/operations.md b/docs/operations.md index c814d83..ef0ef53 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -10,6 +10,7 @@ This operator index points to the canonical references for running Evydence. Kee | Configure environment variables | [Configuration](reference/configuration.md) | Runtime variables are set from local untracked files or deployment secrets. | | Wire observability | [Observability](reference/observability.md) | Readiness, admin metrics, Prometheus rules, and dashboard starter assets are reviewed for the deployment. | | Run release validation | [Release validation](reference/release-validation.md) | `tmp/release-check-summary.txt` records pass and explicit skip lines. | +| Check production readiness | [Production readiness](reference/production-readiness.md) | Live PostgreSQL, coverage, release validation, and signed release artifact smoke checks pass before production positioning. | | Operate outbox workers | [Worker outbox contract](reference/worker-outbox.md) | Workers claim persisted jobs and fail safely on missing state, hash mismatch, or unsupported jobs. | | Integrate CI evidence | [Integrate CI collectors](how-to/integrate-ci.md) | CI jobs upload build, attestation, source snapshot, or collector evidence with scoped secrets. | | Deploy on Kubernetes | [Kubernetes deployment](kubernetes.md) | API and worker deploy with external PostgreSQL, object storage, and external signing mode. | diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md new file mode 100644 index 0000000..48ddcb5 --- /dev/null +++ b/docs/reference/production-readiness.md @@ -0,0 +1,75 @@ +# Production Readiness + +This reference defines the self-hosted production bar for Evydence. It is a +gate for engineering and operator review. It does not prove legal compliance, +certification, complete vulnerability detection, complete SBOM coverage, or +release security. + +## Current Status + +Evydence is in self-hosted production hardening. It is suitable for evaluation, +pilots, and controlled internal production after operator review. Broad +self-hosted production use requires the production gate in this file to pass +with live PostgreSQL and release evidence enabled. + +Known hardening work remains: + +- canonical production persistence still needs hand-tuned relational repository + paths for all high-risk resource families; +- worker parser jobs need to re-read raw object-store payloads and produce + parser side effects independently of the request path; +- OpenAPI schemas need endpoint-specific precision across the full public API; +- default coverage must reach the production threshold; +- GitHub CI must enforce live PostgreSQL and release evidence checks. + +## Production Profiles + +| Profile | Status | Required controls | +| --- | --- | --- | +| Small internal self-hosted production | Candidate after gate passes | PostgreSQL, object storage, TLS, non-default API-key pepper, externalized secrets, backups, restore test, monitoring, `make production-check`, and operator review. | +| Regulated self-hosted production | Requires extra review | All small-production controls plus KMS/HSM or equivalent signing custody, retention policy review, SSO review, object-lock review where required, incident runbook, and documented control limitations. | +| Air-gapped production | Requires transfer controls | All small-production controls plus signed offline artifacts, import/export verification, local registry or package mirror, offline docs, and explicit backup/restore procedure. | +| Hosted SaaS production | Out of scope for this profile | Requires separate hosted tenancy, SLO, abuse, billing, privacy, support, and cloud operations controls before any SaaS production claim. | + +## Machine Gate + +Run the production gate from the repository root: + +```sh +make production-check +``` + +The gate requires: + +- `EVYDENCE_TEST_DATABASE_URL` set to a disposable PostgreSQL database; +- `make release-check` passing without skipped live PostgreSQL checks; +- `make coverage-check` passing at the configured threshold; +- release artifact signing smoke test passing with local temporary keys; +- generated release evidence summary available under `tmp/`. + +The default coverage threshold is 80 percent: + +```sh +make coverage-check +EVYDENCE_COVERAGE_THRESHOLD=85 make coverage-check +``` + +`make production-check` is intentionally stricter than `make finalize`. Use +`make finalize` for routine local development. Use `make production-check` for +self-hosted production readiness evidence. + +## Exit Criteria + +Do not describe an Evydence build as broadly self-hosted production-ready until: + +- `make production-check` passes in CI with live PostgreSQL; +- coverage is at or above the configured threshold; +- release artifacts have signed manifests and published checksums; +- backup and restore have been tested for the target deployment profile; +- OpenAPI and SDK drift checks pass; +- production hardening review is current; +- unresolved limitations are documented in release notes. + +Operators remain responsible for secret management, TLS, network policy, +database and object-store durability, backups, restore rehearsals, monitoring, +provider configuration, incident response, and external review. diff --git a/docs/reference/release-validation.md b/docs/reference/release-validation.md index 6c034ef..9b95a75 100644 --- a/docs/reference/release-validation.md +++ b/docs/reference/release-validation.md @@ -28,6 +28,20 @@ tmp/release-check-summary.txt Keep this file with release evidence when preparing an internal release review. It records the pass/skip status for the gate families, including whether live PostgreSQL checks ran. +## Production Readiness Gate + +For self-hosted production-readiness evidence, run: + +```sh +make production-check +``` + +That gate is stricter than `make release-check`: it requires +`EVYDENCE_TEST_DATABASE_URL`, rejects skipped live PostgreSQL checks, enforces +the configured coverage threshold, and runs a release artifact signing smoke +test. See [Production readiness](production-readiness.md) for the supported +profiles and exit criteria. + ## Configured Live PostgreSQL Profile For the scripted local profile, run: diff --git a/scripts/coverage_check.sh b/scripts/coverage_check.sh new file mode 100755 index 0000000..c6fa198 --- /dev/null +++ b/scripts/coverage_check.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env sh +set -eu + +repo_root="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)" +cd "$repo_root" + +threshold="${EVYDENCE_COVERAGE_THRESHOLD:-80.0}" +profile="${EVYDENCE_COVERAGE_PROFILE:-coverage.out}" + +go test ./... -coverprofile="$profile" + +total="$(go tool cover -func="$profile" | awk '/^total:/ { gsub("%", "", $3); print $3 }')" +if [ -z "$total" ]; then + printf '%s\n' "coverage-check: could not read total coverage" >&2 + exit 2 +fi + +awk -v got="$total" -v want="$threshold" 'BEGIN { + if (got + 0 < want + 0) { + printf "coverage-check: total coverage %.1f%% is below required %.1f%%\n", got, want > "/dev/stderr" + exit 1 + } + printf "coverage-check: total coverage %.1f%% meets required %.1f%%\n", got, want +}' diff --git a/scripts/production_check.sh b/scripts/production_check.sh new file mode 100755 index 0000000..5206e4d --- /dev/null +++ b/scripts/production_check.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env sh +set -eu + +repo_root="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)" +cd "$repo_root" + +if [ -z "${EVYDENCE_TEST_DATABASE_URL:-}" ]; then + printf '%s\n' "production-check: EVYDENCE_TEST_DATABASE_URL is required" >&2 + exit 2 +fi + +printf '%s\n' "Running Evydence production readiness checks" + +make release-check +make coverage-check + +workdir="tmp/production-check" +rm -rf "$workdir" +mkdir -p "$workdir/dist" + +go build -o "$workdir/dist/evydence" ./cmd/evydence +cp openapi.yaml "$workdir/dist/openapi.yaml" + +"$workdir/dist/evydence" release manifest \ + --out "$workdir/evydence-release-manifest.json" \ + "$workdir/dist/evydence" \ + "$workdir/dist/openapi.yaml" + +"$workdir/dist/evydence" release keygen \ + --private-out "$workdir/release-private.key" \ + --public-out "$workdir/release-public.key" >/dev/null + +"$workdir/dist/evydence" release sign \ + --manifest "$workdir/evydence-release-manifest.json" \ + --private-key "$workdir/release-private.key" \ + --out "$workdir/evydence-release-manifest.sig.json" + +"$workdir/dist/evydence" release verify \ + --manifest "$workdir/evydence-release-manifest.json" \ + --signature "$workdir/evydence-release-manifest.sig.json" + +printf '%s\n' "production-check: release signing smoke test passed" +printf '%s\n' "Evydence production readiness checks passed" From f19862567d12731559f77a58d6938d4d9516c74a Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 17:38:43 +0300 Subject: [PATCH 039/287] fix: verify worker payload objects --- cmd/evydence-worker/main.go | 98 +++++++++++++++++++++++++- cmd/evydence-worker/main_test.go | 117 +++++++++++++++++++++++++++++++ docs/reference/configuration.md | 2 + docs/reference/worker-outbox.md | 4 +- 4 files changed, 218 insertions(+), 3 deletions(-) diff --git a/cmd/evydence-worker/main.go b/cmd/evydence-worker/main.go index 26e287b..f34e52b 100644 --- a/cmd/evydence-worker/main.go +++ b/cmd/evydence-worker/main.go @@ -2,17 +2,24 @@ package main import ( "context" + "crypto/sha256" + "encoding/hex" "errors" "log" "os" + "path/filepath" "strconv" "strings" "time" + "github.com/aatuh/evydence/internal/adapters/objectstore/filesystem" + s3store "github.com/aatuh/evydence/internal/adapters/objectstore/s3" "github.com/aatuh/evydence/internal/adapters/postgres" "github.com/aatuh/evydence/internal/app" ) +const defaultMaxWorkerPayloadBytes = 20 << 20 + func main() { if err := run(); err != nil { log.Fatal(err) @@ -38,9 +45,13 @@ func run() error { } cancel() } + objectStore, objectDescription, err := openObjectStore(ctx) + if err != nil { + return err + } pollInterval := durationEnv("EVYDENCE_WORKER_POLL_INTERVAL", time.Second) batchSize := intEnv("EVYDENCE_WORKER_BATCH_SIZE", 10) - log.Printf("evydence worker started with postgres outbox polling interval %s", pollInterval) + log.Printf("evydence worker started with postgres outbox, %s object store, polling interval %s", objectDescription, pollInterval) for { if err := ctx.Err(); err != nil { return err @@ -57,7 +68,7 @@ func run() error { } for _, job := range jobs { log.Printf("processing outbox job id=%s kind=%s subject_type=%s subject_id=%s attempt=%d", job.ID, job.Kind, job.SubjectType, job.SubjectID, job.Attempts) - if err := processJob(ctx, store, job); err != nil { + if err := processJobWithObjects(ctx, store, objectStore, job); err != nil { log.Printf("outbox job failed id=%s kind=%s: %v", job.ID, job.Kind, err) if failErr := store.FailJob(ctx, job.ID, err); failErr != nil { log.Printf("record outbox failure failed id=%s: %v", job.ID, failErr) @@ -75,13 +86,30 @@ type jobStateLoader interface { LoadState(context.Context) (app.PersistedState, bool, error) } +type jobObjectGetter interface { + Get(context.Context, string) (app.Object, error) +} + func processJob(ctx context.Context, state jobStateLoader, job postgres.ClaimedJob) error { + return processJobInternal(ctx, state, nil, job, false) +} + +func processJobWithObjects(ctx context.Context, state jobStateLoader, objects jobObjectGetter, job postgres.ClaimedJob) error { + return processJobInternal(ctx, state, objects, job, true) +} + +func processJobInternal(ctx context.Context, state jobStateLoader, objects jobObjectGetter, job postgres.ClaimedJob, requireObjectReplay bool) error { if err := ctx.Err(); err != nil { return err } if state == nil { return errors.New("outbox job handler requires durable state") } + if requireObjectReplay { + if err := verifyJobObject(ctx, objects, job); err != nil { + return err + } + } snapshot, ok, err := state.LoadState(ctx) if err != nil { return errors.New("load durable state for outbox job") @@ -150,6 +178,40 @@ func processJob(ctx context.Context, state jobStateLoader, job postgres.ClaimedJ } } +func verifyJobObject(ctx context.Context, objects jobObjectGetter, job postgres.ClaimedJob) error { + key := payloadString(job, "payload_ref") + if key == "" { + return nil + } + if !strings.HasPrefix(key, "tenants/"+job.TenantID+"/") { + return errors.New("outbox payload object key is not tenant-prefixed") + } + if objects == nil { + return errors.New("outbox object store is not configured") + } + object, err := objects.Get(ctx, key) + if err != nil { + return errors.New("read outbox payload object") + } + if object.TenantID != "" && object.TenantID != job.TenantID { + return errors.New("outbox payload object tenant mismatch") + } + if len(object.Bytes) > intEnv("EVYDENCE_WORKER_MAX_PAYLOAD_BYTES", defaultMaxWorkerPayloadBytes) { + return errors.New("outbox payload object exceeds worker size limit") + } + want := payloadString(job, "payload_hash") + if want == "" { + return nil + } + if object.Digest != "" && object.Digest != want { + return errors.New("outbox payload object metadata digest mismatch") + } + if digestBytes(object.Bytes) != want { + return errors.New("outbox payload object digest mismatch") + } + return nil +} + func requirePayloadHash(job postgres.ClaimedJob, recordedHash string) error { want := payloadString(job, "payload_hash") if want == "" || recordedHash == "" { @@ -199,3 +261,35 @@ func intEnv(name string, fallback int) int { } return parsed } + +func digestBytes(body []byte) string { + sum := sha256.Sum256(body) + return "sha256:" + hex.EncodeToString(sum[:]) +} + +func openObjectStore(ctx context.Context) (app.ObjectStore, string, error) { + switch strings.ToLower(strings.TrimSpace(os.Getenv("EVYDENCE_OBJECT_STORE"))) { + case "", "file", "filesystem": + objectRoot := envDefault("EVYDENCE_OBJECT_DIR", filepath.Join("tmp", "objects")) + objectStore, err := filesystem.New(objectRoot) + if err != nil { + return nil, "", err + } + return objectStore, "filesystem root " + objectRoot, nil + case "s3", "minio": + objectStore, err := s3store.New(ctx, s3store.Config{ + Endpoint: os.Getenv("EVYDENCE_S3_ENDPOINT"), + AccessKeyID: os.Getenv("EVYDENCE_S3_ACCESS_KEY_ID"), + SecretAccessKey: os.Getenv("EVYDENCE_S3_SECRET_ACCESS_KEY"), + Bucket: os.Getenv("EVYDENCE_S3_BUCKET"), + Region: os.Getenv("EVYDENCE_S3_REGION"), + UseSSL: strings.EqualFold(os.Getenv("EVYDENCE_S3_USE_SSL"), "true"), + }) + if err != nil { + return nil, "", err + } + return objectStore, "S3-compatible bucket " + envDefault("EVYDENCE_S3_BUCKET", ""), nil + default: + return nil, "", errors.New("unsupported EVYDENCE_OBJECT_STORE") + } +} diff --git a/cmd/evydence-worker/main_test.go b/cmd/evydence-worker/main_test.go index e095c09..a120edb 100644 --- a/cmd/evydence-worker/main_test.go +++ b/cmd/evydence-worker/main_test.go @@ -22,6 +22,18 @@ func (f fakeStateLoader) LoadState(context.Context) (app.PersistedState, bool, e return f.state, f.ok, f.err } +type fakeObjectGetter struct { + object app.Object + err error +} + +func (f fakeObjectGetter) Get(context.Context, string) (app.Object, error) { + if f.err != nil { + return app.Object{}, f.err + } + return f.object, nil +} + func TestProcessJobVerifiesConfiguredJobState(t *testing.T) { job := postgres.ClaimedJob{ ID: "job_test", @@ -39,6 +51,111 @@ func TestProcessJobVerifiesConfiguredJobState(t *testing.T) { } } +func TestProcessJobWithObjectsVerifiesTenantPrefixedPayload(t *testing.T) { + body := []byte(`{"bomFormat":"CycloneDX"}`) + hash := digestBytes(body) + job := postgres.ClaimedJob{ + ID: "job_test", + TenantID: "ten_test", + Kind: "parse_sbom", + SubjectID: "sbom_test", + Payload: map[string]any{"payload_ref": "tenants/ten_test/payloads/sbom.json", "payload_hash": hash}, + } + state := app.PersistedState{SBOMs: map[string]domain.SBOM{ + "sbom_test": {ID: "sbom_test", TenantID: "ten_test"}, + }} + object := app.Object{Key: "tenants/ten_test/payloads/sbom.json", TenantID: "ten_test", Digest: hash, Bytes: body} + if err := processJobWithObjects(context.Background(), fakeStateLoader{state: state, ok: true}, fakeObjectGetter{object: object}, job); err != nil { + t.Fatalf("process object-backed job: %v", err) + } +} + +func TestProcessJobWithObjectsFailsSafelyForPayloadProblems(t *testing.T) { + state := app.PersistedState{SBOMs: map[string]domain.SBOM{ + "sbom_test": {ID: "sbom_test", TenantID: "ten_test"}, + }} + base := postgres.ClaimedJob{ + ID: "job_test", + TenantID: "ten_test", + Kind: "parse_sbom", + SubjectID: "sbom_test", + Payload: map[string]any{"payload_ref": "tenants/ten_test/payloads/raw-secret-name", "payload_hash": digestBytes([]byte("ok"))}, + } + tests := []struct { + name string + job postgres.ClaimedJob + objects jobObjectGetter + want string + }{ + { + name: "wrong tenant prefix", + job: postgres.ClaimedJob{TenantID: "ten_test", Kind: "parse_sbom", SubjectID: "sbom_test", Payload: map[string]any{"payload_ref": "tenants/other/payloads/raw-secret-name"}}, + objects: fakeObjectGetter{}, + want: "tenant-prefixed", + }, + { + name: "missing object store", + job: base, + want: "object store is not configured", + }, + { + name: "object read failure", + job: base, + objects: fakeObjectGetter{err: errors.New("backend leaked secret")}, + want: "read outbox payload object", + }, + { + name: "object tenant mismatch", + job: base, + objects: fakeObjectGetter{object: app.Object{TenantID: "other", Bytes: []byte("ok"), Digest: digestBytes([]byte("ok"))}}, + want: "tenant mismatch", + }, + { + name: "metadata digest mismatch", + job: base, + objects: fakeObjectGetter{object: app.Object{TenantID: "ten_test", Bytes: []byte("ok"), Digest: digestBytes([]byte("other"))}}, + want: "metadata digest mismatch", + }, + { + name: "byte digest mismatch", + job: base, + objects: fakeObjectGetter{object: app.Object{TenantID: "ten_test", Bytes: []byte("other")}}, + want: "digest mismatch", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := processJobWithObjects(context.Background(), fakeStateLoader{state: state, ok: true}, tt.objects, tt.job) + if err == nil || !strings.Contains(err.Error(), tt.want) { + t.Fatalf("err=%v want %q", err, tt.want) + } + if strings.Contains(err.Error(), "raw-secret-name") || strings.Contains(err.Error(), "backend leaked secret") { + t.Fatalf("error leaked payload details: %v", err) + } + }) + } +} + +func TestProcessJobWithObjectsRejectsOversizedPayload(t *testing.T) { + t.Setenv("EVYDENCE_WORKER_MAX_PAYLOAD_BYTES", "2") + body := []byte("large") + hash := digestBytes(body) + state := app.PersistedState{SBOMs: map[string]domain.SBOM{ + "sbom_test": {ID: "sbom_test", TenantID: "ten_test"}, + }} + job := postgres.ClaimedJob{ + TenantID: "ten_test", + Kind: "parse_sbom", + SubjectID: "sbom_test", + Payload: map[string]any{"payload_ref": "tenants/ten_test/payloads/sbom.json", "payload_hash": hash}, + } + object := app.Object{TenantID: "ten_test", Digest: hash, Bytes: body} + err := processJobWithObjects(context.Background(), fakeStateLoader{state: state, ok: true}, fakeObjectGetter{object: object}, job) + if err == nil || !strings.Contains(err.Error(), "size limit") { + t.Fatalf("err=%v", err) + } +} + func TestProcessJobFailsSafelyWhenDurableStateIsMissing(t *testing.T) { job := postgres.ClaimedJob{ ID: "job_test", diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 47faf65..46038ed 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -41,6 +41,8 @@ The example secrets are placeholders. Replace them before using shared or produc | `EVYDENCE_BOOTSTRAP_DISABLED` | No | unset | Set to `true` to prevent startup bootstrap on an empty store. | | `EVYDENCE_PRINT_BOOTSTRAP_SECRET` | Local only | `true` in `.api.env.example` | Prints the one-time bootstrap secret. Rejected when `ENV=production`. | | `EVYDENCE_WORKER_POLL_INTERVAL` | No | `1s` | Worker outbox polling interval. | +| `EVYDENCE_WORKER_BATCH_SIZE` | No | `10` | Maximum outbox jobs claimed per polling cycle. | +| `EVYDENCE_WORKER_MAX_PAYLOAD_BYTES` | No | `20971520` | Maximum raw object payload size replayed by a worker job. | | `EVYDENCE_SIGNING_KEY_MODE` | Production yes | `external` for production | Production rejects local plaintext signing-key mode. | | `EVYDENCE_TEST_DATABASE_URL` | Live tests | `.test.env.example` value | Used by `make live-postgres-check`, `make postgres-integration-test`, and `make release-check`. | diff --git a/docs/reference/worker-outbox.md b/docs/reference/worker-outbox.md index d66a9e4..147c424 100644 --- a/docs/reference/worker-outbox.md +++ b/docs/reference/worker-outbox.md @@ -12,7 +12,9 @@ Configured job kinds: - `verify_subject` - `verify_attestation` -Current behavior is intentionally conservative. The API performs parsing, signing, and verification synchronously before enqueueing jobs. The worker then validates that the expected durable state exists and, when a `payload_hash` is present, that the hash matches the recorded state. Missing state, incomplete verification, missing signatures, hash mismatch, uninitialized storage, and unsupported job kinds fail the job safely. +Current behavior is intentionally conservative. The API performs parsing, signing, and verification synchronously before enqueueing jobs. The worker then validates that tenant-prefixed payload objects can be read when `payload_ref` is present, verifies object metadata and byte digests when `payload_hash` is present, and validates that the expected durable state exists. Missing objects, wrong tenant prefixes, tenant mismatches, oversized payload objects, incomplete verification, missing signatures, hash mismatch, uninitialized storage, and unsupported job kinds fail the job safely. + +Workers use the same object-store environment variables as the API. The default worker payload replay limit is 20 MiB and can be adjusted with `EVYDENCE_WORKER_MAX_PAYLOAD_BYTES`. Safe logging rules: From b0a99734176dbbc847820cc6d9fe5affcb0ae2f9 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 17:40:41 +0300 Subject: [PATCH 040/287] ci: add live postgres release checks --- .github/workflows/ci.yml | 62 ++++++++++++++++++++++++++ docs/reference/production-readiness.md | 3 +- docs/reference/release-validation.md | 10 ++++- 3 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..20db497 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,62 @@ +name: CI + +on: + push: + branches: + - master + - main + pull_request: + workflow_dispatch: + +permissions: + contents: read + +jobs: + release-check: + name: Release Check + runs-on: ubuntu-latest + services: + postgres: + image: postgres:16-alpine + env: + POSTGRES_DB: evydence + POSTGRES_USER: evydence + POSTGRES_PASSWORD: change-me + ports: + - 5432:5432 + options: >- + --health-cmd "pg_isready -U evydence" + --health-interval 5s + --health-timeout 5s + --health-retries 20 + env: + EVYDENCE_API_KEY_PEPPER: ci-test-pepper + EVYDENCE_TEST_DATABASE_URL: postgres://evydence:change-me@localhost:5432/evydence?sslmode=disable + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version-file: go.mod + cache: true + + - name: Install QA tools + run: make tools + + - name: Run release check with live PostgreSQL + run: make release-check + + - name: Generate coverage report + run: make coverage + + - name: Upload release evidence artifacts + if: always() + uses: actions/upload-artifact@v4 + with: + name: evydence-ci-evidence + path: | + coverage.out + tmp/release-check-summary.txt + if-no-files-found: ignore diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 48ddcb5..b96d5ea 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -20,7 +20,8 @@ Known hardening work remains: parser side effects independently of the request path; - OpenAPI schemas need endpoint-specific precision across the full public API; - default coverage must reach the production threshold; -- GitHub CI must enforce live PostgreSQL and release evidence checks. +- GitHub CI enforces live PostgreSQL release checks; the 80 percent production + coverage threshold remains hardening work. ## Production Profiles diff --git a/docs/reference/release-validation.md b/docs/reference/release-validation.md index 9b95a75..d3f4b9d 100644 --- a/docs/reference/release-validation.md +++ b/docs/reference/release-validation.md @@ -77,4 +77,12 @@ If either line is skipped, the release evidence should state that durable-store ## CI Usage -CI should provide a disposable PostgreSQL service, set `EVYDENCE_TEST_DATABASE_URL`, run `make release-check`, and preserve `tmp/release-check-summary.txt` as a build artifact. The database should not contain production evidence, customer package tokens, signing-key material, or other real secrets. +The checked-in GitHub Actions workflow provides a disposable PostgreSQL service, +sets `EVYDENCE_TEST_DATABASE_URL`, runs `make release-check`, runs +`make coverage`, and preserves `tmp/release-check-summary.txt` plus +`coverage.out` as build artifacts. The database must not contain production +evidence, customer package tokens, signing-key material, or other real secrets. + +The workflow is release-evidence CI, not the final production-readiness gate. +`make production-check` remains the strict local/CI gate once coverage and the +remaining production-hardening tickets are complete. From a6cd72bba619a007f666e6e5ee9046dd2dfaf52a Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 17:51:48 +0300 Subject: [PATCH 041/287] test: isolate github actions env --- cmd/evydence/main_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmd/evydence/main_test.go b/cmd/evydence/main_test.go index 83bb47b..07d08f2 100644 --- a/cmd/evydence/main_test.go +++ b/cmd/evydence/main_test.go @@ -197,6 +197,10 @@ func TestVerifyAuditChainDetectsHashTampering(t *testing.T) { func TestGitHubActionsUploadBuildRequiresGitHubMetadata(t *testing.T) { t.Setenv("EVYDENCE_API_URL", "http://127.0.0.1") t.Setenv("EVYDENCE_API_KEY", "evy_secret") + t.Setenv("GITHUB_RUN_ID", "") + t.Setenv("GITHUB_SHA", "") + t.Setenv("GITHUB_REPOSITORY", "") + t.Setenv("GITHUB_WORKFLOW_REF", "") err := uploadGitHubActionsBuild(t.Context(), http.DefaultClient, []string{"--project-id", "proj_1", "--release-id", "rel_1"}) if err == nil || !strings.Contains(err.Error(), "GITHUB_RUN_ID") { t.Fatalf("err=%v, want missing GitHub metadata error", err) From c39a78f62e30334498e4db65585fba480a3753b8 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 17:55:44 +0300 Subject: [PATCH 042/287] chore: require patched go toolchain --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 5646298..3424eff 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/aatuh/evydence -go 1.25.0 +go 1.25.7 require ( github.com/aatuh/api-toolkit/v3 v3.1.2 From 40ca5ea0b1b0e5016a6eefcd9a0d53216f163f35 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 17:56:39 +0300 Subject: [PATCH 043/287] chore: raise go patch floor --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 3424eff..01534a1 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/aatuh/evydence -go 1.25.7 +go 1.25.10 require ( github.com/aatuh/api-toolkit/v3 v3.1.2 From 5a99a24bf6246cc3e7b136fb0f2296c4251dca0e Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 17:56:41 +0300 Subject: [PATCH 044/287] docs: add api contract precision matrix --- Makefile | 4 + docs/README.md | 1 + docs/reference/api-contract-matrix.md | 170 +++++++++++++++++++++++ internal/adapters/httpapi/router_test.go | 13 ++ scripts/openapi_contract_matrix.py | 135 ++++++++++++++++++ 5 files changed, 323 insertions(+) create mode 100644 docs/reference/api-contract-matrix.md create mode 100755 scripts/openapi_contract_matrix.py diff --git a/Makefile b/Makefile index f43c1a2..00f91db 100644 --- a/Makefile +++ b/Makefile @@ -89,6 +89,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @test -f docs/how-to/integrate-ci.md @test -f docs/how-to/install-and-operate.md @test -f docs/reference/configuration.md + @test -f docs/reference/api-contract-matrix.md @test -f docs/reference/openapi.md @test -f docs/reference/observability.md @test -f docs/reference/production-readiness.md @@ -112,6 +113,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod "release-signing.md" \ "production-hardening.md" \ "reference/configuration.md" \ + "reference/api-contract-matrix.md" \ "reference/openapi.md" \ "reference/observability.md" \ "reference/production-readiness.md" \ @@ -128,6 +130,8 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod grep -F "$$path" docs/README.md >/dev/null || { echo "docs/README.md missing link to $$path"; exit 1; }; \ done @python3 -c 'import json,re,sys; from pathlib import Path; spec=json.loads(Path("openapi.yaml").read_text()); doc=Path("docs/api.md").read_text(); openapi=set(spec["paths"]); catalog=set(re.findall(r"`(/v1/[^`]+)`", doc)); missing=sorted(openapi-catalog); extra=sorted(catalog-openapi); [print("docs/api.md missing OpenAPI path: "+p) for p in missing]; [print("docs/api.md lists non-OpenAPI path: "+p) for p in extra]; sys.exit(1 if missing or extra else 0)' + @scripts/openapi_contract_matrix.py > /tmp/evydence-api-contract-matrix.md + @cmp -s docs/reference/api-contract-matrix.md /tmp/evydence-api-contract-matrix.md @grep -F 'case "release"' cmd/evydence/main.go >/dev/null @grep -F 'case "import-bundle"' cmd/evydence/main.go >/dev/null @grep -F 'case "upload"' cmd/evydence/main.go >/dev/null diff --git a/docs/README.md b/docs/README.md index 94f08ce..9809b07 100644 --- a/docs/README.md +++ b/docs/README.md @@ -20,6 +20,7 @@ This documentation is organized by reader task. Implementation claims should be ## Reference - [Configuration](reference/configuration.md): canonical environment variables and the roles of `.env.example`, `.api.env.example`, and `.test.env.example`. +- [API contract matrix](reference/api-contract-matrix.md): generated route-by-route contract precision inventory for production hardening. - [OpenAPI contract](reference/openapi.md): generation, drift checks, and review tips for `openapi.yaml`. - [Observability](reference/observability.md): readiness, admin metrics, Prometheus rules, and dashboard starter assets. - [Production readiness](reference/production-readiness.md): self-hosted production profiles, production gates, and exit criteria. diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md new file mode 100644 index 0000000..c86426b --- /dev/null +++ b/docs/reference/api-contract-matrix.md @@ -0,0 +1,170 @@ +# API Contract Matrix + +This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. +It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. + +Generated from 160 operations: 8 precise, 152 broad. + +| Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| GET | /v1/admin/instance | instanceAdminSnapshot | Bearer | instance:admin | - | - | - | 200:application/json:DataEnvelope | broad | +| GET | /v1/api-keys | listAPIKeys | Bearer | admin | - | - | - | 200:unspecified | broad | +| POST | /v1/api-keys | createAPIKey | Bearer | admin | required | - | - | 201:unspecified | broad | +| POST | /v1/api-security-scans | uploadAPISecurityScan | Bearer | security:write | required | - | - | 201:unspecified | broad | +| POST | /v1/approvals | createApproval | Bearer | release:write | required | - | - | 201:unspecified | broad | +| POST | /v1/artifact-signatures | createArtifactSignature | Bearer | evidence:write | required | - | - | 201:unspecified | broad | +| GET | /v1/artifact-signatures/{id} | getArtifactSignature | Bearer | evidence:read | - | - | - | 200:unspecified | broad | +| POST | /v1/artifact-signatures/{id}/verify-cosign | verifyCosignSignature | Bearer | verify:read | required | - | - | 200:unspecified | broad | +| POST | /v1/artifacts | registerArtifact | Bearer | evidence:write | required | - | - | 201:unspecified | broad | +| GET | /v1/audit-chain/verify | verifyAuditChain | Bearer | verify:read | - | - | - | 200:unspecified | broad | +| GET | /v1/audit-log | listAuditLog | Bearer | admin | - | - | - | 200:unspecified | broad | +| POST | /v1/backup-manifests | generateBackupManifest | Bearer | admin | required | - | - | 201:unspecified | broad | +| GET | /v1/backup-manifests/{id}/verify | verifyBackupManifest | Bearer | verify:read | - | - | - | 200:unspecified | broad | +| POST | /v1/build-attestations/{id}/verify-signature | verifyBuildAttestationSignature | Bearer | verify:read | required | - | - | 200:unspecified | broad | +| POST | /v1/builds | createBuild | Bearer | build:write | required | - | - | 201:unspecified | broad | +| GET | /v1/builds/{id} | getBuild | Bearer | build:read | - | - | - | 200:unspecified | broad | +| POST | /v1/builds/{id}/attestations | uploadBuildAttestation | Bearer | build:write | required | - | - | 201:unspecified | broad | +| GET | /v1/collectors | listCollectors | Bearer | collector:read | - | - | - | 200:unspecified | broad | +| POST | /v1/collectors | createCollector | Bearer | collector:admin | required | - | - | 201:unspecified | broad | +| POST | /v1/collectors/github/source-snapshots | uploadGitHubSourceSnapshot | Bearer | source:write | required | - | - | 201:unspecified | broad | +| POST | /v1/collectors/gitlab/source-snapshots | uploadGitLabSourceSnapshot | Bearer | source:write | required | - | - | 201:unspecified | broad | +| GET | /v1/collectors/{id}/health | collectorHealthReport | Bearer | collector:read | - | - | - | 200:unspecified | broad | +| POST | /v1/collectors/{id}/releases | recordCollectorRelease | Bearer | collector:admin | required | - | - | 201:unspecified | broad | +| GET | /v1/commercial-collectors | listCommercialCollectors | Bearer | collector:read | - | - | - | 200:unspecified | broad | +| POST | /v1/commercial-collectors | createCommercialCollector | Bearer | collector:admin | required | - | - | 201:unspecified | broad | +| POST | /v1/container-images | registerContainerImage | Bearer | evidence:write | required | - | - | 201:unspecified | broad | +| GET | /v1/control-evidence | listControlEvidence | Bearer | controls:read | - | - | - | 200:unspecified | broad | +| GET | /v1/control-framework-template-packs | listControlFrameworkTemplatePacks | Bearer | controls:read | - | - | - | 200:unspecified | broad | +| POST | /v1/control-framework-template-packs/{slug}/install | installControlFrameworkTemplatePack | Bearer | controls:admin | required | - | - | 201:unspecified | broad | +| GET | /v1/control-frameworks | listControlFrameworks | Bearer | controls:read | - | - | - | 200:unspecified | broad | +| POST | /v1/control-frameworks | createControlFramework | Bearer | controls:admin | required | - | - | 201:unspecified | broad | +| POST | /v1/controls | createSecurityControl | Bearer | controls:admin | required | - | - | 201:unspecified | broad | +| GET | /v1/controls/{id} | getSecurityControl | Bearer | controls:read | - | - | - | 200:unspecified | broad | +| POST | /v1/controls/{id}/evidence | linkControlEvidence | Bearer | controls:write | required | - | - | 201:unspecified | broad | +| POST | /v1/custom-policies | createCustomPolicy | Bearer | policy:write | required | - | - | 201:unspecified | broad | +| POST | /v1/custom-policies/{id}/evaluate | evaluateCustomPolicy | Bearer | policy:read | required | - | - | 201:unspecified | broad | +| POST | /v1/customer-packages | createCustomerPackage | Bearer | package:write | required | - | - | 201:unspecified | broad | +| GET | /v1/customer-packages/{id} | getCustomerPackage | Bearer | package:read | - | - | - | 200:unspecified | broad | +| GET | /v1/customer-packages/{id}/download | downloadCustomerPackage | Bearer | package:read | - | path:id | - | 200:application/zip:string/binary | precise | +| POST | /v1/customer-portal/access | createCustomerPortalAccess | Bearer | package:write | required | - | application/json:CreateCustomerPortalAccessRequest | 201:application/json:CustomerPortalAccessCreateEnvelope | precise | +| POST | /v1/customer-portal/package | accessCustomerPortalPackage | public | - | not required | - | application/json:CustomerPortalPackageRequest | 200:application/json:DataEnvelope | broad | +| POST | /v1/customer-portal/package/download | downloadCustomerPortalPackage | public | - | not required | - | application/json:CustomerPortalPackageRequest | 200:application/zip:string/binary | precise | +| GET | /v1/deployments | listDeployments | Bearer | deployment:read | - | - | - | 200:unspecified | broad | +| POST | /v1/deployments | recordDeployment | Bearer | deployment:write | required | - | - | 201:unspecified | broad | +| GET | /v1/deployments/{id} | getDeployment | Bearer | deployment:read | - | - | - | 200:unspecified | broad | +| POST | /v1/dsse-trust-roots | createDSSETrustRoot | Bearer | keys:admin | required | - | - | 201:unspecified | broad | +| GET | /v1/environments | listDeploymentEnvironments | Bearer | deployment:read | - | - | - | 200:unspecified | broad | +| POST | /v1/environments | createDeploymentEnvironment | Bearer | deployment:write | required | - | - | 201:unspecified | broad | +| GET | /v1/evidence | listEvidence | Bearer | evidence:read | - | - | - | 200:unspecified | broad | +| POST | /v1/evidence | createEvidence | Bearer | evidence:write | required | - | application/json:CreateEvidenceRequest | 201:application/json:DataEnvelope | broad | +| POST | /v1/evidence-bundles | exportEvidenceBundle | Bearer | bundle:read | required | - | - | 201:unspecified | broad | +| POST | /v1/evidence-bundles/import | importEvidenceBundle | Bearer | bundle:write | required | - | - | 201:unspecified | broad | +| POST | /v1/evidence-graph-snapshots | createGraphSnapshot | Bearer | evidence:read | required | - | - | 201:unspecified | broad | +| POST | /v1/evidence-summaries | createEvidenceSummary | Bearer | report:read | required | - | - | 201:unspecified | broad | +| GET | /v1/evidence/search | searchEvidence | Bearer | evidence:read | - | query:cursor, query:limit, query:product_id, query:project_id, query:release_id, query:source, query:tag, query:type | - | 200:application/json:EvidenceSearchEnvelope | precise | +| GET | /v1/evidence/{id} | getEvidence | Bearer | evidence:read | - | - | - | 200:unspecified | broad | +| GET | /v1/evidence/{id}/lifecycle-events | listEvidenceLifecycleEvents | Bearer | evidence:read | - | - | - | 200:unspecified | broad | +| POST | /v1/evidence/{id}/lifecycle-events | recordEvidenceLifecycleEvent | Bearer | evidence:write | required | - | - | 201:unspecified | broad | +| POST | /v1/evidence/{id}/link | linkEvidence | Bearer | evidence:write | required | - | - | 201:unspecified | broad | +| POST | /v1/evidence/{id}/supersede | supersedeEvidence | Bearer | evidence:write | required | - | - | 201:unspecified | broad | +| GET | /v1/exceptions | listExceptions | Bearer | verify:read | - | - | - | 200:unspecified | broad | +| POST | /v1/exceptions | createException | Bearer | release:write | required | - | - | 201:unspecified | broad | +| POST | /v1/exceptions/{id}/approve | approveException | Bearer | release:write | required | - | - | 200:unspecified | broad | +| GET | /v1/health | health | public | - | - | - | - | 200:unspecified | broad | +| POST | /v1/incident-webhooks/{receiver_id} | receiveIncidentWebhook | public | - | not required | header:X-Evydence-Webhook-Event-ID, header:X-Evydence-Webhook-Signature, header:X-Evydence-Webhook-Timestamp, path:receiver_id | application/json:DataEnvelope | 201:application/json:DataEnvelope | broad | +| POST | /v1/incidents | createIncident | Bearer | incident:write | required | - | - | 201:unspecified | broad | +| POST | /v1/incidents/{id}/timeline | recordIncidentTimeline | Bearer | incident:write | required | - | - | 201:unspecified | broad | +| POST | /v1/incidents/{id}/webhook-receivers | createIncidentWebhookReceiver | Bearer | incident:write | required | path:id | application/json:DataEnvelope | 201:application/json:DataEnvelope | broad | +| POST | /v1/legal-holds | createLegalHold | Bearer | admin | required | - | - | 201:unspecified | broad | +| GET | /v1/marketplace-collectors | listMarketplaceCollectors | Bearer | collector:read | - | - | - | 200:unspecified | broad | +| POST | /v1/marketplace-collectors | createMarketplaceCollector | Bearer | collector:admin | required | - | - | 201:unspecified | broad | +| GET | /v1/marketplace-collectors/{id}/health | marketplaceCollectorHealth | Bearer | collector:read | - | - | - | 200:unspecified | broad | +| POST | /v1/merkle-batches | createMerkleBatch | Bearer | keys:admin | required | - | - | 201:unspecified | broad | +| GET | /v1/merkle-batches/{id}/verify | verifyMerkleBatch | Bearer | verify:read | - | - | - | 200:unspecified | broad | +| GET | /v1/metrics | metrics | Bearer | admin | - | - | - | 200:unspecified | broad | +| POST | /v1/object-retention-policies | createObjectRetentionPolicy | Bearer | admin | required | - | - | 201:unspecified | broad | +| POST | /v1/object-retention-policies/{id}/verify | verifyObjectRetentionPolicy | Bearer | verify:read | required | - | - | 200:unspecified | broad | +| POST | /v1/openapi-contracts | uploadOpenAPIContract | Bearer | evidence:write | required | - | - | 201:unspecified | broad | +| GET | /v1/openapi-contracts/{id} | getOpenAPIContract | Bearer | evidence:read | - | - | - | 200:unspecified | broad | +| POST | /v1/openapi-diffs | createOpenAPIDiff | Bearer | evidence:read | required | - | - | 201:unspecified | broad | +| GET | /v1/openapi.json | openapi | public | - | - | - | - | 200:unspecified | broad | +| POST | /v1/organizations | createOrganization | Bearer | identity:admin | required | - | - | 201:unspecified | broad | +| POST | /v1/policies/evaluate | evaluatePolicy | Bearer | verify:read | required | - | - | 201:unspecified | broad | +| GET | /v1/products | listProducts | Bearer | product:read | - | - | - | 200:unspecified | broad | +| POST | /v1/products | createProduct | Bearer | product:write | required | - | - | 201:unspecified | broad | +| POST | /v1/projects | createProject | Bearer | project:write | required | - | - | 201:unspecified | broad | +| POST | /v1/provider-verifications | verifyProviderIdentity | Bearer | identity:admin | required | - | application/json:VerifyProviderIdentityRequest | 201:application/json:ProviderVerificationEnvelope | precise | +| POST | /v1/public-transparency-log-entries | publishPublicTransparencyLogEntry | Bearer | keys:admin | required | - | - | 201:unspecified | broad | +| POST | /v1/public-transparency-logs | createPublicTransparencyLog | Bearer | keys:admin | required | - | - | 201:unspecified | broad | +| POST | /v1/questionnaire-drafts | createQuestionnaireDraft | Bearer | package:read | required | - | - | 201:unspecified | broad | +| POST | /v1/questionnaire-packages | createQuestionnairePackage | Bearer | package:write | required | - | - | 201:unspecified | broad | +| POST | /v1/questionnaire-templates | createQuestionnaireTemplate | Bearer | package:write | required | - | - | 201:unspecified | broad | +| GET | /v1/ready | ready | public | - | - | - | - | 200:unspecified | broad | +| POST | /v1/redaction-profiles | createRedactionProfile | Bearer | package:write | required | - | - | 201:unspecified | broad | +| POST | /v1/release-bundles | createReleaseBundle | Bearer | bundle:write | required | - | application/json:CreateReleaseBundleRequest | 201:application/json:DataEnvelope | broad | +| GET | /v1/release-bundles/{id} | getReleaseBundle | Bearer | bundle:read | - | - | - | 200:unspecified | broad | +| GET | /v1/release-bundles/{id}/manifest | getReleaseBundleManifest | Bearer | bundle:read | - | - | - | 200:unspecified | broad | +| GET | /v1/release-bundles/{id}/verify | verifyReleaseBundle | Bearer | verify:read | - | path:id | - | 200:application/json:ReleaseBundleVerificationEnvelope | precise | +| GET | /v1/release-candidates | listReleaseCandidates | Bearer | release:read | - | - | - | 200:unspecified | broad | +| POST | /v1/release-candidates | createReleaseCandidate | Bearer | release:write | required | - | - | 201:unspecified | broad | +| GET | /v1/release-candidates/{id} | getReleaseCandidate | Bearer | release:read | - | - | - | 200:unspecified | broad | +| POST | /v1/release-candidates/{id}/promote | promoteReleaseCandidate | Bearer | release:write | required | - | - | 200:unspecified | broad | +| POST | /v1/release-candidates/{id}/reject | rejectReleaseCandidate | Bearer | release:write | required | - | - | 200:unspecified | broad | +| POST | /v1/releases | createRelease | Bearer | release:write | required | - | - | 201:unspecified | broad | +| GET | /v1/releases/{id} | getRelease | Bearer | release:read | - | - | - | 200:unspecified | broad | +| POST | /v1/releases/{id}/approve | approveRelease | Bearer | release:write | required | - | - | 200:unspecified | broad | +| POST | /v1/releases/{id}/freeze | freezeRelease | Bearer | release:write | required | - | - | 200:unspecified | broad | +| POST | /v1/remediation-tasks | createRemediationTask | Bearer | incident:write | required | - | - | 201:unspecified | broad | +| POST | /v1/report-templates | createReportTemplate | Bearer | report:read | required | - | - | 201:unspecified | broad | +| POST | /v1/report-templates/{id}/render | renderReportTemplate | Bearer | report:read | required | - | - | 201:unspecified | broad | +| POST | /v1/reports/anomaly | generateAnomalyReport | Bearer | report:read | required | - | - | 201:unspecified | broad | +| GET | /v1/reports/control-coverage | controlCoverageReport | Bearer | report:read | - | - | - | 200:unspecified | broad | +| GET | /v1/reports/cra-readiness | craReadinessReport | Bearer | report:read | - | - | - | 200:unspecified | broad | +| GET | /v1/reports/cra-readiness-html | craReadinessHTMLPackage | Bearer | report:read | - | - | - | 200:unspecified | broad | +| GET | /v1/reports/incident-package | incidentReport | Bearer | incident:read | - | - | - | 200:unspecified | broad | +| GET | /v1/reports/missing-evidence | missingEvidenceReport | Bearer | verify:read | - | - | - | 200:unspecified | broad | +| POST | /v1/reports/pdf | createPDFReportPackage | Bearer | report:read | required | - | - | 201:unspecified | broad | +| GET | /v1/reports/release-readiness | releaseReadinessReport | Bearer | verify:read | - | - | - | 200:unspecified | broad | +| GET | /v1/reports/retention | retentionReport | Bearer | admin | - | - | - | 200:unspecified | broad | +| GET | /v1/reports/security-review-package | securityReviewPackageReport | Bearer | package:read | - | - | - | 200:unspecified | broad | +| GET | /v1/reports/vulnerability-posture | vulnerabilityPostureReport | Bearer | security:read | - | - | - | 200:unspecified | broad | +| POST | /v1/retention-overrides | createRetentionOverride | Bearer | admin | required | - | - | 201:unspecified | broad | +| GET | /v1/role-bindings | listRoleBindings | Bearer | identity:admin | - | - | - | 200:unspecified | broad | +| POST | /v1/role-bindings | createRoleBinding | Bearer | identity:admin | required | - | - | 201:unspecified | broad | +| POST | /v1/saas/profiles | createSaaSEditionProfile | Bearer | instance:admin | required | - | - | 201:unspecified | broad | +| GET | /v1/sbom-components | listSBOMComponents | Bearer | evidence:read | - | query:artifact_id, query:limit, query:purl, query:query, query:release_id, query:sbom_id | - | 200:application/json:DataEnvelope | broad | +| POST | /v1/sbom-diffs | createSBOMDiff | Bearer | evidence:read | required | - | - | 201:unspecified | broad | +| POST | /v1/sboms | uploadSBOM | Bearer | evidence:write | required | - | - | 201:unspecified | broad | +| POST | /v1/sboms/spdx | uploadSPDXSBOM | Bearer | evidence:write | required | - | - | 201:unspecified | broad | +| GET | /v1/sboms/{id} | getSBOM | Bearer | evidence:read | - | - | - | 200:unspecified | broad | +| POST | /v1/security-documents | uploadManualSecurityDocument | Bearer | security:write | required | - | - | 201:unspecified | broad | +| POST | /v1/security-scans | uploadSecurityScan | Bearer | security:write | required | - | - | 201:unspecified | broad | +| GET | /v1/signing-keys | listSigningKeys | Bearer | verify:read | - | - | - | 200:unspecified | broad | +| POST | /v1/signing-keys/rotate | rotateSigningKey | Bearer | keys:admin | required | - | - | 201:unspecified | broad | +| POST | /v1/signing-keys/{id}/revoke | revokeSigningKey | Bearer | keys:admin | required | - | - | 200:unspecified | broad | +| POST | /v1/signing-operations | createSigningOperation | Bearer | keys:admin | required | - | - | 201:unspecified | broad | +| POST | /v1/signing-providers | createSigningProvider | Bearer | keys:admin | required | - | - | 201:unspecified | broad | +| POST | /v1/source/branches | upsertSourceBranch | Bearer | source:write | required | - | - | 201:unspecified | broad | +| POST | /v1/source/commits | recordSourceCommit | Bearer | source:write | required | - | - | 201:unspecified | broad | +| POST | /v1/source/pull-requests | recordPullRequest | Bearer | source:write | required | - | - | 201:unspecified | broad | +| GET | /v1/source/repositories | listSourceRepositories | Bearer | source:read | - | - | - | 200:unspecified | broad | +| POST | /v1/source/repositories | createSourceRepository | Bearer | source:write | required | - | - | 201:unspecified | broad | +| POST | /v1/sso/identity-links | linkSSOIdentity | Bearer | identity:admin | required | - | - | 201:unspecified | broad | +| POST | /v1/sso/providers | createSSOProvider | Bearer | identity:admin | required | - | application/json:CreateSSOProviderRequest | 201:application/json:SSOProviderEnvelope | precise | +| POST | /v1/sso/sessions | createSSOSession | Bearer | identity:admin | required | - | application/json:CreateSSOSessionRequest | 201:application/json:SSOSessionCreateEnvelope | precise | +| POST | /v1/sso/sessions/{id}/revoke | revokeSSOSession | Bearer | identity:admin | required | - | - | 200:unspecified | broad | +| POST | /v1/transparency-checkpoints | createTransparencyCheckpoint | Bearer | keys:admin | required | - | - | 201:unspecified | broad | +| POST | /v1/users | createUser | Bearer | identity:admin | required | - | - | 201:unspecified | broad | +| POST | /v1/users/{id}/deactivate | deactivateUser | Bearer | identity:admin | required | - | - | 200:unspecified | broad | +| POST | /v1/verify | verify | Bearer | verify:read | required | - | - | 200:unspecified | broad | +| GET | /v1/version | version | public | - | - | - | - | 200:unspecified | broad | +| POST | /v1/vex | uploadVEX | Bearer | evidence:write | required | - | - | 201:unspecified | broad | +| POST | /v1/vex/cyclonedx | uploadCycloneDXVEX | Bearer | evidence:write | required | - | - | 201:unspecified | broad | +| GET | /v1/vex/{id} | getVEX | Bearer | evidence:read | - | - | - | 200:unspecified | broad | +| POST | /v1/vulnerability-findings/{id}/decisions | createVulnerabilityDecision | Bearer | evidence:write | required | - | - | 201:unspecified | broad | +| POST | /v1/vulnerability-findings/{id}/workflow | recordVulnerabilityWorkflow | Bearer | security:write | required | - | - | 201:unspecified | broad | +| POST | /v1/vulnerability-scans | uploadVulnerabilityScan | Bearer | evidence:write | required | - | - | 201:unspecified | broad | +| GET | /v1/vulnerability-scans/{id} | getVulnerabilityScan | Bearer | evidence:read | - | - | - | 200:unspecified | broad | +| POST | /v1/waivers | createWaiver | Bearer | policy:write | required | - | - | 201:unspecified | broad | +| POST | /v1/waivers/{id}/approve | approveWaiver | Bearer | policy:write | required | - | - | 200:unspecified | broad | + diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 77d8654..2f6cf8d 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -487,6 +487,7 @@ func TestCollectorBuildAttestationHTTPFlow(t *testing.T) { if attestationReplay != attestationBody { t.Fatalf("attestation idempotency replay changed response\nfirst=%s\nsecond=%s", attestationBody, attestationReplay) } + postJSON(t, server, secret, "/v1/build-attestations/"+dataField(t, attestationBody, "id")+"/verify-signature", "prov-attestation-verify", map[string]any{}, http.StatusBadRequest) postRaw(t, server, collectorSecret, "/v1/builds/"+buildID+"/attestations", "prov-bad-attestation", []byte(`{"payloadType":"application/vnd.in-toto+json","payload":"@@@","signatures":[{"sig":"abc"}]}`), http.StatusBadRequest) } @@ -537,6 +538,10 @@ func TestControlsAndReportsHTTPFlow(t *testing.T) { if replayed != frameworkBody { t.Fatalf("framework idempotency replay changed response\nfirst=%s\nsecond=%s", frameworkBody, replayed) } + frameworks := getJSON(t, server, secret, "/v1/control-frameworks", http.StatusOK) + if !strings.Contains(frameworks, frameworkID) { + t.Fatalf("framework list missing id %s: %s", frameworkID, frameworks) + } postJSON(t, server, secret, "/v1/control-frameworks", "ctrl-framework-conflict", map[string]any{"name": "Changed", "slug": "evydence-cra-readiness", "version": "2026.05"}, http.StatusConflict) controlBody := postJSON(t, server, secret, "/v1/controls", "ctrl-control", map[string]any{ "framework_id": frameworkID, @@ -613,8 +618,11 @@ func TestEvidenceLifecycleSourceDeploymentHTTPFlow(t *testing.T) { } rcBody := postJSON(t, server, secret, "/v1/release-candidates", "inc-rc", map[string]any{"release_id": releaseID, "name": "rc.1", "artifact_ids": []string{artifactID}}, http.StatusCreated) rcID := dataField(t, rcBody, "id") + getJSON(t, server, secret, "/v1/release-candidates/"+rcID, http.StatusOK) getJSON(t, server, secret, "/v1/release-candidates?release_id="+releaseID, http.StatusOK) postJSON(t, server, secret, "/v1/release-candidates/"+rcID+"/promote", "inc-rc-promote", map[string]any{"reason": "accepted"}, http.StatusOK) + rejectedRCBody := postJSON(t, server, secret, "/v1/release-candidates", "inc-rc-reject", map[string]any{"release_id": releaseID, "name": "rc.reject", "artifact_ids": []string{artifactID}}, http.StatusCreated) + postJSON(t, server, secret, "/v1/release-candidates/"+dataField(t, rejectedRCBody, "id")+"/reject", "inc-rc-reject-transition", map[string]any{"reason": "superseded"}, http.StatusOK) postJSON(t, server, secret, "/v1/container-images", "inc-image", map[string]any{"artifact_id": artifactID, "repository": "ghcr.io/example/api", "tag": "3.0.0", "digest": digest, "platform": "linux/amd64"}, http.StatusCreated) sigBody := postJSON(t, server, secret, "/v1/artifact-signatures", "inc-sig", map[string]any{"artifact_id": artifactID, "algorithm": "cosign", "key_id": "test", "signature": "c2ln", "payload": map[string]any{"sig": "c2ln"}}, http.StatusCreated) sigID := dataField(t, sigBody, "id") @@ -630,6 +638,10 @@ func TestEvidenceLifecycleSourceDeploymentHTTPFlow(t *testing.T) { envBody := postJSON(t, server, secret, "/v1/environments", "inc-env", map[string]any{"product_id": productID, "name": "production", "kind": "production"}, http.StatusCreated) envID := dataField(t, envBody, "id") + envs := getJSON(t, server, secret, "/v1/environments?product_id="+productID, http.StatusOK) + if !strings.Contains(envs, envID) { + t.Fatalf("environment list missing id %s: %s", envID, envs) + } deploymentBody := postJSON(t, server, secret, "/v1/deployments", "inc-deploy", map[string]any{"environment_id": envID, "release_id": releaseID, "artifact_ids": []string{artifactID}, "status": "succeeded", "started_at": "2026-05-28T12:00:00Z"}, http.StatusCreated) deploymentID := dataField(t, deploymentBody, "id") getJSON(t, server, secret, "/v1/deployments/"+deploymentID, http.StatusOK) @@ -812,6 +824,7 @@ func TestEnterprisePortalRetentionAndCommercialCollectorHTTPFlow(t *testing.T) { sessionID := dataFieldFromNestedObject(t, sessionBody, "session", "id") postJSON(t, server, secret, "/v1/sso/sessions/"+sessionID+"/revoke", "ent-session-revoke", map[string]any{}, http.StatusOK) getJSON(t, server, sessionSecret, "/v1/admin/instance", http.StatusUnauthorized) + postJSON(t, server, secret, "/v1/users/"+userID+"/deactivate", "ent-user-deactivate", map[string]any{}, http.StatusOK) } func TestFutureExtensionAndReadAdminHTTPGaps(t *testing.T) { diff --git a/scripts/openapi_contract_matrix.py b/scripts/openapi_contract_matrix.py new file mode 100755 index 0000000..df53f5c --- /dev/null +++ b/scripts/openapi_contract_matrix.py @@ -0,0 +1,135 @@ +#!/usr/bin/env python3 +"""Generate a deterministic public API contract precision matrix.""" + +from __future__ import annotations + +import json +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +OPENAPI = ROOT / "openapi.yaml" + + +def schema_label(media: dict) -> str: + schema = media.get("schema") or {} + ref = schema.get("$ref") + if ref: + return ref.rsplit("/", 1)[-1] + typ = schema.get("type") + fmt = schema.get("format") + if typ and fmt: + return f"{typ}/{fmt}" + if typ: + return str(typ) + return "generic" + + +def request_schema(operation: dict) -> str: + body = operation.get("requestBody") + if not body: + return "-" + content = body.get("content") or {} + if not content: + return "unspecified" + return ", ".join(f"{kind}:{schema_label(media)}" for kind, media in sorted(content.items())) + + +def response_schemas(operation: dict) -> str: + labels: list[str] = [] + for status, response in sorted((operation.get("responses") or {}).items()): + if not status.startswith("2"): + continue + content = response.get("content") or {} + if not content: + labels.append(f"{status}:unspecified") + continue + labels.append(f"{status}:" + ",".join(f"{kind}:{schema_label(media)}" for kind, media in sorted(content.items()))) + return "
".join(labels) if labels else "-" + + +def parameter_names(operation: dict) -> str: + params = operation.get("parameters") or [] + if not params: + return "-" + grouped = [f"{p.get('in', '?')}:{p.get('name', '?')}" for p in params] + return ", ".join(grouped) + + +def auth_label(operation: dict) -> str: + if "security" in operation and not operation.get("security"): + return "public" + if operation.get("security"): + return "Bearer" + return "public" + + +def idempotency_label(method: str, operation: dict) -> str: + if method.lower() != "post": + return "-" + if auth_label(operation) == "public": + return "not required" + return "required" + + +def scopes_label(operation: dict) -> str: + scopes = operation.get("x-scopes") or [] + return ", ".join(scopes) if scopes else "-" + + +def precision_label(operation: dict) -> str: + request = request_schema(operation) + response = response_schemas(operation) + broad_tokens = ("DataEnvelope", "generic", "unspecified") + if any(token in request or token in response for token in broad_tokens): + return "broad" + return "precise" + + +def esc(value: str) -> str: + return value.replace("|", "\\|") + + +def main() -> int: + spec = json.loads(OPENAPI.read_text()) + rows: list[tuple[str, str, str, str, str, str, str, str, str]] = [] + for path, path_item in sorted(spec["paths"].items()): + for method, operation in sorted(path_item.items()): + if method.lower() not in {"get", "post", "put", "patch", "delete"}: + continue + rows.append( + ( + method.upper(), + path, + operation.get("operationId", "-"), + auth_label(operation), + scopes_label(operation), + idempotency_label(method, operation), + parameter_names(operation), + request_schema(operation), + response_schemas(operation), + precision_label(operation), + ) + ) + + precise = sum(1 for row in rows if row[-1] == "precise") + broad = len(rows) - precise + lines = [ + "# API Contract Matrix", + "", + "This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`.", + "It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered.", + "", + f"Generated from {len(rows)} operations: {precise} precise, {broad} broad.", + "", + "| Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision |", + "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |", + ] + for row in rows: + lines.append("| " + " | ".join(esc(value) for value in row) + " |") + print("\n".join(lines) + "\n") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) From 21787de5bf51304a87d785f72c394f229d5f877c Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 17:56:56 +0300 Subject: [PATCH 045/287] test: enforce production coverage gate --- cmd/evydence-worker/main_test.go | 35 ++ internal/adapters/httpapi/router_test.go | 71 +++ internal/adapters/postgres/store_test.go | 23 + internal/app/context_cancellation_test.go | 704 ++++++++++++++++++++++ internal/app/ledger.go | 12 + internal/app/risk_workflows.go | 6 + internal/app/vex.go | 3 + scripts/production_check.sh | 18 +- 8 files changed, 863 insertions(+), 9 deletions(-) create mode 100644 internal/app/context_cancellation_test.go diff --git a/cmd/evydence-worker/main_test.go b/cmd/evydence-worker/main_test.go index a120edb..a23767a 100644 --- a/cmd/evydence-worker/main_test.go +++ b/cmd/evydence-worker/main_test.go @@ -3,6 +3,8 @@ package main import ( "context" "errors" + "os" + "path/filepath" "strings" "testing" "time" @@ -297,3 +299,36 @@ func TestRunRequiresDatabaseURLAndWrapsOpenFailure(t *testing.T) { t.Fatal("expected postgres open failure") } } + +func TestOpenObjectStoreSelectsFilesystemAndRejectsUnsupportedBackend(t *testing.T) { + root := t.TempDir() + t.Setenv("EVYDENCE_OBJECT_STORE", "filesystem") + t.Setenv("EVYDENCE_OBJECT_DIR", filepath.Join(root, "objects")) + store, description, err := openObjectStore(context.Background()) + if err != nil { + t.Fatalf("open filesystem object store: %v", err) + } + if store == nil || !strings.Contains(description, "filesystem root") || !strings.Contains(description, "objects") { + t.Fatalf("filesystem object store description=%q store=%T", description, store) + } + + t.Setenv("EVYDENCE_OBJECT_STORE", "memory") + if store, description, err := openObjectStore(context.Background()); err == nil || store != nil || description != "" || !strings.Contains(err.Error(), "unsupported") { + t.Fatalf("unsupported backend store=%T description=%q err=%v", store, description, err) + } +} + +func TestOpenObjectStoreRejectsIncompleteS3ConfigurationWithoutSecretsInError(t *testing.T) { + t.Setenv("EVYDENCE_OBJECT_STORE", "s3") + t.Setenv("EVYDENCE_S3_ENDPOINT", "") + t.Setenv("EVYDENCE_S3_ACCESS_KEY_ID", "access-key") + t.Setenv("EVYDENCE_S3_SECRET_ACCESS_KEY", "super-secret") + t.Setenv("EVYDENCE_S3_BUCKET", "") + _, _, err := openObjectStore(context.Background()) + if err == nil { + t.Fatal("expected incomplete S3 configuration to fail") + } + if strings.Contains(err.Error(), "super-secret") || strings.Contains(err.Error(), os.Getenv("EVYDENCE_S3_ACCESS_KEY_ID")) { + t.Fatalf("S3 configuration error leaked credential material: %v", err) + } +} diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 2f6cf8d..e69fbab 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -217,6 +217,77 @@ func TestCreateProductRequiresAuthAndIdempotency(t *testing.T) { } } +func TestAuthenticatedReadRoutesRejectMissingBearerToken(t *testing.T) { + server, _ := testServer(t) + paths := []string{ + "/v1/admin/instance", + "/v1/api-keys", + "/v1/artifact-signatures/sig_missing", + "/v1/audit-chain/verify", + "/v1/audit-log", + "/v1/backup-manifests/backup_missing/verify", + "/v1/builds/build_missing", + "/v1/collectors", + "/v1/collectors/collector_missing/health", + "/v1/commercial-collectors", + "/v1/control-evidence", + "/v1/control-framework-template-packs", + "/v1/control-frameworks", + "/v1/controls/control_missing", + "/v1/customer-packages/package_missing", + "/v1/customer-packages/package_missing/download", + "/v1/deployments", + "/v1/deployments/deployment_missing", + "/v1/environments", + "/v1/evidence", + "/v1/evidence/search", + "/v1/evidence/ev_missing", + "/v1/evidence/ev_missing/lifecycle-events", + "/v1/exceptions", + "/v1/marketplace-collectors", + "/v1/marketplace-collectors/collector_missing/health", + "/v1/openapi-contracts/contract_missing", + "/v1/products", + "/v1/release-bundles/bundle_missing", + "/v1/release-bundles/bundle_missing/manifest", + "/v1/release-bundles/bundle_missing/verify", + "/v1/release-candidates", + "/v1/release-candidates/rc_missing", + "/v1/releases/release_missing", + "/v1/reports/control-coverage", + "/v1/reports/cra-readiness", + "/v1/reports/cra-readiness-html", + "/v1/reports/incident-package", + "/v1/reports/missing-evidence", + "/v1/reports/retention", + "/v1/reports/security-review-package", + "/v1/reports/vulnerability-posture", + "/v1/role-bindings", + "/v1/sboms/sbom_missing", + "/v1/signing-keys", + "/v1/source/repositories", + "/v1/vex/vex_missing", + "/v1/vulnerability-scans/scan_missing", + } + for _, path := range paths { + t.Run(path, func(t *testing.T) { + rec := httptest.NewRecorder() + req := httptest.NewRequest(http.MethodGet, path, nil) + server.Handler().ServeHTTP(rec, req) + if rec.Code != http.StatusUnauthorized { + t.Fatalf("GET %s status=%d want 401 body=%s", path, rec.Code, rec.Body.String()) + } + var problem map[string]any + if err := json.Unmarshal(rec.Body.Bytes(), &problem); err != nil { + t.Fatalf("decode problem response: %v body=%s", err, rec.Body.String()) + } + if problem["detail"] != "unauthorized" || strings.Contains(asString(t, problem["detail"]), "missing") { + t.Fatalf("unauthorized detail should stay generic: %#v", problem) + } + }) + } +} + func TestUnknownJSONFieldReturnsProblem(t *testing.T) { server, secret := testServer(t) rec := httptest.NewRecorder() diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index ae2f15c..2a457f0 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -61,4 +61,27 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { if err := store.CompleteJob(ctx, jobs[0].ID); err != nil { t.Fatal(err) } + + retryJob := app.OutboxJob{ID: "job_retry_" + time.Now().Format("150405.000000000"), TenantID: "ten_test", Kind: "parse_sbom", SubjectType: "sbom", SubjectID: "sbom_test", CreatedAt: time.Now().UTC()} + if err := store.Enqueue(ctx, retryJob); err != nil { + t.Fatal(err) + } + if pending, err := store.CountPendingJobs(ctx); err != nil { + t.Fatal(err) + } else if pending == 0 { + t.Fatal("expected pending outbox job") + } + claimed, err := store.ClaimJobs(ctx, 0) + if err != nil { + t.Fatal(err) + } + if len(claimed) == 0 { + t.Fatal("expected retry job claim") + } + if err := store.FailJob(ctx, claimed[0].ID, context.Canceled); err != nil { + t.Fatal(err) + } + if _, err := store.Now(ctx); err != nil { + t.Fatal(err) + } } diff --git a/internal/app/context_cancellation_test.go b/internal/app/context_cancellation_test.go new file mode 100644 index 0000000..556f8ae --- /dev/null +++ b/internal/app/context_cancellation_test.go @@ -0,0 +1,704 @@ +package app + +import ( + "context" + "errors" + "testing" + + "github.com/aatuh/evydence/internal/domain" +) + +func TestLedgerOperationsHonorCanceledContextBeforeWork(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + actor := domain.Actor{TenantID: "ten_ctx", KeyID: "key_ctx", Scopes: []string{"*"}} + ctx, cancel := context.WithCancel(context.Background()) + cancel() + + checks := []struct { + name string + run func() error + }{ + {"BootstrapTenant", func() error { + _, _, _, err := ledger.BootstrapTenant(ctx, "Tenant", "admin", []string{"*"}) + return err + }}, + {"Authenticate", func() error { _, err := ledger.Authenticate(ctx, "secret"); return err }}, + {"CreateAPIKey", func() error { _, _, err := ledger.CreateAPIKey(ctx, actor, "key", []string{"*"}, nil); return err }}, + {"ListAPIKeys", func() error { _, err := ledger.ListAPIKeys(ctx, actor); return err }}, + {"CreateProduct", func() error { _, err := ledger.CreateProduct(ctx, actor, "Product", "product"); return err }}, + {"ListProducts", func() error { _, err := ledger.ListProducts(ctx, actor); return err }}, + {"CreateProject", func() error { _, err := ledger.CreateProject(ctx, actor, "prod", "api"); return err }}, + {"CreateRelease", func() error { _, err := ledger.CreateRelease(ctx, actor, "prod", "1.0.0"); return err }}, + {"GetRelease", func() error { _, err := ledger.GetRelease(ctx, actor, "rel"); return err }}, + {"FreezeRelease", func() error { _, err := ledger.FreezeRelease(ctx, actor, "rel"); return err }}, + {"ApproveRelease", func() error { _, err := ledger.ApproveRelease(ctx, actor, "rel"); return err }}, + {"RegisterArtifact", func() error { + _, err := ledger.RegisterArtifact(ctx, actor, "artifact", "application/octet-stream", sampleDigest("artifact"), 1) + return err + }}, + {"CreateEvidence", func() error { + _, err := ledger.CreateEvidence(ctx, actor, CreateEvidenceInput{Type: "build", Title: "Build"}) + return err + }}, + {"GetEvidence", func() error { _, err := ledger.GetEvidence(ctx, actor, "ev"); return err }}, + {"ListEvidence", func() error { _, err := ledger.ListEvidence(ctx, actor, "", ""); return err }}, + {"SupersedeEvidence", func() error { _, err := ledger.SupersedeEvidence(ctx, actor, "ev", "ev2", "reason"); return err }}, + {"LinkEvidence", func() error { _, err := ledger.LinkEvidence(ctx, actor, "ev", "release", "rel"); return err }}, + {"UploadSBOM", func() error { _, err := ledger.UploadSBOM(ctx, actor, "rel", "art", []byte(`{}`)); return err }}, + {"UploadVulnerabilityScan", func() error { _, err := ledger.UploadVulnerabilityScan(ctx, actor, []byte(`{}`)); return err }}, + {"UploadOpenAPIContract", func() error { + _, err := ledger.UploadOpenAPIContract(ctx, actor, "prod", "rel", "v1", []byte(`{}`)) + return err + }}, + {"EvaluateRelease", func() error { _, err := ledger.EvaluateRelease(ctx, actor, "rel"); return err }}, + {"CreateReleaseBundle", func() error { _, err := ledger.CreateReleaseBundle(ctx, actor, "rel"); return err }}, + {"GetReleaseBundle", func() error { _, err := ledger.GetReleaseBundle(ctx, actor, "bundle"); return err }}, + {"GetSBOM", func() error { _, err := ledger.GetSBOM(ctx, actor, "sbom"); return err }}, + {"ListSBOMComponents", func() error { _, err := ledger.ListSBOMComponents(ctx, actor, ListSBOMComponentsInput{}); return err }}, + {"GetVulnerabilityScan", func() error { _, err := ledger.GetVulnerabilityScan(ctx, actor, "scan"); return err }}, + {"GetOpenAPIContract", func() error { _, err := ledger.GetOpenAPIContract(ctx, actor, "contract"); return err }}, + {"VerifySubject", func() error { _, err := ledger.VerifySubject(ctx, actor, "audit_chain", ""); return err }}, + {"RotateSigningKey", func() error { _, err := ledger.RotateSigningKey(ctx, actor, "reason"); return err }}, + {"ListSigningKeys", func() error { _, err := ledger.ListSigningKeys(ctx, actor); return err }}, + {"MissingEvidenceReport", func() error { _, err := ledger.MissingEvidenceReport(ctx, actor, "rel"); return err }}, + {"SearchEvidence", func() error { _, err := ledger.SearchEvidence(ctx, actor, EvidenceSearchInput{}); return err }}, + {"RecordEvidenceLifecycleEvent", func() error { + _, err := ledger.RecordEvidenceLifecycleEvent(ctx, actor, "ev", RecordEvidenceLifecycleInput{Action: "amendment", Reason: "reason"}) + return err + }}, + {"ListEvidenceLifecycleEvents", func() error { _, err := ledger.ListEvidenceLifecycleEvents(ctx, actor, "ev"); return err }}, + {"CreateReleaseCandidate", func() error { + _, err := ledger.CreateReleaseCandidate(ctx, actor, CreateReleaseCandidateInput{ReleaseID: "rel", Name: "rc"}) + return err + }}, + {"GetReleaseCandidate", func() error { _, err := ledger.GetReleaseCandidate(ctx, actor, "rc"); return err }}, + {"ListReleaseCandidates", func() error { _, err := ledger.ListReleaseCandidates(ctx, actor, "rel"); return err }}, + {"UpdateReleaseCandidateState", func() error { + _, err := ledger.UpdateReleaseCandidateState(ctx, actor, "rc", "promoted", "reason") + return err + }}, + {"RegisterContainerImage", func() error { + _, err := ledger.RegisterContainerImage(ctx, actor, RegisterContainerImageInput{ArtifactID: "art", Repository: "repo", Digest: sampleDigest("image")}) + return err + }}, + {"CreateArtifactSignature", func() error { + _, err := ledger.CreateArtifactSignature(ctx, actor, CreateArtifactSignatureInput{ArtifactID: "art", Algorithm: "cosign", Signature: "sig"}) + return err + }}, + {"GetArtifactSignature", func() error { _, err := ledger.GetArtifactSignature(ctx, actor, "sig"); return err }}, + {"CreateSourceRepository", func() error { + _, err := ledger.CreateSourceRepository(ctx, actor, CreateRepositoryInput{ProjectID: "proj", Provider: "github", FullName: "owner/repo"}) + return err + }}, + {"ListSourceRepositories", func() error { _, err := ledger.ListSourceRepositories(ctx, actor, "proj"); return err }}, + {"RecordSourceCommit", func() error { + _, err := ledger.RecordSourceCommit(ctx, actor, RecordCommitInput{RepositoryID: "repo", SHA: "0123456789abcdef0123456789abcdef01234567"}) + return err + }}, + {"UpsertSourceBranch", func() error { + _, err := ledger.UpsertSourceBranch(ctx, actor, UpsertBranchInput{RepositoryID: "repo", Name: "main"}) + return err + }}, + {"RecordPullRequest", func() error { + _, err := ledger.RecordPullRequest(ctx, actor, RecordPullRequestInput{RepositoryID: "repo", ProviderID: "1", Title: "PR", State: "open"}) + return err + }}, + {"UploadGitHubSourceSnapshot", func() error { _, err := ledger.UploadGitHubSourceSnapshot(ctx, actor, []byte(`{}`)); return err }}, + {"UploadGitLabSourceSnapshot", func() error { _, err := ledger.UploadGitLabSourceSnapshot(ctx, actor, []byte(`{}`)); return err }}, + {"CreateDeploymentEnvironment", func() error { + _, err := ledger.CreateDeploymentEnvironment(ctx, actor, CreateEnvironmentInput{ProductID: "prod", Name: "prod", Kind: "production"}) + return err + }}, + {"ListDeploymentEnvironments", func() error { _, err := ledger.ListDeploymentEnvironments(ctx, actor, "prod"); return err }}, + {"RecordDeployment", func() error { + _, err := ledger.RecordDeployment(ctx, actor, RecordDeploymentInput{EnvironmentID: "env", ReleaseID: "rel", Status: "started"}) + return err + }}, + {"GetDeployment", func() error { _, err := ledger.GetDeployment(ctx, actor, "dep"); return err }}, + {"ListDeployments", func() error { _, err := ledger.ListDeployments(ctx, actor, "rel", "env"); return err }}, + {"UploadVEX", func() error { _, err := ledger.UploadVEX(ctx, actor, "rel", "art", []byte(`{}`)); return err }}, + {"GetVEXDocument", func() error { _, err := ledger.GetVEXDocument(ctx, actor, "vex"); return err }}, + {"CreateVulnerabilityDecision", func() error { + _, err := ledger.CreateVulnerabilityDecision(ctx, actor, "finding", CreateVulnerabilityDecisionInput{Status: "fixed", Justification: "fixed"}) + return err + }}, + {"CreateException", func() error { _, err := ledger.CreateException(ctx, actor, CreateExceptionInput{}); return err }}, + {"ListExceptions", func() error { _, err := ledger.ListExceptions(ctx, actor, "rel"); return err }}, + {"ApproveException", func() error { _, err := ledger.ApproveException(ctx, actor, "ex"); return err }}, + {"ReleaseReadinessReport", func() error { _, err := ledger.ReleaseReadinessReport(ctx, actor, "rel"); return err }}, + {"CreateControlFramework", func() error { + _, err := ledger.CreateControlFramework(ctx, actor, CreateControlFrameworkInput{Name: "Framework", Version: "1"}) + return err + }}, + {"ListControlFrameworks", func() error { _, err := ledger.ListControlFrameworks(ctx, actor); return err }}, + {"CreateSecurityControl", func() error { + _, err := ledger.CreateSecurityControl(ctx, actor, CreateSecurityControlInput{FrameworkID: "fw", Code: "C", Title: "Control", Objective: "Objective"}) + return err + }}, + {"GetSecurityControl", func() error { _, err := ledger.GetSecurityControl(ctx, actor, "ctrl"); return err }}, + {"LinkControlEvidence", func() error { + _, err := ledger.LinkControlEvidence(ctx, actor, "ctrl", LinkControlEvidenceInput{EvidenceType: "sbom", SubjectType: "sbom", SubjectID: "sbom"}) + return err + }}, + {"ListControlEvidence", func() error { _, err := ledger.ListControlEvidence(ctx, actor, "ctrl", "prod", "rel"); return err }}, + {"ControlCoverageReport", func() error { + _, err := ledger.ControlCoverageReport(ctx, actor, ControlCoverageReportInput{FrameworkID: "fw"}) + return err + }}, + {"CRAReadinessReport", func() error { + _, err := ledger.CRAReadinessReport(ctx, actor, CRAReadinessReportInput{ProductID: "prod", ReleaseID: "rel"}) + return err + }}, + {"CreateCollector", func() error { + _, _, _, err := ledger.CreateCollector(ctx, actor, CreateCollectorInput{Name: "collector", Type: "github_actions", Version: "1"}) + return err + }}, + {"ListCollectors", func() error { _, err := ledger.ListCollectors(ctx, actor); return err }}, + {"RecordCollectorRelease", func() error { + _, err := ledger.RecordCollectorRelease(ctx, actor, RecordCollectorReleaseInput{CollectorID: "collector", Version: "1", ArtifactDigest: sampleDigest("collector")}) + return err + }}, + {"CollectorHealthReport", func() error { _, err := ledger.CollectorHealthReport(ctx, actor, "collector"); return err }}, + {"CreateBuildRun", func() error { + _, err := ledger.CreateBuildRun(ctx, actor, CreateBuildRunInput{ProjectID: "proj", ReleaseID: "rel", Provider: "generic_ci", CommitSHA: "0123456789abcdef0123456789abcdef01234567", Status: "passed", StartedAt: fixedNow()}) + return err + }}, + {"GetBuildRun", func() error { _, err := ledger.GetBuildRun(ctx, actor, "build"); return err }}, + {"UploadBuildAttestation", func() error { _, err := ledger.UploadBuildAttestation(ctx, actor, "build", []byte(`{}`)); return err }}, + {"CreateWaiver", func() error { _, err := ledger.CreateWaiver(ctx, actor, CreateWaiverInput{}); return err }}, + {"ApproveWaiver", func() error { _, err := ledger.ApproveWaiver(ctx, actor, "waiver"); return err }}, + {"CreateApprovalRecord", func() error { _, err := ledger.CreateApprovalRecord(ctx, actor, CreateApprovalInput{}); return err }}, + {"CreateRedactionProfile", func() error { + _, err := ledger.CreateRedactionProfile(ctx, actor, CreateRedactionProfileInput{Name: "profile"}) + return err + }}, + {"CreateCustomerSecurityPackage", func() error { + _, err := ledger.CreateCustomerSecurityPackage(ctx, actor, CreateCustomerPackageInput{}) + return err + }}, + {"AccessCustomerSecurityPackage", func() error { _, err := ledger.AccessCustomerSecurityPackage(ctx, actor, "pkg"); return err }}, + {"ExportCustomerSecurityPackageArchive", func() error { _, err := ledger.ExportCustomerSecurityPackageArchive(ctx, actor, "pkg"); return err }}, + {"ExportCustomerPortalPackageArchive", func() error { _, err := ledger.ExportCustomerPortalPackageArchive(ctx, "token"); return err }}, + {"SecurityReviewPackageReport", func() error { _, err := ledger.SecurityReviewPackageReport(ctx, actor, "pkg"); return err }}, + {"CRAReadinessHTMLPackage", func() error { _, err := ledger.CRAReadinessHTMLPackage(ctx, actor, "prod", "rel"); return err }}, + {"ListControlFrameworkTemplatePacks", func() error { _, err := ledger.ListControlFrameworkTemplatePacks(ctx, actor); return err }}, + {"InstallControlFrameworkTemplatePack", func() error { + _, err := ledger.InstallControlFrameworkTemplatePack(ctx, actor, "evydence-cra-readiness") + return err + }}, + {"CreateCustomReportTemplate", func() error { + _, err := ledger.CreateCustomReportTemplate(ctx, actor, CreateReportTemplateInput{Name: "template", Version: "1", ReportType: "summary", Template: "json"}) + return err + }}, + {"RenderCustomReport", func() error { + _, err := ledger.RenderCustomReport(ctx, actor, RenderReportInput{TemplateID: "template", SubjectType: "release", SubjectID: "rel"}) + return err + }}, + {"ExportEvidenceBundle", func() error { _, err := ledger.ExportEvidenceBundle(ctx, actor, "rel", nil); return err }}, + {"ImportEvidenceBundle", func() error { _, err := ledger.ImportEvidenceBundle(ctx, actor, domain.EvidenceBundle{}); return err }}, + {"CreateDSSETrustRoot", func() error { + _, err := ledger.CreateDSSETrustRoot(ctx, actor, CreateDSSETrustRootInput{Name: "root", KeyID: "root", Algorithm: "Ed25519", PublicKey: "pub"}) + return err + }}, + {"VerifyDSSEAttestationSignature", func() error { _, err := ledger.VerifyDSSEAttestationSignature(ctx, actor, "att"); return err }}, + {"CreateIncident", func() error { + _, err := ledger.CreateIncident(ctx, actor, CreateIncidentInput{ProductID: "prod", Title: "incident", Severity: "high"}) + return err + }}, + {"RecordIncidentTimelineEvent", func() error { + _, err := ledger.RecordIncidentTimelineEvent(ctx, actor, "inc", RecordIncidentTimelineInput{EventType: "detected", Summary: "summary"}) + return err + }}, + {"CreateIncidentWebhookReceiver", func() error { + _, err := ledger.CreateIncidentWebhookReceiver(ctx, actor, CreateIncidentWebhookReceiverInput{IncidentID: "inc", Name: "receiver", Provider: "generic", PublicKey: "pub"}) + return err + }}, + {"HandleIncidentWebhook", func() error { _, _, err := ledger.HandleIncidentWebhook(ctx, HandleIncidentWebhookInput{}); return err }}, + {"CreateRemediationTask", func() error { + _, err := ledger.CreateRemediationTask(ctx, actor, CreateRemediationTaskInput{IncidentID: "inc", Title: "task", Owner: "security"}) + return err + }}, + {"IncidentReport", func() error { _, err := ledger.IncidentReport(ctx, actor, "inc"); return err }}, + {"UploadSecurityScan", func() error { _, err := ledger.UploadSecurityScan(ctx, actor, UploadSecurityScanInput{}); return err }}, + {"UploadAPISecurityScan", func() error { + _, err := ledger.UploadAPISecurityScan(ctx, actor, UploadSecurityScanInput{}) + return err + }}, + {"UploadManualSecurityDocument", func() error { + _, err := ledger.UploadManualSecurityDocument(ctx, actor, UploadManualSecurityDocumentInput{}) + return err + }}, + {"UploadSPDXSBOM", func() error { _, err := ledger.UploadSPDXSBOM(ctx, actor, "rel", "art", []byte(`{}`)); return err }}, + {"CreateSBOMDiff", func() error { _, err := ledger.CreateSBOMDiff(ctx, actor, CreateSBOMDiffInput{}); return err }}, + {"UploadCycloneDXVEX", func() error { _, err := ledger.UploadCycloneDXVEX(ctx, actor, "rel", "art", []byte(`{}`)); return err }}, + {"RecordVulnerabilityWorkflow", func() error { + _, err := ledger.RecordVulnerabilityWorkflow(ctx, actor, RecordVulnerabilityWorkflowInput{}) + return err + }}, + {"VulnerabilityPostureReport", func() error { _, err := ledger.VulnerabilityPostureReport(ctx, actor, "rel"); return err }}, + {"CreateContractDiff", func() error { _, err := ledger.CreateContractDiff(ctx, actor, CreateContractDiffInput{}); return err }}, + {"CreateCustomPolicy", func() error { _, err := ledger.CreateCustomPolicy(ctx, actor, CreateCustomPolicyInput{}); return err }}, + {"EvaluateCustomPolicy", func() error { _, err := ledger.EvaluateCustomPolicy(ctx, actor, "policy", "rel"); return err }}, + {"CreateOrganization", func() error { + _, err := ledger.CreateOrganization(ctx, actor, CreateOrganizationInput{Name: "Org", Slug: "org"}) + return err + }}, + {"CreateUser", func() error { + _, err := ledger.CreateUser(ctx, actor, CreateUserInput{OrganizationID: "org", Email: "user@example.test"}) + return err + }}, + {"DeactivateUser", func() error { _, err := ledger.DeactivateUser(ctx, actor, "user"); return err }}, + {"CreateRoleBinding", func() error { + _, err := ledger.CreateRoleBinding(ctx, actor, CreateRoleBindingInput{SubjectType: "user", SubjectID: "user", Role: "tenant_admin", ResourceType: "tenant"}) + return err + }}, + {"ListRoleBindings", func() error { _, err := ledger.ListRoleBindings(ctx, actor); return err }}, + {"CreateSSOProvider", func() error { + _, err := ledger.CreateSSOProvider(ctx, actor, CreateSSOProviderInput{Name: "OIDC", Type: "oidc", Issuer: "https://idp.example.test", ClientID: "client"}) + return err + }}, + {"LinkSSOIdentity", func() error { + _, err := ledger.LinkSSOIdentity(ctx, actor, LinkSSOIdentityInput{UserID: "user", ProviderID: "provider", Subject: "sub", Email: "user@example.test"}) + return err + }}, + {"CreateSSOSession", func() error { + _, _, err := ledger.CreateSSOSession(ctx, actor, CreateSSOSessionInput{UserID: "user", ProviderID: "provider", ExpiresAt: fixedNow().AddDate(0, 0, 1)}) + return err + }}, + {"RevokeSSOSession", func() error { _, err := ledger.RevokeSSOSession(ctx, actor, "session"); return err }}, + {"InstanceAdminSnapshot", func() error { _, err := ledger.InstanceAdminSnapshot(ctx, actor); return err }}, + {"CreateLegalHold", func() error { + _, err := ledger.CreateLegalHold(ctx, actor, CreateLegalHoldInput{ScopeType: "release", ScopeID: "rel", Reason: "review", Owner: "legal"}) + return err + }}, + {"CreateRetentionOverride", func() error { + _, err := ledger.CreateRetentionOverride(ctx, actor, CreateRetentionOverrideInput{ScopeType: "release", ScopeID: "rel", RetentionUntil: fixedNow().AddDate(1, 0, 0), Reason: "review", Owner: "legal"}) + return err + }}, + {"RetentionReport", func() error { _, err := ledger.RetentionReport(ctx, actor, "release", "rel"); return err }}, + {"CreateCustomerPortalAccess", func() error { + _, _, err := ledger.CreateCustomerPortalAccess(ctx, actor, CreateCustomerPortalAccessInput{PackageID: "pkg", CustomerName: "ACME", ExpiresAt: fixedNow().AddDate(0, 0, 1)}) + return err + }}, + {"AccessCustomerPortalPackage", func() error { _, err := ledger.AccessCustomerPortalPackage(ctx, "token"); return err }}, + {"CreateQuestionnaireTemplate", func() error { + _, err := ledger.CreateQuestionnaireTemplate(ctx, actor, CreateQuestionnaireTemplateInput{Name: "template", Version: "1"}) + return err + }}, + {"CreateQuestionnairePackage", func() error { + _, err := ledger.CreateQuestionnairePackage(ctx, actor, CreateQuestionnairePackageInput{TemplateID: "template", PackageID: "pkg", ProductID: "prod", ReleaseID: "rel"}) + return err + }}, + {"CreateCommercialCollectorDefinition", func() error { + _, err := ledger.CreateCommercialCollectorDefinition(ctx, actor, CreateCommercialCollectorInput{Name: "collector", Provider: "jira", Version: "1", ManifestHash: sampleDigest("collector")}) + return err + }}, + {"ListCommercialCollectorDefinitions", func() error { _, err := ledger.ListCommercialCollectorDefinitions(ctx, actor); return err }}, + {"CreateEvidenceSummary", func() error { + _, err := ledger.CreateEvidenceSummary(ctx, actor, CreateEvidenceSummaryInput{SubjectType: "release", SubjectID: "rel"}) + return err + }}, + {"CreateQuestionnaireDraft", func() error { + _, err := ledger.CreateQuestionnaireDraft(ctx, actor, CreateQuestionnaireDraftInput{TemplateID: "template", ProductID: "prod", ReleaseID: "rel"}) + return err + }}, + {"CreateGraphSnapshot", func() error { + _, err := ledger.CreateGraphSnapshot(ctx, actor, CreateGraphSnapshotInput{ProductID: "prod", ReleaseID: "rel"}) + return err + }}, + {"CreateSaaSEditionProfile", func() error { + _, err := ledger.CreateSaaSEditionProfile(ctx, actor, CreateSaaSEditionProfileInput{Name: "profile", Region: "eu", AdminTenantID: "ten", IsolationModel: "self-hosted"}) + return err + }}, + {"CreatePublicTransparencyLog", func() error { + _, err := ledger.CreatePublicTransparencyLog(ctx, actor, CreatePublicTransparencyLogInput{Name: "log", Endpoint: "https://log.example.test", PublicKey: "pub"}) + return err + }}, + {"PublishPublicTransparencyLogEntry", func() error { + _, err := ledger.PublishPublicTransparencyLogEntry(ctx, actor, PublishPublicTransparencyLogEntryInput{LogID: "log", CheckpointID: "checkpoint", ExternalID: "entry"}) + return err + }}, + {"CreateMarketplaceCollector", func() error { + _, err := ledger.CreateMarketplaceCollector(ctx, actor, CreateMarketplaceCollectorInput{Name: "collector", Provider: "scanner", Version: "1", Publisher: "vendor", ManifestHash: sampleDigest("collector")}) + return err + }}, + {"ListMarketplaceCollectors", func() error { _, err := ledger.ListMarketplaceCollectors(ctx, actor); return err }}, + {"MarketplaceCollectorHealth", func() error { _, err := ledger.MarketplaceCollectorHealth(ctx, actor, "collector"); return err }}, + {"CreatePDFReportPackage", func() error { + _, err := ledger.CreatePDFReportPackage(ctx, actor, CreatePDFReportPackageInput{ReportType: "release_readiness", ProductID: "prod", ReleaseID: "rel", Title: "Report"}) + return err + }}, + {"GenerateAnomalyReport", func() error { + _, err := ledger.GenerateAnomalyReport(ctx, actor, AnomalyReportInput{SubjectType: "release", SubjectID: "rel"}) + return err + }}, + {"CreateSigningOperation", func() error { + _, err := ledger.CreateSigningOperation(ctx, actor, CreateSigningOperationInput{ProviderID: "provider", SubjectType: "release", SubjectID: "rel", PayloadHash: sampleDigest("payload"), ExternalSignature: "sig"}) + return err + }}, + {"VerifyProviderIdentity", func() error { + _, err := ledger.VerifyProviderIdentity(ctx, actor, VerifyProviderIdentityInput{ProviderType: "oidc", ProviderID: "provider", Subject: "sub"}) + return err + }}, + {"VerifyCosignSignature", func() error { + _, err := ledger.VerifyCosignSignature(ctx, actor, VerifyCosignInput{ArtifactSignatureID: "sig"}) + return err + }}, + {"RevokeSigningKey", func() error { _, err := ledger.RevokeSigningKey(ctx, actor, "key", "reason"); return err }}, + {"CreateSigningProvider", func() error { + _, err := ledger.CreateSigningProvider(ctx, actor, CreateSigningProviderInput{Name: "kms", Type: "aws_kms", KeyRef: "arn:aws:kms:example", Encrypted: true}) + return err + }}, + {"CreateMerkleBatch", func() error { + _, err := ledger.CreateMerkleBatch(ctx, actor, CreateMerkleBatchInput{FromSequence: 1, ToSequence: 1}) + return err + }}, + {"VerifyMerkleBatch", func() error { _, err := ledger.VerifyMerkleBatch(ctx, actor, "batch"); return err }}, + {"CreateTransparencyCheckpoint", func() error { + _, err := ledger.CreateTransparencyCheckpoint(ctx, actor, CreateTransparencyCheckpointInput{BatchID: "batch", Provider: "internal", ExternalID: "checkpoint"}) + return err + }}, + {"CreateObjectRetentionPolicy", func() error { + _, err := ledger.CreateObjectRetentionPolicy(ctx, actor, CreateObjectRetentionPolicyInput{Name: "policy", ObjectPrefix: "tenants/ten/", Mode: "governance", RetentionDays: 30}) + return err + }}, + {"VerifyObjectRetentionPolicy", func() error { _, err := ledger.VerifyObjectRetentionPolicy(ctx, actor, "policy"); return err }}, + {"GenerateBackupManifest", func() error { _, err := ledger.GenerateBackupManifest(ctx, actor); return err }}, + {"VerifyBackupManifest", func() error { _, err := ledger.VerifyBackupManifest(ctx, actor, "backup"); return err }}, + {"ReadinessStatus", func() error { _, err := ledger.ReadinessStatus(ctx); return err }}, + {"Metrics", func() error { _, err := ledger.Metrics(ctx, actor); return err }}, + {"ListAuditLog", func() error { _, err := ledger.ListAuditLog(ctx, actor, AuditLogFilter{}); return err }}, + } + + for _, check := range checks { + t.Run(check.name, func(t *testing.T) { + if err := check.run(); !errors.Is(err, context.Canceled) { + t.Fatalf("err=%v, want context.Canceled", err) + } + }) + } +} + +func TestLedgerOperationsRejectActorsWithoutRequiredScopesBeforeResourceWork(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + actor := domain.Actor{TenantID: "ten_scope", KeyID: "key_scope"} + ctx := context.Background() + + checks := []struct { + name string + run func() error + }{ + {"CreateAPIKey", func() error { _, _, err := ledger.CreateAPIKey(ctx, actor, "key", []string{"*"}, nil); return err }}, + {"ListAPIKeys", func() error { _, err := ledger.ListAPIKeys(ctx, actor); return err }}, + {"CreateProduct", func() error { _, err := ledger.CreateProduct(ctx, actor, "Product", "product"); return err }}, + {"ListProducts", func() error { _, err := ledger.ListProducts(ctx, actor); return err }}, + {"CreateProject", func() error { _, err := ledger.CreateProject(ctx, actor, "prod", "api"); return err }}, + {"CreateRelease", func() error { _, err := ledger.CreateRelease(ctx, actor, "prod", "1.0.0"); return err }}, + {"GetRelease", func() error { _, err := ledger.GetRelease(ctx, actor, "rel"); return err }}, + {"FreezeRelease", func() error { _, err := ledger.FreezeRelease(ctx, actor, "rel"); return err }}, + {"ApproveRelease", func() error { _, err := ledger.ApproveRelease(ctx, actor, "rel"); return err }}, + {"RegisterArtifact", func() error { + _, err := ledger.RegisterArtifact(ctx, actor, "artifact", "application/octet-stream", sampleDigest("artifact"), 1) + return err + }}, + {"CreateEvidence", func() error { + _, err := ledger.CreateEvidence(ctx, actor, CreateEvidenceInput{Type: "build", Title: "Build"}) + return err + }}, + {"GetEvidence", func() error { _, err := ledger.GetEvidence(ctx, actor, "ev"); return err }}, + {"ListEvidence", func() error { _, err := ledger.ListEvidence(ctx, actor, "", ""); return err }}, + {"SupersedeEvidence", func() error { _, err := ledger.SupersedeEvidence(ctx, actor, "ev", "ev2", "reason"); return err }}, + {"LinkEvidence", func() error { _, err := ledger.LinkEvidence(ctx, actor, "ev", "release", "rel"); return err }}, + {"UploadSBOM", func() error { _, err := ledger.UploadSBOM(ctx, actor, "rel", "art", []byte(`{}`)); return err }}, + {"UploadVulnerabilityScan", func() error { _, err := ledger.UploadVulnerabilityScan(ctx, actor, []byte(`{}`)); return err }}, + {"UploadOpenAPIContract", func() error { + _, err := ledger.UploadOpenAPIContract(ctx, actor, "prod", "rel", "v1", []byte(`{}`)) + return err + }}, + {"EvaluateRelease", func() error { _, err := ledger.EvaluateRelease(ctx, actor, "rel"); return err }}, + {"CreateReleaseBundle", func() error { _, err := ledger.CreateReleaseBundle(ctx, actor, "rel"); return err }}, + {"GetReleaseBundle", func() error { _, err := ledger.GetReleaseBundle(ctx, actor, "bundle"); return err }}, + {"GetSBOM", func() error { _, err := ledger.GetSBOM(ctx, actor, "sbom"); return err }}, + {"ListSBOMComponents", func() error { _, err := ledger.ListSBOMComponents(ctx, actor, ListSBOMComponentsInput{}); return err }}, + {"GetVulnerabilityScan", func() error { _, err := ledger.GetVulnerabilityScan(ctx, actor, "scan"); return err }}, + {"GetOpenAPIContract", func() error { _, err := ledger.GetOpenAPIContract(ctx, actor, "contract"); return err }}, + {"VerifySubject", func() error { _, err := ledger.VerifySubject(ctx, actor, "audit_chain", ""); return err }}, + {"RotateSigningKey", func() error { _, err := ledger.RotateSigningKey(ctx, actor, "reason"); return err }}, + {"ListSigningKeys", func() error { _, err := ledger.ListSigningKeys(ctx, actor); return err }}, + {"MissingEvidenceReport", func() error { _, err := ledger.MissingEvidenceReport(ctx, actor, "rel"); return err }}, + {"SearchEvidence", func() error { _, err := ledger.SearchEvidence(ctx, actor, EvidenceSearchInput{}); return err }}, + {"RecordEvidenceLifecycleEvent", func() error { + _, err := ledger.RecordEvidenceLifecycleEvent(ctx, actor, "ev", RecordEvidenceLifecycleInput{Action: "amendment", Reason: "reason"}) + return err + }}, + {"ListEvidenceLifecycleEvents", func() error { _, err := ledger.ListEvidenceLifecycleEvents(ctx, actor, "ev"); return err }}, + {"CreateReleaseCandidate", func() error { + _, err := ledger.CreateReleaseCandidate(ctx, actor, CreateReleaseCandidateInput{ReleaseID: "rel", Name: "rc"}) + return err + }}, + {"GetReleaseCandidate", func() error { _, err := ledger.GetReleaseCandidate(ctx, actor, "rc"); return err }}, + {"ListReleaseCandidates", func() error { _, err := ledger.ListReleaseCandidates(ctx, actor, "rel"); return err }}, + {"UpdateReleaseCandidateState", func() error { + _, err := ledger.UpdateReleaseCandidateState(ctx, actor, "rc", "promoted", "reason") + return err + }}, + {"RegisterContainerImage", func() error { + _, err := ledger.RegisterContainerImage(ctx, actor, RegisterContainerImageInput{ArtifactID: "art", Repository: "repo", Digest: sampleDigest("image")}) + return err + }}, + {"CreateArtifactSignature", func() error { + _, err := ledger.CreateArtifactSignature(ctx, actor, CreateArtifactSignatureInput{ArtifactID: "art", Algorithm: "cosign", Signature: "sig"}) + return err + }}, + {"GetArtifactSignature", func() error { _, err := ledger.GetArtifactSignature(ctx, actor, "sig"); return err }}, + {"CreateSourceRepository", func() error { + _, err := ledger.CreateSourceRepository(ctx, actor, CreateRepositoryInput{ProjectID: "proj", Provider: "github", FullName: "owner/repo"}) + return err + }}, + {"ListSourceRepositories", func() error { _, err := ledger.ListSourceRepositories(ctx, actor, "proj"); return err }}, + {"RecordSourceCommit", func() error { + _, err := ledger.RecordSourceCommit(ctx, actor, RecordCommitInput{RepositoryID: "repo", SHA: "0123456789abcdef0123456789abcdef01234567"}) + return err + }}, + {"UpsertSourceBranch", func() error { + _, err := ledger.UpsertSourceBranch(ctx, actor, UpsertBranchInput{RepositoryID: "repo", Name: "main"}) + return err + }}, + {"RecordPullRequest", func() error { + _, err := ledger.RecordPullRequest(ctx, actor, RecordPullRequestInput{RepositoryID: "repo", ProviderID: "1", Title: "PR", State: "open"}) + return err + }}, + {"UploadGitHubSourceSnapshot", func() error { _, err := ledger.UploadGitHubSourceSnapshot(ctx, actor, []byte(`{}`)); return err }}, + {"UploadGitLabSourceSnapshot", func() error { _, err := ledger.UploadGitLabSourceSnapshot(ctx, actor, []byte(`{}`)); return err }}, + {"CreateDeploymentEnvironment", func() error { + _, err := ledger.CreateDeploymentEnvironment(ctx, actor, CreateEnvironmentInput{ProductID: "prod", Name: "prod", Kind: "production"}) + return err + }}, + {"ListDeploymentEnvironments", func() error { _, err := ledger.ListDeploymentEnvironments(ctx, actor, "prod"); return err }}, + {"RecordDeployment", func() error { + _, err := ledger.RecordDeployment(ctx, actor, RecordDeploymentInput{EnvironmentID: "env", ReleaseID: "rel", Status: "started"}) + return err + }}, + {"GetDeployment", func() error { _, err := ledger.GetDeployment(ctx, actor, "dep"); return err }}, + {"ListDeployments", func() error { _, err := ledger.ListDeployments(ctx, actor, "rel", "env"); return err }}, + {"UploadVEX", func() error { _, err := ledger.UploadVEX(ctx, actor, "rel", "art", []byte(`{}`)); return err }}, + {"GetVEXDocument", func() error { _, err := ledger.GetVEXDocument(ctx, actor, "vex"); return err }}, + {"CreateVulnerabilityDecision", func() error { + _, err := ledger.CreateVulnerabilityDecision(ctx, actor, "finding", CreateVulnerabilityDecisionInput{Status: "fixed", Justification: "fixed"}) + return err + }}, + {"CreateException", func() error { _, err := ledger.CreateException(ctx, actor, CreateExceptionInput{}); return err }}, + {"ListExceptions", func() error { _, err := ledger.ListExceptions(ctx, actor, "rel"); return err }}, + {"ApproveException", func() error { _, err := ledger.ApproveException(ctx, actor, "ex"); return err }}, + {"ReleaseReadinessReport", func() error { _, err := ledger.ReleaseReadinessReport(ctx, actor, "rel"); return err }}, + {"CreateControlFramework", func() error { + _, err := ledger.CreateControlFramework(ctx, actor, CreateControlFrameworkInput{Name: "Framework", Version: "1"}) + return err + }}, + {"ListControlFrameworks", func() error { _, err := ledger.ListControlFrameworks(ctx, actor); return err }}, + {"CreateSecurityControl", func() error { + _, err := ledger.CreateSecurityControl(ctx, actor, CreateSecurityControlInput{FrameworkID: "fw", Code: "C", Title: "Control", Objective: "Objective"}) + return err + }}, + {"GetSecurityControl", func() error { _, err := ledger.GetSecurityControl(ctx, actor, "ctrl"); return err }}, + {"LinkControlEvidence", func() error { + _, err := ledger.LinkControlEvidence(ctx, actor, "ctrl", LinkControlEvidenceInput{EvidenceType: "sbom", SubjectType: "sbom", SubjectID: "sbom"}) + return err + }}, + {"ListControlEvidence", func() error { _, err := ledger.ListControlEvidence(ctx, actor, "ctrl", "prod", "rel"); return err }}, + {"ControlCoverageReport", func() error { + _, err := ledger.ControlCoverageReport(ctx, actor, ControlCoverageReportInput{FrameworkID: "fw"}) + return err + }}, + {"CRAReadinessReport", func() error { + _, err := ledger.CRAReadinessReport(ctx, actor, CRAReadinessReportInput{ProductID: "prod", ReleaseID: "rel"}) + return err + }}, + {"CreateCollector", func() error { + _, _, _, err := ledger.CreateCollector(ctx, actor, CreateCollectorInput{Name: "collector", Type: "github_actions", Version: "1"}) + return err + }}, + {"ListCollectors", func() error { _, err := ledger.ListCollectors(ctx, actor); return err }}, + {"RecordCollectorRelease", func() error { + _, err := ledger.RecordCollectorRelease(ctx, actor, RecordCollectorReleaseInput{CollectorID: "collector", Version: "1", ArtifactDigest: sampleDigest("collector")}) + return err + }}, + {"CollectorHealthReport", func() error { _, err := ledger.CollectorHealthReport(ctx, actor, "collector"); return err }}, + {"CreateBuildRun", func() error { + _, err := ledger.CreateBuildRun(ctx, actor, CreateBuildRunInput{ProjectID: "proj", ReleaseID: "rel", Provider: "generic_ci", CommitSHA: "0123456789abcdef0123456789abcdef01234567", Status: "passed", StartedAt: fixedNow()}) + return err + }}, + {"GetBuildRun", func() error { _, err := ledger.GetBuildRun(ctx, actor, "build"); return err }}, + {"UploadBuildAttestation", func() error { _, err := ledger.UploadBuildAttestation(ctx, actor, "build", []byte(`{}`)); return err }}, + {"CreateWaiver", func() error { _, err := ledger.CreateWaiver(ctx, actor, CreateWaiverInput{}); return err }}, + {"ApproveWaiver", func() error { _, err := ledger.ApproveWaiver(ctx, actor, "waiver"); return err }}, + {"CreateApprovalRecord", func() error { _, err := ledger.CreateApprovalRecord(ctx, actor, CreateApprovalInput{}); return err }}, + {"CreateRedactionProfile", func() error { + _, err := ledger.CreateRedactionProfile(ctx, actor, CreateRedactionProfileInput{Name: "profile"}) + return err + }}, + {"CreateCustomerSecurityPackage", func() error { + _, err := ledger.CreateCustomerSecurityPackage(ctx, actor, CreateCustomerPackageInput{}) + return err + }}, + {"AccessCustomerSecurityPackage", func() error { _, err := ledger.AccessCustomerSecurityPackage(ctx, actor, "pkg"); return err }}, + {"ExportCustomerSecurityPackageArchive", func() error { _, err := ledger.ExportCustomerSecurityPackageArchive(ctx, actor, "pkg"); return err }}, + {"SecurityReviewPackageReport", func() error { _, err := ledger.SecurityReviewPackageReport(ctx, actor, "pkg"); return err }}, + {"CRAReadinessHTMLPackage", func() error { _, err := ledger.CRAReadinessHTMLPackage(ctx, actor, "prod", "rel"); return err }}, + {"ListControlFrameworkTemplatePacks", func() error { _, err := ledger.ListControlFrameworkTemplatePacks(ctx, actor); return err }}, + {"InstallControlFrameworkTemplatePack", func() error { + _, err := ledger.InstallControlFrameworkTemplatePack(ctx, actor, "evydence-cra-readiness") + return err + }}, + {"CreateCustomReportTemplate", func() error { + _, err := ledger.CreateCustomReportTemplate(ctx, actor, CreateReportTemplateInput{Name: "template", Version: "1", ReportType: "summary", Template: "json"}) + return err + }}, + {"RenderCustomReport", func() error { + _, err := ledger.RenderCustomReport(ctx, actor, RenderReportInput{TemplateID: "template", SubjectType: "release", SubjectID: "rel"}) + return err + }}, + {"ExportEvidenceBundle", func() error { _, err := ledger.ExportEvidenceBundle(ctx, actor, "rel", nil); return err }}, + {"ImportEvidenceBundle", func() error { _, err := ledger.ImportEvidenceBundle(ctx, actor, domain.EvidenceBundle{}); return err }}, + {"CreateDSSETrustRoot", func() error { + _, err := ledger.CreateDSSETrustRoot(ctx, actor, CreateDSSETrustRootInput{Name: "root", KeyID: "root", Algorithm: "Ed25519", PublicKey: "pub"}) + return err + }}, + {"VerifyDSSEAttestationSignature", func() error { _, err := ledger.VerifyDSSEAttestationSignature(ctx, actor, "att"); return err }}, + {"CreateOrganization", func() error { + _, err := ledger.CreateOrganization(ctx, actor, CreateOrganizationInput{Name: "Org", Slug: "org"}) + return err + }}, + {"CreateUser", func() error { + _, err := ledger.CreateUser(ctx, actor, CreateUserInput{OrganizationID: "org", Email: "user@example.test"}) + return err + }}, + {"DeactivateUser", func() error { _, err := ledger.DeactivateUser(ctx, actor, "user"); return err }}, + {"CreateRoleBinding", func() error { + _, err := ledger.CreateRoleBinding(ctx, actor, CreateRoleBindingInput{SubjectType: "user", SubjectID: "user", Role: "tenant_admin", ResourceType: "tenant"}) + return err + }}, + {"ListRoleBindings", func() error { _, err := ledger.ListRoleBindings(ctx, actor); return err }}, + {"CreateSSOProvider", func() error { + _, err := ledger.CreateSSOProvider(ctx, actor, CreateSSOProviderInput{Name: "OIDC", Type: "oidc", Issuer: "https://idp.example.test", ClientID: "client"}) + return err + }}, + {"LinkSSOIdentity", func() error { + _, err := ledger.LinkSSOIdentity(ctx, actor, LinkSSOIdentityInput{UserID: "user", ProviderID: "provider", Subject: "sub", Email: "user@example.test"}) + return err + }}, + {"CreateSSOSession", func() error { + _, _, err := ledger.CreateSSOSession(ctx, actor, CreateSSOSessionInput{UserID: "user", ProviderID: "provider", ExpiresAt: fixedNow().AddDate(0, 0, 1)}) + return err + }}, + {"RevokeSSOSession", func() error { _, err := ledger.RevokeSSOSession(ctx, actor, "session"); return err }}, + {"InstanceAdminSnapshot", func() error { _, err := ledger.InstanceAdminSnapshot(ctx, actor); return err }}, + {"CreateLegalHold", func() error { + _, err := ledger.CreateLegalHold(ctx, actor, CreateLegalHoldInput{ScopeType: "release", ScopeID: "rel", Reason: "review", Owner: "legal"}) + return err + }}, + {"CreateRetentionOverride", func() error { + _, err := ledger.CreateRetentionOverride(ctx, actor, CreateRetentionOverrideInput{ScopeType: "release", ScopeID: "rel", RetentionUntil: fixedNow().AddDate(1, 0, 0), Reason: "review", Owner: "legal"}) + return err + }}, + {"RetentionReport", func() error { _, err := ledger.RetentionReport(ctx, actor, "release", "rel"); return err }}, + {"CreateCustomerPortalAccess", func() error { + _, _, err := ledger.CreateCustomerPortalAccess(ctx, actor, CreateCustomerPortalAccessInput{PackageID: "pkg", CustomerName: "ACME", ExpiresAt: fixedNow().AddDate(0, 0, 1)}) + return err + }}, + {"CreateQuestionnaireTemplate", func() error { + _, err := ledger.CreateQuestionnaireTemplate(ctx, actor, CreateQuestionnaireTemplateInput{Name: "template", Version: "1"}) + return err + }}, + {"CreateQuestionnairePackage", func() error { + _, err := ledger.CreateQuestionnairePackage(ctx, actor, CreateQuestionnairePackageInput{TemplateID: "template", PackageID: "pkg", ProductID: "prod", ReleaseID: "rel"}) + return err + }}, + {"CreateCommercialCollectorDefinition", func() error { + _, err := ledger.CreateCommercialCollectorDefinition(ctx, actor, CreateCommercialCollectorInput{Name: "collector", Provider: "jira", Version: "1", ManifestHash: sampleDigest("collector")}) + return err + }}, + {"ListCommercialCollectorDefinitions", func() error { _, err := ledger.ListCommercialCollectorDefinitions(ctx, actor); return err }}, + {"CreateEvidenceSummary", func() error { + _, err := ledger.CreateEvidenceSummary(ctx, actor, CreateEvidenceSummaryInput{SubjectType: "release", SubjectID: "rel"}) + return err + }}, + {"CreateQuestionnaireDraft", func() error { + _, err := ledger.CreateQuestionnaireDraft(ctx, actor, CreateQuestionnaireDraftInput{TemplateID: "template", ProductID: "prod", ReleaseID: "rel"}) + return err + }}, + {"CreateGraphSnapshot", func() error { + _, err := ledger.CreateGraphSnapshot(ctx, actor, CreateGraphSnapshotInput{ProductID: "prod", ReleaseID: "rel"}) + return err + }}, + {"CreateSaaSEditionProfile", func() error { + _, err := ledger.CreateSaaSEditionProfile(ctx, actor, CreateSaaSEditionProfileInput{Name: "profile", Region: "eu", AdminTenantID: "ten", IsolationModel: "self-hosted"}) + return err + }}, + {"CreatePublicTransparencyLog", func() error { + _, err := ledger.CreatePublicTransparencyLog(ctx, actor, CreatePublicTransparencyLogInput{Name: "log", Endpoint: "https://log.example.test", PublicKey: "pub"}) + return err + }}, + {"PublishPublicTransparencyLogEntry", func() error { + _, err := ledger.PublishPublicTransparencyLogEntry(ctx, actor, PublishPublicTransparencyLogEntryInput{LogID: "log", CheckpointID: "checkpoint", ExternalID: "entry"}) + return err + }}, + {"CreateMarketplaceCollector", func() error { + _, err := ledger.CreateMarketplaceCollector(ctx, actor, CreateMarketplaceCollectorInput{Name: "collector", Provider: "scanner", Version: "1", Publisher: "vendor", ManifestHash: sampleDigest("collector")}) + return err + }}, + {"ListMarketplaceCollectors", func() error { _, err := ledger.ListMarketplaceCollectors(ctx, actor); return err }}, + {"MarketplaceCollectorHealth", func() error { _, err := ledger.MarketplaceCollectorHealth(ctx, actor, "collector"); return err }}, + {"CreatePDFReportPackage", func() error { + _, err := ledger.CreatePDFReportPackage(ctx, actor, CreatePDFReportPackageInput{ReportType: "release_readiness", ProductID: "prod", ReleaseID: "rel", Title: "Report"}) + return err + }}, + {"GenerateAnomalyReport", func() error { + _, err := ledger.GenerateAnomalyReport(ctx, actor, AnomalyReportInput{SubjectType: "release", SubjectID: "rel"}) + return err + }}, + {"CreateSigningOperation", func() error { + _, err := ledger.CreateSigningOperation(ctx, actor, CreateSigningOperationInput{ProviderID: "provider", SubjectType: "release", SubjectID: "rel", PayloadHash: sampleDigest("payload"), ExternalSignature: "sig"}) + return err + }}, + {"VerifyProviderIdentity", func() error { + _, err := ledger.VerifyProviderIdentity(ctx, actor, VerifyProviderIdentityInput{ProviderType: "oidc", ProviderID: "provider", Subject: "sub"}) + return err + }}, + {"VerifyCosignSignature", func() error { + _, err := ledger.VerifyCosignSignature(ctx, actor, VerifyCosignInput{ArtifactSignatureID: "sig"}) + return err + }}, + {"RevokeSigningKey", func() error { _, err := ledger.RevokeSigningKey(ctx, actor, "key", "reason"); return err }}, + {"CreateSigningProvider", func() error { + _, err := ledger.CreateSigningProvider(ctx, actor, CreateSigningProviderInput{Name: "kms", Type: "aws_kms", KeyRef: "arn:aws:kms:example", Encrypted: true}) + return err + }}, + {"CreateMerkleBatch", func() error { + _, err := ledger.CreateMerkleBatch(ctx, actor, CreateMerkleBatchInput{FromSequence: 1, ToSequence: 1}) + return err + }}, + {"VerifyMerkleBatch", func() error { _, err := ledger.VerifyMerkleBatch(ctx, actor, "batch"); return err }}, + {"CreateTransparencyCheckpoint", func() error { + _, err := ledger.CreateTransparencyCheckpoint(ctx, actor, CreateTransparencyCheckpointInput{BatchID: "batch", Provider: "internal", ExternalID: "checkpoint"}) + return err + }}, + {"CreateObjectRetentionPolicy", func() error { + _, err := ledger.CreateObjectRetentionPolicy(ctx, actor, CreateObjectRetentionPolicyInput{Name: "policy", ObjectPrefix: "tenants/ten/", Mode: "governance", RetentionDays: 30}) + return err + }}, + {"VerifyObjectRetentionPolicy", func() error { _, err := ledger.VerifyObjectRetentionPolicy(ctx, actor, "policy"); return err }}, + {"GenerateBackupManifest", func() error { _, err := ledger.GenerateBackupManifest(ctx, actor); return err }}, + {"VerifyBackupManifest", func() error { _, err := ledger.VerifyBackupManifest(ctx, actor, "backup"); return err }}, + {"Metrics", func() error { _, err := ledger.Metrics(ctx, actor); return err }}, + {"ListAuditLog", func() error { _, err := ledger.ListAuditLog(ctx, actor, AuditLogFilter{}); return err }}, + } + + for _, check := range checks { + t.Run(check.name, func(t *testing.T) { + if err := check.run(); !errors.Is(err, ErrForbidden) { + t.Fatalf("err=%v, want ErrForbidden", err) + } + }) + } +} diff --git a/internal/app/ledger.go b/internal/app/ledger.go index cb31620..592fbd6 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -389,6 +389,9 @@ func (l *Ledger) Authenticate(ctx context.Context, secret string) (domain.Actor, } func (l *Ledger) CreateAPIKey(ctx context.Context, actor domain.Actor, name string, scopes []string, expiresAt *time.Time) (domain.APIKey, string, error) { + if err := ctx.Err(); err != nil { + return domain.APIKey{}, "", err + } if err := require(actor, ScopeAdmin); err != nil { return domain.APIKey{}, "", err } @@ -886,6 +889,9 @@ func (l *Ledger) LinkEvidence(ctx context.Context, actor domain.Actor, id, targe } func (l *Ledger) UploadSBOM(ctx context.Context, actor domain.Actor, releaseID, artifactID string, raw []byte) (domain.SBOM, error) { + if err := ctx.Err(); err != nil { + return domain.SBOM{}, err + } if err := require(actor, ScopeEvidenceWrite); err != nil { return domain.SBOM{}, err } @@ -964,6 +970,9 @@ func (l *Ledger) UploadSBOM(ctx context.Context, actor domain.Actor, releaseID, } func (l *Ledger) UploadVulnerabilityScan(ctx context.Context, actor domain.Actor, raw []byte) (domain.VulnerabilityScan, error) { + if err := ctx.Err(); err != nil { + return domain.VulnerabilityScan{}, err + } if err := require(actor, ScopeEvidenceWrite); err != nil { return domain.VulnerabilityScan{}, err } @@ -1047,6 +1056,9 @@ func (l *Ledger) UploadVulnerabilityScan(ctx context.Context, actor domain.Actor } func (l *Ledger) UploadOpenAPIContract(ctx context.Context, actor domain.Actor, productID, releaseID, version string, raw []byte) (domain.OpenAPIContract, error) { + if err := ctx.Err(); err != nil { + return domain.OpenAPIContract{}, err + } if err := require(actor, ScopeEvidenceWrite); err != nil { return domain.OpenAPIContract{}, err } diff --git a/internal/app/risk_workflows.go b/internal/app/risk_workflows.go index 93bfd14..5296830 100644 --- a/internal/app/risk_workflows.go +++ b/internal/app/risk_workflows.go @@ -677,6 +677,9 @@ func (l *Ledger) UploadManualSecurityDocument(ctx context.Context, actor domain. } func (l *Ledger) UploadSPDXSBOM(ctx context.Context, actor domain.Actor, releaseID, artifactID string, raw []byte) (domain.SBOM, error) { + if err := ctx.Err(); err != nil { + return domain.SBOM{}, err + } if err := require(actor, ScopeEvidenceWrite); err != nil { return domain.SBOM{}, err } @@ -807,6 +810,9 @@ func (l *Ledger) CreateSBOMDiff(ctx context.Context, actor domain.Actor, in Crea } func (l *Ledger) UploadCycloneDXVEX(ctx context.Context, actor domain.Actor, releaseID, artifactID string, raw []byte) (domain.VEXDocument, error) { + if err := ctx.Err(); err != nil { + return domain.VEXDocument{}, err + } if err := require(actor, ScopeEvidenceWrite); err != nil { return domain.VEXDocument{}, err } diff --git a/internal/app/vex.go b/internal/app/vex.go index 38ef193..17911d1 100644 --- a/internal/app/vex.go +++ b/internal/app/vex.go @@ -64,6 +64,9 @@ type openVEXProduct struct { } func (l *Ledger) UploadVEX(ctx context.Context, actor domain.Actor, releaseID, artifactID string, raw []byte) (domain.VEXDocument, error) { + if err := ctx.Err(); err != nil { + return domain.VEXDocument{}, err + } if err := require(actor, ScopeEvidenceWrite); err != nil { return domain.VEXDocument{}, err } diff --git a/scripts/production_check.sh b/scripts/production_check.sh index 5206e4d..3e8778e 100755 --- a/scripts/production_check.sh +++ b/scripts/production_check.sh @@ -16,26 +16,26 @@ make coverage-check workdir="tmp/production-check" rm -rf "$workdir" -mkdir -p "$workdir/dist" +mkdir -p "$workdir" -go build -o "$workdir/dist/evydence" ./cmd/evydence -cp openapi.yaml "$workdir/dist/openapi.yaml" +go build -o "$workdir/evydence" ./cmd/evydence +cp openapi.yaml "$workdir/openapi.yaml" -"$workdir/dist/evydence" release manifest \ +"$workdir/evydence" release manifest \ --out "$workdir/evydence-release-manifest.json" \ - "$workdir/dist/evydence" \ - "$workdir/dist/openapi.yaml" + "$workdir/evydence" \ + "$workdir/openapi.yaml" -"$workdir/dist/evydence" release keygen \ +"$workdir/evydence" release keygen \ --private-out "$workdir/release-private.key" \ --public-out "$workdir/release-public.key" >/dev/null -"$workdir/dist/evydence" release sign \ +"$workdir/evydence" release sign \ --manifest "$workdir/evydence-release-manifest.json" \ --private-key "$workdir/release-private.key" \ --out "$workdir/evydence-release-manifest.sig.json" -"$workdir/dist/evydence" release verify \ +"$workdir/evydence" release verify \ --manifest "$workdir/evydence-release-manifest.json" \ --signature "$workdir/evydence-release-manifest.sig.json" From 73d00a1a607ce29c8af8df0e3688ee54bde6bfc4 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 17:56:59 +0300 Subject: [PATCH 046/287] ci: use node24 github actions --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 20db497..fe6f4bf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,10 +34,10 @@ jobs: EVYDENCE_TEST_DATABASE_URL: postgres://evydence:change-me@localhost:5432/evydence?sslmode=disable steps: - name: Check out repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Set up Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version-file: go.mod cache: true @@ -53,7 +53,7 @@ jobs: - name: Upload release evidence artifacts if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: evydence-ci-evidence path: | From f69bf79089dd40d9b13e28290470f72afe87bace Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 17:57:50 +0300 Subject: [PATCH 047/287] ci: use node24 artifact upload --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fe6f4bf..794c48a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,7 +53,7 @@ jobs: - name: Upload release evidence artifacts if: always() - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v7 with: name: evydence-ci-evidence path: | From 517685643f799ab3e124d1883bf3b194fd22ff8b Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 17:59:33 +0300 Subject: [PATCH 048/287] fix: replay worker payload parsers --- README.md | 2 +- cmd/evydence-worker/main.go | 351 ++++++++++++++++++++++++- cmd/evydence-worker/main_test.go | 131 ++++++++- docs/architecture.md | 2 +- docs/reference/production-readiness.md | 11 +- docs/reference/worker-outbox.md | 4 +- 6 files changed, 475 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 011e099..5a53fdb 100644 --- a/README.md +++ b/README.md @@ -107,4 +107,4 @@ make postgres-integration-test `make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. -`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. It is expected to fail until the repository satisfies the production-readiness exit criteria. +`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required production-readiness evidence, but it does not by itself close the remaining relational persistence, worker side-effect, SDK, backup/restore, KMS/HSM, SSO, object-lock, transparency, and exit-review work. diff --git a/cmd/evydence-worker/main.go b/cmd/evydence-worker/main.go index f34e52b..57cacde 100644 --- a/cmd/evydence-worker/main.go +++ b/cmd/evydence-worker/main.go @@ -1,13 +1,18 @@ package main import ( + "bytes" "context" "crypto/sha256" + "encoding/base64" "encoding/hex" + "encoding/json" "errors" + "io" "log" "os" "path/filepath" + "sort" "strconv" "strings" "time" @@ -16,6 +21,8 @@ import ( s3store "github.com/aatuh/evydence/internal/adapters/objectstore/s3" "github.com/aatuh/evydence/internal/adapters/postgres" "github.com/aatuh/evydence/internal/app" + "github.com/aatuh/evydence/internal/domain" + "github.com/getkin/kin-openapi/openapi3" ) const defaultMaxWorkerPayloadBytes = 20 << 20 @@ -105,10 +112,14 @@ func processJobInternal(ctx context.Context, state jobStateLoader, objects jobOb if state == nil { return errors.New("outbox job handler requires durable state") } + var replayed app.Object + var hasReplayedObject bool if requireObjectReplay { - if err := verifyJobObject(ctx, objects, job); err != nil { + object, ok, err := verifyJobObject(ctx, objects, job) + if err != nil { return err } + replayed, hasReplayedObject = object, ok } snapshot, ok, err := state.LoadState(ctx) if err != nil { @@ -123,24 +134,44 @@ func processJobInternal(ctx context.Context, state jobStateLoader, objects jobOb if !ok || sbom.TenantID != job.TenantID { return errors.New("parsed sbom is not available in durable state") } + if hasReplayedObject { + if err := verifyReplayedSBOM(replayed.Bytes, sbom); err != nil { + return err + } + } return requirePayloadHash(job, "") case "parse_vulnerability_scan": scan, ok := snapshot.Scans[job.SubjectID] if !ok || scan.TenantID != job.TenantID { return errors.New("parsed vulnerability scan is not available in durable state") } + if hasReplayedObject { + if err := verifyReplayedVulnerabilityScan(replayed.Bytes, scan); err != nil { + return err + } + } return requirePayloadHash(job, "") case "parse_openapi_contract": contract, ok := snapshot.Contracts[job.SubjectID] if !ok || contract.TenantID != job.TenantID { return errors.New("parsed openapi contract is not available in durable state") } + if hasReplayedObject { + if err := verifyReplayedOpenAPIContract(ctx, replayed.Bytes, contract); err != nil { + return err + } + } return requirePayloadHash(job, contract.Hash) case "parse_vex": vex, ok := snapshot.VEXDocuments[job.SubjectID] if !ok || vex.TenantID != job.TenantID { return errors.New("parsed vex document is not available in durable state") } + if hasReplayedObject { + if err := verifyReplayedVEX(replayed.Bytes, vex); err != nil { + return err + } + } return requirePayloadHash(job, "") case "sign_bundle": bundle, ok := snapshot.Bundles[job.SubjectID] @@ -172,44 +203,49 @@ func processJobInternal(ctx context.Context, state jobStateLoader, objects jobOb if attestation.VerificationStatus == "" { return errors.New("build attestation verification status is incomplete") } + if hasReplayedObject { + if err := verifyReplayedAttestation(replayed.Bytes, attestation); err != nil { + return err + } + } return requirePayloadHash(job, attestation.PayloadHash) default: return errors.New("unsupported outbox job kind") } } -func verifyJobObject(ctx context.Context, objects jobObjectGetter, job postgres.ClaimedJob) error { - key := payloadString(job, "payload_ref") +func verifyJobObject(ctx context.Context, objects jobObjectGetter, job postgres.ClaimedJob) (app.Object, bool, error) { + key := payloadObjectKey(job) if key == "" { - return nil + return app.Object{}, false, nil } if !strings.HasPrefix(key, "tenants/"+job.TenantID+"/") { - return errors.New("outbox payload object key is not tenant-prefixed") + return app.Object{}, false, errors.New("outbox payload object key is not tenant-prefixed") } if objects == nil { - return errors.New("outbox object store is not configured") + return app.Object{}, false, errors.New("outbox object store is not configured") } object, err := objects.Get(ctx, key) if err != nil { - return errors.New("read outbox payload object") + return app.Object{}, false, errors.New("read outbox payload object") } if object.TenantID != "" && object.TenantID != job.TenantID { - return errors.New("outbox payload object tenant mismatch") + return app.Object{}, false, errors.New("outbox payload object tenant mismatch") } if len(object.Bytes) > intEnv("EVYDENCE_WORKER_MAX_PAYLOAD_BYTES", defaultMaxWorkerPayloadBytes) { - return errors.New("outbox payload object exceeds worker size limit") + return app.Object{}, false, errors.New("outbox payload object exceeds worker size limit") } want := payloadString(job, "payload_hash") if want == "" { - return nil + return object, true, nil } if object.Digest != "" && object.Digest != want { - return errors.New("outbox payload object metadata digest mismatch") + return app.Object{}, false, errors.New("outbox payload object metadata digest mismatch") } if digestBytes(object.Bytes) != want { - return errors.New("outbox payload object digest mismatch") + return app.Object{}, false, errors.New("outbox payload object digest mismatch") } - return nil + return object, true, nil } func requirePayloadHash(job postgres.ClaimedJob, recordedHash string) error { @@ -231,6 +267,295 @@ func payloadString(job postgres.ClaimedJob, key string) string { return strings.TrimSpace(value) } +func payloadObjectKey(job postgres.ClaimedJob) string { + ref := payloadString(job, "payload_ref") + return strings.TrimPrefix(ref, "object://") +} + +type replayedSBOM struct { + SpecVersion string + ComponentCount int +} + +func verifyReplayedSBOM(raw []byte, sbom domain.SBOM) error { + parsed, err := parseReplayedSBOM(raw) + if err != nil { + return err + } + if sbom.SpecVersion != "" && parsed.SpecVersion != sbom.SpecVersion { + return errors.New("replayed sbom payload does not match durable state") + } + if sbom.ComponentCount != 0 && parsed.ComponentCount != sbom.ComponentCount { + return errors.New("replayed sbom payload does not match durable state") + } + if len(sbom.Components) != 0 && parsed.ComponentCount != len(sbom.Components) { + return errors.New("replayed sbom payload does not match durable state") + } + return nil +} + +func parseReplayedSBOM(raw []byte) (replayedSBOM, error) { + var doc struct { + BOMFormat string `json:"bomFormat"` + SpecVersion string `json:"specVersion"` + Components []struct { + Name string `json:"name"` + Version string `json:"version"` + PURL string `json:"purl"` + } `json:"components"` + } + if err := strictDecodeWorker(raw, &doc); err != nil || strings.ToLower(strings.TrimSpace(doc.BOMFormat)) != "cyclonedx" { + return replayedSBOM{}, errors.New("replayed sbom payload is invalid") + } + for _, component := range doc.Components { + if strings.TrimSpace(component.Name) == "" { + return replayedSBOM{}, errors.New("replayed sbom payload is invalid") + } + } + return replayedSBOM{SpecVersion: strings.TrimSpace(doc.SpecVersion), ComponentCount: len(doc.Components)}, nil +} + +type replayedVulnerabilityScan struct { + Scanner string + TargetRef string + FindingCount int + Summary map[string]int +} + +func verifyReplayedVulnerabilityScan(raw []byte, scan domain.VulnerabilityScan) error { + parsed, err := parseReplayedVulnerabilityScan(raw) + if err != nil { + return err + } + if scan.Scanner != "" && parsed.Scanner != scan.Scanner { + return errors.New("replayed vulnerability scan payload does not match durable state") + } + if scan.TargetRef != "" && parsed.TargetRef != scan.TargetRef { + return errors.New("replayed vulnerability scan payload does not match durable state") + } + if len(scan.Findings) != 0 && parsed.FindingCount != len(scan.Findings) { + return errors.New("replayed vulnerability scan payload does not match durable state") + } + for severity, count := range scan.Summary { + if parsed.Summary[severity] != count { + return errors.New("replayed vulnerability scan payload does not match durable state") + } + } + return nil +} + +func parseReplayedVulnerabilityScan(raw []byte) (replayedVulnerabilityScan, error) { + var doc struct { + Scanner string `json:"scanner"` + TargetRef string `json:"target_ref"` + Findings []struct { + Vulnerability string `json:"vulnerability"` + Component string `json:"component"` + Severity string `json:"severity"` + State string `json:"state"` + } `json:"findings"` + ReleaseID string `json:"release_id"` + } + if err := strictDecodeWorker(raw, &doc); err != nil || strings.TrimSpace(doc.Scanner) == "" || strings.TrimSpace(doc.TargetRef) == "" || strings.TrimSpace(doc.ReleaseID) == "" { + return replayedVulnerabilityScan{}, errors.New("replayed vulnerability scan payload is invalid") + } + summary := map[string]int{} + for _, finding := range doc.Findings { + if strings.TrimSpace(finding.Vulnerability) == "" || strings.TrimSpace(finding.Severity) == "" { + return replayedVulnerabilityScan{}, errors.New("replayed vulnerability scan payload is invalid") + } + summary[strings.ToLower(strings.TrimSpace(finding.Severity))]++ + } + return replayedVulnerabilityScan{Scanner: strings.TrimSpace(doc.Scanner), TargetRef: strings.TrimSpace(doc.TargetRef), FindingCount: len(doc.Findings), Summary: summary}, nil +} + +func verifyReplayedOpenAPIContract(ctx context.Context, raw []byte, contract domain.OpenAPIContract) error { + loader := openapi3.NewLoader() + doc, err := loader.LoadFromData(raw) + if err != nil { + return errors.New("replayed openapi contract payload is invalid") + } + if err := doc.Validate(ctx); err != nil { + return errors.New("replayed openapi contract payload is invalid") + } + pathCount := 0 + if doc.Paths != nil { + pathCount = len(doc.Paths.Map()) + } + if contract.PathCount != 0 && pathCount != contract.PathCount { + return errors.New("replayed openapi contract payload does not match durable state") + } + if contract.Hash != "" && digestBytes(raw) != contract.Hash { + return errors.New("replayed openapi contract payload does not match durable state") + } + return nil +} + +type replayedVEX struct { + Author string + StatementCount int + StatusSummary map[string]int +} + +func verifyReplayedVEX(raw []byte, vex domain.VEXDocument) error { + parsed, err := parseReplayedVEX(raw) + if err != nil { + return err + } + if vex.Author != "" && parsed.Author != vex.Author { + return errors.New("replayed vex payload does not match durable state") + } + if vex.StatementCount != 0 && parsed.StatementCount != vex.StatementCount { + return errors.New("replayed vex payload does not match durable state") + } + for status, count := range vex.StatusSummary { + if parsed.StatusSummary[status] != count { + return errors.New("replayed vex payload does not match durable state") + } + } + return nil +} + +func parseReplayedVEX(raw []byte) (replayedVEX, error) { + var doc struct { + Context any `json:"@context"` + ID string `json:"@id"` + Author string `json:"author"` + Timestamp string `json:"timestamp"` + Version any `json:"version"` + Statements []struct { + Vulnerability struct { + Name string `json:"name"` + } `json:"vulnerability"` + Products []map[string]any `json:"products"` + Status string `json:"status"` + Justification string `json:"justification"` + ImpactStatement string `json:"impact_statement"` + ActionStatement string `json:"action_statement"` + } `json:"statements"` + } + if err := strictDecodeWorker(raw, &doc); err != nil || strings.TrimSpace(doc.Author) == "" || strings.TrimSpace(doc.Timestamp) == "" || len(doc.Statements) == 0 { + return replayedVEX{}, errors.New("replayed vex payload is invalid") + } + summary := map[string]int{} + for _, statement := range doc.Statements { + status := strings.TrimSpace(statement.Status) + if strings.TrimSpace(statement.Vulnerability.Name) == "" || status == "" || len(statement.Products) == 0 { + return replayedVEX{}, errors.New("replayed vex payload is invalid") + } + switch status { + case "affected", "not_affected", "fixed", "under_investigation": + default: + return replayedVEX{}, errors.New("replayed vex payload is invalid") + } + summary[status]++ + } + return replayedVEX{Author: strings.TrimSpace(doc.Author), StatementCount: len(doc.Statements), StatusSummary: summary}, nil +} + +func verifyReplayedAttestation(raw []byte, attestation domain.BuildAttestation) error { + parsed, err := parseReplayedAttestation(raw) + if err != nil { + return err + } + if attestation.PayloadHash != "" && digestBytes(raw) != attestation.PayloadHash { + return errors.New("replayed build attestation payload does not match durable state") + } + if len(attestation.SubjectDigests) != 0 && !equalStringSets(parsed.SubjectDigests, attestation.SubjectDigests) { + return errors.New("replayed build attestation payload does not match durable state") + } + if attestation.PredicateType != "" && parsed.PredicateType != attestation.PredicateType { + return errors.New("replayed build attestation payload does not match durable state") + } + return nil +} + +type replayedAttestation struct { + PredicateType string + SubjectDigests []string +} + +func parseReplayedAttestation(raw []byte) (replayedAttestation, error) { + var envelope struct { + PayloadType string `json:"payloadType"` + Payload string `json:"payload"` + Signatures []struct { + KeyID string `json:"keyid,omitempty"` + Sig string `json:"sig"` + } `json:"signatures"` + } + if err := strictDecodeWorker(raw, &envelope); err != nil || strings.TrimSpace(envelope.PayloadType) == "" || strings.TrimSpace(envelope.Payload) == "" || len(envelope.Signatures) == 0 { + return replayedAttestation{}, errors.New("replayed build attestation payload is invalid") + } + for _, signature := range envelope.Signatures { + if strings.TrimSpace(signature.Sig) == "" { + return replayedAttestation{}, errors.New("replayed build attestation payload is invalid") + } + } + payload, err := base64.StdEncoding.DecodeString(envelope.Payload) + if err != nil { + return replayedAttestation{}, errors.New("replayed build attestation payload is invalid") + } + var statement struct { + Type string `json:"_type"` + PredicateType string `json:"predicateType"` + Subject []struct { + Name string `json:"name"` + Digest map[string]string `json:"digest"` + } `json:"subject"` + Predicate map[string]any `json:"predicate"` + } + if err := strictDecodeWorker(payload, &statement); err != nil || strings.TrimSpace(statement.Type) == "" || strings.TrimSpace(statement.PredicateType) == "" || len(statement.Subject) == 0 { + return replayedAttestation{}, errors.New("replayed build attestation payload is invalid") + } + digests := make([]string, 0, len(statement.Subject)) + for _, subject := range statement.Subject { + digest := "sha256:" + strings.ToLower(strings.TrimSpace(subject.Digest["sha256"])) + if !validWorkerDigest(digest) { + return replayedAttestation{}, errors.New("replayed build attestation payload is invalid") + } + digests = append(digests, digest) + } + sort.Strings(digests) + return replayedAttestation{PredicateType: strings.TrimSpace(statement.PredicateType), SubjectDigests: digests}, nil +} + +func equalStringSets(a, b []string) bool { + if len(a) != len(b) { + return false + } + left := append([]string(nil), a...) + right := append([]string(nil), b...) + sort.Strings(left) + sort.Strings(right) + for i := range left { + if left[i] != right[i] { + return false + } + } + return true +} + +func strictDecodeWorker(raw []byte, out any) error { + dec := json.NewDecoder(bytes.NewReader(raw)) + dec.DisallowUnknownFields() + if err := dec.Decode(out); err != nil { + return err + } + if err := dec.Decode(&struct{}{}); err != io.EOF { + return errors.New("trailing json") + } + return nil +} + +func validWorkerDigest(value string) bool { + if !strings.HasPrefix(value, "sha256:") || len(value) != len("sha256:")+64 { + return false + } + _, err := hex.DecodeString(strings.TrimPrefix(value, "sha256:")) + return err == nil +} + func envDefault(name, fallback string) string { if value := strings.TrimSpace(os.Getenv(name)); value != "" { return value diff --git a/cmd/evydence-worker/main_test.go b/cmd/evydence-worker/main_test.go index a23767a..fe57ef4 100644 --- a/cmd/evydence-worker/main_test.go +++ b/cmd/evydence-worker/main_test.go @@ -2,6 +2,8 @@ package main import ( "context" + "encoding/base64" + "encoding/json" "errors" "os" "path/filepath" @@ -25,14 +27,18 @@ func (f fakeStateLoader) LoadState(context.Context) (app.PersistedState, bool, e } type fakeObjectGetter struct { - object app.Object - err error + object app.Object + err error + wantKey string } -func (f fakeObjectGetter) Get(context.Context, string) (app.Object, error) { +func (f fakeObjectGetter) Get(_ context.Context, key string) (app.Object, error) { if f.err != nil { return app.Object{}, f.err } + if f.wantKey != "" && key != f.wantKey { + return app.Object{}, errors.New("unexpected object key") + } return f.object, nil } @@ -61,17 +67,107 @@ func TestProcessJobWithObjectsVerifiesTenantPrefixedPayload(t *testing.T) { TenantID: "ten_test", Kind: "parse_sbom", SubjectID: "sbom_test", - Payload: map[string]any{"payload_ref": "tenants/ten_test/payloads/sbom.json", "payload_hash": hash}, + Payload: map[string]any{"payload_ref": "object://tenants/ten_test/payloads/sbom.json", "payload_hash": hash}, } state := app.PersistedState{SBOMs: map[string]domain.SBOM{ "sbom_test": {ID: "sbom_test", TenantID: "ten_test"}, }} object := app.Object{Key: "tenants/ten_test/payloads/sbom.json", TenantID: "ten_test", Digest: hash, Bytes: body} - if err := processJobWithObjects(context.Background(), fakeStateLoader{state: state, ok: true}, fakeObjectGetter{object: object}, job); err != nil { + if err := processJobWithObjects(context.Background(), fakeStateLoader{state: state, ok: true}, fakeObjectGetter{object: object, wantKey: "tenants/ten_test/payloads/sbom.json"}, job); err != nil { t.Fatalf("process object-backed job: %v", err) } } +func TestProcessJobWithObjectsParsesPayloadAndChecksDurableState(t *testing.T) { + now := time.Now().UTC() + attestationBody := dsseEnvelopeForTest(t, "sha256:"+strings.Repeat("a", 64)) + tests := []struct { + name string + body []byte + job postgres.ClaimedJob + state app.PersistedState + object app.Object + }{ + { + name: "sbom component count", + body: []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","components":[{"name":"api"},{"name":"worker"}]}`), + job: postgres.ClaimedJob{TenantID: "ten_test", Kind: "parse_sbom", SubjectID: "sbom_test"}, + state: app.PersistedState{SBOMs: map[string]domain.SBOM{ + "sbom_test": {ID: "sbom_test", TenantID: "ten_test", SpecVersion: "1.6", ComponentCount: 2}, + }}, + }, + { + name: "vulnerability scan summary", + body: []byte(`{"scanner":"grype","target_ref":"pkg:oci/api","release_id":"rel_test","findings":[{"vulnerability":"CVE-1","severity":"critical"},{"vulnerability":"CVE-2","severity":"high"}]}`), + job: postgres.ClaimedJob{TenantID: "ten_test", Kind: "parse_vulnerability_scan", SubjectID: "scan_test"}, + state: app.PersistedState{Scans: map[string]domain.VulnerabilityScan{ + "scan_test": {ID: "scan_test", TenantID: "ten_test", Scanner: "grype", TargetRef: "pkg:oci/api", Summary: map[string]int{"critical": 1, "high": 1}, Findings: []domain.VulnerabilityFinding{{ID: "vf_1"}, {ID: "vf_2"}}}, + }}, + }, + { + name: "openapi contract path count", + body: []byte(`{"openapi":"3.1.0","info":{"title":"API","version":"1"},"paths":{"/v1/a":{"get":{"responses":{"200":{"description":"ok"}}}}}}`), + job: postgres.ClaimedJob{TenantID: "ten_test", Kind: "parse_openapi_contract", SubjectID: "oas_test"}, + state: app.PersistedState{Contracts: map[string]domain.OpenAPIContract{ + "oas_test": {ID: "oas_test", TenantID: "ten_test", PathCount: 1}, + }}, + }, + { + name: "openvex statement count", + body: []byte(`{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex","author":"security@example.test","timestamp":"2026-05-28T12:00:00Z","version":1,"statements":[{"vulnerability":{"name":"CVE-1"},"products":[{"@id":"pkg:oci/api"}],"status":"fixed","justification":"fixed","impact_statement":"fixed","action_statement":"none"}]}`), + job: postgres.ClaimedJob{TenantID: "ten_test", Kind: "parse_vex", SubjectID: "vex_test"}, + state: app.PersistedState{VEXDocuments: map[string]domain.VEXDocument{ + "vex_test": {ID: "vex_test", TenantID: "ten_test", Format: "openvex", Author: "security@example.test", StatementCount: 1, StatusSummary: map[string]int{"fixed": 1}}, + }}, + }, + { + name: "dsse attestation subject digest", + body: attestationBody, + job: postgres.ClaimedJob{TenantID: "ten_test", Kind: "verify_attestation", SubjectID: "att_test"}, + state: app.PersistedState{BuildAttestations: map[string]domain.BuildAttestation{ + "att_test": {ID: "att_test", TenantID: "ten_test", PayloadHash: digestBytes(attestationBody), SubjectDigests: []string{"sha256:" + strings.Repeat("a", 64)}, VerificationStatus: "structurally_valid", CreatedAt: now}, + }}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + hash := digestBytes(tt.body) + tt.job.Payload = map[string]any{"payload_ref": "tenants/ten_test/payloads/replay.json", "payload_hash": hash} + tt.object = app.Object{Key: "tenants/ten_test/payloads/replay.json", TenantID: "ten_test", Digest: hash, Bytes: tt.body} + if tt.job.Kind == "parse_openapi_contract" { + contract := tt.state.Contracts[tt.job.SubjectID] + contract.Hash = hash + tt.state.Contracts[tt.job.SubjectID] = contract + } + if err := processJobWithObjects(context.Background(), fakeStateLoader{state: tt.state, ok: true}, fakeObjectGetter{object: tt.object}, tt.job); err != nil { + t.Fatalf("process replay payload: %v", err) + } + }) + } +} + +func TestProcessJobWithObjectsFailsSafelyForParserMismatches(t *testing.T) { + body := []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","components":[{"name":"api"},{"name":"worker"}]}`) + hash := digestBytes(body) + job := postgres.ClaimedJob{ + TenantID: "ten_test", + Kind: "parse_sbom", + SubjectID: "sbom_test", + Payload: map[string]any{"payload_ref": "tenants/ten_test/payloads/raw-secret-name", "payload_hash": hash}, + } + state := app.PersistedState{SBOMs: map[string]domain.SBOM{ + "sbom_test": {ID: "sbom_test", TenantID: "ten_test", ComponentCount: 1}, + }} + object := app.Object{Key: "tenants/ten_test/payloads/raw-secret-name", TenantID: "ten_test", Digest: hash, Bytes: body} + err := processJobWithObjects(context.Background(), fakeStateLoader{state: state, ok: true}, fakeObjectGetter{object: object}, job) + if err == nil || !strings.Contains(err.Error(), "replayed sbom payload does not match durable state") { + t.Fatalf("err=%v", err) + } + if strings.Contains(err.Error(), "raw-secret-name") || strings.Contains(err.Error(), string(body)) { + t.Fatalf("error leaked payload details: %v", err) + } +} + func TestProcessJobWithObjectsFailsSafelyForPayloadProblems(t *testing.T) { state := app.PersistedState{SBOMs: map[string]domain.SBOM{ "sbom_test": {ID: "sbom_test", TenantID: "ten_test"}, @@ -332,3 +428,28 @@ func TestOpenObjectStoreRejectsIncompleteS3ConfigurationWithoutSecretsInError(t t.Fatalf("S3 configuration error leaked credential material: %v", err) } } + +func dsseEnvelopeForTest(t *testing.T, digest string) []byte { + t.Helper() + statement, err := json.Marshal(map[string]any{ + "_type": "https://in-toto.io/Statement/v1", + "predicateType": "https://slsa.dev/provenance/v1", + "subject": []map[string]any{{ + "name": "api", + "digest": map[string]string{"sha256": strings.TrimPrefix(digest, "sha256:")}, + }}, + "predicate": map[string]any{"builder": map[string]string{"id": "github-actions"}, "buildType": "test", "materials": []any{}}, + }) + if err != nil { + t.Fatal(err) + } + envelope, err := json.Marshal(map[string]any{ + "payloadType": "application/vnd.in-toto+json", + "payload": base64.StdEncoding.EncodeToString(statement), + "signatures": []map[string]string{{"sig": "abc"}}, + }) + if err != nil { + t.Fatal(err) + } + return envelope +} diff --git a/docs/architecture.md b/docs/architecture.md index ff37d44..ed623e3 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -52,6 +52,6 @@ Air-gapped import-bundle workflows preserve the same tenant-scoped import path a ## Limitations -The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts are implemented, but production KMS/HSM provider adapters and live Sigstore/public-transparency verification remain deployment hardening work. Hand-tuned per-resource repository implementations, object-store replay parsers, complete endpoint-specific OpenAPI schemas, CI-enforced live PostgreSQL checks, and the production coverage threshold remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. +The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts are implemented, but production KMS/HSM provider adapters and live Sigstore/public-transparency verification remain deployment hardening work. Hand-tuned per-resource repository implementations, moving parser side effects fully out of request paths, and complete endpoint-specific OpenAPI schemas remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. Evydence does not prove provider truth, scanner authority, runtime security, legal compliance, or release security by itself. diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index b96d5ea..05969ba 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -16,12 +16,13 @@ Known hardening work remains: - canonical production persistence still needs hand-tuned relational repository paths for all high-risk resource families; -- worker parser jobs need to re-read raw object-store payloads and produce - parser side effects independently of the request path; +- worker parser jobs re-read raw object-store payloads for key formats and + validate durable state, but parser side effects still need to move + independently out of the request path; - OpenAPI schemas need endpoint-specific precision across the full public API; -- default coverage must reach the production threshold; -- GitHub CI enforces live PostgreSQL release checks; the 80 percent production - coverage threshold remains hardening work. +- GitHub CI enforces live PostgreSQL release checks and the default 80 percent + production coverage threshold, but the broader production exit review remains + incomplete. ## Production Profiles diff --git a/docs/reference/worker-outbox.md b/docs/reference/worker-outbox.md index 147c424..77cf2ca 100644 --- a/docs/reference/worker-outbox.md +++ b/docs/reference/worker-outbox.md @@ -12,7 +12,9 @@ Configured job kinds: - `verify_subject` - `verify_attestation` -Current behavior is intentionally conservative. The API performs parsing, signing, and verification synchronously before enqueueing jobs. The worker then validates that tenant-prefixed payload objects can be read when `payload_ref` is present, verifies object metadata and byte digests when `payload_hash` is present, and validates that the expected durable state exists. Missing objects, wrong tenant prefixes, tenant mismatches, oversized payload objects, incomplete verification, missing signatures, hash mismatch, uninitialized storage, and unsupported job kinds fail the job safely. +Current behavior is intentionally conservative. The API still records normalized parser, signing, and verification results before enqueueing jobs for the implemented upload paths. The worker independently replays tenant-prefixed payload objects when `payload_ref` is present, verifies object metadata and byte digests when `payload_hash` is present, parses SBOM, vulnerability-scan, OpenAPI, OpenVEX, and DSSE attestation payloads, and checks that replayed payload summaries match the expected durable state. Missing objects, wrong tenant prefixes, tenant mismatches, oversized payload objects, malformed replay payloads, durable-state mismatches, incomplete verification, missing signatures, hash mismatch, uninitialized storage, and unsupported job kinds fail the job safely. + +Parser replay currently validates durable side effects instead of being the only writer of normalized records. Moving parser side effects fully out of the request path remains production hardening work. Workers use the same object-store environment variables as the API. The default worker payload replay limit is 20 MiB and can be adjusted with `EVYDENCE_WORKER_MAX_PAYLOAD_BYTES`. From 3e1159b09ba3c8861201de45ebe90eefb118de45 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 18:00:45 +0300 Subject: [PATCH 049/287] docs: tighten release ledger openapi contracts --- docs/reference/api-contract-matrix.md | 36 ++-- internal/adapters/httpapi/openapi.go | 156 ++++++++++++++++++ .../adapters/httpapi/openapi_operations.go | 65 ++++++++ internal/adapters/httpapi/router_test.go | 33 +++- openapi.yaml | 2 +- 5 files changed, 272 insertions(+), 20 deletions(-) diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index c86426b..6e617c6 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 160 operations: 8 precise, 152 broad. +Generated from 160 operations: 25 precise, 135 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -15,14 +15,14 @@ Generated from 160 operations: 8 precise, 152 broad. | POST | /v1/artifact-signatures | createArtifactSignature | Bearer | evidence:write | required | - | - | 201:unspecified | broad | | GET | /v1/artifact-signatures/{id} | getArtifactSignature | Bearer | evidence:read | - | - | - | 200:unspecified | broad | | POST | /v1/artifact-signatures/{id}/verify-cosign | verifyCosignSignature | Bearer | verify:read | required | - | - | 200:unspecified | broad | -| POST | /v1/artifacts | registerArtifact | Bearer | evidence:write | required | - | - | 201:unspecified | broad | +| POST | /v1/artifacts | registerArtifact | Bearer | evidence:write | required | - | application/json:RegisterArtifactRequest | 201:application/json:ArtifactEnvelope | precise | | GET | /v1/audit-chain/verify | verifyAuditChain | Bearer | verify:read | - | - | - | 200:unspecified | broad | | GET | /v1/audit-log | listAuditLog | Bearer | admin | - | - | - | 200:unspecified | broad | | POST | /v1/backup-manifests | generateBackupManifest | Bearer | admin | required | - | - | 201:unspecified | broad | | GET | /v1/backup-manifests/{id}/verify | verifyBackupManifest | Bearer | verify:read | - | - | - | 200:unspecified | broad | | POST | /v1/build-attestations/{id}/verify-signature | verifyBuildAttestationSignature | Bearer | verify:read | required | - | - | 200:unspecified | broad | -| POST | /v1/builds | createBuild | Bearer | build:write | required | - | - | 201:unspecified | broad | -| GET | /v1/builds/{id} | getBuild | Bearer | build:read | - | - | - | 200:unspecified | broad | +| POST | /v1/builds | createBuild | Bearer | build:write | required | - | application/json:CreateBuildRequest | 201:application/json:BuildRunEnvelope | precise | +| GET | /v1/builds/{id} | getBuild | Bearer | build:read | - | path:id | - | 200:application/json:BuildRunEnvelope | precise | | POST | /v1/builds/{id}/attestations | uploadBuildAttestation | Bearer | build:write | required | - | - | 201:unspecified | broad | | GET | /v1/collectors | listCollectors | Bearer | collector:read | - | - | - | 200:unspecified | broad | | POST | /v1/collectors | createCollector | Bearer | collector:admin | required | - | - | 201:unspecified | broad | @@ -90,9 +90,9 @@ Generated from 160 operations: 8 precise, 152 broad. | GET | /v1/openapi.json | openapi | public | - | - | - | - | 200:unspecified | broad | | POST | /v1/organizations | createOrganization | Bearer | identity:admin | required | - | - | 201:unspecified | broad | | POST | /v1/policies/evaluate | evaluatePolicy | Bearer | verify:read | required | - | - | 201:unspecified | broad | -| GET | /v1/products | listProducts | Bearer | product:read | - | - | - | 200:unspecified | broad | -| POST | /v1/products | createProduct | Bearer | product:write | required | - | - | 201:unspecified | broad | -| POST | /v1/projects | createProject | Bearer | project:write | required | - | - | 201:unspecified | broad | +| GET | /v1/products | listProducts | Bearer | product:read | - | - | - | 200:application/json:ProductListEnvelope | precise | +| POST | /v1/products | createProduct | Bearer | product:write | required | - | application/json:CreateProductRequest | 201:application/json:ProductEnvelope | precise | +| POST | /v1/projects | createProject | Bearer | project:write | required | - | application/json:CreateProjectRequest | 201:application/json:ProjectEnvelope | precise | | POST | /v1/provider-verifications | verifyProviderIdentity | Bearer | identity:admin | required | - | application/json:VerifyProviderIdentityRequest | 201:application/json:ProviderVerificationEnvelope | precise | | POST | /v1/public-transparency-log-entries | publishPublicTransparencyLogEntry | Bearer | keys:admin | required | - | - | 201:unspecified | broad | | POST | /v1/public-transparency-logs | createPublicTransparencyLog | Bearer | keys:admin | required | - | - | 201:unspecified | broad | @@ -110,10 +110,10 @@ Generated from 160 operations: 8 precise, 152 broad. | GET | /v1/release-candidates/{id} | getReleaseCandidate | Bearer | release:read | - | - | - | 200:unspecified | broad | | POST | /v1/release-candidates/{id}/promote | promoteReleaseCandidate | Bearer | release:write | required | - | - | 200:unspecified | broad | | POST | /v1/release-candidates/{id}/reject | rejectReleaseCandidate | Bearer | release:write | required | - | - | 200:unspecified | broad | -| POST | /v1/releases | createRelease | Bearer | release:write | required | - | - | 201:unspecified | broad | -| GET | /v1/releases/{id} | getRelease | Bearer | release:read | - | - | - | 200:unspecified | broad | -| POST | /v1/releases/{id}/approve | approveRelease | Bearer | release:write | required | - | - | 200:unspecified | broad | -| POST | /v1/releases/{id}/freeze | freezeRelease | Bearer | release:write | required | - | - | 200:unspecified | broad | +| POST | /v1/releases | createRelease | Bearer | release:write | required | - | application/json:CreateReleaseRequest | 201:application/json:ReleaseEnvelope | precise | +| GET | /v1/releases/{id} | getRelease | Bearer | release:read | - | path:id | - | 200:application/json:ReleaseEnvelope | precise | +| POST | /v1/releases/{id}/approve | approveRelease | Bearer | release:write | required | path:id | application/json:EmptyObject | 200:application/json:ReleaseEnvelope | precise | +| POST | /v1/releases/{id}/freeze | freezeRelease | Bearer | release:write | required | path:id | application/json:EmptyObject | 200:application/json:ReleaseEnvelope | precise | | POST | /v1/remediation-tasks | createRemediationTask | Bearer | incident:write | required | - | - | 201:unspecified | broad | | POST | /v1/report-templates | createReportTemplate | Bearer | report:read | required | - | - | 201:unspecified | broad | | POST | /v1/report-templates/{id}/render | renderReportTemplate | Bearer | report:read | required | - | - | 201:unspecified | broad | @@ -134,9 +134,9 @@ Generated from 160 operations: 8 precise, 152 broad. | POST | /v1/saas/profiles | createSaaSEditionProfile | Bearer | instance:admin | required | - | - | 201:unspecified | broad | | GET | /v1/sbom-components | listSBOMComponents | Bearer | evidence:read | - | query:artifact_id, query:limit, query:purl, query:query, query:release_id, query:sbom_id | - | 200:application/json:DataEnvelope | broad | | POST | /v1/sbom-diffs | createSBOMDiff | Bearer | evidence:read | required | - | - | 201:unspecified | broad | -| POST | /v1/sboms | uploadSBOM | Bearer | evidence:write | required | - | - | 201:unspecified | broad | +| POST | /v1/sboms | uploadSBOM | Bearer | evidence:write | required | - | application/json:EvidenceUploadRequest | 201:application/json:SBOMEnvelope | precise | | POST | /v1/sboms/spdx | uploadSPDXSBOM | Bearer | evidence:write | required | - | - | 201:unspecified | broad | -| GET | /v1/sboms/{id} | getSBOM | Bearer | evidence:read | - | - | - | 200:unspecified | broad | +| GET | /v1/sboms/{id} | getSBOM | Bearer | evidence:read | - | path:id | - | 200:application/json:SBOMEnvelope | precise | | POST | /v1/security-documents | uploadManualSecurityDocument | Bearer | security:write | required | - | - | 201:unspecified | broad | | POST | /v1/security-scans | uploadSecurityScan | Bearer | security:write | required | - | - | 201:unspecified | broad | | GET | /v1/signing-keys | listSigningKeys | Bearer | verify:read | - | - | - | 200:unspecified | broad | @@ -158,13 +158,13 @@ Generated from 160 operations: 8 precise, 152 broad. | POST | /v1/users/{id}/deactivate | deactivateUser | Bearer | identity:admin | required | - | - | 200:unspecified | broad | | POST | /v1/verify | verify | Bearer | verify:read | required | - | - | 200:unspecified | broad | | GET | /v1/version | version | public | - | - | - | - | 200:unspecified | broad | -| POST | /v1/vex | uploadVEX | Bearer | evidence:write | required | - | - | 201:unspecified | broad | -| POST | /v1/vex/cyclonedx | uploadCycloneDXVEX | Bearer | evidence:write | required | - | - | 201:unspecified | broad | -| GET | /v1/vex/{id} | getVEX | Bearer | evidence:read | - | - | - | 200:unspecified | broad | +| POST | /v1/vex | uploadVEX | Bearer | evidence:write | required | - | application/json:EvidenceUploadRequest | 201:application/json:VEXDocumentEnvelope | precise | +| POST | /v1/vex/cyclonedx | uploadCycloneDXVEX | Bearer | evidence:write | required | - | application/json:EvidenceUploadRequest | 201:application/json:VEXDocumentEnvelope | precise | +| GET | /v1/vex/{id} | getVEX | Bearer | evidence:read | - | path:id | - | 200:application/json:VEXDocumentEnvelope | precise | | POST | /v1/vulnerability-findings/{id}/decisions | createVulnerabilityDecision | Bearer | evidence:write | required | - | - | 201:unspecified | broad | | POST | /v1/vulnerability-findings/{id}/workflow | recordVulnerabilityWorkflow | Bearer | security:write | required | - | - | 201:unspecified | broad | -| POST | /v1/vulnerability-scans | uploadVulnerabilityScan | Bearer | evidence:write | required | - | - | 201:unspecified | broad | -| GET | /v1/vulnerability-scans/{id} | getVulnerabilityScan | Bearer | evidence:read | - | - | - | 200:unspecified | broad | +| POST | /v1/vulnerability-scans | uploadVulnerabilityScan | Bearer | evidence:write | required | - | application/json:UploadVulnerabilityScanRequest | 201:application/json:VulnerabilityScanEnvelope | precise | +| GET | /v1/vulnerability-scans/{id} | getVulnerabilityScan | Bearer | evidence:read | - | path:id | - | 200:application/json:VulnerabilityScanEnvelope | precise | | POST | /v1/waivers | createWaiver | Bearer | policy:write | required | - | - | 201:unspecified | broad | | POST | /v1/waivers/{id}/approve | approveWaiver | Bearer | policy:write | required | - | - | 200:unspecified | broad | diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 819eba6..a00f5df 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -35,6 +35,7 @@ func registerCriticalSchemas(registry *specs.Registry) { "api_version": map[string]any{"type": "string"}, }, "api_version"), }, "data", "meta")) + registry.RegisterSchema("EmptyObject", objectSchema(map[string]any{})) registry.RegisterSchema("InstanceAdminSnapshot", objectSchema(map[string]any{ "tenant_count": map[string]any{"type": "integer"}, "user_count": map[string]any{"type": "integer"}, @@ -102,6 +103,152 @@ func registerCriticalSchemas(registry *specs.Registry) { "secret": map[string]any{"type": "string", "description": "One-time SSO session bearer secret; not returned by list/read operations."}, }, "session", "secret")) registry.RegisterSchema("SSOSessionCreateEnvelope", dataEnvelopeSchema("#/components/schemas/SSOSessionCreateResponse")) + registry.RegisterSchema("CreateProductRequest", objectSchema(map[string]any{ + "name": map[string]any{"type": "string"}, + "slug": map[string]any{"type": "string"}, + }, "name", "slug")) + registry.RegisterSchema("Product", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "slug": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "name", "slug", "schema_version", "created_at")) + registry.RegisterSchema("ProductEnvelope", dataEnvelopeSchema("#/components/schemas/Product")) + registry.RegisterSchema("ProductListEnvelope", dataArrayEnvelopeSchema("#/components/schemas/Product")) + registry.RegisterSchema("CreateProjectRequest", objectSchema(map[string]any{ + "product_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "slug": map[string]any{"type": "string"}, + }, "product_id", "name", "slug")) + registry.RegisterSchema("Project", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "slug": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "product_id", "name", "slug", "schema_version", "created_at")) + registry.RegisterSchema("ProjectEnvelope", dataEnvelopeSchema("#/components/schemas/Project")) + registry.RegisterSchema("CreateReleaseRequest", objectSchema(map[string]any{ + "product_id": map[string]any{"type": "string"}, + "project_id": map[string]any{"type": "string"}, + "version": map[string]any{"type": "string"}, + }, "product_id", "version")) + registry.RegisterSchema("Release", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "project_id": map[string]any{"type": "string"}, + "version": map[string]any{"type": "string"}, + "status": map[string]any{"type": "string", "enum": []string{"draft", "frozen", "approved"}}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + "frozen_at": map[string]any{"type": "string", "format": "date-time"}, + "approved_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "product_id", "version", "status", "schema_version", "created_at")) + registry.RegisterSchema("ReleaseEnvelope", dataEnvelopeSchema("#/components/schemas/Release")) + registry.RegisterSchema("RegisterArtifactRequest", objectSchema(map[string]any{ + "release_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "media_type": map[string]any{"type": "string"}, + "digest": map[string]any{"type": "string", "pattern": "^sha256:"}, + "size": map[string]any{"type": "integer", "minimum": 0}, + "subject_ref": map[string]any{"type": "string"}, + }, "name", "digest")) + registry.RegisterSchema("Artifact", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "media_type": map[string]any{"type": "string"}, + "digest": map[string]any{"type": "string"}, + "size": map[string]any{"type": "integer"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "name", "digest", "schema_version", "created_at")) + registry.RegisterSchema("ArtifactEnvelope", dataEnvelopeSchema("#/components/schemas/Artifact")) + registry.RegisterSchema("CreateBuildRequest", objectSchema(map[string]any{ + "project_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "provider": map[string]any{"type": "string"}, + "commit_sha": map[string]any{"type": "string"}, + "status": map[string]any{"type": "string", "enum": []string{"queued", "running", "passed", "failed", "cancelled"}}, + "started_at": map[string]any{"type": "string", "format": "date-time"}, + "completed_at": map[string]any{"type": "string", "format": "date-time"}, + "github": map[string]any{"type": "object"}, + "outputs": map[string]any{"type": "array", "items": map[string]any{"type": "object"}}, + }, "project_id", "release_id", "provider", "commit_sha", "status", "started_at")) + registry.RegisterSchema("BuildRun", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "collector_id": map[string]any{"type": "string"}, + "project_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "provider": map[string]any{"type": "string"}, + "commit_sha": map[string]any{"type": "string"}, + "status": map[string]any{"type": "string"}, + "outputs": map[string]any{"type": "array", "items": map[string]any{"type": "object"}}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "project_id", "release_id", "provider", "commit_sha", "status", "schema_version", "created_at")) + registry.RegisterSchema("BuildRunEnvelope", dataEnvelopeSchema("#/components/schemas/BuildRun")) + registry.RegisterSchema("EvidenceUploadRequest", objectSchema(map[string]any{ + "release_id": map[string]any{"type": "string"}, + "artifact_id": map[string]any{"type": "string"}, + "payload": map[string]any{"type": "object"}, + }, "release_id", "payload")) + registry.RegisterSchema("SBOM", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "evidence_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "artifact_id": map[string]any{"type": "string"}, + "format": map[string]any{"type": "string"}, + "spec_version": map[string]any{"type": "string"}, + "component_count": map[string]any{"type": "integer"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "evidence_id", "release_id", "format", "component_count", "created_at")) + registry.RegisterSchema("SBOMEnvelope", dataEnvelopeSchema("#/components/schemas/SBOM")) + registry.RegisterSchema("VEXDocument", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "evidence_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "artifact_id": map[string]any{"type": "string"}, + "format": map[string]any{"type": "string"}, + "author": map[string]any{"type": "string"}, + "statement_count": map[string]any{"type": "integer"}, + "status_summary": map[string]any{"type": "object", "additionalProperties": map[string]any{"type": "integer"}}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "evidence_id", "release_id", "format", "statement_count", "schema_version", "created_at")) + registry.RegisterSchema("VEXDocumentEnvelope", dataEnvelopeSchema("#/components/schemas/VEXDocument")) + registry.RegisterSchema("VulnerabilityScan", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "scanner": map[string]any{"type": "string"}, + "target_ref": map[string]any{"type": "string"}, + "summary": map[string]any{"type": "object", "additionalProperties": map[string]any{"type": "integer"}}, + "findings": map[string]any{"type": "array", "items": map[string]any{"type": "object"}}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "release_id", "scanner", "target_ref", "summary", "findings", "created_at")) + registry.RegisterSchema("VulnerabilityScanEnvelope", dataEnvelopeSchema("#/components/schemas/VulnerabilityScan")) + registry.RegisterSchema("UploadVulnerabilityScanRequest", objectSchema(map[string]any{ + "scanner": map[string]any{"type": "string"}, + "target_ref": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "findings": map[string]any{"type": "array", "items": objectSchema(map[string]any{ + "vulnerability": map[string]any{"type": "string"}, + "component": map[string]any{"type": "string"}, + "severity": map[string]any{"type": "string"}, + "state": map[string]any{"type": "string"}, + }, "vulnerability", "severity")}, + }, "scanner", "target_ref", "release_id", "findings")) registry.RegisterSchema("CreateEvidenceRequest", objectSchema(map[string]any{ "product_id": map[string]any{"type": "string"}, "project_id": map[string]any{"type": "string"}, @@ -166,3 +313,12 @@ func dataEnvelopeSchema(dataRef string) map[string]any { }, "api_version"), }, "data", "meta") } + +func dataArrayEnvelopeSchema(itemRef string) map[string]any { + return objectSchema(map[string]any{ + "data": map[string]any{"type": "array", "items": map[string]any{"$ref": itemRef}}, + "meta": objectSchema(map[string]any{ + "api_version": map[string]any{"type": "string"}, + }, "api_version"), + }, "data", "meta") +} diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 42367d6..bc9c84b 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -24,6 +24,71 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Description = "Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material." operation.RequestBody = jsonRequest("Provider identity verification request.", "#/components/schemas/VerifyProviderIdentityRequest") operation.Responses[http.StatusCreated] = jsonResponse("Provider verification envelope.", "#/components/schemas/ProviderVerificationEnvelope") + case "createProduct": + operation.Description = "Creates a tenant-scoped product. Product slugs must be unique per tenant." + operation.RequestBody = jsonRequest("Product creation request.", "#/components/schemas/CreateProductRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created product envelope.", "#/components/schemas/ProductEnvelope") + case "listProducts": + operation.Description = "Lists tenant-scoped products visible to the authenticated actor." + operation.Responses[http.StatusOK] = jsonResponse("Product list envelope.", "#/components/schemas/ProductListEnvelope") + case "createProject": + operation.Description = "Creates a tenant-scoped project under a product." + operation.RequestBody = jsonRequest("Project creation request.", "#/components/schemas/CreateProjectRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created project envelope.", "#/components/schemas/ProjectEnvelope") + case "createRelease": + operation.Description = "Creates an append-only release record under a product and optional project." + operation.RequestBody = jsonRequest("Release creation request.", "#/components/schemas/CreateReleaseRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created release envelope.", "#/components/schemas/ReleaseEnvelope") + case "getRelease": + operation.Description = "Returns a tenant-scoped release by id." + operation.Parameters = append(operation.Parameters, pathParam("id", "Release id.")) + operation.Responses[http.StatusOK] = jsonResponse("Release envelope.", "#/components/schemas/ReleaseEnvelope") + case "freezeRelease": + operation.Description = "Freezes a release as an append-only transition." + operation.Parameters = append(operation.Parameters, pathParam("id", "Release id.")) + operation.RequestBody = jsonRequest("Empty JSON object.", "#/components/schemas/EmptyObject") + operation.Responses[http.StatusOK] = jsonResponse("Frozen release envelope.", "#/components/schemas/ReleaseEnvelope") + case "approveRelease": + operation.Description = "Approves a release as an append-only transition." + operation.Parameters = append(operation.Parameters, pathParam("id", "Release id.")) + operation.RequestBody = jsonRequest("Empty JSON object.", "#/components/schemas/EmptyObject") + operation.Responses[http.StatusOK] = jsonResponse("Approved release envelope.", "#/components/schemas/ReleaseEnvelope") + case "registerArtifact": + operation.Description = "Registers an artifact digest for release evidence and later build/attestation matching." + operation.RequestBody = jsonRequest("Artifact registration request.", "#/components/schemas/RegisterArtifactRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Registered artifact envelope.", "#/components/schemas/ArtifactEnvelope") + case "createBuild": + operation.Description = "Records an immutable CI build run. Collector identity is derived from the authenticated key when present." + operation.RequestBody = jsonRequest("Build run creation request.", "#/components/schemas/CreateBuildRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created build run envelope.", "#/components/schemas/BuildRunEnvelope") + case "getBuild": + operation.Description = "Returns a tenant-scoped build run by id." + operation.Parameters = append(operation.Parameters, pathParam("id", "Build run id.")) + operation.Responses[http.StatusOK] = jsonResponse("Build run envelope.", "#/components/schemas/BuildRunEnvelope") + case "uploadSBOM": + operation.Description = "Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata." + operation.RequestBody = jsonRequest("CycloneDX SBOM upload request.", "#/components/schemas/EvidenceUploadRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created SBOM envelope.", "#/components/schemas/SBOMEnvelope") + case "getSBOM": + operation.Description = "Returns a tenant-scoped SBOM metadata record by id." + operation.Parameters = append(operation.Parameters, pathParam("id", "SBOM id.")) + operation.Responses[http.StatusOK] = jsonResponse("SBOM envelope.", "#/components/schemas/SBOMEnvelope") + case "uploadVEX", "uploadCycloneDXVEX": + operation.Description = "Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable." + operation.RequestBody = jsonRequest("VEX upload request.", "#/components/schemas/EvidenceUploadRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created VEX document envelope.", "#/components/schemas/VEXDocumentEnvelope") + case "getVEX": + operation.Description = "Returns a tenant-scoped VEX document metadata record by id." + operation.Parameters = append(operation.Parameters, pathParam("id", "VEX document id.")) + operation.Responses[http.StatusOK] = jsonResponse("VEX document envelope.", "#/components/schemas/VEXDocumentEnvelope") + case "uploadVulnerabilityScan": + operation.Description = "Uploads a generic vulnerability scan JSON payload and records normalized findings." + operation.RequestBody = jsonRequest("Vulnerability scan upload payload.", "#/components/schemas/UploadVulnerabilityScanRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created vulnerability scan envelope.", "#/components/schemas/VulnerabilityScanEnvelope") + case "getVulnerabilityScan": + operation.Description = "Returns a tenant-scoped vulnerability scan by id." + operation.Parameters = append(operation.Parameters, pathParam("id", "Vulnerability scan id.")) + operation.Responses[http.StatusOK] = jsonResponse("Vulnerability scan envelope.", "#/components/schemas/VulnerabilityScanEnvelope") case "createEvidence": operation.Description = "Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation." operation.RequestBody = jsonRequest("Evidence creation request.", "#/components/schemas/CreateEvidenceRequest") diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index e69fbab..21ec2f6 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -84,13 +84,44 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { if _, ok := problemProps["request_id"]; !ok { t.Fatalf("Problem schema missing request_id: %#v", problemProps) } - for _, schemaName := range []string{"CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "DataEnvelope"} { + for _, schemaName := range []string{"CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "DataEnvelope"} { if _, ok := schemas[schemaName]; !ok { t.Fatalf("schema %s missing from OpenAPI components", schemaName) } } paths := asStringAnyMap(t, doc["paths"]) + createProduct := operationMap(t, paths, "/v1/products", "post") + assertRequestRef(t, createProduct, "#/components/schemas/CreateProductRequest") + assertResponseRef(t, createProduct, "201", "#/components/schemas/ProductEnvelope") + listProducts := operationMap(t, paths, "/v1/products", "get") + assertResponseRef(t, listProducts, "200", "#/components/schemas/ProductListEnvelope") + createProject := operationMap(t, paths, "/v1/projects", "post") + assertRequestRef(t, createProject, "#/components/schemas/CreateProjectRequest") + assertResponseRef(t, createProject, "201", "#/components/schemas/ProjectEnvelope") + createRelease := operationMap(t, paths, "/v1/releases", "post") + assertRequestRef(t, createRelease, "#/components/schemas/CreateReleaseRequest") + assertResponseRef(t, createRelease, "201", "#/components/schemas/ReleaseEnvelope") + getRelease := operationMap(t, paths, "/v1/releases/{id}", "get") + assertResponseRef(t, getRelease, "200", "#/components/schemas/ReleaseEnvelope") + freezeRelease := operationMap(t, paths, "/v1/releases/{id}/freeze", "post") + assertRequestRef(t, freezeRelease, "#/components/schemas/EmptyObject") + assertResponseRef(t, freezeRelease, "200", "#/components/schemas/ReleaseEnvelope") + registerArtifact := operationMap(t, paths, "/v1/artifacts", "post") + assertRequestRef(t, registerArtifact, "#/components/schemas/RegisterArtifactRequest") + assertResponseRef(t, registerArtifact, "201", "#/components/schemas/ArtifactEnvelope") + createBuild := operationMap(t, paths, "/v1/builds", "post") + assertRequestRef(t, createBuild, "#/components/schemas/CreateBuildRequest") + assertResponseRef(t, createBuild, "201", "#/components/schemas/BuildRunEnvelope") + uploadSBOM := operationMap(t, paths, "/v1/sboms", "post") + assertRequestRef(t, uploadSBOM, "#/components/schemas/EvidenceUploadRequest") + assertResponseRef(t, uploadSBOM, "201", "#/components/schemas/SBOMEnvelope") + uploadVulnerabilityScan := operationMap(t, paths, "/v1/vulnerability-scans", "post") + assertRequestRef(t, uploadVulnerabilityScan, "#/components/schemas/UploadVulnerabilityScanRequest") + assertResponseRef(t, uploadVulnerabilityScan, "201", "#/components/schemas/VulnerabilityScanEnvelope") + uploadVEX := operationMap(t, paths, "/v1/vex", "post") + assertRequestRef(t, uploadVEX, "#/components/schemas/EvidenceUploadRequest") + assertResponseRef(t, uploadVEX, "201", "#/components/schemas/VEXDocumentEnvelope") createEvidence := operationMap(t, paths, "/v1/evidence", "post") assertRequestRef(t, createEvidence, "#/components/schemas/CreateEvidenceRequest") assertProblemResponseRef(t, createEvidence, "400") diff --git a/openapi.yaml b/openapi.yaml index 968c0fe..44b6d59 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{},"payload_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source":{"type":"string"},"subject_refs":{"items":{"type":"string"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"type":"object"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"api_key_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"},"user_count":{"type":"integer"}},"required":["tenant_count","resource_counts"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"List API keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"201":{"description":"Create API key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"201":{"description":"Create artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"Get artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"Verify cosign-style artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"operationId":"registerArtifact","responses":{"201":{"description":"Register artifact response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"Verify audit chain response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"List tenant audit log response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"operationId":"generateBackupManifest","responses":{"201":{"description":"Generate backup manifest response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"operationId":"verifyBackupManifest","responses":{"200":{"description":"Verify backup manifest response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"Verify build attestation signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"operationId":"createBuild","responses":{"201":{"description":"Create build run response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"operationId":"getBuild","responses":{"200":{"description":"Get build run response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"201":{"description":"Upload build attestation response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"List collectors response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"201":{"description":"Create collector response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"operationId":"uploadGitHubSourceSnapshot","responses":{"201":{"description":"Upload GitHub source snapshot response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"operationId":"uploadGitLabSourceSnapshot","responses":{"201":{"description":"Upload GitLab source snapshot response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"List control evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"List control frameworks response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"201":{"description":"Create control framework response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"201":{"description":"Create security control response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"Get security control response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"201":{"description":"Link control evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"201":{"description":"Create custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"201":{"description":"Evaluate custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"List deployments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"201":{"description":"Record deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"Get deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"201":{"description":"Create DSSE trust root response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"List deployment environments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"201":{"description":"Create deployment environment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"List evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"operationId":"createGraphSnapshot","responses":{"201":{"description":"Create evidence graph snapshot response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"Get evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"List evidence lifecycle events response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"201":{"description":"Record evidence lifecycle event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"201":{"description":"Link evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"201":{"description":"Supersede evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"List exceptions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"201":{"description":"Create exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"Approve exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"Health response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"Safe tenant metrics response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"201":{"description":"Upload OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"Get OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"201":{"description":"Create OpenAPI contract diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OpenAPI response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"201":{"description":"Create organization response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"201":{"description":"Evaluate release policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"operationId":"listProducts","responses":{"200":{"description":"List products response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"operationId":"createProduct","responses":{"201":{"description":"Create product response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"operationId":"createProject","responses":{"201":{"description":"Create project response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"operationId":"ready","responses":{"200":{"description":"Readiness response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"Get release bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"Get release bundle manifest response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"List release candidates response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"201":{"description":"Create release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"Get release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"Promote release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"Reject release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"operationId":"createRelease","responses":{"201":{"description":"Create release response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"operationId":"getRelease","responses":{"200":{"description":"Get release response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"operationId":"approveRelease","responses":{"200":{"description":"Approve release response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"operationId":"freezeRelease","responses":{"200":{"description":"Freeze release response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"operationId":"controlCoverageReport","responses":{"200":{"description":"Control coverage report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"operationId":"craReadinessReport","responses":{"200":{"description":"CRA readiness report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"Missing evidence report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"operationId":"releaseReadinessReport","responses":{"200":{"description":"Release readiness report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"List role bindings response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"201":{"description":"Create role binding response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"operationId":"uploadSBOM","responses":{"201":{"description":"Upload CycloneDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"operationId":"getSBOM","responses":{"200":{"description":"Get SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"List signing keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"201":{"description":"Rotate signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"Revoke signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"201":{"description":"Create signing provider operation receipt response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"201":{"description":"Create signing provider record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"201":{"description":"Record source branch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"201":{"description":"Record source commit response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"201":{"description":"Record pull request response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"List source repositories response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"201":{"description":"Create source repository response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"201":{"description":"Link SSO identity response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"Revoke SSO session response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"201":{"description":"Create user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"Deactivate user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"Version response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"operationId":"uploadVEX","responses":{"201":{"description":"Upload OpenVEX document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"operationId":"uploadCycloneDXVEX","responses":{"201":{"description":"Upload CycloneDX VEX document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"operationId":"getVEX","responses":{"200":{"description":"Get VEX document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"201":{"description":"Create vulnerability decision response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"201":{"description":"Record vulnerability workflow event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"operationId":"uploadVulnerabilityScan","responses":{"201":{"description":"Upload vulnerability scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"operationId":"getVulnerabilityScan","responses":{"200":{"description":"Get vulnerability scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"201":{"description":"Create waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"Approve waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{},"payload_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source":{"type":"string"},"subject_refs":{"items":{"type":"string"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"type":"object"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"api_key_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"},"user_count":{"type":"integer"}},"required":["tenant_count","resource_counts"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"List API keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"201":{"description":"Create API key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"201":{"description":"Create artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"Get artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"Verify cosign-style artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"Verify audit chain response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"List tenant audit log response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"operationId":"generateBackupManifest","responses":{"201":{"description":"Generate backup manifest response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"operationId":"verifyBackupManifest","responses":{"200":{"description":"Verify backup manifest response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"Verify build attestation signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"201":{"description":"Upload build attestation response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"List collectors response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"201":{"description":"Create collector response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"operationId":"uploadGitHubSourceSnapshot","responses":{"201":{"description":"Upload GitHub source snapshot response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"operationId":"uploadGitLabSourceSnapshot","responses":{"201":{"description":"Upload GitLab source snapshot response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"List control evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"List control frameworks response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"201":{"description":"Create control framework response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"201":{"description":"Create security control response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"Get security control response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"201":{"description":"Link control evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"201":{"description":"Create custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"201":{"description":"Evaluate custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"List deployments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"201":{"description":"Record deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"Get deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"201":{"description":"Create DSSE trust root response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"List deployment environments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"201":{"description":"Create deployment environment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"List evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"operationId":"createGraphSnapshot","responses":{"201":{"description":"Create evidence graph snapshot response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"Get evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"List evidence lifecycle events response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"201":{"description":"Record evidence lifecycle event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"201":{"description":"Link evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"201":{"description":"Supersede evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"List exceptions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"201":{"description":"Create exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"Approve exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"Health response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"Safe tenant metrics response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"201":{"description":"Upload OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"Get OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"201":{"description":"Create OpenAPI contract diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OpenAPI response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"201":{"description":"Create organization response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"201":{"description":"Evaluate release policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"operationId":"ready","responses":{"200":{"description":"Readiness response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"Get release bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"Get release bundle manifest response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"List release candidates response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"201":{"description":"Create release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"Get release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"Promote release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"Reject release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"operationId":"controlCoverageReport","responses":{"200":{"description":"Control coverage report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"operationId":"craReadinessReport","responses":{"200":{"description":"CRA readiness report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"Missing evidence report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"operationId":"releaseReadinessReport","responses":{"200":{"description":"Release readiness report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"List role bindings response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"201":{"description":"Create role binding response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"List signing keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"201":{"description":"Rotate signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"Revoke signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"201":{"description":"Create signing provider operation receipt response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"201":{"description":"Create signing provider record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"201":{"description":"Record source branch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"201":{"description":"Record source commit response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"201":{"description":"Record pull request response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"List source repositories response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"201":{"description":"Create source repository response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"201":{"description":"Link SSO identity response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"Revoke SSO session response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"201":{"description":"Create user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"Deactivate user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"Version response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"201":{"description":"Create vulnerability decision response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"201":{"description":"Record vulnerability workflow event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"201":{"description":"Create waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"Approve waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From afacdfeb7489e0ad006b2e520b68236cfd6e71d9 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 18:05:49 +0300 Subject: [PATCH 050/287] test: add restore rehearsal coverage --- docs/production-hardening.md | 2 + docs/reference/production-readiness.md | 3 +- internal/app/integrity_runtime_test.go | 84 ++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 1 deletion(-) diff --git a/docs/production-hardening.md b/docs/production-hardening.md index fb2d9b8..0748820 100644 --- a/docs/production-hardening.md +++ b/docs/production-hardening.md @@ -33,6 +33,8 @@ These checks are enforced by API startup. See [Configuration](reference/configur - Audit-chain verification and release-bundle verification are run after restore. - `POST /v1/backup-manifests` is recorded after the database and object-store backups complete. +The repository includes a local restore rehearsal that saves ledger state, copies object payloads, starts a fresh ledger from the restored state, verifies a backup manifest, checks payload digest availability, and verifies a release bundle after restore. Deployment-specific restore tests still need to exercise the target PostgreSQL, object store, secrets, signing provider, and backup tooling. + Backup manifests help compare recorded ledger state. They intentionally exclude raw payload bytes and private signing-key material, so they cannot replace matched database and object-store backups. ## Deployment Verification diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 05969ba..7434b81 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -67,7 +67,8 @@ Do not describe an Evydence build as broadly self-hosted production-ready until: - `make production-check` passes in CI with live PostgreSQL; - coverage is at or above the configured threshold; - release artifacts have signed manifests and published checksums; -- backup and restore have been tested for the target deployment profile; +- the built-in local restore rehearsal passes and backup/restore have been + tested for the target deployment profile; - OpenAPI and SDK drift checks pass; - production hardening review is current; - unresolved limitations are documented in release notes. diff --git a/internal/app/integrity_runtime_test.go b/internal/app/integrity_runtime_test.go index f91c5ff..e6034fc 100644 --- a/internal/app/integrity_runtime_test.go +++ b/internal/app/integrity_runtime_test.go @@ -3,6 +3,7 @@ package app import ( "context" "errors" + "strings" "testing" "time" ) @@ -119,6 +120,89 @@ func TestRuntimeRetentionBackupReadinessMetricsAndAudit(t *testing.T) { } } +func TestBackupRestoreRehearsalPreservesLedgerAndObjectPayloads(t *testing.T) { + ctx := context.Background() + store := NewMemoryStore() + objects := newTestObjectStore() + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow, Store: store, ObjectStore: objects}) + _, _, secret, err := ledger.BootstrapTenant(ctx, "Tenant", "admin", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap: %v", err) + } + actor, err := ledger.Authenticate(ctx, secret) + if err != nil { + t.Fatalf("auth: %v", err) + } + product, err := ledger.CreateProduct(ctx, actor, "Payments API", "payments") + if err != nil { + t.Fatalf("product: %v", err) + } + release, err := ledger.CreateRelease(ctx, actor, product.ID, "1.0.0") + if err != nil { + t.Fatalf("release: %v", err) + } + artifact, err := ledger.RegisterArtifact(ctx, actor, "payments-api.tar.gz", "application/gzip", sampleDigest("artifact"), 123) + if err != nil { + t.Fatalf("artifact: %v", err) + } + sbom, err := ledger.UploadSBOM(ctx, actor, release.ID, artifact.ID, []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","components":[{"name":"api","purl":"pkg:oci/api"}]}`)) + if err != nil { + t.Fatalf("upload sbom: %v", err) + } + bundle, err := ledger.CreateReleaseBundle(ctx, actor, release.ID) + if err != nil { + t.Fatalf("release bundle: %v", err) + } + manifest, err := ledger.GenerateBackupManifest(ctx, actor) + if err != nil { + t.Fatalf("backup manifest: %v", err) + } + if manifest.StateHash == "" || manifest.ResourceCounts["evidence"] == 0 { + t.Fatalf("manifest missing restore-relevant counts: %#v", manifest) + } + + dbBackup, ok, err := store.LoadState(ctx) + if err != nil || !ok { + t.Fatalf("load backed-up state ok=%v err=%v", ok, err) + } + objectBackup := map[string]Object{} + for key, object := range objects.objects { + objectBackup[key] = object + } + restoredStore := NewMemoryStore() + if err := restoredStore.SaveState(ctx, dbBackup); err != nil { + t.Fatalf("restore state: %v", err) + } + restoredObjects := &testObjectStore{objects: objectBackup} + restored := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow, Store: restoredStore, ObjectStore: restoredObjects}) + + restoredActor, err := restored.Authenticate(ctx, secret) + if err != nil { + t.Fatalf("authenticate restored api key: %v", err) + } + if _, err := restored.VerifyBackupManifest(ctx, restoredActor, manifest.ID); err != nil { + t.Fatalf("verify restored backup manifest: %v", err) + } + restoredSBOM, err := restored.GetSBOM(ctx, restoredActor, sbom.ID) + if err != nil || restoredSBOM.ComponentCount != sbom.ComponentCount { + t.Fatalf("restored sbom = %#v err=%v", restoredSBOM, err) + } + evidence, err := restored.GetEvidence(ctx, restoredActor, restoredSBOM.EvidenceID) + if err != nil { + t.Fatalf("restored evidence: %v", err) + } + payloadKey := strings.TrimPrefix(evidence.PayloadRef, "object://") + if payloadKey == "" { + t.Fatalf("restored evidence missing payload ref: %#v", evidence) + } + if object, err := restoredObjects.Get(ctx, payloadKey); err != nil || object.Digest != evidence.PayloadHash { + t.Fatalf("restored object digest=%q err=%v want %q", object.Digest, err, evidence.PayloadHash) + } + if vr, err := restored.VerifySubject(ctx, restoredActor, "release_bundle", bundle.ID); err != nil || vr.Result != "passed" { + t.Fatalf("verify restored bundle = %#v err=%v", vr, err) + } +} + func TestSigningProviderRejectsPlaintextLocalDev(t *testing.T) { ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) ctx := context.Background() From a0c5ee161d40d867cd728c3e8dd463991021b9e4 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 18:10:24 +0300 Subject: [PATCH 051/287] feat: add api rate limiting hook --- .api.env.example | 1 + cmd/evydence-api/main.go | 17 ++++- cmd/evydence-api/main_test.go | 11 ++++ docs/production-hardening.md | 1 + docs/reference/configuration.md | 1 + internal/adapters/httpapi/router.go | 83 ++++++++++++++++++++++-- internal/adapters/httpapi/router_test.go | 32 +++++++++ internal/app/errors.go | 1 + internal/app/ledger.go | 4 ++ 9 files changed, 144 insertions(+), 7 deletions(-) diff --git a/.api.env.example b/.api.env.example index 11b8100..7a2a49c 100644 --- a/.api.env.example +++ b/.api.env.example @@ -3,6 +3,7 @@ EVYDENCE_API_KEY_PEPPER=change-me-long-random-pepper EVYDENCE_DATABASE_URL=postgres://evydence:change-me@localhost:5432/evydence?sslmode=disable EVYDENCE_OBJECT_STORE=filesystem EVYDENCE_OBJECT_DIR=./tmp/objects +EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE=0 # For MinIO/S3, set EVYDENCE_OBJECT_STORE=minio and provide: # EVYDENCE_S3_ENDPOINT=localhost:9000 # EVYDENCE_S3_BUCKET=evydence diff --git a/cmd/evydence-api/main.go b/cmd/evydence-api/main.go index 9a8ac6e..b38dec1 100644 --- a/cmd/evydence-api/main.go +++ b/cmd/evydence-api/main.go @@ -9,6 +9,7 @@ import ( "net/http" "os" "path/filepath" + "strconv" "strings" "time" @@ -80,7 +81,9 @@ func run() error { log.Printf("bootstrapped tenant %s and key %s; set EVYDENCE_PRINT_BOOTSTRAP_SECRET=true for local-only secret output", tenant.ID, key.ID) } } - server, err := httpapi.NewServer(ledger) + server, err := httpapi.NewServerWithOptions(ledger, httpapi.ServerOptions{ + RateLimitRequestsPerMinute: intEnv("EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE", 0), + }) if err != nil { return fmt.Errorf("create server: %w", err) } @@ -120,6 +123,18 @@ func envDefault(name, fallback string) string { return fallback } +func intEnv(name string, fallback int) int { + value := strings.TrimSpace(os.Getenv(name)) + if value == "" { + return fallback + } + parsed, err := strconv.Atoi(value) + if err != nil || parsed < 0 { + return fallback + } + return parsed +} + func openObjectStore(ctx context.Context) (app.ObjectStore, string, error) { switch strings.ToLower(strings.TrimSpace(os.Getenv("EVYDENCE_OBJECT_STORE"))) { case "", "file", "filesystem": diff --git a/cmd/evydence-api/main_test.go b/cmd/evydence-api/main_test.go index bb46f31..3ec5255 100644 --- a/cmd/evydence-api/main_test.go +++ b/cmd/evydence-api/main_test.go @@ -69,6 +69,17 @@ func TestEnvDefaultAndObjectStoreSelection(t *testing.T) { } } +func TestIntEnvParsesRateLimitConfiguration(t *testing.T) { + t.Setenv("EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE", "25") + if got := intEnv("EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE", 0); got != 25 { + t.Fatalf("configured int env = %d", got) + } + t.Setenv("EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE", "-1") + if got := intEnv("EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE", 7); got != 7 { + t.Fatalf("negative int env fallback = %d", got) + } +} + func TestOpenObjectStoreRejectsIncompleteS3Config(t *testing.T) { t.Setenv("EVYDENCE_OBJECT_STORE", "s3") t.Setenv("EVYDENCE_S3_ENDPOINT", "localhost:9000") diff --git a/docs/production-hardening.md b/docs/production-hardening.md index 0748820..1c6380b 100644 --- a/docs/production-hardening.md +++ b/docs/production-hardening.md @@ -19,6 +19,7 @@ These checks are enforced by API startup. See [Configuration](reference/configur - PostgreSQL is external, backed up, monitored, and restored in a test environment. - Object storage is external S3/MinIO-compatible storage with tenant-prefixed paths, encryption, lifecycle policy, and retention/object-lock policy where required. - Ingress terminates TLS and does not expose internal diagnostics. +- Edge rate limiting is configured at the reverse proxy or ingress. The optional `EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE` in-process limiter is a local safety net and keys by TCP remote address only. - `/v1/metrics`, `/v1/audit-log`, and `/v1/admin/instance` are protected by server-side scopes and are not public. - API keys and collector keys are scoped, rotated, and stored outside source control. - Customer portal access tokens are short-lived, scoped to one package, and handled as bearer secrets. diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 46038ed..b2e6030 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -35,6 +35,7 @@ The example secrets are placeholders. Replace them before using shared or produc | `EVYDENCE_S3_SECRET_ACCESS_KEY` | S3/MinIO object store | local example value | Store outside source control and logs. | | `EVYDENCE_S3_REGION` | No | empty | Optional S3 region. | | `EVYDENCE_S3_USE_SSL` | No | `false` locally, `true` in chart values | Use TLS for remote object storage. | +| `EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE` | No | `0` disabled | Optional in-process per-client request limit using the TCP remote address. Use reverse-proxy or ingress rate limiting for production edge controls. | | `EVYDENCE_SKIP_MIGRATIONS` | No | unset | Set to `true` only when migrations are applied by a separate release process. | | `EVYDENCE_MIGRATIONS_DIR` | No | `migrations` | Migration directory for API startup and `cmd/evydence-migrate`. | | `EVYDENCE_BOOTSTRAP_TENANT` | No | `Local Tenant` | Tenant name used when bootstrapping an empty store. | diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index 7b5ad2d..23cf8da 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -7,9 +7,11 @@ import ( "encoding/json" "errors" "io" + "net" "net/http" "strconv" "strings" + "sync" "time" "github.com/aatuh/api-toolkit/v3/httpx" @@ -25,13 +27,22 @@ const maxJSONBody = 2 << 20 const requestIDHeader = "X-Request-ID" type Server struct { - ledger *app.Ledger - mux *http.ServeMux - specs *specs.Registry - routes *routecontracts.Registry + ledger *app.Ledger + mux *http.ServeMux + specs *specs.Registry + routes *routecontracts.Registry + limiter *requestRateLimiter +} + +type ServerOptions struct { + RateLimitRequestsPerMinute int } func NewServer(ledger *app.Ledger) (*Server, error) { + return NewServerWithOptions(ledger, ServerOptions{}) +} + +func NewServerWithOptions(ledger *app.Ledger, opts ServerOptions) (*Server, error) { if ledger == nil { ledger = app.NewLedger(app.Config{}) } @@ -39,7 +50,7 @@ func NewServer(ledger *app.Ledger) (*Server, error) { specRegistry := NewSpecRegistry() router := &serveMuxRouter{mux: mux} routeRegistry := routecontracts.NewRegistry(router, specRegistry) - server := &Server{ledger: ledger, mux: mux, specs: specRegistry, routes: routeRegistry} + server := &Server{ledger: ledger, mux: mux, specs: specRegistry, routes: routeRegistry, limiter: newRequestRateLimiter(opts.RateLimitRequestsPerMinute)} if err := server.registerRoutes(); err != nil { return nil, err } @@ -47,7 +58,7 @@ func NewServer(ledger *app.Ledger) (*Server, error) { } func (s *Server) Handler() http.Handler { - return secureHeaders(requestIDMiddleware(s.mux)) + return secureHeaders(requestIDMiddleware(s.rateLimitMiddleware(s.mux))) } func (s *Server) OpenAPI() ([]byte, error) { @@ -2116,6 +2127,66 @@ func writeProblem(w http.ResponseWriter, r *http.Request, err error) { httpx.WriteProblem(w, status, problem) } +type requestRateLimiter struct { + mu sync.Mutex + limit int + window time.Duration + buckets map[string]rateLimitBucket +} + +type rateLimitBucket struct { + reset time.Time + used int +} + +func newRequestRateLimiter(limit int) *requestRateLimiter { + if limit <= 0 { + return nil + } + return &requestRateLimiter{limit: limit, window: time.Minute, buckets: map[string]rateLimitBucket{}} +} + +func (s *Server) rateLimitMiddleware(next http.Handler) http.Handler { + if s.limiter == nil { + return next + } + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if !s.limiter.allow(clientRateLimitKey(r), time.Now().UTC()) { + w.Header().Set("Retry-After", "60") + writeProblem(w, r, app.ErrRateLimited) + return + } + next.ServeHTTP(w, r) + }) +} + +func (l *requestRateLimiter) allow(key string, now time.Time) bool { + l.mu.Lock() + defer l.mu.Unlock() + bucket := l.buckets[key] + if bucket.reset.IsZero() || !now.Before(bucket.reset) { + bucket = rateLimitBucket{reset: now.Add(l.window)} + } + if bucket.used >= l.limit { + l.buckets[key] = bucket + return false + } + bucket.used++ + l.buckets[key] = bucket + return true +} + +func clientRateLimitKey(r *http.Request) string { + host, _, err := net.SplitHostPort(strings.TrimSpace(r.RemoteAddr)) + if err == nil && host != "" { + return host + } + if remote := strings.TrimSpace(r.RemoteAddr); remote != "" { + return remote + } + return "unknown" +} + func requestIDMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { requestID := strings.TrimSpace(r.Header.Get(requestIDHeader)) diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 21ec2f6..efb825f 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -248,6 +248,38 @@ func TestCreateProductRequiresAuthAndIdempotency(t *testing.T) { } } +func TestServerRateLimitReturnsSafeProblem(t *testing.T) { + ledger := app.NewLedger(app.Config{APIKeyPepper: "test"}) + server, err := NewServerWithOptions(ledger, ServerOptions{RateLimitRequestsPerMinute: 2}) + if err != nil { + t.Fatalf("NewServerWithOptions: %v", err) + } + handler := server.Handler() + for i := 0; i < 2; i++ { + rec := httptest.NewRecorder() + req := httptest.NewRequest(http.MethodGet, "/v1/version", nil) + req.RemoteAddr = "203.0.113.10:12345" + handler.ServeHTTP(rec, req) + if rec.Code != http.StatusOK { + t.Fatalf("request %d status=%d body=%s", i, rec.Code, rec.Body.String()) + } + } + rec := httptest.NewRecorder() + req := httptest.NewRequest(http.MethodGet, "/v1/version", nil) + req.RemoteAddr = "203.0.113.10:23456" + req.Header.Set("Authorization", "Bearer should-not-leak") + handler.ServeHTTP(rec, req) + if rec.Code != http.StatusTooManyRequests { + t.Fatalf("rate limited status=%d body=%s", rec.Code, rec.Body.String()) + } + if !strings.Contains(rec.Body.String(), "RATE_LIMITED") || strings.Contains(rec.Body.String(), "should-not-leak") { + t.Fatalf("unsafe rate limit problem body: %s", rec.Body.String()) + } + if rec.Header().Get("Retry-After") == "" || rec.Header().Get(requestIDHeader) == "" { + t.Fatalf("missing retry/request headers: %#v", rec.Header()) + } +} + func TestAuthenticatedReadRoutesRejectMissingBearerToken(t *testing.T) { server, _ := testServer(t) paths := []string{ diff --git a/internal/app/errors.go b/internal/app/errors.go index d5a0b40..b850f11 100644 --- a/internal/app/errors.go +++ b/internal/app/errors.go @@ -11,4 +11,5 @@ var ( ErrImmutable = errors.New("immutable resource") ErrIdempotencyConflict = errors.New("idempotency key reused with different request") ErrVerificationFailed = errors.New("verification failed") + ErrRateLimited = errors.New("rate limited") ) diff --git a/internal/app/ledger.go b/internal/app/ledger.go index 592fbd6..466627e 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -2023,6 +2023,8 @@ func ProblemCode(err error) string { return "IDEMPOTENCY_KEY_REUSED" case errors.Is(err, ErrVerificationFailed): return "VERIFICATION_FAILED" + case errors.Is(err, ErrRateLimited): + return "RATE_LIMITED" case errors.Is(err, ErrValidation): return "VALIDATION_FAILED" default: @@ -2044,6 +2046,8 @@ func StatusCode(err error) int { return 400 case errors.Is(err, ErrVerificationFailed): return 422 + case errors.Is(err, ErrRateLimited): + return 429 default: return 500 } From 4c383fbe078b9a78143e26609958110ee003e3a3 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 18:10:48 +0300 Subject: [PATCH 052/287] docs: specify operations readiness contracts --- docs/reference/api-contract-matrix.md | 14 +++---- internal/adapters/httpapi/openapi.go | 42 +++++++++++++++++++ .../adapters/httpapi/openapi_operations.go | 32 ++++++++++++++ internal/adapters/httpapi/router_test.go | 15 ++++++- openapi.yaml | 2 +- 5 files changed, 96 insertions(+), 9 deletions(-) diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index 6e617c6..98d1cf6 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 160 operations: 25 precise, 135 broad. +Generated from 160 operations: 31 precise, 129 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -18,8 +18,8 @@ Generated from 160 operations: 25 precise, 135 broad. | POST | /v1/artifacts | registerArtifact | Bearer | evidence:write | required | - | application/json:RegisterArtifactRequest | 201:application/json:ArtifactEnvelope | precise | | GET | /v1/audit-chain/verify | verifyAuditChain | Bearer | verify:read | - | - | - | 200:unspecified | broad | | GET | /v1/audit-log | listAuditLog | Bearer | admin | - | - | - | 200:unspecified | broad | -| POST | /v1/backup-manifests | generateBackupManifest | Bearer | admin | required | - | - | 201:unspecified | broad | -| GET | /v1/backup-manifests/{id}/verify | verifyBackupManifest | Bearer | verify:read | - | - | - | 200:unspecified | broad | +| POST | /v1/backup-manifests | generateBackupManifest | Bearer | admin | required | - | application/json:EmptyObject | 201:application/json:BackupManifestEnvelope | precise | +| GET | /v1/backup-manifests/{id}/verify | verifyBackupManifest | Bearer | verify:read | - | path:id | - | 200:application/json:VerificationResultEnvelope | precise | | POST | /v1/build-attestations/{id}/verify-signature | verifyBuildAttestationSignature | Bearer | verify:read | required | - | - | 200:unspecified | broad | | POST | /v1/builds | createBuild | Bearer | build:write | required | - | application/json:CreateBuildRequest | 201:application/json:BuildRunEnvelope | precise | | GET | /v1/builds/{id} | getBuild | Bearer | build:read | - | path:id | - | 200:application/json:BuildRunEnvelope | precise | @@ -99,7 +99,7 @@ Generated from 160 operations: 25 precise, 135 broad. | POST | /v1/questionnaire-drafts | createQuestionnaireDraft | Bearer | package:read | required | - | - | 201:unspecified | broad | | POST | /v1/questionnaire-packages | createQuestionnairePackage | Bearer | package:write | required | - | - | 201:unspecified | broad | | POST | /v1/questionnaire-templates | createQuestionnaireTemplate | Bearer | package:write | required | - | - | 201:unspecified | broad | -| GET | /v1/ready | ready | public | - | - | - | - | 200:unspecified | broad | +| GET | /v1/ready | ready | public | - | - | - | - | 200:application/json:ReadinessStatusEnvelope | precise | | POST | /v1/redaction-profiles | createRedactionProfile | Bearer | package:write | required | - | - | 201:unspecified | broad | | POST | /v1/release-bundles | createReleaseBundle | Bearer | bundle:write | required | - | application/json:CreateReleaseBundleRequest | 201:application/json:DataEnvelope | broad | | GET | /v1/release-bundles/{id} | getReleaseBundle | Bearer | bundle:read | - | - | - | 200:unspecified | broad | @@ -118,13 +118,13 @@ Generated from 160 operations: 25 precise, 135 broad. | POST | /v1/report-templates | createReportTemplate | Bearer | report:read | required | - | - | 201:unspecified | broad | | POST | /v1/report-templates/{id}/render | renderReportTemplate | Bearer | report:read | required | - | - | 201:unspecified | broad | | POST | /v1/reports/anomaly | generateAnomalyReport | Bearer | report:read | required | - | - | 201:unspecified | broad | -| GET | /v1/reports/control-coverage | controlCoverageReport | Bearer | report:read | - | - | - | 200:unspecified | broad | -| GET | /v1/reports/cra-readiness | craReadinessReport | Bearer | report:read | - | - | - | 200:unspecified | broad | +| GET | /v1/reports/control-coverage | controlCoverageReport | Bearer | report:read | - | query:framework_id, query:product_id, query:release_id | - | 200:application/json:ReadinessReportEnvelope | precise | +| GET | /v1/reports/cra-readiness | craReadinessReport | Bearer | report:read | - | query:product_id, query:release_id | - | 200:application/json:ReadinessReportEnvelope | precise | | GET | /v1/reports/cra-readiness-html | craReadinessHTMLPackage | Bearer | report:read | - | - | - | 200:unspecified | broad | | GET | /v1/reports/incident-package | incidentReport | Bearer | incident:read | - | - | - | 200:unspecified | broad | | GET | /v1/reports/missing-evidence | missingEvidenceReport | Bearer | verify:read | - | - | - | 200:unspecified | broad | | POST | /v1/reports/pdf | createPDFReportPackage | Bearer | report:read | required | - | - | 201:unspecified | broad | -| GET | /v1/reports/release-readiness | releaseReadinessReport | Bearer | verify:read | - | - | - | 200:unspecified | broad | +| GET | /v1/reports/release-readiness | releaseReadinessReport | Bearer | verify:read | - | query:release_id | - | 200:application/json:ReadinessReportEnvelope | precise | | GET | /v1/reports/retention | retentionReport | Bearer | admin | - | - | - | 200:unspecified | broad | | GET | /v1/reports/security-review-package | securityReviewPackageReport | Bearer | package:read | - | - | - | 200:unspecified | broad | | GET | /v1/reports/vulnerability-posture | vulnerabilityPostureReport | Bearer | security:read | - | - | - | 200:unspecified | broad | diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index a00f5df..1f762d6 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -69,6 +69,48 @@ func registerCriticalSchemas(registry *specs.Registry) { "result": map[string]any{"type": "string", "enum": []string{"passed", "failed", "warning"}}, "detail": map[string]any{"type": "string"}, }, "name", "result")) + registry.RegisterSchema("ReadinessStatus", objectSchema(map[string]any{ + "status": map[string]any{"type": "string"}, + "checks": map[string]any{"type": "array", "items": objectSchema(map[string]any{ + "name": map[string]any{"type": "string"}, + "status": map[string]any{"type": "string"}, + }, "name", "status")}, + }, "status", "checks")) + registry.RegisterSchema("ReadinessStatusEnvelope", dataEnvelopeSchema("#/components/schemas/ReadinessStatus")) + registry.RegisterSchema("BackupManifest", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "state_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "resource_counts": map[string]any{"type": "object", "additionalProperties": map[string]any{"type": "integer"}}, + "consistency_checks": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/VerifyCheck"}}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "state_hash", "resource_counts", "consistency_checks", "limitations", "schema_version", "created_at")) + registry.RegisterSchema("BackupManifestEnvelope", dataEnvelopeSchema("#/components/schemas/BackupManifest")) + registry.RegisterSchema("VerificationResult", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "subject_type": map[string]any{"type": "string"}, + "subject_id": map[string]any{"type": "string"}, + "result": map[string]any{"type": "string", "enum": []string{"passed", "failed"}}, + "checks": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/VerifyCheck"}}, + "verified_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "subject_type", "subject_id", "result", "checks", "verified_at")) + registry.RegisterSchema("VerificationResultEnvelope", dataEnvelopeSchema("#/components/schemas/VerificationResult")) + registry.RegisterSchema("ReadinessReport", objectSchema(map[string]any{ + "report_type": map[string]any{"type": "string"}, + "template_version": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "result": map[string]any{"type": "string"}, + "checks": map[string]any{"type": "array", "items": map[string]any{"type": "object"}}, + "gaps": map[string]any{"type": "array", "items": map[string]any{"type": "object"}}, + "assumptions": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "generated_at": map[string]any{"type": "string", "format": "date-time"}, + }, "report_type", "template_version", "result", "assumptions", "limitations", "generated_at")) + registry.RegisterSchema("ReadinessReportEnvelope", dataEnvelopeSchema("#/components/schemas/ReadinessReport")) registry.RegisterSchema("SSOProvider", objectSchema(map[string]any{ "id": map[string]any{"type": "string"}, "tenant_id": map[string]any{"type": "string"}, diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index bc9c84b..6b763dd 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -9,6 +9,11 @@ import ( func withCriticalOperationDetails(operation specs.Operation) specs.Operation { addProblemResponses(&operation) switch operation.OperationID { + case "ready": + operation.Description = "Returns low-detail process readiness without tenant evidence or secret material." + operation.Security = nil + operation.Scopes = nil + operation.Responses[http.StatusOK] = jsonResponse("Readiness status envelope.", "#/components/schemas/ReadinessStatusEnvelope") case "instanceAdminSnapshot": operation.Description = "Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient." operation.Responses[http.StatusOK] = jsonResponse("Instance admin snapshot envelope.", "#/components/schemas/DataEnvelope") @@ -143,6 +148,33 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Description = "Verifies a tenant-scoped release bundle and returns a deterministic verification result." operation.Parameters = append(operation.Parameters, pathParam("id", "Release bundle id.")) operation.Responses[http.StatusOK] = jsonResponse("Release bundle verification envelope.", "#/components/schemas/ReleaseBundleVerificationEnvelope") + case "generateBackupManifest": + operation.Description = "Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material." + operation.RequestBody = jsonRequest("Empty JSON object.", "#/components/schemas/EmptyObject") + operation.Responses[http.StatusCreated] = jsonResponse("Backup manifest envelope.", "#/components/schemas/BackupManifestEnvelope") + case "verifyBackupManifest": + operation.Description = "Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks." + operation.Parameters = append(operation.Parameters, pathParam("id", "Backup manifest id.")) + operation.Responses[http.StatusOK] = jsonResponse("Backup manifest verification envelope.", "#/components/schemas/VerificationResultEnvelope") + case "releaseReadinessReport": + operation.Description = "Returns a deterministic release-readiness report with gaps, assumptions, and limitations." + operation.Parameters = append(operation.Parameters, queryParam("release_id", "Release id.", "string")) + operation.Responses[http.StatusOK] = jsonResponse("Release readiness report envelope.", "#/components/schemas/ReadinessReportEnvelope") + case "craReadinessReport": + operation.Description = "Returns a CRA-oriented readiness report without legal compliance or certification conclusions." + operation.Parameters = append(operation.Parameters, + queryParam("product_id", "Product id.", "string"), + queryParam("release_id", "Release id.", "string"), + ) + operation.Responses[http.StatusOK] = jsonResponse("CRA readiness report envelope.", "#/components/schemas/ReadinessReportEnvelope") + case "controlCoverageReport": + operation.Description = "Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations." + operation.Parameters = append(operation.Parameters, + queryParam("framework_id", "Control framework id.", "string"), + queryParam("product_id", "Product id.", "string"), + queryParam("release_id", "Release id.", "string"), + ) + operation.Responses[http.StatusOK] = jsonResponse("Control coverage report envelope.", "#/components/schemas/ReadinessReportEnvelope") case "createCustomerPortalAccess": operation.Description = "Creates token-based customer portal access for a customer package and returns the token once." operation.RequestBody = jsonRequest("Customer portal access creation request.", "#/components/schemas/CreateCustomerPortalAccessRequest") diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index efb825f..9ff9059 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -84,13 +84,26 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { if _, ok := problemProps["request_id"]; !ok { t.Fatalf("Problem schema missing request_id: %#v", problemProps) } - for _, schemaName := range []string{"CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "DataEnvelope"} { + for _, schemaName := range []string{"ReadinessStatusEnvelope", "BackupManifestEnvelope", "VerificationResultEnvelope", "ReadinessReportEnvelope", "CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "DataEnvelope"} { if _, ok := schemas[schemaName]; !ok { t.Fatalf("schema %s missing from OpenAPI components", schemaName) } } paths := asStringAnyMap(t, doc["paths"]) + ready := operationMap(t, paths, "/v1/ready", "get") + assertResponseRef(t, ready, "200", "#/components/schemas/ReadinessStatusEnvelope") + backupManifest := operationMap(t, paths, "/v1/backup-manifests", "post") + assertRequestRef(t, backupManifest, "#/components/schemas/EmptyObject") + assertResponseRef(t, backupManifest, "201", "#/components/schemas/BackupManifestEnvelope") + verifyBackup := operationMap(t, paths, "/v1/backup-manifests/{id}/verify", "get") + assertResponseRef(t, verifyBackup, "200", "#/components/schemas/VerificationResultEnvelope") + releaseReadiness := operationMap(t, paths, "/v1/reports/release-readiness", "get") + assertQueryParams(t, releaseReadiness, "release_id") + assertResponseRef(t, releaseReadiness, "200", "#/components/schemas/ReadinessReportEnvelope") + craReadiness := operationMap(t, paths, "/v1/reports/cra-readiness", "get") + assertQueryParams(t, craReadiness, "product_id", "release_id") + assertResponseRef(t, craReadiness, "200", "#/components/schemas/ReadinessReportEnvelope") createProduct := operationMap(t, paths, "/v1/products", "post") assertRequestRef(t, createProduct, "#/components/schemas/CreateProductRequest") assertResponseRef(t, createProduct, "201", "#/components/schemas/ProductEnvelope") diff --git a/openapi.yaml b/openapi.yaml index 44b6d59..0d9fd8d 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{},"payload_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source":{"type":"string"},"subject_refs":{"items":{"type":"string"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"type":"object"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"api_key_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"},"user_count":{"type":"integer"}},"required":["tenant_count","resource_counts"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"List API keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"201":{"description":"Create API key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"201":{"description":"Create artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"Get artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"Verify cosign-style artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"Verify audit chain response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"List tenant audit log response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"operationId":"generateBackupManifest","responses":{"201":{"description":"Generate backup manifest response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"operationId":"verifyBackupManifest","responses":{"200":{"description":"Verify backup manifest response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"Verify build attestation signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"201":{"description":"Upload build attestation response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"List collectors response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"201":{"description":"Create collector response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"operationId":"uploadGitHubSourceSnapshot","responses":{"201":{"description":"Upload GitHub source snapshot response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"operationId":"uploadGitLabSourceSnapshot","responses":{"201":{"description":"Upload GitLab source snapshot response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"List control evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"List control frameworks response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"201":{"description":"Create control framework response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"201":{"description":"Create security control response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"Get security control response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"201":{"description":"Link control evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"201":{"description":"Create custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"201":{"description":"Evaluate custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"List deployments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"201":{"description":"Record deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"Get deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"201":{"description":"Create DSSE trust root response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"List deployment environments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"201":{"description":"Create deployment environment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"List evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"operationId":"createGraphSnapshot","responses":{"201":{"description":"Create evidence graph snapshot response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"Get evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"List evidence lifecycle events response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"201":{"description":"Record evidence lifecycle event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"201":{"description":"Link evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"201":{"description":"Supersede evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"List exceptions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"201":{"description":"Create exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"Approve exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"Health response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"Safe tenant metrics response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"201":{"description":"Upload OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"Get OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"201":{"description":"Create OpenAPI contract diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OpenAPI response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"201":{"description":"Create organization response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"201":{"description":"Evaluate release policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"operationId":"ready","responses":{"200":{"description":"Readiness response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"Get release bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"Get release bundle manifest response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"List release candidates response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"201":{"description":"Create release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"Get release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"Promote release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"Reject release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"operationId":"controlCoverageReport","responses":{"200":{"description":"Control coverage report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"operationId":"craReadinessReport","responses":{"200":{"description":"CRA readiness report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"Missing evidence report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"operationId":"releaseReadinessReport","responses":{"200":{"description":"Release readiness report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"List role bindings response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"201":{"description":"Create role binding response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"List signing keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"201":{"description":"Rotate signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"Revoke signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"201":{"description":"Create signing provider operation receipt response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"201":{"description":"Create signing provider record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"201":{"description":"Record source branch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"201":{"description":"Record source commit response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"201":{"description":"Record pull request response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"List source repositories response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"201":{"description":"Create source repository response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"201":{"description":"Link SSO identity response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"Revoke SSO session response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"201":{"description":"Create user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"Deactivate user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"Version response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"201":{"description":"Create vulnerability decision response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"201":{"description":"Record vulnerability workflow event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"201":{"description":"Create waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"Approve waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{},"payload_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source":{"type":"string"},"subject_refs":{"items":{"type":"string"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"type":"object"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"api_key_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"},"user_count":{"type":"integer"}},"required":["tenant_count","resource_counts"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"List API keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"201":{"description":"Create API key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"201":{"description":"Create artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"Get artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"Verify cosign-style artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"Verify audit chain response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"List tenant audit log response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"Verify build attestation signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"201":{"description":"Upload build attestation response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"List collectors response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"201":{"description":"Create collector response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"operationId":"uploadGitHubSourceSnapshot","responses":{"201":{"description":"Upload GitHub source snapshot response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"operationId":"uploadGitLabSourceSnapshot","responses":{"201":{"description":"Upload GitLab source snapshot response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"List control evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"List control frameworks response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"201":{"description":"Create control framework response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"201":{"description":"Create security control response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"Get security control response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"201":{"description":"Link control evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"201":{"description":"Create custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"201":{"description":"Evaluate custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"List deployments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"201":{"description":"Record deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"Get deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"201":{"description":"Create DSSE trust root response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"List deployment environments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"201":{"description":"Create deployment environment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"List evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"operationId":"createGraphSnapshot","responses":{"201":{"description":"Create evidence graph snapshot response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"Get evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"List evidence lifecycle events response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"201":{"description":"Record evidence lifecycle event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"201":{"description":"Link evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"201":{"description":"Supersede evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"List exceptions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"201":{"description":"Create exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"Approve exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"Health response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"Safe tenant metrics response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"201":{"description":"Upload OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"Get OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"201":{"description":"Create OpenAPI contract diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OpenAPI response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"201":{"description":"Create organization response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"201":{"description":"Evaluate release policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"Get release bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"Get release bundle manifest response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"List release candidates response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"201":{"description":"Create release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"Get release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"Promote release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"Reject release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"Missing evidence report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"List role bindings response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"201":{"description":"Create role binding response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"List signing keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"201":{"description":"Rotate signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"Revoke signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"201":{"description":"Create signing provider operation receipt response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"201":{"description":"Create signing provider record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"201":{"description":"Record source branch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"201":{"description":"Record source commit response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"201":{"description":"Record pull request response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"List source repositories response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"201":{"description":"Create source repository response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"201":{"description":"Link SSO identity response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"Revoke SSO session response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"201":{"description":"Create user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"Deactivate user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"Version response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"201":{"description":"Create vulnerability decision response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"201":{"description":"Record vulnerability workflow event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"201":{"description":"Create waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"Approve waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From 56ffd7bdd0e09a1de3ad90774f8e83e9c1c7e6c1 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 18:12:10 +0300 Subject: [PATCH 053/287] style: format worker imports --- cmd/evydence-worker/main.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/evydence-worker/main.go b/cmd/evydence-worker/main.go index 57cacde..05ff7a1 100644 --- a/cmd/evydence-worker/main.go +++ b/cmd/evydence-worker/main.go @@ -17,12 +17,13 @@ import ( "strings" "time" + "github.com/getkin/kin-openapi/openapi3" + "github.com/aatuh/evydence/internal/adapters/objectstore/filesystem" s3store "github.com/aatuh/evydence/internal/adapters/objectstore/s3" "github.com/aatuh/evydence/internal/adapters/postgres" "github.com/aatuh/evydence/internal/app" "github.com/aatuh/evydence/internal/domain" - "github.com/getkin/kin-openapi/openapi3" ) const defaultMaxWorkerPayloadBytes = 20 << 20 From 6be9eed4c759928528487df65ff64dcd523efd7e Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 18:15:10 +0300 Subject: [PATCH 054/287] feat: expand sdk contract coverage --- Makefile | 3 +- docs/sdk/README.md | 51 ++++++------ scripts/sdk_check.py | 130 +++++++++++++++++++++++++++++ sdk/go/evydence/client.go | 94 +++++++++++++++++++++ sdk/go/evydence/client_test.go | 148 +++++++++++++++++++++++++++++++++ sdk/python/evydence_client.py | 53 ++++++++++++ sdk/typescript/client.ts | 90 ++++++++++++++++++++ 7 files changed, 541 insertions(+), 28 deletions(-) create mode 100755 scripts/sdk_check.py diff --git a/Makefile b/Makefile index 00f91db..c22db11 100644 --- a/Makefile +++ b/Makefile @@ -158,10 +158,11 @@ deploy-check: ## Validate deployment and air-gap skeletons exist @test -f deploy/observability/prometheus-rules.yaml @test -f deploy/observability/grafana-dashboard.json -sdk-check: ## Validate curated SDK example files exist +sdk-check: ## Validate curated SDK helper coverage against OpenAPI @test -f sdk/go/evydence/client.go @test -f sdk/typescript/client.ts @test -f sdk/python/evydence_client.py + @python3 scripts/sdk_check.py fast-check: ## Run non-mutating fast validation @$(MAKE) test diff --git a/docs/sdk/README.md b/docs/sdk/README.md index 61ce1aa..4da5b67 100644 --- a/docs/sdk/README.md +++ b/docs/sdk/README.md @@ -4,13 +4,13 @@ This is a reference for the lightweight SDK wrappers committed in this repositor ## Current Scope -The wrappers provide authenticated JSON `POST` helpers with explicit idempotency keys and small typed convenience helpers for the SSO/OIDC identity-provider routes: +The wrappers provide authenticated JSON helpers with explicit idempotency keys and small typed convenience helpers for the release-ledger and SSO/OIDC identity-provider routes: - Go: `sdk/go/evydence` - TypeScript: `sdk/typescript/client.ts` - Python: `sdk/python/evydence_client.py` -They do not expose typed methods for every route. Broader generated clients should be regenerated from the committed `openapi.yaml`, reviewed, and released through a separate SDK publishing process. +They do not expose typed methods for every route. The current typed coverage is intentionally narrow: products, releases, artifacts, build runs, process readiness, release-readiness reports, SSO provider creation, and provider identity verification. Broader generated clients should be regenerated from the committed `openapi.yaml`, reviewed, and released through a separate SDK publishing process. No package publishing manifests are committed for these wrappers yet. Use them as in-repository examples or copy them into an application-owned SDK package until a release process publishes versioned SDK artifacts. @@ -29,29 +29,28 @@ import ( ) func createProduct() error { -client := evydence.Client{ - BaseURL: "http://localhost:8080", - APIKey: os.Getenv("EVYDENCE_API_KEY"), -} - -var out map[string]any -err := client.Post( - context.Background(), - "/v1/products", - "product-payments-api", - map[string]any{"name": "Payments API", "slug": "payments-api"}, - &out, -) -if err != nil { - return err -} -return nil + client := evydence.Client{ + BaseURL: "http://localhost:8080", + APIKey: os.Getenv("EVYDENCE_API_KEY"), + } + + var out map[string]any + err := client.CreateProduct( + context.Background(), + "product-payments-api", + evydence.CreateProductRequest{Name: "Payments API", Slug: "payments-api"}, + &out, + ) + if err != nil { + return err + } + return nil } ``` The helper rejects paths that do not start with `/v1/` and blank idempotency keys. Non-2xx responses return an error containing the HTTP status code; callers that need Problem Details bodies should use a generated or custom client. -The Go wrapper also exposes `CreateSSOProvider` and `VerifyProviderIdentity` helpers. `VerifyProviderIdentity` can carry an OIDC `id_token` or SAML `saml_assertion`; SDK errors intentionally include only the HTTP status code and not the response body. +The Go wrapper also exposes typed helpers for `CreateRelease`, `RegisterArtifact`, `CreateBuild`, `Readiness`, `ReleaseReadiness`, `CreateSSOProvider`, and `VerifyProviderIdentity`. `VerifyProviderIdentity` can carry an OIDC `id_token` or SAML `saml_assertion`; SDK errors intentionally include only the HTTP status code and not the response body. ## TypeScript @@ -65,8 +64,7 @@ const client = new EvydenceClient({ apiKey: process.env.EVYDENCE_API_KEY!, }); -const response = await client.post<{ data: { id: string } }>( - "/v1/products", +const response = await client.createProduct<{ data: { id: string } }>( "product-payments-api", { name: "Payments API", slug: "payments-api" }, ); @@ -74,7 +72,7 @@ const response = await client.post<{ data: { id: string } }>( The helper validates `/v1/` paths and idempotency keys. Non-2xx responses throw an error with the HTTP status code. -The TypeScript wrapper also exposes `createSSOProvider` and `verifyProviderIdentity` helpers over the same routes. +The TypeScript wrapper also exposes `createRelease`, `registerArtifact`, `createBuild`, `readiness`, `releaseReadiness`, `createSSOProvider`, and `verifyProviderIdentity` helpers over the same routes. ## Python @@ -90,8 +88,7 @@ client = EvydenceClient( api_key=os.environ["EVYDENCE_API_KEY"], ) -response = client.post( - "/v1/products", +response = client.create_product( "product-payments-api", {"name": "Payments API", "slug": "payments-api"}, ) @@ -99,7 +96,7 @@ response = client.post( The helper validates `/v1/` paths and idempotency keys. HTTP errors raise `RuntimeError` with the status code. -The Python wrapper also exposes `create_sso_provider` and `verify_provider_identity` helpers over the same routes. +The Python wrapper also exposes `create_release`, `register_artifact`, `create_build`, `readiness`, `release_readiness`, `create_sso_provider`, and `verify_provider_identity` helpers over the same routes. ## Idempotency Guidance @@ -123,4 +120,4 @@ make test make sdk-check ``` -Generated SDK publishing is not an API runtime dependency. Keep generated clients tied to the committed `openapi.yaml` and document any route coverage gaps at release time. +`make sdk-check` runs `scripts/sdk_check.py`, which verifies that the curated helper methods still map to committed OpenAPI operations, idempotent routes still require `Idempotency-Key`, and SDKs keep basic `/v1/` path validation. Generated SDK publishing is not an API runtime dependency. Keep generated clients tied to the committed `openapi.yaml` and document any route coverage gaps at release time. diff --git a/scripts/sdk_check.py b/scripts/sdk_check.py new file mode 100755 index 0000000..f1d14f0 --- /dev/null +++ b/scripts/sdk_check.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python3 +"""Validate curated SDK helper coverage against the committed OpenAPI contract.""" + +from __future__ import annotations + +import json +import pathlib +import sys +from dataclasses import dataclass + + +ROOT = pathlib.Path(__file__).resolve().parents[1] + + +@dataclass(frozen=True) +class RequiredHelper: + operation_id: str + method: str + path: str + go_name: str + typescript_name: str + python_name: str + idempotent: bool + + +REQUIRED_HELPERS = ( + RequiredHelper("createProduct", "post", "/v1/products", "CreateProduct", "createProduct", "create_product", True), + RequiredHelper("createRelease", "post", "/v1/releases", "CreateRelease", "createRelease", "create_release", True), + RequiredHelper( + "registerArtifact", + "post", + "/v1/artifacts", + "RegisterArtifact", + "registerArtifact", + "register_artifact", + True, + ), + RequiredHelper("createBuild", "post", "/v1/builds", "CreateBuild", "createBuild", "create_build", True), + RequiredHelper("ready", "get", "/v1/ready", "Readiness", "readiness", "readiness", False), + RequiredHelper( + "releaseReadinessReport", + "get", + "/v1/reports/release-readiness", + "ReleaseReadiness", + "releaseReadiness", + "release_readiness", + False, + ), + RequiredHelper( + "createSSOProvider", + "post", + "/v1/sso/providers", + "CreateSSOProvider", + "createSSOProvider", + "create_sso_provider", + True, + ), + RequiredHelper( + "verifyProviderIdentity", + "post", + "/v1/provider-verifications", + "VerifyProviderIdentity", + "verifyProviderIdentity", + "verify_provider_identity", + True, + ), +) + + +def fail(message: str) -> None: + print(f"sdk-check: {message}", file=sys.stderr) + raise SystemExit(2) + + +def load_openapi() -> dict: + try: + return json.loads((ROOT / "openapi.yaml").read_text(encoding="utf-8")) + except FileNotFoundError: + fail("missing openapi.yaml") + except json.JSONDecodeError as exc: + fail(f"openapi.yaml is not parseable JSON: {exc}") + + +def operation(spec: dict, helper: RequiredHelper) -> dict: + try: + op = spec["paths"][helper.path][helper.method] + except KeyError as exc: + fail(f"missing OpenAPI operation for {helper.method.upper()} {helper.path}: {exc}") + if op.get("operationId") != helper.operation_id: + fail( + f"{helper.method.upper()} {helper.path} operationId is {op.get('operationId')!r}, " + f"expected {helper.operation_id!r}" + ) + if helper.idempotent and not op.get("x-idempotency-key", {}).get("required"): + fail(f"{helper.operation_id} must require Idempotency-Key in OpenAPI") + if helper.idempotent and not op.get("requestBody", {}).get("content", {}).get("application/json", {}).get("schema"): + fail(f"{helper.operation_id} must declare an application/json request schema") + if "200" not in op.get("responses", {}) and "201" not in op.get("responses", {}): + fail(f"{helper.operation_id} must declare a success response") + return op + + +def require_text(source: str, token: str, label: str) -> None: + if token not in source: + fail(f"{label} missing {token!r}") + + +def main() -> None: + spec = load_openapi() + for helper in REQUIRED_HELPERS: + operation(spec, helper) + + go_client = (ROOT / "sdk/go/evydence/client.go").read_text(encoding="utf-8") + typescript_client = (ROOT / "sdk/typescript/client.ts").read_text(encoding="utf-8") + python_client = (ROOT / "sdk/python/evydence_client.py").read_text(encoding="utf-8") + + for helper in REQUIRED_HELPERS: + require_text(go_client, f"func (c Client) {helper.go_name}", "Go SDK") + require_text(typescript_client, f"async {helper.typescript_name}", "TypeScript SDK") + require_text(python_client, f"def {helper.python_name}", "Python SDK") + + require_text(go_client, "strings.HasPrefix(path, \"/v1/\")", "Go SDK path validation") + require_text(typescript_client, "path.startsWith(\"/v1/\")", "TypeScript SDK path validation") + require_text(python_client, "path.startswith(\"/v1/\")", "Python SDK path validation") + + print(f"sdk-check: validated {len(REQUIRED_HELPERS)} SDK helpers against openapi.yaml") + + +if __name__ == "__main__": + main() diff --git a/sdk/go/evydence/client.go b/sdk/go/evydence/client.go index 8e610ea..03dd214 100644 --- a/sdk/go/evydence/client.go +++ b/sdk/go/evydence/client.go @@ -7,6 +7,7 @@ import ( "fmt" "io" "net/http" + "net/url" "strings" ) @@ -16,6 +17,42 @@ type Client struct { HTTP *http.Client } +type CreateProductRequest struct { + Name string `json:"name"` + Slug string `json:"slug"` +} + +type CreateReleaseRequest struct { + ProductID string `json:"product_id"` + ProjectID string `json:"project_id,omitempty"` + Version string `json:"version"` +} + +type RegisterArtifactRequest struct { + ReleaseID string `json:"release_id,omitempty"` + Name string `json:"name"` + MediaType string `json:"media_type,omitempty"` + Digest string `json:"digest"` + Size int64 `json:"size,omitempty"` +} + +type BuildOutput struct { + ArtifactID string `json:"artifact_id,omitempty"` + Digest string `json:"digest"` + Name string `json:"name,omitempty"` +} + +type CreateBuildRequest struct { + ProjectID string `json:"project_id"` + ReleaseID string `json:"release_id"` + Provider string `json:"provider"` + CommitSHA string `json:"commit_sha"` + Status string `json:"status"` + StartedAt string `json:"started_at"` + Outputs []BuildOutput `json:"outputs,omitempty"` + GitHub map[string]any `json:"github,omitempty"` +} + type CreateSSOProviderRequest struct { Name string `json:"name"` Type string `json:"type"` @@ -72,6 +109,63 @@ func (c Client) Post(ctx context.Context, path, idempotencyKey string, payload a return json.Unmarshal(responseBody, out) } +func (c Client) Get(ctx context.Context, path string, out any) error { + if !strings.HasPrefix(path, "/v1/") { + return fmt.Errorf("evydence: invalid path") + } + req, err := http.NewRequestWithContext(ctx, http.MethodGet, strings.TrimRight(c.BaseURL, "/")+path, nil) + if err != nil { + return err + } + if strings.TrimSpace(c.APIKey) != "" { + req.Header.Set("Authorization", "Bearer "+strings.TrimSpace(c.APIKey)) + } + httpClient := c.HTTP + if httpClient == nil { + httpClient = http.DefaultClient + } + resp, err := httpClient.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + responseBody, err := io.ReadAll(io.LimitReader(resp.Body, 1<<20)) + if err != nil { + return err + } + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + return fmt.Errorf("evydence: request failed with status %d", resp.StatusCode) + } + if out == nil { + return nil + } + return json.Unmarshal(responseBody, out) +} + +func (c Client) CreateProduct(ctx context.Context, idempotencyKey string, payload CreateProductRequest, out any) error { + return c.Post(ctx, "/v1/products", idempotencyKey, payload, out) +} + +func (c Client) CreateRelease(ctx context.Context, idempotencyKey string, payload CreateReleaseRequest, out any) error { + return c.Post(ctx, "/v1/releases", idempotencyKey, payload, out) +} + +func (c Client) RegisterArtifact(ctx context.Context, idempotencyKey string, payload RegisterArtifactRequest, out any) error { + return c.Post(ctx, "/v1/artifacts", idempotencyKey, payload, out) +} + +func (c Client) CreateBuild(ctx context.Context, idempotencyKey string, payload CreateBuildRequest, out any) error { + return c.Post(ctx, "/v1/builds", idempotencyKey, payload, out) +} + +func (c Client) Readiness(ctx context.Context, out any) error { + return c.Get(ctx, "/v1/ready", out) +} + +func (c Client) ReleaseReadiness(ctx context.Context, releaseID string, out any) error { + return c.Get(ctx, "/v1/reports/release-readiness?release_id="+url.QueryEscape(releaseID), out) +} + func (c Client) CreateSSOProvider(ctx context.Context, idempotencyKey string, payload CreateSSOProviderRequest, out any) error { return c.Post(ctx, "/v1/sso/providers", idempotencyKey, payload, out) } diff --git a/sdk/go/evydence/client_test.go b/sdk/go/evydence/client_test.go index 61bba0c..c63f901 100644 --- a/sdk/go/evydence/client_test.go +++ b/sdk/go/evydence/client_test.go @@ -85,6 +85,154 @@ func TestPostReturnsSafeStatusError(t *testing.T) { } } +func TestReleaseLedgerTypedHelpersUseContractRoutes(t *testing.T) { + seen := map[string]bool{} + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + route := r.Method + " " + r.URL.Path + seen[route] = true + if got := r.Header.Get("Authorization"); got != "Bearer secret" { + t.Fatalf("authorization header = %q", got) + } + if got := r.Header.Get("Idempotency-Key"); got != "idem-typed" { + t.Fatalf("idempotency header = %q", got) + } + + switch route { + case "POST /v1/products": + var body CreateProductRequest + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + t.Fatalf("decode product: %v", err) + } + if body.Name != "API" || body.Slug != "api" { + t.Fatalf("product body = %#v", body) + } + case "POST /v1/releases": + var body CreateReleaseRequest + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + t.Fatalf("decode release: %v", err) + } + if body.ProductID != "prod_1" || body.ProjectID != "proj_1" || body.Version != "1.0.0" { + t.Fatalf("release body = %#v", body) + } + case "POST /v1/artifacts": + var body RegisterArtifactRequest + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + t.Fatalf("decode artifact: %v", err) + } + if body.ReleaseID != "rel_1" || body.Digest != "sha256:abc" || body.Size != 42 { + t.Fatalf("artifact body = %#v", body) + } + case "POST /v1/builds": + var body CreateBuildRequest + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + t.Fatalf("decode build: %v", err) + } + if body.ProjectID != "proj_1" || body.ReleaseID != "rel_1" || body.Provider != "github_actions" || body.CommitSHA != "0123456789abcdef0123456789abcdef01234567" || body.Status != "passed" || len(body.Outputs) != 1 { + t.Fatalf("build body = %#v", body) + } + default: + t.Fatalf("unexpected route %s", route) + } + _, _ = w.Write([]byte(`{"data":{"ok":true}}`)) + })) + defer server.Close() + + client := Client{BaseURL: server.URL, APIKey: "secret", HTTP: server.Client()} + calls := []struct { + name string + run func() error + }{ + { + name: "product", + run: func() error { + return client.CreateProduct(context.Background(), "idem-typed", CreateProductRequest{Name: "API", Slug: "api"}, nil) + }, + }, + { + name: "release", + run: func() error { + return client.CreateRelease(context.Background(), "idem-typed", CreateReleaseRequest{ProductID: "prod_1", ProjectID: "proj_1", Version: "1.0.0"}, nil) + }, + }, + { + name: "artifact", + run: func() error { + return client.RegisterArtifact(context.Background(), "idem-typed", RegisterArtifactRequest{ReleaseID: "rel_1", Digest: "sha256:abc", Size: 42}, nil) + }, + }, + { + name: "build", + run: func() error { + return client.CreateBuild(context.Background(), "idem-typed", CreateBuildRequest{ + ProjectID: "proj_1", + ReleaseID: "rel_1", + Provider: "github_actions", + CommitSHA: "0123456789abcdef0123456789abcdef01234567", + Status: "passed", + StartedAt: "2026-05-28T10:00:00Z", + Outputs: []BuildOutput{{Digest: "sha256:abc"}}, + }, nil) + }, + }, + } + for _, call := range calls { + t.Run(call.name, func(t *testing.T) { + if err := call.run(); err != nil { + t.Fatalf("call failed: %v", err) + } + }) + } + for _, route := range []string{"POST /v1/products", "POST /v1/releases", "POST /v1/artifacts", "POST /v1/builds"} { + if !seen[route] { + t.Fatalf("missing route %s", route) + } + } +} + +func TestReadinessHelpersUseGetAndSafeErrors(t *testing.T) { + const secretBody = "token=secret" + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodGet { + t.Fatalf("method = %s", r.Method) + } + switch r.URL.Path { + case "/v1/ready": + if got := r.Header.Get("Authorization"); got != "" { + t.Fatalf("public readiness should not send blank API key authorization header: %q", got) + } + _, _ = w.Write([]byte(`{"status":"ok"}`)) + case "/v1/reports/release-readiness": + if got := r.Header.Get("Authorization"); got != "Bearer secret" { + t.Fatalf("authorization header = %q", got) + } + if got := r.URL.Query().Get("release_id"); got != "rel 1+#" { + t.Fatalf("release_id query = %q", got) + } + http.Error(w, secretBody, http.StatusForbidden) + default: + t.Fatalf("unexpected path %s", r.URL.String()) + } + })) + defer server.Close() + + var ready map[string]string + if err := (Client{BaseURL: server.URL, HTTP: server.Client()}).Readiness(context.Background(), &ready); err != nil { + t.Fatalf("readiness: %v", err) + } + if ready["status"] != "ok" { + t.Fatalf("ready = %#v", ready) + } + + err := (Client{BaseURL: server.URL, APIKey: " secret ", HTTP: server.Client()}). + ReleaseReadiness(context.Background(), "rel 1+#", nil) + if err == nil { + t.Fatal("expected status error") + } + if !strings.Contains(err.Error(), "status 403") || strings.Contains(err.Error(), secretBody) { + t.Fatalf("unsafe or unexpected error: %v", err) + } +} + func TestCreateSSOProviderUsesTypedRoute(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost || r.URL.Path != "/v1/sso/providers" { diff --git a/sdk/python/evydence_client.py b/sdk/python/evydence_client.py index b6d8398..cb2ef0c 100644 --- a/sdk/python/evydence_client.py +++ b/sdk/python/evydence_client.py @@ -2,6 +2,7 @@ import json import urllib.error +import urllib.parse import urllib.request from dataclasses import dataclass from typing import Any @@ -32,6 +33,58 @@ def post(self, path: str, idempotency_key: str, payload: dict[str, Any]) -> dict except urllib.error.HTTPError as exc: raise RuntimeError(f"Evydence request failed with status {exc.code}") from exc + def get(self, path: str) -> dict[str, Any]: + if not path.startswith("/v1/"): + raise ValueError("invalid Evydence path") + headers = {} + if self.api_key.strip(): + headers["Authorization"] = f"Bearer {self.api_key.strip()}" + request = urllib.request.Request( + self.base_url.rstrip("/") + path, + method="GET", + headers=headers, + ) + try: + with urllib.request.urlopen(request, timeout=30) as response: + return json.loads(response.read().decode("utf-8")) + except urllib.error.HTTPError as exc: + raise RuntimeError(f"Evydence request failed with status {exc.code}") from exc + + def create_product( + self, + idempotency_key: str, + payload: dict[str, Any], + ) -> dict[str, Any]: + return self.post("/v1/products", idempotency_key, payload) + + def create_release( + self, + idempotency_key: str, + payload: dict[str, Any], + ) -> dict[str, Any]: + return self.post("/v1/releases", idempotency_key, payload) + + def register_artifact( + self, + idempotency_key: str, + payload: dict[str, Any], + ) -> dict[str, Any]: + return self.post("/v1/artifacts", idempotency_key, payload) + + def create_build( + self, + idempotency_key: str, + payload: dict[str, Any], + ) -> dict[str, Any]: + return self.post("/v1/builds", idempotency_key, payload) + + def readiness(self) -> dict[str, Any]: + return self.get("/v1/ready") + + def release_readiness(self, release_id: str) -> dict[str, Any]: + encoded_release_id = urllib.parse.quote(release_id, safe="") + return self.get(f"/v1/reports/release-readiness?release_id={encoded_release_id}") + def create_sso_provider( self, idempotency_key: str, diff --git a/sdk/typescript/client.ts b/sdk/typescript/client.ts index 7f25758..08563b5 100644 --- a/sdk/typescript/client.ts +++ b/sdk/typescript/client.ts @@ -4,6 +4,42 @@ export type EvydenceClientOptions = { fetchImpl?: typeof fetch; }; +export type CreateProductRequest = { + name: string; + slug: string; +}; + +export type CreateReleaseRequest = { + product_id: string; + project_id?: string; + version: string; +}; + +export type RegisterArtifactRequest = { + release_id?: string; + name?: string; + media_type?: string; + digest: string; + size?: number; +}; + +export type BuildOutput = { + artifact_id?: string; + digest: string; + name?: string; +}; + +export type CreateBuildRequest = { + project_id: string; + release_id: string; + provider: "github_actions" | "generic"; + commit_sha: string; + status: "queued" | "running" | "passed" | "failed" | "cancelled"; + started_at: string; + outputs?: BuildOutput[]; + github?: Record; +}; + export type CreateSSOProviderRequest = { name: string; type: "oidc" | "saml"; @@ -53,6 +89,60 @@ export class EvydenceClient { return response.json() as Promise; } + async get(path: string): Promise { + if (!path.startsWith("/v1/")) { + throw new Error("invalid Evydence path"); + } + const headers: Record = {}; + if (this.apiKey.trim()) { + headers["Authorization"] = `Bearer ${this.apiKey.trim()}`; + } + const response = await this.fetchImpl(`${this.baseUrl}${path}`, { + method: "GET", + headers, + }); + if (!response.ok) { + throw new Error(`Evydence request failed with status ${response.status}`); + } + return response.json() as Promise; + } + + async createProduct( + idempotencyKey: string, + payload: CreateProductRequest, + ): Promise { + return this.post("/v1/products", idempotencyKey, payload); + } + + async createRelease( + idempotencyKey: string, + payload: CreateReleaseRequest, + ): Promise { + return this.post("/v1/releases", idempotencyKey, payload); + } + + async registerArtifact( + idempotencyKey: string, + payload: RegisterArtifactRequest, + ): Promise { + return this.post("/v1/artifacts", idempotencyKey, payload); + } + + async createBuild( + idempotencyKey: string, + payload: CreateBuildRequest, + ): Promise { + return this.post("/v1/builds", idempotencyKey, payload); + } + + async readiness(): Promise { + return this.get("/v1/ready"); + } + + async releaseReadiness(releaseId: string): Promise { + return this.get(`/v1/reports/release-readiness?release_id=${encodeURIComponent(releaseId)}`); + } + async createSSOProvider( idempotencyKey: string, payload: CreateSSOProviderRequest, From b143794db3ff03fe850009f936326415e42bfcdb Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 18:15:36 +0300 Subject: [PATCH 055/287] ci: add signed release artifact workflow --- .github/workflows/release-artifacts.yml | 179 ++++++++++++++++++++++++ Makefile | 5 + docs/reference/release-validation.md | 34 +++++ 3 files changed, 218 insertions(+) create mode 100644 .github/workflows/release-artifacts.yml diff --git a/.github/workflows/release-artifacts.yml b/.github/workflows/release-artifacts.yml new file mode 100644 index 0000000..01164bd --- /dev/null +++ b/.github/workflows/release-artifacts.yml @@ -0,0 +1,179 @@ +name: Release Artifacts + +on: + push: + tags: + - "v*" + workflow_dispatch: + inputs: + tag: + description: "Release tag to package, for example v0.1.0" + required: true + type: string + upload_draft_release: + description: "Create or update a draft GitHub release with the generated artifacts" + required: true + default: false + type: boolean + +permissions: + contents: write + +jobs: + package: + name: Package Signed Release Artifacts + runs-on: ubuntu-latest + services: + postgres: + image: postgres:16-alpine + env: + POSTGRES_DB: evydence + POSTGRES_USER: evydence + POSTGRES_PASSWORD: change-me + ports: + - 5432:5432 + options: >- + --health-cmd "pg_isready -U evydence" + --health-interval 5s + --health-timeout 5s + --health-retries 20 + env: + EVYDENCE_API_KEY_PEPPER: ci-test-pepper + EVYDENCE_TEST_DATABASE_URL: postgres://evydence:change-me@localhost:5432/evydence?sslmode=disable + RELEASE_SIGNING_PRIVATE_KEY_B64: ${{ secrets.EVYDENCE_RELEASE_SIGNING_PRIVATE_KEY_B64 }} + steps: + - name: Check out repository + uses: actions/checkout@v5 + with: + fetch-depth: 0 + + - name: Resolve release tag + id: release + shell: bash + run: | + set -euo pipefail + if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then + tag="${GITHUB_REF_NAME}" + else + tag="${{ github.event.inputs.tag }}" + fi + if [[ ! "${tag}" =~ ^v[0-9]+(\.[0-9]+){1,2}(-[0-9A-Za-z.-]+)?$ ]]; then + echo "release tag must look like v1.2.3 or v1.2.3-rc.1" >&2 + exit 2 + fi + echo "tag=${tag}" >> "${GITHUB_OUTPUT}" + + - name: Set up Go + uses: actions/setup-go@v6 + with: + go-version-file: go.mod + cache: true + + - name: Install QA tools + run: make tools + + - name: Run production gate + run: make production-check + + - name: Require release signing secret + shell: bash + run: | + set -euo pipefail + if [[ -z "${RELEASE_SIGNING_PRIVATE_KEY_B64}" ]]; then + echo "EVYDENCE_RELEASE_SIGNING_PRIVATE_KEY_B64 secret is required to sign release artifacts" >&2 + exit 2 + fi + + - name: Build release archives + shell: bash + run: | + set -euo pipefail + version="${{ steps.release.outputs.tag }}" + mkdir -p dist tmp/release + commands=(evydence evydence-api evydence-worker evydence-migrate) + targets=(linux/amd64 linux/arm64 darwin/amd64 darwin/arm64 windows/amd64) + for target in "${targets[@]}"; do + goos="${target%/*}" + goarch="${target#*/}" + outdir="tmp/release/evydence_${version}_${goos}_${goarch}" + mkdir -p "${outdir}" + for command in "${commands[@]}"; do + suffix="" + if [[ "${goos}" == "windows" ]]; then + suffix=".exe" + fi + GOOS="${goos}" GOARCH="${goarch}" CGO_ENABLED=0 \ + go build -trimpath -ldflags "-s -w" \ + -o "${outdir}/${command}${suffix}" "./cmd/${command}" + done + cp LICENSE README.md "${outdir}/" + if [[ "${goos}" == "windows" ]]; then + (cd tmp/release && zip -qr "../../dist/evydence_${version}_${goos}_${goarch}.zip" "evydence_${version}_${goos}_${goarch}") + else + tar -C tmp/release -czf "dist/evydence_${version}_${goos}_${goarch}.tar.gz" "evydence_${version}_${goos}_${goarch}" + fi + done + cp openapi.yaml dist/openapi.yaml + cp coverage.out dist/coverage.out + cp tmp/release-check-summary.txt dist/release-check-summary.txt + find migrations -type f -print | LC_ALL=C sort | xargs sha256sum > dist/migrations.sha256 + (cd dist && sha256sum evydence_${version}_*.tar.gz evydence_${version}_*.zip openapi.yaml coverage.out release-check-summary.txt migrations.sha256 > SHA256SUMS) + + - name: Create and sign release manifest + shell: bash + run: | + set -euo pipefail + install -m 700 -d tmp/release-signing + signing_key="tmp/release-signing/private.key" + umask 077 + printf '%s' "${RELEASE_SIGNING_PRIVATE_KEY_B64}" > "${signing_key}" + tar -xzf "dist/evydence_${{ steps.release.outputs.tag }}_linux_amd64.tar.gz" -C tmp/release-signing + cli="tmp/release-signing/evydence_${{ steps.release.outputs.tag }}_linux_amd64/evydence" + "${cli}" release manifest \ + --out dist/evydence-release-manifest.json \ + dist/evydence_${{ steps.release.outputs.tag }}_*.tar.gz \ + dist/evydence_${{ steps.release.outputs.tag }}_*.zip \ + dist/openapi.yaml \ + dist/coverage.out \ + dist/release-check-summary.txt \ + dist/migrations.sha256 \ + dist/SHA256SUMS + "${cli}" release sign \ + --manifest dist/evydence-release-manifest.json \ + --private-key "${signing_key}" \ + --out dist/evydence-release-manifest.sig.json + rm -f "${signing_key}" + "${cli}" release verify \ + --manifest dist/evydence-release-manifest.json \ + --signature dist/evydence-release-manifest.sig.json + + - name: Write release notes + shell: bash + run: | + set -euo pipefail + cat > dist/release-notes.md <<'NOTES' + Evydence release artifacts include binaries, checksums, the OpenAPI contract, migration checksums, coverage output, a release-check summary, a signed release artifact manifest, and verification metadata. + + This release evidence supports engineering review of technical evidence handling. It is not legal compliance proof, certification, a secure-release guarantee, complete SBOM proof, or authoritative vulnerability coverage. + NOTES + + - name: Upload packaged release evidence + uses: actions/upload-artifact@v7 + with: + name: evydence-release-artifacts-${{ steps.release.outputs.tag }} + path: dist/ + if-no-files-found: error + + - name: Create or update draft GitHub release + if: github.event_name == 'push' || github.event.inputs.upload_draft_release == 'true' + env: + GH_TOKEN: ${{ github.token }} + shell: bash + run: | + set -euo pipefail + tag="${{ steps.release.outputs.tag }}" + if gh release view "${tag}" >/dev/null 2>&1; then + gh release upload "${tag}" dist/* --clobber + else + gh release create "${tag}" dist/* --draft --title "Evydence ${tag}" --notes-file dist/release-notes.md + fi diff --git a/Makefile b/Makefile index c22db11..d371843 100644 --- a/Makefile +++ b/Makefile @@ -101,6 +101,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @test -f docs/github-actions/release-evidence-workflow.yml @test -f docs/github-actions/upload-build/action.yml @test -f docs/gitlab/evydence-release-evidence.gitlab-ci.yml + @test -f .github/workflows/release-artifacts.yml @test -f docs/sdk/README.md @for path in \ "tutorials/getting-started.md" \ @@ -147,6 +148,10 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'cat > evydence-upload-manifest.json' docs/gitlab/evydence-release-evidence.gitlab-ci.yml >/dev/null @grep -F 'artifact.digest' docs/gitlab/evydence-release-evidence.gitlab-ci.yml >/dev/null @grep -F -- '--manifest evydence-upload-manifest.json' docs/gitlab/evydence-release-evidence.gitlab-ci.yml >/dev/null + @grep -F 'make production-check' .github/workflows/release-artifacts.yml >/dev/null + @grep -F 'EVYDENCE_RELEASE_SIGNING_PRIVATE_KEY_B64' .github/workflows/release-artifacts.yml >/dev/null + @grep -F 'evydence-release-manifest.sig.json' .github/workflows/release-artifacts.yml >/dev/null + @grep -F 'gh release create' .github/workflows/release-artifacts.yml >/dev/null @! grep -R -i "automatically compliant\|certified secure\|legally sufficient\|SBOM is complete\|all vulnerabilities detected\|scanner findings are authoritative\|regulator-ready without review" README.md docs deploy-check: ## Validate deployment and air-gap skeletons exist diff --git a/docs/reference/release-validation.md b/docs/reference/release-validation.md index d3f4b9d..7c84e50 100644 --- a/docs/reference/release-validation.md +++ b/docs/reference/release-validation.md @@ -86,3 +86,37 @@ evidence, customer package tokens, signing-key material, or other real secrets. The workflow is release-evidence CI, not the final production-readiness gate. `make production-check` remains the strict local/CI gate once coverage and the remaining production-hardening tickets are complete. + +## Signed Release Artifact Workflow + +The checked-in `.github/workflows/release-artifacts.yml` workflow packages +self-contained release archives for the CLI, API, worker, and migration +commands on Linux, macOS, and Windows targets. It runs `make production-check` +against disposable PostgreSQL before building artifacts. + +The workflow requires this repository secret: + +```text +EVYDENCE_RELEASE_SIGNING_PRIVATE_KEY_B64 +``` + +The value must be the base64 Ed25519 private key generated by: + +```sh +./dist/evydence release keygen \ + --private-out evydence-release-private.key \ + --public-out evydence-release-public.key +``` + +The private key is written only to a temporary file with restrictive +permissions inside the workflow, used to produce +`evydence-release-manifest.sig.json`, and then removed. The uploaded artifact +set includes binaries, checksums, `openapi.yaml`, migration checksums, +`coverage.out`, `tmp/release-check-summary.txt`, the release manifest, and the +manifest signature. Tag pushes create or update a draft GitHub release; manual +runs can upload only the workflow artifact unless `upload_draft_release` is +enabled. + +These artifacts support reproducible engineering review. They are not legal +compliance proof, certification, a secure-release guarantee, complete SBOM +proof, or authoritative vulnerability coverage. From e2c003923dff7d77730dc42d1fce1b200d93745b Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 18:19:11 +0300 Subject: [PATCH 056/287] docs: tighten source snapshot openapi contracts --- docs/reference/api-contract-matrix.md | 10 +- internal/adapters/httpapi/openapi.go | 121 +++++++++++++++++- .../adapters/httpapi/openapi_operations.go | 14 +- openapi.yaml | 2 +- 4 files changed, 137 insertions(+), 10 deletions(-) diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index 98d1cf6..ed991ca 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,11 +3,11 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 160 operations: 31 precise, 129 broad. +Generated from 160 operations: 35 precise, 125 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | -| GET | /v1/admin/instance | instanceAdminSnapshot | Bearer | instance:admin | - | - | - | 200:application/json:DataEnvelope | broad | +| GET | /v1/admin/instance | instanceAdminSnapshot | Bearer | instance:admin | - | - | - | 200:application/json:InstanceAdminSnapshotEnvelope | precise | | GET | /v1/api-keys | listAPIKeys | Bearer | admin | - | - | - | 200:unspecified | broad | | POST | /v1/api-keys | createAPIKey | Bearer | admin | required | - | - | 201:unspecified | broad | | POST | /v1/api-security-scans | uploadAPISecurityScan | Bearer | security:write | required | - | - | 201:unspecified | broad | @@ -26,8 +26,8 @@ Generated from 160 operations: 31 precise, 129 broad. | POST | /v1/builds/{id}/attestations | uploadBuildAttestation | Bearer | build:write | required | - | - | 201:unspecified | broad | | GET | /v1/collectors | listCollectors | Bearer | collector:read | - | - | - | 200:unspecified | broad | | POST | /v1/collectors | createCollector | Bearer | collector:admin | required | - | - | 201:unspecified | broad | -| POST | /v1/collectors/github/source-snapshots | uploadGitHubSourceSnapshot | Bearer | source:write | required | - | - | 201:unspecified | broad | -| POST | /v1/collectors/gitlab/source-snapshots | uploadGitLabSourceSnapshot | Bearer | source:write | required | - | - | 201:unspecified | broad | +| POST | /v1/collectors/github/source-snapshots | uploadGitHubSourceSnapshot | Bearer | source:write | required | - | application/json:SourceSnapshotRequest | 201:application/json:SourceSnapshotEnvelope | precise | +| POST | /v1/collectors/gitlab/source-snapshots | uploadGitLabSourceSnapshot | Bearer | source:write | required | - | application/json:SourceSnapshotRequest | 201:application/json:SourceSnapshotEnvelope | precise | | GET | /v1/collectors/{id}/health | collectorHealthReport | Bearer | collector:read | - | - | - | 200:unspecified | broad | | POST | /v1/collectors/{id}/releases | recordCollectorRelease | Bearer | collector:admin | required | - | - | 201:unspecified | broad | | GET | /v1/commercial-collectors | listCommercialCollectors | Bearer | collector:read | - | - | - | 200:unspecified | broad | @@ -59,7 +59,7 @@ Generated from 160 operations: 31 precise, 129 broad. | POST | /v1/evidence | createEvidence | Bearer | evidence:write | required | - | application/json:CreateEvidenceRequest | 201:application/json:DataEnvelope | broad | | POST | /v1/evidence-bundles | exportEvidenceBundle | Bearer | bundle:read | required | - | - | 201:unspecified | broad | | POST | /v1/evidence-bundles/import | importEvidenceBundle | Bearer | bundle:write | required | - | - | 201:unspecified | broad | -| POST | /v1/evidence-graph-snapshots | createGraphSnapshot | Bearer | evidence:read | required | - | - | 201:unspecified | broad | +| POST | /v1/evidence-graph-snapshots | createGraphSnapshot | Bearer | evidence:read | required | - | application/json:CreateGraphSnapshotRequest | 201:application/json:EvidenceGraphSnapshotEnvelope | precise | | POST | /v1/evidence-summaries | createEvidenceSummary | Bearer | report:read | required | - | - | 201:unspecified | broad | | GET | /v1/evidence/search | searchEvidence | Bearer | evidence:read | - | query:cursor, query:limit, query:product_id, query:project_id, query:release_id, query:source, query:tag, query:type | - | 200:application/json:EvidenceSearchEnvelope | precise | | GET | /v1/evidence/{id} | getEvidence | Bearer | evidence:read | - | - | - | 200:unspecified | broad | diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 1f762d6..baaa7cb 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -37,11 +37,13 @@ func registerCriticalSchemas(registry *specs.Registry) { }, "data", "meta")) registry.RegisterSchema("EmptyObject", objectSchema(map[string]any{})) registry.RegisterSchema("InstanceAdminSnapshot", objectSchema(map[string]any{ + "report_type": map[string]any{"type": "string"}, "tenant_count": map[string]any{"type": "integer"}, - "user_count": map[string]any{"type": "integer"}, - "api_key_count": map[string]any{"type": "integer"}, "resource_counts": map[string]any{"type": "object", "additionalProperties": map[string]any{"type": "integer"}}, - }, "tenant_count", "resource_counts")) + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "generated_at": map[string]any{"type": "string", "format": "date-time"}, + }, "report_type", "tenant_count", "resource_counts", "limitations", "generated_at")) + registry.RegisterSchema("InstanceAdminSnapshotEnvelope", dataEnvelopeSchema("#/components/schemas/InstanceAdminSnapshot")) registry.RegisterSchema("CreateSSOSessionRequest", objectSchema(map[string]any{ "user_id": map[string]any{"type": "string"}, "provider_id": map[string]any{"type": "string"}, @@ -237,6 +239,119 @@ func registerCriticalSchemas(registry *specs.Registry) { "created_at": map[string]any{"type": "string", "format": "date-time"}, }, "id", "tenant_id", "project_id", "release_id", "provider", "commit_sha", "status", "schema_version", "created_at")) registry.RegisterSchema("BuildRunEnvelope", dataEnvelopeSchema("#/components/schemas/BuildRun")) + registry.RegisterSchema("SourceSnapshotRepositoryInput", objectSchema(map[string]any{ + "full_name": map[string]any{"type": "string"}, + "clone_url": map[string]any{"type": "string"}, + "default_branch": map[string]any{"type": "string"}, + }, "full_name")) + registry.RegisterSchema("SourceSnapshotCommitInput", objectSchema(map[string]any{ + "sha": map[string]any{"type": "string"}, + "author": map[string]any{"type": "string"}, + "message": map[string]any{"type": "string", "description": "Commit message supplied by the collector; Evydence stores a message hash."}, + "committed_at": map[string]any{"type": "string", "format": "date-time"}, + }, "sha", "committed_at")) + registry.RegisterSchema("SourceSnapshotBranchInput", objectSchema(map[string]any{ + "name": map[string]any{"type": "string"}, + "protected": map[string]any{"type": "boolean"}, + "protection_hash": map[string]any{"type": "string"}, + }, "name")) + registry.RegisterSchema("SourceSnapshotPullRequestInput", objectSchema(map[string]any{ + "provider_id": map[string]any{"type": "string"}, + "title": map[string]any{"type": "string"}, + "state": map[string]any{"type": "string"}, + "source_branch": map[string]any{"type": "string"}, + "target_branch": map[string]any{"type": "string"}, + "review_decision": map[string]any{"type": "string"}, + }, "provider_id", "state")) + registry.RegisterSchema("SourceSnapshotRequest", objectSchema(map[string]any{ + "project_id": map[string]any{"type": "string"}, + "repository": map[string]any{"$ref": "#/components/schemas/SourceSnapshotRepositoryInput"}, + "commit": map[string]any{"$ref": "#/components/schemas/SourceSnapshotCommitInput"}, + "branch": map[string]any{"$ref": "#/components/schemas/SourceSnapshotBranchInput"}, + "pull_request": map[string]any{"$ref": "#/components/schemas/SourceSnapshotPullRequestInput"}, + }, "repository")) + registry.RegisterSchema("SourceRepository", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "project_id": map[string]any{"type": "string"}, + "provider": map[string]any{"type": "string"}, + "full_name": map[string]any{"type": "string"}, + "clone_url": map[string]any{"type": "string"}, + "default_branch": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "provider", "full_name", "schema_version", "created_at")) + registry.RegisterSchema("SourceCommit", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "repository_id": map[string]any{"type": "string"}, + "sha": map[string]any{"type": "string"}, + "author": map[string]any{"type": "string"}, + "message_hash": map[string]any{"type": "string"}, + "committed_at": map[string]any{"type": "string", "format": "date-time"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "repository_id", "sha", "schema_version", "created_at")) + registry.RegisterSchema("SourceBranch", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "repository_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "head_commit_id": map[string]any{"type": "string"}, + "protected": map[string]any{"type": "boolean"}, + "protection_hash": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "repository_id", "name", "protected", "schema_version", "created_at")) + registry.RegisterSchema("PullRequest", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "repository_id": map[string]any{"type": "string"}, + "provider": map[string]any{"type": "string"}, + "provider_id": map[string]any{"type": "string"}, + "title": map[string]any{"type": "string"}, + "state": map[string]any{"type": "string"}, + "source_branch": map[string]any{"type": "string"}, + "target_branch": map[string]any{"type": "string"}, + "head_commit_id": map[string]any{"type": "string"}, + "review_decision": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "repository_id", "provider", "provider_id", "state", "schema_version", "created_at")) + registry.RegisterSchema("SourceSnapshotResult", objectSchema(map[string]any{ + "repository": map[string]any{"$ref": "#/components/schemas/SourceRepository"}, + "commit": map[string]any{"$ref": "#/components/schemas/SourceCommit"}, + "branch": map[string]any{"$ref": "#/components/schemas/SourceBranch"}, + "pull_request": map[string]any{"$ref": "#/components/schemas/PullRequest"}, + }, "repository")) + registry.RegisterSchema("SourceSnapshotEnvelope", dataEnvelopeSchema("#/components/schemas/SourceSnapshotResult")) + registry.RegisterSchema("CreateGraphSnapshotRequest", objectSchema(map[string]any{ + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + })) + registry.RegisterSchema("EvidenceGraphNode", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "type": map[string]any{"type": "string"}, + "label": map[string]any{"type": "string"}, + }, "id", "type", "label")) + registry.RegisterSchema("EvidenceGraphEdge", objectSchema(map[string]any{ + "from": map[string]any{"type": "string"}, + "to": map[string]any{"type": "string"}, + "relationship": map[string]any{"type": "string"}, + }, "from", "to", "relationship")) + registry.RegisterSchema("EvidenceGraphSnapshot", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "nodes": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/EvidenceGraphNode"}}, + "edges": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/EvidenceGraphEdge"}}, + "graph_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "nodes", "edges", "graph_hash", "limitations", "schema_version", "created_at")) + registry.RegisterSchema("EvidenceGraphSnapshotEnvelope", dataEnvelopeSchema("#/components/schemas/EvidenceGraphSnapshot")) registry.RegisterSchema("EvidenceUploadRequest", objectSchema(map[string]any{ "release_id": map[string]any{"type": "string"}, "artifact_id": map[string]any{"type": "string"}, diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 6b763dd..b95dc98 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -16,7 +16,7 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Responses[http.StatusOK] = jsonResponse("Readiness status envelope.", "#/components/schemas/ReadinessStatusEnvelope") case "instanceAdminSnapshot": operation.Description = "Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient." - operation.Responses[http.StatusOK] = jsonResponse("Instance admin snapshot envelope.", "#/components/schemas/DataEnvelope") + operation.Responses[http.StatusOK] = jsonResponse("Instance admin snapshot envelope.", "#/components/schemas/InstanceAdminSnapshotEnvelope") case "createSSOSession": operation.Description = "Creates an admin-managed human SSO session record and returns a one-time bearer secret." operation.RequestBody = jsonRequest("SSO session creation request.", "#/components/schemas/CreateSSOSessionRequest") @@ -70,6 +70,14 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Description = "Returns a tenant-scoped build run by id." operation.Parameters = append(operation.Parameters, pathParam("id", "Build run id.")) operation.Responses[http.StatusOK] = jsonResponse("Build run envelope.", "#/components/schemas/BuildRunEnvelope") + case "uploadGitHubSourceSnapshot": + operation.Description = "Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records." + operation.RequestBody = jsonRequest("GitHub source snapshot upload request.", "#/components/schemas/SourceSnapshotRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created source snapshot resources envelope.", "#/components/schemas/SourceSnapshotEnvelope") + case "uploadGitLabSourceSnapshot": + operation.Description = "Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records." + operation.RequestBody = jsonRequest("GitLab source snapshot upload request.", "#/components/schemas/SourceSnapshotRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created source snapshot resources envelope.", "#/components/schemas/SourceSnapshotEnvelope") case "uploadSBOM": operation.Description = "Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata." operation.RequestBody = jsonRequest("CycloneDX SBOM upload request.", "#/components/schemas/EvidenceUploadRequest") @@ -111,6 +119,10 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { queryParam("limit", "Maximum returned records.", "integer"), ) operation.Responses[http.StatusOK] = jsonResponse("Evidence search result envelope.", "#/components/schemas/EvidenceSearchEnvelope") + case "createGraphSnapshot": + operation.Description = "Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records." + operation.RequestBody = jsonRequest("Evidence graph snapshot creation request.", "#/components/schemas/CreateGraphSnapshotRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created evidence graph snapshot envelope.", "#/components/schemas/EvidenceGraphSnapshotEnvelope") case "listSBOMComponents": operation.Description = "Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL." operation.Parameters = append(operation.Parameters, diff --git a/openapi.yaml b/openapi.yaml index 0d9fd8d..6bf6ddb 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{},"payload_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source":{"type":"string"},"subject_refs":{"items":{"type":"string"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"type":"object"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"api_key_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"},"user_count":{"type":"integer"}},"required":["tenant_count","resource_counts"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"List API keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"201":{"description":"Create API key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"201":{"description":"Create artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"Get artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"Verify cosign-style artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"Verify audit chain response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"List tenant audit log response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"Verify build attestation signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"201":{"description":"Upload build attestation response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"List collectors response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"201":{"description":"Create collector response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"operationId":"uploadGitHubSourceSnapshot","responses":{"201":{"description":"Upload GitHub source snapshot response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"operationId":"uploadGitLabSourceSnapshot","responses":{"201":{"description":"Upload GitLab source snapshot response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"List control evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"List control frameworks response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"201":{"description":"Create control framework response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"201":{"description":"Create security control response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"Get security control response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"201":{"description":"Link control evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"201":{"description":"Create custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"201":{"description":"Evaluate custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"List deployments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"201":{"description":"Record deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"Get deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"201":{"description":"Create DSSE trust root response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"List deployment environments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"201":{"description":"Create deployment environment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"List evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"operationId":"createGraphSnapshot","responses":{"201":{"description":"Create evidence graph snapshot response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"Get evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"List evidence lifecycle events response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"201":{"description":"Record evidence lifecycle event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"201":{"description":"Link evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"201":{"description":"Supersede evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"List exceptions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"201":{"description":"Create exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"Approve exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"Health response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"Safe tenant metrics response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"201":{"description":"Upload OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"Get OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"201":{"description":"Create OpenAPI contract diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OpenAPI response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"201":{"description":"Create organization response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"201":{"description":"Evaluate release policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"Get release bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"Get release bundle manifest response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"List release candidates response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"201":{"description":"Create release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"Get release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"Promote release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"Reject release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"Missing evidence report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"List role bindings response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"201":{"description":"Create role binding response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"List signing keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"201":{"description":"Rotate signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"Revoke signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"201":{"description":"Create signing provider operation receipt response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"201":{"description":"Create signing provider record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"201":{"description":"Record source branch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"201":{"description":"Record source commit response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"201":{"description":"Record pull request response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"List source repositories response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"201":{"description":"Create source repository response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"201":{"description":"Link SSO identity response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"Revoke SSO session response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"201":{"description":"Create user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"Deactivate user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"Version response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"201":{"description":"Create vulnerability decision response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"201":{"description":"Record vulnerability workflow event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"201":{"description":"Create waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"Approve waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{},"payload_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source":{"type":"string"},"subject_refs":{"items":{"type":"string"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"type":"object"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"List API keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"201":{"description":"Create API key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"201":{"description":"Create artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"Get artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"Verify cosign-style artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"Verify audit chain response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"List tenant audit log response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"Verify build attestation signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"201":{"description":"Upload build attestation response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"List collectors response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"201":{"description":"Create collector response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"List control evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"List control frameworks response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"201":{"description":"Create control framework response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"201":{"description":"Create security control response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"Get security control response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"201":{"description":"Link control evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"201":{"description":"Create custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"201":{"description":"Evaluate custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"List deployments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"201":{"description":"Record deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"Get deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"201":{"description":"Create DSSE trust root response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"List deployment environments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"201":{"description":"Create deployment environment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"List evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"Get evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"List evidence lifecycle events response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"201":{"description":"Record evidence lifecycle event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"201":{"description":"Link evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"201":{"description":"Supersede evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"List exceptions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"201":{"description":"Create exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"Approve exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"Health response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"Safe tenant metrics response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"201":{"description":"Upload OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"Get OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"201":{"description":"Create OpenAPI contract diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OpenAPI response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"201":{"description":"Create organization response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"201":{"description":"Evaluate release policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"Get release bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"Get release bundle manifest response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"List release candidates response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"201":{"description":"Create release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"Get release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"Promote release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"Reject release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"Missing evidence report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"List role bindings response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"201":{"description":"Create role binding response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"List signing keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"201":{"description":"Rotate signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"Revoke signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"201":{"description":"Create signing provider operation receipt response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"201":{"description":"Create signing provider record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"201":{"description":"Record source branch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"201":{"description":"Record source commit response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"201":{"description":"Record pull request response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"List source repositories response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"201":{"description":"Create source repository response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"201":{"description":"Link SSO identity response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"Revoke SSO session response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"201":{"description":"Create user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"Deactivate user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"Version response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"201":{"description":"Create vulnerability decision response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"201":{"description":"Record vulnerability workflow event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"201":{"description":"Create waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"Approve waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From bc04db8acf316383e734b3d7c79d903f8c0c2ff6 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 18:20:14 +0300 Subject: [PATCH 057/287] ci: enforce production check in github actions --- .github/workflows/ci.yml | 13 ++++++------- Makefile | 1 + docs/reference/release-validation.md | 17 +++++++++-------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 794c48a..1451c77 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,8 +12,8 @@ permissions: contents: read jobs: - release-check: - name: Release Check + production-check: + name: Production Check runs-on: ubuntu-latest services: postgres: @@ -45,11 +45,8 @@ jobs: - name: Install QA tools run: make tools - - name: Run release check with live PostgreSQL - run: make release-check - - - name: Generate coverage report - run: make coverage + - name: Run production check with live PostgreSQL + run: make production-check - name: Upload release evidence artifacts if: always() @@ -59,4 +56,6 @@ jobs: path: | coverage.out tmp/release-check-summary.txt + tmp/production-check/evydence-release-manifest.json + tmp/production-check/evydence-release-manifest.sig.json if-no-files-found: ignore diff --git a/Makefile b/Makefile index d371843..353b8e2 100644 --- a/Makefile +++ b/Makefile @@ -148,6 +148,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'cat > evydence-upload-manifest.json' docs/gitlab/evydence-release-evidence.gitlab-ci.yml >/dev/null @grep -F 'artifact.digest' docs/gitlab/evydence-release-evidence.gitlab-ci.yml >/dev/null @grep -F -- '--manifest evydence-upload-manifest.json' docs/gitlab/evydence-release-evidence.gitlab-ci.yml >/dev/null + @grep -F 'make production-check' .github/workflows/ci.yml >/dev/null @grep -F 'make production-check' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'EVYDENCE_RELEASE_SIGNING_PRIVATE_KEY_B64' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'evydence-release-manifest.sig.json' .github/workflows/release-artifacts.yml >/dev/null diff --git a/docs/reference/release-validation.md b/docs/reference/release-validation.md index 7c84e50..6e45f44 100644 --- a/docs/reference/release-validation.md +++ b/docs/reference/release-validation.md @@ -78,14 +78,15 @@ If either line is skipped, the release evidence should state that durable-store ## CI Usage The checked-in GitHub Actions workflow provides a disposable PostgreSQL service, -sets `EVYDENCE_TEST_DATABASE_URL`, runs `make release-check`, runs -`make coverage`, and preserves `tmp/release-check-summary.txt` plus -`coverage.out` as build artifacts. The database must not contain production -evidence, customer package tokens, signing-key material, or other real secrets. - -The workflow is release-evidence CI, not the final production-readiness gate. -`make production-check` remains the strict local/CI gate once coverage and the -remaining production-hardening tickets are complete. +sets `EVYDENCE_TEST_DATABASE_URL`, and runs `make production-check`. That gate +runs the live PostgreSQL release check, coverage threshold enforcement, lint, +gosec, govulncheck, race tests, OpenAPI/docs/deployment/SDK checks, and a +release manifest signing smoke test. + +The workflow preserves `tmp/release-check-summary.txt`, `coverage.out`, and the +production-check release manifest/signature smoke artifacts as build artifacts. +The database must not contain production evidence, customer package tokens, +signing-key material, or other real secrets. ## Signed Release Artifact Workflow From c5605b33bcd1b89a3903616f63d2584689fca36e Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 18:21:52 +0300 Subject: [PATCH 058/287] docs: tighten evidence openapi contracts --- docs/reference/api-contract-matrix.md | 8 +- internal/adapters/httpapi/openapi.go | 90 ++++++++++++++++--- .../adapters/httpapi/openapi_operations.go | 13 ++- openapi.yaml | 2 +- 4 files changed, 93 insertions(+), 20 deletions(-) diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index ed991ca..4c6d7a3 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 160 operations: 35 precise, 125 broad. +Generated from 160 operations: 38 precise, 122 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -55,14 +55,14 @@ Generated from 160 operations: 35 precise, 125 broad. | POST | /v1/dsse-trust-roots | createDSSETrustRoot | Bearer | keys:admin | required | - | - | 201:unspecified | broad | | GET | /v1/environments | listDeploymentEnvironments | Bearer | deployment:read | - | - | - | 200:unspecified | broad | | POST | /v1/environments | createDeploymentEnvironment | Bearer | deployment:write | required | - | - | 201:unspecified | broad | -| GET | /v1/evidence | listEvidence | Bearer | evidence:read | - | - | - | 200:unspecified | broad | -| POST | /v1/evidence | createEvidence | Bearer | evidence:write | required | - | application/json:CreateEvidenceRequest | 201:application/json:DataEnvelope | broad | +| GET | /v1/evidence | listEvidence | Bearer | evidence:read | - | query:release_id, query:type | - | 200:application/json:EvidenceItemListEnvelope | precise | +| POST | /v1/evidence | createEvidence | Bearer | evidence:write | required | - | application/json:CreateEvidenceRequest | 201:application/json:EvidenceItemEnvelope | precise | | POST | /v1/evidence-bundles | exportEvidenceBundle | Bearer | bundle:read | required | - | - | 201:unspecified | broad | | POST | /v1/evidence-bundles/import | importEvidenceBundle | Bearer | bundle:write | required | - | - | 201:unspecified | broad | | POST | /v1/evidence-graph-snapshots | createGraphSnapshot | Bearer | evidence:read | required | - | application/json:CreateGraphSnapshotRequest | 201:application/json:EvidenceGraphSnapshotEnvelope | precise | | POST | /v1/evidence-summaries | createEvidenceSummary | Bearer | report:read | required | - | - | 201:unspecified | broad | | GET | /v1/evidence/search | searchEvidence | Bearer | evidence:read | - | query:cursor, query:limit, query:product_id, query:project_id, query:release_id, query:source, query:tag, query:type | - | 200:application/json:EvidenceSearchEnvelope | precise | -| GET | /v1/evidence/{id} | getEvidence | Bearer | evidence:read | - | - | - | 200:unspecified | broad | +| GET | /v1/evidence/{id} | getEvidence | Bearer | evidence:read | - | path:id | - | 200:application/json:EvidenceItemEnvelope | precise | | GET | /v1/evidence/{id}/lifecycle-events | listEvidenceLifecycleEvents | Bearer | evidence:read | - | - | - | 200:unspecified | broad | | POST | /v1/evidence/{id}/lifecycle-events | recordEvidenceLifecycleEvent | Bearer | evidence:write | required | - | - | 201:unspecified | broad | | POST | /v1/evidence/{id}/link | linkEvidence | Bearer | evidence:write | required | - | - | 201:unspecified | broad | diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index baaa7cb..6a5f009 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -406,22 +406,84 @@ func registerCriticalSchemas(registry *specs.Registry) { "state": map[string]any{"type": "string"}, }, "vulnerability", "severity")}, }, "scanner", "target_ref", "release_id", "findings")) - registry.RegisterSchema("CreateEvidenceRequest", objectSchema(map[string]any{ - "product_id": map[string]any{"type": "string"}, - "project_id": map[string]any{"type": "string"}, - "release_id": map[string]any{"type": "string"}, - "artifact_id": map[string]any{"type": "string"}, + registry.RegisterSchema("SubjectRef", objectSchema(map[string]any{ + "type": map[string]any{"type": "string"}, + "id": map[string]any{"type": "string"}, + "digest": map[string]any{"type": "string"}, + }, "type")) + registry.RegisterSchema("EvidenceRef", objectSchema(map[string]any{ "type": map[string]any{"type": "string"}, - "subtype": map[string]any{"type": "string"}, - "title": map[string]any{"type": "string"}, - "payload_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, - "payload": map[string]any{}, - "tags": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, - "source": map[string]any{"type": "string"}, - "subject_refs": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, - }, "type", "title")) + "id": map[string]any{"type": "string"}, + "relationship": map[string]any{"type": "string"}, + }, "type", "id")) + registry.RegisterSchema("EvidenceNotice", objectSchema(map[string]any{ + "code": map[string]any{"type": "string"}, + "message": map[string]any{"type": "string"}, + }, "code", "message")) + registry.RegisterSchema("CreateEvidenceRequest", objectSchema(map[string]any{ + "product_id": map[string]any{"type": "string"}, + "project_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "build_id": map[string]any{"type": "string"}, + "deployment_id": map[string]any{"type": "string"}, + "type": map[string]any{"type": "string"}, + "subtype": map[string]any{"type": "string"}, + "title": map[string]any{"type": "string"}, + "source_system": map[string]any{"type": "string"}, + "source_identity": map[string]any{"type": "object", "additionalProperties": true}, + "collector_id": map[string]any{"type": "string"}, + "observed_at": map[string]any{"type": "string", "format": "date-time"}, + "payload_ref": map[string]any{"type": "string"}, + "payload_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "payload_media_type": map[string]any{"type": "string"}, + "payload_size": map[string]any{"type": "integer", "minimum": 0}, + "subject_refs": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/SubjectRef"}}, + "metadata": map[string]any{"type": "object", "additionalProperties": true}, + "tags": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + }, "type", "title", "payload_hash")) + registry.RegisterSchema("EvidenceItem", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "project_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "build_id": map[string]any{"type": "string"}, + "deployment_id": map[string]any{"type": "string"}, + "type": map[string]any{"type": "string"}, + "subtype": map[string]any{"type": "string"}, + "title": map[string]any{"type": "string"}, + "source_system": map[string]any{"type": "string"}, + "source_identity": map[string]any{"type": "object", "additionalProperties": true}, + "collector_id": map[string]any{"type": "string"}, + "uploaded_by": map[string]any{"type": "string"}, + "observed_at": map[string]any{"type": "string", "format": "date-time"}, + "evidence_version": map[string]any{"type": "integer"}, + "schema_version": map[string]any{"type": "string"}, + "payload_ref": map[string]any{"type": "string"}, + "payload_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "payload_media_type": map[string]any{"type": "string"}, + "payload_size": map[string]any{"type": "integer"}, + "canonical_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "canonicalization": map[string]any{"type": "string"}, + "subject_refs": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/SubjectRef"}}, + "related_evidence_refs": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/EvidenceRef"}}, + "supersedes": map[string]any{"type": "string"}, + "superseded_by": map[string]any{"type": "string"}, + "trust_level": map[string]any{"type": "string"}, + "verification_status": map[string]any{"type": "string"}, + "signature_refs": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "chain_entry_id": map[string]any{"type": "string"}, + "tags": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "metadata": map[string]any{"type": "object", "additionalProperties": true}, + "warnings": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/EvidenceNotice"}}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "type", "title", "source_system", "observed_at", "evidence_version", "schema_version", "payload_hash", "canonical_hash", "canonicalization", "trust_level", "verification_status", "chain_entry_id", "created_at")) + registry.RegisterSchema("EvidenceItemEnvelope", dataEnvelopeSchema("#/components/schemas/EvidenceItem")) + registry.RegisterSchema("EvidenceItemListEnvelope", dataArrayEnvelopeSchema("#/components/schemas/EvidenceItem")) registry.RegisterSchema("EvidenceSearchResponse", objectSchema(map[string]any{ - "items": map[string]any{"type": "array", "items": map[string]any{"type": "object"}}, + "items": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/EvidenceItem"}}, "next_cursor": map[string]any{"type": "string"}, }, "items")) registry.RegisterSchema("EvidenceSearchEnvelope", dataEnvelopeSchema("#/components/schemas/EvidenceSearchResponse")) diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index b95dc98..714e819 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -105,7 +105,14 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { case "createEvidence": operation.Description = "Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation." operation.RequestBody = jsonRequest("Evidence creation request.", "#/components/schemas/CreateEvidenceRequest") - operation.Responses[http.StatusCreated] = jsonResponse("Created evidence item envelope.", "#/components/schemas/DataEnvelope") + operation.Responses[http.StatusCreated] = jsonResponse("Created evidence item envelope.", "#/components/schemas/EvidenceItemEnvelope") + case "listEvidence": + operation.Description = "Lists tenant-scoped evidence by optional release and evidence type filters." + operation.Parameters = append(operation.Parameters, + queryParam("release_id", "Filter by release id.", "string"), + queryParam("type", "Filter by evidence type.", "string"), + ) + operation.Responses[http.StatusOK] = jsonResponse("Evidence item list envelope.", "#/components/schemas/EvidenceItemListEnvelope") case "searchEvidence": operation.Description = "Searches tenant-scoped evidence with deterministic filters and cursor-style pagination." operation.Parameters = append(operation.Parameters, @@ -119,6 +126,10 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { queryParam("limit", "Maximum returned records.", "integer"), ) operation.Responses[http.StatusOK] = jsonResponse("Evidence search result envelope.", "#/components/schemas/EvidenceSearchEnvelope") + case "getEvidence": + operation.Description = "Returns a tenant-scoped immutable evidence item by id." + operation.Parameters = append(operation.Parameters, pathParam("id", "Evidence item id.")) + operation.Responses[http.StatusOK] = jsonResponse("Evidence item envelope.", "#/components/schemas/EvidenceItemEnvelope") case "createGraphSnapshot": operation.Description = "Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records." operation.RequestBody = jsonRequest("Evidence graph snapshot creation request.", "#/components/schemas/CreateGraphSnapshotRequest") diff --git a/openapi.yaml b/openapi.yaml index 6bf6ddb..a675d31 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{},"payload_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source":{"type":"string"},"subject_refs":{"items":{"type":"string"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"type":"object"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"List API keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"201":{"description":"Create API key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"201":{"description":"Create artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"Get artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"Verify cosign-style artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"Verify audit chain response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"List tenant audit log response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"Verify build attestation signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"201":{"description":"Upload build attestation response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"List collectors response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"201":{"description":"Create collector response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"List control evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"List control frameworks response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"201":{"description":"Create control framework response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"201":{"description":"Create security control response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"Get security control response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"201":{"description":"Link control evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"201":{"description":"Create custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"201":{"description":"Evaluate custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"List deployments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"201":{"description":"Record deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"Get deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"201":{"description":"Create DSSE trust root response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"List deployment environments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"201":{"description":"Create deployment environment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"operationId":"listEvidence","responses":{"200":{"description":"List evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"operationId":"getEvidence","responses":{"200":{"description":"Get evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"List evidence lifecycle events response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"201":{"description":"Record evidence lifecycle event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"201":{"description":"Link evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"201":{"description":"Supersede evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"List exceptions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"201":{"description":"Create exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"Approve exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"Health response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"Safe tenant metrics response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"201":{"description":"Upload OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"Get OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"201":{"description":"Create OpenAPI contract diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OpenAPI response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"201":{"description":"Create organization response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"201":{"description":"Evaluate release policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"Get release bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"Get release bundle manifest response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"List release candidates response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"201":{"description":"Create release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"Get release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"Promote release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"Reject release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"Missing evidence report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"List role bindings response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"201":{"description":"Create role binding response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"List signing keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"201":{"description":"Rotate signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"Revoke signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"201":{"description":"Create signing provider operation receipt response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"201":{"description":"Create signing provider record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"201":{"description":"Record source branch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"201":{"description":"Record source commit response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"201":{"description":"Record pull request response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"List source repositories response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"201":{"description":"Create source repository response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"201":{"description":"Link SSO identity response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"Revoke SSO session response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"201":{"description":"Create user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"Deactivate user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"Version response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"201":{"description":"Create vulnerability decision response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"201":{"description":"Record vulnerability workflow event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"201":{"description":"Create waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"Approve waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"List API keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"201":{"description":"Create API key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"201":{"description":"Create artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"Get artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"Verify cosign-style artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"Verify audit chain response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"List tenant audit log response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"Verify build attestation signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"201":{"description":"Upload build attestation response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"List collectors response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"201":{"description":"Create collector response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"List control evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"List control frameworks response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"201":{"description":"Create control framework response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"201":{"description":"Create security control response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"Get security control response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"201":{"description":"Link control evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"201":{"description":"Create custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"201":{"description":"Evaluate custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"List deployments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"201":{"description":"Record deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"Get deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"201":{"description":"Create DSSE trust root response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"List deployment environments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"201":{"description":"Create deployment environment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"List evidence lifecycle events response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"201":{"description":"Record evidence lifecycle event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"201":{"description":"Link evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"201":{"description":"Supersede evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"List exceptions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"201":{"description":"Create exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"Approve exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"Health response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"Safe tenant metrics response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"201":{"description":"Upload OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"Get OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"201":{"description":"Create OpenAPI contract diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OpenAPI response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"201":{"description":"Create organization response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"201":{"description":"Evaluate release policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"Get release bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"Get release bundle manifest response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"List release candidates response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"201":{"description":"Create release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"Get release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"Promote release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"Reject release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"Missing evidence report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"List role bindings response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"201":{"description":"Create role binding response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"List signing keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"201":{"description":"Rotate signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"Revoke signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"201":{"description":"Create signing provider operation receipt response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"201":{"description":"Create signing provider record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"201":{"description":"Record source branch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"201":{"description":"Record source commit response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"201":{"description":"Record pull request response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"List source repositories response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"201":{"description":"Create source repository response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"201":{"description":"Link SSO identity response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"Revoke SSO session response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"201":{"description":"Create user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"Deactivate user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"Version response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"201":{"description":"Create vulnerability decision response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"201":{"description":"Record vulnerability workflow event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"201":{"description":"Create waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"Approve waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From edaf75d11da509ddd391802052847e209e1e3632 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 18:22:20 +0300 Subject: [PATCH 059/287] test: add migration compatibility gate --- Makefile | 5 +- docs/reference/release-validation.md | 11 +- .../postgres/migration_compatibility_test.go | 151 ++++++++++++++++++ scripts/production_check.sh | 1 + 4 files changed, 162 insertions(+), 6 deletions(-) create mode 100644 internal/adapters/postgres/migration_compatibility_test.go diff --git a/Makefile b/Makefile index 353b8e2..55f8666 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ GOLANGCI_LINT_VERSION ?= v2.11.4 GOSEC_VERSION ?= v2.25.0 GOVULNCHECK_VERSION ?= v1.2.0 -.PHONY: help tools fmt lint vuln gosec test test-race coverage coverage-check openapi-check meta-check docs-check deploy-check sdk-check fast-check finalize release-acceptance release-check production-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean +.PHONY: help tools fmt lint vuln gosec test test-race coverage coverage-check openapi-check meta-check docs-check deploy-check sdk-check fast-check finalize release-acceptance release-check production-check migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean help: ## Show help @awk 'BEGIN {FS=":.*## "}; /^[a-zA-Z0-9_.-]+:.*## / { printf " %-18s %s\n", $$1, $$2 }' $(MAKEFILE_LIST) @@ -218,6 +218,9 @@ release-check: ## Release validation with security, race, and configured live in production-check: ## Strict self-hosted production readiness gate; requires live PostgreSQL and coverage threshold @scripts/production_check.sh +migration-compatibility-check: ## Verify every committed migration prefix upgrades to current schema + @$(GO) test ./internal/adapters/postgres -run TestMigrationCompatibilityFromEveryCommittedState -count=1 + release-check-local-postgres: ## Start Compose Postgres, load .test.env or .test.env.example, and run release-check @docker compose up -d postgres @echo "waiting for compose postgres..." diff --git a/docs/reference/release-validation.md b/docs/reference/release-validation.md index 6e45f44..a131d03 100644 --- a/docs/reference/release-validation.md +++ b/docs/reference/release-validation.md @@ -38,9 +38,10 @@ make production-check That gate is stricter than `make release-check`: it requires `EVYDENCE_TEST_DATABASE_URL`, rejects skipped live PostgreSQL checks, enforces -the configured coverage threshold, and runs a release artifact signing smoke -test. See [Production readiness](production-readiness.md) for the supported -profiles and exit criteria. +the configured coverage threshold, verifies every committed migration prefix can +upgrade to the current schema in a temporary PostgreSQL schema, and runs a +release artifact signing smoke test. See [Production readiness](production-readiness.md) +for the supported profiles and exit criteria. ## Configured Live PostgreSQL Profile @@ -80,8 +81,8 @@ If either line is skipped, the release evidence should state that durable-store The checked-in GitHub Actions workflow provides a disposable PostgreSQL service, sets `EVYDENCE_TEST_DATABASE_URL`, and runs `make production-check`. That gate runs the live PostgreSQL release check, coverage threshold enforcement, lint, -gosec, govulncheck, race tests, OpenAPI/docs/deployment/SDK checks, and a -release manifest signing smoke test. +gosec, govulncheck, race tests, OpenAPI/docs/deployment/SDK checks, migration +compatibility tests, and a release manifest signing smoke test. The workflow preserves `tmp/release-check-summary.txt`, `coverage.out`, and the production-check release manifest/signature smoke artifacts as build artifacts. diff --git a/internal/adapters/postgres/migration_compatibility_test.go b/internal/adapters/postgres/migration_compatibility_test.go new file mode 100644 index 0000000..01ddb60 --- /dev/null +++ b/internal/adapters/postgres/migration_compatibility_test.go @@ -0,0 +1,151 @@ +package postgres + +import ( + "context" + "fmt" + "net/url" + "os" + "path/filepath" + "sort" + "strings" + "testing" + "time" + + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgxpool" +) + +func TestMigrationCompatibilityFromEveryCommittedState(t *testing.T) { + databaseURL := os.Getenv("EVYDENCE_TEST_DATABASE_URL") + if strings.TrimSpace(databaseURL) == "" { + t.Skip("EVYDENCE_TEST_DATABASE_URL is not set") + } + names := migrationFileNames(t, "../../../migrations") + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + defer cancel() + + basePool, err := pgxpool.New(ctx, databaseURL) + if err != nil { + t.Fatal(err) + } + defer basePool.Close() + + for prefix := 0; prefix <= len(names); prefix++ { + prefix := prefix + t.Run(fmt.Sprintf("prefix_%02d", prefix), func(t *testing.T) { + schema := fmt.Sprintf("evydence_migration_%d_%02d", time.Now().UnixNano(), prefix) + quotedSchema := pgx.Identifier{schema}.Sanitize() + if _, err := basePool.Exec(ctx, "CREATE SCHEMA "+quotedSchema); err != nil { + t.Fatal(err) + } + defer func() { + _, _ = basePool.Exec(context.Background(), "DROP SCHEMA "+quotedSchema+" CASCADE") + }() + + store, err := Open(ctx, databaseURLWithSearchPath(t, databaseURL, schema)) + if err != nil { + t.Fatal(err) + } + defer store.Close() + + applyMigrationPrefix(t, ctx, store, "../../../migrations", names[:prefix]) + applied, err := store.ApplyMigrations(ctx, "../../../migrations") + if err != nil { + t.Fatalf("upgrade from prefix %d: %v", prefix, err) + } + if want := len(names) - prefix; applied != want { + t.Fatalf("applied migrations = %d, want %d", applied, want) + } + var count int + if err := store.pool.QueryRow(ctx, `SELECT count(*) FROM schema_migrations`).Scan(&count); err != nil { + t.Fatal(err) + } + if count != len(names) { + t.Fatalf("schema_migrations count = %d, want %d", count, len(names)) + } + again, err := store.ApplyMigrations(ctx, "../../../migrations") + if err != nil { + t.Fatalf("idempotent apply from prefix %d: %v", prefix, err) + } + if again != 0 { + t.Fatalf("second apply = %d, want 0", again) + } + for _, table := range []string{"ledger_state", "resource_index", "outbox_jobs", "schema_migrations"} { + var exists bool + err := store.pool.QueryRow(ctx, `SELECT to_regclass($1) IS NOT NULL`, table).Scan(&exists) + if err != nil { + t.Fatal(err) + } + if !exists { + t.Fatalf("table %s is missing after migration upgrade", table) + } + } + }) + } +} + +func migrationFileNames(t *testing.T, dir string) []string { + t.Helper() + entries, err := os.ReadDir(dir) + if err != nil { + t.Fatal(err) + } + names := []string{} + for _, entry := range entries { + if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".up.sql") { + continue + } + names = append(names, entry.Name()) + } + sort.Strings(names) + if len(names) == 0 { + t.Fatal("no migration files found") + } + return names +} + +func applyMigrationPrefix(t *testing.T, ctx context.Context, store *Store, dir string, names []string) { + t.Helper() + if _, err := store.pool.Exec(ctx, ` + CREATE TABLE IF NOT EXISTS schema_migrations ( + version text PRIMARY KEY, + applied_at timestamptz NOT NULL DEFAULT now() + ) + `); err != nil { + t.Fatal(err) + } + for _, name := range names { + version := strings.TrimSuffix(name, ".up.sql") + body, err := os.ReadFile(filepath.Join(dir, name)) // #nosec G304 -- migration names come from ReadDir and are filtered to .up.sql files. + if err != nil { + t.Fatal(err) + } + tx, err := store.pool.BeginTx(ctx, pgx.TxOptions{}) + if err != nil { + t.Fatal(err) + } + if _, err := tx.Exec(ctx, string(body)); err != nil { + _ = tx.Rollback(ctx) + t.Fatalf("apply prefix migration %s: %v", version, err) + } + if _, err := tx.Exec(ctx, `INSERT INTO schema_migrations (version) VALUES ($1)`, version); err != nil { + _ = tx.Rollback(ctx) + t.Fatalf("record prefix migration %s: %v", version, err) + } + if err := tx.Commit(ctx); err != nil { + t.Fatal(err) + } + } +} + +func databaseURLWithSearchPath(t *testing.T, rawURL, schema string) string { + t.Helper() + parsed, err := url.Parse(rawURL) + if err != nil { + t.Fatal(err) + } + query := parsed.Query() + query.Set("search_path", schema) + parsed.RawQuery = query.Encode() + return parsed.String() +} diff --git a/scripts/production_check.sh b/scripts/production_check.sh index 3e8778e..eed6517 100755 --- a/scripts/production_check.sh +++ b/scripts/production_check.sh @@ -13,6 +13,7 @@ printf '%s\n' "Running Evydence production readiness checks" make release-check make coverage-check +make migration-compatibility-check workdir="tmp/production-check" rm -rf "$workdir" From 369bc41e81c8f0b6308c01a706e5310760b719d0 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 18:30:18 +0300 Subject: [PATCH 060/287] fix: clean migration compatibility schemas safely --- internal/adapters/postgres/migration_compatibility_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/adapters/postgres/migration_compatibility_test.go b/internal/adapters/postgres/migration_compatibility_test.go index 01ddb60..a3f7051 100644 --- a/internal/adapters/postgres/migration_compatibility_test.go +++ b/internal/adapters/postgres/migration_compatibility_test.go @@ -38,9 +38,9 @@ func TestMigrationCompatibilityFromEveryCommittedState(t *testing.T) { if _, err := basePool.Exec(ctx, "CREATE SCHEMA "+quotedSchema); err != nil { t.Fatal(err) } - defer func() { - _, _ = basePool.Exec(context.Background(), "DROP SCHEMA "+quotedSchema+" CASCADE") - }() + defer func(cleanupCtx context.Context) { + _, _ = basePool.Exec(cleanupCtx, "DROP SCHEMA "+quotedSchema+" CASCADE") + }(context.WithoutCancel(ctx)) store, err := Open(ctx, databaseURLWithSearchPath(t, databaseURL, schema)) if err != nil { From e1b0fd5fbc7ea299b41d117b99deb347b9b3796c Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 18:36:44 +0300 Subject: [PATCH 061/287] feat: fail closed on pending migrations --- cmd/evydence-api/main.go | 6 +- cmd/evydence-worker/main.go | 9 ++- docs/reference/configuration.md | 2 +- internal/adapters/postgres/migrate.go | 83 +++++++++++++++++++----- internal/adapters/postgres/store_test.go | 55 ++++++++++++++++ 5 files changed, 134 insertions(+), 21 deletions(-) diff --git a/cmd/evydence-api/main.go b/cmd/evydence-api/main.go index b38dec1..2305ce8 100644 --- a/cmd/evydence-api/main.go +++ b/cmd/evydence-api/main.go @@ -43,11 +43,15 @@ func run() error { return err } closeStore = pgStore.Close + migrationsDir := envDefault("EVYDENCE_MIGRATIONS_DIR", "migrations") if !strings.EqualFold(os.Getenv("EVYDENCE_SKIP_MIGRATIONS"), "true") { - if _, err := pgStore.ApplyMigrations(ctx, envDefault("EVYDENCE_MIGRATIONS_DIR", "migrations")); err != nil { + if _, err := pgStore.ApplyMigrations(ctx, migrationsDir); err != nil { closeStore() return fmt.Errorf("apply migrations: %w", err) } + } else if err := pgStore.RequireNoPendingMigrations(ctx, migrationsDir); err != nil { + closeStore() + return fmt.Errorf("check migrations: %w", err) } objectStore, objectDescription, err := openObjectStore(ctx) if err != nil { diff --git a/cmd/evydence-worker/main.go b/cmd/evydence-worker/main.go index 05ff7a1..ffc45ec 100644 --- a/cmd/evydence-worker/main.go +++ b/cmd/evydence-worker/main.go @@ -8,6 +8,7 @@ import ( "encoding/hex" "encoding/json" "errors" + "fmt" "io" "log" "os" @@ -45,14 +46,18 @@ func run() error { return err } defer store.Close() + migrationsDir := envDefault("EVYDENCE_MIGRATIONS_DIR", "migrations") + migrateCtx, cancel := context.WithTimeout(ctx, 30*time.Second) if !strings.EqualFold(os.Getenv("EVYDENCE_SKIP_MIGRATIONS"), "true") { - migrateCtx, cancel := context.WithTimeout(ctx, 30*time.Second) - if _, err := store.ApplyMigrations(migrateCtx, envDefault("EVYDENCE_MIGRATIONS_DIR", "migrations")); err != nil { + if _, err := store.ApplyMigrations(migrateCtx, migrationsDir); err != nil { cancel() return err } + } else if err := store.RequireNoPendingMigrations(migrateCtx, migrationsDir); err != nil { cancel() + return fmt.Errorf("check migrations: %w", err) } + cancel() objectStore, objectDescription, err := openObjectStore(ctx) if err != nil { return err diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index b2e6030..fac146b 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -36,7 +36,7 @@ The example secrets are placeholders. Replace them before using shared or produc | `EVYDENCE_S3_REGION` | No | empty | Optional S3 region. | | `EVYDENCE_S3_USE_SSL` | No | `false` locally, `true` in chart values | Use TLS for remote object storage. | | `EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE` | No | `0` disabled | Optional in-process per-client request limit using the TCP remote address. Use reverse-proxy or ingress rate limiting for production edge controls. | -| `EVYDENCE_SKIP_MIGRATIONS` | No | unset | Set to `true` only when migrations are applied by a separate release process. | +| `EVYDENCE_SKIP_MIGRATIONS` | No | unset | Set to `true` only when migrations are applied by a separate release process. API and worker startup still verify that no committed migrations are pending and fail closed if the database is behind. | | `EVYDENCE_MIGRATIONS_DIR` | No | `migrations` | Migration directory for API startup and `cmd/evydence-migrate`. | | `EVYDENCE_BOOTSTRAP_TENANT` | No | `Local Tenant` | Tenant name used when bootstrapping an empty store. | | `EVYDENCE_BOOTSTRAP_DISABLED` | No | unset | Set to `true` to prevent startup bootstrap on an empty store. | diff --git a/internal/adapters/postgres/migrate.go b/internal/adapters/postgres/migrate.go index be29dd6..5f636fc 100644 --- a/internal/adapters/postgres/migrate.go +++ b/internal/adapters/postgres/migrate.go @@ -12,25 +12,12 @@ import ( ) func (s *Store) ApplyMigrations(ctx context.Context, dir string) (int, error) { - entries, err := os.ReadDir(dir) + names, err := migrationNames(dir) if err != nil { - return 0, fmt.Errorf("read migrations: %w", err) - } - names := []string{} - for _, entry := range entries { - if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".up.sql") { - continue - } - names = append(names, entry.Name()) + return 0, err } - sort.Strings(names) - if _, err := s.pool.Exec(ctx, ` - CREATE TABLE IF NOT EXISTS schema_migrations ( - version text PRIMARY KEY, - applied_at timestamptz NOT NULL DEFAULT now() - ) - `); err != nil { - return 0, fmt.Errorf("ensure schema migrations table: %w", err) + if err := s.ensureSchemaMigrationsTable(ctx); err != nil { + return 0, err } applied := 0 for _, name := range names { @@ -66,3 +53,65 @@ func (s *Store) ApplyMigrations(ctx context.Context, dir string) (int, error) { } return applied, nil } + +func (s *Store) PendingMigrationVersions(ctx context.Context, dir string) ([]string, error) { + names, err := migrationNames(dir) + if err != nil { + return nil, err + } + if err := s.ensureSchemaMigrationsTable(ctx); err != nil { + return nil, err + } + pending := []string{} + for _, name := range names { + version := strings.TrimSuffix(name, ".up.sql") + var exists bool + err := s.pool.QueryRow(ctx, `SELECT EXISTS (SELECT 1 FROM schema_migrations WHERE version = $1)`, version).Scan(&exists) + if err != nil { + return nil, fmt.Errorf("check migration %s: %w", version, err) + } + if !exists { + pending = append(pending, version) + } + } + return pending, nil +} + +func (s *Store) RequireNoPendingMigrations(ctx context.Context, dir string) error { + pending, err := s.PendingMigrationVersions(ctx, dir) + if err != nil { + return err + } + if len(pending) > 0 { + return fmt.Errorf("database has %d unapplied migration(s); first pending migration is %s", len(pending), pending[0]) + } + return nil +} + +func (s *Store) ensureSchemaMigrationsTable(ctx context.Context) error { + if _, err := s.pool.Exec(ctx, ` + CREATE TABLE IF NOT EXISTS schema_migrations ( + version text PRIMARY KEY, + applied_at timestamptz NOT NULL DEFAULT now() + ) + `); err != nil { + return fmt.Errorf("ensure schema migrations table: %w", err) + } + return nil +} + +func migrationNames(dir string) ([]string, error) { + entries, err := os.ReadDir(dir) + if err != nil { + return nil, fmt.Errorf("read migrations: %w", err) + } + names := []string{} + for _, entry := range entries { + if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".up.sql") { + continue + } + names = append(names, entry.Name()) + } + sort.Strings(names) + return names, nil +} diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index 2a457f0..404dccd 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -3,9 +3,12 @@ package postgres import ( "context" "os" + "strings" "testing" "time" + "github.com/jackc/pgx/v5" + "github.com/aatuh/evydence/internal/app" "github.com/aatuh/evydence/internal/domain" ) @@ -85,3 +88,55 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { t.Fatal(err) } } + +func TestPendingMigrationVersionsWithPostgres(t *testing.T) { + databaseURL := os.Getenv("EVYDENCE_TEST_DATABASE_URL") + if databaseURL == "" { + t.Skip("EVYDENCE_TEST_DATABASE_URL is not set") + } + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + baseStore, err := Open(ctx, databaseURL) + if err != nil { + t.Fatal(err) + } + defer baseStore.Close() + schema := "evydence_pending_migrations_" + strings.ReplaceAll(time.Now().Format("150405.000000000"), ".", "_") + quotedSchema := pgx.Identifier{schema}.Sanitize() + if _, err := baseStore.pool.Exec(ctx, "CREATE SCHEMA "+quotedSchema); err != nil { + t.Fatal(err) + } + defer func(cleanupCtx context.Context) { + _, _ = baseStore.pool.Exec(cleanupCtx, "DROP SCHEMA "+quotedSchema+" CASCADE") + }(context.WithoutCancel(ctx)) + + store, err := Open(ctx, databaseURLWithSearchPath(t, databaseURL, schema)) + if err != nil { + t.Fatal(err) + } + defer store.Close() + pending, err := store.PendingMigrationVersions(ctx, "../../../migrations") + if err != nil { + t.Fatal(err) + } + names := migrationFileNames(t, "../../../migrations") + if len(pending) != len(names) { + t.Fatalf("pending migrations = %d, want %d", len(pending), len(names)) + } + if err := store.RequireNoPendingMigrations(ctx, "../../../migrations"); err == nil { + t.Fatal("expected pending migrations to fail closed") + } + if _, err := store.ApplyMigrations(ctx, "../../../migrations"); err != nil { + t.Fatal(err) + } + pending, err = store.PendingMigrationVersions(ctx, "../../../migrations") + if err != nil { + t.Fatal(err) + } + if len(pending) != 0 { + t.Fatalf("pending after apply = %#v", pending) + } + if err := store.RequireNoPendingMigrations(ctx, "../../../migrations"); err != nil { + t.Fatalf("require no pending after apply: %v", err) + } +} From c6d26be8a0a29c11fea1095474d4451ace555092 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 18:40:35 +0300 Subject: [PATCH 062/287] docs: tighten identity collector openapi contracts --- docs/reference/api-contract-matrix.md | 10 ++-- internal/adapters/httpapi/openapi.go | 48 +++++++++++++++++++ .../adapters/httpapi/openapi_operations.go | 14 ++++++ openapi.yaml | 2 +- 4 files changed, 68 insertions(+), 6 deletions(-) diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index 4c6d7a3..d42e9d7 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,13 +3,13 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 160 operations: 38 precise, 122 broad. +Generated from 160 operations: 42 precise, 118 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | GET | /v1/admin/instance | instanceAdminSnapshot | Bearer | instance:admin | - | - | - | 200:application/json:InstanceAdminSnapshotEnvelope | precise | -| GET | /v1/api-keys | listAPIKeys | Bearer | admin | - | - | - | 200:unspecified | broad | -| POST | /v1/api-keys | createAPIKey | Bearer | admin | required | - | - | 201:unspecified | broad | +| GET | /v1/api-keys | listAPIKeys | Bearer | admin | - | - | - | 200:application/json:APIKeyListEnvelope | precise | +| POST | /v1/api-keys | createAPIKey | Bearer | admin | required | - | application/json:CreateAPIKeyRequest | 201:application/json:APIKeyCreateEnvelope | precise | | POST | /v1/api-security-scans | uploadAPISecurityScan | Bearer | security:write | required | - | - | 201:unspecified | broad | | POST | /v1/approvals | createApproval | Bearer | release:write | required | - | - | 201:unspecified | broad | | POST | /v1/artifact-signatures | createArtifactSignature | Bearer | evidence:write | required | - | - | 201:unspecified | broad | @@ -24,8 +24,8 @@ Generated from 160 operations: 38 precise, 122 broad. | POST | /v1/builds | createBuild | Bearer | build:write | required | - | application/json:CreateBuildRequest | 201:application/json:BuildRunEnvelope | precise | | GET | /v1/builds/{id} | getBuild | Bearer | build:read | - | path:id | - | 200:application/json:BuildRunEnvelope | precise | | POST | /v1/builds/{id}/attestations | uploadBuildAttestation | Bearer | build:write | required | - | - | 201:unspecified | broad | -| GET | /v1/collectors | listCollectors | Bearer | collector:read | - | - | - | 200:unspecified | broad | -| POST | /v1/collectors | createCollector | Bearer | collector:admin | required | - | - | 201:unspecified | broad | +| GET | /v1/collectors | listCollectors | Bearer | collector:read | - | - | - | 200:application/json:CollectorListEnvelope | precise | +| POST | /v1/collectors | createCollector | Bearer | collector:admin | required | - | application/json:CreateCollectorRequest | 201:application/json:CollectorCreateEnvelope | precise | | POST | /v1/collectors/github/source-snapshots | uploadGitHubSourceSnapshot | Bearer | source:write | required | - | application/json:SourceSnapshotRequest | 201:application/json:SourceSnapshotEnvelope | precise | | POST | /v1/collectors/gitlab/source-snapshots | uploadGitLabSourceSnapshot | Bearer | source:write | required | - | application/json:SourceSnapshotRequest | 201:application/json:SourceSnapshotEnvelope | precise | | GET | /v1/collectors/{id}/health | collectorHealthReport | Bearer | collector:read | - | - | - | 200:unspecified | broad | diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 6a5f009..8eed27f 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -147,6 +147,54 @@ func registerCriticalSchemas(registry *specs.Registry) { "secret": map[string]any{"type": "string", "description": "One-time SSO session bearer secret; not returned by list/read operations."}, }, "session", "secret")) registry.RegisterSchema("SSOSessionCreateEnvelope", dataEnvelopeSchema("#/components/schemas/SSOSessionCreateResponse")) + registry.RegisterSchema("CreateAPIKeyRequest", objectSchema(map[string]any{ + "name": map[string]any{"type": "string"}, + "scopes": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "expires_at": map[string]any{"type": "string", "format": "date-time"}, + }, "name", "scopes")) + registry.RegisterSchema("APIKey", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "prefix": map[string]any{"type": "string", "description": "Non-secret key prefix for lookup and audit displays."}, + "scopes": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + "expires_at": map[string]any{"type": "string", "format": "date-time"}, + "revoked_at": map[string]any{"type": "string", "format": "date-time"}, + "last_used_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "name", "prefix", "scopes", "created_at")) + registry.RegisterSchema("APIKeyCreateResponse", objectSchema(map[string]any{ + "api_key": map[string]any{"$ref": "#/components/schemas/APIKey"}, + "secret": map[string]any{"type": "string", "description": "One-time API key secret; stored only as a peppered HMAC hash."}, + }, "api_key", "secret")) + registry.RegisterSchema("APIKeyCreateEnvelope", dataEnvelopeSchema("#/components/schemas/APIKeyCreateResponse")) + registry.RegisterSchema("APIKeyListEnvelope", dataArrayEnvelopeSchema("#/components/schemas/APIKey")) + registry.RegisterSchema("CreateCollectorRequest", objectSchema(map[string]any{ + "name": map[string]any{"type": "string"}, + "type": map[string]any{"type": "string", "enum": []string{"github_actions", "gitlab_ci", "generic_ci", "import_bundle"}}, + "version": map[string]any{"type": "string"}, + "scopes": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + }, "name", "type", "version")) + registry.RegisterSchema("Collector", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "type": map[string]any{"type": "string"}, + "version": map[string]any{"type": "string"}, + "api_key_id": map[string]any{"type": "string"}, + "status": map[string]any{"type": "string"}, + "allowed_scopes": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "last_seen_at": map[string]any{"type": "string", "format": "date-time"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "name", "type", "version", "api_key_id", "status", "allowed_scopes", "schema_version", "created_at")) + registry.RegisterSchema("CollectorCreateResponse", objectSchema(map[string]any{ + "collector": map[string]any{"$ref": "#/components/schemas/Collector"}, + "api_key": map[string]any{"$ref": "#/components/schemas/APIKey"}, + "secret": map[string]any{"type": "string", "description": "One-time collector API key secret; stored only as a peppered HMAC hash."}, + }, "collector", "api_key", "secret")) + registry.RegisterSchema("CollectorCreateEnvelope", dataEnvelopeSchema("#/components/schemas/CollectorCreateResponse")) + registry.RegisterSchema("CollectorListEnvelope", dataArrayEnvelopeSchema("#/components/schemas/Collector")) registry.RegisterSchema("CreateProductRequest", objectSchema(map[string]any{ "name": map[string]any{"type": "string"}, "slug": map[string]any{"type": "string"}, diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 714e819..4de0589 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -29,6 +29,20 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Description = "Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material." operation.RequestBody = jsonRequest("Provider identity verification request.", "#/components/schemas/VerifyProviderIdentityRequest") operation.Responses[http.StatusCreated] = jsonResponse("Provider verification envelope.", "#/components/schemas/ProviderVerificationEnvelope") + case "createAPIKey": + operation.Description = "Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata." + operation.RequestBody = jsonRequest("API key creation request.", "#/components/schemas/CreateAPIKeyRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created API key and one-time secret envelope.", "#/components/schemas/APIKeyCreateEnvelope") + case "listAPIKeys": + operation.Description = "Lists tenant-scoped API key metadata without key hashes or one-time secrets." + operation.Responses[http.StatusOK] = jsonResponse("API key list envelope.", "#/components/schemas/APIKeyListEnvelope") + case "createCollector": + operation.Description = "Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once." + operation.RequestBody = jsonRequest("Collector creation request.", "#/components/schemas/CreateCollectorRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created collector and one-time key secret envelope.", "#/components/schemas/CollectorCreateEnvelope") + case "listCollectors": + operation.Description = "Lists tenant-scoped collector metadata without API key hashes or one-time secrets." + operation.Responses[http.StatusOK] = jsonResponse("Collector list envelope.", "#/components/schemas/CollectorListEnvelope") case "createProduct": operation.Description = "Creates a tenant-scoped product. Product slugs must be unique per tenant." operation.RequestBody = jsonRequest("Product creation request.", "#/components/schemas/CreateProductRequest") diff --git a/openapi.yaml b/openapi.yaml index a675d31..275dd1c 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"operationId":"listAPIKeys","responses":{"200":{"description":"List API keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"operationId":"createAPIKey","responses":{"201":{"description":"Create API key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"201":{"description":"Create artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"Get artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"Verify cosign-style artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"Verify audit chain response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"List tenant audit log response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"Verify build attestation signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"201":{"description":"Upload build attestation response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"operationId":"listCollectors","responses":{"200":{"description":"List collectors response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCollector","responses":{"201":{"description":"Create collector response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"List control evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"List control frameworks response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"201":{"description":"Create control framework response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"201":{"description":"Create security control response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"Get security control response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"201":{"description":"Link control evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"201":{"description":"Create custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"201":{"description":"Evaluate custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"List deployments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"201":{"description":"Record deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"Get deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"201":{"description":"Create DSSE trust root response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"List deployment environments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"201":{"description":"Create deployment environment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"List evidence lifecycle events response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"201":{"description":"Record evidence lifecycle event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"201":{"description":"Link evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"201":{"description":"Supersede evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"List exceptions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"201":{"description":"Create exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"Approve exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"Health response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"Safe tenant metrics response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"201":{"description":"Upload OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"Get OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"201":{"description":"Create OpenAPI contract diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OpenAPI response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"201":{"description":"Create organization response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"201":{"description":"Evaluate release policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"Get release bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"Get release bundle manifest response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"List release candidates response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"201":{"description":"Create release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"Get release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"Promote release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"Reject release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"Missing evidence report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"List role bindings response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"201":{"description":"Create role binding response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"List signing keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"201":{"description":"Rotate signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"Revoke signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"201":{"description":"Create signing provider operation receipt response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"201":{"description":"Create signing provider record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"201":{"description":"Record source branch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"201":{"description":"Record source commit response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"201":{"description":"Record pull request response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"List source repositories response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"201":{"description":"Create source repository response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"201":{"description":"Link SSO identity response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"Revoke SSO session response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"201":{"description":"Create user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"Deactivate user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"Version response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"201":{"description":"Create vulnerability decision response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"201":{"description":"Record vulnerability workflow event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"201":{"description":"Create waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"Approve waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"201":{"description":"Create artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"Get artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"Verify cosign-style artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"Verify audit chain response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"List tenant audit log response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"Verify build attestation signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"201":{"description":"Upload build attestation response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"List control evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"List control frameworks response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"201":{"description":"Create control framework response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"201":{"description":"Create security control response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"Get security control response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"201":{"description":"Link control evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"201":{"description":"Create custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"201":{"description":"Evaluate custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"List deployments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"201":{"description":"Record deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"Get deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"201":{"description":"Create DSSE trust root response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"List deployment environments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"201":{"description":"Create deployment environment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"List evidence lifecycle events response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"201":{"description":"Record evidence lifecycle event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"201":{"description":"Link evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"201":{"description":"Supersede evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"List exceptions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"201":{"description":"Create exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"Approve exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"Health response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"Safe tenant metrics response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"201":{"description":"Upload OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"Get OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"201":{"description":"Create OpenAPI contract diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OpenAPI response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"201":{"description":"Create organization response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"201":{"description":"Evaluate release policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"Get release bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"Get release bundle manifest response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"List release candidates response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"201":{"description":"Create release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"Get release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"Promote release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"Reject release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"Missing evidence report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"List role bindings response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"201":{"description":"Create role binding response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"List signing keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"201":{"description":"Rotate signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"Revoke signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"201":{"description":"Create signing provider operation receipt response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"201":{"description":"Create signing provider record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"201":{"description":"Record source branch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"201":{"description":"Record source commit response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"201":{"description":"Record pull request response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"List source repositories response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"201":{"description":"Create source repository response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"201":{"description":"Link SSO identity response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"Revoke SSO session response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"201":{"description":"Create user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"Deactivate user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"Version response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"201":{"description":"Create vulnerability decision response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"201":{"description":"Record vulnerability workflow event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"201":{"description":"Create waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"Approve waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From edf81578dcc80d7355ff2b9da5a565c50a54246d Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 18:53:43 +0300 Subject: [PATCH 063/287] docs: tighten control openapi contracts --- docs/reference/api-contract-matrix.md | 14 ++-- internal/adapters/httpapi/openapi.go | 72 +++++++++++++++++++ .../adapters/httpapi/openapi_operations.go | 28 ++++++++ openapi.yaml | 2 +- 4 files changed, 108 insertions(+), 8 deletions(-) diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index d42e9d7..9e6f05c 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 160 operations: 42 precise, 118 broad. +Generated from 160 operations: 48 precise, 112 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -33,14 +33,14 @@ Generated from 160 operations: 42 precise, 118 broad. | GET | /v1/commercial-collectors | listCommercialCollectors | Bearer | collector:read | - | - | - | 200:unspecified | broad | | POST | /v1/commercial-collectors | createCommercialCollector | Bearer | collector:admin | required | - | - | 201:unspecified | broad | | POST | /v1/container-images | registerContainerImage | Bearer | evidence:write | required | - | - | 201:unspecified | broad | -| GET | /v1/control-evidence | listControlEvidence | Bearer | controls:read | - | - | - | 200:unspecified | broad | +| GET | /v1/control-evidence | listControlEvidence | Bearer | controls:read | - | query:control_id, query:product_id, query:release_id | - | 200:application/json:ControlEvidenceListEnvelope | precise | | GET | /v1/control-framework-template-packs | listControlFrameworkTemplatePacks | Bearer | controls:read | - | - | - | 200:unspecified | broad | | POST | /v1/control-framework-template-packs/{slug}/install | installControlFrameworkTemplatePack | Bearer | controls:admin | required | - | - | 201:unspecified | broad | -| GET | /v1/control-frameworks | listControlFrameworks | Bearer | controls:read | - | - | - | 200:unspecified | broad | -| POST | /v1/control-frameworks | createControlFramework | Bearer | controls:admin | required | - | - | 201:unspecified | broad | -| POST | /v1/controls | createSecurityControl | Bearer | controls:admin | required | - | - | 201:unspecified | broad | -| GET | /v1/controls/{id} | getSecurityControl | Bearer | controls:read | - | - | - | 200:unspecified | broad | -| POST | /v1/controls/{id}/evidence | linkControlEvidence | Bearer | controls:write | required | - | - | 201:unspecified | broad | +| GET | /v1/control-frameworks | listControlFrameworks | Bearer | controls:read | - | - | - | 200:application/json:ControlFrameworkListEnvelope | precise | +| POST | /v1/control-frameworks | createControlFramework | Bearer | controls:admin | required | - | application/json:CreateControlFrameworkRequest | 201:application/json:ControlFrameworkEnvelope | precise | +| POST | /v1/controls | createSecurityControl | Bearer | controls:admin | required | - | application/json:CreateSecurityControlRequest | 201:application/json:SecurityControlEnvelope | precise | +| GET | /v1/controls/{id} | getSecurityControl | Bearer | controls:read | - | path:id | - | 200:application/json:SecurityControlEnvelope | precise | +| POST | /v1/controls/{id}/evidence | linkControlEvidence | Bearer | controls:write | required | path:id | application/json:LinkControlEvidenceRequest | 201:application/json:ControlEvidenceEnvelope | precise | | POST | /v1/custom-policies | createCustomPolicy | Bearer | policy:write | required | - | - | 201:unspecified | broad | | POST | /v1/custom-policies/{id}/evaluate | evaluateCustomPolicy | Bearer | policy:read | required | - | - | 201:unspecified | broad | | POST | /v1/customer-packages | createCustomerPackage | Bearer | package:write | required | - | - | 201:unspecified | broad | diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 8eed27f..692b464 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -195,6 +195,78 @@ func registerCriticalSchemas(registry *specs.Registry) { }, "collector", "api_key", "secret")) registry.RegisterSchema("CollectorCreateEnvelope", dataEnvelopeSchema("#/components/schemas/CollectorCreateResponse")) registry.RegisterSchema("CollectorListEnvelope", dataArrayEnvelopeSchema("#/components/schemas/Collector")) + registry.RegisterSchema("CreateControlFrameworkRequest", objectSchema(map[string]any{ + "name": map[string]any{"type": "string"}, + "slug": map[string]any{"type": "string"}, + "version": map[string]any{"type": "string"}, + "description": map[string]any{"type": "string"}, + }, "name", "version")) + registry.RegisterSchema("ControlFramework", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "slug": map[string]any{"type": "string"}, + "version": map[string]any{"type": "string"}, + "description": map[string]any{"type": "string"}, + "status": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "name", "slug", "version", "status", "schema_version", "created_at")) + registry.RegisterSchema("ControlFrameworkEnvelope", dataEnvelopeSchema("#/components/schemas/ControlFramework")) + registry.RegisterSchema("ControlFrameworkListEnvelope", dataArrayEnvelopeSchema("#/components/schemas/ControlFramework")) + registry.RegisterSchema("ControlEvidenceRequirement", objectSchema(map[string]any{ + "type": map[string]any{"type": "string"}, + "freshness_days": map[string]any{"type": "integer", "minimum": 0}, + "required": map[string]any{"type": "boolean"}, + }, "type", "required")) + registry.RegisterSchema("CreateSecurityControlRequest", objectSchema(map[string]any{ + "framework_id": map[string]any{"type": "string"}, + "code": map[string]any{"type": "string"}, + "title": map[string]any{"type": "string"}, + "objective": map[string]any{"type": "string"}, + "evidence_requirements": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/ControlEvidenceRequirement"}}, + "applicability": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + }, "framework_id", "code", "title", "objective")) + registry.RegisterSchema("SecurityControl", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "framework_id": map[string]any{"type": "string"}, + "code": map[string]any{"type": "string"}, + "title": map[string]any{"type": "string"}, + "objective": map[string]any{"type": "string"}, + "evidence_requirements": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/ControlEvidenceRequirement"}}, + "applicability": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "framework_id", "code", "title", "objective", "schema_version", "created_at")) + registry.RegisterSchema("SecurityControlEnvelope", dataEnvelopeSchema("#/components/schemas/SecurityControl")) + registry.RegisterSchema("LinkControlEvidenceRequest", objectSchema(map[string]any{ + "evidence_type": map[string]any{"type": "string"}, + "subject_type": map[string]any{"type": "string"}, + "subject_id": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "confidence": map[string]any{"type": "string", "enum": []string{"high", "medium", "low", "unsupported"}}, + "notes": map[string]any{"type": "string"}, + }, "evidence_type", "subject_type", "subject_id", "confidence")) + registry.RegisterSchema("ControlEvidence", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "control_id": map[string]any{"type": "string"}, + "evidence_type": map[string]any{"type": "string"}, + "subject_type": map[string]any{"type": "string"}, + "subject_id": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "confidence": map[string]any{"type": "string"}, + "notes": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "control_id", "evidence_type", "subject_type", "subject_id", "confidence", "schema_version", "created_at")) + registry.RegisterSchema("ControlEvidenceEnvelope", dataEnvelopeSchema("#/components/schemas/ControlEvidence")) + registry.RegisterSchema("ControlEvidenceListEnvelope", dataArrayEnvelopeSchema("#/components/schemas/ControlEvidence")) registry.RegisterSchema("CreateProductRequest", objectSchema(map[string]any{ "name": map[string]any{"type": "string"}, "slug": map[string]any{"type": "string"}, diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 4de0589..748af5b 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -43,6 +43,34 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { case "listCollectors": operation.Description = "Lists tenant-scoped collector metadata without API key hashes or one-time secrets." operation.Responses[http.StatusOK] = jsonResponse("Collector list envelope.", "#/components/schemas/CollectorListEnvelope") + case "createControlFramework": + operation.Description = "Creates a tenant-scoped versioned control framework." + operation.RequestBody = jsonRequest("Control framework creation request.", "#/components/schemas/CreateControlFrameworkRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created control framework envelope.", "#/components/schemas/ControlFrameworkEnvelope") + case "listControlFrameworks": + operation.Description = "Lists tenant-scoped control frameworks." + operation.Responses[http.StatusOK] = jsonResponse("Control framework list envelope.", "#/components/schemas/ControlFrameworkListEnvelope") + case "createSecurityControl": + operation.Description = "Creates a framework-owned security control with deterministic evidence requirements." + operation.RequestBody = jsonRequest("Security control creation request.", "#/components/schemas/CreateSecurityControlRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created security control envelope.", "#/components/schemas/SecurityControlEnvelope") + case "getSecurityControl": + operation.Description = "Returns a tenant-scoped security control by id." + operation.Parameters = append(operation.Parameters, pathParam("id", "Security control id.")) + operation.Responses[http.StatusOK] = jsonResponse("Security control envelope.", "#/components/schemas/SecurityControlEnvelope") + case "linkControlEvidence": + operation.Description = "Creates an append-only link between a security control and tenant-scoped evidence or related release resource." + operation.Parameters = append(operation.Parameters, pathParam("id", "Security control id.")) + operation.RequestBody = jsonRequest("Control evidence link request.", "#/components/schemas/LinkControlEvidenceRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created control evidence link envelope.", "#/components/schemas/ControlEvidenceEnvelope") + case "listControlEvidence": + operation.Description = "Lists tenant-scoped control evidence links with optional control, product, and release filters." + operation.Parameters = append(operation.Parameters, + queryParam("control_id", "Filter by security control id.", "string"), + queryParam("product_id", "Filter by product id.", "string"), + queryParam("release_id", "Filter by release id.", "string"), + ) + operation.Responses[http.StatusOK] = jsonResponse("Control evidence list envelope.", "#/components/schemas/ControlEvidenceListEnvelope") case "createProduct": operation.Description = "Creates a tenant-scoped product. Product slugs must be unique per tenant." operation.RequestBody = jsonRequest("Product creation request.", "#/components/schemas/CreateProductRequest") diff --git a/openapi.yaml b/openapi.yaml index 275dd1c..5d522a1 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"201":{"description":"Create artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"Get artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"Verify cosign-style artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"Verify audit chain response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"List tenant audit log response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"Verify build attestation signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"201":{"description":"Upload build attestation response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"operationId":"listControlEvidence","responses":{"200":{"description":"List control evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"operationId":"listControlFrameworks","responses":{"200":{"description":"List control frameworks response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"operationId":"createControlFramework","responses":{"201":{"description":"Create control framework response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"operationId":"createSecurityControl","responses":{"201":{"description":"Create security control response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"operationId":"getSecurityControl","responses":{"200":{"description":"Get security control response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"operationId":"linkControlEvidence","responses":{"201":{"description":"Link control evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"201":{"description":"Create custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"201":{"description":"Evaluate custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"List deployments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"201":{"description":"Record deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"Get deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"201":{"description":"Create DSSE trust root response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"List deployment environments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"201":{"description":"Create deployment environment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"List evidence lifecycle events response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"201":{"description":"Record evidence lifecycle event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"201":{"description":"Link evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"201":{"description":"Supersede evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"List exceptions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"201":{"description":"Create exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"Approve exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"Health response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"Safe tenant metrics response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"201":{"description":"Upload OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"Get OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"201":{"description":"Create OpenAPI contract diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OpenAPI response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"201":{"description":"Create organization response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"201":{"description":"Evaluate release policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"Get release bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"Get release bundle manifest response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"List release candidates response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"201":{"description":"Create release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"Get release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"Promote release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"Reject release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"Missing evidence report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"List role bindings response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"201":{"description":"Create role binding response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"List signing keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"201":{"description":"Rotate signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"Revoke signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"201":{"description":"Create signing provider operation receipt response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"201":{"description":"Create signing provider record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"201":{"description":"Record source branch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"201":{"description":"Record source commit response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"201":{"description":"Record pull request response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"List source repositories response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"201":{"description":"Create source repository response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"201":{"description":"Link SSO identity response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"Revoke SSO session response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"201":{"description":"Create user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"Deactivate user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"Version response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"201":{"description":"Create vulnerability decision response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"201":{"description":"Record vulnerability workflow event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"201":{"description":"Create waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"Approve waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"201":{"description":"Create artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"Get artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"Verify cosign-style artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"Verify audit chain response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"List tenant audit log response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"Verify build attestation signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"201":{"description":"Upload build attestation response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"201":{"description":"Create custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"201":{"description":"Evaluate custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"List deployments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"201":{"description":"Record deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"Get deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"201":{"description":"Create DSSE trust root response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"List deployment environments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"201":{"description":"Create deployment environment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"List evidence lifecycle events response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"201":{"description":"Record evidence lifecycle event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"201":{"description":"Link evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"201":{"description":"Supersede evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"List exceptions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"201":{"description":"Create exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"Approve exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"Health response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"Safe tenant metrics response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"201":{"description":"Upload OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"Get OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"201":{"description":"Create OpenAPI contract diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OpenAPI response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"201":{"description":"Create organization response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"201":{"description":"Evaluate release policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"Get release bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"Get release bundle manifest response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"List release candidates response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"201":{"description":"Create release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"Get release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"Promote release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"Reject release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"Missing evidence report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"List role bindings response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"201":{"description":"Create role binding response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"List signing keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"201":{"description":"Rotate signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"Revoke signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"201":{"description":"Create signing provider operation receipt response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"201":{"description":"Create signing provider record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"201":{"description":"Record source branch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"201":{"description":"Record source commit response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"201":{"description":"Record pull request response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"List source repositories response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"201":{"description":"Create source repository response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"201":{"description":"Link SSO identity response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"Revoke SSO session response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"201":{"description":"Create user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"Deactivate user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"Version response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"201":{"description":"Create vulnerability decision response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"201":{"description":"Record vulnerability workflow event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"201":{"description":"Create waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"Approve waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From c38015c8b43c72427b956af7a132a9818ab606ed Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 18:56:00 +0300 Subject: [PATCH 064/287] docs: clarify remaining production backlog --- docs/reference/production-readiness.md | 46 +++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 7434b81..1d332d1 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -19,10 +19,14 @@ Known hardening work remains: - worker parser jobs re-read raw object-store payloads for key formats and validate durable state, but parser side effects still need to move independently out of the request path; -- OpenAPI schemas need endpoint-specific precision across the full public API; -- GitHub CI enforces live PostgreSQL release checks and the default 80 percent - production coverage threshold, but the broader production exit review remains - incomplete. +- OpenAPI schemas need endpoint-specific precision across the full public API. + The current generated matrix is the source of truth for precise versus broad + operations; +- production KMS/HSM execution, full browser OIDC/SAML login flows, provider + discovery/group sync, object-lock enforcement proof, and transparency + inclusion proof verification remain provider- and deployment-dependent + hardening areas; +- the broader production exit review remains incomplete. ## Production Profiles @@ -46,6 +50,8 @@ The gate requires: - `EVYDENCE_TEST_DATABASE_URL` set to a disposable PostgreSQL database; - `make release-check` passing without skipped live PostgreSQL checks; - `make coverage-check` passing at the configured threshold; +- migration compatibility from every committed migration prefix to the current + schema passing in temporary PostgreSQL schemas; - release artifact signing smoke test passing with local temporary keys; - generated release evidence summary available under `tmp/`. @@ -67,12 +73,42 @@ Do not describe an Evydence build as broadly self-hosted production-ready until: - `make production-check` passes in CI with live PostgreSQL; - coverage is at or above the configured threshold; - release artifacts have signed manifests and published checksums; +- committed migrations have passed compatibility checks from every migration + prefix to the current schema; - the built-in local restore rehearsal passes and backup/restore have been tested for the target deployment profile; -- OpenAPI and SDK drift checks pass; +- OpenAPI and SDK drift checks pass, and route-contract gaps are accepted in + release notes or closed with endpoint-specific schemas; - production hardening review is current; - unresolved limitations are documented in release notes. +## Remaining Production Maturity Backlog + +These items are tracked separately from the feature-completeness checklist in +`.implementation_increments.md` because they are hardening work on already +implemented capabilities: + +- Replace canonical snapshot writes with dependency-ordered relational + repositories for identity, idempotency, evidence, audit-chain entries, + bundles, reports, packages, and secondary resources. Keep snapshots only for + export/import and upgrade compatibility. +- Split the large application ledger aggregate into focused services or + repositories once relational writes are in place, preserving tenant isolation + and append-only behavior throughout. +- Move parser-owned side effects for SBOM, vulnerability scan, OpenAPI, VEX, + and attestation payloads fully into worker processors while keeping upload + responses backward compatible. +- Continue reducing broad OpenAPI operations until production-critical and + customer/package-facing routes have endpoint-specific schemas. +- Add production signing-provider execution for a configured external provider + profile without storing private key material in Evydence. +- Complete live OIDC/SAML browser login callbacks, provider discovery, JWKS + refresh, logout, and optional group mapping where those profiles are enabled. +- Add provider-backed object-lock/WORM verification and optional transparency + inclusion proof verification for deployments that require those controls. +- Run final product, codebase, security, documentation, and test audits before + changing release status beyond controlled self-hosted production candidate. + Operators remain responsible for secret management, TLS, network policy, database and object-store durability, backups, restore rehearsals, monitoring, provider configuration, incident response, and external review. From 1d1eca62a515529eeaf963c44b755fa7eb687ebe Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 18:57:21 +0300 Subject: [PATCH 065/287] test: gate openapi contract precision --- Makefile | 7 +++- docs/reference/openapi.md | 11 +++++ scripts/openapi_precision_check.py | 67 ++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100755 scripts/openapi_precision_check.py diff --git a/Makefile b/Makefile index 55f8666..9d4ca08 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ GOLANGCI_LINT_VERSION ?= v2.11.4 GOSEC_VERSION ?= v2.25.0 GOVULNCHECK_VERSION ?= v1.2.0 -.PHONY: help tools fmt lint vuln gosec test test-race coverage coverage-check openapi-check meta-check docs-check deploy-check sdk-check fast-check finalize release-acceptance release-check production-check migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean +.PHONY: help tools fmt lint vuln gosec test test-race coverage coverage-check openapi-check openapi-precision-check meta-check docs-check deploy-check sdk-check fast-check finalize release-acceptance release-check production-check migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean help: ## Show help @awk 'BEGIN {FS=":.*## "}; /^[a-zA-Z0-9_.-]+:.*## / { printf " %-18s %s\n", $$1, $$2 }' $(MAKEFILE_LIST) @@ -50,6 +50,9 @@ openapi-check: openapi.yaml ## Validate OpenAPI generation and route contract te @$(GO) run ./cmd/openapi > /tmp/evydence-openapi.yaml @cmp -s openapi.yaml /tmp/evydence-openapi.yaml +openapi-precision-check: ## Enforce current OpenAPI precision floor and broad-route ceiling + @python3 scripts/openapi_precision_check.py + meta-check: ## Validate root legal, governance, support, and release-evidence metadata @test -f LICENSE @test -f COMMERCIAL.md @@ -173,6 +176,7 @@ sdk-check: ## Validate curated SDK helper coverage against OpenAPI fast-check: ## Run non-mutating fast validation @$(MAKE) test @$(MAKE) openapi-check + @$(MAKE) openapi-precision-check @$(MAKE) docs-check @$(MAKE) deploy-check @$(MAKE) sdk-check @@ -181,6 +185,7 @@ finalize: ## Thorough validity check @$(MAKE) fmt @$(MAKE) test @$(MAKE) openapi-check + @$(MAKE) openapi-precision-check @$(MAKE) docs-check @$(MAKE) deploy-check @$(MAKE) sdk-check diff --git a/docs/reference/openapi.md b/docs/reference/openapi.md index 84bb128..e7924ee 100644 --- a/docs/reference/openapi.md +++ b/docs/reference/openapi.md @@ -18,6 +18,17 @@ make openapi-check `make openapi-check` regenerates the contract, compares it with the committed file, and runs route contract tests for the HTTP adapter. +Check precision regression: + +```sh +make openapi-precision-check +``` + +`make openapi-precision-check` enforces the current floor for endpoint-specific +contracts and the current ceiling for broad contracts. Raise +`EVYDENCE_OPENAPI_MIN_PRECISE` and lower `EVYDENCE_OPENAPI_MAX_BROAD` as more +routes receive concrete request and response schemas. + `make docs-check` compares the paths in `openapi.yaml` with the endpoint catalog in [API reference](../api.md). Add every generated path to that catalog, or the docs check fails. ## Review The Contract diff --git a/scripts/openapi_precision_check.py b/scripts/openapi_precision_check.py new file mode 100755 index 0000000..32abe52 --- /dev/null +++ b/scripts/openapi_precision_check.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 +"""Fail when committed OpenAPI contract precision regresses.""" + +from __future__ import annotations + +import json +import os +import pathlib +import sys + +import openapi_contract_matrix + + +ROOT = pathlib.Path(__file__).resolve().parents[1] + + +def int_env(name: str, fallback: int) -> int: + value = os.environ.get(name, "").strip() + if not value: + return fallback + try: + parsed = int(value) + except ValueError: + print(f"openapi-precision-check: {name} must be an integer", file=sys.stderr) + raise SystemExit(2) + if parsed < 0: + print(f"openapi-precision-check: {name} must be non-negative", file=sys.stderr) + raise SystemExit(2) + return parsed + + +def main() -> int: + spec = json.loads((ROOT / "openapi.yaml").read_text(encoding="utf-8")) + precise = 0 + broad = 0 + for path_item in spec["paths"].values(): + for method, operation in path_item.items(): + if method.lower() not in {"get", "post", "put", "patch", "delete"}: + continue + if openapi_contract_matrix.precision_label(operation) == "precise": + precise += 1 + else: + broad += 1 + + min_precise = int_env("EVYDENCE_OPENAPI_MIN_PRECISE", 48) + max_broad = int_env("EVYDENCE_OPENAPI_MAX_BROAD", 112) + if precise < min_precise: + print( + f"openapi-precision-check: precise operations {precise} below required {min_precise}", + file=sys.stderr, + ) + return 1 + if broad > max_broad: + print( + f"openapi-precision-check: broad operations {broad} above allowed {max_broad}", + file=sys.stderr, + ) + return 1 + print( + f"openapi-precision-check: {precise} precise operations, {broad} broad operations " + f"(minimum precise {min_precise}, maximum broad {max_broad})" + ) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) From 5f0cba458e71cf7ac129cbac741817560b9a3198 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 18:57:45 +0300 Subject: [PATCH 066/287] docs: tighten system openapi contracts --- docs/reference/api-contract-matrix.md | 14 +++--- internal/adapters/httpapi/openapi.go | 49 ++++++++++++++++++- .../adapters/httpapi/openapi_operations.go | 37 ++++++++++++++ openapi.yaml | 2 +- scripts/openapi_precision_check.py | 4 +- 5 files changed, 95 insertions(+), 11 deletions(-) diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index 9e6f05c..22071a6 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 160 operations: 48 precise, 112 broad. +Generated from 160 operations: 54 precise, 106 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -16,8 +16,8 @@ Generated from 160 operations: 48 precise, 112 broad. | GET | /v1/artifact-signatures/{id} | getArtifactSignature | Bearer | evidence:read | - | - | - | 200:unspecified | broad | | POST | /v1/artifact-signatures/{id}/verify-cosign | verifyCosignSignature | Bearer | verify:read | required | - | - | 200:unspecified | broad | | POST | /v1/artifacts | registerArtifact | Bearer | evidence:write | required | - | application/json:RegisterArtifactRequest | 201:application/json:ArtifactEnvelope | precise | -| GET | /v1/audit-chain/verify | verifyAuditChain | Bearer | verify:read | - | - | - | 200:unspecified | broad | -| GET | /v1/audit-log | listAuditLog | Bearer | admin | - | - | - | 200:unspecified | broad | +| GET | /v1/audit-chain/verify | verifyAuditChain | Bearer | verify:read | - | - | - | 200:application/json:VerificationResultEnvelope | precise | +| GET | /v1/audit-log | listAuditLog | Bearer | admin | - | query:limit, query:since, query:subject_id, query:subject_type | - | 200:application/json:AuditChainEntryListEnvelope | precise | | POST | /v1/backup-manifests | generateBackupManifest | Bearer | admin | required | - | application/json:EmptyObject | 201:application/json:BackupManifestEnvelope | precise | | GET | /v1/backup-manifests/{id}/verify | verifyBackupManifest | Bearer | verify:read | - | path:id | - | 200:application/json:VerificationResultEnvelope | precise | | POST | /v1/build-attestations/{id}/verify-signature | verifyBuildAttestationSignature | Bearer | verify:read | required | - | - | 200:unspecified | broad | @@ -70,7 +70,7 @@ Generated from 160 operations: 48 precise, 112 broad. | GET | /v1/exceptions | listExceptions | Bearer | verify:read | - | - | - | 200:unspecified | broad | | POST | /v1/exceptions | createException | Bearer | release:write | required | - | - | 201:unspecified | broad | | POST | /v1/exceptions/{id}/approve | approveException | Bearer | release:write | required | - | - | 200:unspecified | broad | -| GET | /v1/health | health | public | - | - | - | - | 200:unspecified | broad | +| GET | /v1/health | health | public | - | - | - | - | 200:application/json:HealthStatusEnvelope | precise | | POST | /v1/incident-webhooks/{receiver_id} | receiveIncidentWebhook | public | - | not required | header:X-Evydence-Webhook-Event-ID, header:X-Evydence-Webhook-Signature, header:X-Evydence-Webhook-Timestamp, path:receiver_id | application/json:DataEnvelope | 201:application/json:DataEnvelope | broad | | POST | /v1/incidents | createIncident | Bearer | incident:write | required | - | - | 201:unspecified | broad | | POST | /v1/incidents/{id}/timeline | recordIncidentTimeline | Bearer | incident:write | required | - | - | 201:unspecified | broad | @@ -81,13 +81,13 @@ Generated from 160 operations: 48 precise, 112 broad. | GET | /v1/marketplace-collectors/{id}/health | marketplaceCollectorHealth | Bearer | collector:read | - | - | - | 200:unspecified | broad | | POST | /v1/merkle-batches | createMerkleBatch | Bearer | keys:admin | required | - | - | 201:unspecified | broad | | GET | /v1/merkle-batches/{id}/verify | verifyMerkleBatch | Bearer | verify:read | - | - | - | 200:unspecified | broad | -| GET | /v1/metrics | metrics | Bearer | admin | - | - | - | 200:unspecified | broad | +| GET | /v1/metrics | metrics | Bearer | admin | - | - | - | 200:application/json:MetricsSnapshotEnvelope,text/plain:string | precise | | POST | /v1/object-retention-policies | createObjectRetentionPolicy | Bearer | admin | required | - | - | 201:unspecified | broad | | POST | /v1/object-retention-policies/{id}/verify | verifyObjectRetentionPolicy | Bearer | verify:read | required | - | - | 200:unspecified | broad | | POST | /v1/openapi-contracts | uploadOpenAPIContract | Bearer | evidence:write | required | - | - | 201:unspecified | broad | | GET | /v1/openapi-contracts/{id} | getOpenAPIContract | Bearer | evidence:read | - | - | - | 200:unspecified | broad | | POST | /v1/openapi-diffs | createOpenAPIDiff | Bearer | evidence:read | required | - | - | 201:unspecified | broad | -| GET | /v1/openapi.json | openapi | public | - | - | - | - | 200:unspecified | broad | +| GET | /v1/openapi.json | openapi | public | - | - | - | - | 200:application/json:OpenAPIDocument | precise | | POST | /v1/organizations | createOrganization | Bearer | identity:admin | required | - | - | 201:unspecified | broad | | POST | /v1/policies/evaluate | evaluatePolicy | Bearer | verify:read | required | - | - | 201:unspecified | broad | | GET | /v1/products | listProducts | Bearer | product:read | - | - | - | 200:application/json:ProductListEnvelope | precise | @@ -157,7 +157,7 @@ Generated from 160 operations: 48 precise, 112 broad. | POST | /v1/users | createUser | Bearer | identity:admin | required | - | - | 201:unspecified | broad | | POST | /v1/users/{id}/deactivate | deactivateUser | Bearer | identity:admin | required | - | - | 200:unspecified | broad | | POST | /v1/verify | verify | Bearer | verify:read | required | - | - | 200:unspecified | broad | -| GET | /v1/version | version | public | - | - | - | - | 200:unspecified | broad | +| GET | /v1/version | version | public | - | - | - | - | 200:application/json:VersionInfoEnvelope | precise | | POST | /v1/vex | uploadVEX | Bearer | evidence:write | required | - | application/json:EvidenceUploadRequest | 201:application/json:VEXDocumentEnvelope | precise | | POST | /v1/vex/cyclonedx | uploadCycloneDXVEX | Bearer | evidence:write | required | - | application/json:EvidenceUploadRequest | 201:application/json:VEXDocumentEnvelope | precise | | GET | /v1/vex/{id} | getVEX | Bearer | evidence:read | - | path:id | - | 200:application/json:VEXDocumentEnvelope | precise | diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 692b464..692c3e4 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -36,6 +36,32 @@ func registerCriticalSchemas(registry *specs.Registry) { }, "api_version"), }, "data", "meta")) registry.RegisterSchema("EmptyObject", objectSchema(map[string]any{})) + registry.RegisterSchema("HealthStatus", objectSchema(map[string]any{ + "status": map[string]any{"type": "string", "enum": []string{"ok"}}, + }, "status")) + registry.RegisterSchema("HealthStatusEnvelope", dataEnvelopeSchema("#/components/schemas/HealthStatus")) + registry.RegisterSchema("VersionInfo", objectSchema(map[string]any{ + "version": map[string]any{"type": "string"}, + }, "version")) + registry.RegisterSchema("VersionInfoEnvelope", dataEnvelopeSchema("#/components/schemas/VersionInfo")) + registry.RegisterSchema("MetricsSnapshot", objectSchema(map[string]any{ + "tenant_id": map[string]any{"type": "string"}, + "resource_counts": map[string]any{"type": "object", "additionalProperties": map[string]any{"type": "integer"}}, + "customer_portal_failed_access_count": map[string]any{"type": "integer"}, + "customer_portal_revoked_access_count": map[string]any{"type": "integer"}, + }, "tenant_id", "resource_counts", "customer_portal_failed_access_count", "customer_portal_revoked_access_count")) + registry.RegisterSchema("MetricsSnapshotEnvelope", dataEnvelopeSchema("#/components/schemas/MetricsSnapshot")) + registry.RegisterSchema("OpenAPIDocument", map[string]any{ + "type": "object", + "additionalProperties": true, + "properties": map[string]any{ + "openapi": map[string]any{"type": "string"}, + "info": map[string]any{"type": "object", "additionalProperties": true}, + "paths": map[string]any{"type": "object", "additionalProperties": true}, + "components": map[string]any{"type": "object", "additionalProperties": true}, + }, + "required": []string{"openapi", "info", "paths"}, + }) registry.RegisterSchema("InstanceAdminSnapshot", objectSchema(map[string]any{ "report_type": map[string]any{"type": "string"}, "tenant_count": map[string]any{"type": "integer"}, @@ -68,9 +94,30 @@ func registerCriticalSchemas(registry *specs.Registry) { }, "provider_type", "provider_id", "subject")) registry.RegisterSchema("VerifyCheck", objectSchema(map[string]any{ "name": map[string]any{"type": "string"}, - "result": map[string]any{"type": "string", "enum": []string{"passed", "failed", "warning"}}, + "result": map[string]any{"type": "string", "enum": []string{"passed", "failed", "warning", "skipped"}}, "detail": map[string]any{"type": "string"}, }, "name", "result")) + registry.RegisterSchema("AuditChainEntry", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "sequence": map[string]any{"type": "integer", "format": "int64"}, + "entry_type": map[string]any{"type": "string"}, + "subject_type": map[string]any{"type": "string"}, + "subject_id": map[string]any{"type": "string"}, + "actor_type": map[string]any{"type": "string"}, + "actor_id": map[string]any{"type": "string"}, + "occurred_at": map[string]any{"type": "string", "format": "date-time"}, + "request_id": map[string]any{"type": "string"}, + "idempotency_key": map[string]any{"type": "string"}, + "payload_hash": map[string]any{"type": "string"}, + "canonical_entry_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "previous_entry_hash": map[string]any{"type": "string"}, + "entry_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "signature_ref": map[string]any{"type": "string"}, + "metadata": map[string]any{"type": "object", "additionalProperties": true}, + "schema_version": map[string]any{"type": "string"}, + }, "id", "tenant_id", "sequence", "entry_type", "subject_type", "subject_id", "actor_type", "actor_id", "occurred_at", "canonical_entry_hash", "previous_entry_hash", "entry_hash", "schema_version")) + registry.RegisterSchema("AuditChainEntryListEnvelope", dataArrayEnvelopeSchema("#/components/schemas/AuditChainEntry")) registry.RegisterSchema("ReadinessStatus", objectSchema(map[string]any{ "status": map[string]any{"type": "string"}, "checks": map[string]any{"type": "array", "items": objectSchema(map[string]any{ diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 748af5b..fc93827 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -9,11 +9,36 @@ import ( func withCriticalOperationDetails(operation specs.Operation) specs.Operation { addProblemResponses(&operation) switch operation.OperationID { + case "health": + operation.Description = "Returns low-detail liveness status without touching tenant evidence or secret material." + operation.Security = nil + operation.Scopes = nil + operation.Responses[http.StatusOK] = jsonResponse("Liveness status envelope.", "#/components/schemas/HealthStatusEnvelope") case "ready": operation.Description = "Returns low-detail process readiness without tenant evidence or secret material." operation.Security = nil operation.Scopes = nil operation.Responses[http.StatusOK] = jsonResponse("Readiness status envelope.", "#/components/schemas/ReadinessStatusEnvelope") + case "version": + operation.Description = "Returns the API process version string." + operation.Security = nil + operation.Scopes = nil + operation.Responses[http.StatusOK] = jsonResponse("Version information envelope.", "#/components/schemas/VersionInfoEnvelope") + case "metrics": + operation.Description = "Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain." + operation.Responses[http.StatusOK] = specs.Response{ + Description: "Tenant metrics envelope or Prometheus text metrics.", + ContentTypes: []string{"application/json", "text/plain"}, + Content: map[string]specs.MediaType{ + "application/json": {SchemaRef: "#/components/schemas/MetricsSnapshotEnvelope"}, + "text/plain": {Schema: map[string]any{"type": "string"}}, + }, + } + case "openapi": + operation.Description = "Returns the generated OpenAPI 3.1 document served by this process." + operation.Security = nil + operation.Scopes = nil + operation.Responses[http.StatusOK] = jsonResponse("OpenAPI document.", "#/components/schemas/OpenAPIDocument") case "instanceAdminSnapshot": operation.Description = "Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient." operation.Responses[http.StatusOK] = jsonResponse("Instance admin snapshot envelope.", "#/components/schemas/InstanceAdminSnapshotEnvelope") @@ -213,6 +238,18 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Description = "Verifies a tenant-scoped release bundle and returns a deterministic verification result." operation.Parameters = append(operation.Parameters, pathParam("id", "Release bundle id.")) operation.Responses[http.StatusOK] = jsonResponse("Release bundle verification envelope.", "#/components/schemas/ReleaseBundleVerificationEnvelope") + case "verifyAuditChain": + operation.Description = "Verifies the tenant audit chain continuity and returns deterministic verification checks." + operation.Responses[http.StatusOK] = jsonResponse("Audit chain verification envelope.", "#/components/schemas/VerificationResultEnvelope") + case "listAuditLog": + operation.Description = "Lists tenant-scoped append-only audit-chain entries in reverse chronological order." + operation.Parameters = append(operation.Parameters, + queryParam("subject_type", "Filter by audited subject type.", "string"), + queryParam("subject_id", "Filter by audited subject id.", "string"), + queryParam("since", "Only include entries at or after this RFC3339 timestamp.", "string"), + queryParam("limit", "Maximum returned entries; defaults to 100 and caps at 500.", "integer"), + ) + operation.Responses[http.StatusOK] = jsonResponse("Audit-chain entry list envelope.", "#/components/schemas/AuditChainEntryListEnvelope") case "generateBackupManifest": operation.Description = "Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material." operation.RequestBody = jsonRequest("Empty JSON object.", "#/components/schemas/EmptyObject") diff --git a/openapi.yaml b/openapi.yaml index 5d522a1..ddab413 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"201":{"description":"Create artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"Get artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"Verify cosign-style artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"operationId":"verifyAuditChain","responses":{"200":{"description":"Verify audit chain response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"operationId":"listAuditLog","responses":{"200":{"description":"List tenant audit log response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"Verify build attestation signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"201":{"description":"Upload build attestation response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"201":{"description":"Create custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"201":{"description":"Evaluate custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"List deployments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"201":{"description":"Record deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"Get deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"201":{"description":"Create DSSE trust root response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"List deployment environments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"201":{"description":"Create deployment environment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"List evidence lifecycle events response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"201":{"description":"Record evidence lifecycle event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"201":{"description":"Link evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"201":{"description":"Supersede evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"List exceptions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"201":{"description":"Create exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"Approve exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"operationId":"health","responses":{"200":{"description":"Health response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"operationId":"metrics","responses":{"200":{"description":"Safe tenant metrics response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"201":{"description":"Upload OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"Get OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"201":{"description":"Create OpenAPI contract diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"OpenAPI response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"201":{"description":"Create organization response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"201":{"description":"Evaluate release policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"Get release bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"Get release bundle manifest response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"List release candidates response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"201":{"description":"Create release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"Get release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"Promote release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"Reject release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"Missing evidence report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"List role bindings response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"201":{"description":"Create role binding response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"List signing keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"201":{"description":"Rotate signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"Revoke signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"201":{"description":"Create signing provider operation receipt response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"201":{"description":"Create signing provider record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"201":{"description":"Record source branch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"201":{"description":"Record source commit response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"201":{"description":"Record pull request response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"List source repositories response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"201":{"description":"Create source repository response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"201":{"description":"Link SSO identity response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"Revoke SSO session response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"201":{"description":"Create user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"Deactivate user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"operationId":"version","responses":{"200":{"description":"Version response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"201":{"description":"Create vulnerability decision response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"201":{"description":"Record vulnerability workflow event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"201":{"description":"Create waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"Approve waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"201":{"description":"Create artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"Get artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"Verify cosign-style artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"Verify build attestation signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"201":{"description":"Upload build attestation response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"201":{"description":"Create custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"201":{"description":"Evaluate custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"List deployments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"201":{"description":"Record deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"Get deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"201":{"description":"Create DSSE trust root response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"List deployment environments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"201":{"description":"Create deployment environment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"List evidence lifecycle events response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"201":{"description":"Record evidence lifecycle event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"201":{"description":"Link evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"201":{"description":"Supersede evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"List exceptions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"201":{"description":"Create exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"Approve exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"201":{"description":"Upload OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"Get OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"201":{"description":"Create OpenAPI contract diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"201":{"description":"Create organization response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"201":{"description":"Evaluate release policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"Get release bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"Get release bundle manifest response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"List release candidates response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"201":{"description":"Create release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"Get release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"Promote release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"Reject release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"Missing evidence report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"List role bindings response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"201":{"description":"Create role binding response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"List signing keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"201":{"description":"Rotate signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"Revoke signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"201":{"description":"Create signing provider operation receipt response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"201":{"description":"Create signing provider record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"201":{"description":"Record source branch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"201":{"description":"Record source commit response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"201":{"description":"Record pull request response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"List source repositories response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"201":{"description":"Create source repository response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"201":{"description":"Link SSO identity response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"Revoke SSO session response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"201":{"description":"Create user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"Deactivate user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"201":{"description":"Create vulnerability decision response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"201":{"description":"Record vulnerability workflow event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"201":{"description":"Create waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"Approve waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/scripts/openapi_precision_check.py b/scripts/openapi_precision_check.py index 32abe52..2461f9d 100755 --- a/scripts/openapi_precision_check.py +++ b/scripts/openapi_precision_check.py @@ -42,8 +42,8 @@ def main() -> int: else: broad += 1 - min_precise = int_env("EVYDENCE_OPENAPI_MIN_PRECISE", 48) - max_broad = int_env("EVYDENCE_OPENAPI_MAX_BROAD", 112) + min_precise = int_env("EVYDENCE_OPENAPI_MIN_PRECISE", 54) + max_broad = int_env("EVYDENCE_OPENAPI_MAX_BROAD", 106) if precise < min_precise: print( f"openapi-precision-check: precise operations {precise} below required {min_precise}", From f0eeb33786c8756c47d6aae48317084f39d845e7 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 18:57:49 +0300 Subject: [PATCH 067/287] docs: tighten identity openapi contracts --- docs/reference/api-contract-matrix.md | 16 ++-- internal/adapters/httpapi/openapi.go | 84 ++++++++++++++++++- .../adapters/httpapi/openapi_operations.go | 29 +++++++ openapi.yaml | 2 +- scripts/openapi_precision_check.py | 4 +- 5 files changed, 123 insertions(+), 12 deletions(-) diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index 22071a6..7172df7 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 160 operations: 54 precise, 106 broad. +Generated from 160 operations: 61 precise, 99 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -88,7 +88,7 @@ Generated from 160 operations: 54 precise, 106 broad. | GET | /v1/openapi-contracts/{id} | getOpenAPIContract | Bearer | evidence:read | - | - | - | 200:unspecified | broad | | POST | /v1/openapi-diffs | createOpenAPIDiff | Bearer | evidence:read | required | - | - | 201:unspecified | broad | | GET | /v1/openapi.json | openapi | public | - | - | - | - | 200:application/json:OpenAPIDocument | precise | -| POST | /v1/organizations | createOrganization | Bearer | identity:admin | required | - | - | 201:unspecified | broad | +| POST | /v1/organizations | createOrganization | Bearer | identity:admin | required | - | application/json:CreateOrganizationRequest | 201:application/json:OrganizationEnvelope | precise | | POST | /v1/policies/evaluate | evaluatePolicy | Bearer | verify:read | required | - | - | 201:unspecified | broad | | GET | /v1/products | listProducts | Bearer | product:read | - | - | - | 200:application/json:ProductListEnvelope | precise | | POST | /v1/products | createProduct | Bearer | product:write | required | - | application/json:CreateProductRequest | 201:application/json:ProductEnvelope | precise | @@ -129,8 +129,8 @@ Generated from 160 operations: 54 precise, 106 broad. | GET | /v1/reports/security-review-package | securityReviewPackageReport | Bearer | package:read | - | - | - | 200:unspecified | broad | | GET | /v1/reports/vulnerability-posture | vulnerabilityPostureReport | Bearer | security:read | - | - | - | 200:unspecified | broad | | POST | /v1/retention-overrides | createRetentionOverride | Bearer | admin | required | - | - | 201:unspecified | broad | -| GET | /v1/role-bindings | listRoleBindings | Bearer | identity:admin | - | - | - | 200:unspecified | broad | -| POST | /v1/role-bindings | createRoleBinding | Bearer | identity:admin | required | - | - | 201:unspecified | broad | +| GET | /v1/role-bindings | listRoleBindings | Bearer | identity:admin | - | - | - | 200:application/json:RoleBindingListEnvelope | precise | +| POST | /v1/role-bindings | createRoleBinding | Bearer | identity:admin | required | - | application/json:CreateRoleBindingRequest | 201:application/json:RoleBindingEnvelope | precise | | POST | /v1/saas/profiles | createSaaSEditionProfile | Bearer | instance:admin | required | - | - | 201:unspecified | broad | | GET | /v1/sbom-components | listSBOMComponents | Bearer | evidence:read | - | query:artifact_id, query:limit, query:purl, query:query, query:release_id, query:sbom_id | - | 200:application/json:DataEnvelope | broad | | POST | /v1/sbom-diffs | createSBOMDiff | Bearer | evidence:read | required | - | - | 201:unspecified | broad | @@ -149,13 +149,13 @@ Generated from 160 operations: 54 precise, 106 broad. | POST | /v1/source/pull-requests | recordPullRequest | Bearer | source:write | required | - | - | 201:unspecified | broad | | GET | /v1/source/repositories | listSourceRepositories | Bearer | source:read | - | - | - | 200:unspecified | broad | | POST | /v1/source/repositories | createSourceRepository | Bearer | source:write | required | - | - | 201:unspecified | broad | -| POST | /v1/sso/identity-links | linkSSOIdentity | Bearer | identity:admin | required | - | - | 201:unspecified | broad | +| POST | /v1/sso/identity-links | linkSSOIdentity | Bearer | identity:admin | required | - | application/json:LinkSSOIdentityRequest | 201:application/json:UserIdentityLinkEnvelope | precise | | POST | /v1/sso/providers | createSSOProvider | Bearer | identity:admin | required | - | application/json:CreateSSOProviderRequest | 201:application/json:SSOProviderEnvelope | precise | | POST | /v1/sso/sessions | createSSOSession | Bearer | identity:admin | required | - | application/json:CreateSSOSessionRequest | 201:application/json:SSOSessionCreateEnvelope | precise | -| POST | /v1/sso/sessions/{id}/revoke | revokeSSOSession | Bearer | identity:admin | required | - | - | 200:unspecified | broad | +| POST | /v1/sso/sessions/{id}/revoke | revokeSSOSession | Bearer | identity:admin | required | path:id | application/json:EmptyObject | 200:application/json:SSOSessionEnvelope | precise | | POST | /v1/transparency-checkpoints | createTransparencyCheckpoint | Bearer | keys:admin | required | - | - | 201:unspecified | broad | -| POST | /v1/users | createUser | Bearer | identity:admin | required | - | - | 201:unspecified | broad | -| POST | /v1/users/{id}/deactivate | deactivateUser | Bearer | identity:admin | required | - | - | 200:unspecified | broad | +| POST | /v1/users | createUser | Bearer | identity:admin | required | - | application/json:CreateUserRequest | 201:application/json:HumanUserEnvelope | precise | +| POST | /v1/users/{id}/deactivate | deactivateUser | Bearer | identity:admin | required | path:id | application/json:EmptyObject | 200:application/json:HumanUserEnvelope | precise | | POST | /v1/verify | verify | Bearer | verify:read | required | - | - | 200:unspecified | broad | | GET | /v1/version | version | public | - | - | - | - | 200:application/json:VersionInfoEnvelope | precise | | POST | /v1/vex | uploadVEX | Bearer | evidence:write | required | - | application/json:EvidenceUploadRequest | 201:application/json:VEXDocumentEnvelope | precise | diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 692c3e4..e549452 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -189,8 +189,90 @@ func registerCriticalSchemas(registry *specs.Registry) { "created_at": map[string]any{"type": "string", "format": "date-time"}, }, "id", "tenant_id", "provider_type", "provider_id", "subject", "result", "checks", "limitations", "schema_version", "created_at")) registry.RegisterSchema("ProviderVerificationEnvelope", dataEnvelopeSchema("#/components/schemas/ProviderVerification")) + registry.RegisterSchema("CreateOrganizationRequest", objectSchema(map[string]any{ + "name": map[string]any{"type": "string"}, + "slug": map[string]any{"type": "string"}, + }, "name", "slug")) + registry.RegisterSchema("Organization", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "slug": map[string]any{"type": "string"}, + "status": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "name", "slug", "status", "schema_version", "created_at")) + registry.RegisterSchema("OrganizationEnvelope", dataEnvelopeSchema("#/components/schemas/Organization")) + registry.RegisterSchema("CreateUserRequest", objectSchema(map[string]any{ + "organization_id": map[string]any{"type": "string"}, + "email": map[string]any{"type": "string", "format": "email"}, + "display_name": map[string]any{"type": "string"}, + }, "email", "display_name")) + registry.RegisterSchema("HumanUser", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "organization_id": map[string]any{"type": "string"}, + "email": map[string]any{"type": "string", "format": "email"}, + "display_name": map[string]any{"type": "string"}, + "status": map[string]any{"type": "string"}, + "deactivated_at": map[string]any{"type": "string", "format": "date-time"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "email", "display_name", "status", "schema_version", "created_at")) + registry.RegisterSchema("HumanUserEnvelope", dataEnvelopeSchema("#/components/schemas/HumanUser")) + registry.RegisterSchema("CreateRoleBindingRequest", objectSchema(map[string]any{ + "subject_type": map[string]any{"type": "string", "enum": []string{"user", "collector"}}, + "subject_id": map[string]any{"type": "string"}, + "role": map[string]any{"type": "string"}, + "resource_type": map[string]any{"type": "string"}, + "resource_id": map[string]any{"type": "string"}, + }, "subject_type", "subject_id", "role")) + registry.RegisterSchema("RoleBinding", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "subject_type": map[string]any{"type": "string"}, + "subject_id": map[string]any{"type": "string"}, + "role": map[string]any{"type": "string"}, + "resource_type": map[string]any{"type": "string"}, + "resource_id": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "subject_type", "subject_id", "role", "schema_version", "created_at")) + registry.RegisterSchema("RoleBindingEnvelope", dataEnvelopeSchema("#/components/schemas/RoleBinding")) + registry.RegisterSchema("RoleBindingListEnvelope", dataArrayEnvelopeSchema("#/components/schemas/RoleBinding")) + registry.RegisterSchema("LinkSSOIdentityRequest", objectSchema(map[string]any{ + "user_id": map[string]any{"type": "string"}, + "provider_id": map[string]any{"type": "string"}, + "subject": map[string]any{"type": "string"}, + "email": map[string]any{"type": "string", "format": "email"}, + "verified": map[string]any{"type": "boolean"}, + }, "user_id", "provider_id", "subject", "email", "verified")) + registry.RegisterSchema("UserIdentityLink", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "user_id": map[string]any{"type": "string"}, + "provider_id": map[string]any{"type": "string"}, + "subject": map[string]any{"type": "string"}, + "email": map[string]any{"type": "string", "format": "email"}, + "verified": map[string]any{"type": "boolean"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "user_id", "provider_id", "subject", "email", "verified", "schema_version", "created_at")) + registry.RegisterSchema("UserIdentityLinkEnvelope", dataEnvelopeSchema("#/components/schemas/UserIdentityLink")) + registry.RegisterSchema("SSOSession", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "user_id": map[string]any{"type": "string"}, + "provider_id": map[string]any{"type": "string"}, + "prefix": map[string]any{"type": "string", "description": "Non-secret session token prefix for audit displays."}, + "expires_at": map[string]any{"type": "string", "format": "date-time"}, + "revoked_at": map[string]any{"type": "string", "format": "date-time"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "user_id", "provider_id", "prefix", "expires_at", "schema_version", "created_at")) + registry.RegisterSchema("SSOSessionEnvelope", dataEnvelopeSchema("#/components/schemas/SSOSession")) registry.RegisterSchema("SSOSessionCreateResponse", objectSchema(map[string]any{ - "session": map[string]any{"type": "object"}, + "session": map[string]any{"$ref": "#/components/schemas/SSOSession"}, "secret": map[string]any{"type": "string", "description": "One-time SSO session bearer secret; not returned by list/read operations."}, }, "session", "secret")) registry.RegisterSchema("SSOSessionCreateEnvelope", dataEnvelopeSchema("#/components/schemas/SSOSessionCreateResponse")) diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index fc93827..b086007 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -42,10 +42,35 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { case "instanceAdminSnapshot": operation.Description = "Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient." operation.Responses[http.StatusOK] = jsonResponse("Instance admin snapshot envelope.", "#/components/schemas/InstanceAdminSnapshotEnvelope") + case "createOrganization": + operation.Description = "Creates a tenant-scoped organization record for human identity grouping." + operation.RequestBody = jsonRequest("Organization creation request.", "#/components/schemas/CreateOrganizationRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created organization envelope.", "#/components/schemas/OrganizationEnvelope") + case "createUser": + operation.Description = "Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows." + operation.RequestBody = jsonRequest("Human user creation request.", "#/components/schemas/CreateUserRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created human user envelope.", "#/components/schemas/HumanUserEnvelope") + case "deactivateUser": + operation.Description = "Deactivates a tenant-scoped human user as an audited lifecycle transition." + operation.Parameters = append(operation.Parameters, pathParam("id", "Human user id.")) + operation.RequestBody = jsonRequest("Empty JSON object.", "#/components/schemas/EmptyObject") + operation.Responses[http.StatusOK] = jsonResponse("Deactivated human user envelope.", "#/components/schemas/HumanUserEnvelope") + case "createRoleBinding": + operation.Description = "Creates a tenant-scoped role binding for a user or collector subject." + operation.RequestBody = jsonRequest("Role binding creation request.", "#/components/schemas/CreateRoleBindingRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created role binding envelope.", "#/components/schemas/RoleBindingEnvelope") + case "listRoleBindings": + operation.Description = "Lists tenant-scoped role bindings visible to the identity administrator." + operation.Responses[http.StatusOK] = jsonResponse("Role binding list envelope.", "#/components/schemas/RoleBindingListEnvelope") case "createSSOSession": operation.Description = "Creates an admin-managed human SSO session record and returns a one-time bearer secret." operation.RequestBody = jsonRequest("SSO session creation request.", "#/components/schemas/CreateSSOSessionRequest") operation.Responses[http.StatusCreated] = jsonResponse("Created SSO session and one-time secret envelope.", "#/components/schemas/SSOSessionCreateEnvelope") + case "revokeSSOSession": + operation.Description = "Revokes a tenant-scoped SSO session as an audited lifecycle transition." + operation.Parameters = append(operation.Parameters, pathParam("id", "SSO session id.")) + operation.RequestBody = jsonRequest("Empty JSON object.", "#/components/schemas/EmptyObject") + operation.Responses[http.StatusOK] = jsonResponse("Revoked SSO session envelope.", "#/components/schemas/SSOSessionEnvelope") case "createSSOProvider": operation.Description = "Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls." operation.RequestBody = jsonRequest("SSO provider creation request.", "#/components/schemas/CreateSSOProviderRequest") @@ -54,6 +79,10 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Description = "Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material." operation.RequestBody = jsonRequest("Provider identity verification request.", "#/components/schemas/VerifyProviderIdentityRequest") operation.Responses[http.StatusCreated] = jsonResponse("Provider verification envelope.", "#/components/schemas/ProviderVerificationEnvelope") + case "linkSSOIdentity": + operation.Description = "Links a verified provider subject to a tenant-scoped human user." + operation.RequestBody = jsonRequest("SSO identity link request.", "#/components/schemas/LinkSSOIdentityRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created SSO identity link envelope.", "#/components/schemas/UserIdentityLinkEnvelope") case "createAPIKey": operation.Description = "Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata." operation.RequestBody = jsonRequest("API key creation request.", "#/components/schemas/CreateAPIKeyRequest") diff --git a/openapi.yaml b/openapi.yaml index ddab413..6e8ac55 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"type":"object"}},"required":["session","secret"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"201":{"description":"Create artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"Get artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"Verify cosign-style artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"Verify build attestation signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"201":{"description":"Upload build attestation response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"201":{"description":"Create custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"201":{"description":"Evaluate custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"List deployments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"201":{"description":"Record deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"Get deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"201":{"description":"Create DSSE trust root response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"List deployment environments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"201":{"description":"Create deployment environment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"List evidence lifecycle events response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"201":{"description":"Record evidence lifecycle event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"201":{"description":"Link evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"201":{"description":"Supersede evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"List exceptions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"201":{"description":"Create exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"Approve exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"201":{"description":"Upload OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"Get OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"201":{"description":"Create OpenAPI contract diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"operationId":"createOrganization","responses":{"201":{"description":"Create organization response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"201":{"description":"Evaluate release policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"Get release bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"Get release bundle manifest response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"List release candidates response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"201":{"description":"Create release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"Get release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"Promote release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"Reject release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"Missing evidence report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"operationId":"listRoleBindings","responses":{"200":{"description":"List role bindings response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"operationId":"createRoleBinding","responses":{"201":{"description":"Create role binding response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"List signing keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"201":{"description":"Rotate signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"Revoke signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"201":{"description":"Create signing provider operation receipt response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"201":{"description":"Create signing provider record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"201":{"description":"Record source branch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"201":{"description":"Record source commit response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"201":{"description":"Record pull request response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"List source repositories response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"201":{"description":"Create source repository response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"operationId":"linkSSOIdentity","responses":{"201":{"description":"Link SSO identity response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"operationId":"revokeSSOSession","responses":{"200":{"description":"Revoke SSO session response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"operationId":"createUser","responses":{"201":{"description":"Create user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"operationId":"deactivateUser","responses":{"200":{"description":"Deactivate user response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"201":{"description":"Create vulnerability decision response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"201":{"description":"Record vulnerability workflow event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"201":{"description":"Create waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"Approve waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"201":{"description":"Create artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"Get artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"Verify cosign-style artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"Verify build attestation signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"201":{"description":"Upload build attestation response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"201":{"description":"Create custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"201":{"description":"Evaluate custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"List deployments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"201":{"description":"Record deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"Get deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"201":{"description":"Create DSSE trust root response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"List deployment environments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"201":{"description":"Create deployment environment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"List evidence lifecycle events response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"201":{"description":"Record evidence lifecycle event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"201":{"description":"Link evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"201":{"description":"Supersede evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"List exceptions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"201":{"description":"Create exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"Approve exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"201":{"description":"Upload OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"Get OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"201":{"description":"Create OpenAPI contract diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"201":{"description":"Evaluate release policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"Get release bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"Get release bundle manifest response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"List release candidates response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"201":{"description":"Create release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"Get release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"Promote release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"Reject release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"Missing evidence report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"List signing keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"201":{"description":"Rotate signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"Revoke signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"201":{"description":"Create signing provider operation receipt response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"201":{"description":"Create signing provider record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"201":{"description":"Record source branch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"201":{"description":"Record source commit response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"201":{"description":"Record pull request response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"List source repositories response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"201":{"description":"Create source repository response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"201":{"description":"Create vulnerability decision response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"201":{"description":"Record vulnerability workflow event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"201":{"description":"Create waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"Approve waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/scripts/openapi_precision_check.py b/scripts/openapi_precision_check.py index 2461f9d..536ddb7 100755 --- a/scripts/openapi_precision_check.py +++ b/scripts/openapi_precision_check.py @@ -42,8 +42,8 @@ def main() -> int: else: broad += 1 - min_precise = int_env("EVYDENCE_OPENAPI_MIN_PRECISE", 54) - max_broad = int_env("EVYDENCE_OPENAPI_MAX_BROAD", 106) + min_precise = int_env("EVYDENCE_OPENAPI_MIN_PRECISE", 61) + max_broad = int_env("EVYDENCE_OPENAPI_MAX_BROAD", 99) if precise < min_precise: print( f"openapi-precision-check: precise operations {precise} below required {min_precise}", From b042761e8b4b85e9d5029f84dd3b9ea1b71f6bd5 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 18:58:58 +0300 Subject: [PATCH 068/287] docs: tighten release ledger openapi contracts --- docs/reference/api-contract-matrix.md | 14 ++--- internal/adapters/httpapi/openapi.go | 54 +++++++++++++++++++ .../adapters/httpapi/openapi_operations.go | 20 ++++++- internal/adapters/httpapi/router_test.go | 2 +- openapi.yaml | 2 +- scripts/openapi_precision_check.py | 4 +- 6 files changed, 83 insertions(+), 13 deletions(-) diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index 7172df7..8b1b190 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 160 operations: 61 precise, 99 broad. +Generated from 160 operations: 66 precise, 94 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -89,7 +89,7 @@ Generated from 160 operations: 61 precise, 99 broad. | POST | /v1/openapi-diffs | createOpenAPIDiff | Bearer | evidence:read | required | - | - | 201:unspecified | broad | | GET | /v1/openapi.json | openapi | public | - | - | - | - | 200:application/json:OpenAPIDocument | precise | | POST | /v1/organizations | createOrganization | Bearer | identity:admin | required | - | application/json:CreateOrganizationRequest | 201:application/json:OrganizationEnvelope | precise | -| POST | /v1/policies/evaluate | evaluatePolicy | Bearer | verify:read | required | - | - | 201:unspecified | broad | +| POST | /v1/policies/evaluate | evaluatePolicy | Bearer | verify:read | required | - | application/json:EvaluatePolicyRequest | 201:application/json:PolicyEvaluationEnvelope | precise | | GET | /v1/products | listProducts | Bearer | product:read | - | - | - | 200:application/json:ProductListEnvelope | precise | | POST | /v1/products | createProduct | Bearer | product:write | required | - | application/json:CreateProductRequest | 201:application/json:ProductEnvelope | precise | | POST | /v1/projects | createProject | Bearer | project:write | required | - | application/json:CreateProjectRequest | 201:application/json:ProjectEnvelope | precise | @@ -101,10 +101,10 @@ Generated from 160 operations: 61 precise, 99 broad. | POST | /v1/questionnaire-templates | createQuestionnaireTemplate | Bearer | package:write | required | - | - | 201:unspecified | broad | | GET | /v1/ready | ready | public | - | - | - | - | 200:application/json:ReadinessStatusEnvelope | precise | | POST | /v1/redaction-profiles | createRedactionProfile | Bearer | package:write | required | - | - | 201:unspecified | broad | -| POST | /v1/release-bundles | createReleaseBundle | Bearer | bundle:write | required | - | application/json:CreateReleaseBundleRequest | 201:application/json:DataEnvelope | broad | -| GET | /v1/release-bundles/{id} | getReleaseBundle | Bearer | bundle:read | - | - | - | 200:unspecified | broad | -| GET | /v1/release-bundles/{id}/manifest | getReleaseBundleManifest | Bearer | bundle:read | - | - | - | 200:unspecified | broad | -| GET | /v1/release-bundles/{id}/verify | verifyReleaseBundle | Bearer | verify:read | - | path:id | - | 200:application/json:ReleaseBundleVerificationEnvelope | precise | +| POST | /v1/release-bundles | createReleaseBundle | Bearer | bundle:write | required | - | application/json:CreateReleaseBundleRequest | 201:application/json:ReleaseBundleEnvelope | precise | +| GET | /v1/release-bundles/{id} | getReleaseBundle | Bearer | bundle:read | - | path:id | - | 200:application/json:ReleaseBundleEnvelope | precise | +| GET | /v1/release-bundles/{id}/manifest | getReleaseBundleManifest | Bearer | bundle:read | - | path:id | - | 200:application/json:ReleaseBundleManifestEnvelope | precise | +| GET | /v1/release-bundles/{id}/verify | verifyReleaseBundle | Bearer | verify:read | - | path:id | - | 200:application/json:VerificationResultEnvelope | precise | | GET | /v1/release-candidates | listReleaseCandidates | Bearer | release:read | - | - | - | 200:unspecified | broad | | POST | /v1/release-candidates | createReleaseCandidate | Bearer | release:write | required | - | - | 201:unspecified | broad | | GET | /v1/release-candidates/{id} | getReleaseCandidate | Bearer | release:read | - | - | - | 200:unspecified | broad | @@ -122,7 +122,7 @@ Generated from 160 operations: 61 precise, 99 broad. | GET | /v1/reports/cra-readiness | craReadinessReport | Bearer | report:read | - | query:product_id, query:release_id | - | 200:application/json:ReadinessReportEnvelope | precise | | GET | /v1/reports/cra-readiness-html | craReadinessHTMLPackage | Bearer | report:read | - | - | - | 200:unspecified | broad | | GET | /v1/reports/incident-package | incidentReport | Bearer | incident:read | - | - | - | 200:unspecified | broad | -| GET | /v1/reports/missing-evidence | missingEvidenceReport | Bearer | verify:read | - | - | - | 200:unspecified | broad | +| GET | /v1/reports/missing-evidence | missingEvidenceReport | Bearer | verify:read | - | query:release_id | - | 200:application/json:MissingEvidenceReportEnvelope | precise | | POST | /v1/reports/pdf | createPDFReportPackage | Bearer | report:read | required | - | - | 201:unspecified | broad | | GET | /v1/reports/release-readiness | releaseReadinessReport | Bearer | verify:read | - | query:release_id | - | 200:application/json:ReadinessReportEnvelope | precise | | GET | /v1/reports/retention | retentionReport | Bearer | admin | - | - | - | 200:unspecified | broad | diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index e549452..9bd1717 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -147,6 +147,26 @@ func registerCriticalSchemas(registry *specs.Registry) { "verified_at": map[string]any{"type": "string", "format": "date-time"}, }, "id", "tenant_id", "subject_type", "subject_id", "result", "checks", "verified_at")) registry.RegisterSchema("VerificationResultEnvelope", dataEnvelopeSchema("#/components/schemas/VerificationResult")) + registry.RegisterSchema("PolicyCheck", objectSchema(map[string]any{ + "name": map[string]any{"type": "string"}, + "result": map[string]any{"type": "string", "enum": []string{"passed", "failed", "warning", "skipped"}}, + "severity": map[string]any{"type": "string"}, + "missing": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "explanation": map[string]any{"type": "string"}, + }, "name", "result", "severity", "explanation")) + registry.RegisterSchema("PolicyEvaluation", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "result": map[string]any{"type": "string", "enum": []string{"passed", "failed"}}, + "policy_set": map[string]any{"type": "string"}, + "checks": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/PolicyCheck"}}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "release_id", "result", "policy_set", "checks", "created_at")) + registry.RegisterSchema("PolicyEvaluationEnvelope", dataEnvelopeSchema("#/components/schemas/PolicyEvaluation")) + registry.RegisterSchema("EvaluatePolicyRequest", objectSchema(map[string]any{ + "release_id": map[string]any{"type": "string"}, + }, "release_id")) registry.RegisterSchema("ReadinessReport", objectSchema(map[string]any{ "report_type": map[string]any{"type": "string"}, "template_version": map[string]any{"type": "string"}, @@ -160,6 +180,16 @@ func registerCriticalSchemas(registry *specs.Registry) { "generated_at": map[string]any{"type": "string", "format": "date-time"}, }, "report_type", "template_version", "result", "assumptions", "limitations", "generated_at")) registry.RegisterSchema("ReadinessReportEnvelope", dataEnvelopeSchema("#/components/schemas/ReadinessReport")) + registry.RegisterSchema("MissingEvidenceReport", objectSchema(map[string]any{ + "report_type": map[string]any{"type": "string"}, + "template_version": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "result": map[string]any{"type": "string", "enum": []string{"passed", "failed"}}, + "missing": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "assumptions": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + }, "report_type", "template_version", "release_id", "result", "missing", "assumptions", "limitations")) + registry.RegisterSchema("MissingEvidenceReportEnvelope", dataEnvelopeSchema("#/components/schemas/MissingEvidenceReport")) registry.RegisterSchema("SSOProvider", objectSchema(map[string]any{ "id": map[string]any{"type": "string"}, "tenant_id": map[string]any{"type": "string"}, @@ -739,6 +769,30 @@ func registerCriticalSchemas(registry *specs.Registry) { registry.RegisterSchema("CreateReleaseBundleRequest", objectSchema(map[string]any{ "release_id": map[string]any{"type": "string"}, }, "release_id")) + registry.RegisterSchema("ReleaseBundleManifest", objectSchema(map[string]any{ + "manifest_version": map[string]any{"type": "string"}, + "bundle_id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "release": map[string]any{"type": "object", "additionalProperties": true}, + "evidence_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "chain_checkpoint": map[string]any{"type": "object", "additionalProperties": true}, + "generated_at": map[string]any{"type": "string", "format": "date-time"}, + "generator": map[string]any{"type": "object", "additionalProperties": true}, + }, "manifest_version", "bundle_id", "tenant_id", "release", "evidence_ids", "chain_checkpoint", "generated_at", "generator")) + registry.RegisterSchema("ReleaseBundleManifestEnvelope", dataEnvelopeSchema("#/components/schemas/ReleaseBundleManifest")) + registry.RegisterSchema("ReleaseBundle", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "state": map[string]any{"type": "string"}, + "manifest": map[string]any{"$ref": "#/components/schemas/ReleaseBundleManifest"}, + "manifest_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "signature_refs": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + "published_at": map[string]any{"type": "string", "format": "date-time"}, + "revoked_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "release_id", "state", "manifest", "manifest_hash", "signature_refs", "created_at")) + registry.RegisterSchema("ReleaseBundleEnvelope", dataEnvelopeSchema("#/components/schemas/ReleaseBundle")) registry.RegisterSchema("ReleaseBundleVerification", objectSchema(map[string]any{ "result": map[string]any{"type": "string", "enum": []string{"passed", "failed"}}, "subject_type": map[string]any{"type": "string"}, diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index b086007..57602a2 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -262,11 +262,19 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { case "createReleaseBundle": operation.Description = "Creates an immutable signed release bundle for a release." operation.RequestBody = jsonRequest("Release bundle creation request.", "#/components/schemas/CreateReleaseBundleRequest") - operation.Responses[http.StatusCreated] = jsonResponse("Created release bundle envelope.", "#/components/schemas/DataEnvelope") + operation.Responses[http.StatusCreated] = jsonResponse("Created release bundle envelope.", "#/components/schemas/ReleaseBundleEnvelope") + case "getReleaseBundle": + operation.Description = "Returns a tenant-scoped immutable release bundle by id." + operation.Parameters = append(operation.Parameters, pathParam("id", "Release bundle id.")) + operation.Responses[http.StatusOK] = jsonResponse("Release bundle envelope.", "#/components/schemas/ReleaseBundleEnvelope") + case "getReleaseBundleManifest": + operation.Description = "Returns the deterministic release bundle manifest by bundle id." + operation.Parameters = append(operation.Parameters, pathParam("id", "Release bundle id.")) + operation.Responses[http.StatusOK] = jsonResponse("Release bundle manifest envelope.", "#/components/schemas/ReleaseBundleManifestEnvelope") case "verifyReleaseBundle": operation.Description = "Verifies a tenant-scoped release bundle and returns a deterministic verification result." operation.Parameters = append(operation.Parameters, pathParam("id", "Release bundle id.")) - operation.Responses[http.StatusOK] = jsonResponse("Release bundle verification envelope.", "#/components/schemas/ReleaseBundleVerificationEnvelope") + operation.Responses[http.StatusOK] = jsonResponse("Release bundle verification envelope.", "#/components/schemas/VerificationResultEnvelope") case "verifyAuditChain": operation.Description = "Verifies the tenant audit chain continuity and returns deterministic verification checks." operation.Responses[http.StatusOK] = jsonResponse("Audit chain verification envelope.", "#/components/schemas/VerificationResultEnvelope") @@ -291,6 +299,14 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Description = "Returns a deterministic release-readiness report with gaps, assumptions, and limitations." operation.Parameters = append(operation.Parameters, queryParam("release_id", "Release id.", "string")) operation.Responses[http.StatusOK] = jsonResponse("Release readiness report envelope.", "#/components/schemas/ReadinessReportEnvelope") + case "missingEvidenceReport": + operation.Description = "Returns a deterministic missing-evidence report for a release with assumptions and limitations." + operation.Parameters = append(operation.Parameters, queryParam("release_id", "Release id.", "string")) + operation.Responses[http.StatusOK] = jsonResponse("Missing evidence report envelope.", "#/components/schemas/MissingEvidenceReportEnvelope") + case "evaluatePolicy": + operation.Description = "Evaluates built-in deterministic release policy checks for a release." + operation.RequestBody = jsonRequest("Policy evaluation request.", "#/components/schemas/EvaluatePolicyRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Policy evaluation envelope.", "#/components/schemas/PolicyEvaluationEnvelope") case "craReadinessReport": operation.Description = "Returns a CRA-oriented readiness report without legal compliance or certification conclusions." operation.Parameters = append(operation.Parameters, diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 9ff9059..6e341b5 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -172,7 +172,7 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { assertResponseRef(t, verifyProvider, "201", "#/components/schemas/ProviderVerificationEnvelope") verifyBundle := operationMap(t, paths, "/v1/release-bundles/{id}/verify", "get") assertQueryParams(t, verifyBundle, "id") - assertResponseRef(t, verifyBundle, "200", "#/components/schemas/ReleaseBundleVerificationEnvelope") + assertResponseRef(t, verifyBundle, "200", "#/components/schemas/VerificationResultEnvelope") instanceAdmin := operationMap(t, paths, "/v1/admin/instance", "get") if !strings.Contains(asString(t, instanceAdmin["description"]), "instance:admin") { t.Fatalf("instance admin description should document exact scope: %#v", instanceAdmin["description"]) diff --git a/openapi.yaml b/openapi.yaml index 6e8ac55..c328a8e 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"201":{"description":"Create artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"Get artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"Verify cosign-style artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"Verify build attestation signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"201":{"description":"Upload build attestation response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"201":{"description":"Create custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"201":{"description":"Evaluate custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"List deployments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"201":{"description":"Record deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"Get deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"201":{"description":"Create DSSE trust root response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"List deployment environments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"201":{"description":"Create deployment environment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"List evidence lifecycle events response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"201":{"description":"Record evidence lifecycle event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"201":{"description":"Link evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"201":{"description":"Supersede evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"List exceptions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"201":{"description":"Create exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"Approve exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"201":{"description":"Upload OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"Get OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"201":{"description":"Create OpenAPI contract diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"operationId":"evaluatePolicy","responses":{"201":{"description":"Evaluate release policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"operationId":"getReleaseBundle","responses":{"200":{"description":"Get release bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"operationId":"getReleaseBundleManifest","responses":{"200":{"description":"Get release bundle manifest response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleVerificationEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"List release candidates response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"201":{"description":"Create release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"Get release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"Promote release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"Reject release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"operationId":"missingEvidenceReport","responses":{"200":{"description":"Missing evidence report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"List signing keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"201":{"description":"Rotate signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"Revoke signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"201":{"description":"Create signing provider operation receipt response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"201":{"description":"Create signing provider record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"201":{"description":"Record source branch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"201":{"description":"Record source commit response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"201":{"description":"Record pull request response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"List source repositories response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"201":{"description":"Create source repository response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"201":{"description":"Create vulnerability decision response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"201":{"description":"Record vulnerability workflow event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"201":{"description":"Create waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"Approve waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"201":{"description":"Create artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"Get artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"Verify cosign-style artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"Verify build attestation signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"201":{"description":"Upload build attestation response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"201":{"description":"Create custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"201":{"description":"Evaluate custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"List deployments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"201":{"description":"Record deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"Get deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"201":{"description":"Create DSSE trust root response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"List deployment environments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"201":{"description":"Create deployment environment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"List evidence lifecycle events response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"201":{"description":"Record evidence lifecycle event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"201":{"description":"Link evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"201":{"description":"Supersede evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"List exceptions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"201":{"description":"Create exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"Approve exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"201":{"description":"Upload OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"Get OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"201":{"description":"Create OpenAPI contract diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"List release candidates response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"201":{"description":"Create release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"Get release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"Promote release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"Reject release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"List signing keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"201":{"description":"Rotate signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"Revoke signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"201":{"description":"Create signing provider operation receipt response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"201":{"description":"Create signing provider record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"201":{"description":"Record source branch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"201":{"description":"Record source commit response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"201":{"description":"Record pull request response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"List source repositories response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"201":{"description":"Create source repository response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"201":{"description":"Create vulnerability decision response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"201":{"description":"Record vulnerability workflow event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"201":{"description":"Create waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"Approve waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/scripts/openapi_precision_check.py b/scripts/openapi_precision_check.py index 536ddb7..b0eddda 100755 --- a/scripts/openapi_precision_check.py +++ b/scripts/openapi_precision_check.py @@ -42,8 +42,8 @@ def main() -> int: else: broad += 1 - min_precise = int_env("EVYDENCE_OPENAPI_MIN_PRECISE", 61) - max_broad = int_env("EVYDENCE_OPENAPI_MAX_BROAD", 99) + min_precise = int_env("EVYDENCE_OPENAPI_MIN_PRECISE", 66) + max_broad = int_env("EVYDENCE_OPENAPI_MAX_BROAD", 94) if precise < min_precise: print( f"openapi-precision-check: precise operations {precise} below required {min_precise}", From bd017346ff4933a7099aad5e85ec090bff794d40 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 19:07:55 +0300 Subject: [PATCH 069/287] docs: tighten risk policy openapi contracts --- docs/reference/api-contract-matrix.md | 20 +-- internal/adapters/httpapi/openapi.go | 134 ++++++++++++++++++ .../adapters/httpapi/openapi_operations.go | 41 ++++++ openapi.yaml | 2 +- scripts/openapi_precision_check.py | 4 +- 5 files changed, 188 insertions(+), 13 deletions(-) diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index 8b1b190..288df0d 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 160 operations: 66 precise, 94 broad. +Generated from 160 operations: 75 precise, 85 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -41,8 +41,8 @@ Generated from 160 operations: 66 precise, 94 broad. | POST | /v1/controls | createSecurityControl | Bearer | controls:admin | required | - | application/json:CreateSecurityControlRequest | 201:application/json:SecurityControlEnvelope | precise | | GET | /v1/controls/{id} | getSecurityControl | Bearer | controls:read | - | path:id | - | 200:application/json:SecurityControlEnvelope | precise | | POST | /v1/controls/{id}/evidence | linkControlEvidence | Bearer | controls:write | required | path:id | application/json:LinkControlEvidenceRequest | 201:application/json:ControlEvidenceEnvelope | precise | -| POST | /v1/custom-policies | createCustomPolicy | Bearer | policy:write | required | - | - | 201:unspecified | broad | -| POST | /v1/custom-policies/{id}/evaluate | evaluateCustomPolicy | Bearer | policy:read | required | - | - | 201:unspecified | broad | +| POST | /v1/custom-policies | createCustomPolicy | Bearer | policy:write | required | - | application/json:CreateCustomPolicyRequest | 201:application/json:CustomPolicyEnvelope | precise | +| POST | /v1/custom-policies/{id}/evaluate | evaluateCustomPolicy | Bearer | policy:read | required | path:id | application/json:EvaluatePolicyRequest | 201:application/json:CustomPolicyEvaluationEnvelope | precise | | POST | /v1/customer-packages | createCustomerPackage | Bearer | package:write | required | - | - | 201:unspecified | broad | | GET | /v1/customer-packages/{id} | getCustomerPackage | Bearer | package:read | - | - | - | 200:unspecified | broad | | GET | /v1/customer-packages/{id}/download | downloadCustomerPackage | Bearer | package:read | - | path:id | - | 200:application/zip:string/binary | precise | @@ -67,9 +67,9 @@ Generated from 160 operations: 66 precise, 94 broad. | POST | /v1/evidence/{id}/lifecycle-events | recordEvidenceLifecycleEvent | Bearer | evidence:write | required | - | - | 201:unspecified | broad | | POST | /v1/evidence/{id}/link | linkEvidence | Bearer | evidence:write | required | - | - | 201:unspecified | broad | | POST | /v1/evidence/{id}/supersede | supersedeEvidence | Bearer | evidence:write | required | - | - | 201:unspecified | broad | -| GET | /v1/exceptions | listExceptions | Bearer | verify:read | - | - | - | 200:unspecified | broad | -| POST | /v1/exceptions | createException | Bearer | release:write | required | - | - | 201:unspecified | broad | -| POST | /v1/exceptions/{id}/approve | approveException | Bearer | release:write | required | - | - | 200:unspecified | broad | +| GET | /v1/exceptions | listExceptions | Bearer | verify:read | - | query:release_id | - | 200:application/json:ExceptionListEnvelope | precise | +| POST | /v1/exceptions | createException | Bearer | release:write | required | - | application/json:CreateExceptionRequest | 201:application/json:ExceptionEnvelope | precise | +| POST | /v1/exceptions/{id}/approve | approveException | Bearer | release:write | required | path:id | application/json:EmptyObject | 200:application/json:ExceptionEnvelope | precise | | GET | /v1/health | health | public | - | - | - | - | 200:application/json:HealthStatusEnvelope | precise | | POST | /v1/incident-webhooks/{receiver_id} | receiveIncidentWebhook | public | - | not required | header:X-Evydence-Webhook-Event-ID, header:X-Evydence-Webhook-Signature, header:X-Evydence-Webhook-Timestamp, path:receiver_id | application/json:DataEnvelope | 201:application/json:DataEnvelope | broad | | POST | /v1/incidents | createIncident | Bearer | incident:write | required | - | - | 201:unspecified | broad | @@ -161,10 +161,10 @@ Generated from 160 operations: 66 precise, 94 broad. | POST | /v1/vex | uploadVEX | Bearer | evidence:write | required | - | application/json:EvidenceUploadRequest | 201:application/json:VEXDocumentEnvelope | precise | | POST | /v1/vex/cyclonedx | uploadCycloneDXVEX | Bearer | evidence:write | required | - | application/json:EvidenceUploadRequest | 201:application/json:VEXDocumentEnvelope | precise | | GET | /v1/vex/{id} | getVEX | Bearer | evidence:read | - | path:id | - | 200:application/json:VEXDocumentEnvelope | precise | -| POST | /v1/vulnerability-findings/{id}/decisions | createVulnerabilityDecision | Bearer | evidence:write | required | - | - | 201:unspecified | broad | -| POST | /v1/vulnerability-findings/{id}/workflow | recordVulnerabilityWorkflow | Bearer | security:write | required | - | - | 201:unspecified | broad | +| POST | /v1/vulnerability-findings/{id}/decisions | createVulnerabilityDecision | Bearer | evidence:write | required | path:id | application/json:CreateVulnerabilityDecisionRequest | 201:application/json:VulnerabilityDecisionEnvelope | precise | +| POST | /v1/vulnerability-findings/{id}/workflow | recordVulnerabilityWorkflow | Bearer | security:write | required | path:id | application/json:RecordVulnerabilityWorkflowRequest | 201:application/json:VulnerabilityWorkflowRecordEnvelope | precise | | POST | /v1/vulnerability-scans | uploadVulnerabilityScan | Bearer | evidence:write | required | - | application/json:UploadVulnerabilityScanRequest | 201:application/json:VulnerabilityScanEnvelope | precise | | GET | /v1/vulnerability-scans/{id} | getVulnerabilityScan | Bearer | evidence:read | - | path:id | - | 200:application/json:VulnerabilityScanEnvelope | precise | -| POST | /v1/waivers | createWaiver | Bearer | policy:write | required | - | - | 201:unspecified | broad | -| POST | /v1/waivers/{id}/approve | approveWaiver | Bearer | policy:write | required | - | - | 200:unspecified | broad | +| POST | /v1/waivers | createWaiver | Bearer | policy:write | required | - | application/json:CreateWaiverRequest | 201:application/json:WaiverEnvelope | precise | +| POST | /v1/waivers/{id}/approve | approveWaiver | Bearer | policy:write | required | path:id | application/json:EmptyObject | 200:application/json:WaiverEnvelope | precise | diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 9bd1717..4ed2ce5 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -167,6 +167,140 @@ func registerCriticalSchemas(registry *specs.Registry) { registry.RegisterSchema("EvaluatePolicyRequest", objectSchema(map[string]any{ "release_id": map[string]any{"type": "string"}, }, "release_id")) + registry.RegisterSchema("CreateVulnerabilityDecisionRequest", objectSchema(map[string]any{ + "status": map[string]any{"type": "string", "enum": []string{"affected", "not_affected", "fixed", "under_investigation"}}, + "justification": map[string]any{"type": "string"}, + "impact_statement": map[string]any{"type": "string"}, + "action_statement": map[string]any{"type": "string"}, + }, "status", "justification")) + registry.RegisterSchema("VulnerabilityDecision", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "finding_id": map[string]any{"type": "string"}, + "scan_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "vulnerability": map[string]any{"type": "string"}, + "component": map[string]any{"type": "string"}, + "status": map[string]any{"type": "string"}, + "justification": map[string]any{"type": "string"}, + "impact_statement": map[string]any{"type": "string"}, + "action_statement": map[string]any{"type": "string"}, + "source": map[string]any{"type": "string"}, + "evidence_id": map[string]any{"type": "string"}, + "vex_document_id": map[string]any{"type": "string"}, + "supersedes": map[string]any{"type": "string"}, + "superseded_by": map[string]any{"type": "string"}, + "approved_by": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "finding_id", "scan_id", "vulnerability", "status", "justification", "source", "schema_version", "created_at")) + registry.RegisterSchema("VulnerabilityDecisionEnvelope", dataEnvelopeSchema("#/components/schemas/VulnerabilityDecision")) + registry.RegisterSchema("RecordVulnerabilityWorkflowRequest", objectSchema(map[string]any{ + "action": map[string]any{"type": "string"}, + "reason": map[string]any{"type": "string"}, + }, "action", "reason")) + registry.RegisterSchema("VulnerabilityWorkflowRecord", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "finding_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "action": map[string]any{"type": "string"}, + "reason": map[string]any{"type": "string"}, + "actor_id": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "finding_id", "action", "reason", "actor_id", "schema_version", "created_at")) + registry.RegisterSchema("VulnerabilityWorkflowRecordEnvelope", dataEnvelopeSchema("#/components/schemas/VulnerabilityWorkflowRecord")) + registry.RegisterSchema("CreateExceptionRequest", objectSchema(map[string]any{ + "release_id": map[string]any{"type": "string"}, + "finding_id": map[string]any{"type": "string"}, + "control_id": map[string]any{"type": "string"}, + "reason": map[string]any{"type": "string"}, + "owner": map[string]any{"type": "string"}, + "expires_at": map[string]any{"type": "string", "format": "date-time"}, + }, "release_id", "reason", "owner", "expires_at")) + registry.RegisterSchema("Exception", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "finding_id": map[string]any{"type": "string"}, + "control_id": map[string]any{"type": "string"}, + "reason": map[string]any{"type": "string"}, + "owner": map[string]any{"type": "string"}, + "expires_at": map[string]any{"type": "string", "format": "date-time"}, + "approved": map[string]any{"type": "boolean"}, + "approved_by": map[string]any{"type": "string"}, + "approved_at": map[string]any{"type": "string", "format": "date-time"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "release_id", "reason", "owner", "expires_at", "approved", "created_at")) + registry.RegisterSchema("ExceptionEnvelope", dataEnvelopeSchema("#/components/schemas/Exception")) + registry.RegisterSchema("ExceptionListEnvelope", dataArrayEnvelopeSchema("#/components/schemas/Exception")) + registry.RegisterSchema("PolicyRule", objectSchema(map[string]any{ + "name": map[string]any{"type": "string"}, + "evidence_type": map[string]any{"type": "string"}, + "severity": map[string]any{"type": "string"}, + "required": map[string]any{"type": "boolean"}, + }, "name", "severity", "required")) + registry.RegisterSchema("CreateCustomPolicyRequest", objectSchema(map[string]any{ + "name": map[string]any{"type": "string"}, + "version": map[string]any{"type": "string"}, + "description": map[string]any{"type": "string"}, + "rules": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/PolicyRule"}}, + }, "name", "version", "rules")) + registry.RegisterSchema("CustomPolicy", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "version": map[string]any{"type": "string"}, + "description": map[string]any{"type": "string"}, + "rules": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/PolicyRule"}}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "name", "version", "rules", "schema_version", "created_at")) + registry.RegisterSchema("CustomPolicyEnvelope", dataEnvelopeSchema("#/components/schemas/CustomPolicy")) + registry.RegisterSchema("CustomPolicyEvaluation", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "policy_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "result": map[string]any{"type": "string", "enum": []string{"passed", "failed"}}, + "checks": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/PolicyCheck"}}, + "input_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "policy_id", "release_id", "result", "checks", "input_hash", "schema_version", "created_at")) + registry.RegisterSchema("CustomPolicyEvaluationEnvelope", dataEnvelopeSchema("#/components/schemas/CustomPolicyEvaluation")) + registry.RegisterSchema("CreateWaiverRequest", objectSchema(map[string]any{ + "scope_type": map[string]any{"type": "string"}, + "scope_id": map[string]any{"type": "string"}, + "control_id": map[string]any{"type": "string"}, + "policy_id": map[string]any{"type": "string"}, + "owner": map[string]any{"type": "string"}, + "risk": map[string]any{"type": "string"}, + "reason": map[string]any{"type": "string"}, + "expires_at": map[string]any{"type": "string", "format": "date-time"}, + "supersedes": map[string]any{"type": "string"}, + }, "scope_type", "scope_id", "owner", "risk", "reason", "expires_at")) + registry.RegisterSchema("Waiver", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "scope_type": map[string]any{"type": "string"}, + "scope_id": map[string]any{"type": "string"}, + "control_id": map[string]any{"type": "string"}, + "policy_id": map[string]any{"type": "string"}, + "owner": map[string]any{"type": "string"}, + "risk": map[string]any{"type": "string"}, + "reason": map[string]any{"type": "string"}, + "expires_at": map[string]any{"type": "string", "format": "date-time"}, + "approved": map[string]any{"type": "boolean"}, + "approved_by": map[string]any{"type": "string"}, + "approved_at": map[string]any{"type": "string", "format": "date-time"}, + "supersedes": map[string]any{"type": "string"}, + "superseded_by": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "scope_type", "scope_id", "owner", "risk", "reason", "expires_at", "approved", "schema_version", "created_at")) + registry.RegisterSchema("WaiverEnvelope", dataEnvelopeSchema("#/components/schemas/Waiver")) registry.RegisterSchema("ReadinessReport", objectSchema(map[string]any{ "report_type": map[string]any{"type": "string"}, "template_version": map[string]any{"type": "string"}, diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 57602a2..88b2f6a 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -307,6 +307,47 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Description = "Evaluates built-in deterministic release policy checks for a release." operation.RequestBody = jsonRequest("Policy evaluation request.", "#/components/schemas/EvaluatePolicyRequest") operation.Responses[http.StatusCreated] = jsonResponse("Policy evaluation envelope.", "#/components/schemas/PolicyEvaluationEnvelope") + case "createVulnerabilityDecision": + operation.Description = "Creates an append-only vulnerability decision for a tenant-scoped scan finding." + operation.Parameters = append(operation.Parameters, pathParam("id", "Vulnerability finding id.")) + operation.RequestBody = jsonRequest("Vulnerability decision creation request.", "#/components/schemas/CreateVulnerabilityDecisionRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created vulnerability decision envelope.", "#/components/schemas/VulnerabilityDecisionEnvelope") + case "recordVulnerabilityWorkflow": + operation.Description = "Records an append-only vulnerability workflow event for a tenant-scoped finding." + operation.Parameters = append(operation.Parameters, pathParam("id", "Vulnerability finding id.")) + operation.RequestBody = jsonRequest("Vulnerability workflow event request.", "#/components/schemas/RecordVulnerabilityWorkflowRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created vulnerability workflow record envelope.", "#/components/schemas/VulnerabilityWorkflowRecordEnvelope") + case "createException": + operation.Description = "Creates a scoped, expiring release/finding/control exception that is inactive until approved." + operation.RequestBody = jsonRequest("Exception creation request.", "#/components/schemas/CreateExceptionRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created exception envelope.", "#/components/schemas/ExceptionEnvelope") + case "listExceptions": + operation.Description = "Lists tenant-scoped exceptions, optionally filtered by release." + operation.Parameters = append(operation.Parameters, queryParam("release_id", "Release id.", "string")) + operation.Responses[http.StatusOK] = jsonResponse("Exception list envelope.", "#/components/schemas/ExceptionListEnvelope") + case "approveException": + operation.Description = "Approves an unexpired exception as an audited append-only transition." + operation.Parameters = append(operation.Parameters, pathParam("id", "Exception id.")) + operation.RequestBody = jsonRequest("Empty JSON object.", "#/components/schemas/EmptyObject") + operation.Responses[http.StatusOK] = jsonResponse("Approved exception envelope.", "#/components/schemas/ExceptionEnvelope") + case "createCustomPolicy": + operation.Description = "Creates a deterministic custom policy definition for tenant-managed release checks." + operation.RequestBody = jsonRequest("Custom policy creation request.", "#/components/schemas/CreateCustomPolicyRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created custom policy envelope.", "#/components/schemas/CustomPolicyEnvelope") + case "evaluateCustomPolicy": + operation.Description = "Evaluates a tenant custom policy against a release and records the input hash." + operation.Parameters = append(operation.Parameters, pathParam("id", "Custom policy id.")) + operation.RequestBody = jsonRequest("Custom policy evaluation request.", "#/components/schemas/EvaluatePolicyRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Custom policy evaluation envelope.", "#/components/schemas/CustomPolicyEvaluationEnvelope") + case "createWaiver": + operation.Description = "Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition." + operation.RequestBody = jsonRequest("Waiver creation request.", "#/components/schemas/CreateWaiverRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created waiver envelope.", "#/components/schemas/WaiverEnvelope") + case "approveWaiver": + operation.Description = "Approves an unexpired waiver as an audited transition." + operation.Parameters = append(operation.Parameters, pathParam("id", "Waiver id.")) + operation.RequestBody = jsonRequest("Empty JSON object.", "#/components/schemas/EmptyObject") + operation.Responses[http.StatusOK] = jsonResponse("Approved waiver envelope.", "#/components/schemas/WaiverEnvelope") case "craReadinessReport": operation.Description = "Returns a CRA-oriented readiness report without legal compliance or certification conclusions." operation.Parameters = append(operation.Parameters, diff --git a/openapi.yaml b/openapi.yaml index c328a8e..922fb1d 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"201":{"description":"Create artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"Get artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"Verify cosign-style artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"Verify build attestation signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"201":{"description":"Upload build attestation response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"operationId":"createCustomPolicy","responses":{"201":{"description":"Create custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"operationId":"evaluateCustomPolicy","responses":{"201":{"description":"Evaluate custom policy response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"List deployments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"201":{"description":"Record deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"Get deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"201":{"description":"Create DSSE trust root response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"List deployment environments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"201":{"description":"Create deployment environment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"List evidence lifecycle events response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"201":{"description":"Record evidence lifecycle event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"201":{"description":"Link evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"201":{"description":"Supersede evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"operationId":"listExceptions","responses":{"200":{"description":"List exceptions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"operationId":"createException","responses":{"201":{"description":"Create exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"operationId":"approveException","responses":{"200":{"description":"Approve exception response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"201":{"description":"Upload OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"Get OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"201":{"description":"Create OpenAPI contract diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"List release candidates response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"201":{"description":"Create release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"Get release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"Promote release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"Reject release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"List signing keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"201":{"description":"Rotate signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"Revoke signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"201":{"description":"Create signing provider operation receipt response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"201":{"description":"Create signing provider record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"201":{"description":"Record source branch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"201":{"description":"Record source commit response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"201":{"description":"Record pull request response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"List source repositories response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"201":{"description":"Create source repository response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"operationId":"createVulnerabilityDecision","responses":{"201":{"description":"Create vulnerability decision response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"operationId":"recordVulnerabilityWorkflow","responses":{"201":{"description":"Record vulnerability workflow event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"operationId":"createWaiver","responses":{"201":{"description":"Create waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"operationId":"approveWaiver","responses":{"200":{"description":"Approve waiver response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"201":{"description":"Create artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"Get artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"Verify cosign-style artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"Verify build attestation signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"201":{"description":"Upload build attestation response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"List deployments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"201":{"description":"Record deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"Get deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"201":{"description":"Create DSSE trust root response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"List deployment environments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"201":{"description":"Create deployment environment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"List evidence lifecycle events response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"201":{"description":"Record evidence lifecycle event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"201":{"description":"Link evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"201":{"description":"Supersede evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"201":{"description":"Upload OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"Get OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"201":{"description":"Create OpenAPI contract diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"List release candidates response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"201":{"description":"Create release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"Get release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"Promote release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"Reject release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"List signing keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"201":{"description":"Rotate signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"Revoke signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"201":{"description":"Create signing provider operation receipt response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"201":{"description":"Create signing provider record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"201":{"description":"Record source branch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"201":{"description":"Record source commit response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"201":{"description":"Record pull request response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"List source repositories response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"201":{"description":"Create source repository response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/scripts/openapi_precision_check.py b/scripts/openapi_precision_check.py index b0eddda..9d9f5bf 100755 --- a/scripts/openapi_precision_check.py +++ b/scripts/openapi_precision_check.py @@ -42,8 +42,8 @@ def main() -> int: else: broad += 1 - min_precise = int_env("EVYDENCE_OPENAPI_MIN_PRECISE", 66) - max_broad = int_env("EVYDENCE_OPENAPI_MAX_BROAD", 94) + min_precise = int_env("EVYDENCE_OPENAPI_MIN_PRECISE", 75) + max_broad = int_env("EVYDENCE_OPENAPI_MAX_BROAD", 85) if precise < min_precise: print( f"openapi-precision-check: precise operations {precise} below required {min_precise}", From 916ca282c976f10914e590d95dd93e55db8f5268 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 19:09:28 +0300 Subject: [PATCH 070/287] docs: tighten contract signing openapi contracts --- docs/reference/api-contract-matrix.md | 18 ++-- internal/adapters/httpapi/openapi.go | 101 ++++++++++++++++++ .../adapters/httpapi/openapi_operations.go | 32 ++++++ openapi.yaml | 2 +- scripts/openapi_precision_check.py | 4 +- 5 files changed, 145 insertions(+), 12 deletions(-) diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index 288df0d..334e8aa 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 160 operations: 75 precise, 85 broad. +Generated from 160 operations: 83 precise, 77 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -84,9 +84,9 @@ Generated from 160 operations: 75 precise, 85 broad. | GET | /v1/metrics | metrics | Bearer | admin | - | - | - | 200:application/json:MetricsSnapshotEnvelope,text/plain:string | precise | | POST | /v1/object-retention-policies | createObjectRetentionPolicy | Bearer | admin | required | - | - | 201:unspecified | broad | | POST | /v1/object-retention-policies/{id}/verify | verifyObjectRetentionPolicy | Bearer | verify:read | required | - | - | 200:unspecified | broad | -| POST | /v1/openapi-contracts | uploadOpenAPIContract | Bearer | evidence:write | required | - | - | 201:unspecified | broad | -| GET | /v1/openapi-contracts/{id} | getOpenAPIContract | Bearer | evidence:read | - | - | - | 200:unspecified | broad | -| POST | /v1/openapi-diffs | createOpenAPIDiff | Bearer | evidence:read | required | - | - | 201:unspecified | broad | +| POST | /v1/openapi-contracts | uploadOpenAPIContract | Bearer | evidence:write | required | - | application/json:UploadOpenAPIContractRequest | 201:application/json:OpenAPIContractEnvelope | precise | +| GET | /v1/openapi-contracts/{id} | getOpenAPIContract | Bearer | evidence:read | - | path:id | - | 200:application/json:OpenAPIContractEnvelope | precise | +| POST | /v1/openapi-diffs | createOpenAPIDiff | Bearer | evidence:read | required | - | application/json:CreateOpenAPIDiffRequest | 201:application/json:ContractDiffEnvelope | precise | | GET | /v1/openapi.json | openapi | public | - | - | - | - | 200:application/json:OpenAPIDocument | precise | | POST | /v1/organizations | createOrganization | Bearer | identity:admin | required | - | application/json:CreateOrganizationRequest | 201:application/json:OrganizationEnvelope | precise | | POST | /v1/policies/evaluate | evaluatePolicy | Bearer | verify:read | required | - | application/json:EvaluatePolicyRequest | 201:application/json:PolicyEvaluationEnvelope | precise | @@ -139,11 +139,11 @@ Generated from 160 operations: 75 precise, 85 broad. | GET | /v1/sboms/{id} | getSBOM | Bearer | evidence:read | - | path:id | - | 200:application/json:SBOMEnvelope | precise | | POST | /v1/security-documents | uploadManualSecurityDocument | Bearer | security:write | required | - | - | 201:unspecified | broad | | POST | /v1/security-scans | uploadSecurityScan | Bearer | security:write | required | - | - | 201:unspecified | broad | -| GET | /v1/signing-keys | listSigningKeys | Bearer | verify:read | - | - | - | 200:unspecified | broad | -| POST | /v1/signing-keys/rotate | rotateSigningKey | Bearer | keys:admin | required | - | - | 201:unspecified | broad | -| POST | /v1/signing-keys/{id}/revoke | revokeSigningKey | Bearer | keys:admin | required | - | - | 200:unspecified | broad | -| POST | /v1/signing-operations | createSigningOperation | Bearer | keys:admin | required | - | - | 201:unspecified | broad | -| POST | /v1/signing-providers | createSigningProvider | Bearer | keys:admin | required | - | - | 201:unspecified | broad | +| GET | /v1/signing-keys | listSigningKeys | Bearer | verify:read | - | - | - | 200:application/json:SigningKeyListEnvelope | precise | +| POST | /v1/signing-keys/rotate | rotateSigningKey | Bearer | keys:admin | required | - | application/json:SigningKeyTransitionRequest | 201:application/json:SigningKeyEnvelope | precise | +| POST | /v1/signing-keys/{id}/revoke | revokeSigningKey | Bearer | keys:admin | required | path:id | application/json:SigningKeyTransitionRequest | 200:application/json:SigningKeyEnvelope | precise | +| POST | /v1/signing-operations | createSigningOperation | Bearer | keys:admin | required | - | application/json:CreateSigningOperationRequest | 201:application/json:SigningOperationEnvelope | precise | +| POST | /v1/signing-providers | createSigningProvider | Bearer | keys:admin | required | - | application/json:CreateSigningProviderRequest | 201:application/json:SigningProviderEnvelope | precise | | POST | /v1/source/branches | upsertSourceBranch | Bearer | source:write | required | - | - | 201:unspecified | broad | | POST | /v1/source/commits | recordSourceCommit | Bearer | source:write | required | - | - | 201:unspecified | broad | | POST | /v1/source/pull-requests | recordPullRequest | Bearer | source:write | required | - | - | 201:unspecified | broad | diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 4ed2ce5..ae7c601 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -301,6 +301,107 @@ func registerCriticalSchemas(registry *specs.Registry) { "created_at": map[string]any{"type": "string", "format": "date-time"}, }, "id", "tenant_id", "scope_type", "scope_id", "owner", "risk", "reason", "expires_at", "approved", "schema_version", "created_at")) registry.RegisterSchema("WaiverEnvelope", dataEnvelopeSchema("#/components/schemas/Waiver")) + registry.RegisterSchema("UploadOpenAPIContractRequest", objectSchema(map[string]any{ + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "version": map[string]any{"type": "string"}, + "spec": map[string]any{"type": "object", "additionalProperties": true}, + }, "product_id", "release_id", "version", "spec")) + registry.RegisterSchema("OpenAPIOperationRecord", objectSchema(map[string]any{ + "path": map[string]any{"type": "string"}, + "method": map[string]any{"type": "string"}, + "operation_id": map[string]any{"type": "string"}, + "deprecated": map[string]any{"type": "boolean"}, + "request_body_required": map[string]any{"type": "boolean"}, + "required_request_fields": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "response_statuses": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + }, "path", "method")) + registry.RegisterSchema("OpenAPIContract", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "version": map[string]any{"type": "string"}, + "hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "path_count": map[string]any{"type": "integer"}, + "operations": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/OpenAPIOperationRecord"}}, + "evidence_id": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "product_id", "version", "hash", "path_count", "evidence_id", "created_at")) + registry.RegisterSchema("OpenAPIContractEnvelope", dataEnvelopeSchema("#/components/schemas/OpenAPIContract")) + registry.RegisterSchema("CreateOpenAPIDiffRequest", objectSchema(map[string]any{ + "base_contract_id": map[string]any{"type": "string"}, + "target_contract_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + }, "base_contract_id", "target_contract_id", "release_id")) + registry.RegisterSchema("ContractDiff", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "base_contract_id": map[string]any{"type": "string"}, + "target_contract_id": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "result": map[string]any{"type": "string"}, + "breaking_changes": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "non_breaking_changes": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "base_contract_id", "target_contract_id", "product_id", "result", "schema_version", "created_at")) + registry.RegisterSchema("ContractDiffEnvelope", dataEnvelopeSchema("#/components/schemas/ContractDiff")) + registry.RegisterSchema("SigningKey", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "kid": map[string]any{"type": "string"}, + "algorithm": map[string]any{"type": "string"}, + "status": map[string]any{"type": "string"}, + "public_key": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + "revoked_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "kid", "algorithm", "status", "public_key", "created_at")) + registry.RegisterSchema("SigningKeyEnvelope", dataEnvelopeSchema("#/components/schemas/SigningKey")) + registry.RegisterSchema("SigningKeyListEnvelope", dataArrayEnvelopeSchema("#/components/schemas/SigningKey")) + registry.RegisterSchema("SigningKeyTransitionRequest", objectSchema(map[string]any{ + "reason": map[string]any{"type": "string"}, + })) + registry.RegisterSchema("CreateSigningProviderRequest", objectSchema(map[string]any{ + "name": map[string]any{"type": "string"}, + "type": map[string]any{"type": "string"}, + "key_ref": map[string]any{"type": "string"}, + "encrypted": map[string]any{"type": "boolean"}, + }, "name", "type", "key_ref")) + registry.RegisterSchema("SigningProvider", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "type": map[string]any{"type": "string"}, + "status": map[string]any{"type": "string"}, + "key_ref": map[string]any{"type": "string"}, + "encrypted": map[string]any{"type": "boolean"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "name", "type", "status", "key_ref", "encrypted", "schema_version", "created_at")) + registry.RegisterSchema("SigningProviderEnvelope", dataEnvelopeSchema("#/components/schemas/SigningProvider")) + registry.RegisterSchema("CreateSigningOperationRequest", objectSchema(map[string]any{ + "provider_id": map[string]any{"type": "string"}, + "subject_type": map[string]any{"type": "string"}, + "subject_id": map[string]any{"type": "string"}, + "payload_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "external_signature": map[string]any{"type": "string"}, + }, "provider_id", "subject_type", "subject_id", "payload_hash")) + registry.RegisterSchema("SigningOperation", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "provider_id": map[string]any{"type": "string"}, + "subject_type": map[string]any{"type": "string"}, + "subject_id": map[string]any{"type": "string"}, + "payload_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "signature_ref": map[string]any{"type": "string"}, + "result": map[string]any{"type": "string"}, + "checks": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/VerifyCheck"}}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "provider_id", "subject_type", "subject_id", "payload_hash", "result", "checks", "schema_version", "created_at")) + registry.RegisterSchema("SigningOperationEnvelope", dataEnvelopeSchema("#/components/schemas/SigningOperation")) registry.RegisterSchema("ReadinessReport", objectSchema(map[string]any{ "report_type": map[string]any{"type": "string"}, "template_version": map[string]any{"type": "string"}, diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 88b2f6a..95e6cbd 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -348,6 +348,38 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Parameters = append(operation.Parameters, pathParam("id", "Waiver id.")) operation.RequestBody = jsonRequest("Empty JSON object.", "#/components/schemas/EmptyObject") operation.Responses[http.StatusOK] = jsonResponse("Approved waiver envelope.", "#/components/schemas/WaiverEnvelope") + case "uploadOpenAPIContract": + operation.Description = "Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata." + operation.RequestBody = jsonRequest("OpenAPI contract upload request.", "#/components/schemas/UploadOpenAPIContractRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created OpenAPI contract envelope.", "#/components/schemas/OpenAPIContractEnvelope") + case "getOpenAPIContract": + operation.Description = "Returns a tenant-scoped OpenAPI contract metadata record by id." + operation.Parameters = append(operation.Parameters, pathParam("id", "OpenAPI contract id.")) + operation.Responses[http.StatusOK] = jsonResponse("OpenAPI contract envelope.", "#/components/schemas/OpenAPIContractEnvelope") + case "createOpenAPIDiff": + operation.Description = "Creates a deterministic OpenAPI contract diff for release contract checks." + operation.RequestBody = jsonRequest("OpenAPI contract diff request.", "#/components/schemas/CreateOpenAPIDiffRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created OpenAPI contract diff envelope.", "#/components/schemas/ContractDiffEnvelope") + case "listSigningKeys": + operation.Description = "Lists tenant signing public-key metadata without private key material." + operation.Responses[http.StatusOK] = jsonResponse("Signing key list envelope.", "#/components/schemas/SigningKeyListEnvelope") + case "rotateSigningKey": + operation.Description = "Rotates the active tenant signing key and returns public-key metadata only." + operation.RequestBody = jsonRequest("Signing key rotation request.", "#/components/schemas/SigningKeyTransitionRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Rotated signing key envelope.", "#/components/schemas/SigningKeyEnvelope") + case "revokeSigningKey": + operation.Description = "Revokes a tenant signing key as an audited lifecycle transition." + operation.Parameters = append(operation.Parameters, pathParam("id", "Signing key id.")) + operation.RequestBody = jsonRequest("Signing key revocation request.", "#/components/schemas/SigningKeyTransitionRequest") + operation.Responses[http.StatusOK] = jsonResponse("Revoked signing key envelope.", "#/components/schemas/SigningKeyEnvelope") + case "createSigningProvider": + operation.Description = "Creates signing provider metadata for external signing operations. Production private key material must not be supplied." + operation.RequestBody = jsonRequest("Signing provider creation request.", "#/components/schemas/CreateSigningProviderRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created signing provider envelope.", "#/components/schemas/SigningProviderEnvelope") + case "createSigningOperation": + operation.Description = "Records an external signing operation receipt and checks payload/signature metadata without logging secrets." + operation.RequestBody = jsonRequest("Signing operation creation request.", "#/components/schemas/CreateSigningOperationRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created signing operation envelope.", "#/components/schemas/SigningOperationEnvelope") case "craReadinessReport": operation.Description = "Returns a CRA-oriented readiness report without legal compliance or certification conclusions." operation.Parameters = append(operation.Parameters, diff --git a/openapi.yaml b/openapi.yaml index 922fb1d..e5b3349 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"201":{"description":"Create artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"Get artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"Verify cosign-style artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"Verify build attestation signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"201":{"description":"Upload build attestation response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"List deployments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"201":{"description":"Record deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"Get deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"201":{"description":"Create DSSE trust root response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"List deployment environments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"201":{"description":"Create deployment environment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"List evidence lifecycle events response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"201":{"description":"Record evidence lifecycle event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"201":{"description":"Link evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"201":{"description":"Supersede evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"operationId":"uploadOpenAPIContract","responses":{"201":{"description":"Upload OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"operationId":"getOpenAPIContract","responses":{"200":{"description":"Get OpenAPI contract response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"operationId":"createOpenAPIDiff","responses":{"201":{"description":"Create OpenAPI contract diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"List release candidates response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"201":{"description":"Create release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"Get release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"Promote release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"Reject release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"operationId":"listSigningKeys","responses":{"200":{"description":"List signing keys response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"operationId":"rotateSigningKey","responses":{"201":{"description":"Rotate signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"operationId":"revokeSigningKey","responses":{"200":{"description":"Revoke signing key response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"operationId":"createSigningOperation","responses":{"201":{"description":"Create signing provider operation receipt response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"operationId":"createSigningProvider","responses":{"201":{"description":"Create signing provider record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"201":{"description":"Record source branch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"201":{"description":"Record source commit response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"201":{"description":"Record pull request response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"List source repositories response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"201":{"description":"Create source repository response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"201":{"description":"Create artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"Get artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"Verify cosign-style artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"Verify build attestation signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"201":{"description":"Upload build attestation response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"List deployments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"201":{"description":"Record deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"Get deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"201":{"description":"Create DSSE trust root response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"List deployment environments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"201":{"description":"Create deployment environment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"List evidence lifecycle events response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"201":{"description":"Record evidence lifecycle event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"201":{"description":"Link evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"201":{"description":"Supersede evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"List release candidates response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"201":{"description":"Create release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"Get release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"Promote release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"Reject release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"201":{"description":"Record source branch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"201":{"description":"Record source commit response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"201":{"description":"Record pull request response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"List source repositories response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"201":{"description":"Create source repository response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/scripts/openapi_precision_check.py b/scripts/openapi_precision_check.py index 9d9f5bf..9e87ee7 100755 --- a/scripts/openapi_precision_check.py +++ b/scripts/openapi_precision_check.py @@ -42,8 +42,8 @@ def main() -> int: else: broad += 1 - min_precise = int_env("EVYDENCE_OPENAPI_MIN_PRECISE", 75) - max_broad = int_env("EVYDENCE_OPENAPI_MAX_BROAD", 85) + min_precise = int_env("EVYDENCE_OPENAPI_MIN_PRECISE", 83) + max_broad = int_env("EVYDENCE_OPENAPI_MAX_BROAD", 77) if precise < min_precise: print( f"openapi-precision-check: precise operations {precise} below required {min_precise}", From f990269df1db4883fe4a3df2444e5fb1c1485064 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 19:10:18 +0300 Subject: [PATCH 071/287] docs: tighten provenance openapi contracts --- docs/reference/api-contract-matrix.md | 14 +-- internal/adapters/httpapi/openapi.go | 92 +++++++++++++++++++ .../adapters/httpapi/openapi_operations.go | 27 ++++++ openapi.yaml | 2 +- scripts/openapi_precision_check.py | 4 +- 5 files changed, 129 insertions(+), 10 deletions(-) diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index 334e8aa..ab09f1f 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 160 operations: 83 precise, 77 broad. +Generated from 160 operations: 89 precise, 71 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -12,18 +12,18 @@ Generated from 160 operations: 83 precise, 77 broad. | POST | /v1/api-keys | createAPIKey | Bearer | admin | required | - | application/json:CreateAPIKeyRequest | 201:application/json:APIKeyCreateEnvelope | precise | | POST | /v1/api-security-scans | uploadAPISecurityScan | Bearer | security:write | required | - | - | 201:unspecified | broad | | POST | /v1/approvals | createApproval | Bearer | release:write | required | - | - | 201:unspecified | broad | -| POST | /v1/artifact-signatures | createArtifactSignature | Bearer | evidence:write | required | - | - | 201:unspecified | broad | -| GET | /v1/artifact-signatures/{id} | getArtifactSignature | Bearer | evidence:read | - | - | - | 200:unspecified | broad | -| POST | /v1/artifact-signatures/{id}/verify-cosign | verifyCosignSignature | Bearer | verify:read | required | - | - | 200:unspecified | broad | +| POST | /v1/artifact-signatures | createArtifactSignature | Bearer | evidence:write | required | - | application/json:CreateArtifactSignatureRequest | 201:application/json:ArtifactSignatureEnvelope | precise | +| GET | /v1/artifact-signatures/{id} | getArtifactSignature | Bearer | evidence:read | - | path:id | - | 200:application/json:ArtifactSignatureEnvelope | precise | +| POST | /v1/artifact-signatures/{id}/verify-cosign | verifyCosignSignature | Bearer | verify:read | required | path:id | application/json:VerifyCosignSignatureRequest | 200:application/json:CosignVerificationEnvelope | precise | | POST | /v1/artifacts | registerArtifact | Bearer | evidence:write | required | - | application/json:RegisterArtifactRequest | 201:application/json:ArtifactEnvelope | precise | | GET | /v1/audit-chain/verify | verifyAuditChain | Bearer | verify:read | - | - | - | 200:application/json:VerificationResultEnvelope | precise | | GET | /v1/audit-log | listAuditLog | Bearer | admin | - | query:limit, query:since, query:subject_id, query:subject_type | - | 200:application/json:AuditChainEntryListEnvelope | precise | | POST | /v1/backup-manifests | generateBackupManifest | Bearer | admin | required | - | application/json:EmptyObject | 201:application/json:BackupManifestEnvelope | precise | | GET | /v1/backup-manifests/{id}/verify | verifyBackupManifest | Bearer | verify:read | - | path:id | - | 200:application/json:VerificationResultEnvelope | precise | -| POST | /v1/build-attestations/{id}/verify-signature | verifyBuildAttestationSignature | Bearer | verify:read | required | - | - | 200:unspecified | broad | +| POST | /v1/build-attestations/{id}/verify-signature | verifyBuildAttestationSignature | Bearer | verify:read | required | path:id | application/json:EmptyObject | 200:application/json:VerificationResultEnvelope | precise | | POST | /v1/builds | createBuild | Bearer | build:write | required | - | application/json:CreateBuildRequest | 201:application/json:BuildRunEnvelope | precise | | GET | /v1/builds/{id} | getBuild | Bearer | build:read | - | path:id | - | 200:application/json:BuildRunEnvelope | precise | -| POST | /v1/builds/{id}/attestations | uploadBuildAttestation | Bearer | build:write | required | - | - | 201:unspecified | broad | +| POST | /v1/builds/{id}/attestations | uploadBuildAttestation | Bearer | build:write | required | path:id | application/json:DSSEEnvelope | 201:application/json:BuildAttestationEnvelope | precise | | GET | /v1/collectors | listCollectors | Bearer | collector:read | - | - | - | 200:application/json:CollectorListEnvelope | precise | | POST | /v1/collectors | createCollector | Bearer | collector:admin | required | - | application/json:CreateCollectorRequest | 201:application/json:CollectorCreateEnvelope | precise | | POST | /v1/collectors/github/source-snapshots | uploadGitHubSourceSnapshot | Bearer | source:write | required | - | application/json:SourceSnapshotRequest | 201:application/json:SourceSnapshotEnvelope | precise | @@ -52,7 +52,7 @@ Generated from 160 operations: 83 precise, 77 broad. | GET | /v1/deployments | listDeployments | Bearer | deployment:read | - | - | - | 200:unspecified | broad | | POST | /v1/deployments | recordDeployment | Bearer | deployment:write | required | - | - | 201:unspecified | broad | | GET | /v1/deployments/{id} | getDeployment | Bearer | deployment:read | - | - | - | 200:unspecified | broad | -| POST | /v1/dsse-trust-roots | createDSSETrustRoot | Bearer | keys:admin | required | - | - | 201:unspecified | broad | +| POST | /v1/dsse-trust-roots | createDSSETrustRoot | Bearer | keys:admin | required | - | application/json:CreateDSSETrustRootRequest | 201:application/json:DSSETrustRootEnvelope | precise | | GET | /v1/environments | listDeploymentEnvironments | Bearer | deployment:read | - | - | - | 200:unspecified | broad | | POST | /v1/environments | createDeploymentEnvironment | Bearer | deployment:write | required | - | - | 201:unspecified | broad | | GET | /v1/evidence | listEvidence | Bearer | evidence:read | - | query:release_id, query:type | - | 200:application/json:EvidenceItemListEnvelope | precise | diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index ae7c601..a2e6cf9 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -402,6 +402,98 @@ func registerCriticalSchemas(registry *specs.Registry) { "created_at": map[string]any{"type": "string", "format": "date-time"}, }, "id", "tenant_id", "provider_id", "subject_type", "subject_id", "payload_hash", "result", "checks", "schema_version", "created_at")) registry.RegisterSchema("SigningOperationEnvelope", dataEnvelopeSchema("#/components/schemas/SigningOperation")) + registry.RegisterSchema("CreateArtifactSignatureRequest", objectSchema(map[string]any{ + "artifact_id": map[string]any{"type": "string"}, + "algorithm": map[string]any{"type": "string"}, + "key_id": map[string]any{"type": "string"}, + "signature": map[string]any{"type": "string"}, + "payload": map[string]any{"type": "object", "additionalProperties": true}, + "payload_media_type": map[string]any{"type": "string"}, + }, "artifact_id", "algorithm", "signature")) + registry.RegisterSchema("ArtifactSignature", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "artifact_id": map[string]any{"type": "string"}, + "subject_digest": map[string]any{"type": "string"}, + "algorithm": map[string]any{"type": "string"}, + "key_id": map[string]any{"type": "string"}, + "signature": map[string]any{"type": "string"}, + "payload_ref": map[string]any{"type": "string"}, + "payload_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "verification_status": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "artifact_id", "subject_digest", "algorithm", "signature", "verification_status", "schema_version", "created_at")) + registry.RegisterSchema("ArtifactSignatureEnvelope", dataEnvelopeSchema("#/components/schemas/ArtifactSignature")) + registry.RegisterSchema("VerifyCosignSignatureRequest", objectSchema(map[string]any{ + "rekor_uuid": map[string]any{"type": "string"}, + "rekor_log_index": map[string]any{"type": "string"}, + "certificate_identity": map[string]any{"type": "string"}, + "certificate_issuer": map[string]any{"type": "string"}, + })) + registry.RegisterSchema("CosignVerification", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "artifact_id": map[string]any{"type": "string"}, + "container_image_id": map[string]any{"type": "string"}, + "artifact_signature_id": map[string]any{"type": "string"}, + "subject_digest": map[string]any{"type": "string"}, + "rekor_uuid": map[string]any{"type": "string"}, + "rekor_log_index": map[string]any{"type": "string"}, + "certificate_identity": map[string]any{"type": "string"}, + "certificate_issuer": map[string]any{"type": "string"}, + "result": map[string]any{"type": "string", "enum": []string{"passed", "failed"}}, + "checks": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/VerifyCheck"}}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "artifact_signature_id", "subject_digest", "result", "checks", "schema_version", "created_at")) + registry.RegisterSchema("CosignVerificationEnvelope", dataEnvelopeSchema("#/components/schemas/CosignVerification")) + registry.RegisterSchema("DSSEEnvelope", objectSchema(map[string]any{ + "payloadType": map[string]any{"type": "string"}, + "payload": map[string]any{"type": "string"}, + "signatures": map[string]any{"type": "array", "items": objectSchema(map[string]any{ + "keyid": map[string]any{"type": "string"}, + "sig": map[string]any{"type": "string"}, + }, "sig")}, + }, "payloadType", "payload", "signatures")) + registry.RegisterSchema("BuildAttestation", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "build_id": map[string]any{"type": "string"}, + "evidence_id": map[string]any{"type": "string"}, + "payload_ref": map[string]any{"type": "string"}, + "payload_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "payload_size": map[string]any{"type": "integer"}, + "payload_type": map[string]any{"type": "string"}, + "predicate_type": map[string]any{"type": "string"}, + "subject_digests": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "builder_id": map[string]any{"type": "string"}, + "build_type": map[string]any{"type": "string"}, + "materials_count": map[string]any{"type": "integer"}, + "signature_count": map[string]any{"type": "integer"}, + "verification_status": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "build_id", "evidence_id", "payload_hash", "payload_size", "payload_type", "predicate_type", "subject_digests", "signature_count", "verification_status", "schema_version", "created_at")) + registry.RegisterSchema("BuildAttestationEnvelope", dataEnvelopeSchema("#/components/schemas/BuildAttestation")) + registry.RegisterSchema("CreateDSSETrustRootRequest", objectSchema(map[string]any{ + "name": map[string]any{"type": "string"}, + "key_id": map[string]any{"type": "string"}, + "algorithm": map[string]any{"type": "string", "enum": []string{"Ed25519"}}, + "public_key": map[string]any{"type": "string", "description": "Base64-encoded Ed25519 public key."}, + }, "name", "key_id", "algorithm", "public_key")) + registry.RegisterSchema("DSSETrustRoot", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "key_id": map[string]any{"type": "string"}, + "algorithm": map[string]any{"type": "string"}, + "public_key": map[string]any{"type": "string"}, + "status": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "name", "key_id", "algorithm", "public_key", "status", "schema_version", "created_at")) + registry.RegisterSchema("DSSETrustRootEnvelope", dataEnvelopeSchema("#/components/schemas/DSSETrustRoot")) registry.RegisterSchema("ReadinessReport", objectSchema(map[string]any{ "report_type": map[string]any{"type": "string"}, "template_version": map[string]any{"type": "string"}, diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 95e6cbd..a30d034 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -380,6 +380,33 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Description = "Records an external signing operation receipt and checks payload/signature metadata without logging secrets." operation.RequestBody = jsonRequest("Signing operation creation request.", "#/components/schemas/CreateSigningOperationRequest") operation.Responses[http.StatusCreated] = jsonResponse("Created signing operation envelope.", "#/components/schemas/SigningOperationEnvelope") + case "createArtifactSignature": + operation.Description = "Records detached artifact signature evidence and optional raw signature payload metadata." + operation.RequestBody = jsonRequest("Artifact signature creation request.", "#/components/schemas/CreateArtifactSignatureRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created artifact signature envelope.", "#/components/schemas/ArtifactSignatureEnvelope") + case "getArtifactSignature": + operation.Description = "Returns tenant-scoped artifact signature metadata by id." + operation.Parameters = append(operation.Parameters, pathParam("id", "Artifact signature id.")) + operation.Responses[http.StatusOK] = jsonResponse("Artifact signature envelope.", "#/components/schemas/ArtifactSignatureEnvelope") + case "verifyCosignSignature": + operation.Description = "Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust." + operation.Parameters = append(operation.Parameters, pathParam("id", "Artifact signature id.")) + operation.RequestBody = jsonRequest("Cosign verification metadata request.", "#/components/schemas/VerifyCosignSignatureRequest") + operation.Responses[http.StatusOK] = jsonResponse("Cosign verification envelope.", "#/components/schemas/CosignVerificationEnvelope") + case "uploadBuildAttestation": + operation.Description = "Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage." + operation.Parameters = append(operation.Parameters, pathParam("id", "Build run id.")) + operation.RequestBody = jsonRequest("DSSE envelope.", "#/components/schemas/DSSEEnvelope") + operation.Responses[http.StatusCreated] = jsonResponse("Created build attestation envelope.", "#/components/schemas/BuildAttestationEnvelope") + case "verifyBuildAttestationSignature": + operation.Description = "Verifies a build attestation signature against configured tenant DSSE trust roots." + operation.Parameters = append(operation.Parameters, pathParam("id", "Build attestation id.")) + operation.RequestBody = jsonRequest("Empty JSON object.", "#/components/schemas/EmptyObject") + operation.Responses[http.StatusOK] = jsonResponse("Build attestation verification envelope.", "#/components/schemas/VerificationResultEnvelope") + case "createDSSETrustRoot": + operation.Description = "Creates a tenant-scoped DSSE trust root using public verification key material only." + operation.RequestBody = jsonRequest("DSSE trust-root creation request.", "#/components/schemas/CreateDSSETrustRootRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created DSSE trust root envelope.", "#/components/schemas/DSSETrustRootEnvelope") case "craReadinessReport": operation.Description = "Returns a CRA-oriented readiness report without legal compliance or certification conclusions." operation.Parameters = append(operation.Parameters, diff --git a/openapi.yaml b/openapi.yaml index e5b3349..49ae2f9 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"operationId":"createArtifactSignature","responses":{"201":{"description":"Create artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"operationId":"getArtifactSignature","responses":{"200":{"description":"Get artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"operationId":"verifyCosignSignature","responses":{"200":{"description":"Verify cosign-style artifact signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"operationId":"verifyBuildAttestationSignature","responses":{"200":{"description":"Verify build attestation signature response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"operationId":"uploadBuildAttestation","responses":{"201":{"description":"Upload build attestation response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"List deployments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"201":{"description":"Record deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"Get deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"operationId":"createDSSETrustRoot","responses":{"201":{"description":"Create DSSE trust root response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"List deployment environments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"201":{"description":"Create deployment environment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"List evidence lifecycle events response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"201":{"description":"Record evidence lifecycle event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"201":{"description":"Link evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"201":{"description":"Supersede evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"List release candidates response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"201":{"description":"Create release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"Get release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"Promote release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"Reject release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"201":{"description":"Record source branch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"201":{"description":"Record source commit response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"201":{"description":"Record pull request response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"List source repositories response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"201":{"description":"Create source repository response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"List deployments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"201":{"description":"Record deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"Get deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"List deployment environments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"201":{"description":"Create deployment environment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"List evidence lifecycle events response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"201":{"description":"Record evidence lifecycle event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"201":{"description":"Link evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"201":{"description":"Supersede evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"List release candidates response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"201":{"description":"Create release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"Get release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"Promote release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"Reject release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"201":{"description":"Record source branch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"201":{"description":"Record source commit response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"201":{"description":"Record pull request response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"List source repositories response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"201":{"description":"Create source repository response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/scripts/openapi_precision_check.py b/scripts/openapi_precision_check.py index 9e87ee7..a36629b 100755 --- a/scripts/openapi_precision_check.py +++ b/scripts/openapi_precision_check.py @@ -42,8 +42,8 @@ def main() -> int: else: broad += 1 - min_precise = int_env("EVYDENCE_OPENAPI_MIN_PRECISE", 83) - max_broad = int_env("EVYDENCE_OPENAPI_MAX_BROAD", 77) + min_precise = int_env("EVYDENCE_OPENAPI_MIN_PRECISE", 89) + max_broad = int_env("EVYDENCE_OPENAPI_MAX_BROAD", 71) if precise < min_precise: print( f"openapi-precision-check: precise operations {precise} below required {min_precise}", From 7ba94f485726cab3f0f1f43fbaa688c3db4e3438 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 19:11:52 +0300 Subject: [PATCH 072/287] docs: tighten evidence lifecycle openapi contracts --- docs/reference/api-contract-matrix.md | 20 +++--- internal/adapters/httpapi/openapi.go | 63 +++++++++++++++++++ .../adapters/httpapi/openapi_operations.go | 36 +++++++++++ openapi.yaml | 2 +- scripts/openapi_precision_check.py | 4 +- 5 files changed, 112 insertions(+), 13 deletions(-) diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index ab09f1f..f980a44 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 160 operations: 89 precise, 71 broad. +Generated from 160 operations: 98 precise, 62 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -63,10 +63,10 @@ Generated from 160 operations: 89 precise, 71 broad. | POST | /v1/evidence-summaries | createEvidenceSummary | Bearer | report:read | required | - | - | 201:unspecified | broad | | GET | /v1/evidence/search | searchEvidence | Bearer | evidence:read | - | query:cursor, query:limit, query:product_id, query:project_id, query:release_id, query:source, query:tag, query:type | - | 200:application/json:EvidenceSearchEnvelope | precise | | GET | /v1/evidence/{id} | getEvidence | Bearer | evidence:read | - | path:id | - | 200:application/json:EvidenceItemEnvelope | precise | -| GET | /v1/evidence/{id}/lifecycle-events | listEvidenceLifecycleEvents | Bearer | evidence:read | - | - | - | 200:unspecified | broad | -| POST | /v1/evidence/{id}/lifecycle-events | recordEvidenceLifecycleEvent | Bearer | evidence:write | required | - | - | 201:unspecified | broad | -| POST | /v1/evidence/{id}/link | linkEvidence | Bearer | evidence:write | required | - | - | 201:unspecified | broad | -| POST | /v1/evidence/{id}/supersede | supersedeEvidence | Bearer | evidence:write | required | - | - | 201:unspecified | broad | +| GET | /v1/evidence/{id}/lifecycle-events | listEvidenceLifecycleEvents | Bearer | evidence:read | - | path:id | - | 200:application/json:EvidenceLifecycleEventListEnvelope | precise | +| POST | /v1/evidence/{id}/lifecycle-events | recordEvidenceLifecycleEvent | Bearer | evidence:write | required | path:id | application/json:RecordEvidenceLifecycleEventRequest | 201:application/json:EvidenceLifecycleEventEnvelope | precise | +| POST | /v1/evidence/{id}/link | linkEvidence | Bearer | evidence:write | required | path:id | application/json:LinkEvidenceRequest | 201:application/json:EvidenceItemEnvelope | precise | +| POST | /v1/evidence/{id}/supersede | supersedeEvidence | Bearer | evidence:write | required | path:id | application/json:SupersedeEvidenceRequest | 201:application/json:EvidenceItemEnvelope | precise | | GET | /v1/exceptions | listExceptions | Bearer | verify:read | - | query:release_id | - | 200:application/json:ExceptionListEnvelope | precise | | POST | /v1/exceptions | createException | Bearer | release:write | required | - | application/json:CreateExceptionRequest | 201:application/json:ExceptionEnvelope | precise | | POST | /v1/exceptions/{id}/approve | approveException | Bearer | release:write | required | path:id | application/json:EmptyObject | 200:application/json:ExceptionEnvelope | precise | @@ -105,11 +105,11 @@ Generated from 160 operations: 89 precise, 71 broad. | GET | /v1/release-bundles/{id} | getReleaseBundle | Bearer | bundle:read | - | path:id | - | 200:application/json:ReleaseBundleEnvelope | precise | | GET | /v1/release-bundles/{id}/manifest | getReleaseBundleManifest | Bearer | bundle:read | - | path:id | - | 200:application/json:ReleaseBundleManifestEnvelope | precise | | GET | /v1/release-bundles/{id}/verify | verifyReleaseBundle | Bearer | verify:read | - | path:id | - | 200:application/json:VerificationResultEnvelope | precise | -| GET | /v1/release-candidates | listReleaseCandidates | Bearer | release:read | - | - | - | 200:unspecified | broad | -| POST | /v1/release-candidates | createReleaseCandidate | Bearer | release:write | required | - | - | 201:unspecified | broad | -| GET | /v1/release-candidates/{id} | getReleaseCandidate | Bearer | release:read | - | - | - | 200:unspecified | broad | -| POST | /v1/release-candidates/{id}/promote | promoteReleaseCandidate | Bearer | release:write | required | - | - | 200:unspecified | broad | -| POST | /v1/release-candidates/{id}/reject | rejectReleaseCandidate | Bearer | release:write | required | - | - | 200:unspecified | broad | +| GET | /v1/release-candidates | listReleaseCandidates | Bearer | release:read | - | query:release_id | - | 200:application/json:ReleaseCandidateListEnvelope | precise | +| POST | /v1/release-candidates | createReleaseCandidate | Bearer | release:write | required | - | application/json:CreateReleaseCandidateRequest | 201:application/json:ReleaseCandidateEnvelope | precise | +| GET | /v1/release-candidates/{id} | getReleaseCandidate | Bearer | release:read | - | path:id | - | 200:application/json:ReleaseCandidateEnvelope | precise | +| POST | /v1/release-candidates/{id}/promote | promoteReleaseCandidate | Bearer | release:write | required | path:id | application/json:ReleaseCandidateTransitionRequest | 200:application/json:ReleaseCandidateEnvelope | precise | +| POST | /v1/release-candidates/{id}/reject | rejectReleaseCandidate | Bearer | release:write | required | path:id | application/json:ReleaseCandidateTransitionRequest | 200:application/json:ReleaseCandidateEnvelope | precise | | POST | /v1/releases | createRelease | Bearer | release:write | required | - | application/json:CreateReleaseRequest | 201:application/json:ReleaseEnvelope | precise | | GET | /v1/releases/{id} | getRelease | Bearer | release:read | - | path:id | - | 200:application/json:ReleaseEnvelope | precise | | POST | /v1/releases/{id}/approve | approveRelease | Bearer | release:write | required | path:id | application/json:EmptyObject | 200:application/json:ReleaseEnvelope | precise | diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index a2e6cf9..ac361c7 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -494,6 +494,69 @@ func registerCriticalSchemas(registry *specs.Registry) { "created_at": map[string]any{"type": "string", "format": "date-time"}, }, "id", "tenant_id", "name", "key_id", "algorithm", "public_key", "status", "schema_version", "created_at")) registry.RegisterSchema("DSSETrustRootEnvelope", dataEnvelopeSchema("#/components/schemas/DSSETrustRoot")) + registry.RegisterSchema("CreateReleaseCandidateRequest", objectSchema(map[string]any{ + "release_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "build_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "artifact_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "sbom_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "scan_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "vex_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "contract_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "bundle_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + }, "release_id", "name")) + registry.RegisterSchema("ReleaseCandidateTransitionRequest", objectSchema(map[string]any{ + "reason": map[string]any{"type": "string"}, + })) + registry.RegisterSchema("ReleaseCandidate", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "state": map[string]any{"type": "string"}, + "build_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "artifact_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "sbom_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "scan_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "vex_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "contract_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "bundle_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "snapshot_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + "promoted_at": map[string]any{"type": "string", "format": "date-time"}, + "rejected_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "release_id", "name", "state", "snapshot_hash", "schema_version", "created_at")) + registry.RegisterSchema("ReleaseCandidateEnvelope", dataEnvelopeSchema("#/components/schemas/ReleaseCandidate")) + registry.RegisterSchema("ReleaseCandidateListEnvelope", dataArrayEnvelopeSchema("#/components/schemas/ReleaseCandidate")) + registry.RegisterSchema("SupersedeEvidenceRequest", objectSchema(map[string]any{ + "replacement_evidence_id": map[string]any{"type": "string"}, + "reason": map[string]any{"type": "string"}, + }, "replacement_evidence_id", "reason")) + registry.RegisterSchema("LinkEvidenceRequest", objectSchema(map[string]any{ + "target_type": map[string]any{"type": "string"}, + "target_id": map[string]any{"type": "string"}, + }, "target_type", "target_id")) + registry.RegisterSchema("RecordEvidenceLifecycleEventRequest", objectSchema(map[string]any{ + "action": map[string]any{"type": "string"}, + "reason": map[string]any{"type": "string"}, + "details": map[string]any{"type": "object", "additionalProperties": true}, + "replacement_id": map[string]any{"type": "string"}, + }, "action", "reason")) + registry.RegisterSchema("EvidenceLifecycleEvent", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "evidence_id": map[string]any{"type": "string"}, + "action": map[string]any{"type": "string"}, + "reason": map[string]any{"type": "string"}, + "details": map[string]any{"type": "object", "additionalProperties": true}, + "replacement_id": map[string]any{"type": "string"}, + "actor_id": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "evidence_id", "action", "reason", "actor_id", "schema_version", "created_at")) + registry.RegisterSchema("EvidenceLifecycleEventEnvelope", dataEnvelopeSchema("#/components/schemas/EvidenceLifecycleEvent")) + registry.RegisterSchema("EvidenceLifecycleEventListEnvelope", dataArrayEnvelopeSchema("#/components/schemas/EvidenceLifecycleEvent")) registry.RegisterSchema("ReadinessReport", objectSchema(map[string]any{ "report_type": map[string]any{"type": "string"}, "template_version": map[string]any{"type": "string"}, diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index a30d034..b200f94 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -407,6 +407,42 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Description = "Creates a tenant-scoped DSSE trust root using public verification key material only." operation.RequestBody = jsonRequest("DSSE trust-root creation request.", "#/components/schemas/CreateDSSETrustRootRequest") operation.Responses[http.StatusCreated] = jsonResponse("Created DSSE trust root envelope.", "#/components/schemas/DSSETrustRootEnvelope") + case "createReleaseCandidate": + operation.Description = "Creates an immutable release-candidate snapshot of selected release evidence references." + operation.RequestBody = jsonRequest("Release candidate creation request.", "#/components/schemas/CreateReleaseCandidateRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created release candidate envelope.", "#/components/schemas/ReleaseCandidateEnvelope") + case "listReleaseCandidates": + operation.Description = "Lists tenant-scoped release candidates, optionally filtered by release." + operation.Parameters = append(operation.Parameters, queryParam("release_id", "Release id.", "string")) + operation.Responses[http.StatusOK] = jsonResponse("Release candidate list envelope.", "#/components/schemas/ReleaseCandidateListEnvelope") + case "getReleaseCandidate": + operation.Description = "Returns a tenant-scoped release candidate by id." + operation.Parameters = append(operation.Parameters, pathParam("id", "Release candidate id.")) + operation.Responses[http.StatusOK] = jsonResponse("Release candidate envelope.", "#/components/schemas/ReleaseCandidateEnvelope") + case "promoteReleaseCandidate", "rejectReleaseCandidate": + operation.Description = "Records a release-candidate lifecycle transition without mutating the original snapshot." + operation.Parameters = append(operation.Parameters, pathParam("id", "Release candidate id.")) + operation.RequestBody = jsonRequest("Release candidate transition request.", "#/components/schemas/ReleaseCandidateTransitionRequest") + operation.Responses[http.StatusOK] = jsonResponse("Transitioned release candidate envelope.", "#/components/schemas/ReleaseCandidateEnvelope") + case "supersedeEvidence": + operation.Description = "Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata." + operation.Parameters = append(operation.Parameters, pathParam("id", "Evidence item id.")) + operation.RequestBody = jsonRequest("Evidence supersession request.", "#/components/schemas/SupersedeEvidenceRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Superseded evidence item envelope.", "#/components/schemas/EvidenceItemEnvelope") + case "linkEvidence": + operation.Description = "Creates an append-only relationship from evidence to another tenant-scoped subject." + operation.Parameters = append(operation.Parameters, pathParam("id", "Evidence item id.")) + operation.RequestBody = jsonRequest("Evidence link request.", "#/components/schemas/LinkEvidenceRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Linked evidence item envelope.", "#/components/schemas/EvidenceItemEnvelope") + case "recordEvidenceLifecycleEvent": + operation.Description = "Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker." + operation.Parameters = append(operation.Parameters, pathParam("id", "Evidence item id.")) + operation.RequestBody = jsonRequest("Evidence lifecycle event request.", "#/components/schemas/RecordEvidenceLifecycleEventRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created evidence lifecycle event envelope.", "#/components/schemas/EvidenceLifecycleEventEnvelope") + case "listEvidenceLifecycleEvents": + operation.Description = "Lists append-only lifecycle events for a tenant-scoped evidence item." + operation.Parameters = append(operation.Parameters, pathParam("id", "Evidence item id.")) + operation.Responses[http.StatusOK] = jsonResponse("Evidence lifecycle event list envelope.", "#/components/schemas/EvidenceLifecycleEventListEnvelope") case "craReadinessReport": operation.Description = "Returns a CRA-oriented readiness report without legal compliance or certification conclusions." operation.Parameters = append(operation.Parameters, diff --git a/openapi.yaml b/openapi.yaml index 49ae2f9..31fe697 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"List deployments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"201":{"description":"Record deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"Get deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"List deployment environments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"201":{"description":"Create deployment environment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"operationId":"listEvidenceLifecycleEvents","responses":{"200":{"description":"List evidence lifecycle events response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"operationId":"recordEvidenceLifecycleEvent","responses":{"201":{"description":"Record evidence lifecycle event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"operationId":"linkEvidence","responses":{"201":{"description":"Link evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"operationId":"supersedeEvidence","responses":{"201":{"description":"Supersede evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"operationId":"listReleaseCandidates","responses":{"200":{"description":"List release candidates response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"operationId":"createReleaseCandidate","responses":{"201":{"description":"Create release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"operationId":"getReleaseCandidate","responses":{"200":{"description":"Get release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"operationId":"promoteReleaseCandidate","responses":{"200":{"description":"Promote release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"operationId":"rejectReleaseCandidate","responses":{"200":{"description":"Reject release candidate response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"201":{"description":"Record source branch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"201":{"description":"Record source commit response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"201":{"description":"Record pull request response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"List source repositories response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"201":{"description":"Create source repository response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"List deployments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"201":{"description":"Record deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"Get deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"List deployment environments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"201":{"description":"Create deployment environment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"201":{"description":"Record source branch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"201":{"description":"Record source commit response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"201":{"description":"Record pull request response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"List source repositories response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"201":{"description":"Create source repository response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/scripts/openapi_precision_check.py b/scripts/openapi_precision_check.py index a36629b..55708fd 100755 --- a/scripts/openapi_precision_check.py +++ b/scripts/openapi_precision_check.py @@ -42,8 +42,8 @@ def main() -> int: else: broad += 1 - min_precise = int_env("EVYDENCE_OPENAPI_MIN_PRECISE", 89) - max_broad = int_env("EVYDENCE_OPENAPI_MAX_BROAD", 71) + min_precise = int_env("EVYDENCE_OPENAPI_MIN_PRECISE", 98) + max_broad = int_env("EVYDENCE_OPENAPI_MAX_BROAD", 62) if precise < min_precise: print( f"openapi-precision-check: precise operations {precise} below required {min_precise}", From 30fb8e8f5f85a455a7a7234a66959275817f5a6d Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 19:14:42 +0300 Subject: [PATCH 073/287] docs: tighten source deployment openapi contracts --- docs/reference/api-contract-matrix.md | 22 +-- internal/adapters/httpapi/openapi.go | 126 ++++++++++++++++++ .../adapters/httpapi/openapi_operations.go | 43 ++++++ openapi.yaml | 2 +- scripts/openapi_precision_check.py | 4 +- 5 files changed, 183 insertions(+), 14 deletions(-) diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index f980a44..6160c1b 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 160 operations: 98 precise, 62 broad. +Generated from 160 operations: 108 precise, 52 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -49,12 +49,12 @@ Generated from 160 operations: 98 precise, 62 broad. | POST | /v1/customer-portal/access | createCustomerPortalAccess | Bearer | package:write | required | - | application/json:CreateCustomerPortalAccessRequest | 201:application/json:CustomerPortalAccessCreateEnvelope | precise | | POST | /v1/customer-portal/package | accessCustomerPortalPackage | public | - | not required | - | application/json:CustomerPortalPackageRequest | 200:application/json:DataEnvelope | broad | | POST | /v1/customer-portal/package/download | downloadCustomerPortalPackage | public | - | not required | - | application/json:CustomerPortalPackageRequest | 200:application/zip:string/binary | precise | -| GET | /v1/deployments | listDeployments | Bearer | deployment:read | - | - | - | 200:unspecified | broad | -| POST | /v1/deployments | recordDeployment | Bearer | deployment:write | required | - | - | 201:unspecified | broad | -| GET | /v1/deployments/{id} | getDeployment | Bearer | deployment:read | - | - | - | 200:unspecified | broad | +| GET | /v1/deployments | listDeployments | Bearer | deployment:read | - | query:environment_id, query:release_id | - | 200:application/json:DeploymentEventListEnvelope | precise | +| POST | /v1/deployments | recordDeployment | Bearer | deployment:write | required | - | application/json:RecordDeploymentRequest | 201:application/json:DeploymentEventEnvelope | precise | +| GET | /v1/deployments/{id} | getDeployment | Bearer | deployment:read | - | path:id | - | 200:application/json:DeploymentEventEnvelope | precise | | POST | /v1/dsse-trust-roots | createDSSETrustRoot | Bearer | keys:admin | required | - | application/json:CreateDSSETrustRootRequest | 201:application/json:DSSETrustRootEnvelope | precise | -| GET | /v1/environments | listDeploymentEnvironments | Bearer | deployment:read | - | - | - | 200:unspecified | broad | -| POST | /v1/environments | createDeploymentEnvironment | Bearer | deployment:write | required | - | - | 201:unspecified | broad | +| GET | /v1/environments | listDeploymentEnvironments | Bearer | deployment:read | - | query:product_id | - | 200:application/json:DeploymentEnvironmentListEnvelope | precise | +| POST | /v1/environments | createDeploymentEnvironment | Bearer | deployment:write | required | - | application/json:CreateDeploymentEnvironmentRequest | 201:application/json:DeploymentEnvironmentEnvelope | precise | | GET | /v1/evidence | listEvidence | Bearer | evidence:read | - | query:release_id, query:type | - | 200:application/json:EvidenceItemListEnvelope | precise | | POST | /v1/evidence | createEvidence | Bearer | evidence:write | required | - | application/json:CreateEvidenceRequest | 201:application/json:EvidenceItemEnvelope | precise | | POST | /v1/evidence-bundles | exportEvidenceBundle | Bearer | bundle:read | required | - | - | 201:unspecified | broad | @@ -144,11 +144,11 @@ Generated from 160 operations: 98 precise, 62 broad. | POST | /v1/signing-keys/{id}/revoke | revokeSigningKey | Bearer | keys:admin | required | path:id | application/json:SigningKeyTransitionRequest | 200:application/json:SigningKeyEnvelope | precise | | POST | /v1/signing-operations | createSigningOperation | Bearer | keys:admin | required | - | application/json:CreateSigningOperationRequest | 201:application/json:SigningOperationEnvelope | precise | | POST | /v1/signing-providers | createSigningProvider | Bearer | keys:admin | required | - | application/json:CreateSigningProviderRequest | 201:application/json:SigningProviderEnvelope | precise | -| POST | /v1/source/branches | upsertSourceBranch | Bearer | source:write | required | - | - | 201:unspecified | broad | -| POST | /v1/source/commits | recordSourceCommit | Bearer | source:write | required | - | - | 201:unspecified | broad | -| POST | /v1/source/pull-requests | recordPullRequest | Bearer | source:write | required | - | - | 201:unspecified | broad | -| GET | /v1/source/repositories | listSourceRepositories | Bearer | source:read | - | - | - | 200:unspecified | broad | -| POST | /v1/source/repositories | createSourceRepository | Bearer | source:write | required | - | - | 201:unspecified | broad | +| POST | /v1/source/branches | upsertSourceBranch | Bearer | source:write | required | - | application/json:UpsertSourceBranchRequest | 201:application/json:SourceBranchEnvelope | precise | +| POST | /v1/source/commits | recordSourceCommit | Bearer | source:write | required | - | application/json:RecordSourceCommitRequest | 201:application/json:SourceCommitEnvelope | precise | +| POST | /v1/source/pull-requests | recordPullRequest | Bearer | source:write | required | - | application/json:RecordPullRequestRequest | 201:application/json:PullRequestEnvelope | precise | +| GET | /v1/source/repositories | listSourceRepositories | Bearer | source:read | - | query:project_id | - | 200:application/json:SourceRepositoryListEnvelope | precise | +| POST | /v1/source/repositories | createSourceRepository | Bearer | source:write | required | - | application/json:CreateSourceRepositoryRequest | 201:application/json:SourceRepositoryEnvelope | precise | | POST | /v1/sso/identity-links | linkSSOIdentity | Bearer | identity:admin | required | - | application/json:LinkSSOIdentityRequest | 201:application/json:UserIdentityLinkEnvelope | precise | | POST | /v1/sso/providers | createSSOProvider | Bearer | identity:admin | required | - | application/json:CreateSSOProviderRequest | 201:application/json:SSOProviderEnvelope | precise | | POST | /v1/sso/sessions | createSSOSession | Bearer | identity:admin | required | - | application/json:CreateSSOSessionRequest | 201:application/json:SSOSessionCreateEnvelope | precise | diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index ac361c7..9d37d3a 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -557,6 +557,132 @@ func registerCriticalSchemas(registry *specs.Registry) { }, "id", "tenant_id", "evidence_id", "action", "reason", "actor_id", "schema_version", "created_at")) registry.RegisterSchema("EvidenceLifecycleEventEnvelope", dataEnvelopeSchema("#/components/schemas/EvidenceLifecycleEvent")) registry.RegisterSchema("EvidenceLifecycleEventListEnvelope", dataArrayEnvelopeSchema("#/components/schemas/EvidenceLifecycleEvent")) + registry.RegisterSchema("CreateSourceRepositoryRequest", objectSchema(map[string]any{ + "project_id": map[string]any{"type": "string"}, + "provider": map[string]any{"type": "string"}, + "full_name": map[string]any{"type": "string"}, + "clone_url": map[string]any{"type": "string"}, + "default_branch": map[string]any{"type": "string"}, + }, "provider", "full_name")) + registry.RegisterSchema("SourceRepository", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "project_id": map[string]any{"type": "string"}, + "provider": map[string]any{"type": "string"}, + "full_name": map[string]any{"type": "string"}, + "clone_url": map[string]any{"type": "string"}, + "default_branch": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "provider", "full_name", "schema_version", "created_at")) + registry.RegisterSchema("SourceRepositoryEnvelope", dataEnvelopeSchema("#/components/schemas/SourceRepository")) + registry.RegisterSchema("SourceRepositoryListEnvelope", dataArrayEnvelopeSchema("#/components/schemas/SourceRepository")) + registry.RegisterSchema("RecordSourceCommitRequest", objectSchema(map[string]any{ + "repository_id": map[string]any{"type": "string"}, + "sha": map[string]any{"type": "string"}, + "author": map[string]any{"type": "string"}, + "message": map[string]any{"type": "string", "description": "Commit message is hashed before storage."}, + "committed_at": map[string]any{"type": "string", "format": "date-time"}, + }, "repository_id", "sha", "committed_at")) + registry.RegisterSchema("SourceCommit", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "repository_id": map[string]any{"type": "string"}, + "sha": map[string]any{"type": "string"}, + "author": map[string]any{"type": "string"}, + "message_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "committed_at": map[string]any{"type": "string", "format": "date-time"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "repository_id", "sha", "committed_at", "schema_version", "created_at")) + registry.RegisterSchema("SourceCommitEnvelope", dataEnvelopeSchema("#/components/schemas/SourceCommit")) + registry.RegisterSchema("UpsertSourceBranchRequest", objectSchema(map[string]any{ + "repository_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "head_commit_id": map[string]any{"type": "string"}, + "protected": map[string]any{"type": "boolean"}, + "protection_hash": map[string]any{"type": "string"}, + }, "repository_id", "name")) + registry.RegisterSchema("SourceBranch", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "repository_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "head_commit_id": map[string]any{"type": "string"}, + "protected": map[string]any{"type": "boolean"}, + "protection_hash": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "repository_id", "name", "protected", "schema_version", "created_at")) + registry.RegisterSchema("SourceBranchEnvelope", dataEnvelopeSchema("#/components/schemas/SourceBranch")) + registry.RegisterSchema("RecordPullRequestRequest", objectSchema(map[string]any{ + "repository_id": map[string]any{"type": "string"}, + "provider": map[string]any{"type": "string"}, + "provider_id": map[string]any{"type": "string"}, + "title": map[string]any{"type": "string"}, + "state": map[string]any{"type": "string"}, + "source_branch": map[string]any{"type": "string"}, + "target_branch": map[string]any{"type": "string"}, + "head_commit_id": map[string]any{"type": "string"}, + "review_decision": map[string]any{"type": "string"}, + }, "repository_id", "provider", "provider_id", "title", "state")) + registry.RegisterSchema("PullRequest", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "repository_id": map[string]any{"type": "string"}, + "provider": map[string]any{"type": "string"}, + "provider_id": map[string]any{"type": "string"}, + "title": map[string]any{"type": "string"}, + "state": map[string]any{"type": "string"}, + "source_branch": map[string]any{"type": "string"}, + "target_branch": map[string]any{"type": "string"}, + "head_commit_id": map[string]any{"type": "string"}, + "review_decision": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "repository_id", "provider", "provider_id", "title", "state", "schema_version", "created_at")) + registry.RegisterSchema("PullRequestEnvelope", dataEnvelopeSchema("#/components/schemas/PullRequest")) + registry.RegisterSchema("CreateDeploymentEnvironmentRequest", objectSchema(map[string]any{ + "product_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "kind": map[string]any{"type": "string"}, + }, "product_id", "name", "kind")) + registry.RegisterSchema("DeploymentEnvironment", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "kind": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "product_id", "name", "kind", "schema_version", "created_at")) + registry.RegisterSchema("DeploymentEnvironmentEnvelope", dataEnvelopeSchema("#/components/schemas/DeploymentEnvironment")) + registry.RegisterSchema("DeploymentEnvironmentListEnvelope", dataArrayEnvelopeSchema("#/components/schemas/DeploymentEnvironment")) + registry.RegisterSchema("RecordDeploymentRequest", objectSchema(map[string]any{ + "environment_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "artifact_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "status": map[string]any{"type": "string"}, + "started_at": map[string]any{"type": "string", "format": "date-time"}, + "finished_at": map[string]any{"type": "string", "format": "date-time"}, + "rollback_of": map[string]any{"type": "string"}, + }, "environment_id", "release_id", "status", "started_at")) + registry.RegisterSchema("DeploymentEvent", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "environment_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "artifact_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "status": map[string]any{"type": "string"}, + "started_at": map[string]any{"type": "string", "format": "date-time"}, + "finished_at": map[string]any{"type": "string", "format": "date-time"}, + "rollback_of": map[string]any{"type": "string"}, + "evidence_id": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "environment_id", "release_id", "status", "started_at", "schema_version", "created_at")) + registry.RegisterSchema("DeploymentEventEnvelope", dataEnvelopeSchema("#/components/schemas/DeploymentEvent")) + registry.RegisterSchema("DeploymentEventListEnvelope", dataArrayEnvelopeSchema("#/components/schemas/DeploymentEvent")) registry.RegisterSchema("ReadinessReport", objectSchema(map[string]any{ "report_type": map[string]any{"type": "string"}, "template_version": map[string]any{"type": "string"}, diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index b200f94..66c8108 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -443,6 +443,49 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Description = "Lists append-only lifecycle events for a tenant-scoped evidence item." operation.Parameters = append(operation.Parameters, pathParam("id", "Evidence item id.")) operation.Responses[http.StatusOK] = jsonResponse("Evidence lifecycle event list envelope.", "#/components/schemas/EvidenceLifecycleEventListEnvelope") + case "createSourceRepository": + operation.Description = "Creates a tenant-scoped source repository record." + operation.RequestBody = jsonRequest("Source repository creation request.", "#/components/schemas/CreateSourceRepositoryRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created source repository envelope.", "#/components/schemas/SourceRepositoryEnvelope") + case "listSourceRepositories": + operation.Description = "Lists tenant-scoped source repositories, optionally filtered by project." + operation.Parameters = append(operation.Parameters, queryParam("project_id", "Project id.", "string")) + operation.Responses[http.StatusOK] = jsonResponse("Source repository list envelope.", "#/components/schemas/SourceRepositoryListEnvelope") + case "recordSourceCommit": + operation.Description = "Records immutable source commit metadata and stores only a hash of the commit message." + operation.RequestBody = jsonRequest("Source commit creation request.", "#/components/schemas/RecordSourceCommitRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created source commit envelope.", "#/components/schemas/SourceCommitEnvelope") + case "upsertSourceBranch": + operation.Description = "Records or updates source branch metadata and protected-branch snapshot hash." + operation.RequestBody = jsonRequest("Source branch upsert request.", "#/components/schemas/UpsertSourceBranchRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Source branch envelope.", "#/components/schemas/SourceBranchEnvelope") + case "recordPullRequest": + operation.Description = "Records pull-request review metadata linked to source repository evidence." + operation.RequestBody = jsonRequest("Pull request record request.", "#/components/schemas/RecordPullRequestRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created pull request envelope.", "#/components/schemas/PullRequestEnvelope") + case "createDeploymentEnvironment": + operation.Description = "Creates a tenant-scoped deployment environment for release deployment evidence." + operation.RequestBody = jsonRequest("Deployment environment creation request.", "#/components/schemas/CreateDeploymentEnvironmentRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created deployment environment envelope.", "#/components/schemas/DeploymentEnvironmentEnvelope") + case "listDeploymentEnvironments": + operation.Description = "Lists tenant-scoped deployment environments, optionally filtered by product." + operation.Parameters = append(operation.Parameters, queryParam("product_id", "Product id.", "string")) + operation.Responses[http.StatusOK] = jsonResponse("Deployment environment list envelope.", "#/components/schemas/DeploymentEnvironmentListEnvelope") + case "recordDeployment": + operation.Description = "Records append-only deployment evidence for a release/environment/artifact set." + operation.RequestBody = jsonRequest("Deployment event creation request.", "#/components/schemas/RecordDeploymentRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created deployment event envelope.", "#/components/schemas/DeploymentEventEnvelope") + case "listDeployments": + operation.Description = "Lists tenant-scoped deployment events by optional release and environment filters." + operation.Parameters = append(operation.Parameters, + queryParam("release_id", "Release id.", "string"), + queryParam("environment_id", "Deployment environment id.", "string"), + ) + operation.Responses[http.StatusOK] = jsonResponse("Deployment event list envelope.", "#/components/schemas/DeploymentEventListEnvelope") + case "getDeployment": + operation.Description = "Returns a tenant-scoped deployment event by id." + operation.Parameters = append(operation.Parameters, pathParam("id", "Deployment event id.")) + operation.Responses[http.StatusOK] = jsonResponse("Deployment event envelope.", "#/components/schemas/DeploymentEventEnvelope") case "craReadinessReport": operation.Description = "Returns a CRA-oriented readiness report without legal compliance or certification conclusions." operation.Parameters = append(operation.Parameters, diff --git a/openapi.yaml b/openapi.yaml index 31fe697..daefe86 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"operationId":"listDeployments","responses":{"200":{"description":"List deployments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"recordDeployment","responses":{"201":{"description":"Record deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"operationId":"getDeployment","responses":{"200":{"description":"Get deployment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"operationId":"listDeploymentEnvironments","responses":{"200":{"description":"List deployment environments response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"operationId":"createDeploymentEnvironment","responses":{"201":{"description":"Create deployment environment response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"operationId":"upsertSourceBranch","responses":{"201":{"description":"Record source branch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"operationId":"recordSourceCommit","responses":{"201":{"description":"Record source commit response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"operationId":"recordPullRequest","responses":{"201":{"description":"Record pull request response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"operationId":"listSourceRepositories","responses":{"200":{"description":"List source repositories response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"operationId":"createSourceRepository","responses":{"201":{"description":"Create source repository response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/scripts/openapi_precision_check.py b/scripts/openapi_precision_check.py index 55708fd..7ef7a9c 100755 --- a/scripts/openapi_precision_check.py +++ b/scripts/openapi_precision_check.py @@ -42,8 +42,8 @@ def main() -> int: else: broad += 1 - min_precise = int_env("EVYDENCE_OPENAPI_MIN_PRECISE", 98) - max_broad = int_env("EVYDENCE_OPENAPI_MAX_BROAD", 62) + min_precise = int_env("EVYDENCE_OPENAPI_MIN_PRECISE", 108) + max_broad = int_env("EVYDENCE_OPENAPI_MAX_BROAD", 52) if precise < min_precise: print( f"openapi-precision-check: precise operations {precise} below required {min_precise}", From 91696efc68ef3767665217b68e189fa160b15f9e Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 19:14:48 +0300 Subject: [PATCH 074/287] docs: tighten collector openapi contracts --- docs/reference/api-contract-matrix.md | 22 +-- internal/adapters/httpapi/openapi.go | 131 ++++++++++++++++++ .../adapters/httpapi/openapi_operations.go | 39 ++++++ openapi.yaml | 2 +- scripts/openapi_precision_check.py | 4 +- 5 files changed, 184 insertions(+), 14 deletions(-) diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index 6160c1b..d91f041 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 160 operations: 108 precise, 52 broad. +Generated from 160 operations: 118 precise, 42 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -28,14 +28,14 @@ Generated from 160 operations: 108 precise, 52 broad. | POST | /v1/collectors | createCollector | Bearer | collector:admin | required | - | application/json:CreateCollectorRequest | 201:application/json:CollectorCreateEnvelope | precise | | POST | /v1/collectors/github/source-snapshots | uploadGitHubSourceSnapshot | Bearer | source:write | required | - | application/json:SourceSnapshotRequest | 201:application/json:SourceSnapshotEnvelope | precise | | POST | /v1/collectors/gitlab/source-snapshots | uploadGitLabSourceSnapshot | Bearer | source:write | required | - | application/json:SourceSnapshotRequest | 201:application/json:SourceSnapshotEnvelope | precise | -| GET | /v1/collectors/{id}/health | collectorHealthReport | Bearer | collector:read | - | - | - | 200:unspecified | broad | -| POST | /v1/collectors/{id}/releases | recordCollectorRelease | Bearer | collector:admin | required | - | - | 201:unspecified | broad | -| GET | /v1/commercial-collectors | listCommercialCollectors | Bearer | collector:read | - | - | - | 200:unspecified | broad | -| POST | /v1/commercial-collectors | createCommercialCollector | Bearer | collector:admin | required | - | - | 201:unspecified | broad | -| POST | /v1/container-images | registerContainerImage | Bearer | evidence:write | required | - | - | 201:unspecified | broad | +| GET | /v1/collectors/{id}/health | collectorHealthReport | Bearer | collector:read | - | path:id | - | 200:application/json:CollectorHealthReportEnvelope | precise | +| POST | /v1/collectors/{id}/releases | recordCollectorRelease | Bearer | collector:admin | required | path:id | application/json:RecordCollectorReleaseRequest | 201:application/json:CollectorReleaseEnvelope | precise | +| GET | /v1/commercial-collectors | listCommercialCollectors | Bearer | collector:read | - | - | - | 200:application/json:CommercialCollectorDefinitionListEnvelope | precise | +| POST | /v1/commercial-collectors | createCommercialCollector | Bearer | collector:admin | required | - | application/json:CreateCommercialCollectorRequest | 201:application/json:CommercialCollectorDefinitionEnvelope | precise | +| POST | /v1/container-images | registerContainerImage | Bearer | evidence:write | required | - | application/json:RegisterContainerImageRequest | 201:application/json:ContainerImageEnvelope | precise | | GET | /v1/control-evidence | listControlEvidence | Bearer | controls:read | - | query:control_id, query:product_id, query:release_id | - | 200:application/json:ControlEvidenceListEnvelope | precise | -| GET | /v1/control-framework-template-packs | listControlFrameworkTemplatePacks | Bearer | controls:read | - | - | - | 200:unspecified | broad | -| POST | /v1/control-framework-template-packs/{slug}/install | installControlFrameworkTemplatePack | Bearer | controls:admin | required | - | - | 201:unspecified | broad | +| GET | /v1/control-framework-template-packs | listControlFrameworkTemplatePacks | Bearer | controls:read | - | - | - | 200:application/json:ControlFrameworkTemplatePackListEnvelope | precise | +| POST | /v1/control-framework-template-packs/{slug}/install | installControlFrameworkTemplatePack | Bearer | controls:admin | required | path:slug | application/json:EmptyObject | 201:application/json:ControlFrameworkEnvelope | precise | | GET | /v1/control-frameworks | listControlFrameworks | Bearer | controls:read | - | - | - | 200:application/json:ControlFrameworkListEnvelope | precise | | POST | /v1/control-frameworks | createControlFramework | Bearer | controls:admin | required | - | application/json:CreateControlFrameworkRequest | 201:application/json:ControlFrameworkEnvelope | precise | | POST | /v1/controls | createSecurityControl | Bearer | controls:admin | required | - | application/json:CreateSecurityControlRequest | 201:application/json:SecurityControlEnvelope | precise | @@ -76,9 +76,9 @@ Generated from 160 operations: 108 precise, 52 broad. | POST | /v1/incidents/{id}/timeline | recordIncidentTimeline | Bearer | incident:write | required | - | - | 201:unspecified | broad | | POST | /v1/incidents/{id}/webhook-receivers | createIncidentWebhookReceiver | Bearer | incident:write | required | path:id | application/json:DataEnvelope | 201:application/json:DataEnvelope | broad | | POST | /v1/legal-holds | createLegalHold | Bearer | admin | required | - | - | 201:unspecified | broad | -| GET | /v1/marketplace-collectors | listMarketplaceCollectors | Bearer | collector:read | - | - | - | 200:unspecified | broad | -| POST | /v1/marketplace-collectors | createMarketplaceCollector | Bearer | collector:admin | required | - | - | 201:unspecified | broad | -| GET | /v1/marketplace-collectors/{id}/health | marketplaceCollectorHealth | Bearer | collector:read | - | - | - | 200:unspecified | broad | +| GET | /v1/marketplace-collectors | listMarketplaceCollectors | Bearer | collector:read | - | - | - | 200:application/json:MarketplaceCollectorListEnvelope | precise | +| POST | /v1/marketplace-collectors | createMarketplaceCollector | Bearer | collector:admin | required | - | application/json:CreateMarketplaceCollectorRequest | 201:application/json:MarketplaceCollectorEnvelope | precise | +| GET | /v1/marketplace-collectors/{id}/health | marketplaceCollectorHealth | Bearer | collector:read | - | path:id | - | 200:application/json:MarketplaceCollectorHealthReportEnvelope | precise | | POST | /v1/merkle-batches | createMerkleBatch | Bearer | keys:admin | required | - | - | 201:unspecified | broad | | GET | /v1/merkle-batches/{id}/verify | verifyMerkleBatch | Bearer | verify:read | - | - | - | 200:unspecified | broad | | GET | /v1/metrics | metrics | Bearer | admin | - | - | - | 200:application/json:MetricsSnapshotEnvelope,text/plain:string | precise | diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 9d37d3a..3767ae4 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -683,6 +683,137 @@ func registerCriticalSchemas(registry *specs.Registry) { }, "id", "tenant_id", "environment_id", "release_id", "status", "started_at", "schema_version", "created_at")) registry.RegisterSchema("DeploymentEventEnvelope", dataEnvelopeSchema("#/components/schemas/DeploymentEvent")) registry.RegisterSchema("DeploymentEventListEnvelope", dataArrayEnvelopeSchema("#/components/schemas/DeploymentEvent")) + registry.RegisterSchema("RecordCollectorReleaseRequest", objectSchema(map[string]any{ + "version": map[string]any{"type": "string"}, + "artifact_digest": map[string]any{"type": "string"}, + "signature_id": map[string]any{"type": "string"}, + "sbom_id": map[string]any{"type": "string"}, + "scan_id": map[string]any{"type": "string"}, + "pinned": map[string]any{"type": "boolean"}, + }, "version", "artifact_digest")) + registry.RegisterSchema("CollectorRelease", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "collector_id": map[string]any{"type": "string"}, + "version": map[string]any{"type": "string"}, + "artifact_digest": map[string]any{"type": "string"}, + "signature_id": map[string]any{"type": "string"}, + "sbom_id": map[string]any{"type": "string"}, + "scan_id": map[string]any{"type": "string"}, + "pinned": map[string]any{"type": "boolean"}, + "verification_status": map[string]any{"type": "string"}, + "health_status": map[string]any{"type": "string"}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "collector_id", "version", "artifact_digest", "pinned", "verification_status", "health_status", "schema_version", "created_at")) + registry.RegisterSchema("CollectorReleaseEnvelope", dataEnvelopeSchema("#/components/schemas/CollectorRelease")) + registry.RegisterSchema("CollectorHealthReport", objectSchema(map[string]any{ + "report_type": map[string]any{"type": "string"}, + "collector_id": map[string]any{"type": "string"}, + "collector_status": map[string]any{"type": "string"}, + "version": map[string]any{"type": "string"}, + "pinned_release_id": map[string]any{"type": "string"}, + "supply_chain_status": map[string]any{"type": "string"}, + "checks": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/VerifyCheck"}}, + "latest_release": map[string]any{"$ref": "#/components/schemas/CollectorRelease"}, + "assumptions": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "generated_at": map[string]any{"type": "string", "format": "date-time"}, + }, "report_type", "collector_id", "collector_status", "supply_chain_status", "checks", "assumptions", "limitations", "generated_at")) + registry.RegisterSchema("CollectorHealthReportEnvelope", dataEnvelopeSchema("#/components/schemas/CollectorHealthReport")) + registry.RegisterSchema("CreateCommercialCollectorRequest", objectSchema(map[string]any{ + "name": map[string]any{"type": "string"}, + "provider": map[string]any{"type": "string"}, + "version": map[string]any{"type": "string"}, + "manifest_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "allowed_scopes": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + }, "name", "provider", "version", "manifest_hash")) + registry.RegisterSchema("CommercialCollectorDefinition", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "provider": map[string]any{"type": "string"}, + "version": map[string]any{"type": "string"}, + "manifest_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "allowed_scopes": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "status": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "name", "provider", "version", "manifest_hash", "allowed_scopes", "status", "schema_version", "created_at")) + registry.RegisterSchema("CommercialCollectorDefinitionEnvelope", dataEnvelopeSchema("#/components/schemas/CommercialCollectorDefinition")) + registry.RegisterSchema("CommercialCollectorDefinitionListEnvelope", dataArrayEnvelopeSchema("#/components/schemas/CommercialCollectorDefinition")) + registry.RegisterSchema("CreateMarketplaceCollectorRequest", objectSchema(map[string]any{ + "name": map[string]any{"type": "string"}, + "provider": map[string]any{"type": "string"}, + "version": map[string]any{"type": "string"}, + "publisher": map[string]any{"type": "string"}, + "manifest_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "signature_id": map[string]any{"type": "string"}, + "sbom_id": map[string]any{"type": "string"}, + "scan_id": map[string]any{"type": "string"}, + }, "name", "provider", "version", "publisher", "manifest_hash")) + registry.RegisterSchema("MarketplaceCollector", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "provider": map[string]any{"type": "string"}, + "version": map[string]any{"type": "string"}, + "publisher": map[string]any{"type": "string"}, + "manifest_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "signature_id": map[string]any{"type": "string"}, + "sbom_id": map[string]any{"type": "string"}, + "scan_id": map[string]any{"type": "string"}, + "state": map[string]any{"type": "string"}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "name", "provider", "version", "publisher", "manifest_hash", "state", "schema_version", "created_at")) + registry.RegisterSchema("MarketplaceCollectorEnvelope", dataEnvelopeSchema("#/components/schemas/MarketplaceCollector")) + registry.RegisterSchema("MarketplaceCollectorListEnvelope", dataArrayEnvelopeSchema("#/components/schemas/MarketplaceCollector")) + registry.RegisterSchema("MarketplaceCollectorHealthReport", objectSchema(map[string]any{ + "report_type": map[string]any{"type": "string"}, + "collector_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "provider": map[string]any{"type": "string"}, + "version": map[string]any{"type": "string"}, + "supply_chain_status": map[string]any{"type": "string"}, + "checks": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/VerifyCheck"}}, + "collector": map[string]any{"$ref": "#/components/schemas/MarketplaceCollector"}, + "assumptions": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "generated_at": map[string]any{"type": "string", "format": "date-time"}, + }, "report_type", "collector_id", "name", "provider", "version", "supply_chain_status", "checks", "collector", "assumptions", "limitations", "generated_at")) + registry.RegisterSchema("MarketplaceCollectorHealthReportEnvelope", dataEnvelopeSchema("#/components/schemas/MarketplaceCollectorHealthReport")) + registry.RegisterSchema("ControlFrameworkTemplatePack", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "slug": map[string]any{"type": "string"}, + "version": map[string]any{"type": "string"}, + "description": map[string]any{"type": "string"}, + "controls": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/SecurityControl"}}, + "schema_version": map[string]any{"type": "string"}, + }, "id", "name", "slug", "version", "controls", "schema_version")) + registry.RegisterSchema("ControlFrameworkTemplatePackListEnvelope", dataArrayEnvelopeSchema("#/components/schemas/ControlFrameworkTemplatePack")) + registry.RegisterSchema("RegisterContainerImageRequest", objectSchema(map[string]any{ + "artifact_id": map[string]any{"type": "string"}, + "repository": map[string]any{"type": "string"}, + "tag": map[string]any{"type": "string"}, + "digest": map[string]any{"type": "string"}, + "platform": map[string]any{"type": "string"}, + }, "repository", "digest")) + registry.RegisterSchema("ContainerImage", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "artifact_id": map[string]any{"type": "string"}, + "repository": map[string]any{"type": "string"}, + "tag": map[string]any{"type": "string"}, + "digest": map[string]any{"type": "string"}, + "platform": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "repository", "digest", "schema_version", "created_at")) + registry.RegisterSchema("ContainerImageEnvelope", dataEnvelopeSchema("#/components/schemas/ContainerImage")) registry.RegisterSchema("ReadinessReport", objectSchema(map[string]any{ "report_type": map[string]any{"type": "string"}, "template_version": map[string]any{"type": "string"}, diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 66c8108..5971ef9 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -486,6 +486,45 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Description = "Returns a tenant-scoped deployment event by id." operation.Parameters = append(operation.Parameters, pathParam("id", "Deployment event id.")) operation.Responses[http.StatusOK] = jsonResponse("Deployment event envelope.", "#/components/schemas/DeploymentEventEnvelope") + case "recordCollectorRelease": + operation.Description = "Records collector release supply-chain evidence for a tenant-scoped collector." + operation.Parameters = append(operation.Parameters, pathParam("id", "Collector id.")) + operation.RequestBody = jsonRequest("Collector release record request.", "#/components/schemas/RecordCollectorReleaseRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created collector release envelope.", "#/components/schemas/CollectorReleaseEnvelope") + case "collectorHealthReport": + operation.Description = "Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations." + operation.Parameters = append(operation.Parameters, pathParam("id", "Collector id.")) + operation.Responses[http.StatusOK] = jsonResponse("Collector health report envelope.", "#/components/schemas/CollectorHealthReportEnvelope") + case "createCommercialCollector": + operation.Description = "Creates tenant-scoped commercial collector metadata without installing external code." + operation.RequestBody = jsonRequest("Commercial collector definition request.", "#/components/schemas/CreateCommercialCollectorRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created commercial collector definition envelope.", "#/components/schemas/CommercialCollectorDefinitionEnvelope") + case "listCommercialCollectors": + operation.Description = "Lists tenant-scoped commercial collector definitions." + operation.Responses[http.StatusOK] = jsonResponse("Commercial collector definition list envelope.", "#/components/schemas/CommercialCollectorDefinitionListEnvelope") + case "createMarketplaceCollector": + operation.Description = "Creates tenant-scoped marketplace collector package metadata and evidence references." + operation.RequestBody = jsonRequest("Marketplace collector creation request.", "#/components/schemas/CreateMarketplaceCollectorRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created marketplace collector envelope.", "#/components/schemas/MarketplaceCollectorEnvelope") + case "listMarketplaceCollectors": + operation.Description = "Lists tenant-scoped marketplace collector package metadata." + operation.Responses[http.StatusOK] = jsonResponse("Marketplace collector list envelope.", "#/components/schemas/MarketplaceCollectorListEnvelope") + case "marketplaceCollectorHealth": + operation.Description = "Returns marketplace collector package health from recorded signature, SBOM, and scan evidence." + operation.Parameters = append(operation.Parameters, pathParam("id", "Marketplace collector id.")) + operation.Responses[http.StatusOK] = jsonResponse("Marketplace collector health report envelope.", "#/components/schemas/MarketplaceCollectorHealthReportEnvelope") + case "listControlFrameworkTemplatePacks": + operation.Description = "Lists built-in control framework template packs available for explicit tenant installation." + operation.Responses[http.StatusOK] = jsonResponse("Control framework template pack list envelope.", "#/components/schemas/ControlFrameworkTemplatePackListEnvelope") + case "installControlFrameworkTemplatePack": + operation.Description = "Installs a named control framework template pack into the tenant as ordinary framework/control records." + operation.Parameters = append(operation.Parameters, pathParam("slug", "Control framework template pack slug.")) + operation.RequestBody = jsonRequest("Empty JSON object.", "#/components/schemas/EmptyObject") + operation.Responses[http.StatusCreated] = jsonResponse("Installed control framework envelope.", "#/components/schemas/ControlFrameworkEnvelope") + case "registerContainerImage": + operation.Description = "Registers OCI/container image metadata and digest evidence linked to an optional artifact." + operation.RequestBody = jsonRequest("Container image registration request.", "#/components/schemas/RegisterContainerImageRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Registered container image envelope.", "#/components/schemas/ContainerImageEnvelope") case "craReadinessReport": operation.Description = "Returns a CRA-oriented readiness report without legal compliance or certification conclusions." operation.Parameters = append(operation.Parameters, diff --git a/openapi.yaml b/openapi.yaml index daefe86..b1c0ffe 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"operationId":"collectorHealthReport","responses":{"200":{"description":"Collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"operationId":"recordCollectorRelease","responses":{"201":{"description":"Record collector release evidence response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"operationId":"listCommercialCollectors","responses":{"200":{"description":"List commercial collector definitions response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createCommercialCollector","responses":{"201":{"description":"Create commercial collector definition response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"operationId":"registerContainerImage","responses":{"201":{"description":"Register container image response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"description":"List control framework template packs response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"operationId":"installControlFrameworkTemplatePack","responses":{"201":{"description":"Install control framework template pack response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"operationId":"listMarketplaceCollectors","responses":{"200":{"description":"List marketplace collector records response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"operationId":"createMarketplaceCollector","responses":{"201":{"description":"Create marketplace collector record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"operationId":"marketplaceCollectorHealth","responses":{"200":{"description":"Marketplace collector health report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/scripts/openapi_precision_check.py b/scripts/openapi_precision_check.py index 7ef7a9c..69c1453 100755 --- a/scripts/openapi_precision_check.py +++ b/scripts/openapi_precision_check.py @@ -42,8 +42,8 @@ def main() -> int: else: broad += 1 - min_precise = int_env("EVYDENCE_OPENAPI_MIN_PRECISE", 108) - max_broad = int_env("EVYDENCE_OPENAPI_MAX_BROAD", 52) + min_precise = int_env("EVYDENCE_OPENAPI_MIN_PRECISE", 118) + max_broad = int_env("EVYDENCE_OPENAPI_MAX_BROAD", 42) if precise < min_precise: print( f"openapi-precision-check: precise operations {precise} below required {min_precise}", From f1e79794f4a76fac79981a1b93f36b86916d3b8f Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 19:21:49 +0300 Subject: [PATCH 075/287] docs: tighten package report openapi contracts --- docs/reference/api-contract-matrix.md | 32 +-- internal/adapters/httpapi/openapi.go | 237 ++++++++++++++++++ .../adapters/httpapi/openapi_operations.go | 62 ++++- openapi.yaml | 2 +- scripts/openapi_precision_check.py | 4 +- 5 files changed, 317 insertions(+), 20 deletions(-) diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index d91f041..4b16dd2 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 160 operations: 118 precise, 42 broad. +Generated from 160 operations: 133 precise, 27 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -43,11 +43,11 @@ Generated from 160 operations: 118 precise, 42 broad. | POST | /v1/controls/{id}/evidence | linkControlEvidence | Bearer | controls:write | required | path:id | application/json:LinkControlEvidenceRequest | 201:application/json:ControlEvidenceEnvelope | precise | | POST | /v1/custom-policies | createCustomPolicy | Bearer | policy:write | required | - | application/json:CreateCustomPolicyRequest | 201:application/json:CustomPolicyEnvelope | precise | | POST | /v1/custom-policies/{id}/evaluate | evaluateCustomPolicy | Bearer | policy:read | required | path:id | application/json:EvaluatePolicyRequest | 201:application/json:CustomPolicyEvaluationEnvelope | precise | -| POST | /v1/customer-packages | createCustomerPackage | Bearer | package:write | required | - | - | 201:unspecified | broad | -| GET | /v1/customer-packages/{id} | getCustomerPackage | Bearer | package:read | - | - | - | 200:unspecified | broad | +| POST | /v1/customer-packages | createCustomerPackage | Bearer | package:write | required | - | application/json:CreateCustomerPackageRequest | 201:application/json:CustomerSecurityPackageEnvelope | precise | +| GET | /v1/customer-packages/{id} | getCustomerPackage | Bearer | package:read | - | path:id | - | 200:application/json:CustomerSecurityPackageEnvelope | precise | | GET | /v1/customer-packages/{id}/download | downloadCustomerPackage | Bearer | package:read | - | path:id | - | 200:application/zip:string/binary | precise | | POST | /v1/customer-portal/access | createCustomerPortalAccess | Bearer | package:write | required | - | application/json:CreateCustomerPortalAccessRequest | 201:application/json:CustomerPortalAccessCreateEnvelope | precise | -| POST | /v1/customer-portal/package | accessCustomerPortalPackage | public | - | not required | - | application/json:CustomerPortalPackageRequest | 200:application/json:DataEnvelope | broad | +| POST | /v1/customer-portal/package | accessCustomerPortalPackage | public | - | not required | - | application/json:CustomerPortalPackageRequest | 200:application/json:CustomerSecurityPackageEnvelope | precise | | POST | /v1/customer-portal/package/download | downloadCustomerPortalPackage | public | - | not required | - | application/json:CustomerPortalPackageRequest | 200:application/zip:string/binary | precise | | GET | /v1/deployments | listDeployments | Bearer | deployment:read | - | query:environment_id, query:release_id | - | 200:application/json:DeploymentEventListEnvelope | precise | | POST | /v1/deployments | recordDeployment | Bearer | deployment:write | required | - | application/json:RecordDeploymentRequest | 201:application/json:DeploymentEventEnvelope | precise | @@ -57,10 +57,10 @@ Generated from 160 operations: 118 precise, 42 broad. | POST | /v1/environments | createDeploymentEnvironment | Bearer | deployment:write | required | - | application/json:CreateDeploymentEnvironmentRequest | 201:application/json:DeploymentEnvironmentEnvelope | precise | | GET | /v1/evidence | listEvidence | Bearer | evidence:read | - | query:release_id, query:type | - | 200:application/json:EvidenceItemListEnvelope | precise | | POST | /v1/evidence | createEvidence | Bearer | evidence:write | required | - | application/json:CreateEvidenceRequest | 201:application/json:EvidenceItemEnvelope | precise | -| POST | /v1/evidence-bundles | exportEvidenceBundle | Bearer | bundle:read | required | - | - | 201:unspecified | broad | -| POST | /v1/evidence-bundles/import | importEvidenceBundle | Bearer | bundle:write | required | - | - | 201:unspecified | broad | +| POST | /v1/evidence-bundles | exportEvidenceBundle | Bearer | bundle:read | required | - | application/json:ExportEvidenceBundleRequest | 201:application/json:EvidenceBundleEnvelope | precise | +| POST | /v1/evidence-bundles/import | importEvidenceBundle | Bearer | bundle:write | required | - | application/json:EvidenceBundle | 201:application/json:EvidenceBundleImportEnvelope | precise | | POST | /v1/evidence-graph-snapshots | createGraphSnapshot | Bearer | evidence:read | required | - | application/json:CreateGraphSnapshotRequest | 201:application/json:EvidenceGraphSnapshotEnvelope | precise | -| POST | /v1/evidence-summaries | createEvidenceSummary | Bearer | report:read | required | - | - | 201:unspecified | broad | +| POST | /v1/evidence-summaries | createEvidenceSummary | Bearer | report:read | required | - | application/json:CreateEvidenceSummaryRequest | 201:application/json:EvidenceSummaryEnvelope | precise | | GET | /v1/evidence/search | searchEvidence | Bearer | evidence:read | - | query:cursor, query:limit, query:product_id, query:project_id, query:release_id, query:source, query:tag, query:type | - | 200:application/json:EvidenceSearchEnvelope | precise | | GET | /v1/evidence/{id} | getEvidence | Bearer | evidence:read | - | path:id | - | 200:application/json:EvidenceItemEnvelope | precise | | GET | /v1/evidence/{id}/lifecycle-events | listEvidenceLifecycleEvents | Bearer | evidence:read | - | path:id | - | 200:application/json:EvidenceLifecycleEventListEnvelope | precise | @@ -96,11 +96,11 @@ Generated from 160 operations: 118 precise, 42 broad. | POST | /v1/provider-verifications | verifyProviderIdentity | Bearer | identity:admin | required | - | application/json:VerifyProviderIdentityRequest | 201:application/json:ProviderVerificationEnvelope | precise | | POST | /v1/public-transparency-log-entries | publishPublicTransparencyLogEntry | Bearer | keys:admin | required | - | - | 201:unspecified | broad | | POST | /v1/public-transparency-logs | createPublicTransparencyLog | Bearer | keys:admin | required | - | - | 201:unspecified | broad | -| POST | /v1/questionnaire-drafts | createQuestionnaireDraft | Bearer | package:read | required | - | - | 201:unspecified | broad | -| POST | /v1/questionnaire-packages | createQuestionnairePackage | Bearer | package:write | required | - | - | 201:unspecified | broad | -| POST | /v1/questionnaire-templates | createQuestionnaireTemplate | Bearer | package:write | required | - | - | 201:unspecified | broad | +| POST | /v1/questionnaire-drafts | createQuestionnaireDraft | Bearer | package:read | required | - | application/json:CreateQuestionnaireDraftRequest | 201:application/json:QuestionnaireDraftEnvelope | precise | +| POST | /v1/questionnaire-packages | createQuestionnairePackage | Bearer | package:write | required | - | application/json:CreateQuestionnairePackageRequest | 201:application/json:QuestionnairePackageEnvelope | precise | +| POST | /v1/questionnaire-templates | createQuestionnaireTemplate | Bearer | package:write | required | - | application/json:CreateQuestionnaireTemplateRequest | 201:application/json:QuestionnaireTemplateEnvelope | precise | | GET | /v1/ready | ready | public | - | - | - | - | 200:application/json:ReadinessStatusEnvelope | precise | -| POST | /v1/redaction-profiles | createRedactionProfile | Bearer | package:write | required | - | - | 201:unspecified | broad | +| POST | /v1/redaction-profiles | createRedactionProfile | Bearer | package:write | required | - | application/json:CreateRedactionProfileRequest | 201:application/json:RedactionProfileEnvelope | precise | | POST | /v1/release-bundles | createReleaseBundle | Bearer | bundle:write | required | - | application/json:CreateReleaseBundleRequest | 201:application/json:ReleaseBundleEnvelope | precise | | GET | /v1/release-bundles/{id} | getReleaseBundle | Bearer | bundle:read | - | path:id | - | 200:application/json:ReleaseBundleEnvelope | precise | | GET | /v1/release-bundles/{id}/manifest | getReleaseBundleManifest | Bearer | bundle:read | - | path:id | - | 200:application/json:ReleaseBundleManifestEnvelope | precise | @@ -115,18 +115,18 @@ Generated from 160 operations: 118 precise, 42 broad. | POST | /v1/releases/{id}/approve | approveRelease | Bearer | release:write | required | path:id | application/json:EmptyObject | 200:application/json:ReleaseEnvelope | precise | | POST | /v1/releases/{id}/freeze | freezeRelease | Bearer | release:write | required | path:id | application/json:EmptyObject | 200:application/json:ReleaseEnvelope | precise | | POST | /v1/remediation-tasks | createRemediationTask | Bearer | incident:write | required | - | - | 201:unspecified | broad | -| POST | /v1/report-templates | createReportTemplate | Bearer | report:read | required | - | - | 201:unspecified | broad | -| POST | /v1/report-templates/{id}/render | renderReportTemplate | Bearer | report:read | required | - | - | 201:unspecified | broad | +| POST | /v1/report-templates | createReportTemplate | Bearer | report:read | required | - | application/json:CreateReportTemplateRequest | 201:application/json:CustomReportTemplateEnvelope | precise | +| POST | /v1/report-templates/{id}/render | renderReportTemplate | Bearer | report:read | required | path:id | application/json:RenderReportTemplateRequest | 201:application/json:RenderedCustomReportEnvelope | precise | | POST | /v1/reports/anomaly | generateAnomalyReport | Bearer | report:read | required | - | - | 201:unspecified | broad | | GET | /v1/reports/control-coverage | controlCoverageReport | Bearer | report:read | - | query:framework_id, query:product_id, query:release_id | - | 200:application/json:ReadinessReportEnvelope | precise | | GET | /v1/reports/cra-readiness | craReadinessReport | Bearer | report:read | - | query:product_id, query:release_id | - | 200:application/json:ReadinessReportEnvelope | precise | -| GET | /v1/reports/cra-readiness-html | craReadinessHTMLPackage | Bearer | report:read | - | - | - | 200:unspecified | broad | +| GET | /v1/reports/cra-readiness-html | craReadinessHTMLPackage | Bearer | report:read | - | query:product_id, query:release_id | - | 200:application/json:HTMLReportPackageEnvelope | precise | | GET | /v1/reports/incident-package | incidentReport | Bearer | incident:read | - | - | - | 200:unspecified | broad | | GET | /v1/reports/missing-evidence | missingEvidenceReport | Bearer | verify:read | - | query:release_id | - | 200:application/json:MissingEvidenceReportEnvelope | precise | -| POST | /v1/reports/pdf | createPDFReportPackage | Bearer | report:read | required | - | - | 201:unspecified | broad | +| POST | /v1/reports/pdf | createPDFReportPackage | Bearer | report:read | required | - | application/json:CreatePDFReportPackageRequest | 201:application/json:PDFReportPackageEnvelope | precise | | GET | /v1/reports/release-readiness | releaseReadinessReport | Bearer | verify:read | - | query:release_id | - | 200:application/json:ReadinessReportEnvelope | precise | | GET | /v1/reports/retention | retentionReport | Bearer | admin | - | - | - | 200:unspecified | broad | -| GET | /v1/reports/security-review-package | securityReviewPackageReport | Bearer | package:read | - | - | - | 200:unspecified | broad | +| GET | /v1/reports/security-review-package | securityReviewPackageReport | Bearer | package:read | - | query:package_id | - | 200:application/json:SecurityReviewPackageReportEnvelope | precise | | GET | /v1/reports/vulnerability-posture | vulnerabilityPostureReport | Bearer | security:read | - | - | - | 200:unspecified | broad | | POST | /v1/retention-overrides | createRetentionOverride | Bearer | admin | required | - | - | 201:unspecified | broad | | GET | /v1/role-bindings | listRoleBindings | Bearer | identity:admin | - | - | - | 200:application/json:RoleBindingListEnvelope | precise | diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 3767ae4..1acd7e6 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -814,6 +814,243 @@ func registerCriticalSchemas(registry *specs.Registry) { "created_at": map[string]any{"type": "string", "format": "date-time"}, }, "id", "tenant_id", "repository", "digest", "schema_version", "created_at")) registry.RegisterSchema("ContainerImageEnvelope", dataEnvelopeSchema("#/components/schemas/ContainerImage")) + registry.RegisterSchema("CreateRedactionProfileRequest", objectSchema(map[string]any{ + "name": map[string]any{"type": "string"}, + "description": map[string]any{"type": "string"}, + "allowed_types": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "excluded_fields": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + }, "name")) + registry.RegisterSchema("RedactionProfile", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "description": map[string]any{"type": "string"}, + "allowed_types": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "excluded_fields": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "name", "schema_version", "created_at")) + registry.RegisterSchema("RedactionProfileEnvelope", dataEnvelopeSchema("#/components/schemas/RedactionProfile")) + registry.RegisterSchema("CreateCustomerPackageRequest", objectSchema(map[string]any{ + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "redaction_profile_id": map[string]any{"type": "string"}, + "title": map[string]any{"type": "string"}, + "expires_at": map[string]any{"type": "string", "format": "date-time"}, + }, "product_id", "redaction_profile_id", "title", "expires_at")) + registry.RegisterSchema("CustomerSecurityPackage", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "redaction_profile_id": map[string]any{"type": "string"}, + "title": map[string]any{"type": "string"}, + "state": map[string]any{"type": "string"}, + "manifest": map[string]any{"type": "object", "additionalProperties": true}, + "manifest_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "expires_at": map[string]any{"type": "string", "format": "date-time"}, + "access_count": map[string]any{"type": "integer"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "product_id", "redaction_profile_id", "title", "state", "manifest", "manifest_hash", "expires_at", "access_count", "schema_version", "created_at")) + registry.RegisterSchema("CustomerSecurityPackageEnvelope", dataEnvelopeSchema("#/components/schemas/CustomerSecurityPackage")) + registry.RegisterSchema("SecurityReviewPackageReport", objectSchema(map[string]any{ + "report_type": map[string]any{"type": "string"}, + "template_version": map[string]any{"type": "string"}, + "package_id": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "evidence_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "assumptions": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "generated_at": map[string]any{"type": "string", "format": "date-time"}, + }, "report_type", "template_version", "package_id", "product_id", "evidence_ids", "assumptions", "limitations", "generated_at")) + registry.RegisterSchema("SecurityReviewPackageReportEnvelope", dataEnvelopeSchema("#/components/schemas/SecurityReviewPackageReport")) + registry.RegisterSchema("HTMLReportPackage", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "report_type": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "html": map[string]any{"type": "string"}, + "hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "report_type", "product_id", "html", "hash", "schema_version", "created_at")) + registry.RegisterSchema("HTMLReportPackageEnvelope", dataEnvelopeSchema("#/components/schemas/HTMLReportPackage")) + registry.RegisterSchema("CreateReportTemplateRequest", objectSchema(map[string]any{ + "name": map[string]any{"type": "string"}, + "version": map[string]any{"type": "string"}, + "report_type": map[string]any{"type": "string"}, + "allowed_fields": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "template": map[string]any{"type": "string"}, + }, "name", "version", "report_type", "allowed_fields", "template")) + registry.RegisterSchema("CustomReportTemplate", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "version": map[string]any{"type": "string"}, + "report_type": map[string]any{"type": "string"}, + "allowed_fields": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "template": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "name", "version", "report_type", "allowed_fields", "template", "schema_version", "created_at")) + registry.RegisterSchema("CustomReportTemplateEnvelope", dataEnvelopeSchema("#/components/schemas/CustomReportTemplate")) + registry.RegisterSchema("RenderReportTemplateRequest", objectSchema(map[string]any{ + "subject_type": map[string]any{"type": "string"}, + "subject_id": map[string]any{"type": "string"}, + }, "subject_type", "subject_id")) + registry.RegisterSchema("RenderedCustomReport", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "template_id": map[string]any{"type": "string"}, + "subject_type": map[string]any{"type": "string"}, + "subject_id": map[string]any{"type": "string"}, + "output": map[string]any{"type": "object", "additionalProperties": true}, + "hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "template_id", "subject_type", "subject_id", "output", "hash", "schema_version", "created_at")) + registry.RegisterSchema("RenderedCustomReportEnvelope", dataEnvelopeSchema("#/components/schemas/RenderedCustomReport")) + registry.RegisterSchema("ExportEvidenceBundleRequest", objectSchema(map[string]any{ + "release_id": map[string]any{"type": "string"}, + "evidence_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + })) + registry.RegisterSchema("EvidenceBundle", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "evidence_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "manifest": map[string]any{"type": "object", "additionalProperties": true}, + "manifest_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "signature_refs": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "verification_text": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "evidence_ids", "manifest", "manifest_hash", "verification_text", "schema_version", "created_at")) + registry.RegisterSchema("EvidenceBundleEnvelope", dataEnvelopeSchema("#/components/schemas/EvidenceBundle")) + registry.RegisterSchema("EvidenceBundleImport", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "bundle_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "result": map[string]any{"type": "string"}, + "imported_count": map[string]any{"type": "integer"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "bundle_hash", "result", "imported_count", "schema_version", "created_at")) + registry.RegisterSchema("EvidenceBundleImportEnvelope", dataEnvelopeSchema("#/components/schemas/EvidenceBundleImport")) + registry.RegisterSchema("CreateEvidenceSummaryRequest", objectSchema(map[string]any{ + "subject_type": map[string]any{"type": "string"}, + "subject_id": map[string]any{"type": "string"}, + "evidence_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + }, "subject_type", "subject_id", "evidence_ids")) + registry.RegisterSchema("EvidenceCitation", objectSchema(map[string]any{ + "evidence_id": map[string]any{"type": "string"}, + "type": map[string]any{"type": "string"}, + "title": map[string]any{"type": "string"}, + "canonical_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + }, "evidence_id", "type", "title", "canonical_hash")) + registry.RegisterSchema("EvidenceSummary", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "subject_type": map[string]any{"type": "string"}, + "subject_id": map[string]any{"type": "string"}, + "evidence_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "summary": map[string]any{"type": "string"}, + "citations": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/EvidenceCitation"}}, + "assumptions": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "subject_type", "subject_id", "evidence_ids", "summary", "citations", "assumptions", "limitations", "schema_version", "created_at")) + registry.RegisterSchema("EvidenceSummaryEnvelope", dataEnvelopeSchema("#/components/schemas/EvidenceSummary")) + registry.RegisterSchema("QuestionnaireQuestion", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "prompt": map[string]any{"type": "string"}, + "evidence_type": map[string]any{"type": "string"}, + "control_id": map[string]any{"type": "string"}, + "allowed_fields": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + }, "id", "prompt")) + registry.RegisterSchema("QuestionnaireResponse", objectSchema(map[string]any{ + "question_id": map[string]any{"type": "string"}, + "answer": map[string]any{"type": "string"}, + "evidence_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + }, "question_id", "answer")) + registry.RegisterSchema("CreateQuestionnaireTemplateRequest", objectSchema(map[string]any{ + "name": map[string]any{"type": "string"}, + "version": map[string]any{"type": "string"}, + "questions": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/QuestionnaireQuestion"}}, + }, "name", "version", "questions")) + registry.RegisterSchema("QuestionnaireTemplate", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "version": map[string]any{"type": "string"}, + "questions": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/QuestionnaireQuestion"}}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "name", "version", "questions", "schema_version", "created_at")) + registry.RegisterSchema("QuestionnaireTemplateEnvelope", dataEnvelopeSchema("#/components/schemas/QuestionnaireTemplate")) + registry.RegisterSchema("CreateQuestionnairePackageRequest", objectSchema(map[string]any{ + "template_id": map[string]any{"type": "string"}, + "package_id": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + }, "template_id")) + registry.RegisterSchema("QuestionnairePackage", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "template_id": map[string]any{"type": "string"}, + "package_id": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "responses": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/QuestionnaireResponse"}}, + "manifest_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "template_id", "responses", "manifest_hash", "schema_version", "created_at")) + registry.RegisterSchema("QuestionnairePackageEnvelope", dataEnvelopeSchema("#/components/schemas/QuestionnairePackage")) + registry.RegisterSchema("CreateQuestionnaireDraftRequest", objectSchema(map[string]any{ + "template_id": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + }, "template_id")) + registry.RegisterSchema("QuestionnaireDraft", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "template_id": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "responses": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/QuestionnaireResponse"}}, + "manifest_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "template_id", "responses", "manifest_hash", "limitations", "schema_version", "created_at")) + registry.RegisterSchema("QuestionnaireDraftEnvelope", dataEnvelopeSchema("#/components/schemas/QuestionnaireDraft")) + registry.RegisterSchema("CreatePDFReportPackageRequest", objectSchema(map[string]any{ + "report_type": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "title": map[string]any{"type": "string"}, + }, "report_type", "title")) + registry.RegisterSchema("PDFReportPackage", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "report_type": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "title": map[string]any{"type": "string"}, + "payload_ref": map[string]any{"type": "string"}, + "payload_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "payload_size": map[string]any{"type": "integer"}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "report_type", "title", "payload_hash", "payload_size", "limitations", "schema_version", "created_at")) + registry.RegisterSchema("PDFReportPackageEnvelope", dataEnvelopeSchema("#/components/schemas/PDFReportPackage")) registry.RegisterSchema("ReadinessReport", objectSchema(map[string]any{ "report_type": map[string]any{"type": "string"}, "template_version": map[string]any{"type": "string"}, diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 5971ef9..fbe6910 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -540,6 +540,18 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { queryParam("release_id", "Release id.", "string"), ) operation.Responses[http.StatusOK] = jsonResponse("Control coverage report envelope.", "#/components/schemas/ReadinessReportEnvelope") + case "createRedactionProfile": + operation.Description = "Creates an explicit redaction profile for customer and report package generation." + operation.RequestBody = jsonRequest("Redaction profile creation request.", "#/components/schemas/CreateRedactionProfileRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created redaction profile envelope.", "#/components/schemas/RedactionProfileEnvelope") + case "createCustomerPackage": + operation.Description = "Creates a scoped customer security package manifest using an explicit redaction profile." + operation.RequestBody = jsonRequest("Customer package creation request.", "#/components/schemas/CreateCustomerPackageRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created customer security package envelope.", "#/components/schemas/CustomerSecurityPackageEnvelope") + case "getCustomerPackage": + operation.Description = "Returns a tenant-scoped customer security package manifest by id." + operation.Parameters = append(operation.Parameters, pathParam("id", "Customer package id.")) + operation.Responses[http.StatusOK] = jsonResponse("Customer security package envelope.", "#/components/schemas/CustomerSecurityPackageEnvelope") case "createCustomerPortalAccess": operation.Description = "Creates token-based customer portal access for a customer package and returns the token once." operation.RequestBody = jsonRequest("Customer portal access creation request.", "#/components/schemas/CreateCustomerPortalAccessRequest") @@ -553,13 +565,61 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.RequestBody = jsonRequest("Customer portal token request.", "#/components/schemas/CustomerPortalPackageRequest") operation.Security = nil operation.Scopes = nil - operation.Responses[http.StatusOK] = jsonResponse("Scoped customer package envelope.", "#/components/schemas/DataEnvelope") + operation.Responses[http.StatusOK] = jsonResponse("Scoped customer package envelope.", "#/components/schemas/CustomerSecurityPackageEnvelope") case "downloadCustomerPortalPackage": operation.Description = "Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body." operation.RequestBody = jsonRequest("Customer portal token request.", "#/components/schemas/CustomerPortalPackageRequest") operation.Security = nil operation.Scopes = nil operation.Responses[http.StatusOK] = binaryResponse("Customer security package ZIP archive.") + case "securityReviewPackageReport": + operation.Description = "Returns a redaction-aware security-review package report with assumptions and limitations." + operation.Parameters = append(operation.Parameters, queryParam("package_id", "Customer package id.", "string")) + operation.Responses[http.StatusOK] = jsonResponse("Security review package report envelope.", "#/components/schemas/SecurityReviewPackageReportEnvelope") + case "craReadinessHTMLPackage": + operation.Description = "Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions." + operation.Parameters = append(operation.Parameters, + queryParam("product_id", "Product id.", "string"), + queryParam("release_id", "Release id.", "string"), + ) + operation.Responses[http.StatusOK] = jsonResponse("CRA readiness HTML package envelope.", "#/components/schemas/HTMLReportPackageEnvelope") + case "createReportTemplate": + operation.Description = "Creates a tenant-defined deterministic report template with an explicit allowed-field list." + operation.RequestBody = jsonRequest("Report template creation request.", "#/components/schemas/CreateReportTemplateRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created report template envelope.", "#/components/schemas/CustomReportTemplateEnvelope") + case "renderReportTemplate": + operation.Description = "Renders a tenant report template for a scoped subject using allowed fields only." + operation.Parameters = append(operation.Parameters, pathParam("id", "Report template id.")) + operation.RequestBody = jsonRequest("Report template render request.", "#/components/schemas/RenderReportTemplateRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Rendered report envelope.", "#/components/schemas/RenderedCustomReportEnvelope") + case "exportEvidenceBundle": + operation.Description = "Exports a portable evidence bundle manifest with hashes, signatures, and verification text." + operation.RequestBody = jsonRequest("Evidence bundle export request.", "#/components/schemas/ExportEvidenceBundleRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created evidence bundle envelope.", "#/components/schemas/EvidenceBundleEnvelope") + case "importEvidenceBundle": + operation.Description = "Imports a portable evidence bundle manifest and records deterministic import metadata." + operation.RequestBody = jsonRequest("Evidence bundle import request.", "#/components/schemas/EvidenceBundle") + operation.Responses[http.StatusCreated] = jsonResponse("Evidence bundle import result envelope.", "#/components/schemas/EvidenceBundleImportEnvelope") + case "createEvidenceSummary": + operation.Description = "Creates an evidence-backed summary with citations, assumptions, and limitations." + operation.RequestBody = jsonRequest("Evidence summary creation request.", "#/components/schemas/CreateEvidenceSummaryRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created evidence summary envelope.", "#/components/schemas/EvidenceSummaryEnvelope") + case "createQuestionnaireTemplate": + operation.Description = "Creates a tenant questionnaire template with explicit evidence/control mapping fields." + operation.RequestBody = jsonRequest("Questionnaire template creation request.", "#/components/schemas/CreateQuestionnaireTemplateRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created questionnaire template envelope.", "#/components/schemas/QuestionnaireTemplateEnvelope") + case "createQuestionnairePackage": + operation.Description = "Creates a questionnaire response package from a template and scoped evidence package." + operation.RequestBody = jsonRequest("Questionnaire package creation request.", "#/components/schemas/CreateQuestionnairePackageRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created questionnaire package envelope.", "#/components/schemas/QuestionnairePackageEnvelope") + case "createQuestionnaireDraft": + operation.Description = "Creates an evidence-backed questionnaire draft with limitations." + operation.RequestBody = jsonRequest("Questionnaire draft creation request.", "#/components/schemas/CreateQuestionnaireDraftRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created questionnaire draft envelope.", "#/components/schemas/QuestionnaireDraftEnvelope") + case "createPDFReportPackage": + operation.Description = "Creates a deterministic PDF report package record and payload metadata." + operation.RequestBody = jsonRequest("PDF report package creation request.", "#/components/schemas/CreatePDFReportPackageRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created PDF report package envelope.", "#/components/schemas/PDFReportPackageEnvelope") } return operation } diff --git a/openapi.yaml b/openapi.yaml index b1c0ffe..98f8949 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"operationId":"createCustomerPackage","responses":{"201":{"description":"Create customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"operationId":"getCustomerPackage","responses":{"200":{"description":"Get customer security package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"operationId":"exportEvidenceBundle","responses":{"201":{"description":"Export evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"operationId":"importEvidenceBundle","responses":{"201":{"description":"Import evidence bundle response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"operationId":"createEvidenceSummary","responses":{"201":{"description":"Create evidence-backed summary response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"operationId":"createQuestionnaireDraft","responses":{"201":{"description":"Create evidence-backed questionnaire draft response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"operationId":"createQuestionnairePackage","responses":{"201":{"description":"Create questionnaire package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"operationId":"createQuestionnaireTemplate","responses":{"201":{"description":"Create questionnaire template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"operationId":"createRedactionProfile","responses":{"201":{"description":"Create redaction profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"operationId":"createReportTemplate","responses":{"201":{"description":"Create report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"operationId":"renderReportTemplate","responses":{"201":{"description":"Render report template response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"operationId":"craReadinessHTMLPackage","responses":{"200":{"description":"CRA readiness HTML package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"operationId":"createPDFReportPackage","responses":{"201":{"description":"Create reproducible PDF report package response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"operationId":"securityReviewPackageReport","responses":{"200":{"description":"Security review package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/scripts/openapi_precision_check.py b/scripts/openapi_precision_check.py index 69c1453..a55234f 100755 --- a/scripts/openapi_precision_check.py +++ b/scripts/openapi_precision_check.py @@ -42,8 +42,8 @@ def main() -> int: else: broad += 1 - min_precise = int_env("EVYDENCE_OPENAPI_MIN_PRECISE", 118) - max_broad = int_env("EVYDENCE_OPENAPI_MAX_BROAD", 42) + min_precise = int_env("EVYDENCE_OPENAPI_MIN_PRECISE", 133) + max_broad = int_env("EVYDENCE_OPENAPI_MAX_BROAD", 27) if precise < min_precise: print( f"openapi-precision-check: precise operations {precise} below required {min_precise}", From 4b64f2a3ff22ad62dad571e4e15674d4b6944379 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 19:26:38 +0300 Subject: [PATCH 076/287] docs: complete openapi route schemas --- docs/reference/api-contract-matrix.md | 56 +-- internal/adapters/httpapi/openapi.go | 431 ++++++++++++++++++ .../adapters/httpapi/openapi_operations.go | 107 ++++- openapi.yaml | 2 +- scripts/openapi_precision_check.py | 4 +- 5 files changed, 564 insertions(+), 36 deletions(-) diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index 4b16dd2..32e8e95 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,15 +3,15 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 160 operations: 133 precise, 27 broad. +Generated from 160 operations: 160 precise, 0 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | GET | /v1/admin/instance | instanceAdminSnapshot | Bearer | instance:admin | - | - | - | 200:application/json:InstanceAdminSnapshotEnvelope | precise | | GET | /v1/api-keys | listAPIKeys | Bearer | admin | - | - | - | 200:application/json:APIKeyListEnvelope | precise | | POST | /v1/api-keys | createAPIKey | Bearer | admin | required | - | application/json:CreateAPIKeyRequest | 201:application/json:APIKeyCreateEnvelope | precise | -| POST | /v1/api-security-scans | uploadAPISecurityScan | Bearer | security:write | required | - | - | 201:unspecified | broad | -| POST | /v1/approvals | createApproval | Bearer | release:write | required | - | - | 201:unspecified | broad | +| POST | /v1/api-security-scans | uploadAPISecurityScan | Bearer | security:write | required | - | application/json:UploadSecurityScanRequest | 201:application/json:SecurityScanEnvelope | precise | +| POST | /v1/approvals | createApproval | Bearer | release:write | required | - | application/json:CreateApprovalRequest | 201:application/json:ApprovalRecordEnvelope | precise | | POST | /v1/artifact-signatures | createArtifactSignature | Bearer | evidence:write | required | - | application/json:CreateArtifactSignatureRequest | 201:application/json:ArtifactSignatureEnvelope | precise | | GET | /v1/artifact-signatures/{id} | getArtifactSignature | Bearer | evidence:read | - | path:id | - | 200:application/json:ArtifactSignatureEnvelope | precise | | POST | /v1/artifact-signatures/{id}/verify-cosign | verifyCosignSignature | Bearer | verify:read | required | path:id | application/json:VerifyCosignSignatureRequest | 200:application/json:CosignVerificationEnvelope | precise | @@ -71,19 +71,19 @@ Generated from 160 operations: 133 precise, 27 broad. | POST | /v1/exceptions | createException | Bearer | release:write | required | - | application/json:CreateExceptionRequest | 201:application/json:ExceptionEnvelope | precise | | POST | /v1/exceptions/{id}/approve | approveException | Bearer | release:write | required | path:id | application/json:EmptyObject | 200:application/json:ExceptionEnvelope | precise | | GET | /v1/health | health | public | - | - | - | - | 200:application/json:HealthStatusEnvelope | precise | -| POST | /v1/incident-webhooks/{receiver_id} | receiveIncidentWebhook | public | - | not required | header:X-Evydence-Webhook-Event-ID, header:X-Evydence-Webhook-Signature, header:X-Evydence-Webhook-Timestamp, path:receiver_id | application/json:DataEnvelope | 201:application/json:DataEnvelope | broad | -| POST | /v1/incidents | createIncident | Bearer | incident:write | required | - | - | 201:unspecified | broad | -| POST | /v1/incidents/{id}/timeline | recordIncidentTimeline | Bearer | incident:write | required | - | - | 201:unspecified | broad | -| POST | /v1/incidents/{id}/webhook-receivers | createIncidentWebhookReceiver | Bearer | incident:write | required | path:id | application/json:DataEnvelope | 201:application/json:DataEnvelope | broad | -| POST | /v1/legal-holds | createLegalHold | Bearer | admin | required | - | - | 201:unspecified | broad | +| POST | /v1/incident-webhooks/{receiver_id} | receiveIncidentWebhook | public | - | not required | header:X-Evydence-Webhook-Event-ID, header:X-Evydence-Webhook-Signature, header:X-Evydence-Webhook-Timestamp, path:receiver_id | application/json:SignedIncidentWebhookPayload | 201:application/json:IncidentWebhookDeliveryEnvelope | precise | +| POST | /v1/incidents | createIncident | Bearer | incident:write | required | - | application/json:CreateIncidentRequest | 201:application/json:IncidentEnvelope | precise | +| POST | /v1/incidents/{id}/timeline | recordIncidentTimeline | Bearer | incident:write | required | path:id | application/json:RecordIncidentTimelineRequest | 201:application/json:IncidentTimelineEventEnvelope | precise | +| POST | /v1/incidents/{id}/webhook-receivers | createIncidentWebhookReceiver | Bearer | incident:write | required | path:id | application/json:CreateIncidentWebhookReceiverRequest | 201:application/json:IncidentWebhookReceiverEnvelope | precise | +| POST | /v1/legal-holds | createLegalHold | Bearer | admin | required | - | application/json:CreateLegalHoldRequest | 201:application/json:LegalHoldEnvelope | precise | | GET | /v1/marketplace-collectors | listMarketplaceCollectors | Bearer | collector:read | - | - | - | 200:application/json:MarketplaceCollectorListEnvelope | precise | | POST | /v1/marketplace-collectors | createMarketplaceCollector | Bearer | collector:admin | required | - | application/json:CreateMarketplaceCollectorRequest | 201:application/json:MarketplaceCollectorEnvelope | precise | | GET | /v1/marketplace-collectors/{id}/health | marketplaceCollectorHealth | Bearer | collector:read | - | path:id | - | 200:application/json:MarketplaceCollectorHealthReportEnvelope | precise | -| POST | /v1/merkle-batches | createMerkleBatch | Bearer | keys:admin | required | - | - | 201:unspecified | broad | -| GET | /v1/merkle-batches/{id}/verify | verifyMerkleBatch | Bearer | verify:read | - | - | - | 200:unspecified | broad | +| POST | /v1/merkle-batches | createMerkleBatch | Bearer | keys:admin | required | - | application/json:CreateMerkleBatchRequest | 201:application/json:MerkleBatchEnvelope | precise | +| GET | /v1/merkle-batches/{id}/verify | verifyMerkleBatch | Bearer | verify:read | - | path:id | - | 200:application/json:VerificationResultEnvelope | precise | | GET | /v1/metrics | metrics | Bearer | admin | - | - | - | 200:application/json:MetricsSnapshotEnvelope,text/plain:string | precise | -| POST | /v1/object-retention-policies | createObjectRetentionPolicy | Bearer | admin | required | - | - | 201:unspecified | broad | -| POST | /v1/object-retention-policies/{id}/verify | verifyObjectRetentionPolicy | Bearer | verify:read | required | - | - | 200:unspecified | broad | +| POST | /v1/object-retention-policies | createObjectRetentionPolicy | Bearer | admin | required | - | application/json:CreateObjectRetentionPolicyRequest | 201:application/json:ObjectRetentionPolicyEnvelope | precise | +| POST | /v1/object-retention-policies/{id}/verify | verifyObjectRetentionPolicy | Bearer | verify:read | required | path:id | application/json:EmptyObject | 200:application/json:ObjectRetentionPolicyEnvelope | precise | | POST | /v1/openapi-contracts | uploadOpenAPIContract | Bearer | evidence:write | required | - | application/json:UploadOpenAPIContractRequest | 201:application/json:OpenAPIContractEnvelope | precise | | GET | /v1/openapi-contracts/{id} | getOpenAPIContract | Bearer | evidence:read | - | path:id | - | 200:application/json:OpenAPIContractEnvelope | precise | | POST | /v1/openapi-diffs | createOpenAPIDiff | Bearer | evidence:read | required | - | application/json:CreateOpenAPIDiffRequest | 201:application/json:ContractDiffEnvelope | precise | @@ -94,8 +94,8 @@ Generated from 160 operations: 133 precise, 27 broad. | POST | /v1/products | createProduct | Bearer | product:write | required | - | application/json:CreateProductRequest | 201:application/json:ProductEnvelope | precise | | POST | /v1/projects | createProject | Bearer | project:write | required | - | application/json:CreateProjectRequest | 201:application/json:ProjectEnvelope | precise | | POST | /v1/provider-verifications | verifyProviderIdentity | Bearer | identity:admin | required | - | application/json:VerifyProviderIdentityRequest | 201:application/json:ProviderVerificationEnvelope | precise | -| POST | /v1/public-transparency-log-entries | publishPublicTransparencyLogEntry | Bearer | keys:admin | required | - | - | 201:unspecified | broad | -| POST | /v1/public-transparency-logs | createPublicTransparencyLog | Bearer | keys:admin | required | - | - | 201:unspecified | broad | +| POST | /v1/public-transparency-log-entries | publishPublicTransparencyLogEntry | Bearer | keys:admin | required | - | application/json:PublishPublicTransparencyLogEntryRequest | 201:application/json:PublicTransparencyLogEntryEnvelope | precise | +| POST | /v1/public-transparency-logs | createPublicTransparencyLog | Bearer | keys:admin | required | - | application/json:CreatePublicTransparencyLogRequest | 201:application/json:PublicTransparencyLogEnvelope | precise | | POST | /v1/questionnaire-drafts | createQuestionnaireDraft | Bearer | package:read | required | - | application/json:CreateQuestionnaireDraftRequest | 201:application/json:QuestionnaireDraftEnvelope | precise | | POST | /v1/questionnaire-packages | createQuestionnairePackage | Bearer | package:write | required | - | application/json:CreateQuestionnairePackageRequest | 201:application/json:QuestionnairePackageEnvelope | precise | | POST | /v1/questionnaire-templates | createQuestionnaireTemplate | Bearer | package:write | required | - | application/json:CreateQuestionnaireTemplateRequest | 201:application/json:QuestionnaireTemplateEnvelope | precise | @@ -114,31 +114,31 @@ Generated from 160 operations: 133 precise, 27 broad. | GET | /v1/releases/{id} | getRelease | Bearer | release:read | - | path:id | - | 200:application/json:ReleaseEnvelope | precise | | POST | /v1/releases/{id}/approve | approveRelease | Bearer | release:write | required | path:id | application/json:EmptyObject | 200:application/json:ReleaseEnvelope | precise | | POST | /v1/releases/{id}/freeze | freezeRelease | Bearer | release:write | required | path:id | application/json:EmptyObject | 200:application/json:ReleaseEnvelope | precise | -| POST | /v1/remediation-tasks | createRemediationTask | Bearer | incident:write | required | - | - | 201:unspecified | broad | +| POST | /v1/remediation-tasks | createRemediationTask | Bearer | incident:write | required | - | application/json:CreateRemediationTaskRequest | 201:application/json:RemediationTaskEnvelope | precise | | POST | /v1/report-templates | createReportTemplate | Bearer | report:read | required | - | application/json:CreateReportTemplateRequest | 201:application/json:CustomReportTemplateEnvelope | precise | | POST | /v1/report-templates/{id}/render | renderReportTemplate | Bearer | report:read | required | path:id | application/json:RenderReportTemplateRequest | 201:application/json:RenderedCustomReportEnvelope | precise | -| POST | /v1/reports/anomaly | generateAnomalyReport | Bearer | report:read | required | - | - | 201:unspecified | broad | +| POST | /v1/reports/anomaly | generateAnomalyReport | Bearer | report:read | required | - | application/json:CreateAnomalyReportRequest | 201:application/json:AnomalyReportEnvelope | precise | | GET | /v1/reports/control-coverage | controlCoverageReport | Bearer | report:read | - | query:framework_id, query:product_id, query:release_id | - | 200:application/json:ReadinessReportEnvelope | precise | | GET | /v1/reports/cra-readiness | craReadinessReport | Bearer | report:read | - | query:product_id, query:release_id | - | 200:application/json:ReadinessReportEnvelope | precise | | GET | /v1/reports/cra-readiness-html | craReadinessHTMLPackage | Bearer | report:read | - | query:product_id, query:release_id | - | 200:application/json:HTMLReportPackageEnvelope | precise | -| GET | /v1/reports/incident-package | incidentReport | Bearer | incident:read | - | - | - | 200:unspecified | broad | +| GET | /v1/reports/incident-package | incidentReport | Bearer | incident:read | - | query:incident_id | - | 200:application/json:IncidentReportEnvelope | precise | | GET | /v1/reports/missing-evidence | missingEvidenceReport | Bearer | verify:read | - | query:release_id | - | 200:application/json:MissingEvidenceReportEnvelope | precise | | POST | /v1/reports/pdf | createPDFReportPackage | Bearer | report:read | required | - | application/json:CreatePDFReportPackageRequest | 201:application/json:PDFReportPackageEnvelope | precise | | GET | /v1/reports/release-readiness | releaseReadinessReport | Bearer | verify:read | - | query:release_id | - | 200:application/json:ReadinessReportEnvelope | precise | -| GET | /v1/reports/retention | retentionReport | Bearer | admin | - | - | - | 200:unspecified | broad | +| GET | /v1/reports/retention | retentionReport | Bearer | admin | - | query:scope_id, query:scope_type | - | 200:application/json:RetentionReportEnvelope | precise | | GET | /v1/reports/security-review-package | securityReviewPackageReport | Bearer | package:read | - | query:package_id | - | 200:application/json:SecurityReviewPackageReportEnvelope | precise | -| GET | /v1/reports/vulnerability-posture | vulnerabilityPostureReport | Bearer | security:read | - | - | - | 200:unspecified | broad | -| POST | /v1/retention-overrides | createRetentionOverride | Bearer | admin | required | - | - | 201:unspecified | broad | +| GET | /v1/reports/vulnerability-posture | vulnerabilityPostureReport | Bearer | security:read | - | query:release_id | - | 200:application/json:VulnerabilityPostureReportEnvelope | precise | +| POST | /v1/retention-overrides | createRetentionOverride | Bearer | admin | required | - | application/json:CreateRetentionOverrideRequest | 201:application/json:RetentionOverrideEnvelope | precise | | GET | /v1/role-bindings | listRoleBindings | Bearer | identity:admin | - | - | - | 200:application/json:RoleBindingListEnvelope | precise | | POST | /v1/role-bindings | createRoleBinding | Bearer | identity:admin | required | - | application/json:CreateRoleBindingRequest | 201:application/json:RoleBindingEnvelope | precise | -| POST | /v1/saas/profiles | createSaaSEditionProfile | Bearer | instance:admin | required | - | - | 201:unspecified | broad | -| GET | /v1/sbom-components | listSBOMComponents | Bearer | evidence:read | - | query:artifact_id, query:limit, query:purl, query:query, query:release_id, query:sbom_id | - | 200:application/json:DataEnvelope | broad | -| POST | /v1/sbom-diffs | createSBOMDiff | Bearer | evidence:read | required | - | - | 201:unspecified | broad | +| POST | /v1/saas/profiles | createSaaSEditionProfile | Bearer | instance:admin | required | - | application/json:CreateSaaSEditionProfileRequest | 201:application/json:SaaSEditionProfileEnvelope | precise | +| GET | /v1/sbom-components | listSBOMComponents | Bearer | evidence:read | - | query:artifact_id, query:limit, query:purl, query:query, query:release_id, query:sbom_id | - | 200:application/json:SBOMComponentRecordListEnvelope | precise | +| POST | /v1/sbom-diffs | createSBOMDiff | Bearer | evidence:read | required | - | application/json:CreateSBOMDiffRequest | 201:application/json:SBOMDiffEnvelope | precise | | POST | /v1/sboms | uploadSBOM | Bearer | evidence:write | required | - | application/json:EvidenceUploadRequest | 201:application/json:SBOMEnvelope | precise | -| POST | /v1/sboms/spdx | uploadSPDXSBOM | Bearer | evidence:write | required | - | - | 201:unspecified | broad | +| POST | /v1/sboms/spdx | uploadSPDXSBOM | Bearer | evidence:write | required | - | application/json:UploadSPDXSBOMRequest | 201:application/json:SBOMEnvelope | precise | | GET | /v1/sboms/{id} | getSBOM | Bearer | evidence:read | - | path:id | - | 200:application/json:SBOMEnvelope | precise | -| POST | /v1/security-documents | uploadManualSecurityDocument | Bearer | security:write | required | - | - | 201:unspecified | broad | -| POST | /v1/security-scans | uploadSecurityScan | Bearer | security:write | required | - | - | 201:unspecified | broad | +| POST | /v1/security-documents | uploadManualSecurityDocument | Bearer | security:write | required | - | application/json:UploadManualSecurityDocumentRequest | 201:application/json:ManualSecurityDocumentEnvelope | precise | +| POST | /v1/security-scans | uploadSecurityScan | Bearer | security:write | required | - | application/json:UploadSecurityScanRequest | 201:application/json:SecurityScanEnvelope | precise | | GET | /v1/signing-keys | listSigningKeys | Bearer | verify:read | - | - | - | 200:application/json:SigningKeyListEnvelope | precise | | POST | /v1/signing-keys/rotate | rotateSigningKey | Bearer | keys:admin | required | - | application/json:SigningKeyTransitionRequest | 201:application/json:SigningKeyEnvelope | precise | | POST | /v1/signing-keys/{id}/revoke | revokeSigningKey | Bearer | keys:admin | required | path:id | application/json:SigningKeyTransitionRequest | 200:application/json:SigningKeyEnvelope | precise | @@ -153,10 +153,10 @@ Generated from 160 operations: 133 precise, 27 broad. | POST | /v1/sso/providers | createSSOProvider | Bearer | identity:admin | required | - | application/json:CreateSSOProviderRequest | 201:application/json:SSOProviderEnvelope | precise | | POST | /v1/sso/sessions | createSSOSession | Bearer | identity:admin | required | - | application/json:CreateSSOSessionRequest | 201:application/json:SSOSessionCreateEnvelope | precise | | POST | /v1/sso/sessions/{id}/revoke | revokeSSOSession | Bearer | identity:admin | required | path:id | application/json:EmptyObject | 200:application/json:SSOSessionEnvelope | precise | -| POST | /v1/transparency-checkpoints | createTransparencyCheckpoint | Bearer | keys:admin | required | - | - | 201:unspecified | broad | +| POST | /v1/transparency-checkpoints | createTransparencyCheckpoint | Bearer | keys:admin | required | - | application/json:CreateTransparencyCheckpointRequest | 201:application/json:TransparencyCheckpointEnvelope | precise | | POST | /v1/users | createUser | Bearer | identity:admin | required | - | application/json:CreateUserRequest | 201:application/json:HumanUserEnvelope | precise | | POST | /v1/users/{id}/deactivate | deactivateUser | Bearer | identity:admin | required | path:id | application/json:EmptyObject | 200:application/json:HumanUserEnvelope | precise | -| POST | /v1/verify | verify | Bearer | verify:read | required | - | - | 200:unspecified | broad | +| POST | /v1/verify | verify | Bearer | verify:read | required | - | application/json:VerifySubjectRequest | 200:application/json:VerificationResultEnvelope | precise | | GET | /v1/version | version | public | - | - | - | - | 200:application/json:VersionInfoEnvelope | precise | | POST | /v1/vex | uploadVEX | Bearer | evidence:write | required | - | application/json:EvidenceUploadRequest | 201:application/json:VEXDocumentEnvelope | precise | | POST | /v1/vex/cyclonedx | uploadCycloneDXVEX | Bearer | evidence:write | required | - | application/json:EvidenceUploadRequest | 201:application/json:VEXDocumentEnvelope | precise | diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 1acd7e6..e2593e5 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -147,6 +147,109 @@ func registerCriticalSchemas(registry *specs.Registry) { "verified_at": map[string]any{"type": "string", "format": "date-time"}, }, "id", "tenant_id", "subject_type", "subject_id", "result", "checks", "verified_at")) registry.RegisterSchema("VerificationResultEnvelope", dataEnvelopeSchema("#/components/schemas/VerificationResult")) + registry.RegisterSchema("CreateMerkleBatchRequest", objectSchema(map[string]any{ + "from_sequence": map[string]any{"type": "integer", "format": "int64"}, + "to_sequence": map[string]any{"type": "integer", "format": "int64"}, + })) + registry.RegisterSchema("MerkleBatch", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "from_sequence": map[string]any{"type": "integer", "format": "int64"}, + "to_sequence": map[string]any{"type": "integer", "format": "int64"}, + "entry_count": map[string]any{"type": "integer"}, + "leaf_hashes": map[string]any{"type": "array", "items": map[string]any{"type": "string", "pattern": "^sha256:"}}, + "root_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "signature_refs": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "from_sequence", "to_sequence", "entry_count", "leaf_hashes", "root_hash", "schema_version", "created_at")) + registry.RegisterSchema("MerkleBatchEnvelope", dataEnvelopeSchema("#/components/schemas/MerkleBatch")) + registry.RegisterSchema("CreateTransparencyCheckpointRequest", objectSchema(map[string]any{ + "batch_id": map[string]any{"type": "string"}, + "provider": map[string]any{"type": "string"}, + "external_url": map[string]any{"type": "string"}, + "external_id": map[string]any{"type": "string"}, + }, "batch_id", "provider")) + registry.RegisterSchema("TransparencyCheckpoint", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "batch_id": map[string]any{"type": "string"}, + "provider": map[string]any{"type": "string"}, + "external_url": map[string]any{"type": "string"}, + "external_id": map[string]any{"type": "string"}, + "timestamp_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "state": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "batch_id", "provider", "timestamp_hash", "state", "schema_version", "created_at")) + registry.RegisterSchema("TransparencyCheckpointEnvelope", dataEnvelopeSchema("#/components/schemas/TransparencyCheckpoint")) + registry.RegisterSchema("CreateObjectRetentionPolicyRequest", objectSchema(map[string]any{ + "name": map[string]any{"type": "string"}, + "object_prefix": map[string]any{"type": "string"}, + "mode": map[string]any{"type": "string", "enum": []string{"governance", "compliance"}}, + "retention_days": map[string]any{"type": "integer", "minimum": 1}, + }, "name", "mode", "retention_days")) + registry.RegisterSchema("ObjectRetentionPolicy", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "object_prefix": map[string]any{"type": "string"}, + "mode": map[string]any{"type": "string"}, + "retention_days": map[string]any{"type": "integer"}, + "status": map[string]any{"type": "string"}, + "verified_at": map[string]any{"type": "string", "format": "date-time"}, + "verification_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "name", "object_prefix", "mode", "retention_days", "status", "schema_version", "created_at")) + registry.RegisterSchema("ObjectRetentionPolicyEnvelope", dataEnvelopeSchema("#/components/schemas/ObjectRetentionPolicy")) + registry.RegisterSchema("CreateLegalHoldRequest", objectSchema(map[string]any{ + "scope_type": map[string]any{"type": "string"}, + "scope_id": map[string]any{"type": "string"}, + "reason": map[string]any{"type": "string"}, + "owner": map[string]any{"type": "string"}, + }, "scope_type", "scope_id", "reason", "owner")) + registry.RegisterSchema("LegalHold", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "scope_type": map[string]any{"type": "string"}, + "scope_id": map[string]any{"type": "string"}, + "reason": map[string]any{"type": "string"}, + "owner": map[string]any{"type": "string"}, + "released_at": map[string]any{"type": "string", "format": "date-time"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "scope_type", "scope_id", "reason", "owner", "schema_version", "created_at")) + registry.RegisterSchema("LegalHoldEnvelope", dataEnvelopeSchema("#/components/schemas/LegalHold")) + registry.RegisterSchema("CreateRetentionOverrideRequest", objectSchema(map[string]any{ + "scope_type": map[string]any{"type": "string"}, + "scope_id": map[string]any{"type": "string"}, + "retention_until": map[string]any{"type": "string", "format": "date-time"}, + "reason": map[string]any{"type": "string"}, + "owner": map[string]any{"type": "string"}, + }, "scope_type", "scope_id", "retention_until", "reason", "owner")) + registry.RegisterSchema("RetentionOverride", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "scope_type": map[string]any{"type": "string"}, + "scope_id": map[string]any{"type": "string"}, + "retention_until": map[string]any{"type": "string", "format": "date-time"}, + "reason": map[string]any{"type": "string"}, + "owner": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "scope_type", "scope_id", "retention_until", "reason", "owner", "schema_version", "created_at")) + registry.RegisterSchema("RetentionOverrideEnvelope", dataEnvelopeSchema("#/components/schemas/RetentionOverride")) + registry.RegisterSchema("RetentionReport", objectSchema(map[string]any{ + "report_type": map[string]any{"type": "string"}, + "scope_type": map[string]any{"type": "string"}, + "scope_id": map[string]any{"type": "string"}, + "legal_holds": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/LegalHold"}}, + "retention_overrides": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/RetentionOverride"}}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "generated_at": map[string]any{"type": "string", "format": "date-time"}, + }, "report_type", "legal_holds", "retention_overrides", "limitations", "generated_at")) + registry.RegisterSchema("RetentionReportEnvelope", dataEnvelopeSchema("#/components/schemas/RetentionReport")) registry.RegisterSchema("PolicyCheck", objectSchema(map[string]any{ "name": map[string]any{"type": "string"}, "result": map[string]any{"type": "string", "enum": []string{"passed", "failed", "warning", "skipped"}}, @@ -301,6 +404,26 @@ func registerCriticalSchemas(registry *specs.Registry) { "created_at": map[string]any{"type": "string", "format": "date-time"}, }, "id", "tenant_id", "scope_type", "scope_id", "owner", "risk", "reason", "expires_at", "approved", "schema_version", "created_at")) registry.RegisterSchema("WaiverEnvelope", dataEnvelopeSchema("#/components/schemas/Waiver")) + registry.RegisterSchema("CreateApprovalRequest", objectSchema(map[string]any{ + "subject_type": map[string]any{"type": "string"}, + "subject_id": map[string]any{"type": "string"}, + "decision": map[string]any{"type": "string", "enum": []string{"approved", "rejected", "accepted"}}, + "reason": map[string]any{"type": "string"}, + "evidence_id": map[string]any{"type": "string"}, + }, "subject_type", "subject_id", "decision", "reason")) + registry.RegisterSchema("ApprovalRecord", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "subject_type": map[string]any{"type": "string"}, + "subject_id": map[string]any{"type": "string"}, + "decision": map[string]any{"type": "string"}, + "reason": map[string]any{"type": "string"}, + "approver_id": map[string]any{"type": "string"}, + "evidence_id": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "subject_type", "subject_id", "decision", "reason", "approver_id", "schema_version", "created_at")) + registry.RegisterSchema("ApprovalRecordEnvelope", dataEnvelopeSchema("#/components/schemas/ApprovalRecord")) registry.RegisterSchema("UploadOpenAPIContractRequest", objectSchema(map[string]any{ "product_id": map[string]any{"type": "string"}, "release_id": map[string]any{"type": "string"}, @@ -1533,6 +1656,52 @@ func registerCriticalSchemas(registry *specs.Registry) { "created_at": map[string]any{"type": "string", "format": "date-time"}, }, "id", "tenant_id", "evidence_id", "release_id", "format", "component_count", "created_at")) registry.RegisterSchema("SBOMEnvelope", dataEnvelopeSchema("#/components/schemas/SBOM")) + registry.RegisterSchema("SBOMComponent", objectSchema(map[string]any{ + "name": map[string]any{"type": "string"}, + "version": map[string]any{"type": "string"}, + "purl": map[string]any{"type": "string"}, + "hashes": map[string]any{"type": "object", "additionalProperties": map[string]any{"type": "string"}}, + }, "name")) + registry.RegisterSchema("SBOMComponentRecord", objectSchema(map[string]any{ + "sbom_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "artifact_id": map[string]any{"type": "string"}, + "component": map[string]any{"$ref": "#/components/schemas/SBOMComponent"}, + }, "sbom_id", "component")) + registry.RegisterSchema("SBOMComponentRecordListEnvelope", dataArrayEnvelopeSchema("#/components/schemas/SBOMComponentRecord")) + registry.RegisterSchema("UploadSPDXSBOMRequest", objectSchema(map[string]any{ + "release_id": map[string]any{"type": "string"}, + "artifact_id": map[string]any{"type": "string"}, + "payload": map[string]any{"type": "object", "additionalProperties": true}, + }, "release_id", "payload")) + registry.RegisterSchema("CreateSBOMDiffRequest", objectSchema(map[string]any{ + "base_sbom_id": map[string]any{"type": "string"}, + "target_sbom_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + }, "base_sbom_id", "target_sbom_id")) + registry.RegisterSchema("DependencyChange", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "sbom_diff_id": map[string]any{"type": "string"}, + "change_type": map[string]any{"type": "string", "enum": []string{"added", "removed", "changed"}}, + "component": map[string]any{"$ref": "#/components/schemas/SBOMComponent"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "sbom_diff_id", "change_type", "component", "schema_version", "created_at")) + registry.RegisterSchema("SBOMDiff", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "base_sbom_id": map[string]any{"type": "string"}, + "target_sbom_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "added_components": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/SBOMComponent"}}, + "removed_components": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/SBOMComponent"}}, + "unchanged_count": map[string]any{"type": "integer"}, + "dependency_changes": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/DependencyChange"}}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "base_sbom_id", "target_sbom_id", "unchanged_count", "schema_version", "created_at")) + registry.RegisterSchema("SBOMDiffEnvelope", dataEnvelopeSchema("#/components/schemas/SBOMDiff")) registry.RegisterSchema("VEXDocument", objectSchema(map[string]any{ "id": map[string]any{"type": "string"}, "tenant_id": map[string]any{"type": "string"}, @@ -1569,6 +1738,268 @@ func registerCriticalSchemas(registry *specs.Registry) { "state": map[string]any{"type": "string"}, }, "vulnerability", "severity")}, }, "scanner", "target_ref", "release_id", "findings")) + registry.RegisterSchema("CreateIncidentRequest", objectSchema(map[string]any{ + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "title": map[string]any{"type": "string"}, + "severity": map[string]any{"type": "string", "enum": []string{"low", "medium", "high", "critical"}}, + "opened_at": map[string]any{"type": "string", "format": "date-time"}, + }, "product_id", "title", "severity")) + registry.RegisterSchema("Incident", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "title": map[string]any{"type": "string"}, + "severity": map[string]any{"type": "string"}, + "status": map[string]any{"type": "string"}, + "opened_at": map[string]any{"type": "string", "format": "date-time"}, + "closed_at": map[string]any{"type": "string", "format": "date-time"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "product_id", "title", "severity", "status", "opened_at", "schema_version", "created_at")) + registry.RegisterSchema("IncidentEnvelope", dataEnvelopeSchema("#/components/schemas/Incident")) + registry.RegisterSchema("RecordIncidentTimelineRequest", objectSchema(map[string]any{ + "event_type": map[string]any{"type": "string"}, + "summary": map[string]any{"type": "string"}, + "evidence_id": map[string]any{"type": "string"}, + "occurred_at": map[string]any{"type": "string", "format": "date-time"}, + }, "event_type", "summary")) + registry.RegisterSchema("IncidentTimelineEvent", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "incident_id": map[string]any{"type": "string"}, + "event_type": map[string]any{"type": "string"}, + "summary": map[string]any{"type": "string"}, + "evidence_id": map[string]any{"type": "string"}, + "occurred_at": map[string]any{"type": "string", "format": "date-time"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "incident_id", "event_type", "summary", "occurred_at", "schema_version", "created_at")) + registry.RegisterSchema("IncidentTimelineEventEnvelope", dataEnvelopeSchema("#/components/schemas/IncidentTimelineEvent")) + registry.RegisterSchema("CreateIncidentWebhookReceiverRequest", objectSchema(map[string]any{ + "name": map[string]any{"type": "string"}, + "provider": map[string]any{"type": "string"}, + "public_key": map[string]any{"type": "string", "description": "Ed25519 public key used to verify signed incident webhook events."}, + }, "name", "provider", "public_key")) + registry.RegisterSchema("IncidentWebhookReceiver", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "incident_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "provider": map[string]any{"type": "string"}, + "public_key": map[string]any{"type": "string"}, + "status": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "incident_id", "name", "provider", "public_key", "status", "schema_version", "created_at")) + registry.RegisterSchema("IncidentWebhookReceiverEnvelope", dataEnvelopeSchema("#/components/schemas/IncidentWebhookReceiver")) + registry.RegisterSchema("SignedIncidentWebhookPayload", objectSchema(map[string]any{ + "event_type": map[string]any{"type": "string"}, + "summary": map[string]any{"type": "string"}, + "evidence_id": map[string]any{"type": "string"}, + "occurred_at": map[string]any{"type": "string", "format": "date-time"}, + }, "event_type", "summary")) + registry.RegisterSchema("IncidentWebhookEvent", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "receiver_id": map[string]any{"type": "string"}, + "incident_id": map[string]any{"type": "string"}, + "provider": map[string]any{"type": "string"}, + "event_id": map[string]any{"type": "string"}, + "payload_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "signature_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "timeline_event_id": map[string]any{"type": "string"}, + "result": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "receiver_id", "incident_id", "provider", "event_id", "payload_hash", "signature_hash", "result", "schema_version", "created_at")) + registry.RegisterSchema("IncidentWebhookDelivery", objectSchema(map[string]any{ + "webhook_event": map[string]any{"$ref": "#/components/schemas/IncidentWebhookEvent"}, + "timeline_event": map[string]any{"$ref": "#/components/schemas/IncidentTimelineEvent"}, + }, "webhook_event", "timeline_event")) + registry.RegisterSchema("IncidentWebhookDeliveryEnvelope", dataEnvelopeSchema("#/components/schemas/IncidentWebhookDelivery")) + registry.RegisterSchema("CreateRemediationTaskRequest", objectSchema(map[string]any{ + "incident_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "title": map[string]any{"type": "string"}, + "owner": map[string]any{"type": "string"}, + "due_at": map[string]any{"type": "string", "format": "date-time"}, + "evidence_id": map[string]any{"type": "string"}, + }, "title", "owner")) + registry.RegisterSchema("RemediationTask", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "incident_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "title": map[string]any{"type": "string"}, + "owner": map[string]any{"type": "string"}, + "status": map[string]any{"type": "string"}, + "due_at": map[string]any{"type": "string", "format": "date-time"}, + "evidence_id": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "title", "owner", "status", "schema_version", "created_at")) + registry.RegisterSchema("RemediationTaskEnvelope", dataEnvelopeSchema("#/components/schemas/RemediationTask")) + registry.RegisterSchema("IncidentReport", objectSchema(map[string]any{ + "report_type": map[string]any{"type": "string"}, + "template_version": map[string]any{"type": "string"}, + "incident_id": map[string]any{"type": "string"}, + "result": map[string]any{"type": "string"}, + "timeline": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/IncidentTimelineEvent"}}, + "tasks": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/RemediationTask"}}, + "linked_evidence": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "assumptions": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "generated_at": map[string]any{"type": "string", "format": "date-time"}, + }, "report_type", "template_version", "incident_id", "result", "timeline", "tasks", "assumptions", "limitations", "generated_at")) + registry.RegisterSchema("IncidentReportEnvelope", dataEnvelopeSchema("#/components/schemas/IncidentReport")) + registry.RegisterSchema("UploadSecurityScanRequest", objectSchema(map[string]any{ + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "artifact_id": map[string]any{"type": "string"}, + "category": map[string]any{"type": "string", "enum": []string{"sast", "dast", "secret", "license", "api_security"}}, + "format": map[string]any{"type": "string"}, + "scanner": map[string]any{"type": "string"}, + "target_ref": map[string]any{"type": "string"}, + "payload": map[string]any{"type": "object", "additionalProperties": true}, + }, "category", "format", "scanner", "target_ref", "payload")) + registry.RegisterSchema("SecurityScan", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "artifact_id": map[string]any{"type": "string"}, + "category": map[string]any{"type": "string"}, + "format": map[string]any{"type": "string"}, + "scanner": map[string]any{"type": "string"}, + "target_ref": map[string]any{"type": "string"}, + "evidence_id": map[string]any{"type": "string"}, + "payload_ref": map[string]any{"type": "string"}, + "payload_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "finding_count": map[string]any{"type": "integer"}, + "summary": map[string]any{"type": "object", "additionalProperties": map[string]any{"type": "integer"}}, + "redacted": map[string]any{"type": "boolean"}, + "quarantined": map[string]any{"type": "boolean"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "category", "format", "scanner", "target_ref", "evidence_id", "payload_hash", "finding_count", "redacted", "quarantined", "schema_version", "created_at")) + registry.RegisterSchema("SecurityScanEnvelope", dataEnvelopeSchema("#/components/schemas/SecurityScan")) + registry.RegisterSchema("UploadManualSecurityDocumentRequest", objectSchema(map[string]any{ + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "document_type": map[string]any{"type": "string", "enum": []string{"threat_model", "security_review", "pentest_report"}}, + "title": map[string]any{"type": "string"}, + "sensitivity": map[string]any{"type": "string", "enum": []string{"internal", "restricted", "confidential"}}, + "payload": map[string]any{"type": "string", "description": "Document payload or text supplied for object storage; responses expose only payload hash/ref metadata."}, + "media_type": map[string]any{"type": "string"}, + }, "document_type", "title", "sensitivity", "payload")) + registry.RegisterSchema("ManualSecurityDocument", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "document_type": map[string]any{"type": "string"}, + "title": map[string]any{"type": "string"}, + "sensitivity": map[string]any{"type": "string"}, + "evidence_id": map[string]any{"type": "string"}, + "payload_ref": map[string]any{"type": "string"}, + "payload_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "document_type", "title", "sensitivity", "evidence_id", "payload_hash", "schema_version", "created_at")) + registry.RegisterSchema("ManualSecurityDocumentEnvelope", dataEnvelopeSchema("#/components/schemas/ManualSecurityDocument")) + registry.RegisterSchema("VulnerabilityPostureReport", objectSchema(map[string]any{ + "report_type": map[string]any{"type": "string"}, + "template_version": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "summary": map[string]any{"type": "object", "additionalProperties": map[string]any{"type": "integer"}}, + "open_critical": map[string]any{"type": "integer"}, + "assumptions": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "generated_at": map[string]any{"type": "string", "format": "date-time"}, + }, "report_type", "template_version", "summary", "open_critical", "assumptions", "limitations", "generated_at")) + registry.RegisterSchema("VulnerabilityPostureReportEnvelope", dataEnvelopeSchema("#/components/schemas/VulnerabilityPostureReport")) + registry.RegisterSchema("CreateAnomalyReportRequest", objectSchema(map[string]any{ + "subject_type": map[string]any{"type": "string"}, + "subject_id": map[string]any{"type": "string"}, + }, "subject_type", "subject_id")) + registry.RegisterSchema("AnomalySignal", objectSchema(map[string]any{ + "name": map[string]any{"type": "string"}, + "severity": map[string]any{"type": "string"}, + "detail": map[string]any{"type": "string"}, + }, "name", "severity", "detail")) + registry.RegisterSchema("AnomalyReport", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "subject_type": map[string]any{"type": "string"}, + "subject_id": map[string]any{"type": "string"}, + "result": map[string]any{"type": "string"}, + "signals": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/AnomalySignal"}}, + "assumptions": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "subject_type", "subject_id", "result", "assumptions", "limitations", "schema_version", "created_at")) + registry.RegisterSchema("AnomalyReportEnvelope", dataEnvelopeSchema("#/components/schemas/AnomalyReport")) + registry.RegisterSchema("CreatePublicTransparencyLogRequest", objectSchema(map[string]any{ + "name": map[string]any{"type": "string"}, + "endpoint": map[string]any{"type": "string"}, + "public_key": map[string]any{"type": "string"}, + }, "name", "endpoint", "public_key")) + registry.RegisterSchema("PublicTransparencyLog", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "endpoint": map[string]any{"type": "string"}, + "public_key": map[string]any{"type": "string"}, + "state": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "name", "endpoint", "public_key", "state", "schema_version", "created_at")) + registry.RegisterSchema("PublicTransparencyLogEnvelope", dataEnvelopeSchema("#/components/schemas/PublicTransparencyLog")) + registry.RegisterSchema("PublishPublicTransparencyLogEntryRequest", objectSchema(map[string]any{ + "log_id": map[string]any{"type": "string"}, + "checkpoint_id": map[string]any{"type": "string"}, + "external_id": map[string]any{"type": "string"}, + }, "log_id", "checkpoint_id", "external_id")) + registry.RegisterSchema("PublicTransparencyLogEntry", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "log_id": map[string]any{"type": "string"}, + "checkpoint_id": map[string]any{"type": "string"}, + "merkle_batch_id": map[string]any{"type": "string"}, + "external_id": map[string]any{"type": "string"}, + "entry_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "state": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "log_id", "checkpoint_id", "merkle_batch_id", "external_id", "entry_hash", "state", "schema_version", "created_at")) + registry.RegisterSchema("PublicTransparencyLogEntryEnvelope", dataEnvelopeSchema("#/components/schemas/PublicTransparencyLogEntry")) + registry.RegisterSchema("CreateSaaSEditionProfileRequest", objectSchema(map[string]any{ + "name": map[string]any{"type": "string"}, + "region": map[string]any{"type": "string"}, + "admin_tenant_id": map[string]any{"type": "string"}, + "isolation_model": map[string]any{"type": "string"}, + }, "name", "region", "admin_tenant_id", "isolation_model")) + registry.RegisterSchema("SaaSEditionProfile", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "region": map[string]any{"type": "string"}, + "admin_tenant_id": map[string]any{"type": "string"}, + "isolation_model": map[string]any{"type": "string"}, + "status": map[string]any{"type": "string"}, + "config_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "name", "region", "admin_tenant_id", "isolation_model", "status", "config_hash", "limitations", "schema_version", "created_at")) + registry.RegisterSchema("SaaSEditionProfileEnvelope", dataEnvelopeSchema("#/components/schemas/SaaSEditionProfile")) + registry.RegisterSchema("VerifySubjectRequest", objectSchema(map[string]any{ + "subject_type": map[string]any{"type": "string"}, + "subject_id": map[string]any{"type": "string"}, + }, "subject_type")) registry.RegisterSchema("SubjectRef", objectSchema(map[string]any{ "type": map[string]any{"type": "string"}, "id": map[string]any{"type": "string"}, diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index fbe6910..15d87f9 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -240,12 +240,21 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { queryParam("purl", "Exact package URL filter.", "string"), queryParam("limit", "Maximum returned component records.", "integer"), ) - operation.Responses[http.StatusOK] = jsonResponse("SBOM component result envelope.", "#/components/schemas/DataEnvelope") + operation.Responses[http.StatusOK] = jsonResponse("SBOM component result envelope.", "#/components/schemas/SBOMComponentRecordListEnvelope") + case "createIncident": + operation.Description = "Creates an append-only incident record linked to tenant-scoped product and optional release evidence." + operation.RequestBody = jsonRequest("Incident creation request.", "#/components/schemas/CreateIncidentRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created incident envelope.", "#/components/schemas/IncidentEnvelope") + case "recordIncidentTimeline": + operation.Description = "Appends an incident timeline event and optional evidence reference." + operation.Parameters = append(operation.Parameters, pathParam("id", "Incident id.")) + operation.RequestBody = jsonRequest("Incident timeline event request.", "#/components/schemas/RecordIncidentTimelineRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created incident timeline event envelope.", "#/components/schemas/IncidentTimelineEventEnvelope") case "createIncidentWebhookReceiver": operation.Description = "Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool." operation.Parameters = append(operation.Parameters, pathParam("id", "Incident id.")) - operation.RequestBody = jsonRequest("Incident webhook receiver creation request.", "#/components/schemas/DataEnvelope") - operation.Responses[http.StatusCreated] = jsonResponse("Created incident webhook receiver envelope.", "#/components/schemas/DataEnvelope") + operation.RequestBody = jsonRequest("Incident webhook receiver creation request.", "#/components/schemas/CreateIncidentWebhookReceiverRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created incident webhook receiver envelope.", "#/components/schemas/IncidentWebhookReceiverEnvelope") case "receiveIncidentWebhook": operation.Description = "Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields." operation.Parameters = append(operation.Parameters, @@ -254,11 +263,19 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { headerParam("X-Evydence-Webhook-Timestamp", "RFC3339 timestamp included in the signed payload."), headerParam("X-Evydence-Webhook-Signature", "ed25519= over timestamp, event id, and raw body."), ) - operation.RequestBody = jsonRequest("Signed incident timeline event payload.", "#/components/schemas/DataEnvelope") + operation.RequestBody = jsonRequest("Signed incident timeline event payload.", "#/components/schemas/SignedIncidentWebhookPayload") operation.Security = nil operation.Scopes = nil operation.Extensions = nil - operation.Responses[http.StatusCreated] = jsonResponse("Accepted webhook event and timeline event envelope.", "#/components/schemas/DataEnvelope") + operation.Responses[http.StatusCreated] = jsonResponse("Accepted webhook event and timeline event envelope.", "#/components/schemas/IncidentWebhookDeliveryEnvelope") + case "createRemediationTask": + operation.Description = "Creates an incident or release remediation task linked to optional evidence." + operation.RequestBody = jsonRequest("Remediation task creation request.", "#/components/schemas/CreateRemediationTaskRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created remediation task envelope.", "#/components/schemas/RemediationTaskEnvelope") + case "incidentReport": + operation.Description = "Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations." + operation.Parameters = append(operation.Parameters, queryParam("incident_id", "Incident id.", "string")) + operation.Responses[http.StatusOK] = jsonResponse("Incident package report envelope.", "#/components/schemas/IncidentReportEnvelope") case "createReleaseBundle": operation.Description = "Creates an immutable signed release bundle for a release." operation.RequestBody = jsonRequest("Release bundle creation request.", "#/components/schemas/CreateReleaseBundleRequest") @@ -278,6 +295,10 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { case "verifyAuditChain": operation.Description = "Verifies the tenant audit chain continuity and returns deterministic verification checks." operation.Responses[http.StatusOK] = jsonResponse("Audit chain verification envelope.", "#/components/schemas/VerificationResultEnvelope") + case "verify": + operation.Description = "Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target." + operation.RequestBody = jsonRequest("Subject verification request.", "#/components/schemas/VerifySubjectRequest") + operation.Responses[http.StatusOK] = jsonResponse("Subject verification envelope.", "#/components/schemas/VerificationResultEnvelope") case "listAuditLog": operation.Description = "Lists tenant-scoped append-only audit-chain entries in reverse chronological order." operation.Parameters = append(operation.Parameters, @@ -348,6 +369,10 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Parameters = append(operation.Parameters, pathParam("id", "Waiver id.")) operation.RequestBody = jsonRequest("Empty JSON object.", "#/components/schemas/EmptyObject") operation.Responses[http.StatusOK] = jsonResponse("Approved waiver envelope.", "#/components/schemas/WaiverEnvelope") + case "createApproval": + operation.Description = "Creates an immutable approval record for a release, waiver, package, or review subject." + operation.RequestBody = jsonRequest("Approval creation request.", "#/components/schemas/CreateApprovalRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created approval envelope.", "#/components/schemas/ApprovalRecordEnvelope") case "uploadOpenAPIContract": operation.Description = "Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata." operation.RequestBody = jsonRequest("OpenAPI contract upload request.", "#/components/schemas/UploadOpenAPIContractRequest") @@ -525,6 +550,78 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Description = "Registers OCI/container image metadata and digest evidence linked to an optional artifact." operation.RequestBody = jsonRequest("Container image registration request.", "#/components/schemas/RegisterContainerImageRequest") operation.Responses[http.StatusCreated] = jsonResponse("Registered container image envelope.", "#/components/schemas/ContainerImageEnvelope") + case "uploadSecurityScan", "uploadAPISecurityScan": + operation.Description = "Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses." + operation.RequestBody = jsonRequest("Security scan upload request.", "#/components/schemas/UploadSecurityScanRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created security scan envelope.", "#/components/schemas/SecurityScanEnvelope") + case "uploadManualSecurityDocument": + operation.Description = "Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference." + operation.RequestBody = jsonRequest("Manual security document upload request.", "#/components/schemas/UploadManualSecurityDocumentRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created manual security document envelope.", "#/components/schemas/ManualSecurityDocumentEnvelope") + case "uploadSPDXSBOM": + operation.Description = "Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata." + operation.RequestBody = jsonRequest("SPDX SBOM upload request.", "#/components/schemas/UploadSPDXSBOMRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created SBOM envelope.", "#/components/schemas/SBOMEnvelope") + case "createSBOMDiff": + operation.Description = "Creates a deterministic SBOM diff between two tenant-scoped SBOM records." + operation.RequestBody = jsonRequest("SBOM diff creation request.", "#/components/schemas/CreateSBOMDiffRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created SBOM diff envelope.", "#/components/schemas/SBOMDiffEnvelope") + case "vulnerabilityPostureReport": + operation.Description = "Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records." + operation.Parameters = append(operation.Parameters, queryParam("release_id", "Release id.", "string")) + operation.Responses[http.StatusOK] = jsonResponse("Vulnerability posture report envelope.", "#/components/schemas/VulnerabilityPostureReportEnvelope") + case "generateAnomalyReport": + operation.Description = "Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations." + operation.RequestBody = jsonRequest("Anomaly report creation request.", "#/components/schemas/CreateAnomalyReportRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created anomaly report envelope.", "#/components/schemas/AnomalyReportEnvelope") + case "createMerkleBatch": + operation.Description = "Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring." + operation.RequestBody = jsonRequest("Merkle batch creation request.", "#/components/schemas/CreateMerkleBatchRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created Merkle batch envelope.", "#/components/schemas/MerkleBatchEnvelope") + case "verifyMerkleBatch": + operation.Description = "Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries." + operation.Parameters = append(operation.Parameters, pathParam("id", "Merkle batch id.")) + operation.Responses[http.StatusOK] = jsonResponse("Merkle batch verification envelope.", "#/components/schemas/VerificationResultEnvelope") + case "createTransparencyCheckpoint": + operation.Description = "Records an external transparency or timestamp checkpoint reference for a Merkle batch." + operation.RequestBody = jsonRequest("Transparency checkpoint creation request.", "#/components/schemas/CreateTransparencyCheckpointRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created transparency checkpoint envelope.", "#/components/schemas/TransparencyCheckpointEnvelope") + case "createPublicTransparencyLog": + operation.Description = "Creates tenant metadata for an optional public transparency log trust root." + operation.RequestBody = jsonRequest("Public transparency log creation request.", "#/components/schemas/CreatePublicTransparencyLogRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created public transparency log envelope.", "#/components/schemas/PublicTransparencyLogEnvelope") + case "publishPublicTransparencyLogEntry": + operation.Description = "Records publication metadata for a checkpoint submitted to a configured public transparency log." + operation.RequestBody = jsonRequest("Public transparency log entry publication request.", "#/components/schemas/PublishPublicTransparencyLogEntryRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created public transparency log entry envelope.", "#/components/schemas/PublicTransparencyLogEntryEnvelope") + case "createObjectRetentionPolicy": + operation.Description = "Creates an object retention policy record for storage immutability verification." + operation.RequestBody = jsonRequest("Object retention policy creation request.", "#/components/schemas/CreateObjectRetentionPolicyRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created object retention policy envelope.", "#/components/schemas/ObjectRetentionPolicyEnvelope") + case "verifyObjectRetentionPolicy": + operation.Description = "Records verification metadata for a tenant object retention policy." + operation.Parameters = append(operation.Parameters, pathParam("id", "Object retention policy id.")) + operation.RequestBody = jsonRequest("Empty JSON object.", "#/components/schemas/EmptyObject") + operation.Responses[http.StatusOK] = jsonResponse("Verified object retention policy envelope.", "#/components/schemas/ObjectRetentionPolicyEnvelope") + case "createLegalHold": + operation.Description = "Creates an append-only legal-hold marker for a tenant-scoped retention subject." + operation.RequestBody = jsonRequest("Legal hold creation request.", "#/components/schemas/CreateLegalHoldRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created legal hold envelope.", "#/components/schemas/LegalHoldEnvelope") + case "createRetentionOverride": + operation.Description = "Creates an append-only retention override for a tenant-scoped retention subject." + operation.RequestBody = jsonRequest("Retention override creation request.", "#/components/schemas/CreateRetentionOverrideRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created retention override envelope.", "#/components/schemas/RetentionOverrideEnvelope") + case "retentionReport": + operation.Description = "Returns a retention report for tenant-scoped holds and overrides with storage verification limitations." + operation.Parameters = append(operation.Parameters, + queryParam("scope_type", "Optional retention scope type.", "string"), + queryParam("scope_id", "Optional retention scope id.", "string"), + ) + operation.Responses[http.StatusOK] = jsonResponse("Retention report envelope.", "#/components/schemas/RetentionReportEnvelope") + case "createSaaSEditionProfile": + operation.Description = "Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim." + operation.RequestBody = jsonRequest("SaaS edition profile creation request.", "#/components/schemas/CreateSaaSEditionProfileRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created SaaS edition profile envelope.", "#/components/schemas/SaaSEditionProfileEnvelope") case "craReadinessReport": operation.Description = "Returns a CRA-oriented readiness report without legal compliance or certification conclusions." operation.Parameters = append(operation.Parameters, diff --git a/openapi.yaml b/openapi.yaml index 98f8949..20c5eed 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"operationId":"uploadAPISecurityScan","responses":{"201":{"description":"Upload API security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"operationId":"createApproval","responses":{"201":{"description":"Create approval record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"operationId":"createIncident","responses":{"201":{"description":"Create incident response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"operationId":"recordIncidentTimeline","responses":{"201":{"description":"Record incident timeline event response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"operationId":"createLegalHold","responses":{"201":{"description":"Create legal hold response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"operationId":"createMerkleBatch","responses":{"201":{"description":"Create Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"operationId":"verifyMerkleBatch","responses":{"200":{"description":"Verify Merkle checkpoint batch response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"operationId":"createObjectRetentionPolicy","responses":{"201":{"description":"Create object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"operationId":"verifyObjectRetentionPolicy","responses":{"200":{"description":"Verify object retention policy record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"operationId":"publishPublicTransparencyLogEntry","responses":{"201":{"description":"Publish public transparency log entry record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"operationId":"createPublicTransparencyLog","responses":{"201":{"description":"Create public transparency log record response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"operationId":"createRemediationTask","responses":{"201":{"description":"Create remediation task response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"operationId":"generateAnomalyReport","responses":{"201":{"description":"Generate deterministic anomaly report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"operationId":"incidentReport","responses":{"200":{"description":"Incident package report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"operationId":"retentionReport","responses":{"200":{"description":"Retention report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"operationId":"vulnerabilityPostureReport","responses":{"200":{"description":"Vulnerability posture report response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"operationId":"createRetentionOverride","responses":{"201":{"description":"Create retention override response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"operationId":"createSaaSEditionProfile","responses":{"201":{"description":"Create SaaS edition profile response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"operationId":"createSBOMDiff","responses":{"201":{"description":"Create SBOM diff response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"operationId":"uploadSPDXSBOM","responses":{"201":{"description":"Upload SPDX SBOM response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"operationId":"uploadManualSecurityDocument","responses":{"201":{"description":"Upload manual security document response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"operationId":"uploadSecurityScan","responses":{"201":{"description":"Upload security scan response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"operationId":"createTransparencyCheckpoint","responses":{"201":{"description":"Record external transparency checkpoint response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"operationId":"verify","responses":{"200":{"description":"Verify subject response"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/scripts/openapi_precision_check.py b/scripts/openapi_precision_check.py index a55234f..fb5ccda 100755 --- a/scripts/openapi_precision_check.py +++ b/scripts/openapi_precision_check.py @@ -42,8 +42,8 @@ def main() -> int: else: broad += 1 - min_precise = int_env("EVYDENCE_OPENAPI_MIN_PRECISE", 133) - max_broad = int_env("EVYDENCE_OPENAPI_MAX_BROAD", 27) + min_precise = int_env("EVYDENCE_OPENAPI_MIN_PRECISE", 160) + max_broad = int_env("EVYDENCE_OPENAPI_MAX_BROAD", 0) if precise < min_precise: print( f"openapi-precision-check: precise operations {precise} below required {min_precise}", From 3512d9aed54949287662f1f8391a78f404cba3e2 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 19:30:26 +0300 Subject: [PATCH 077/287] docs: update openapi maturity status --- docs/architecture.md | 2 +- docs/reference/openapi.md | 11 +++++------ docs/reference/production-readiness.md | 13 ++++++------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/docs/architecture.md b/docs/architecture.md index ed623e3..f2531b4 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -52,6 +52,6 @@ Air-gapped import-bundle workflows preserve the same tenant-scoped import path a ## Limitations -The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts are implemented, but production KMS/HSM provider adapters and live Sigstore/public-transparency verification remain deployment hardening work. Hand-tuned per-resource repository implementations, moving parser side effects fully out of request paths, and complete endpoint-specific OpenAPI schemas remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. +The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts are implemented, but production KMS/HSM provider adapters and live Sigstore/public-transparency verification remain deployment hardening work. Hand-tuned per-resource repository implementations and moving parser side effects fully out of request paths remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. Evydence does not prove provider truth, scanner authority, runtime security, legal compliance, or release security by itself. diff --git a/docs/reference/openapi.md b/docs/reference/openapi.md index e7924ee..a13901e 100644 --- a/docs/reference/openapi.md +++ b/docs/reference/openapi.md @@ -24,10 +24,9 @@ Check precision regression: make openapi-precision-check ``` -`make openapi-precision-check` enforces the current floor for endpoint-specific -contracts and the current ceiling for broad contracts. Raise -`EVYDENCE_OPENAPI_MIN_PRECISE` and lower `EVYDENCE_OPENAPI_MAX_BROAD` as more -routes receive concrete request and response schemas. +`make openapi-precision-check` enforces endpoint-specific contracts for all +registered public routes and fails if any operation falls back to a broad +request or response shape. `make docs-check` compares the paths in `openapi.yaml` with the endpoint catalog in [API reference](../api.md). Add every generated path to that catalog, or the docs check fails. @@ -56,8 +55,8 @@ GET /v1/openapi.json ## Current Limitations - `openapi.yaml` is generated in a compact JSON-compatible representation. -- Critical routes such as evidence creation, evidence search, release bundle verification, SSO session creation, customer portal token exchange, and instance diagnostics have more precise request/response schemas. -- Some broad resource families still use generic data envelopes while the human examples live in [API reference](../api.md) and HTTP tests. +- Registered public routes have endpoint-specific request and response schemas. +- New routes must update operation metadata, component schemas, `openapi.yaml`, and the generated [API contract matrix](api-contract-matrix.md). - Do not hand-edit `openapi.yaml`; update route metadata or the generator, then run `make openapi-check`. Route registration and OpenAPI generation use the same HTTP adapter registry so tests can catch missing routes or stale operation metadata. diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 1d332d1..bc40f61 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -19,9 +19,9 @@ Known hardening work remains: - worker parser jobs re-read raw object-store payloads for key formats and validate durable state, but parser side effects still need to move independently out of the request path; -- OpenAPI schemas need endpoint-specific precision across the full public API. - The current generated matrix is the source of truth for precise versus broad - operations; +- OpenAPI precision is enforced across the registered public API. The generated + matrix remains the source of truth for operation ids, scopes, idempotency, + parameters, and request/response schemas; - production KMS/HSM execution, full browser OIDC/SAML login flows, provider discovery/group sync, object-lock enforcement proof, and transparency inclusion proof verification remain provider- and deployment-dependent @@ -77,8 +77,7 @@ Do not describe an Evydence build as broadly self-hosted production-ready until: prefix to the current schema; - the built-in local restore rehearsal passes and backup/restore have been tested for the target deployment profile; -- OpenAPI and SDK drift checks pass, and route-contract gaps are accepted in - release notes or closed with endpoint-specific schemas; +- OpenAPI, OpenAPI precision, route-contract, and SDK drift checks pass; - production hardening review is current; - unresolved limitations are documented in release notes. @@ -98,8 +97,8 @@ implemented capabilities: - Move parser-owned side effects for SBOM, vulnerability scan, OpenAPI, VEX, and attestation payloads fully into worker processors while keeping upload responses backward compatible. -- Continue reducing broad OpenAPI operations until production-critical and - customer/package-facing routes have endpoint-specific schemas. +- Keep OpenAPI precision at zero broad operations as routes are added or + changed, and expand generated SDK coverage from the committed contract. - Add production signing-provider execution for a configured external provider profile without storing private key material in Evydence. - Complete live OIDC/SAML browser login callbacks, provider discovery, JWKS From 1c7832a751094e17c3a20b6ce4023ed753a83ae2 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 19:37:19 +0300 Subject: [PATCH 078/287] build: add sdk route catalog check --- Makefile | 3 +- docs/sdk/README.md | 6 +- scripts/generate_sdk_route_catalog.py | 60 + scripts/sdk_check.py | 28 +- sdk/openapi-route-catalog.json | 2710 +++++++++++++++++++++++++ 5 files changed, 2802 insertions(+), 5 deletions(-) create mode 100755 scripts/generate_sdk_route_catalog.py create mode 100644 sdk/openapi-route-catalog.json diff --git a/Makefile b/Makefile index 9d4ca08..2064edc 100644 --- a/Makefile +++ b/Makefile @@ -167,10 +167,11 @@ deploy-check: ## Validate deployment and air-gap skeletons exist @test -f deploy/observability/prometheus-rules.yaml @test -f deploy/observability/grafana-dashboard.json -sdk-check: ## Validate curated SDK helper coverage against OpenAPI +sdk-check: ## Validate SDK helper and generated route-catalog coverage against OpenAPI @test -f sdk/go/evydence/client.go @test -f sdk/typescript/client.ts @test -f sdk/python/evydence_client.py + @test -f sdk/openapi-route-catalog.json @python3 scripts/sdk_check.py fast-check: ## Run non-mutating fast validation diff --git a/docs/sdk/README.md b/docs/sdk/README.md index 4da5b67..efc0d52 100644 --- a/docs/sdk/README.md +++ b/docs/sdk/README.md @@ -10,7 +10,9 @@ The wrappers provide authenticated JSON helpers with explicit idempotency keys a - TypeScript: `sdk/typescript/client.ts` - Python: `sdk/python/evydence_client.py` -They do not expose typed methods for every route. The current typed coverage is intentionally narrow: products, releases, artifacts, build runs, process readiness, release-readiness reports, SSO provider creation, and provider identity verification. Broader generated clients should be regenerated from the committed `openapi.yaml`, reviewed, and released through a separate SDK publishing process. +They do not expose typed methods for every route. The current typed coverage is intentionally narrow: products, releases, artifacts, build runs, process readiness, release-readiness reports, SSO provider creation, and provider identity verification. + +The generated SDK route catalog at [`sdk/openapi-route-catalog.json`](../../sdk/openapi-route-catalog.json) lists every committed public operation with method, path, scopes, idempotency requirement, and request/response schema references. Use that catalog as the checked input for broader generated clients, then review and release language-specific packages through a separate SDK publishing process. No package publishing manifests are committed for these wrappers yet. Use them as in-repository examples or copy them into an application-owned SDK package until a release process publishes versioned SDK artifacts. @@ -120,4 +122,4 @@ make test make sdk-check ``` -`make sdk-check` runs `scripts/sdk_check.py`, which verifies that the curated helper methods still map to committed OpenAPI operations, idempotent routes still require `Idempotency-Key`, and SDKs keep basic `/v1/` path validation. Generated SDK publishing is not an API runtime dependency. Keep generated clients tied to the committed `openapi.yaml` and document any route coverage gaps at release time. +`make sdk-check` runs `scripts/sdk_check.py`, which verifies that the curated helper methods still map to committed OpenAPI operations, idempotent routes still require `Idempotency-Key`, SDKs keep basic `/v1/` path validation, and the generated route catalog matches `openapi.yaml`. Generated SDK publishing is not an API runtime dependency. Keep generated clients tied to the committed `openapi.yaml` and document any route coverage gaps at release time. diff --git a/scripts/generate_sdk_route_catalog.py b/scripts/generate_sdk_route_catalog.py new file mode 100755 index 0000000..43270e8 --- /dev/null +++ b/scripts/generate_sdk_route_catalog.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +"""Generate a deterministic SDK route catalog from committed OpenAPI.""" + +from __future__ import annotations + +import json +import pathlib + + +ROOT = pathlib.Path(__file__).resolve().parents[1] + + +def success_statuses(operation: dict) -> list[str]: + statuses: list[str] = [] + for status in sorted(operation.get("responses", {})): + if status.isdigit() and 200 <= int(status) < 300: + statuses.append(status) + return statuses + + +def main() -> None: + spec = json.loads((ROOT / "openapi.yaml").read_text(encoding="utf-8")) + routes: list[dict] = [] + for path, methods in sorted(spec.get("paths", {}).items()): + for method, operation in sorted(methods.items()): + if method.lower() not in {"get", "post", "put", "patch", "delete"}: + continue + routes.append( + { + "operation_id": operation.get("operationId", ""), + "method": method.upper(), + "path": path, + "scopes": operation.get("x-scopes", []), + "idempotency_key_required": bool(operation.get("x-idempotency-key", {}).get("required")), + "request_schema": operation.get("requestBody", {}) + .get("content", {}) + .get("application/json", {}) + .get("schema", {}) + .get("$ref", ""), + "success_statuses": success_statuses(operation), + "response_schemas": sorted( + { + media.get("schema", {}).get("$ref", "") + for response in operation.get("responses", {}).values() + for media in response.get("content", {}).values() + if media.get("schema", {}).get("$ref") + } + ), + } + ) + output = { + "source": "openapi.yaml", + "route_count": len(routes), + "routes": routes, + } + print(json.dumps(output, indent=2, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/scripts/sdk_check.py b/scripts/sdk_check.py index f1d14f0..b90bad9 100755 --- a/scripts/sdk_check.py +++ b/scripts/sdk_check.py @@ -1,10 +1,11 @@ #!/usr/bin/env python3 -"""Validate curated SDK helper coverage against the committed OpenAPI contract.""" +"""Validate SDK helper and route-catalog coverage against committed OpenAPI.""" from __future__ import annotations import json import pathlib +import subprocess import sys from dataclasses import dataclass @@ -107,6 +108,26 @@ def require_text(source: str, token: str, label: str) -> None: def main() -> None: spec = load_openapi() + catalog_path = ROOT / "sdk" / "openapi-route-catalog.json" + if not catalog_path.exists(): + fail("missing sdk/openapi-route-catalog.json") + generated_catalog = subprocess.check_output( + [sys.executable, str(ROOT / "scripts" / "generate_sdk_route_catalog.py")], + text=True, + ) + committed_catalog = catalog_path.read_text(encoding="utf-8") + if json.loads(generated_catalog) != json.loads(committed_catalog): + fail("sdk/openapi-route-catalog.json is out of date; run scripts/generate_sdk_route_catalog.py") + catalog = json.loads(committed_catalog) + if catalog.get("route_count") != len( + [ + None + for path_item in spec.get("paths", {}).values() + for method in path_item + if method.lower() in {"get", "post", "put", "patch", "delete"} + ] + ): + fail("SDK route catalog route_count does not match openapi.yaml") for helper in REQUIRED_HELPERS: operation(spec, helper) @@ -123,7 +144,10 @@ def main() -> None: require_text(typescript_client, "path.startsWith(\"/v1/\")", "TypeScript SDK path validation") require_text(python_client, "path.startswith(\"/v1/\")", "Python SDK path validation") - print(f"sdk-check: validated {len(REQUIRED_HELPERS)} SDK helpers against openapi.yaml") + print( + f"sdk-check: validated {len(REQUIRED_HELPERS)} SDK helpers and " + f"{catalog.get('route_count')} generated route catalog entries against openapi.yaml" + ) if __name__ == "__main__": diff --git a/sdk/openapi-route-catalog.json b/sdk/openapi-route-catalog.json new file mode 100644 index 0000000..a63df4f --- /dev/null +++ b/sdk/openapi-route-catalog.json @@ -0,0 +1,2710 @@ +{ + "route_count": 160, + "routes": [ + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "instanceAdminSnapshot", + "path": "/v1/admin/instance", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/InstanceAdminSnapshotEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "instance:admin" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "listAPIKeys", + "path": "/v1/api-keys", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/APIKeyListEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "admin" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createAPIKey", + "path": "/v1/api-keys", + "request_schema": "#/components/schemas/CreateAPIKeyRequest", + "response_schemas": [ + "#/components/schemas/APIKeyCreateEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "admin" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "uploadAPISecurityScan", + "path": "/v1/api-security-scans", + "request_schema": "#/components/schemas/UploadSecurityScanRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SecurityScanEnvelope" + ], + "scopes": [ + "security:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createApproval", + "path": "/v1/approvals", + "request_schema": "#/components/schemas/CreateApprovalRequest", + "response_schemas": [ + "#/components/schemas/ApprovalRecordEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "release:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createArtifactSignature", + "path": "/v1/artifact-signatures", + "request_schema": "#/components/schemas/CreateArtifactSignatureRequest", + "response_schemas": [ + "#/components/schemas/ArtifactSignatureEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "evidence:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "getArtifactSignature", + "path": "/v1/artifact-signatures/{id}", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/ArtifactSignatureEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "evidence:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "verifyCosignSignature", + "path": "/v1/artifact-signatures/{id}/verify-cosign", + "request_schema": "#/components/schemas/VerifyCosignSignatureRequest", + "response_schemas": [ + "#/components/schemas/CosignVerificationEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "verify:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "registerArtifact", + "path": "/v1/artifacts", + "request_schema": "#/components/schemas/RegisterArtifactRequest", + "response_schemas": [ + "#/components/schemas/ArtifactEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "evidence:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "verifyAuditChain", + "path": "/v1/audit-chain/verify", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/VerificationResultEnvelope" + ], + "scopes": [ + "verify:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "listAuditLog", + "path": "/v1/audit-log", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/AuditChainEntryListEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "admin" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "generateBackupManifest", + "path": "/v1/backup-manifests", + "request_schema": "#/components/schemas/EmptyObject", + "response_schemas": [ + "#/components/schemas/BackupManifestEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "admin" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "verifyBackupManifest", + "path": "/v1/backup-manifests/{id}/verify", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/VerificationResultEnvelope" + ], + "scopes": [ + "verify:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "verifyBuildAttestationSignature", + "path": "/v1/build-attestations/{id}/verify-signature", + "request_schema": "#/components/schemas/EmptyObject", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/VerificationResultEnvelope" + ], + "scopes": [ + "verify:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createBuild", + "path": "/v1/builds", + "request_schema": "#/components/schemas/CreateBuildRequest", + "response_schemas": [ + "#/components/schemas/BuildRunEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "build:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "getBuild", + "path": "/v1/builds/{id}", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/BuildRunEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "build:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "uploadBuildAttestation", + "path": "/v1/builds/{id}/attestations", + "request_schema": "#/components/schemas/DSSEEnvelope", + "response_schemas": [ + "#/components/schemas/BuildAttestationEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "build:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "listCollectors", + "path": "/v1/collectors", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/CollectorListEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "collector:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createCollector", + "path": "/v1/collectors", + "request_schema": "#/components/schemas/CreateCollectorRequest", + "response_schemas": [ + "#/components/schemas/CollectorCreateEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "collector:admin" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "uploadGitHubSourceSnapshot", + "path": "/v1/collectors/github/source-snapshots", + "request_schema": "#/components/schemas/SourceSnapshotRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SourceSnapshotEnvelope" + ], + "scopes": [ + "source:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "uploadGitLabSourceSnapshot", + "path": "/v1/collectors/gitlab/source-snapshots", + "request_schema": "#/components/schemas/SourceSnapshotRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SourceSnapshotEnvelope" + ], + "scopes": [ + "source:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "collectorHealthReport", + "path": "/v1/collectors/{id}/health", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/CollectorHealthReportEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "collector:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "recordCollectorRelease", + "path": "/v1/collectors/{id}/releases", + "request_schema": "#/components/schemas/RecordCollectorReleaseRequest", + "response_schemas": [ + "#/components/schemas/CollectorReleaseEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "collector:admin" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "listCommercialCollectors", + "path": "/v1/commercial-collectors", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/CommercialCollectorDefinitionListEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "collector:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createCommercialCollector", + "path": "/v1/commercial-collectors", + "request_schema": "#/components/schemas/CreateCommercialCollectorRequest", + "response_schemas": [ + "#/components/schemas/CommercialCollectorDefinitionEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "collector:admin" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "registerContainerImage", + "path": "/v1/container-images", + "request_schema": "#/components/schemas/RegisterContainerImageRequest", + "response_schemas": [ + "#/components/schemas/ContainerImageEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "evidence:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "listControlEvidence", + "path": "/v1/control-evidence", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/ControlEvidenceListEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "controls:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "listControlFrameworkTemplatePacks", + "path": "/v1/control-framework-template-packs", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/ControlFrameworkTemplatePackListEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "controls:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "installControlFrameworkTemplatePack", + "path": "/v1/control-framework-template-packs/{slug}/install", + "request_schema": "#/components/schemas/EmptyObject", + "response_schemas": [ + "#/components/schemas/ControlFrameworkEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "controls:admin" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "listControlFrameworks", + "path": "/v1/control-frameworks", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/ControlFrameworkListEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "controls:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createControlFramework", + "path": "/v1/control-frameworks", + "request_schema": "#/components/schemas/CreateControlFrameworkRequest", + "response_schemas": [ + "#/components/schemas/ControlFrameworkEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "controls:admin" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createSecurityControl", + "path": "/v1/controls", + "request_schema": "#/components/schemas/CreateSecurityControlRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SecurityControlEnvelope" + ], + "scopes": [ + "controls:admin" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "getSecurityControl", + "path": "/v1/controls/{id}", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SecurityControlEnvelope" + ], + "scopes": [ + "controls:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "linkControlEvidence", + "path": "/v1/controls/{id}/evidence", + "request_schema": "#/components/schemas/LinkControlEvidenceRequest", + "response_schemas": [ + "#/components/schemas/ControlEvidenceEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "controls:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createCustomPolicy", + "path": "/v1/custom-policies", + "request_schema": "#/components/schemas/CreateCustomPolicyRequest", + "response_schemas": [ + "#/components/schemas/CustomPolicyEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "policy:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "evaluateCustomPolicy", + "path": "/v1/custom-policies/{id}/evaluate", + "request_schema": "#/components/schemas/EvaluatePolicyRequest", + "response_schemas": [ + "#/components/schemas/CustomPolicyEvaluationEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "policy:read" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createCustomerPackage", + "path": "/v1/customer-packages", + "request_schema": "#/components/schemas/CreateCustomerPackageRequest", + "response_schemas": [ + "#/components/schemas/CustomerSecurityPackageEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "package:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "getCustomerPackage", + "path": "/v1/customer-packages/{id}", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/CustomerSecurityPackageEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "package:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "downloadCustomerPackage", + "path": "/v1/customer-packages/{id}/download", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem" + ], + "scopes": [ + "package:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createCustomerPortalAccess", + "path": "/v1/customer-portal/access", + "request_schema": "#/components/schemas/CreateCustomerPortalAccessRequest", + "response_schemas": [ + "#/components/schemas/CustomerPortalAccessCreateEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "package:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "accessCustomerPortalPackage", + "path": "/v1/customer-portal/package", + "request_schema": "#/components/schemas/CustomerPortalPackageRequest", + "response_schemas": [ + "#/components/schemas/CustomerSecurityPackageEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "downloadCustomerPortalPackage", + "path": "/v1/customer-portal/package/download", + "request_schema": "#/components/schemas/CustomerPortalPackageRequest", + "response_schemas": [ + "#/components/schemas/Problem" + ], + "scopes": [], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "listDeployments", + "path": "/v1/deployments", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/DeploymentEventListEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "deployment:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "recordDeployment", + "path": "/v1/deployments", + "request_schema": "#/components/schemas/RecordDeploymentRequest", + "response_schemas": [ + "#/components/schemas/DeploymentEventEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "deployment:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "getDeployment", + "path": "/v1/deployments/{id}", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/DeploymentEventEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "deployment:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createDSSETrustRoot", + "path": "/v1/dsse-trust-roots", + "request_schema": "#/components/schemas/CreateDSSETrustRootRequest", + "response_schemas": [ + "#/components/schemas/DSSETrustRootEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "keys:admin" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "listDeploymentEnvironments", + "path": "/v1/environments", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/DeploymentEnvironmentListEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "deployment:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createDeploymentEnvironment", + "path": "/v1/environments", + "request_schema": "#/components/schemas/CreateDeploymentEnvironmentRequest", + "response_schemas": [ + "#/components/schemas/DeploymentEnvironmentEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "deployment:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "listEvidence", + "path": "/v1/evidence", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/EvidenceItemListEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "evidence:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createEvidence", + "path": "/v1/evidence", + "request_schema": "#/components/schemas/CreateEvidenceRequest", + "response_schemas": [ + "#/components/schemas/EvidenceItemEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "evidence:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "exportEvidenceBundle", + "path": "/v1/evidence-bundles", + "request_schema": "#/components/schemas/ExportEvidenceBundleRequest", + "response_schemas": [ + "#/components/schemas/EvidenceBundleEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "bundle:read" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "importEvidenceBundle", + "path": "/v1/evidence-bundles/import", + "request_schema": "#/components/schemas/EvidenceBundle", + "response_schemas": [ + "#/components/schemas/EvidenceBundleImportEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "bundle:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createGraphSnapshot", + "path": "/v1/evidence-graph-snapshots", + "request_schema": "#/components/schemas/CreateGraphSnapshotRequest", + "response_schemas": [ + "#/components/schemas/EvidenceGraphSnapshotEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "evidence:read" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createEvidenceSummary", + "path": "/v1/evidence-summaries", + "request_schema": "#/components/schemas/CreateEvidenceSummaryRequest", + "response_schemas": [ + "#/components/schemas/EvidenceSummaryEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "report:read" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "searchEvidence", + "path": "/v1/evidence/search", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/EvidenceSearchEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "evidence:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "getEvidence", + "path": "/v1/evidence/{id}", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/EvidenceItemEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "evidence:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "listEvidenceLifecycleEvents", + "path": "/v1/evidence/{id}/lifecycle-events", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/EvidenceLifecycleEventListEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "evidence:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "recordEvidenceLifecycleEvent", + "path": "/v1/evidence/{id}/lifecycle-events", + "request_schema": "#/components/schemas/RecordEvidenceLifecycleEventRequest", + "response_schemas": [ + "#/components/schemas/EvidenceLifecycleEventEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "evidence:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "linkEvidence", + "path": "/v1/evidence/{id}/link", + "request_schema": "#/components/schemas/LinkEvidenceRequest", + "response_schemas": [ + "#/components/schemas/EvidenceItemEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "evidence:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "supersedeEvidence", + "path": "/v1/evidence/{id}/supersede", + "request_schema": "#/components/schemas/SupersedeEvidenceRequest", + "response_schemas": [ + "#/components/schemas/EvidenceItemEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "evidence:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "listExceptions", + "path": "/v1/exceptions", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/ExceptionListEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "verify:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createException", + "path": "/v1/exceptions", + "request_schema": "#/components/schemas/CreateExceptionRequest", + "response_schemas": [ + "#/components/schemas/ExceptionEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "release:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "approveException", + "path": "/v1/exceptions/{id}/approve", + "request_schema": "#/components/schemas/EmptyObject", + "response_schemas": [ + "#/components/schemas/ExceptionEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "release:write" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "health", + "path": "/v1/health", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/HealthStatusEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": false, + "method": "POST", + "operation_id": "receiveIncidentWebhook", + "path": "/v1/incident-webhooks/{receiver_id}", + "request_schema": "#/components/schemas/SignedIncidentWebhookPayload", + "response_schemas": [ + "#/components/schemas/IncidentWebhookDeliveryEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createIncident", + "path": "/v1/incidents", + "request_schema": "#/components/schemas/CreateIncidentRequest", + "response_schemas": [ + "#/components/schemas/IncidentEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "incident:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "recordIncidentTimeline", + "path": "/v1/incidents/{id}/timeline", + "request_schema": "#/components/schemas/RecordIncidentTimelineRequest", + "response_schemas": [ + "#/components/schemas/IncidentTimelineEventEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "incident:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createIncidentWebhookReceiver", + "path": "/v1/incidents/{id}/webhook-receivers", + "request_schema": "#/components/schemas/CreateIncidentWebhookReceiverRequest", + "response_schemas": [ + "#/components/schemas/IncidentWebhookReceiverEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "incident:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createLegalHold", + "path": "/v1/legal-holds", + "request_schema": "#/components/schemas/CreateLegalHoldRequest", + "response_schemas": [ + "#/components/schemas/LegalHoldEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "admin" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "listMarketplaceCollectors", + "path": "/v1/marketplace-collectors", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/MarketplaceCollectorListEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "collector:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createMarketplaceCollector", + "path": "/v1/marketplace-collectors", + "request_schema": "#/components/schemas/CreateMarketplaceCollectorRequest", + "response_schemas": [ + "#/components/schemas/MarketplaceCollectorEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "collector:admin" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "marketplaceCollectorHealth", + "path": "/v1/marketplace-collectors/{id}/health", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/MarketplaceCollectorHealthReportEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "collector:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createMerkleBatch", + "path": "/v1/merkle-batches", + "request_schema": "#/components/schemas/CreateMerkleBatchRequest", + "response_schemas": [ + "#/components/schemas/MerkleBatchEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "keys:admin" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "verifyMerkleBatch", + "path": "/v1/merkle-batches/{id}/verify", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/VerificationResultEnvelope" + ], + "scopes": [ + "verify:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "metrics", + "path": "/v1/metrics", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/MetricsSnapshotEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "admin" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createObjectRetentionPolicy", + "path": "/v1/object-retention-policies", + "request_schema": "#/components/schemas/CreateObjectRetentionPolicyRequest", + "response_schemas": [ + "#/components/schemas/ObjectRetentionPolicyEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "admin" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "verifyObjectRetentionPolicy", + "path": "/v1/object-retention-policies/{id}/verify", + "request_schema": "#/components/schemas/EmptyObject", + "response_schemas": [ + "#/components/schemas/ObjectRetentionPolicyEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "verify:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "uploadOpenAPIContract", + "path": "/v1/openapi-contracts", + "request_schema": "#/components/schemas/UploadOpenAPIContractRequest", + "response_schemas": [ + "#/components/schemas/OpenAPIContractEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "evidence:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "getOpenAPIContract", + "path": "/v1/openapi-contracts/{id}", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/OpenAPIContractEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "evidence:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createOpenAPIDiff", + "path": "/v1/openapi-diffs", + "request_schema": "#/components/schemas/CreateOpenAPIDiffRequest", + "response_schemas": [ + "#/components/schemas/ContractDiffEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "evidence:read" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "openapi", + "path": "/v1/openapi.json", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/OpenAPIDocument", + "#/components/schemas/Problem" + ], + "scopes": [], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createOrganization", + "path": "/v1/organizations", + "request_schema": "#/components/schemas/CreateOrganizationRequest", + "response_schemas": [ + "#/components/schemas/OrganizationEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "identity:admin" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "evaluatePolicy", + "path": "/v1/policies/evaluate", + "request_schema": "#/components/schemas/EvaluatePolicyRequest", + "response_schemas": [ + "#/components/schemas/PolicyEvaluationEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "verify:read" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "listProducts", + "path": "/v1/products", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/ProductListEnvelope" + ], + "scopes": [ + "product:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createProduct", + "path": "/v1/products", + "request_schema": "#/components/schemas/CreateProductRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/ProductEnvelope" + ], + "scopes": [ + "product:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createProject", + "path": "/v1/projects", + "request_schema": "#/components/schemas/CreateProjectRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/ProjectEnvelope" + ], + "scopes": [ + "project:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "verifyProviderIdentity", + "path": "/v1/provider-verifications", + "request_schema": "#/components/schemas/VerifyProviderIdentityRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/ProviderVerificationEnvelope" + ], + "scopes": [ + "identity:admin" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "publishPublicTransparencyLogEntry", + "path": "/v1/public-transparency-log-entries", + "request_schema": "#/components/schemas/PublishPublicTransparencyLogEntryRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/PublicTransparencyLogEntryEnvelope" + ], + "scopes": [ + "keys:admin" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createPublicTransparencyLog", + "path": "/v1/public-transparency-logs", + "request_schema": "#/components/schemas/CreatePublicTransparencyLogRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/PublicTransparencyLogEnvelope" + ], + "scopes": [ + "keys:admin" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createQuestionnaireDraft", + "path": "/v1/questionnaire-drafts", + "request_schema": "#/components/schemas/CreateQuestionnaireDraftRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/QuestionnaireDraftEnvelope" + ], + "scopes": [ + "package:read" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createQuestionnairePackage", + "path": "/v1/questionnaire-packages", + "request_schema": "#/components/schemas/CreateQuestionnairePackageRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/QuestionnairePackageEnvelope" + ], + "scopes": [ + "package:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createQuestionnaireTemplate", + "path": "/v1/questionnaire-templates", + "request_schema": "#/components/schemas/CreateQuestionnaireTemplateRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/QuestionnaireTemplateEnvelope" + ], + "scopes": [ + "package:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "ready", + "path": "/v1/ready", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/ReadinessStatusEnvelope" + ], + "scopes": [], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createRedactionProfile", + "path": "/v1/redaction-profiles", + "request_schema": "#/components/schemas/CreateRedactionProfileRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/RedactionProfileEnvelope" + ], + "scopes": [ + "package:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createReleaseBundle", + "path": "/v1/release-bundles", + "request_schema": "#/components/schemas/CreateReleaseBundleRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/ReleaseBundleEnvelope" + ], + "scopes": [ + "bundle:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "getReleaseBundle", + "path": "/v1/release-bundles/{id}", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/ReleaseBundleEnvelope" + ], + "scopes": [ + "bundle:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "getReleaseBundleManifest", + "path": "/v1/release-bundles/{id}/manifest", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/ReleaseBundleManifestEnvelope" + ], + "scopes": [ + "bundle:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "verifyReleaseBundle", + "path": "/v1/release-bundles/{id}/verify", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/VerificationResultEnvelope" + ], + "scopes": [ + "verify:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "listReleaseCandidates", + "path": "/v1/release-candidates", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/ReleaseCandidateListEnvelope" + ], + "scopes": [ + "release:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createReleaseCandidate", + "path": "/v1/release-candidates", + "request_schema": "#/components/schemas/CreateReleaseCandidateRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/ReleaseCandidateEnvelope" + ], + "scopes": [ + "release:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "getReleaseCandidate", + "path": "/v1/release-candidates/{id}", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/ReleaseCandidateEnvelope" + ], + "scopes": [ + "release:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "promoteReleaseCandidate", + "path": "/v1/release-candidates/{id}/promote", + "request_schema": "#/components/schemas/ReleaseCandidateTransitionRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/ReleaseCandidateEnvelope" + ], + "scopes": [ + "release:write" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "rejectReleaseCandidate", + "path": "/v1/release-candidates/{id}/reject", + "request_schema": "#/components/schemas/ReleaseCandidateTransitionRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/ReleaseCandidateEnvelope" + ], + "scopes": [ + "release:write" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createRelease", + "path": "/v1/releases", + "request_schema": "#/components/schemas/CreateReleaseRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/ReleaseEnvelope" + ], + "scopes": [ + "release:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "getRelease", + "path": "/v1/releases/{id}", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/ReleaseEnvelope" + ], + "scopes": [ + "release:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "approveRelease", + "path": "/v1/releases/{id}/approve", + "request_schema": "#/components/schemas/EmptyObject", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/ReleaseEnvelope" + ], + "scopes": [ + "release:write" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "freezeRelease", + "path": "/v1/releases/{id}/freeze", + "request_schema": "#/components/schemas/EmptyObject", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/ReleaseEnvelope" + ], + "scopes": [ + "release:write" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createRemediationTask", + "path": "/v1/remediation-tasks", + "request_schema": "#/components/schemas/CreateRemediationTaskRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/RemediationTaskEnvelope" + ], + "scopes": [ + "incident:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createReportTemplate", + "path": "/v1/report-templates", + "request_schema": "#/components/schemas/CreateReportTemplateRequest", + "response_schemas": [ + "#/components/schemas/CustomReportTemplateEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "report:read" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "renderReportTemplate", + "path": "/v1/report-templates/{id}/render", + "request_schema": "#/components/schemas/RenderReportTemplateRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/RenderedCustomReportEnvelope" + ], + "scopes": [ + "report:read" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "generateAnomalyReport", + "path": "/v1/reports/anomaly", + "request_schema": "#/components/schemas/CreateAnomalyReportRequest", + "response_schemas": [ + "#/components/schemas/AnomalyReportEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "report:read" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "controlCoverageReport", + "path": "/v1/reports/control-coverage", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/ReadinessReportEnvelope" + ], + "scopes": [ + "report:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "craReadinessReport", + "path": "/v1/reports/cra-readiness", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/ReadinessReportEnvelope" + ], + "scopes": [ + "report:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "craReadinessHTMLPackage", + "path": "/v1/reports/cra-readiness-html", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/HTMLReportPackageEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "report:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "incidentReport", + "path": "/v1/reports/incident-package", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/IncidentReportEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "incident:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "missingEvidenceReport", + "path": "/v1/reports/missing-evidence", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/MissingEvidenceReportEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "verify:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createPDFReportPackage", + "path": "/v1/reports/pdf", + "request_schema": "#/components/schemas/CreatePDFReportPackageRequest", + "response_schemas": [ + "#/components/schemas/PDFReportPackageEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "report:read" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "releaseReadinessReport", + "path": "/v1/reports/release-readiness", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/ReadinessReportEnvelope" + ], + "scopes": [ + "verify:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "retentionReport", + "path": "/v1/reports/retention", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/RetentionReportEnvelope" + ], + "scopes": [ + "admin" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "securityReviewPackageReport", + "path": "/v1/reports/security-review-package", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SecurityReviewPackageReportEnvelope" + ], + "scopes": [ + "package:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "vulnerabilityPostureReport", + "path": "/v1/reports/vulnerability-posture", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/VulnerabilityPostureReportEnvelope" + ], + "scopes": [ + "security:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createRetentionOverride", + "path": "/v1/retention-overrides", + "request_schema": "#/components/schemas/CreateRetentionOverrideRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/RetentionOverrideEnvelope" + ], + "scopes": [ + "admin" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "listRoleBindings", + "path": "/v1/role-bindings", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/RoleBindingListEnvelope" + ], + "scopes": [ + "identity:admin" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createRoleBinding", + "path": "/v1/role-bindings", + "request_schema": "#/components/schemas/CreateRoleBindingRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/RoleBindingEnvelope" + ], + "scopes": [ + "identity:admin" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createSaaSEditionProfile", + "path": "/v1/saas/profiles", + "request_schema": "#/components/schemas/CreateSaaSEditionProfileRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SaaSEditionProfileEnvelope" + ], + "scopes": [ + "instance:admin" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "listSBOMComponents", + "path": "/v1/sbom-components", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SBOMComponentRecordListEnvelope" + ], + "scopes": [ + "evidence:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createSBOMDiff", + "path": "/v1/sbom-diffs", + "request_schema": "#/components/schemas/CreateSBOMDiffRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SBOMDiffEnvelope" + ], + "scopes": [ + "evidence:read" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "uploadSBOM", + "path": "/v1/sboms", + "request_schema": "#/components/schemas/EvidenceUploadRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SBOMEnvelope" + ], + "scopes": [ + "evidence:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "uploadSPDXSBOM", + "path": "/v1/sboms/spdx", + "request_schema": "#/components/schemas/UploadSPDXSBOMRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SBOMEnvelope" + ], + "scopes": [ + "evidence:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "getSBOM", + "path": "/v1/sboms/{id}", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SBOMEnvelope" + ], + "scopes": [ + "evidence:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "uploadManualSecurityDocument", + "path": "/v1/security-documents", + "request_schema": "#/components/schemas/UploadManualSecurityDocumentRequest", + "response_schemas": [ + "#/components/schemas/ManualSecurityDocumentEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "security:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "uploadSecurityScan", + "path": "/v1/security-scans", + "request_schema": "#/components/schemas/UploadSecurityScanRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SecurityScanEnvelope" + ], + "scopes": [ + "security:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "listSigningKeys", + "path": "/v1/signing-keys", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SigningKeyListEnvelope" + ], + "scopes": [ + "verify:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "rotateSigningKey", + "path": "/v1/signing-keys/rotate", + "request_schema": "#/components/schemas/SigningKeyTransitionRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SigningKeyEnvelope" + ], + "scopes": [ + "keys:admin" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "revokeSigningKey", + "path": "/v1/signing-keys/{id}/revoke", + "request_schema": "#/components/schemas/SigningKeyTransitionRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SigningKeyEnvelope" + ], + "scopes": [ + "keys:admin" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createSigningOperation", + "path": "/v1/signing-operations", + "request_schema": "#/components/schemas/CreateSigningOperationRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SigningOperationEnvelope" + ], + "scopes": [ + "keys:admin" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createSigningProvider", + "path": "/v1/signing-providers", + "request_schema": "#/components/schemas/CreateSigningProviderRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SigningProviderEnvelope" + ], + "scopes": [ + "keys:admin" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "upsertSourceBranch", + "path": "/v1/source/branches", + "request_schema": "#/components/schemas/UpsertSourceBranchRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SourceBranchEnvelope" + ], + "scopes": [ + "source:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "recordSourceCommit", + "path": "/v1/source/commits", + "request_schema": "#/components/schemas/RecordSourceCommitRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SourceCommitEnvelope" + ], + "scopes": [ + "source:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "recordPullRequest", + "path": "/v1/source/pull-requests", + "request_schema": "#/components/schemas/RecordPullRequestRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/PullRequestEnvelope" + ], + "scopes": [ + "source:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "listSourceRepositories", + "path": "/v1/source/repositories", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SourceRepositoryListEnvelope" + ], + "scopes": [ + "source:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createSourceRepository", + "path": "/v1/source/repositories", + "request_schema": "#/components/schemas/CreateSourceRepositoryRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SourceRepositoryEnvelope" + ], + "scopes": [ + "source:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "linkSSOIdentity", + "path": "/v1/sso/identity-links", + "request_schema": "#/components/schemas/LinkSSOIdentityRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/UserIdentityLinkEnvelope" + ], + "scopes": [ + "identity:admin" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createSSOProvider", + "path": "/v1/sso/providers", + "request_schema": "#/components/schemas/CreateSSOProviderRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SSOProviderEnvelope" + ], + "scopes": [ + "identity:admin" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createSSOSession", + "path": "/v1/sso/sessions", + "request_schema": "#/components/schemas/CreateSSOSessionRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SSOSessionCreateEnvelope" + ], + "scopes": [ + "identity:admin" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "revokeSSOSession", + "path": "/v1/sso/sessions/{id}/revoke", + "request_schema": "#/components/schemas/EmptyObject", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SSOSessionEnvelope" + ], + "scopes": [ + "identity:admin" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createTransparencyCheckpoint", + "path": "/v1/transparency-checkpoints", + "request_schema": "#/components/schemas/CreateTransparencyCheckpointRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/TransparencyCheckpointEnvelope" + ], + "scopes": [ + "keys:admin" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createUser", + "path": "/v1/users", + "request_schema": "#/components/schemas/CreateUserRequest", + "response_schemas": [ + "#/components/schemas/HumanUserEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "identity:admin" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "deactivateUser", + "path": "/v1/users/{id}/deactivate", + "request_schema": "#/components/schemas/EmptyObject", + "response_schemas": [ + "#/components/schemas/HumanUserEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "identity:admin" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "verify", + "path": "/v1/verify", + "request_schema": "#/components/schemas/VerifySubjectRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/VerificationResultEnvelope" + ], + "scopes": [ + "verify:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "version", + "path": "/v1/version", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/VersionInfoEnvelope" + ], + "scopes": [], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "uploadVEX", + "path": "/v1/vex", + "request_schema": "#/components/schemas/EvidenceUploadRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/VEXDocumentEnvelope" + ], + "scopes": [ + "evidence:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "uploadCycloneDXVEX", + "path": "/v1/vex/cyclonedx", + "request_schema": "#/components/schemas/EvidenceUploadRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/VEXDocumentEnvelope" + ], + "scopes": [ + "evidence:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "getVEX", + "path": "/v1/vex/{id}", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/VEXDocumentEnvelope" + ], + "scopes": [ + "evidence:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createVulnerabilityDecision", + "path": "/v1/vulnerability-findings/{id}/decisions", + "request_schema": "#/components/schemas/CreateVulnerabilityDecisionRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/VulnerabilityDecisionEnvelope" + ], + "scopes": [ + "evidence:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "recordVulnerabilityWorkflow", + "path": "/v1/vulnerability-findings/{id}/workflow", + "request_schema": "#/components/schemas/RecordVulnerabilityWorkflowRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/VulnerabilityWorkflowRecordEnvelope" + ], + "scopes": [ + "security:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "uploadVulnerabilityScan", + "path": "/v1/vulnerability-scans", + "request_schema": "#/components/schemas/UploadVulnerabilityScanRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/VulnerabilityScanEnvelope" + ], + "scopes": [ + "evidence:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "getVulnerabilityScan", + "path": "/v1/vulnerability-scans/{id}", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/VulnerabilityScanEnvelope" + ], + "scopes": [ + "evidence:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createWaiver", + "path": "/v1/waivers", + "request_schema": "#/components/schemas/CreateWaiverRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/WaiverEnvelope" + ], + "scopes": [ + "policy:write" + ], + "success_statuses": [ + "201" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "approveWaiver", + "path": "/v1/waivers/{id}/approve", + "request_schema": "#/components/schemas/EmptyObject", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/WaiverEnvelope" + ], + "scopes": [ + "policy:write" + ], + "success_statuses": [ + "200" + ] + } + ], + "source": "openapi.yaml" +} From a8b734ca36bb04cfd71d3b715461fb2ef918f7ac Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 19:38:57 +0300 Subject: [PATCH 079/287] test: add postgres restore rehearsal --- docs/production-hardening.md | 2 +- docs/reference/production-readiness.md | 3 + internal/adapters/postgres/store_test.go | 157 +++++++++++++++++++++++ 3 files changed, 161 insertions(+), 1 deletion(-) diff --git a/docs/production-hardening.md b/docs/production-hardening.md index 1c6380b..062d3a9 100644 --- a/docs/production-hardening.md +++ b/docs/production-hardening.md @@ -34,7 +34,7 @@ These checks are enforced by API startup. See [Configuration](reference/configur - Audit-chain verification and release-bundle verification are run after restore. - `POST /v1/backup-manifests` is recorded after the database and object-store backups complete. -The repository includes a local restore rehearsal that saves ledger state, copies object payloads, starts a fresh ledger from the restored state, verifies a backup manifest, checks payload digest availability, and verifies a release bundle after restore. Deployment-specific restore tests still need to exercise the target PostgreSQL, object store, secrets, signing provider, and backup tooling. +The repository includes local and live-PostgreSQL restore rehearsals. They save ledger state, copy object payloads, start a fresh ledger from the restored state or schema, verify a backup manifest, check payload digest availability, and verify a release bundle after restore. Deployment-specific restore tests still need to exercise the target backup tooling, S3/MinIO bucket policy, secrets, signing provider, and operator recovery procedure. Backup manifests help compare recorded ledger state. They intentionally exclude raw payload bytes and private signing-key material, so they cannot replace matched database and object-store backups. diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index bc40f61..a3f0144 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -52,6 +52,9 @@ The gate requires: - `make coverage-check` passing at the configured threshold; - migration compatibility from every committed migration prefix to the current schema passing in temporary PostgreSQL schemas; +- live PostgreSQL backup/restore rehearsal preserving ledger state, object + payload digests, backup-manifest verification, and release-bundle + verification after restore; - release artifact signing smoke test passing with local temporary keys; - generated release evidence summary available under `tmp/`. diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index 404dccd..f66e28f 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -3,12 +3,14 @@ package postgres import ( "context" "os" + "path/filepath" "strings" "testing" "time" "github.com/jackc/pgx/v5" + fsobject "github.com/aatuh/evydence/internal/adapters/objectstore/filesystem" "github.com/aatuh/evydence/internal/app" "github.com/aatuh/evydence/internal/domain" ) @@ -140,3 +142,158 @@ func TestPendingMigrationVersionsWithPostgres(t *testing.T) { t.Fatalf("require no pending after apply: %v", err) } } + +func TestPostgresBackupRestoreRehearsalPreservesLedgerAndObjects(t *testing.T) { + databaseURL := os.Getenv("EVYDENCE_TEST_DATABASE_URL") + if databaseURL == "" { + t.Skip("EVYDENCE_TEST_DATABASE_URL is not set") + } + ctx, cancel := context.WithTimeout(context.Background(), 45*time.Second) + defer cancel() + baseStore, err := Open(ctx, databaseURL) + if err != nil { + t.Fatal(err) + } + defer baseStore.Close() + sourceSchema := "evydence_restore_source_" + strings.ReplaceAll(time.Now().Format("150405.000000000"), ".", "_") + targetSchema := "evydence_restore_target_" + strings.ReplaceAll(time.Now().Format("150405.000000000"), ".", "_") + for _, schema := range []string{sourceSchema, targetSchema} { + quoted := pgx.Identifier{schema}.Sanitize() + if _, err := baseStore.pool.Exec(ctx, "CREATE SCHEMA "+quoted); err != nil { + t.Fatal(err) + } + defer func(schema string) { + _, _ = baseStore.pool.Exec(context.WithoutCancel(ctx), "DROP SCHEMA "+pgx.Identifier{schema}.Sanitize()+" CASCADE") + }(schema) + } + + sourceStore, err := Open(ctx, databaseURLWithSearchPath(t, databaseURL, sourceSchema)) + if err != nil { + t.Fatal(err) + } + defer sourceStore.Close() + if _, err := sourceStore.ApplyMigrations(ctx, "../../../migrations"); err != nil { + t.Fatal(err) + } + sourceObjectRoot := t.TempDir() + sourceObjects, err := fsobject.New(sourceObjectRoot) + if err != nil { + t.Fatal(err) + } + ledger, err := app.NewLedgerWithError(app.Config{APIKeyPepper: "test-pepper", Store: sourceStore, ObjectStore: sourceObjects}) + if err != nil { + t.Fatal(err) + } + _, _, secret, err := ledger.BootstrapTenant(ctx, "Restore Tenant", "admin", []string{"*"}) + if err != nil { + t.Fatal(err) + } + actor, err := ledger.Authenticate(ctx, secret) + if err != nil { + t.Fatal(err) + } + product, err := ledger.CreateProduct(ctx, actor, "Payments API", "payments-restore") + if err != nil { + t.Fatal(err) + } + release, err := ledger.CreateRelease(ctx, actor, product.ID, "1.0.0") + if err != nil { + t.Fatal(err) + } + artifact, err := ledger.RegisterArtifact(ctx, actor, "payments.tar.gz", "application/gzip", "sha256:"+strings.Repeat("a", 64), 42) + if err != nil { + t.Fatal(err) + } + sbom, err := ledger.UploadSBOM(ctx, actor, release.ID, artifact.ID, []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","components":[{"name":"api","purl":"pkg:oci/api"}]}`)) + if err != nil { + t.Fatal(err) + } + bundle, err := ledger.CreateReleaseBundle(ctx, actor, release.ID) + if err != nil { + t.Fatal(err) + } + manifest, err := ledger.GenerateBackupManifest(ctx, actor) + if err != nil { + t.Fatal(err) + } + dbBackup, ok, err := sourceStore.LoadState(ctx) + if err != nil || !ok { + t.Fatalf("load backup state ok=%v err=%v", ok, err) + } + + targetStore, err := Open(ctx, databaseURLWithSearchPath(t, databaseURL, targetSchema)) + if err != nil { + t.Fatal(err) + } + defer targetStore.Close() + if _, err := targetStore.ApplyMigrations(ctx, "../../../migrations"); err != nil { + t.Fatal(err) + } + if err := targetStore.SaveState(ctx, dbBackup); err != nil { + t.Fatal(err) + } + targetObjectRoot := t.TempDir() + copyTree(t, sourceObjectRoot, targetObjectRoot) + targetObjects, err := fsobject.New(targetObjectRoot) + if err != nil { + t.Fatal(err) + } + restored, err := app.NewLedgerWithError(app.Config{APIKeyPepper: "test-pepper", Store: targetStore, ObjectStore: targetObjects}) + if err != nil { + t.Fatal(err) + } + restoredActor, err := restored.Authenticate(ctx, secret) + if err != nil { + t.Fatal(err) + } + if _, err := restored.VerifyBackupManifest(ctx, restoredActor, manifest.ID); err != nil { + t.Fatalf("verify backup manifest after restore: %v", err) + } + restoredSBOM, err := restored.GetSBOM(ctx, restoredActor, sbom.ID) + if err != nil || restoredSBOM.ComponentCount != sbom.ComponentCount { + t.Fatalf("restored sbom = %#v err=%v", restoredSBOM, err) + } + evidence, err := restored.GetEvidence(ctx, restoredActor, restoredSBOM.EvidenceID) + if err != nil { + t.Fatal(err) + } + objectKey := strings.TrimPrefix(evidence.PayloadRef, "object://") + object, err := targetObjects.Get(ctx, objectKey) + if err != nil { + t.Fatalf("restored object: %v", err) + } + if object.Digest != evidence.PayloadHash { + t.Fatalf("restored object digest = %q, want %q", object.Digest, evidence.PayloadHash) + } + if vr, err := restored.VerifySubject(ctx, restoredActor, "release_bundle", bundle.ID); err != nil || vr.Result != "passed" { + t.Fatalf("verify restored bundle = %#v err=%v", vr, err) + } +} + +func copyTree(t *testing.T, sourceRoot, targetRoot string) { + t.Helper() + err := filepath.WalkDir(sourceRoot, func(path string, entry os.DirEntry, walkErr error) error { + if walkErr != nil { + return walkErr + } + rel, err := filepath.Rel(sourceRoot, path) + if err != nil { + return err + } + if rel == "." { + return nil + } + target := filepath.Join(targetRoot, rel) + if entry.IsDir() { + return os.MkdirAll(target, 0o700) + } + body, err := os.ReadFile(path) // #nosec G304 -- test copies files found under sourceRoot. + if err != nil { + return err + } + return os.WriteFile(target, body, 0o600) + }) + if err != nil { + t.Fatal(err) + } +} From c2af595a9b1df32242333233d903f159c7b50c2a Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 19:52:13 +0300 Subject: [PATCH 080/287] test: harden restore rehearsal copy --- internal/adapters/postgres/store_test.go | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index f66e28f..a39c30e 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -3,7 +3,6 @@ package postgres import ( "context" "os" - "path/filepath" "strings" "testing" "time" @@ -272,28 +271,7 @@ func TestPostgresBackupRestoreRehearsalPreservesLedgerAndObjects(t *testing.T) { func copyTree(t *testing.T, sourceRoot, targetRoot string) { t.Helper() - err := filepath.WalkDir(sourceRoot, func(path string, entry os.DirEntry, walkErr error) error { - if walkErr != nil { - return walkErr - } - rel, err := filepath.Rel(sourceRoot, path) - if err != nil { - return err - } - if rel == "." { - return nil - } - target := filepath.Join(targetRoot, rel) - if entry.IsDir() { - return os.MkdirAll(target, 0o700) - } - body, err := os.ReadFile(path) // #nosec G304 -- test copies files found under sourceRoot. - if err != nil { - return err - } - return os.WriteFile(target, body, 0o600) - }) - if err != nil { + if err := os.CopyFS(targetRoot, os.DirFS(sourceRoot)); err != nil { t.Fatal(err) } } From 4ed95ea6c862a0b77bc7e6ccfa45400034816c8b Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 19:57:48 +0300 Subject: [PATCH 081/287] feat: add external signing executor --- .api.env.example | 5 + cmd/evydence-api/main.go | 23 +++ cmd/evydence-api/main_test.go | 16 ++ docs/architecture.md | 4 +- docs/reference/configuration.md | 13 ++ docs/reference/production-readiness.md | 8 +- internal/adapters/httpapi/openapi.go | 2 +- .../adapters/httpapi/openapi_operations.go | 2 +- .../signing/httpgateway/httpgateway.go | 137 ++++++++++++++++++ .../signing/httpgateway/httpgateway_test.go | 77 ++++++++++ internal/app/future_extensions.go | 64 +++++++- internal/app/future_extensions_test.go | 51 +++++++ internal/app/ledger.go | 3 + internal/app/ports.go | 21 +++ openapi.yaml | 2 +- 15 files changed, 412 insertions(+), 16 deletions(-) create mode 100644 internal/adapters/signing/httpgateway/httpgateway.go create mode 100644 internal/adapters/signing/httpgateway/httpgateway_test.go diff --git a/.api.env.example b/.api.env.example index 7a2a49c..10cb7d6 100644 --- a/.api.env.example +++ b/.api.env.example @@ -4,6 +4,11 @@ EVYDENCE_DATABASE_URL=postgres://evydence:change-me@localhost:5432/evydence?sslm EVYDENCE_OBJECT_STORE=filesystem EVYDENCE_OBJECT_DIR=./tmp/objects EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE=0 +EVYDENCE_SIGNING_KEY_MODE=external +# Optional external signing gateway. Use HTTPS outside localhost. +# EVYDENCE_SIGNING_EXECUTOR_URL=https://signer.example.test/sign +# EVYDENCE_SIGNING_EXECUTOR_TOKEN=replace-with-signing-gateway-token +# EVYDENCE_SIGNING_EXECUTOR_TIMEOUT_SECONDS=10 # For MinIO/S3, set EVYDENCE_OBJECT_STORE=minio and provide: # EVYDENCE_S3_ENDPOINT=localhost:9000 # EVYDENCE_S3_BUCKET=evydence diff --git a/cmd/evydence-api/main.go b/cmd/evydence-api/main.go index 2305ce8..036f392 100644 --- a/cmd/evydence-api/main.go +++ b/cmd/evydence-api/main.go @@ -17,6 +17,7 @@ import ( "github.com/aatuh/evydence/internal/adapters/objectstore/filesystem" s3store "github.com/aatuh/evydence/internal/adapters/objectstore/s3" "github.com/aatuh/evydence/internal/adapters/postgres" + "github.com/aatuh/evydence/internal/adapters/signing/httpgateway" "github.com/aatuh/evydence/internal/app" ) @@ -34,6 +35,11 @@ func run() error { return err } cfg := app.Config{APIKeyPepper: pepper} + if signer, err := openSigningExecutor(); err != nil { + return err + } else { + cfg.Signer = signer + } var closeStore func() if databaseURL != "" { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) @@ -101,6 +107,23 @@ func run() error { return httpServer.ListenAndServe() } +func openSigningExecutor() (app.SigningExecutor, error) { + endpoint := strings.TrimSpace(os.Getenv("EVYDENCE_SIGNING_EXECUTOR_URL")) + if endpoint == "" { + return nil, nil + } + executor, err := httpgateway.New(httpgateway.Config{ + Endpoint: endpoint, + BearerToken: os.Getenv("EVYDENCE_SIGNING_EXECUTOR_TOKEN"), + AllowInsecureForLocalhost: strings.EqualFold(os.Getenv("EVYDENCE_SIGNING_EXECUTOR_ALLOW_INSECURE_LOCALHOST"), "true"), + Timeout: time.Duration(intEnv("EVYDENCE_SIGNING_EXECUTOR_TIMEOUT_SECONDS", 10)) * time.Second, + }) + if err != nil { + return nil, fmt.Errorf("configure signing executor: %w", err) + } + return executor, nil +} + func validateRuntimeConfig(production bool, databaseURL, pepper, signingKeyMode string, printBootstrapSecret bool) error { if !production { return nil diff --git a/cmd/evydence-api/main_test.go b/cmd/evydence-api/main_test.go index 3ec5255..abb3b3b 100644 --- a/cmd/evydence-api/main_test.go +++ b/cmd/evydence-api/main_test.go @@ -87,3 +87,19 @@ func TestOpenObjectStoreRejectsIncompleteS3Config(t *testing.T) { t.Fatal("expected incomplete S3 config to be rejected") } } + +func TestOpenSigningExecutorRequiresHTTPSUnlessLocalOverride(t *testing.T) { + t.Setenv("EVYDENCE_SIGNING_EXECUTOR_URL", "http://signer.example.test/sign") + if _, err := openSigningExecutor(); err == nil || !strings.Contains(err.Error(), "https") { + t.Fatalf("remote http signer err=%v, want https rejection", err) + } + t.Setenv("EVYDENCE_SIGNING_EXECUTOR_URL", "http://127.0.0.1/sign") + t.Setenv("EVYDENCE_SIGNING_EXECUTOR_ALLOW_INSECURE_LOCALHOST", "true") + signer, err := openSigningExecutor() + if err != nil { + t.Fatalf("localhost signer should be accepted: %v", err) + } + if signer == nil { + t.Fatal("expected signer") + } +} diff --git a/docs/architecture.md b/docs/architecture.md index f2531b4..0b7a3ec 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -34,7 +34,7 @@ Release readiness is deterministic and evidence-scoped. Open critical vulnerabil DSSE attestation signatures can be verified against configured Ed25519 trust roots when raw attestation bytes are available. Cosign-style artifact verification records digest binding, signature presence, and optional Rekor metadata without overstating full Sigstore trust-chain validation. Signing keys support revocation and valid-at-signing semantics for historical signatures. -Merkle batches, signed checkpoints, optional transparency checkpoint/public transparency records, backup manifests, object-retention policy records with verification hashes, legal holds, retention overrides, readiness, metrics, instance admin diagnostics, and admin audit queries provide operational integrity and review surfaces. +Merkle batches, signed checkpoints, optional transparency checkpoint/public transparency records, backup manifests, object-retention policy records with verification hashes, legal holds, retention overrides, readiness, metrics, instance admin diagnostics, external signing gateway receipts, and admin audit queries provide operational integrity and review surfaces. ## Reports And Customer-Facing Packages @@ -52,6 +52,6 @@ Air-gapped import-bundle workflows preserve the same tenant-scoped import path a ## Limitations -The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts are implemented, but production KMS/HSM provider adapters and live Sigstore/public-transparency verification remain deployment hardening work. Hand-tuned per-resource repository implementations and moving parser side effects fully out of request paths remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. +The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts and an optional HTTPS signing gateway executor are implemented, but direct cloud KMS/HSM SDK adapters and live Sigstore/public-transparency verification remain deployment hardening work. Hand-tuned per-resource repository implementations and moving parser side effects fully out of request paths remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. Evydence does not prove provider truth, scanner authority, runtime security, legal compliance, or release security by itself. diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index fac146b..83fd3b4 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -45,6 +45,10 @@ The example secrets are placeholders. Replace them before using shared or produc | `EVYDENCE_WORKER_BATCH_SIZE` | No | `10` | Maximum outbox jobs claimed per polling cycle. | | `EVYDENCE_WORKER_MAX_PAYLOAD_BYTES` | No | `20971520` | Maximum raw object payload size replayed by a worker job. | | `EVYDENCE_SIGNING_KEY_MODE` | Production yes | `external` for production | Production rejects local plaintext signing-key mode. | +| `EVYDENCE_SIGNING_EXECUTOR_URL` | No | unset | Optional HTTPS signing gateway used by `POST /v1/signing-operations` when `external_signature` is omitted. The API sends subject metadata and `payload_hash`, not raw payload bytes. | +| `EVYDENCE_SIGNING_EXECUTOR_TOKEN` | Signing gateway | unset | Optional bearer token for the signing gateway. Store outside source control and logs. | +| `EVYDENCE_SIGNING_EXECUTOR_TIMEOUT_SECONDS` | No | `10` | Timeout for signing gateway requests. | +| `EVYDENCE_SIGNING_EXECUTOR_ALLOW_INSECURE_LOCALHOST` | Local only | `false` | Allows `http://localhost` or loopback signing gateway endpoints for local development and tests. Do not use for production. | | `EVYDENCE_TEST_DATABASE_URL` | Live tests | `.test.env.example` value | Used by `make live-postgres-check`, `make postgres-integration-test`, and `make release-check`. | ## Production Rejection Checks @@ -58,6 +62,15 @@ When `ENV=production`, the API refuses to start unless: These checks reduce unsafe runtime defaults. They do not replace secret management, network controls, backup validation, or external signing operations. +## External Signing Gateway + +When `EVYDENCE_SIGNING_EXECUTOR_URL` is set, signing operations can omit +`external_signature`. Evydence sends a JSON request containing tenant id, +provider id/type, key reference, subject type/id, and `payload_hash`. The +gateway returns a signature, optional provider key id, and optional algorithm. +Evydence records the signature receipt and verification checks; it does not +store production private key material or send raw evidence payload bytes. + ## Related Commands - Local operation: [Install and operate](../how-to/install-and-operate.md) diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index a3f0144..d3f5205 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -22,7 +22,8 @@ Known hardening work remains: - OpenAPI precision is enforced across the registered public API. The generated matrix remains the source of truth for operation ids, scopes, idempotency, parameters, and request/response schemas; -- production KMS/HSM execution, full browser OIDC/SAML login flows, provider +- production signing can use the HTTPS signing gateway executor, but direct + cloud KMS/HSM SDK adapters, full browser OIDC/SAML login flows, provider discovery/group sync, object-lock enforcement proof, and transparency inclusion proof verification remain provider- and deployment-dependent hardening areas; @@ -102,8 +103,9 @@ implemented capabilities: responses backward compatible. - Keep OpenAPI precision at zero broad operations as routes are added or changed, and expand generated SDK coverage from the committed contract. -- Add production signing-provider execution for a configured external provider - profile without storing private key material in Evydence. +- Add direct cloud KMS/HSM SDK adapters where required. The current HTTPS + signing gateway executor covers deployments that put KMS/HSM custody behind a + tenant-controlled signing service and do not send raw payload bytes. - Complete live OIDC/SAML browser login callbacks, provider discovery, JWKS refresh, logout, and optional group mapping where those profiles are enabled. - Add provider-backed object-lock/WORM verification and optional transparency diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index e2593e5..b062629 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -509,7 +509,7 @@ func registerCriticalSchemas(registry *specs.Registry) { "subject_type": map[string]any{"type": "string"}, "subject_id": map[string]any{"type": "string"}, "payload_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, - "external_signature": map[string]any{"type": "string"}, + "external_signature": map[string]any{"type": "string", "description": "Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt."}, }, "provider_id", "subject_type", "subject_id", "payload_hash")) registry.RegisterSchema("SigningOperation", objectSchema(map[string]any{ "id": map[string]any{"type": "string"}, diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 15d87f9..621656e 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -402,7 +402,7 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.RequestBody = jsonRequest("Signing provider creation request.", "#/components/schemas/CreateSigningProviderRequest") operation.Responses[http.StatusCreated] = jsonResponse("Created signing provider envelope.", "#/components/schemas/SigningProviderEnvelope") case "createSigningOperation": - operation.Description = "Records an external signing operation receipt and checks payload/signature metadata without logging secrets." + operation.Description = "Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash." operation.RequestBody = jsonRequest("Signing operation creation request.", "#/components/schemas/CreateSigningOperationRequest") operation.Responses[http.StatusCreated] = jsonResponse("Created signing operation envelope.", "#/components/schemas/SigningOperationEnvelope") case "createArtifactSignature": diff --git a/internal/adapters/signing/httpgateway/httpgateway.go b/internal/adapters/signing/httpgateway/httpgateway.go new file mode 100644 index 0000000..f3f68aa --- /dev/null +++ b/internal/adapters/signing/httpgateway/httpgateway.go @@ -0,0 +1,137 @@ +package httpgateway + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "net" + "net/http" + "net/url" + "strings" + "time" + + "github.com/aatuh/evydence/internal/app" + "github.com/aatuh/evydence/internal/domain" +) + +const defaultTimeout = 10 * time.Second + +type Config struct { + Endpoint string + BearerToken string + Timeout time.Duration + AllowInsecureForLocalhost bool + Client *http.Client +} + +type Executor struct { + endpoint string + bearerToken string + client *http.Client +} + +type signRequest struct { + TenantID string `json:"tenant_id"` + ProviderID string `json:"provider_id"` + ProviderType string `json:"provider_type"` + KeyRef string `json:"key_ref"` + SubjectType string `json:"subject_type"` + SubjectID string `json:"subject_id"` + PayloadHash string `json:"payload_hash"` +} + +type signResponse struct { + Signature string `json:"signature"` + KeyID string `json:"key_id"` + Algorithm string `json:"algorithm"` +} + +func New(cfg Config) (*Executor, error) { + endpoint := strings.TrimSpace(cfg.Endpoint) + if endpoint == "" { + return nil, app.ErrValidation + } + parsed, err := url.Parse(endpoint) + if err != nil || parsed.Scheme == "" || parsed.Host == "" { + return nil, app.ErrValidation + } + if parsed.Scheme != "https" && !(cfg.AllowInsecureForLocalhost && parsed.Scheme == "http" && localhostHost(parsed.Hostname())) { + return nil, errors.New("signing gateway endpoint must use https") + } + timeout := cfg.Timeout + if timeout <= 0 { + timeout = defaultTimeout + } + client := cfg.Client + if client == nil { + client = &http.Client{Timeout: timeout} + } + return &Executor{endpoint: endpoint, bearerToken: strings.TrimSpace(cfg.BearerToken), client: client}, nil +} + +func (e *Executor) Sign(ctx context.Context, request app.SigningRequest) (app.SigningResult, error) { + if e == nil || e.client == nil { + return app.SigningResult{}, app.ErrValidation + } + body, err := json.Marshal(signRequest{ + TenantID: request.TenantID, + ProviderID: request.ProviderID, + ProviderType: request.ProviderType, + KeyRef: request.KeyRef, + SubjectType: request.SubjectType, + SubjectID: request.SubjectID, + PayloadHash: request.PayloadHash, + }) + if err != nil { + return app.SigningResult{}, fmt.Errorf("encode signing request: %w", err) + } + httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, e.endpoint, bytes.NewReader(body)) + if err != nil { + return app.SigningResult{}, fmt.Errorf("create signing request: %w", err) + } + httpReq.Header.Set("Content-Type", "application/json") + httpReq.Header.Set("Accept", "application/json") + if e.bearerToken != "" { + httpReq.Header.Set("Authorization", "Bearer "+e.bearerToken) + } + resp, err := e.client.Do(httpReq) + if err != nil { + return app.SigningResult{}, errors.New("execute signing request") + } + defer resp.Body.Close() + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + _, _ = io.Copy(io.Discard, io.LimitReader(resp.Body, 4096)) + return app.SigningResult{}, fmt.Errorf("signing gateway returned status %d", resp.StatusCode) + } + var decoded signResponse + decoder := json.NewDecoder(io.LimitReader(resp.Body, 1<<20)) + decoder.DisallowUnknownFields() + if err := decoder.Decode(&decoded); err != nil { + return app.SigningResult{}, errors.New("decode signing response") + } + decoded.Signature = strings.TrimSpace(decoded.Signature) + decoded.KeyID = strings.TrimSpace(decoded.KeyID) + decoded.Algorithm = strings.TrimSpace(decoded.Algorithm) + if decoded.Signature == "" || len(decoded.Signature) > 32768 { + return app.SigningResult{}, app.ErrValidation + } + return app.SigningResult{ + Signature: decoded.Signature, + KeyID: decoded.KeyID, + Algorithm: decoded.Algorithm, + Checks: []domain.VerifyCheck{ + {Name: "signing_gateway_response", Result: "passed", Detail: "External signing gateway returned a signature over the submitted payload hash."}, + }, + }, nil +} + +func localhostHost(host string) bool { + if host == "localhost" { + return true + } + ip := net.ParseIP(host) + return ip != nil && ip.IsLoopback() +} diff --git a/internal/adapters/signing/httpgateway/httpgateway_test.go b/internal/adapters/signing/httpgateway/httpgateway_test.go new file mode 100644 index 0000000..06b135c --- /dev/null +++ b/internal/adapters/signing/httpgateway/httpgateway_test.go @@ -0,0 +1,77 @@ +package httpgateway + +import ( + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + + "github.com/aatuh/evydence/internal/app" +) + +func TestNewRequiresHTTPSEndpointExceptLocalhostOverride(t *testing.T) { + if _, err := New(Config{Endpoint: "http://example.com/sign"}); err == nil { + t.Fatal("expected non-HTTPS remote endpoint to be rejected") + } + if _, err := New(Config{Endpoint: "http://127.0.0.1/sign", AllowInsecureForLocalhost: true}); err != nil { + t.Fatalf("localhost override should be accepted: %v", err) + } +} + +func TestSignPostsHashOnlyAndReturnsSignature(t *testing.T) { + var gotAuth, gotPayloadHash, gotKeyRef string + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + t.Fatalf("method = %s", r.Method) + } + gotAuth = r.Header.Get("Authorization") + var req signRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + t.Fatal(err) + } + gotPayloadHash = req.PayloadHash + gotKeyRef = req.KeyRef + _ = json.NewEncoder(w).Encode(signResponse{Signature: "sig_external", KeyID: "kms-key-1", Algorithm: "external-aws_kms"}) + })) + defer server.Close() + + executor, err := New(Config{Endpoint: server.URL, BearerToken: "secret-token", AllowInsecureForLocalhost: true}) + if err != nil { + t.Fatal(err) + } + result, err := executor.Sign(t.Context(), app.SigningRequest{ + TenantID: "ten_1", + ProviderID: "sp_1", + ProviderType: "aws_kms", + KeyRef: "arn:aws:kms:example", + SubjectType: "release", + SubjectID: "rel_1", + PayloadHash: "sha256:abcdef", + }) + if err != nil { + t.Fatal(err) + } + if result.Signature != "sig_external" || result.KeyID != "kms-key-1" || result.Algorithm != "external-aws_kms" { + t.Fatalf("result = %#v", result) + } + if gotAuth != "Bearer secret-token" { + t.Fatalf("auth header = %q", gotAuth) + } + if gotPayloadHash != "sha256:abcdef" || gotKeyRef != "arn:aws:kms:example" { + t.Fatalf("request hash/key ref = %q/%q", gotPayloadHash, gotKeyRef) + } +} + +func TestSignRejectsUnknownResponseFields(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + _, _ = w.Write([]byte(`{"signature":"sig","extra":"nope"}`)) + })) + defer server.Close() + executor, err := New(Config{Endpoint: server.URL, AllowInsecureForLocalhost: true}) + if err != nil { + t.Fatal(err) + } + if _, err := executor.Sign(t.Context(), app.SigningRequest{PayloadHash: "sha256:abc"}); err == nil { + t.Fatal("expected strict response decoding to reject unknown fields") + } +} diff --git a/internal/app/future_extensions.go b/internal/app/future_extensions.go index b0a7abc..f2aa5b6 100644 --- a/internal/app/future_extensions.go +++ b/internal/app/future_extensions.go @@ -906,33 +906,81 @@ func (l *Ledger) CreateSigningOperation(ctx context.Context, actor domain.Actor, } providerID, subjectType, subjectID := strings.TrimSpace(in.ProviderID), strings.TrimSpace(in.SubjectType), strings.TrimSpace(in.SubjectID) signatureValue := strings.TrimSpace(in.ExternalSignature) - if providerID == "" || subjectType == "" || subjectID == "" || !validDigest(strings.TrimSpace(in.PayloadHash)) || signatureValue == "" || len(signatureValue) > 32768 { + payloadHash := strings.TrimSpace(in.PayloadHash) + if providerID == "" || subjectType == "" || subjectID == "" || !validDigest(payloadHash) || len(signatureValue) > 32768 { return domain.SigningOperation{}, ErrValidation } l.mu.Lock() - defer l.mu.Unlock() provider, ok := l.signingProviders[providerID] if !ok || provider.TenantID != actor.TenantID { + l.mu.Unlock() return domain.SigningOperation{}, ErrNotFound } if _, err := l.ensureFutureSubjectLocked(actor.TenantID, subjectType, subjectID); err != nil { + l.mu.Unlock() return domain.SigningOperation{}, err } + providerActive := provider.Status == "active" + l.mu.Unlock() + checks := []domain.VerifyCheck{ {Name: "provider_active", Result: "passed"}, {Name: "payload_hash_valid", Result: "passed"}, - {Name: "external_signature_present", Result: "passed", Detail: "Signature value was supplied by the configured provider path; local cryptographic trust verification is not implied."}, } - if provider.Status != "active" { + if !providerActive { checks[0].Result = "failed" } + signatureAlgorithm := "external-" + provider.Type + if signatureValue == "" { + if l.signer == nil { + return domain.SigningOperation{}, ErrValidation + } + if !providerActive { + return domain.SigningOperation{}, ErrVerificationFailed + } + signed, err := l.signer.Sign(ctx, SigningRequest{ + TenantID: actor.TenantID, + ProviderID: provider.ID, + ProviderType: provider.Type, + KeyRef: provider.KeyRef, + SubjectType: subjectType, + SubjectID: subjectID, + PayloadHash: payloadHash, + }) + if err != nil { + return domain.SigningOperation{}, err + } + signatureValue = strings.TrimSpace(signed.Signature) + if signatureValue == "" || len(signatureValue) > 32768 { + return domain.SigningOperation{}, ErrValidation + } + if strings.TrimSpace(signed.Algorithm) != "" { + signatureAlgorithm = strings.TrimSpace(signed.Algorithm) + } + checks = append(checks, signed.Checks...) + checks = append(checks, domain.VerifyCheck{Name: "signing_executor_invoked", Result: "passed", Detail: strings.TrimSpace(signed.KeyID)}) + } else { + checks = append(checks, domain.VerifyCheck{Name: "external_signature_present", Result: "passed", Detail: "Signature value was supplied by the configured provider path; local cryptographic trust verification is not implied."}) + } result := "passed" - if checks[0].Result != "passed" { - result = "failed" + for _, check := range checks { + if check.Result == "failed" { + result = "failed" + break + } + } + l.mu.Lock() + defer l.mu.Unlock() + provider, ok = l.signingProviders[providerID] + if !ok || provider.TenantID != actor.TenantID { + return domain.SigningOperation{}, ErrNotFound + } + if _, err := l.ensureFutureSubjectLocked(actor.TenantID, subjectType, subjectID); err != nil { + return domain.SigningOperation{}, err } - signature := domain.Signature{ID: newID("sig"), TenantID: actor.TenantID, SubjectType: subjectType, SubjectID: subjectID, KeyID: provider.ID, Algorithm: "external-" + provider.Type, Value: signatureValue, CreatedAt: l.now()} + signature := domain.Signature{ID: newID("sig"), TenantID: actor.TenantID, SubjectType: subjectType, SubjectID: subjectID, KeyID: provider.ID, Algorithm: signatureAlgorithm, Value: signatureValue, CreatedAt: l.now()} l.signatures[signature.ID] = signature - op := domain.SigningOperation{ID: newID("sop"), TenantID: actor.TenantID, ProviderID: provider.ID, SubjectType: subjectType, SubjectID: subjectID, PayloadHash: strings.TrimSpace(in.PayloadHash), SignatureRef: signature.ID, Result: result, Checks: checks, SchemaVersion: domain.SigningOperationVersion, CreatedAt: l.now()} + op := domain.SigningOperation{ID: newID("sop"), TenantID: actor.TenantID, ProviderID: provider.ID, SubjectType: subjectType, SubjectID: subjectID, PayloadHash: payloadHash, SignatureRef: signature.ID, Result: result, Checks: checks, SchemaVersion: domain.SigningOperationVersion, CreatedAt: l.now()} l.signingOperations[op.ID] = op _, _ = l.appendChainLocked(actor.TenantID, "signing_operation.created", "signing_operation", op.ID, actorType(actor), actorID(actor), op.PayloadHash, signature.ID) if err := l.persistLocked(ctx); err != nil { diff --git a/internal/app/future_extensions_test.go b/internal/app/future_extensions_test.go index 342826e..6f6cb2c 100644 --- a/internal/app/future_extensions_test.go +++ b/internal/app/future_extensions_test.go @@ -218,3 +218,54 @@ func TestFutureOperationalExtensionsAndPartialTrustClosures(t *testing.T) { t.Fatalf("non-instance saas profile err=%v, want forbidden", err) } } + +type fakeSigningExecutor struct { + request SigningRequest +} + +func (f *fakeSigningExecutor) Sign(_ context.Context, request SigningRequest) (SigningResult, error) { + f.request = request + return SigningResult{ + Signature: "sig_from_executor", + KeyID: "kms-key-1", + Algorithm: "external-aws_kms", + Checks: []domain.VerifyCheck{{Name: "fake_executor", Result: "passed"}}, + }, nil +} + +func TestSigningOperationCanExecuteConfiguredSignerWithoutPrivateKey(t *testing.T) { + signer := &fakeSigningExecutor{} + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow, Signer: signer}) + ctx := context.Background() + actor, release, _ := setupReleaseRiskFixture(t, ledger) + provider, err := ledger.CreateSigningProvider(ctx, actor, CreateSigningProviderInput{Name: "kms", Type: "aws_kms", KeyRef: "arn:aws:kms:example", Encrypted: true}) + if err != nil { + t.Fatalf("provider: %v", err) + } + op, err := ledger.CreateSigningOperation(ctx, actor, CreateSigningOperationInput{ProviderID: provider.ID, SubjectType: "release", SubjectID: release.ID, PayloadHash: sampleDigest("payload")}) + if err != nil { + t.Fatalf("signing operation: %v", err) + } + if op.Result != "passed" || op.SignatureRef == "" { + t.Fatalf("operation = %#v", op) + } + if signer.request.ProviderID != provider.ID || signer.request.KeyRef != provider.KeyRef || signer.request.PayloadHash != sampleDigest("payload") { + t.Fatalf("executor request = %#v", signer.request) + } + if !hasVerifyCheck(op.Checks, "signing_executor_invoked", "passed") || !hasVerifyCheck(op.Checks, "fake_executor", "passed") { + t.Fatalf("operation checks = %#v", op.Checks) + } +} + +func TestSigningOperationRequiresSignatureWhenNoExecutorConfigured(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, release, _ := setupReleaseRiskFixture(t, ledger) + provider, err := ledger.CreateSigningProvider(ctx, actor, CreateSigningProviderInput{Name: "kms", Type: "aws_kms", KeyRef: "arn:aws:kms:example", Encrypted: true}) + if err != nil { + t.Fatalf("provider: %v", err) + } + if _, err := ledger.CreateSigningOperation(ctx, actor, CreateSigningOperationInput{ProviderID: provider.ID, SubjectType: "release", SubjectID: release.ID, PayloadHash: sampleDigest("payload")}); !errors.Is(err, ErrValidation) { + t.Fatalf("err=%v, want validation", err) + } +} diff --git a/internal/app/ledger.go b/internal/app/ledger.go index 466627e..055b952 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -66,6 +66,7 @@ type Config struct { Now func() time.Time Store Store ObjectStore ObjectStore + Signer SigningExecutor Outbox Outbox } @@ -76,6 +77,7 @@ type Ledger struct { now func() time.Time store Store objects ObjectStore + signer SigningExecutor outbox Outbox tenants map[string]domain.Tenant @@ -191,6 +193,7 @@ func NewLedgerWithError(cfg Config) (*Ledger, error) { now: now, store: cfg.Store, objects: cfg.ObjectStore, + signer: cfg.Signer, outbox: cfg.Outbox, tenants: map[string]domain.Tenant{}, organizations: map[string]domain.Organization{}, diff --git a/internal/app/ports.go b/internal/app/ports.go index d68ed1c..c0d3d34 100644 --- a/internal/app/ports.go +++ b/internal/app/ports.go @@ -17,10 +17,31 @@ type ObjectStore interface { Get(context.Context, string) (Object, error) } +type SigningExecutor interface { + Sign(context.Context, SigningRequest) (SigningResult, error) +} + type Outbox interface { Enqueue(context.Context, OutboxJob) error } +type SigningRequest struct { + TenantID string + ProviderID string + ProviderType string + KeyRef string + SubjectType string + SubjectID string + PayloadHash string +} + +type SigningResult struct { + Signature string + KeyID string + Algorithm string + Checks []domain.VerifyCheck +} + type PersistedState struct { Tenants map[string]domain.Tenant `json:"tenants"` Organizations map[string]domain.Organization `json:"organizations"` diff --git a/openapi.yaml b/openapi.yaml index 20c5eed..74a631a 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From fcd49f7c5fc7f72de16aa97a830f1c5a75f5b1e9 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 19:59:13 +0300 Subject: [PATCH 082/287] feat: verify object retention policy settings --- docs/architecture.md | 2 +- docs/production-hardening.md | 1 + docs/reference/configuration.md | 9 ++ docs/reference/production-readiness.md | 5 +- internal/adapters/httpapi/openapi.go | 9 +- internal/adapters/objectstore/s3/s3.go | 87 +++++++++++++++++++ internal/adapters/objectstore/s3/s3_test.go | 55 ++++++++++++ .../signing/httpgateway/httpgateway.go | 2 +- internal/app/integrity_runtime.go | 67 +++++++++++--- internal/app/integrity_runtime_test.go | 87 +++++++++++++++++++ internal/app/ledger.go | 21 +++-- internal/app/ports.go | 18 ++++ internal/domain/domain.go | 24 ++--- openapi.yaml | 2 +- 14 files changed, 354 insertions(+), 35 deletions(-) diff --git a/docs/architecture.md b/docs/architecture.md index 0b7a3ec..c7978ce 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -48,7 +48,7 @@ Evidence summaries, questionnaire drafts, graph snapshots, PDF packages, and ano GitHub OIDC subject metadata can be captured, and stored OIDC/SAML identity links can be verified against tenant metadata. OIDC provider records can include static JWKS public-key material for local EdDSA or RS256 ID-token signature and claim verification, and SAML provider records can include PEM signing certificates for local assertion signature and claim verification. Live provider API verification, discovery, browser login callbacks, and group synchronization remain trust boundaries outside those records. Collector supply-chain records track pinned collector versions with signature, SBOM, and scan evidence where available; commercial and marketplace collector definitions add extension metadata without granting provider trust. -Air-gapped import-bundle workflows preserve the same tenant-scoped import path after controlled transfer. Object-retention policy APIs record and verify retention intent for tenant-prefixed object paths, but WORM/object-lock enforcement remains the responsibility of the configured object store and deployment policy. +Air-gapped import-bundle workflows preserve the same tenant-scoped import path after controlled transfer. Object-retention policy APIs record tenant-scoped retention intent and, when the S3/MinIO object-store adapter is configured, verify bucket versioning plus default object-lock mode and duration. Those checks are bucket-level evidence; WORM/object-lock enforcement, IAM policy, lifecycle rules, and deployment-specific retention review remain operator responsibilities. ## Limitations diff --git a/docs/production-hardening.md b/docs/production-hardening.md index 062d3a9..6d69fb2 100644 --- a/docs/production-hardening.md +++ b/docs/production-hardening.md @@ -18,6 +18,7 @@ These checks are enforced by API startup. See [Configuration](reference/configur - PostgreSQL is external, backed up, monitored, and restored in a test environment. - Object storage is external S3/MinIO-compatible storage with tenant-prefixed paths, encryption, lifecycle policy, and retention/object-lock policy where required. +- S3/MinIO object-retention policy verification has been run for required tenant prefixes, and records show bucket versioning plus default object-lock mode/duration checks with documented limitations. - Ingress terminates TLS and does not expose internal diagnostics. - Edge rate limiting is configured at the reverse proxy or ingress. The optional `EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE` in-process limiter is a local safety net and keys by TCP remote address only. - `/v1/metrics`, `/v1/audit-log`, and `/v1/admin/instance` are protected by server-side scopes and are not public. diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 83fd3b4..bfe05aa 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -62,6 +62,15 @@ When `ENV=production`, the API refuses to start unless: These checks reduce unsafe runtime defaults. They do not replace secret management, network controls, backup validation, or external signing operations. +## S3/MinIO Object-Retention Verification + +When `EVYDENCE_OBJECT_STORE=s3` or `minio`, object-retention policy verification +uses the same S3/MinIO client to check bucket versioning and default +object-lock settings. The resulting policy record includes verification checks +and limitations. The check is bucket-level: operators still need to review +bucket creation mode, IAM policy, lifecycle rules, backups, and any +deployment-specific WORM requirements. + ## External Signing Gateway When `EVYDENCE_SIGNING_EXECUTOR_URL` is set, signing operations can omit diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index d3f5205..ecf24ba 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -108,8 +108,9 @@ implemented capabilities: tenant-controlled signing service and do not send raw payload bytes. - Complete live OIDC/SAML browser login callbacks, provider discovery, JWKS refresh, logout, and optional group mapping where those profiles are enabled. -- Add provider-backed object-lock/WORM verification and optional transparency - inclusion proof verification for deployments that require those controls. +- Extend object-lock/WORM verification beyond current S3/MinIO bucket-level + checks where deployments require object-level legal hold proofs, provider + policy evidence, or optional transparency inclusion proof verification. - Run final product, codebase, security, documentation, and test audits before changing release status beyond controlled self-hosted production candidate. diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index b062629..5ee812a 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -199,8 +199,13 @@ func registerCriticalSchemas(registry *specs.Registry) { "status": map[string]any{"type": "string"}, "verified_at": map[string]any{"type": "string", "format": "date-time"}, "verification_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, - "schema_version": map[string]any{"type": "string"}, - "created_at": map[string]any{"type": "string", "format": "date-time"}, + "verification_checks": map[string]any{ + "type": "array", + "items": map[string]any{"$ref": "#/components/schemas/VerifyCheck"}, + }, + "verification_limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, }, "id", "tenant_id", "name", "object_prefix", "mode", "retention_days", "status", "schema_version", "created_at")) registry.RegisterSchema("ObjectRetentionPolicyEnvelope", dataEnvelopeSchema("#/components/schemas/ObjectRetentionPolicy")) registry.RegisterSchema("CreateLegalHoldRequest", objectSchema(map[string]any{ diff --git a/internal/adapters/objectstore/s3/s3.go b/internal/adapters/objectstore/s3/s3.go index 23ca0ce..fb68ad2 100644 --- a/internal/adapters/objectstore/s3/s3.go +++ b/internal/adapters/objectstore/s3/s3.go @@ -11,6 +11,7 @@ import ( "github.com/minio/minio-go/v7/pkg/credentials" "github.com/aatuh/evydence/internal/app" + "github.com/aatuh/evydence/internal/domain" ) type Config struct { @@ -99,6 +100,24 @@ func (s *Store) Get(ctx context.Context, key string) (app.Object, error) { }, nil } +func (s *Store) VerifyObjectRetention(ctx context.Context, req app.ObjectRetentionRequest) (app.ObjectRetentionResult, error) { + if s == nil || s.client == nil { + return app.ObjectRetentionResult{}, app.ErrValidation + } + if strings.TrimSpace(req.TenantID) == "" || !strings.HasPrefix(strings.TrimSpace(req.ObjectPrefix), "tenants/"+strings.TrimSpace(req.TenantID)+"/") { + return app.ObjectRetentionResult{}, app.ErrValidation + } + versioning, err := s.client.GetBucketVersioning(ctx, s.bucket) + if err != nil { + return app.ObjectRetentionResult{}, fmt.Errorf("check s3 bucket versioning: %w", err) + } + mode, validity, unit, err := s.client.GetBucketObjectLockConfig(ctx, s.bucket) + if err != nil && !objectLockConfigMissing(err) { + return app.ObjectRetentionResult{}, fmt.Errorf("check s3 object lock: %w", err) + } + return evaluateObjectRetention(req, versioning.Enabled(), mode, validity, unit), nil +} + func metadataValue(metadata map[string]string, keys ...string) string { for _, key := range keys { if value := metadata[key]; value != "" { @@ -107,3 +126,71 @@ func metadataValue(metadata map[string]string, keys ...string) string { } return "" } + +func objectLockConfigMissing(err error) bool { + resp := minio.ToErrorResponse(err) + return resp.Code == "NoSuchObjectLockConfiguration" || resp.Code == "ObjectLockConfigurationNotFoundError" +} + +func evaluateObjectRetention(req app.ObjectRetentionRequest, versioningEnabled bool, mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit) app.ObjectRetentionResult { + expectedPrefix := "tenants/" + strings.TrimSpace(req.TenantID) + "/" + prefixOK := strings.HasPrefix(strings.TrimSpace(req.ObjectPrefix), expectedPrefix) + expectedMode := retentionMode(req.Mode) + actualMode := "" + if mode != nil { + actualMode = strings.ToUpper(mode.String()) + } + retentionDays := retentionDays(validity, unit) + modeOK := expectedMode != "" && actualMode == expectedMode + retentionOK := req.RetentionDays > 0 && retentionDays >= uint(req.RetentionDays) + checks := []domain.VerifyCheck{ + {Name: "s3_bucket_versioning", Result: checkResult(versioningEnabled), Detail: "Bucket versioning must be enabled for object-lock retention."}, + {Name: "s3_object_lock_mode", Result: checkResult(modeOK), Detail: "Bucket default object-lock mode must match the policy mode."}, + {Name: "s3_object_lock_retention", Result: checkResult(retentionOK), Detail: "Bucket default object-lock retention must meet or exceed the policy duration."}, + {Name: "tenant_object_prefix", Result: checkResult(prefixOK), Detail: "Object prefix must stay under the tenant namespace."}, + } + return app.ObjectRetentionResult{ + Provider: "s3", + Enforced: versioningEnabled && modeOK && retentionOK && prefixOK, + Checks: checks, + Limitations: []string{ + "S3/MinIO checks validate bucket-level versioning and default object-lock settings only.", + "Operators remain responsible for bucket creation mode, IAM policy, lifecycle rules, backups, and deployment-specific retention review.", + }, + } +} + +func retentionMode(mode string) string { + switch strings.ToLower(strings.TrimSpace(mode)) { + case "governance": + return minio.Governance.String() + case "compliance": + return minio.Compliance.String() + default: + return "" + } +} + +func retentionDays(validity *uint, unit *minio.ValidityUnit) uint { + if validity == nil || unit == nil { + return 0 + } + switch *unit { + case minio.Days: + return *validity + case minio.Years: + if *validity > ^uint(0)/365 { + return ^uint(0) + } + return *validity * 365 + default: + return 0 + } +} + +func checkResult(ok bool) string { + if ok { + return "passed" + } + return "failed" +} diff --git a/internal/adapters/objectstore/s3/s3_test.go b/internal/adapters/objectstore/s3/s3_test.go index 4cb3fd4..cbbbb16 100644 --- a/internal/adapters/objectstore/s3/s3_test.go +++ b/internal/adapters/objectstore/s3/s3_test.go @@ -5,6 +5,8 @@ import ( "errors" "testing" + "github.com/minio/minio-go/v7" + "github.com/aatuh/evydence/internal/app" ) @@ -49,3 +51,56 @@ func TestMetadataValueUsesFirstNonEmptyKey(t *testing.T) { t.Fatalf("missing metadata = %q", got) } } + +func TestEvaluateObjectRetentionRequiresVersioningLockAndTenantPrefix(t *testing.T) { + mode := minio.Compliance + validity := uint(90) + unit := minio.Days + result := evaluateObjectRetention(app.ObjectRetentionRequest{ + TenantID: "ten_1", + ObjectPrefix: "tenants/ten_1/raw/", + Mode: "compliance", + RetentionDays: 30, + }, true, &mode, &validity, &unit) + if !result.Enforced { + t.Fatalf("expected enforced retention: %#v", result) + } + if len(result.Checks) != 4 || result.Checks[0].Result != "passed" { + t.Fatalf("checks = %#v", result.Checks) + } + if len(result.Limitations) == 0 { + t.Fatal("expected limitations") + } +} + +func TestEvaluateObjectRetentionReportsMissingProviderControls(t *testing.T) { + mode := minio.Governance + validity := uint(1) + unit := minio.Days + result := evaluateObjectRetention(app.ObjectRetentionRequest{ + TenantID: "ten_1", + ObjectPrefix: "tenants/other/raw/", + Mode: "compliance", + RetentionDays: 30, + }, false, &mode, &validity, &unit) + if result.Enforced { + t.Fatalf("unexpected enforced retention: %#v", result) + } + failed := 0 + for _, check := range result.Checks { + if check.Result == "failed" { + failed++ + } + } + if failed != 4 { + t.Fatalf("failed checks = %d, checks = %#v", failed, result.Checks) + } +} + +func TestRetentionDaysConvertsYears(t *testing.T) { + validity := uint(2) + unit := minio.Years + if got := retentionDays(&validity, &unit); got != uint(730) { + t.Fatalf("retention days = %d", got) + } +} diff --git a/internal/adapters/signing/httpgateway/httpgateway.go b/internal/adapters/signing/httpgateway/httpgateway.go index f3f68aa..c9c52fa 100644 --- a/internal/adapters/signing/httpgateway/httpgateway.go +++ b/internal/adapters/signing/httpgateway/httpgateway.go @@ -58,7 +58,7 @@ func New(cfg Config) (*Executor, error) { if err != nil || parsed.Scheme == "" || parsed.Host == "" { return nil, app.ErrValidation } - if parsed.Scheme != "https" && !(cfg.AllowInsecureForLocalhost && parsed.Scheme == "http" && localhostHost(parsed.Hostname())) { + if parsed.Scheme != "https" && (!cfg.AllowInsecureForLocalhost || parsed.Scheme != "http" || !localhostHost(parsed.Hostname())) { return nil, errors.New("signing gateway endpoint must use https") } timeout := cfg.Timeout diff --git a/internal/app/integrity_runtime.go b/internal/app/integrity_runtime.go index 5da9673..c931016 100644 --- a/internal/app/integrity_runtime.go +++ b/internal/app/integrity_runtime.go @@ -322,38 +322,83 @@ func (l *Ledger) VerifyObjectRetentionPolicy(ctx context.Context, actor domain.A if err := require(actor, ScopeVerifyRead); err != nil { return domain.ObjectRetentionPolicy{}, err } + id = strings.TrimSpace(id) l.mu.Lock() - defer l.mu.Unlock() - policy, ok := l.retentionPolicies[strings.TrimSpace(id)] + policy, ok := l.retentionPolicies[id] if !ok || policy.TenantID != actor.TenantID { + l.mu.Unlock() return domain.ObjectRetentionPolicy{}, ErrNotFound } + verifier := l.retention + l.mu.Unlock() + + retentionResult := ObjectRetentionResult{ + Provider: "local_record", + Checks: []domain.VerifyCheck{{ + Name: "object_retention_provider_verifier", + Result: "warning", + Detail: "No provider-backed object-lock verifier is configured; this records tenant-scoped retention intent only.", + }}, + Limitations: []string{"Provider-enforced object-lock, bucket versioning, and WORM settings were not checked by this ledger instance."}, + } + status := "verified" + if verifier != nil { + result, err := verifier.VerifyObjectRetention(ctx, ObjectRetentionRequest{ + TenantID: policy.TenantID, + ObjectPrefix: policy.ObjectPrefix, + Mode: policy.Mode, + RetentionDays: policy.RetentionDays, + }) + if err != nil { + return domain.ObjectRetentionPolicy{}, ErrVerificationFailed + } + retentionResult = result + if !result.Enforced { + status = "not_enforced" + } + } + now := l.now() - policy.Status = "verified" + policy.Status = status policy.VerifiedAt = &now + policy.VerificationChecks = append([]domain.VerifyCheck(nil), retentionResult.Checks...) + policy.VerificationLimitations = append([]string(nil), retentionResult.Limitations...) verificationHash, err := canonicalAnyHash(struct { - ID string `json:"id"` - TenantID string `json:"tenant_id"` - ObjectPrefix string `json:"object_prefix"` - Mode string `json:"mode"` - RetentionDays int `json:"retention_days"` - Status string `json:"status"` - VerifiedAt string `json:"verified_at"` + ID string `json:"id"` + TenantID string `json:"tenant_id"` + ObjectPrefix string `json:"object_prefix"` + Mode string `json:"mode"` + Provider string `json:"provider"` + RetentionDays int `json:"retention_days"` + Status string `json:"status"` + VerifiedAt string `json:"verified_at"` + Checks []domain.VerifyCheck `json:"checks"` + Limitations []string `json:"limitations"` }{ ID: policy.ID, TenantID: policy.TenantID, ObjectPrefix: policy.ObjectPrefix, Mode: policy.Mode, + Provider: retentionResult.Provider, RetentionDays: policy.RetentionDays, Status: policy.Status, VerifiedAt: now.Format(time.RFC3339Nano), + Checks: policy.VerificationChecks, + Limitations: policy.VerificationLimitations, }) if err != nil { return domain.ObjectRetentionPolicy{}, err } policy.VerificationHash = verificationHash + + l.mu.Lock() + defer l.mu.Unlock() l.retentionPolicies[policy.ID] = policy - _, _ = l.appendChainLocked(actor.TenantID, "object_retention_policy.verified", "object_retention_policy", policy.ID, actorType(actor), actorID(actor), "", "") + entryType := "object_retention_policy.verified" + if policy.Status != "verified" { + entryType = "object_retention_policy.verification_failed" + } + _, _ = l.appendChainLocked(actor.TenantID, entryType, "object_retention_policy", policy.ID, actorType(actor), actorID(actor), policy.VerificationHash, "") if err := l.persistLocked(ctx); err != nil { return domain.ObjectRetentionPolicy{}, err } diff --git a/internal/app/integrity_runtime_test.go b/internal/app/integrity_runtime_test.go index e6034fc..64a3204 100644 --- a/internal/app/integrity_runtime_test.go +++ b/internal/app/integrity_runtime_test.go @@ -6,6 +6,8 @@ import ( "strings" "testing" "time" + + "github.com/aatuh/evydence/internal/domain" ) func TestCosignMerkleTransparencyAndKeyRevocationFlow(t *testing.T) { @@ -82,6 +84,9 @@ func TestRuntimeRetentionBackupReadinessMetricsAndAudit(t *testing.T) { if verifiedPolicy.Status != "verified" || verifiedPolicy.VerifiedAt == nil { t.Fatalf("verified policy = %#v", verifiedPolicy) } + if len(verifiedPolicy.VerificationChecks) == 0 || len(verifiedPolicy.VerificationLimitations) == 0 { + t.Fatalf("expected local retention verification limitations: %#v", verifiedPolicy) + } manifest, err := ledger.GenerateBackupManifest(ctx, actor) if err != nil { t.Fatalf("backup manifest: %v", err) @@ -120,6 +125,88 @@ func TestRuntimeRetentionBackupReadinessMetricsAndAudit(t *testing.T) { } } +func TestObjectRetentionVerifierRecordsProviderChecks(t *testing.T) { + verifier := &fakeObjectRetentionVerifier{result: ObjectRetentionResult{ + Provider: "s3", + Enforced: true, + Checks: []domain.VerifyCheck{ + {Name: "s3_bucket_versioning", Result: "passed"}, + {Name: "s3_object_lock_mode", Result: "passed"}, + }, + Limitations: []string{"Bucket-level settings checked only."}, + }} + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow, Retention: verifier}) + ctx := context.Background() + _, _, secret, err := ledger.BootstrapTenant(ctx, "Tenant", "admin", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap: %v", err) + } + actor, err := ledger.Authenticate(ctx, secret) + if err != nil { + t.Fatalf("auth: %v", err) + } + policy, err := ledger.CreateObjectRetentionPolicy(ctx, actor, CreateObjectRetentionPolicyInput{Name: "objects", Mode: "compliance", RetentionDays: 90}) + if err != nil { + t.Fatalf("create policy: %v", err) + } + verified, err := ledger.VerifyObjectRetentionPolicy(ctx, actor, policy.ID) + if err != nil { + t.Fatalf("verify policy: %v", err) + } + if verified.Status != "verified" || verified.VerificationHash == "" { + t.Fatalf("verified policy = %#v", verified) + } + if len(verifier.requests) != 1 || verifier.requests[0].ObjectPrefix != "tenants/"+actor.TenantID+"/" { + t.Fatalf("verifier requests = %#v", verifier.requests) + } + if len(verified.VerificationChecks) != 2 || verified.VerificationChecks[0].Name != "s3_bucket_versioning" { + t.Fatalf("checks = %#v", verified.VerificationChecks) + } +} + +func TestObjectRetentionVerifierMarksProviderFailure(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow, Retention: &fakeObjectRetentionVerifier{result: ObjectRetentionResult{ + Provider: "s3", + Enforced: false, + Checks: []domain.VerifyCheck{{Name: "s3_object_lock_retention", Result: "failed"}}, + Limitations: []string{"Bucket default retention is shorter than requested."}, + }}}) + ctx := context.Background() + _, _, secret, err := ledger.BootstrapTenant(ctx, "Tenant", "admin", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap: %v", err) + } + actor, err := ledger.Authenticate(ctx, secret) + if err != nil { + t.Fatalf("auth: %v", err) + } + policy, err := ledger.CreateObjectRetentionPolicy(ctx, actor, CreateObjectRetentionPolicyInput{Name: "objects", Mode: "governance", RetentionDays: 365}) + if err != nil { + t.Fatalf("create policy: %v", err) + } + verified, err := ledger.VerifyObjectRetentionPolicy(ctx, actor, policy.ID) + if err != nil { + t.Fatalf("verify policy: %v", err) + } + if verified.Status != "not_enforced" || verified.VerificationChecks[0].Result != "failed" { + t.Fatalf("verified policy = %#v", verified) + } +} + +type fakeObjectRetentionVerifier struct { + result ObjectRetentionResult + err error + requests []ObjectRetentionRequest +} + +func (f *fakeObjectRetentionVerifier) VerifyObjectRetention(_ context.Context, req ObjectRetentionRequest) (ObjectRetentionResult, error) { + f.requests = append(f.requests, req) + if f.err != nil { + return ObjectRetentionResult{}, f.err + } + return f.result, nil +} + func TestBackupRestoreRehearsalPreservesLedgerAndObjectPayloads(t *testing.T) { ctx := context.Background() store := NewMemoryStore() diff --git a/internal/app/ledger.go b/internal/app/ledger.go index 055b952..91bafc0 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -66,6 +66,7 @@ type Config struct { Now func() time.Time Store Store ObjectStore ObjectStore + Retention ObjectRetentionVerifier Signer SigningExecutor Outbox Outbox } @@ -73,12 +74,13 @@ type Config struct { type Ledger struct { mu sync.Mutex - pepper []byte - now func() time.Time - store Store - objects ObjectStore - signer SigningExecutor - outbox Outbox + pepper []byte + now func() time.Time + store Store + objects ObjectStore + retention ObjectRetentionVerifier + signer SigningExecutor + outbox Outbox tenants map[string]domain.Tenant organizations map[string]domain.Organization @@ -188,11 +190,18 @@ func NewLedgerWithError(cfg Config) (*Ledger, error) { if pepper == "" { pepper = "local-dev-pepper-change-me" } + retention := cfg.Retention + if retention == nil && cfg.ObjectStore != nil { + if verifier, ok := cfg.ObjectStore.(ObjectRetentionVerifier); ok { + retention = verifier + } + } ledger := &Ledger{ pepper: []byte(pepper), now: now, store: cfg.Store, objects: cfg.ObjectStore, + retention: retention, signer: cfg.Signer, outbox: cfg.Outbox, tenants: map[string]domain.Tenant{}, diff --git a/internal/app/ports.go b/internal/app/ports.go index c0d3d34..1ff932b 100644 --- a/internal/app/ports.go +++ b/internal/app/ports.go @@ -17,6 +17,10 @@ type ObjectStore interface { Get(context.Context, string) (Object, error) } +type ObjectRetentionVerifier interface { + VerifyObjectRetention(context.Context, ObjectRetentionRequest) (ObjectRetentionResult, error) +} + type SigningExecutor interface { Sign(context.Context, SigningRequest) (SigningResult, error) } @@ -42,6 +46,20 @@ type SigningResult struct { Checks []domain.VerifyCheck } +type ObjectRetentionRequest struct { + TenantID string + ObjectPrefix string + Mode string + RetentionDays int +} + +type ObjectRetentionResult struct { + Provider string + Enforced bool + Checks []domain.VerifyCheck + Limitations []string +} + type PersistedState struct { Tenants map[string]domain.Tenant `json:"tenants"` Organizations map[string]domain.Organization `json:"organizations"` diff --git a/internal/domain/domain.go b/internal/domain/domain.go index d951399..6ad0f90 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -690,17 +690,19 @@ type TransparencyCheckpoint struct { } type ObjectRetentionPolicy struct { - ID string `json:"id"` - TenantID string `json:"tenant_id"` - Name string `json:"name"` - ObjectPrefix string `json:"object_prefix"` - Mode string `json:"mode"` - RetentionDays int `json:"retention_days"` - Status string `json:"status"` - VerifiedAt *time.Time `json:"verified_at,omitempty"` - VerificationHash string `json:"verification_hash,omitempty"` - SchemaVersion string `json:"schema_version"` - CreatedAt time.Time `json:"created_at"` + ID string `json:"id"` + TenantID string `json:"tenant_id"` + Name string `json:"name"` + ObjectPrefix string `json:"object_prefix"` + Mode string `json:"mode"` + RetentionDays int `json:"retention_days"` + Status string `json:"status"` + VerifiedAt *time.Time `json:"verified_at,omitempty"` + VerificationHash string `json:"verification_hash,omitempty"` + VerificationChecks []VerifyCheck `json:"verification_checks,omitempty"` + VerificationLimitations []string `json:"verification_limitations,omitempty"` + SchemaVersion string `json:"schema_version"` + CreatedAt time.Time `json:"created_at"` } type BackupManifest struct { diff --git a/openapi.yaml b/openapi.yaml index 74a631a..35aeaa5 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From 7e8b22e104561c12733b0c31e09acc5f0ce19a6b Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 19:59:51 +0300 Subject: [PATCH 083/287] feat: verify public transparency inclusion proofs --- .implementation_increments.md | 4 +- README.md | 4 +- docs/api.md | 1 + docs/architecture.md | 4 +- docs/operations.md | 1 + docs/reference/api-contract-matrix.md | 3 +- docs/reference/production-readiness.md | 9 +- internal/adapters/httpapi/future_handlers.go | 23 +++ internal/adapters/httpapi/openapi.go | 32 ++-- .../adapters/httpapi/openapi_operations.go | 5 + .../adapters/httpapi/route_registration.go | 1 + internal/adapters/httpapi/router.go | 1 + internal/adapters/httpapi/router_test.go | 6 + internal/app/future_extensions.go | 166 ++++++++++++++++++ internal/app/future_extensions_test.go | 26 +++ internal/domain/domain.go | 25 +-- openapi.yaml | 2 +- sdk/openapi-route-catalog.json | 19 +- 18 files changed, 299 insertions(+), 33 deletions(-) diff --git a/.implementation_increments.md b/.implementation_increments.md index 66c9a81..c2d08e6 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -238,7 +238,7 @@ Status legend: Added explicit-instance-admin SaaS edition profile records with configuration hashes, limitations, persistence, migrations, API route, OpenAPI entry, docs, and tests. 70. `[x]` Public Transparency Log - Added optional public transparency log and published-entry records linked to local Merkle batches and transparency checkpoints, with entry hashes, persistence, migrations, API routes, OpenAPI entries, docs, and tests. + Added optional public transparency log and published-entry records linked to local Merkle batches and transparency checkpoints, with entry hashes, operator-supplied RFC6962-style inclusion proof verification receipts, persistence, migrations, API routes, OpenAPI entries, docs, and tests. 71. `[x]` Marketplace Collectors Added marketplace collector package records with publisher, provider/version, manifest digest, optional signature/SBOM/scan references, tenant isolation, persistence, migrations, API routes, OpenAPI entries, docs, and tests. @@ -254,7 +254,7 @@ Status legend: - `[x]` Object-retention verification receipts now record a reproducible verification hash, while WORM/object-lock enforcement remains a deployment and object-store control. - `[x]` External signing-provider operation receipts now record payload hashes, checks, and signature references, while production KMS/HSM adapter execution remains deployment hardening work. - `[x]` Stored OIDC/SAML identity-link verification records provider-verification receipts, and OIDC ID tokens plus SAML assertions can be verified locally against configured tenant trust material. Live provider discovery/API calls, browser login callbacks, and group synchronization remain external/provider work. -- `[x]` Public transparency log records now link local Merkle checkpoints to external entry metadata, while live inclusion proof verification remains operator-controlled. +- `[x]` Public transparency log records now link local Merkle checkpoints to external entry metadata and can verify operator-supplied inclusion proof material locally. Live provider fetching remains deployment hardening work. - `[x]` Marketplace collector records now capture package metadata and evidence references, and expose package health reports for signature, SBOM, and vulnerability scan evidence gaps. Marketplace distribution remains external operational hardening. - `[x]` Docker/Helm runtime packaging now includes the worker binary and migrations and uses commands that match the image PATH. - `[x]` GitHub Actions example now passes the digest computed in the workflow instead of an unrelated repository variable. diff --git a/README.md b/README.md index 5a53fdb..8af9e32 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ This repository contains a Go implementation under module `github.com/aatuh/evyd - AGPL license, commercial licensing, governance, contribution, security, support, trademark, release-evidence, and changelog metadata. -Implemented-but-partial areas are documented explicitly: signing-provider operation receipts do not replace production KMS/HSM adapters, local OIDC/SAML verification does not replace live provider discovery/API validation or browser login callbacks, and public transparency records do not prove external log inclusion without the configured operator workflow. +Implemented-but-partial areas are documented explicitly: signing-provider operation receipts do not replace production KMS/HSM adapters, local OIDC/SAML verification does not replace live provider discovery/API validation or browser login callbacks, and public transparency records require operator-supplied inclusion proof material before Evydence can verify local inclusion receipts. ## License, Security, Support, And Governance @@ -107,4 +107,4 @@ make postgres-integration-test `make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. -`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required production-readiness evidence, but it does not by itself close the remaining relational persistence, worker side-effect, SDK, backup/restore, KMS/HSM, SSO, object-lock, transparency, and exit-review work. +`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required production-readiness evidence, but it does not by itself close the remaining relational persistence, worker side-effect, SDK, backup/restore, KMS/HSM, SSO, live provider-fetching, object-lock, and exit-review work. diff --git a/docs/api.md b/docs/api.md index 73010ac..b1f2721 100644 --- a/docs/api.md +++ b/docs/api.md @@ -394,6 +394,7 @@ Source snapshots capture submitted provider metadata. They do not call provider | `POST` | `/v1/transparency-checkpoints` | Record external anchoring metadata. | | `POST` | `/v1/public-transparency-logs` | Record optional public transparency log configuration. | | `POST` | `/v1/public-transparency-log-entries` | Record published public transparency log entry metadata. | +| `POST` | `/v1/public-transparency-log-entries/{id}/verify` | Verify operator-supplied RFC6962-style public transparency inclusion proof material. | | `POST` | `/v1/object-retention-policies` | Record retention policy intent. | | `POST` | `/v1/object-retention-policies/{id}/verify` | Record verification transition. | | `POST` | `/v1/legal-holds` | Record legal hold. | diff --git a/docs/architecture.md b/docs/architecture.md index c7978ce..d66eca1 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -34,7 +34,7 @@ Release readiness is deterministic and evidence-scoped. Open critical vulnerabil DSSE attestation signatures can be verified against configured Ed25519 trust roots when raw attestation bytes are available. Cosign-style artifact verification records digest binding, signature presence, and optional Rekor metadata without overstating full Sigstore trust-chain validation. Signing keys support revocation and valid-at-signing semantics for historical signatures. -Merkle batches, signed checkpoints, optional transparency checkpoint/public transparency records, backup manifests, object-retention policy records with verification hashes, legal holds, retention overrides, readiness, metrics, instance admin diagnostics, external signing gateway receipts, and admin audit queries provide operational integrity and review surfaces. +Merkle batches, signed checkpoints, optional transparency checkpoint/public transparency records with operator-supplied inclusion proof verification, backup manifests, object-retention policy records with verification hashes, legal holds, retention overrides, readiness, metrics, instance admin diagnostics, external signing gateway receipts, and admin audit queries provide operational integrity and review surfaces. ## Reports And Customer-Facing Packages @@ -52,6 +52,6 @@ Air-gapped import-bundle workflows preserve the same tenant-scoped import path a ## Limitations -The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts and an optional HTTPS signing gateway executor are implemented, but direct cloud KMS/HSM SDK adapters and live Sigstore/public-transparency verification remain deployment hardening work. Hand-tuned per-resource repository implementations and moving parser side effects fully out of request paths remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. +The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts and an optional HTTPS signing gateway executor are implemented, but direct cloud KMS/HSM SDK adapters, live Sigstore verification, and live public-transparency proof fetching remain deployment hardening work. Hand-tuned per-resource repository implementations and moving parser side effects fully out of request paths remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. Evydence does not prove provider truth, scanner authority, runtime security, legal compliance, or release security by itself. diff --git a/docs/operations.md b/docs/operations.md index ef0ef53..d850adb 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -24,6 +24,7 @@ This operator index points to the canonical references for running Evydence. Kee - Use `GET /v1/admin/instance` only with an actor explicitly granted `instance:admin`. Tenant admin and ordinary wildcard tenant keys do not satisfy this instance-wide scope by themselves. - Use `POST /v1/backup-manifests` after database and object-store backups complete. The manifest intentionally excludes raw payload bytes and private signing-key material. - Use `POST /v1/merkle-batches` and `POST /v1/transparency-checkpoints` to record signed local checkpoints and optional external anchoring metadata. +- Use `POST /v1/public-transparency-log-entries/{id}/verify` when an operator has public-log inclusion proof material. Evydence verifies the supplied RFC6962-style proof locally and records checks and limitations; it does not fetch proof material from the provider. ## Token And Trust Boundaries diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index 32e8e95..1347389 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 160 operations: 160 precise, 0 broad. +Generated from 161 operations: 161 precise, 0 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -95,6 +95,7 @@ Generated from 160 operations: 160 precise, 0 broad. | POST | /v1/projects | createProject | Bearer | project:write | required | - | application/json:CreateProjectRequest | 201:application/json:ProjectEnvelope | precise | | POST | /v1/provider-verifications | verifyProviderIdentity | Bearer | identity:admin | required | - | application/json:VerifyProviderIdentityRequest | 201:application/json:ProviderVerificationEnvelope | precise | | POST | /v1/public-transparency-log-entries | publishPublicTransparencyLogEntry | Bearer | keys:admin | required | - | application/json:PublishPublicTransparencyLogEntryRequest | 201:application/json:PublicTransparencyLogEntryEnvelope | precise | +| POST | /v1/public-transparency-log-entries/{id}/verify | verifyPublicTransparencyLogEntry | Bearer | keys:admin | required | path:id | application/json:VerifyPublicTransparencyLogEntryRequest | 200:application/json:PublicTransparencyLogEntryEnvelope | precise | | POST | /v1/public-transparency-logs | createPublicTransparencyLog | Bearer | keys:admin | required | - | application/json:CreatePublicTransparencyLogRequest | 201:application/json:PublicTransparencyLogEnvelope | precise | | POST | /v1/questionnaire-drafts | createQuestionnaireDraft | Bearer | package:read | required | - | application/json:CreateQuestionnaireDraftRequest | 201:application/json:QuestionnaireDraftEnvelope | precise | | POST | /v1/questionnaire-packages | createQuestionnairePackage | Bearer | package:write | required | - | application/json:CreateQuestionnairePackageRequest | 201:application/json:QuestionnairePackageEnvelope | precise | diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index ecf24ba..45367df 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -24,8 +24,8 @@ Known hardening work remains: parameters, and request/response schemas; - production signing can use the HTTPS signing gateway executor, but direct cloud KMS/HSM SDK adapters, full browser OIDC/SAML login flows, provider - discovery/group sync, object-lock enforcement proof, and transparency - inclusion proof verification remain provider- and deployment-dependent + discovery/group sync, object-lock enforcement proof, and live + transparency-proof fetching remain provider- and deployment-dependent hardening areas; - the broader production exit review remains incomplete. @@ -109,8 +109,9 @@ implemented capabilities: - Complete live OIDC/SAML browser login callbacks, provider discovery, JWKS refresh, logout, and optional group mapping where those profiles are enabled. - Extend object-lock/WORM verification beyond current S3/MinIO bucket-level - checks where deployments require object-level legal hold proofs, provider - policy evidence, or optional transparency inclusion proof verification. + checks where deployments require object-level legal hold proofs or provider + policy evidence, and add live provider fetching for public transparency proofs + where deployments require it. - Run final product, codebase, security, documentation, and test audits before changing release status beyond controlled self-hosted production candidate. diff --git a/internal/adapters/httpapi/future_handlers.go b/internal/adapters/httpapi/future_handlers.go index 39dddbe..8cb7fb3 100644 --- a/internal/adapters/httpapi/future_handlers.go +++ b/internal/adapters/httpapi/future_handlers.go @@ -97,6 +97,29 @@ func (s *Server) publishPublicTransparencyLogEntry(w http.ResponseWriter, r *htt }) } +func (s *Server) verifyPublicTransparencyLogEntry(w http.ResponseWriter, r *http.Request) { + var req struct { + LeafHash string `json:"leaf_hash"` + RootHash string `json:"root_hash"` + LeafIndex int `json:"leaf_index"` + TreeSize int `json:"tree_size"` + InclusionProof []string `json:"inclusion_proof"` + } + s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + if err := decodeJSON(body, &req); err != nil { + return 0, nil, err + } + entry, err := s.ledger.VerifyPublicTransparencyLogEntry(r.Context(), actor, r.PathValue("id"), app.VerifyPublicTransparencyLogEntryInput{ + LeafHash: req.LeafHash, + RootHash: req.RootHash, + LeafIndex: req.LeafIndex, + TreeSize: req.TreeSize, + InclusionProof: req.InclusionProof, + }) + return http.StatusOK, entry, err + }) +} + func (s *Server) createMarketplaceCollector(w http.ResponseWriter, r *http.Request) { var req struct { Name string `json:"name"` diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 5ee812a..010a9af 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -1968,17 +1968,29 @@ func registerCriticalSchemas(registry *specs.Registry) { "checkpoint_id": map[string]any{"type": "string"}, "external_id": map[string]any{"type": "string"}, }, "log_id", "checkpoint_id", "external_id")) + registry.RegisterSchema("VerifyPublicTransparencyLogEntryRequest", objectSchema(map[string]any{ + "leaf_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "root_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "leaf_index": map[string]any{"type": "integer", "minimum": 0}, + "tree_size": map[string]any{"type": "integer", "minimum": 1}, + "inclusion_proof": map[string]any{"type": "array", "items": map[string]any{"type": "string", "pattern": "^sha256:"}}, + }, "root_hash", "leaf_index", "tree_size", "inclusion_proof")) registry.RegisterSchema("PublicTransparencyLogEntry", objectSchema(map[string]any{ - "id": map[string]any{"type": "string"}, - "tenant_id": map[string]any{"type": "string"}, - "log_id": map[string]any{"type": "string"}, - "checkpoint_id": map[string]any{"type": "string"}, - "merkle_batch_id": map[string]any{"type": "string"}, - "external_id": map[string]any{"type": "string"}, - "entry_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, - "state": map[string]any{"type": "string"}, - "schema_version": map[string]any{"type": "string"}, - "created_at": map[string]any{"type": "string", "format": "date-time"}, + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "log_id": map[string]any{"type": "string"}, + "checkpoint_id": map[string]any{"type": "string"}, + "merkle_batch_id": map[string]any{"type": "string"}, + "external_id": map[string]any{"type": "string"}, + "entry_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "inclusion_root_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "inclusion_proof_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "inclusion_verified_at": map[string]any{"type": "string", "format": "date-time"}, + "verification_checks": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/VerifyCheck"}}, + "verification_limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "state": map[string]any{"type": "string"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, }, "id", "tenant_id", "log_id", "checkpoint_id", "merkle_batch_id", "external_id", "entry_hash", "state", "schema_version", "created_at")) registry.RegisterSchema("PublicTransparencyLogEntryEnvelope", dataEnvelopeSchema("#/components/schemas/PublicTransparencyLogEntry")) registry.RegisterSchema("CreateSaaSEditionProfileRequest", objectSchema(map[string]any{ diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 621656e..7baba64 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -594,6 +594,11 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Description = "Records publication metadata for a checkpoint submitted to a configured public transparency log." operation.RequestBody = jsonRequest("Public transparency log entry publication request.", "#/components/schemas/PublishPublicTransparencyLogEntryRequest") operation.Responses[http.StatusCreated] = jsonResponse("Created public transparency log entry envelope.", "#/components/schemas/PublicTransparencyLogEntryEnvelope") + case "verifyPublicTransparencyLogEntry": + operation.Description = "Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry." + operation.Parameters = append(operation.Parameters, pathParam("id", "Public transparency log entry id.")) + operation.RequestBody = jsonRequest("Public transparency log inclusion proof verification request.", "#/components/schemas/VerifyPublicTransparencyLogEntryRequest") + operation.Responses[http.StatusOK] = jsonResponse("Verified public transparency log entry envelope.", "#/components/schemas/PublicTransparencyLogEntryEnvelope") case "createObjectRetentionPolicy": operation.Description = "Creates an object retention policy record for storage immutability verification." operation.RequestBody = jsonRequest("Object retention policy creation request.", "#/components/schemas/CreateObjectRetentionPolicyRequest") diff --git a/internal/adapters/httpapi/route_registration.go b/internal/adapters/httpapi/route_registration.go index 0bbb3fb..300ddda 100644 --- a/internal/adapters/httpapi/route_registration.go +++ b/internal/adapters/httpapi/route_registration.go @@ -236,6 +236,7 @@ func (s *Server) integrityOpsRoutes() []routeDef { {http.MethodPost, "/v1/transparency-checkpoints", op("createTransparencyCheckpoint", http.MethodPost, "/v1/transparency-checkpoints", "Record external transparency checkpoint", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.createTransparencyCheckpoint)}, {http.MethodPost, "/v1/public-transparency-logs", op("createPublicTransparencyLog", http.MethodPost, "/v1/public-transparency-logs", "Create public transparency log record", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.createPublicTransparencyLog)}, {http.MethodPost, "/v1/public-transparency-log-entries", op("publishPublicTransparencyLogEntry", http.MethodPost, "/v1/public-transparency-log-entries", "Publish public transparency log entry record", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.publishPublicTransparencyLogEntry)}, + {http.MethodPost, "/v1/public-transparency-log-entries/{id}/verify", op("verifyPublicTransparencyLogEntry", http.MethodPost, "/v1/public-transparency-log-entries/{id}/verify", "Verify public transparency log inclusion proof", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.verifyPublicTransparencyLogEntry)}, {http.MethodPost, "/v1/object-retention-policies", op("createObjectRetentionPolicy", http.MethodPost, "/v1/object-retention-policies", "Create object retention policy record", []string{app.ScopeAdmin}), http.HandlerFunc(s.createObjectRetentionPolicy)}, {http.MethodPost, "/v1/object-retention-policies/{id}/verify", op("verifyObjectRetentionPolicy", http.MethodPost, "/v1/object-retention-policies/{id}/verify", "Verify object retention policy record", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.verifyObjectRetentionPolicy)}, {http.MethodPost, "/v1/legal-holds", op("createLegalHold", http.MethodPost, "/v1/legal-holds", "Create legal hold", []string{app.ScopeAdmin}), http.HandlerFunc(s.createLegalHold)}, diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index 23cf8da..f6b54b8 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -2312,6 +2312,7 @@ func defaultSuccessStatus(operationID, method string) int { "downloadCustomerPortalPackage", "approveException", "verifyObjectRetentionPolicy", + "verifyPublicTransparencyLogEntry", "revokeSigningKey", "verify": return http.StatusOK diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 6e341b5..93d2b7e 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -1076,6 +1076,12 @@ func TestFutureExtensionAndReadAdminHTTPGaps(t *testing.T) { if !strings.Contains(entry, `"entry_hash"`) { t.Fatalf("public log entry missing hash: %s", entry) } + entryID := dataField(t, entry, "id") + entryHash := dataField(t, entry, "entry_hash") + verifiedEntry := postJSON(t, server, secret, "/v1/public-transparency-log-entries/"+entryID+"/verify", "future-public-entry-verify", map[string]any{"root_hash": entryHash, "leaf_index": 0, "tree_size": 1, "inclusion_proof": []string{}}, http.StatusOK) + if !strings.Contains(verifiedEntry, `"state":"inclusion_verified"`) { + t.Fatalf("public log entry verification failed: %s", verifiedEntry) + } marketplace := postJSON(t, server, secret, "/v1/marketplace-collectors", "future-marketplace", map[string]any{"name": "scanner", "provider": "scannerco", "version": "1.0.0", "publisher": "scannerco", "manifest_hash": digest}, http.StatusCreated) if !strings.Contains(getJSON(t, server, secret, "/v1/marketplace-collectors", http.StatusOK), dataField(t, marketplace, "id")) { t.Fatalf("marketplace list missing collector") diff --git a/internal/app/future_extensions.go b/internal/app/future_extensions.go index f2aa5b6..92062d0 100644 --- a/internal/app/future_extensions.go +++ b/internal/app/future_extensions.go @@ -1,6 +1,7 @@ package app import ( + "bytes" "context" "crypto" "crypto/ed25519" @@ -8,6 +9,7 @@ import ( "crypto/sha256" "crypto/x509" "encoding/base64" + "encoding/hex" "encoding/json" "encoding/pem" "encoding/xml" @@ -55,6 +57,14 @@ type PublishPublicTransparencyLogEntryInput struct { ExternalID string } +type VerifyPublicTransparencyLogEntryInput struct { + LeafHash string + RootHash string + LeafIndex int + TreeSize int + InclusionProof []string +} + type CreateMarketplaceCollectorInput struct { Name string Provider string @@ -396,6 +406,162 @@ func (l *Ledger) PublishPublicTransparencyLogEntry(ctx context.Context, actor do return entry, nil } +func (l *Ledger) VerifyPublicTransparencyLogEntry(ctx context.Context, actor domain.Actor, id string, in VerifyPublicTransparencyLogEntryInput) (domain.PublicTransparencyLogEntry, error) { + if err := ctx.Err(); err != nil { + return domain.PublicTransparencyLogEntry{}, err + } + if err := require(actor, ScopeKeysAdmin); err != nil { + return domain.PublicTransparencyLogEntry{}, err + } + id = strings.TrimSpace(id) + leafHash := strings.TrimSpace(in.LeafHash) + rootHash := strings.TrimSpace(in.RootHash) + if id == "" || rootHash == "" || in.TreeSize <= 0 || in.LeafIndex < 0 || in.LeafIndex >= in.TreeSize || len(in.InclusionProof) > 64 { + return domain.PublicTransparencyLogEntry{}, ErrValidation + } + for i := range in.InclusionProof { + in.InclusionProof[i] = strings.TrimSpace(in.InclusionProof[i]) + if !validSHA256Digest(in.InclusionProof[i]) { + return domain.PublicTransparencyLogEntry{}, ErrValidation + } + } + if !validSHA256Digest(rootHash) { + return domain.PublicTransparencyLogEntry{}, ErrValidation + } + + l.mu.Lock() + entry, ok := l.publicLogEntries[id] + if !ok || entry.TenantID != actor.TenantID { + l.mu.Unlock() + return domain.PublicTransparencyLogEntry{}, ErrNotFound + } + if leafHash == "" { + leafHash = entry.EntryHash + } + if !validSHA256Digest(leafHash) { + l.mu.Unlock() + return domain.PublicTransparencyLogEntry{}, ErrValidation + } + if _, ok := l.publicLogs[entry.LogID]; !ok { + l.mu.Unlock() + return domain.PublicTransparencyLogEntry{}, ErrNotFound + } + if _, ok := l.transparency[entry.CheckpointID]; !ok { + l.mu.Unlock() + return domain.PublicTransparencyLogEntry{}, ErrNotFound + } + l.mu.Unlock() + + leafBound := leafHash == entry.EntryHash + proofOK := leafBound && verifyRFC6962StyleProof(leafHash, rootHash, in.LeafIndex, in.TreeSize, in.InclusionProof) + checks := []domain.VerifyCheck{ + {Name: "public_log_leaf_binding", Result: checkResultString(leafBound), Detail: "The supplied leaf hash must match the published Evydence entry hash."}, + {Name: "public_log_inclusion_proof", Result: checkResultString(proofOK), Detail: "The supplied proof must recompute the supplied public-log root hash."}, + } + proofHash, err := canonicalAnyHash(struct { + EntryID string `json:"entry_id"` + LeafHash string `json:"leaf_hash"` + RootHash string `json:"root_hash"` + LeafIndex int `json:"leaf_index"` + TreeSize int `json:"tree_size"` + InclusionProof []string `json:"inclusion_proof"` + }{ + EntryID: entry.ID, + LeafHash: leafHash, + RootHash: rootHash, + LeafIndex: in.LeafIndex, + TreeSize: in.TreeSize, + InclusionProof: append([]string(nil), in.InclusionProof...), + }) + if err != nil { + return domain.PublicTransparencyLogEntry{}, err + } + now := l.now() + entry.InclusionRootHash = rootHash + entry.InclusionProofHash = proofHash + entry.InclusionVerifiedAt = &now + entry.VerificationChecks = checks + entry.VerificationLimitations = []string{ + "Evydence verifies the supplied RFC6962-style proof material locally; it does not fetch proof material or prove public-log availability.", + "Operators remain responsible for public-log trust, endpoint availability, and any provider-specific inclusion semantics.", + } + entry.State = "inclusion_verified" + if !proofOK { + entry.State = "inclusion_not_verified" + } + + l.mu.Lock() + defer l.mu.Unlock() + l.publicLogEntries[entry.ID] = entry + eventType := "public_transparency_log_entry.inclusion_verified" + if !proofOK { + eventType = "public_transparency_log_entry.inclusion_not_verified" + } + _, _ = l.appendChainLocked(actor.TenantID, eventType, "public_transparency_log_entry", entry.ID, actorType(actor), actorID(actor), proofHash, "") + if err := l.persistLocked(ctx); err != nil { + return domain.PublicTransparencyLogEntry{}, err + } + return entry, nil +} + +func verifyRFC6962StyleProof(leafHash, rootHash string, leafIndex, treeSize int, proof []string) bool { + if treeSize == 1 { + return leafIndex == 0 && len(proof) == 0 && leafHash == rootHash + } + node, err := decodeSHA256Digest(leafHash) + if err != nil { + return false + } + index := leafIndex + for _, proofHash := range proof { + sibling, err := decodeSHA256Digest(proofHash) + if err != nil { + return false + } + if index%2 == 0 { + node = transparencyParentHash(node, sibling) + } else { + node = transparencyParentHash(sibling, node) + } + index /= 2 + } + root, err := decodeSHA256Digest(rootHash) + if err != nil { + return false + } + return bytes.Equal(node, root) +} + +func transparencyParentHash(left, right []byte) []byte { + h := sha256.New() + h.Write([]byte{0x01}) + h.Write(left) + h.Write(right) + return h.Sum(nil) +} + +func decodeSHA256Digest(value string) ([]byte, error) { + if !validSHA256Digest(value) { + return nil, ErrValidation + } + return hex.DecodeString(strings.TrimPrefix(value, "sha256:")) +} + +func validSHA256Digest(value string) bool { + if !strings.HasPrefix(value, "sha256:") || len(value) != len("sha256:")+64 { + return false + } + _, err := hex.DecodeString(strings.TrimPrefix(value, "sha256:")) + return err == nil +} + +func checkResultString(ok bool) string { + if ok { + return "passed" + } + return "failed" +} + func (l *Ledger) CreateMarketplaceCollector(ctx context.Context, actor domain.Actor, in CreateMarketplaceCollectorInput) (domain.MarketplaceCollector, error) { if err := ctx.Err(); err != nil { return domain.MarketplaceCollector{}, err diff --git a/internal/app/future_extensions_test.go b/internal/app/future_extensions_test.go index 6f6cb2c..231f7e6 100644 --- a/internal/app/future_extensions_test.go +++ b/internal/app/future_extensions_test.go @@ -2,6 +2,7 @@ package app import ( "context" + "encoding/hex" "errors" "strings" "testing" @@ -133,6 +134,28 @@ func TestFutureOperationalExtensionsAndPartialTrustClosures(t *testing.T) { if entry.MerkleBatchID != batch.ID || entry.EntryHash == "" { t.Fatalf("public log entry = %#v", entry) } + leaf, err := decodeSHA256Digest(entry.EntryHash) + if err != nil { + t.Fatalf("decode entry hash: %v", err) + } + siblingHash := sampleDigest("public-log-sibling") + sibling, err := decodeSHA256Digest(siblingHash) + if err != nil { + t.Fatalf("decode sibling hash: %v", err) + } + rootHash := "sha256:" + hex.EncodeToString(transparencyParentHash(leaf, sibling)) + verifiedEntry, err := ledger.VerifyPublicTransparencyLogEntry(ctx, actor, entry.ID, VerifyPublicTransparencyLogEntryInput{ + RootHash: rootHash, + LeafIndex: 0, + TreeSize: 2, + InclusionProof: []string{siblingHash}, + }) + if err != nil { + t.Fatalf("verify public log entry: %v", err) + } + if verifiedEntry.State != "inclusion_verified" || verifiedEntry.InclusionProofHash == "" || len(verifiedEntry.VerificationChecks) != 2 { + t.Fatalf("verified public log entry = %#v", verifiedEntry) + } provider, err := ledger.CreateSigningProvider(ctx, actor, CreateSigningProviderInput{Name: "kms", Type: "aws_kms", KeyRef: "arn:aws:kms:example", Encrypted: true}) if err != nil { @@ -211,6 +234,9 @@ func TestFutureOperationalExtensionsAndPartialTrustClosures(t *testing.T) { if _, err := ledger.PublishPublicTransparencyLogEntry(ctx, other, PublishPublicTransparencyLogEntryInput{LogID: log.ID, CheckpointID: checkpoint.ID, ExternalID: "bad"}); !errors.Is(err, ErrNotFound) { t.Fatalf("cross tenant transparency err=%v, want not found", err) } + if _, err := ledger.VerifyPublicTransparencyLogEntry(ctx, other, entry.ID, VerifyPublicTransparencyLogEntryInput{RootHash: rootHash, LeafIndex: 0, TreeSize: 2, InclusionProof: []string{siblingHash}}); !errors.Is(err, ErrNotFound) { + t.Fatalf("cross tenant transparency verification err=%v, want not found", err) + } if _, err := ledger.CreateSigningOperation(ctx, other, CreateSigningOperationInput{ProviderID: provider.ID, SubjectType: "release", SubjectID: release.ID, PayloadHash: sampleDigest("payload"), ExternalSignature: "sig"}); !errors.Is(err, ErrNotFound) { t.Fatalf("cross tenant signing operation err=%v, want not found", err) } diff --git a/internal/domain/domain.go b/internal/domain/domain.go index 6ad0f90..17a97a9 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -911,16 +911,21 @@ type PublicTransparencyLog struct { } type PublicTransparencyLogEntry struct { - ID string `json:"id"` - TenantID string `json:"tenant_id"` - LogID string `json:"log_id"` - CheckpointID string `json:"checkpoint_id"` - MerkleBatchID string `json:"merkle_batch_id"` - ExternalID string `json:"external_id"` - EntryHash string `json:"entry_hash"` - State string `json:"state"` - SchemaVersion string `json:"schema_version"` - CreatedAt time.Time `json:"created_at"` + ID string `json:"id"` + TenantID string `json:"tenant_id"` + LogID string `json:"log_id"` + CheckpointID string `json:"checkpoint_id"` + MerkleBatchID string `json:"merkle_batch_id"` + ExternalID string `json:"external_id"` + EntryHash string `json:"entry_hash"` + InclusionRootHash string `json:"inclusion_root_hash,omitempty"` + InclusionProofHash string `json:"inclusion_proof_hash,omitempty"` + InclusionVerifiedAt *time.Time `json:"inclusion_verified_at,omitempty"` + VerificationChecks []VerifyCheck `json:"verification_checks,omitempty"` + VerificationLimitations []string `json:"verification_limitations,omitempty"` + State string `json:"state"` + SchemaVersion string `json:"schema_version"` + CreatedAt time.Time `json:"created_at"` } type MarketplaceCollector struct { diff --git a/openapi.yaml b/openapi.yaml index 35aeaa5..cdfd191 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/sdk/openapi-route-catalog.json b/sdk/openapi-route-catalog.json index a63df4f..8760604 100644 --- a/sdk/openapi-route-catalog.json +++ b/sdk/openapi-route-catalog.json @@ -1,5 +1,5 @@ { - "route_count": 160, + "route_count": 161, "routes": [ { "idempotency_key_required": false, @@ -1485,6 +1485,23 @@ "201" ] }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "verifyPublicTransparencyLogEntry", + "path": "/v1/public-transparency-log-entries/{id}/verify", + "request_schema": "#/components/schemas/VerifyPublicTransparencyLogEntryRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/PublicTransparencyLogEntryEnvelope" + ], + "scopes": [ + "keys:admin" + ], + "success_statuses": [ + "200" + ] + }, { "idempotency_key_required": true, "method": "POST", From ebf83dd3de42ed77b8c704293fba68a95bb629cc Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 20:00:28 +0300 Subject: [PATCH 084/287] feat: rotate sso provider trust material --- .implementation_increments.md | 2 +- docs/api.md | 3 +- docs/architecture.md | 2 +- docs/reference/api-contract-matrix.md | 3 +- docs/reference/production-readiness.md | 4 +- .../adapters/httpapi/identity_handlers.go | 14 ++++ internal/adapters/httpapi/openapi.go | 5 ++ .../adapters/httpapi/openapi_operations.go | 5 ++ .../adapters/httpapi/route_registration.go | 1 + internal/adapters/httpapi/router.go | 1 + internal/adapters/httpapi/router_test.go | 11 ++- internal/app/enterprise.go | 70 +++++++++++++++++++ internal/app/enterprise_test.go | 9 ++- internal/domain/domain.go | 1 + openapi.yaml | 2 +- sdk/openapi-route-catalog.json | 19 ++++- 16 files changed, 142 insertions(+), 10 deletions(-) diff --git a/.implementation_increments.md b/.implementation_increments.md index c2d08e6..716e3a2 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -253,7 +253,7 @@ Status legend: - `[x]` Object-retention verification receipts now record a reproducible verification hash, while WORM/object-lock enforcement remains a deployment and object-store control. - `[x]` External signing-provider operation receipts now record payload hashes, checks, and signature references, while production KMS/HSM adapter execution remains deployment hardening work. -- `[x]` Stored OIDC/SAML identity-link verification records provider-verification receipts, and OIDC ID tokens plus SAML assertions can be verified locally against configured tenant trust material. Live provider discovery/API calls, browser login callbacks, and group synchronization remain external/provider work. +- `[x]` Stored OIDC/SAML identity-link verification records provider-verification receipts, and OIDC ID tokens plus SAML assertions can be verified locally against configured tenant trust material. Public JWKS and SAML signing certificates can be rotated without recreating the provider. Live provider discovery/API calls, browser login callbacks, and group synchronization remain external/provider work. - `[x]` Public transparency log records now link local Merkle checkpoints to external entry metadata and can verify operator-supplied inclusion proof material locally. Live provider fetching remains deployment hardening work. - `[x]` Marketplace collector records now capture package metadata and evidence references, and expose package health reports for signature, SBOM, and vulnerability scan evidence gaps. Marketplace distribution remains external operational hardening. - `[x]` Docker/Helm runtime packaging now includes the worker binary and migrations and uses commands that match the image PATH. diff --git a/docs/api.md b/docs/api.md index b1f2721..43b2bc0 100644 --- a/docs/api.md +++ b/docs/api.md @@ -241,13 +241,14 @@ Important scope boundaries: | `POST` | `/v1/role-bindings` | Assign role to user or collector. | | `GET` | `/v1/role-bindings` | List tenant-scoped bindings. | | `POST` | `/v1/sso/providers` | Record OIDC or SAML provider metadata. | +| `POST` | `/v1/sso/providers/{id}/trust-material` | Rotate OIDC JWKS or SAML signing certificates used for local verification. | | `POST` | `/v1/sso/identity-links` | Link verified provider subject to user. | | `POST` | `/v1/sso/sessions` | Issue one-time session secret. | | `POST` | `/v1/sso/sessions/{id}/revoke` | Revoke session. | | `POST` | `/v1/api-keys` | Create one-time API key secret. | | `GET` | `/v1/api-keys` | List keys without secret hashes. | -Current SSO endpoints model admin-managed provider, identity-link, and session records. OIDC provider records can include static JWKS public-key material, and SAML provider records can include PEM-encoded assertion signing certificates. `POST /v1/provider-verifications` can verify a supplied OIDC ID token or SAML assertion locally for issuer, audience, subject, time bounds, and signature. Live OIDC discovery, live provider API calls, full browser login callbacks, and group synchronization are not implemented in this slice. +Current SSO endpoints model admin-managed provider, identity-link, trust-material, and session records. OIDC provider records can include public JWKS material, and SAML provider records can include PEM-encoded assertion signing certificates; both can be rotated through `POST /v1/sso/providers/{id}/trust-material`. `POST /v1/provider-verifications` can verify a supplied OIDC ID token or SAML assertion locally for issuer, audience, subject, time bounds, and signature. Live OIDC discovery, live provider API calls, full browser login callbacks, and group synchronization are not implemented in this slice. ### Products, Releases, Evidence, And Risk diff --git a/docs/architecture.md b/docs/architecture.md index d66eca1..79efe6c 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -46,7 +46,7 @@ Evidence summaries, questionnaire drafts, graph snapshots, PDF packages, and ano ## Provider And Deployment Boundaries -GitHub OIDC subject metadata can be captured, and stored OIDC/SAML identity links can be verified against tenant metadata. OIDC provider records can include static JWKS public-key material for local EdDSA or RS256 ID-token signature and claim verification, and SAML provider records can include PEM signing certificates for local assertion signature and claim verification. Live provider API verification, discovery, browser login callbacks, and group synchronization remain trust boundaries outside those records. Collector supply-chain records track pinned collector versions with signature, SBOM, and scan evidence where available; commercial and marketplace collector definitions add extension metadata without granting provider trust. +GitHub OIDC subject metadata can be captured, and stored OIDC/SAML identity links can be verified against tenant metadata. OIDC provider records can include public JWKS material for local EdDSA or RS256 ID-token signature and claim verification, and SAML provider records can include PEM signing certificates for local assertion signature and claim verification. Trust material can be rotated without recreating the provider. Live provider API verification, discovery, browser login callbacks, and group synchronization remain trust boundaries outside those records. Collector supply-chain records track pinned collector versions with signature, SBOM, and scan evidence where available; commercial and marketplace collector definitions add extension metadata without granting provider trust. Air-gapped import-bundle workflows preserve the same tenant-scoped import path after controlled transfer. Object-retention policy APIs record tenant-scoped retention intent and, when the S3/MinIO object-store adapter is configured, verify bucket versioning plus default object-lock mode and duration. Those checks are bucket-level evidence; WORM/object-lock enforcement, IAM policy, lifecycle rules, and deployment-specific retention review remain operator responsibilities. diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index 1347389..7595a47 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 161 operations: 161 precise, 0 broad. +Generated from 162 operations: 162 precise, 0 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -152,6 +152,7 @@ Generated from 161 operations: 161 precise, 0 broad. | POST | /v1/source/repositories | createSourceRepository | Bearer | source:write | required | - | application/json:CreateSourceRepositoryRequest | 201:application/json:SourceRepositoryEnvelope | precise | | POST | /v1/sso/identity-links | linkSSOIdentity | Bearer | identity:admin | required | - | application/json:LinkSSOIdentityRequest | 201:application/json:UserIdentityLinkEnvelope | precise | | POST | /v1/sso/providers | createSSOProvider | Bearer | identity:admin | required | - | application/json:CreateSSOProviderRequest | 201:application/json:SSOProviderEnvelope | precise | +| POST | /v1/sso/providers/{id}/trust-material | updateSSOProviderTrustMaterial | Bearer | identity:admin | required | path:id | application/json:UpdateSSOProviderTrustMaterialRequest | 200:application/json:SSOProviderEnvelope | precise | | POST | /v1/sso/sessions | createSSOSession | Bearer | identity:admin | required | - | application/json:CreateSSOSessionRequest | 201:application/json:SSOSessionCreateEnvelope | precise | | POST | /v1/sso/sessions/{id}/revoke | revokeSSOSession | Bearer | identity:admin | required | path:id | application/json:EmptyObject | 200:application/json:SSOSessionEnvelope | precise | | POST | /v1/transparency-checkpoints | createTransparencyCheckpoint | Bearer | keys:admin | required | - | application/json:CreateTransparencyCheckpointRequest | 201:application/json:TransparencyCheckpointEnvelope | precise | diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 45367df..08a9d44 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -107,7 +107,9 @@ implemented capabilities: signing gateway executor covers deployments that put KMS/HSM custody behind a tenant-controlled signing service and do not send raw payload bytes. - Complete live OIDC/SAML browser login callbacks, provider discovery, JWKS - refresh, logout, and optional group mapping where those profiles are enabled. + fetching, logout, and optional group mapping where those profiles are + enabled. Manual JWKS and SAML signing-certificate rotation is implemented + through the SSO provider trust-material endpoint. - Extend object-lock/WORM verification beyond current S3/MinIO bucket-level checks where deployments require object-level legal hold proofs or provider policy evidence, and add live provider fetching for public transparency proofs diff --git a/internal/adapters/httpapi/identity_handlers.go b/internal/adapters/httpapi/identity_handlers.go index a3c510c..94a8677 100644 --- a/internal/adapters/httpapi/identity_handlers.go +++ b/internal/adapters/httpapi/identity_handlers.go @@ -107,6 +107,20 @@ func (s *Server) createSSOProvider(w http.ResponseWriter, r *http.Request) { }) } +func (s *Server) updateSSOProviderTrustMaterial(w http.ResponseWriter, r *http.Request) { + var req struct { + JWKS map[string]any `json:"jwks"` + SAMLSigningCertificates []string `json:"saml_signing_certificates"` + } + s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + if err := decodeJSON(body, &req); err != nil { + return 0, nil, err + } + provider, err := s.ledger.UpdateSSOProviderTrustMaterial(r.Context(), actor, r.PathValue("id"), app.UpdateSSOProviderTrustMaterialInput{JWKS: req.JWKS, SAMLSigningCertificates: req.SAMLSigningCertificates}) + return http.StatusOK, provider, err + }) +} + func (s *Server) linkSSOIdentity(w http.ResponseWriter, r *http.Request) { var req struct { UserID string `json:"user_id"` diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 010a9af..98e7c05 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -85,6 +85,10 @@ func registerCriticalSchemas(registry *specs.Registry) { "jwks": map[string]any{"type": "object", "description": "Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied."}, "saml_signing_certificates": map[string]any{"type": "array", "items": map[string]any{"type": "string"}, "description": "Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied."}, }, "name", "type", "issuer", "client_id")) + registry.RegisterSchema("UpdateSSOProviderTrustMaterialRequest", objectSchema(map[string]any{ + "jwks": map[string]any{"type": "object", "description": "OIDC public JWKS material. Private keys and provider secrets must not be supplied."}, + "saml_signing_certificates": map[string]any{"type": "array", "items": map[string]any{"type": "string"}, "description": "PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied."}, + })) registry.RegisterSchema("VerifyProviderIdentityRequest", objectSchema(map[string]any{ "provider_type": map[string]any{"type": "string", "enum": []string{"oidc", "saml"}}, "provider_id": map[string]any{"type": "string"}, @@ -1213,6 +1217,7 @@ func registerCriticalSchemas(registry *specs.Registry) { "role_mapping": map[string]any{"type": "object", "additionalProperties": map[string]any{"type": "string"}}, "jwks": map[string]any{"type": "object", "description": "Configured public JWKS material, when supplied."}, "saml_signing_certificates": map[string]any{"type": "array", "items": map[string]any{"type": "string"}, "description": "Configured SAML assertion signing certificates, when supplied."}, + "trust_material_updated_at": map[string]any{"type": "string", "format": "date-time"}, "status": map[string]any{"type": "string"}, "schema_version": map[string]any{"type": "string"}, "created_at": map[string]any{"type": "string", "format": "date-time"}, diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 7baba64..13e0a35 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -75,6 +75,11 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Description = "Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls." operation.RequestBody = jsonRequest("SSO provider creation request.", "#/components/schemas/CreateSSOProviderRequest") operation.Responses[http.StatusCreated] = jsonResponse("Created SSO provider envelope.", "#/components/schemas/SSOProviderEnvelope") + case "updateSSOProviderTrustMaterial": + operation.Description = "Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets." + operation.Parameters = append(operation.Parameters, pathParam("id", "SSO provider id.")) + operation.RequestBody = jsonRequest("SSO provider trust material update request.", "#/components/schemas/UpdateSSOProviderTrustMaterialRequest") + operation.Responses[http.StatusOK] = jsonResponse("Updated SSO provider envelope.", "#/components/schemas/SSOProviderEnvelope") case "verifyProviderIdentity": operation.Description = "Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material." operation.RequestBody = jsonRequest("Provider identity verification request.", "#/components/schemas/VerifyProviderIdentityRequest") diff --git a/internal/adapters/httpapi/route_registration.go b/internal/adapters/httpapi/route_registration.go index 300ddda..2fb89aa 100644 --- a/internal/adapters/httpapi/route_registration.go +++ b/internal/adapters/httpapi/route_registration.go @@ -65,6 +65,7 @@ func (s *Server) identityRoutes() []routeDef { {http.MethodPost, "/v1/role-bindings", op("createRoleBinding", http.MethodPost, "/v1/role-bindings", "Create role binding", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.createRoleBinding)}, {http.MethodGet, "/v1/role-bindings", op("listRoleBindings", http.MethodGet, "/v1/role-bindings", "List role bindings", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.listRoleBindings)}, {http.MethodPost, "/v1/sso/providers", op("createSSOProvider", http.MethodPost, "/v1/sso/providers", "Create SSO provider", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.createSSOProvider)}, + {http.MethodPost, "/v1/sso/providers/{id}/trust-material", op("updateSSOProviderTrustMaterial", http.MethodPost, "/v1/sso/providers/{id}/trust-material", "Update SSO provider trust material", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.updateSSOProviderTrustMaterial)}, {http.MethodPost, "/v1/sso/identity-links", op("linkSSOIdentity", http.MethodPost, "/v1/sso/identity-links", "Link SSO identity", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.linkSSOIdentity)}, {http.MethodPost, "/v1/sso/sessions", op("createSSOSession", http.MethodPost, "/v1/sso/sessions", "Create SSO session", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.createSSOSession)}, {http.MethodPost, "/v1/sso/sessions/{id}/revoke", op("revokeSSOSession", http.MethodPost, "/v1/sso/sessions/{id}/revoke", "Revoke SSO session", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.revokeSSOSession)}, diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index f6b54b8..b7d4a15 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -2301,6 +2301,7 @@ func defaultSuccessStatus(operationID, method string) int { switch operationID { case "deactivateUser", "revokeSSOSession", + "updateSSOProviderTrustMaterial", "freezeRelease", "approveRelease", "promoteReleaseCandidate", diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 93d2b7e..5037a4e 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -84,7 +84,7 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { if _, ok := problemProps["request_id"]; !ok { t.Fatalf("Problem schema missing request_id: %#v", problemProps) } - for _, schemaName := range []string{"ReadinessStatusEnvelope", "BackupManifestEnvelope", "VerificationResultEnvelope", "ReadinessReportEnvelope", "CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "DataEnvelope"} { + for _, schemaName := range []string{"ReadinessStatusEnvelope", "BackupManifestEnvelope", "VerificationResultEnvelope", "ReadinessReportEnvelope", "CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "UpdateSSOProviderTrustMaterialRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "DataEnvelope"} { if _, ok := schemas[schemaName]; !ok { t.Fatalf("schema %s missing from OpenAPI components", schemaName) } @@ -167,6 +167,9 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { createProvider := operationMap(t, paths, "/v1/sso/providers", "post") assertRequestRef(t, createProvider, "#/components/schemas/CreateSSOProviderRequest") assertResponseRef(t, createProvider, "201", "#/components/schemas/SSOProviderEnvelope") + updateProviderTrust := operationMap(t, paths, "/v1/sso/providers/{id}/trust-material", "post") + assertRequestRef(t, updateProviderTrust, "#/components/schemas/UpdateSSOProviderTrustMaterialRequest") + assertResponseRef(t, updateProviderTrust, "200", "#/components/schemas/SSOProviderEnvelope") verifyProvider := operationMap(t, paths, "/v1/provider-verifications", "post") assertRequestRef(t, verifyProvider, "#/components/schemas/VerifyProviderIdentityRequest") assertResponseRef(t, verifyProvider, "201", "#/components/schemas/ProviderVerificationEnvelope") @@ -1105,8 +1108,12 @@ func TestFutureExtensionAndReadAdminHTTPGaps(t *testing.T) { t.Fatalf("oidc keygen: %v", err) } jwks := map[string]any{"keys": []any{map[string]any{"kty": "OKP", "crv": "Ed25519", "kid": "kid-1", "alg": "EdDSA", "x": base64.RawURLEncoding.EncodeToString(pub)}}} - signedProvider := postJSON(t, server, secret, "/v1/sso/providers", "future-sso-jwks", map[string]any{"name": "Signed OIDC", "type": "oidc", "issuer": "https://signed-idp.example.test", "client_id": "signed-client", "jwks": jwks}, http.StatusCreated) + signedProvider := postJSON(t, server, secret, "/v1/sso/providers", "future-sso-jwks", map[string]any{"name": "Signed OIDC", "type": "oidc", "issuer": "https://signed-idp.example.test", "client_id": "signed-client"}, http.StatusCreated) signedProviderID := dataField(t, signedProvider, "id") + updatedProvider := postJSON(t, server, secret, "/v1/sso/providers/"+signedProviderID+"/trust-material", "future-sso-jwks-update", map[string]any{"jwks": jwks}, http.StatusOK) + if !strings.Contains(updatedProvider, `"trust_material_updated_at"`) { + t.Fatalf("updated provider missing trust material timestamp: %s", updatedProvider) + } postJSON(t, server, secret, "/v1/sso/identity-links", "future-signed-link", map[string]any{"user_id": dataField(t, userBody, "id"), "provider_id": signedProviderID, "subject": "signed-sub", "email": "future@example.test", "verified": true}, http.StatusCreated) idToken := signedRouterIDToken(t, priv, "kid-1", map[string]any{"iss": "https://signed-idp.example.test", "aud": "signed-client", "sub": "signed-sub", "email": "future@example.test", "email_verified": true, "exp": time.Now().UTC().Add(time.Hour).Unix()}) signedVerification := postJSON(t, server, secret, "/v1/provider-verifications", "future-provider-token-verification", map[string]any{"provider_type": "oidc", "provider_id": signedProviderID, "subject": "signed-sub", "id_token": idToken}, http.StatusCreated) diff --git a/internal/app/enterprise.go b/internal/app/enterprise.go index 7e1dc07..b872381 100644 --- a/internal/app/enterprise.go +++ b/internal/app/enterprise.go @@ -42,6 +42,11 @@ type CreateSSOProviderInput struct { SAMLSigningCertificates []string } +type UpdateSSOProviderTrustMaterialInput struct { + JWKS map[string]any + SAMLSigningCertificates []string +} + type LinkSSOIdentityInput struct { UserID string ProviderID string @@ -263,6 +268,71 @@ func (l *Ledger) CreateSSOProvider(ctx context.Context, actor domain.Actor, in C return provider, nil } +func (l *Ledger) UpdateSSOProviderTrustMaterial(ctx context.Context, actor domain.Actor, id string, in UpdateSSOProviderTrustMaterialInput) (domain.SSOProvider, error) { + if err := ctx.Err(); err != nil { + return domain.SSOProvider{}, err + } + if err := require(actor, ScopeIdentityAdmin); err != nil { + return domain.SSOProvider{}, err + } + id = strings.TrimSpace(id) + if id == "" { + return domain.SSOProvider{}, ErrValidation + } + jwks, err := normalizeJWKS(in.JWKS) + if err != nil { + return domain.SSOProvider{}, ErrValidation + } + samlCerts, err := normalizeSAMLSigningCertificates(in.SAMLSigningCertificates) + if err != nil { + return domain.SSOProvider{}, ErrValidation + } + l.mu.Lock() + defer l.mu.Unlock() + provider, ok := l.ssoProviders[id] + if !ok || provider.TenantID != actor.TenantID { + return domain.SSOProvider{}, ErrNotFound + } + switch provider.Type { + case "oidc": + if len(jwks) == 0 || len(samlCerts) != 0 { + return domain.SSOProvider{}, ErrValidation + } + provider.JWKS = jwks + provider.SAMLSigningCertificates = nil + case "saml": + if len(samlCerts) == 0 || len(jwks) != 0 { + return domain.SSOProvider{}, ErrValidation + } + provider.SAMLSigningCertificates = samlCerts + provider.JWKS = nil + default: + return domain.SSOProvider{}, ErrValidation + } + now := l.now() + provider.TrustMaterialUpdatedAt = &now + materialHash, err := canonicalAnyHash(struct { + ProviderID string `json:"provider_id"` + JWKS map[string]any `json:"jwks,omitempty"` + SAMLSigningCertificates []string `json:"saml_signing_certificates,omitempty"` + UpdatedAt string `json:"updated_at"` + }{ + ProviderID: provider.ID, + JWKS: provider.JWKS, + SAMLSigningCertificates: provider.SAMLSigningCertificates, + UpdatedAt: now.Format(time.RFC3339Nano), + }) + if err != nil { + return domain.SSOProvider{}, err + } + l.ssoProviders[provider.ID] = provider + _, _ = l.appendChainLocked(actor.TenantID, "sso_provider.trust_material_updated", "sso_provider", provider.ID, actorType(actor), actorID(actor), materialHash, "") + if err := l.persistLocked(ctx); err != nil { + return domain.SSOProvider{}, err + } + return provider, nil +} + func (l *Ledger) LinkSSOIdentity(ctx context.Context, actor domain.Actor, in LinkSSOIdentityInput) (domain.UserIdentityLink, error) { if err := ctx.Err(); err != nil { return domain.UserIdentityLink{}, err diff --git a/internal/app/enterprise_test.go b/internal/app/enterprise_test.go index c8df150..925f26c 100644 --- a/internal/app/enterprise_test.go +++ b/internal/app/enterprise_test.go @@ -164,10 +164,17 @@ func TestOIDCProviderIdentityVerificationSupportsRS256JWKS(t *testing.T) { "n": base64.RawURLEncoding.EncodeToString(privateKey.N.Bytes()), "e": base64.RawURLEncoding.EncodeToString(bigEndianExponent(privateKey.E)), }}} - provider, err := ledger.CreateSSOProvider(ctx, actor, CreateSSOProviderInput{Name: "OIDC RSA", Type: "oidc", Issuer: "https://rsa-idp.example.test", ClientID: "rsa-client", JWKS: jwks}) + provider, err := ledger.CreateSSOProvider(ctx, actor, CreateSSOProviderInput{Name: "OIDC RSA", Type: "oidc", Issuer: "https://rsa-idp.example.test", ClientID: "rsa-client"}) if err != nil { t.Fatalf("sso provider: %v", err) } + provider, err = ledger.UpdateSSOProviderTrustMaterial(ctx, actor, provider.ID, UpdateSSOProviderTrustMaterialInput{JWKS: jwks}) + if err != nil { + t.Fatalf("update sso trust material: %v", err) + } + if provider.TrustMaterialUpdatedAt == nil || len(provider.JWKS) == 0 { + t.Fatalf("provider trust material = %#v", provider) + } org, err := ledger.CreateOrganization(ctx, actor, CreateOrganizationInput{Name: "RSA Example", Slug: "rsa-example"}) if err != nil { t.Fatalf("org: %v", err) diff --git a/internal/domain/domain.go b/internal/domain/domain.go index 17a97a9..bcca054 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -157,6 +157,7 @@ type SSOProvider struct { RoleMapping map[string]string `json:"role_mapping,omitempty"` JWKS map[string]any `json:"jwks,omitempty"` SAMLSigningCertificates []string `json:"saml_signing_certificates,omitempty"` + TrustMaterialUpdatedAt *time.Time `json:"trust_material_updated_at,omitempty"` Status string `json:"status"` SchemaVersion string `json:"schema_version"` CreatedAt time.Time `json:"created_at"` diff --git a/openapi.yaml b/openapi.yaml index cdfd191..5c5d43f 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/sdk/openapi-route-catalog.json b/sdk/openapi-route-catalog.json index 8760604..6b86a4d 100644 --- a/sdk/openapi-route-catalog.json +++ b/sdk/openapi-route-catalog.json @@ -1,5 +1,5 @@ { - "route_count": 161, + "route_count": 162, "routes": [ { "idempotency_key_required": false, @@ -2452,6 +2452,23 @@ "201" ] }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "updateSSOProviderTrustMaterial", + "path": "/v1/sso/providers/{id}/trust-material", + "request_schema": "#/components/schemas/UpdateSSOProviderTrustMaterialRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SSOProviderEnvelope" + ], + "scopes": [ + "identity:admin" + ], + "success_statuses": [ + "200" + ] + }, { "idempotency_key_required": true, "method": "POST", From 106b69c51dc463ff698d68b5bad45f71082b0409 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 20:00:43 +0300 Subject: [PATCH 085/287] fix: persist idempotency with relational identity rows --- .implementation_increments.md | 2 +- docs/architecture.md | 2 +- docs/reference/production-readiness.md | 11 +- internal/adapters/postgres/store.go | 227 ++++++++++++++++++ internal/adapters/postgres/store_test.go | 58 +++++ internal/app/ledger.go | 57 ++++- internal/app/ledger_test.go | 73 ++++++ internal/app/ports.go | 8 + ...1300_sso_trust_material_timestamp.down.sql | 2 + ...001300_sso_trust_material_timestamp.up.sql | 2 + 10 files changed, 435 insertions(+), 7 deletions(-) create mode 100644 migrations/20260528001300_sso_trust_material_timestamp.down.sql create mode 100644 migrations/20260528001300_sso_trust_material_timestamp.up.sql diff --git a/.implementation_increments.md b/.implementation_increments.md index 716e3a2..7c7db1b 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -36,7 +36,7 @@ Status legend: ## Remaining Core Product Increments 6. `[x]` Relational Store Split - Added migration-backed relational tables and tenant-scoped resource projection rows for implemented resources, with transactional PostgreSQL saves, tenant/release indexes, persisted idempotency state, and outbox row locking. Canonical runtime loading still uses the versioned ledger snapshot while per-resource repository tuning remains future hardening. + Added migration-backed relational tables and tenant-scoped resource projection rows for implemented resources, with transactional PostgreSQL saves, relational identity/idempotency rows, tenant/release indexes, persisted idempotency state, and outbox row locking. Canonical runtime loading still uses the versioned ledger snapshot while per-resource repository tuning remains future hardening. 7. `[x]` Evidence Search, Filtering, And Timeline Querying Added tenant-scoped evidence search by product, project, release, build, deployment, type, subtype, source, collector, created time, subject refs, tags, and verification status. diff --git a/docs/architecture.md b/docs/architecture.md index 79efe6c..6cdf8d1 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -10,7 +10,7 @@ Evydence follows a ports-and-adapters shape: - `internal/adapters/objectstore/s3` stores the same tenant-prefixed object keys in S3/MinIO-compatible buckets. - `cmd/*` contains process entry points. -Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Moving canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. +Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity and idempotency records are also synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. ## Tenant And Auth Boundaries diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 08a9d44..a041ad4 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -15,7 +15,9 @@ with live PostgreSQL and release evidence enabled. Known hardening work remains: - canonical production persistence still needs hand-tuned relational repository - paths for all high-risk resource families; + paths for all high-risk resource families. PostgreSQL now maintains + relational identity and idempotency rows alongside the canonical snapshot, + but the snapshot remains the runtime load source; - worker parser jobs re-read raw object-store payloads for key formats and validate durable state, but parser side effects still need to move independently out of the request path; @@ -92,9 +94,10 @@ These items are tracked separately from the feature-completeness checklist in implemented capabilities: - Replace canonical snapshot writes with dependency-ordered relational - repositories for identity, idempotency, evidence, audit-chain entries, - bundles, reports, packages, and secondary resources. Keep snapshots only for - export/import and upgrade compatibility. + repositories for evidence, audit-chain entries, bundles, reports, packages, + and secondary resources. Identity and idempotency rows are synchronized into + relational tables, but runtime loading still uses the canonical snapshot. + Keep snapshots only for export/import and upgrade compatibility. - Split the large application ledger aggregate into focused services or repositories once relational writes are in place, preserving tenant isolation and append-only behavior throughout. diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index dbebb28..7355cf9 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -82,12 +82,225 @@ func (s *Store) SaveState(ctx context.Context, state app.PersistedState) error { if err := syncResourceIndex(ctx, tx, state); err != nil { return err } + if err := syncIdentityAndIdempotency(ctx, tx, state); err != nil { + return err + } if err := tx.Commit(ctx); err != nil { return fmt.Errorf("commit save ledger state transaction: %w", err) } return nil } +func syncIdentityAndIdempotency(ctx context.Context, tx pgx.Tx, state app.PersistedState) error { + for _, tenant := range state.Tenants { + if tenant.ID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO tenants (id, name, created_at) + VALUES ($1, $2, $3) + ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name + `, tenant.ID, tenant.Name, nonZeroTime(tenant.CreatedAt)); err != nil { + return fmt.Errorf("upsert tenant row: %w", err) + } + } + for id, key := range state.APIKeys { + if key.ID == "" || key.TenantID == "" { + continue + } + hash := state.APIKeyHashes[id] + if hash == "" { + hash = key.Hash + } + scopes, err := json.Marshal(key.Scopes) + if err != nil { + return fmt.Errorf("encode api key scopes: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO api_keys ( + id, tenant_id, name, prefix, hash, scopes, expires_at, + revoked_at, last_used_at, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) + ON CONFLICT (id) DO UPDATE SET + name = EXCLUDED.name, + prefix = EXCLUDED.prefix, + hash = EXCLUDED.hash, + scopes = EXCLUDED.scopes, + expires_at = EXCLUDED.expires_at, + revoked_at = EXCLUDED.revoked_at, + last_used_at = EXCLUDED.last_used_at + `, key.ID, key.TenantID, key.Name, key.Prefix, hash, scopes, nullableTime(key.ExpiresAt), nullableTime(key.RevokedAt), nullableTime(key.LastUsedAt), nonZeroTime(key.CreatedAt)); err != nil { + return fmt.Errorf("upsert api key row: %w", err) + } + } + for _, org := range state.Organizations { + if org.ID == "" || org.TenantID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO organizations (id, tenant_id, name, slug, status, schema_version, created_at) + VALUES ($1, $2, $3, $4, $5, $6, $7) + ON CONFLICT (id) DO UPDATE SET + name = EXCLUDED.name, + slug = EXCLUDED.slug, + status = EXCLUDED.status, + schema_version = EXCLUDED.schema_version + `, org.ID, org.TenantID, org.Name, org.Slug, org.Status, org.SchemaVersion, nonZeroTime(org.CreatedAt)); err != nil { + return fmt.Errorf("upsert organization row: %w", err) + } + } + for _, user := range state.Users { + if user.ID == "" || user.TenantID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO human_users ( + id, tenant_id, organization_id, email, display_name, status, + deactivated_at, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + ON CONFLICT (id) DO UPDATE SET + organization_id = EXCLUDED.organization_id, + email = EXCLUDED.email, + display_name = EXCLUDED.display_name, + status = EXCLUDED.status, + deactivated_at = EXCLUDED.deactivated_at, + schema_version = EXCLUDED.schema_version + `, user.ID, user.TenantID, nullableString(user.OrganizationID), user.Email, user.DisplayName, user.Status, nullableTime(user.DeactivatedAt), user.SchemaVersion, nonZeroTime(user.CreatedAt)); err != nil { + return fmt.Errorf("upsert human user row: %w", err) + } + } + for _, binding := range state.RoleBindings { + if binding.ID == "" || binding.TenantID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO role_bindings ( + id, tenant_id, subject_type, subject_id, role, resource_type, + resource_id, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + ON CONFLICT (id) DO UPDATE SET + subject_type = EXCLUDED.subject_type, + subject_id = EXCLUDED.subject_id, + role = EXCLUDED.role, + resource_type = EXCLUDED.resource_type, + resource_id = EXCLUDED.resource_id, + schema_version = EXCLUDED.schema_version + `, binding.ID, binding.TenantID, binding.SubjectType, binding.SubjectID, binding.Role, nullableString(binding.ResourceType), nullableString(binding.ResourceID), binding.SchemaVersion, nonZeroTime(binding.CreatedAt)); err != nil { + return fmt.Errorf("upsert role binding row: %w", err) + } + } + for _, provider := range state.SSOProviders { + if provider.ID == "" || provider.TenantID == "" { + continue + } + roleMapping, err := json.Marshal(provider.RoleMapping) + if err != nil { + return fmt.Errorf("encode sso role mapping: %w", err) + } + jwks, err := json.Marshal(provider.JWKS) + if err != nil { + return fmt.Errorf("encode sso jwks: %w", err) + } + samlCerts, err := json.Marshal(provider.SAMLSigningCertificates) + if err != nil { + return fmt.Errorf("encode sso signing certificates: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO sso_providers ( + id, tenant_id, name, type, issuer, client_id, groups_claim, + role_mapping, status, schema_version, created_at, jwks, + saml_signing_certificates, trust_material_updated_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) + ON CONFLICT (id) DO UPDATE SET + name = EXCLUDED.name, + type = EXCLUDED.type, + issuer = EXCLUDED.issuer, + client_id = EXCLUDED.client_id, + groups_claim = EXCLUDED.groups_claim, + role_mapping = EXCLUDED.role_mapping, + status = EXCLUDED.status, + schema_version = EXCLUDED.schema_version, + jwks = EXCLUDED.jwks, + saml_signing_certificates = EXCLUDED.saml_signing_certificates, + trust_material_updated_at = EXCLUDED.trust_material_updated_at + `, provider.ID, provider.TenantID, provider.Name, provider.Type, provider.Issuer, provider.ClientID, nullableString(provider.GroupsClaim), roleMapping, provider.Status, provider.SchemaVersion, nonZeroTime(provider.CreatedAt), jwks, samlCerts, nullableTime(provider.TrustMaterialUpdatedAt)); err != nil { + return fmt.Errorf("upsert sso provider row: %w", err) + } + } + for _, link := range state.IdentityLinks { + if link.ID == "" || link.TenantID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO user_identity_links ( + id, tenant_id, user_id, provider_id, subject, email, verified, + schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + ON CONFLICT (id) DO UPDATE SET + user_id = EXCLUDED.user_id, + provider_id = EXCLUDED.provider_id, + subject = EXCLUDED.subject, + email = EXCLUDED.email, + verified = EXCLUDED.verified, + schema_version = EXCLUDED.schema_version + `, link.ID, link.TenantID, link.UserID, link.ProviderID, link.Subject, link.Email, link.Verified, link.SchemaVersion, nonZeroTime(link.CreatedAt)); err != nil { + return fmt.Errorf("upsert user identity link row: %w", err) + } + } + for id, session := range state.SSOSessions { + if session.ID == "" || session.TenantID == "" { + continue + } + hash := state.SSOSessionHashes[id] + if hash == "" { + hash = session.Hash + } + if _, err := tx.Exec(ctx, ` + INSERT INTO sso_sessions ( + id, tenant_id, user_id, provider_id, prefix, hash, expires_at, + revoked_at, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) + ON CONFLICT (id) DO UPDATE SET + prefix = EXCLUDED.prefix, + hash = EXCLUDED.hash, + expires_at = EXCLUDED.expires_at, + revoked_at = EXCLUDED.revoked_at, + schema_version = EXCLUDED.schema_version + `, session.ID, session.TenantID, session.UserID, session.ProviderID, session.Prefix, hash, session.ExpiresAt, nullableTime(session.RevokedAt), session.SchemaVersion, nonZeroTime(session.CreatedAt)); err != nil { + return fmt.Errorf("upsert sso session row: %w", err) + } + } + if _, err := tx.Exec(ctx, `DELETE FROM idempotency_records`); err != nil { + return fmt.Errorf("clear idempotency records: %w", err) + } + for key, record := range state.Idempotency { + parts, ok := app.ParseIdempotencyRecordKey(key) + if !ok { + continue + } + response, err := json.Marshal(record.Response) + if err != nil { + return fmt.Errorf("encode idempotency response: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO idempotency_records ( + tenant_id, actor_key_id, method, path, idempotency_key, + request_hash, status, response, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + `, parts.TenantID, parts.ActorID, parts.Method, parts.Path, parts.IdempotencyKey, record.RequestHash, record.Status, response, nonZeroTime(record.CreatedAt)); err != nil { + return fmt.Errorf("insert idempotency record row: %w", err) + } + } + return nil +} + type resourceProjection struct { TenantID string ResourceType string @@ -369,6 +582,20 @@ func nullableString(value string) any { return value } +func nullableTime(value *time.Time) any { + if value == nil || value.IsZero() { + return nil + } + return value.UTC() +} + +func nonZeroTime(value time.Time) time.Time { + if value.IsZero() { + return time.Now().UTC() + } + return value.UTC() +} + func (s *Store) Enqueue(ctx context.Context, job app.OutboxJob) error { payload, err := json.Marshal(job.Payload) if err != nil { diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index a39c30e..5484d56 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -33,6 +33,32 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { Tenants: map[string]domain.Tenant{ "ten_test": {ID: "ten_test", Name: "Test", CreatedAt: time.Now().UTC()}, }, + Organizations: map[string]domain.Organization{ + "org_test": {ID: "org_test", TenantID: "ten_test", Name: "Org", Slug: "org", Status: "active", SchemaVersion: domain.OrganizationSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + Users: map[string]domain.HumanUser{ + "user_test": {ID: "user_test", TenantID: "ten_test", OrganizationID: "org_test", Email: "user@example.test", DisplayName: "User", Status: "active", SchemaVersion: domain.HumanUserSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + RoleBindings: map[string]domain.RoleBinding{ + "rb_test": {ID: "rb_test", TenantID: "ten_test", SubjectType: "user", SubjectID: "user_test", Role: "security_engineer", SchemaVersion: domain.RoleBindingSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + APIKeys: map[string]domain.APIKey{ + "key_test": {ID: "key_test", TenantID: "ten_test", Name: "api", Prefix: "evy_test", Scopes: []string{"evidence:write"}, CreatedAt: time.Now().UTC()}, + }, + APIKeyHashes: map[string]string{"key_test": "hmac-test-hash"}, + SSOProviders: map[string]domain.SSOProvider{ + "sso_test": {ID: "sso_test", TenantID: "ten_test", Name: "OIDC", Type: "oidc", Issuer: "https://idp.example.test", ClientID: "client", Status: "active", JWKS: map[string]any{"keys": []any{map[string]any{"kty": "OKP", "kid": "kid-1", "crv": "Ed25519", "x": "abc"}}}, SchemaVersion: domain.SSOProviderSchemaVersion, CreatedAt: time.Now().UTC(), TrustMaterialUpdatedAt: ptrTime(time.Now().UTC())}, + }, + IdentityLinks: map[string]domain.UserIdentityLink{ + "link_test": {ID: "link_test", TenantID: "ten_test", UserID: "user_test", ProviderID: "sso_test", Subject: "sub", Email: "user@example.test", Verified: true, SchemaVersion: "user-identity-link.v1.0.0", CreatedAt: time.Now().UTC()}, + }, + SSOSessions: map[string]domain.SSOSession{ + "sess_test": {ID: "sess_test", TenantID: "ten_test", UserID: "user_test", ProviderID: "sso_test", Prefix: "sess", ExpiresAt: time.Now().UTC().Add(time.Hour), SchemaVersion: domain.SSOSessionSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + SSOSessionHashes: map[string]string{"sess_test": "session-hash"}, + Idempotency: map[string]app.IdempotencyRecord{ + app.NewIdempotencyRecordKey("ten_test", "user:user_test", "POST", "/v1/products", "idem"): {RequestHash: "sha256:request", Status: 201, Response: map[string]any{"ok": true}, CreatedAt: time.Now().UTC()}, + }, } if err := store.SaveState(ctx, state); err != nil { t.Fatal(err) @@ -51,6 +77,34 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { if indexed != 1 { t.Fatalf("resource index rows = %d, want 1", indexed) } + var apiKeyHash string + if err := store.pool.QueryRow(ctx, `SELECT hash FROM api_keys WHERE id = 'key_test' AND tenant_id = 'ten_test'`).Scan(&apiKeyHash); err != nil { + t.Fatal(err) + } + if apiKeyHash != "hmac-test-hash" { + t.Fatalf("api key hash = %q", apiKeyHash) + } + var userRows int + if err := store.pool.QueryRow(ctx, `SELECT count(*) FROM human_users WHERE tenant_id = 'ten_test' AND email = 'user@example.test'`).Scan(&userRows); err != nil { + t.Fatal(err) + } + if userRows != 1 { + t.Fatalf("human user rows = %d, want 1", userRows) + } + var ssoTrustRows int + if err := store.pool.QueryRow(ctx, `SELECT count(*) FROM sso_providers WHERE id = 'sso_test' AND trust_material_updated_at IS NOT NULL AND jwks <> '{}'::jsonb`).Scan(&ssoTrustRows); err != nil { + t.Fatal(err) + } + if ssoTrustRows != 1 { + t.Fatalf("sso trust rows = %d, want 1", ssoTrustRows) + } + var idemActor string + if err := store.pool.QueryRow(ctx, `SELECT actor_key_id FROM idempotency_records WHERE tenant_id = 'ten_test' AND idempotency_key = 'idem'`).Scan(&idemActor); err != nil { + t.Fatal(err) + } + if idemActor != "user:user_test" { + t.Fatalf("idempotency actor = %q", idemActor) + } job := app.OutboxJob{ID: "job_test_" + time.Now().Format("150405.000000000"), TenantID: "ten_test", Kind: "verify_subject", SubjectType: "audit_chain", SubjectID: "audit_chain", CreatedAt: time.Now().UTC()} if err := store.Enqueue(ctx, job); err != nil { t.Fatal(err) @@ -90,6 +144,10 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { } } +func ptrTime(t time.Time) *time.Time { + return &t +} + func TestPendingMigrationVersionsWithPostgres(t *testing.T) { databaseURL := os.Getenv("EVYDENCE_TEST_DATABASE_URL") if databaseURL == "" { diff --git a/internal/app/ledger.go b/internal/app/ledger.go index 91bafc0..420c814 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -1659,7 +1659,7 @@ func (l *Ledger) WithIdempotency(ctx context.Context, actor domain.Actor, method return 0, nil, ErrValidation } requestHash := hashBytes(append([]byte(method+"\n"+path+"\n"), body...)) - storeKey := actor.TenantID + "\x00" + actor.KeyID + "\x00" + method + "\x00" + path + "\x00" + key + storeKey := NewIdempotencyRecordKey(actor.TenantID, idempotencyActorID(actor), method, path, key) l.mu.Lock() record, ok := l.idempotency[storeKey] l.mu.Unlock() @@ -1683,6 +1683,61 @@ func (l *Ledger) WithIdempotency(ctx context.Context, actor domain.Actor, method return status, response, nil } +func idempotencyActorID(actor domain.Actor) string { + switch { + case strings.TrimSpace(actor.KeyID) != "": + return "api_key:" + strings.TrimSpace(actor.KeyID) + case strings.TrimSpace(actor.UserID) != "": + return "user:" + strings.TrimSpace(actor.UserID) + case strings.TrimSpace(actor.CollectorID) != "": + return "collector:" + strings.TrimSpace(actor.CollectorID) + default: + return "anonymous" + } +} + +func NewIdempotencyRecordKey(tenantID, actorID, method, path, key string) string { + parts := []string{tenantID, actorID, method, path, key} + encoded := make([]string, 0, len(parts)) + for _, part := range parts { + encoded = append(encoded, base64.RawURLEncoding.EncodeToString([]byte(part))) + } + return "v2:" + strings.Join(encoded, ".") +} + +func ParseIdempotencyRecordKey(value string) (IdempotencyRecordKey, bool) { + value = strings.TrimSpace(value) + if strings.HasPrefix(value, "v2:") { + parts := strings.Split(strings.TrimPrefix(value, "v2:"), ".") + if len(parts) != 5 { + return IdempotencyRecordKey{}, false + } + decoded := make([]string, 0, len(parts)) + for _, part := range parts { + raw, err := base64.RawURLEncoding.DecodeString(part) + if err != nil { + return IdempotencyRecordKey{}, false + } + decoded = append(decoded, string(raw)) + } + return idempotencyRecordKeyFromParts(decoded) + } + return idempotencyRecordKeyFromParts(strings.Split(value, "\x00")) +} + +func idempotencyRecordKeyFromParts(parts []string) (IdempotencyRecordKey, bool) { + if len(parts) != 5 || parts[0] == "" || parts[1] == "" || parts[4] == "" { + return IdempotencyRecordKey{}, false + } + return IdempotencyRecordKey{ + TenantID: parts[0], + ActorID: parts[1], + Method: parts[2], + Path: parts[3], + IdempotencyKey: parts[4], + }, true +} + func (l *Ledger) createAPIKeyLocked(tenantID, name string, scopes []string, expiresAt *time.Time) (domain.APIKey, string, error) { secret := "evy_" + randomToken(32) key := domain.APIKey{ID: newID("key"), TenantID: tenantID, Name: name, Prefix: secretPrefix(secret), Scopes: sortedStrings(scopes), CreatedAt: l.now(), ExpiresAt: expiresAt, Hash: l.hashSecret(secret)} diff --git a/internal/app/ledger_test.go b/internal/app/ledger_test.go index 3f9dfa4..01f2b11 100644 --- a/internal/app/ledger_test.go +++ b/internal/app/ledger_test.go @@ -128,6 +128,79 @@ func TestIdempotencyReplayAndConflict(t *testing.T) { } } +func TestIdempotencyIsScopedByHumanSessionActor(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + _, _, secret, err := ledger.BootstrapTenant(ctx, "Tenant", "admin", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap: %v", err) + } + admin, err := ledger.Authenticate(ctx, secret) + if err != nil { + t.Fatalf("auth admin: %v", err) + } + org, err := ledger.CreateOrganization(ctx, admin, CreateOrganizationInput{Name: "Org", Slug: "org"}) + if err != nil { + t.Fatalf("org: %v", err) + } + provider, err := ledger.CreateSSOProvider(ctx, admin, CreateSSOProviderInput{Name: "OIDC", Type: "oidc", Issuer: "https://idp.example.test", ClientID: "client"}) + if err != nil { + t.Fatalf("provider: %v", err) + } + userA, err := ledger.CreateUser(ctx, admin, CreateUserInput{OrganizationID: org.ID, Email: "a@example.test", DisplayName: "A"}) + if err != nil { + t.Fatalf("user a: %v", err) + } + userB, err := ledger.CreateUser(ctx, admin, CreateUserInput{OrganizationID: org.ID, Email: "b@example.test", DisplayName: "B"}) + if err != nil { + t.Fatalf("user b: %v", err) + } + for _, user := range []domain.HumanUser{userA, userB} { + if _, err := ledger.CreateRoleBinding(ctx, admin, CreateRoleBindingInput{SubjectType: "user", SubjectID: user.ID, Role: "security_engineer"}); err != nil { + t.Fatalf("role binding: %v", err) + } + } + _, secretA, err := ledger.CreateSSOSession(ctx, admin, CreateSSOSessionInput{UserID: userA.ID, ProviderID: provider.ID, ExpiresAt: fixedNow().Add(time.Hour)}) + if err != nil { + t.Fatalf("session a: %v", err) + } + _, secretB, err := ledger.CreateSSOSession(ctx, admin, CreateSSOSessionInput{UserID: userB.ID, ProviderID: provider.ID, ExpiresAt: fixedNow().Add(time.Hour)}) + if err != nil { + t.Fatalf("session b: %v", err) + } + actorA, err := ledger.Authenticate(ctx, secretA) + if err != nil { + t.Fatalf("auth a: %v", err) + } + actorB, err := ledger.Authenticate(ctx, secretB) + if err != nil { + t.Fatalf("auth b: %v", err) + } + if _, _, err := ledger.WithIdempotency(ctx, actorA, "POST", "/v1/products", "shared", []byte(`{"name":"A"}`), func() (int, any, error) { + return 201, map[string]any{"actor": "a"}, nil + }); err != nil { + t.Fatalf("idempotency a: %v", err) + } + for key := range ledger.idempotency { + if strings.ContainsRune(key, '\x00') { + t.Fatalf("idempotency key contains postgres-unsafe NUL: %q", key) + } + if parsed, ok := ParseIdempotencyRecordKey(key); !ok || parsed.ActorID == "" { + t.Fatalf("idempotency key did not parse: %q parsed=%#v ok=%v", key, parsed, ok) + } + } + status, response, err := ledger.WithIdempotency(ctx, actorB, "POST", "/v1/products", "shared", []byte(`{"name":"B"}`), func() (int, any, error) { + return 201, map[string]any{"actor": "b"}, nil + }) + if err != nil { + t.Fatalf("idempotency b should not conflict with actor a: %v", err) + } + got, _ := response.(map[string]any) + if status != 201 || got["actor"] != "b" { + t.Fatalf("unexpected actor b response status=%d response=%#v", status, response) + } +} + func TestEvidenceCanonicalHashAndAuditChainVerification(t *testing.T) { ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) ctx := context.Background() diff --git a/internal/app/ports.go b/internal/app/ports.go index 1ff932b..d791bb6 100644 --- a/internal/app/ports.go +++ b/internal/app/ports.go @@ -163,6 +163,14 @@ type IdempotencyRecord struct { CreatedAt time.Time `json:"created_at"` } +type IdempotencyRecordKey struct { + TenantID string + ActorID string + Method string + Path string + IdempotencyKey string +} + type Object struct { Key string TenantID string diff --git a/migrations/20260528001300_sso_trust_material_timestamp.down.sql b/migrations/20260528001300_sso_trust_material_timestamp.down.sql new file mode 100644 index 0000000..7d744de --- /dev/null +++ b/migrations/20260528001300_sso_trust_material_timestamp.down.sql @@ -0,0 +1,2 @@ +ALTER TABLE sso_providers + DROP COLUMN IF EXISTS trust_material_updated_at; diff --git a/migrations/20260528001300_sso_trust_material_timestamp.up.sql b/migrations/20260528001300_sso_trust_material_timestamp.up.sql new file mode 100644 index 0000000..2d2bb8e --- /dev/null +++ b/migrations/20260528001300_sso_trust_material_timestamp.up.sql @@ -0,0 +1,2 @@ +ALTER TABLE sso_providers + ADD COLUMN IF NOT EXISTS trust_material_updated_at timestamptz; From 29cc8e036c2c987abad89c0f3d2d28a54872bcc5 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 20:01:16 +0300 Subject: [PATCH 086/287] feat: synchronize release ledger core rows --- .implementation_increments.md | 2 +- docs/architecture.md | 2 +- docs/reference/production-readiness.md | 14 +- internal/adapters/postgres/store.go | 344 ++++++++++++++++++ internal/adapters/postgres/store_test.go | 84 +++++ ...0_release_core_relational_columns.down.sql | 13 + ...400_release_core_relational_columns.up.sql | 17 + 7 files changed, 468 insertions(+), 8 deletions(-) create mode 100644 migrations/20260528001400_release_core_relational_columns.down.sql create mode 100644 migrations/20260528001400_release_core_relational_columns.up.sql diff --git a/.implementation_increments.md b/.implementation_increments.md index 7c7db1b..32c42e3 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -36,7 +36,7 @@ Status legend: ## Remaining Core Product Increments 6. `[x]` Relational Store Split - Added migration-backed relational tables and tenant-scoped resource projection rows for implemented resources, with transactional PostgreSQL saves, relational identity/idempotency rows, tenant/release indexes, persisted idempotency state, and outbox row locking. Canonical runtime loading still uses the versioned ledger snapshot while per-resource repository tuning remains future hardening. + Added migration-backed relational tables and tenant-scoped resource projection rows for implemented resources, with transactional PostgreSQL saves, relational identity/idempotency rows, relational release-ledger core rows, tenant/release indexes, persisted idempotency state, and outbox row locking. Canonical runtime loading still uses the versioned ledger snapshot while per-resource repository tuning remains future hardening. 7. `[x]` Evidence Search, Filtering, And Timeline Querying Added tenant-scoped evidence search by product, project, release, build, deployment, type, subtype, source, collector, created time, subject refs, tags, and verification status. diff --git a/docs/architecture.md b/docs/architecture.md index 6cdf8d1..ea4affc 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -10,7 +10,7 @@ Evydence follows a ports-and-adapters shape: - `internal/adapters/objectstore/s3` stores the same tenant-prefixed object keys in S3/MinIO-compatible buckets. - `cmd/*` contains process entry points. -Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity and idempotency records are also synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. +Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity and idempotency records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. ## Tenant And Auth Boundaries diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index a041ad4..a3c86e2 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -16,8 +16,9 @@ Known hardening work remains: - canonical production persistence still needs hand-tuned relational repository paths for all high-risk resource families. PostgreSQL now maintains - relational identity and idempotency rows alongside the canonical snapshot, - but the snapshot remains the runtime load source; + relational identity, idempotency, release-ledger core, audit-chain, signing, + bundle, policy, and verification rows alongside the canonical snapshot, but + the snapshot remains the runtime load source; - worker parser jobs re-read raw object-store payloads for key formats and validate durable state, but parser side effects still need to move independently out of the request path; @@ -94,10 +95,11 @@ These items are tracked separately from the feature-completeness checklist in implemented capabilities: - Replace canonical snapshot writes with dependency-ordered relational - repositories for evidence, audit-chain entries, bundles, reports, packages, - and secondary resources. Identity and idempotency rows are synchronized into - relational tables, but runtime loading still uses the canonical snapshot. - Keep snapshots only for export/import and upgrade compatibility. + repositories for remaining report, package, portal, retention, and secondary + resources. Identity, idempotency, release-ledger core, audit-chain, signing, + bundle, policy, and verification rows are synchronized into relational + tables, but runtime loading still uses the canonical snapshot. Keep snapshots + only for export/import and upgrade compatibility. - Split the large application ledger aggregate into focused services or repositories once relational writes are in place, preserving tenant isolation and append-only behavior throughout. diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index 7355cf9..2b2e64b 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -85,12 +85,335 @@ func (s *Store) SaveState(ctx context.Context, state app.PersistedState) error { if err := syncIdentityAndIdempotency(ctx, tx, state); err != nil { return err } + if err := syncReleaseLedgerCore(ctx, tx, state); err != nil { + return err + } if err := tx.Commit(ctx); err != nil { return fmt.Errorf("commit save ledger state transaction: %w", err) } return nil } +func syncReleaseLedgerCore(ctx context.Context, tx pgx.Tx, state app.PersistedState) error { + for _, product := range state.Products { + if product.ID == "" || product.TenantID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO products (id, tenant_id, name, slug, created_at) + VALUES ($1, $2, $3, $4, $5) + ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name, slug = EXCLUDED.slug + `, product.ID, product.TenantID, product.Name, product.Slug, nonZeroTime(product.CreatedAt)); err != nil { + return fmt.Errorf("upsert product row: %w", err) + } + } + for _, project := range state.Projects { + if project.ID == "" || project.TenantID == "" || project.ProductID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO projects (id, tenant_id, product_id, name, created_at) + VALUES ($1, $2, $3, $4, $5) + ON CONFLICT (id) DO UPDATE SET product_id = EXCLUDED.product_id, name = EXCLUDED.name + `, project.ID, project.TenantID, project.ProductID, project.Name, nonZeroTime(project.CreatedAt)); err != nil { + return fmt.Errorf("upsert project row: %w", err) + } + } + for _, release := range state.Releases { + if release.ID == "" || release.TenantID == "" || release.ProductID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO releases (id, tenant_id, product_id, version, state, frozen_at, approved_at, created_at) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8) + ON CONFLICT (id) DO UPDATE SET + state = EXCLUDED.state, + frozen_at = EXCLUDED.frozen_at, + approved_at = EXCLUDED.approved_at + `, release.ID, release.TenantID, release.ProductID, release.Version, release.State, nullableTime(release.FrozenAt), nullableTime(release.ApprovedAt), nonZeroTime(release.CreatedAt)); err != nil { + return fmt.Errorf("upsert release row: %w", err) + } + } + for _, artifact := range state.Artifacts { + if artifact.ID == "" || artifact.TenantID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO artifacts (id, tenant_id, name, media_type, size, digest, created_at) + VALUES ($1, $2, $3, $4, $5, $6, $7) + ON CONFLICT (id) DO UPDATE SET + name = EXCLUDED.name, + media_type = EXCLUDED.media_type, + size = EXCLUDED.size, + digest = EXCLUDED.digest + `, artifact.ID, artifact.TenantID, artifact.Name, artifact.MediaType, artifact.Size, artifact.Digest, nonZeroTime(artifact.CreatedAt)); err != nil { + return fmt.Errorf("upsert artifact row: %w", err) + } + } + for _, evidence := range state.Evidence { + if evidence.ID == "" || evidence.TenantID == "" { + continue + } + sourceIdentity, err := json.Marshal(evidence.SourceIdentity) + if err != nil { + return fmt.Errorf("encode evidence source identity: %w", err) + } + subjectRefs, err := json.Marshal(evidence.SubjectRefs) + if err != nil { + return fmt.Errorf("encode evidence subject refs: %w", err) + } + relatedRefs, err := json.Marshal(evidence.RelatedEvidenceRefs) + if err != nil { + return fmt.Errorf("encode evidence related refs: %w", err) + } + signatureRefs, err := json.Marshal(evidence.SignatureRefs) + if err != nil { + return fmt.Errorf("encode evidence signature refs: %w", err) + } + tags, err := json.Marshal(evidence.Tags) + if err != nil { + return fmt.Errorf("encode evidence tags: %w", err) + } + metadata, err := json.Marshal(evidence.Metadata) + if err != nil { + return fmt.Errorf("encode evidence metadata: %w", err) + } + warnings, err := json.Marshal(evidence.Warnings) + if err != nil { + return fmt.Errorf("encode evidence warnings: %w", err) + } + limitations, err := json.Marshal(evidence.Limitations) + if err != nil { + return fmt.Errorf("encode evidence limitations: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO evidence_items ( + id, tenant_id, product_id, project_id, release_id, build_id, deployment_id, + type, subtype, title, source_system, source_identity, collector_id, + uploaded_by, observed_at, evidence_version, schema_version, payload_ref, + payload_hash, payload_media_type, payload_size, canonical_hash, + canonicalization, subject_refs, related_evidence_refs, supersedes, + superseded_by, trust_level, verification_status, signature_refs, + chain_entry_id, tags, metadata, warnings, limitations, created_at + ) + VALUES ( + $1, $2, $3, $4, $5, $6, $7, + $8, $9, $10, $11, $12, $13, + $14, $15, $16, $17, $18, + $19, $20, $21, $22, + $23, $24, $25, $26, + $27, $28, $29, $30, + $31, $32, $33, $34, $35, $36 + ) + ON CONFLICT (id) DO UPDATE SET + superseded_by = EXCLUDED.superseded_by, + verification_status = EXCLUDED.verification_status, + signature_refs = EXCLUDED.signature_refs, + chain_entry_id = EXCLUDED.chain_entry_id, + tags = EXCLUDED.tags, + metadata = EXCLUDED.metadata, + warnings = EXCLUDED.warnings, + limitations = EXCLUDED.limitations + `, evidence.ID, evidence.TenantID, nullableString(evidence.ProductID), nullableString(evidence.ProjectID), nullableString(evidence.ReleaseID), nullableString(evidence.BuildID), nullableString(evidence.DeploymentID), + evidence.Type, nullableString(evidence.Subtype), evidence.Title, evidence.SourceSystem, sourceIdentity, nullableString(evidence.CollectorID), + nullableString(evidence.UploadedBy), nonZeroTime(evidence.ObservedAt), nonZeroInt(evidence.EvidenceVersion, 1), evidence.SchemaVersion, nullableString(evidence.PayloadRef), + evidence.PayloadHash, nullableString(evidence.PayloadMediaType), nullableInt64(evidence.PayloadSize), evidence.CanonicalHash, + evidence.Canonicalization, subjectRefs, relatedRefs, nullableString(evidence.Supersedes), + nullableString(evidence.SupersededBy), evidence.TrustLevel, evidence.VerificationStatus, signatureRefs, + nullableString(evidence.ChainEntryID), tags, metadata, warnings, limitations, nonZeroTime(evidence.CreatedAt)); err != nil { + return fmt.Errorf("upsert evidence item row: %w", err) + } + } + for _, tenantChain := range state.Chain { + for _, entry := range tenantChain { + if entry.ID == "" || entry.TenantID == "" { + continue + } + metadata, err := json.Marshal(entry.Metadata) + if err != nil { + return fmt.Errorf("encode audit chain metadata: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO audit_chain_entries ( + id, tenant_id, sequence, entry_type, subject_type, subject_id, + actor_type, actor_id, occurred_at, payload_hash, + canonical_entry_hash, previous_entry_hash, entry_hash, + signature_ref, metadata, schema_version + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16) + ON CONFLICT (id) DO NOTHING + `, entry.ID, entry.TenantID, entry.Sequence, entry.EntryType, entry.SubjectType, entry.SubjectID, + entry.ActorType, entry.ActorID, nonZeroTime(entry.OccurredAt), nullableString(entry.PayloadHash), + entry.CanonicalEntryHash, entry.PreviousEntryHash, entry.EntryHash, + nullableString(entry.SignatureRef), metadata, entry.SchemaVersion); err != nil { + return fmt.Errorf("insert audit chain row: %w", err) + } + } + } + for id, key := range state.SigningKeys { + if key.ID == "" || key.TenantID == "" { + continue + } + private := state.SigningKeyPrivate[id] + if len(private) == 0 { + private = key.Private + } + if _, err := tx.Exec(ctx, ` + INSERT INTO signing_keys ( + id, tenant_id, kid, algorithm, status, public_key, + encrypted_private_key, created_at, revoked_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + ON CONFLICT (id) DO UPDATE SET + status = EXCLUDED.status, + public_key = EXCLUDED.public_key, + encrypted_private_key = EXCLUDED.encrypted_private_key, + revoked_at = EXCLUDED.revoked_at + `, key.ID, key.TenantID, key.KID, key.Algorithm, key.Status, key.PublicKey, nullableBytes(private), nonZeroTime(key.CreatedAt), nullableTime(key.RevokedAt)); err != nil { + return fmt.Errorf("upsert signing key row: %w", err) + } + } + for _, signature := range state.Signatures { + if signature.ID == "" || signature.TenantID == "" || signature.KeyID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO signatures ( + id, tenant_id, subject_type, subject_id, key_id, algorithm, value, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8) + ON CONFLICT (id) DO NOTHING + `, signature.ID, signature.TenantID, signature.SubjectType, signature.SubjectID, signature.KeyID, signature.Algorithm, signature.Value, nonZeroTime(signature.CreatedAt)); err != nil { + return fmt.Errorf("insert signature row: %w", err) + } + } + for _, sbom := range state.SBOMs { + if sbom.ID == "" || sbom.TenantID == "" || sbom.EvidenceID == "" { + continue + } + components, err := json.Marshal(sbom.Components) + if err != nil { + return fmt.Errorf("encode sbom components: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO sboms ( + id, tenant_id, evidence_id, release_id, artifact_id, format, + spec_version, component_count, components, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) + ON CONFLICT (id) DO UPDATE SET components = EXCLUDED.components, component_count = EXCLUDED.component_count + `, sbom.ID, sbom.TenantID, sbom.EvidenceID, nullableString(sbom.ReleaseID), nullableString(sbom.ArtifactID), sbom.Format, sbom.SpecVersion, sbom.ComponentCount, components, nonZeroTime(sbom.CreatedAt)); err != nil { + return fmt.Errorf("upsert sbom row: %w", err) + } + } + for _, scan := range state.Scans { + if scan.ID == "" || scan.TenantID == "" || scan.EvidenceID == "" { + continue + } + summary, err := json.Marshal(scan.Summary) + if err != nil { + return fmt.Errorf("encode vulnerability scan summary: %w", err) + } + findings, err := json.Marshal(scan.Findings) + if err != nil { + return fmt.Errorf("encode vulnerability scan findings: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO vulnerability_scans ( + id, tenant_id, evidence_id, release_id, scanner, target_ref, + summary, findings, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + ON CONFLICT (id) DO UPDATE SET summary = EXCLUDED.summary, findings = EXCLUDED.findings + `, scan.ID, scan.TenantID, scan.EvidenceID, nullableString(scan.ReleaseID), scan.Scanner, scan.TargetRef, summary, findings, nonZeroTime(scan.CreatedAt)); err != nil { + return fmt.Errorf("upsert vulnerability scan row: %w", err) + } + } + for _, contract := range state.Contracts { + if contract.ID == "" || contract.TenantID == "" || contract.ProductID == "" || contract.EvidenceID == "" { + continue + } + operations, err := json.Marshal(contract.Operations) + if err != nil { + return fmt.Errorf("encode openapi operations: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO openapi_contracts ( + id, tenant_id, product_id, release_id, version, hash, + path_count, operations, evidence_id, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) + ON CONFLICT (id) DO UPDATE SET path_count = EXCLUDED.path_count, operations = EXCLUDED.operations + `, contract.ID, contract.TenantID, contract.ProductID, nullableString(contract.ReleaseID), contract.Version, contract.Hash, contract.PathCount, operations, contract.EvidenceID, nonZeroTime(contract.CreatedAt)); err != nil { + return fmt.Errorf("upsert openapi contract row: %w", err) + } + } + for _, policy := range state.Policies { + if policy.ID == "" || policy.TenantID == "" || policy.ReleaseID == "" { + continue + } + checks, err := json.Marshal(policy.Checks) + if err != nil { + return fmt.Errorf("encode policy checks: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO policy_evaluations ( + id, tenant_id, release_id, result, policy_set, checks, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7) + ON CONFLICT (id) DO UPDATE SET result = EXCLUDED.result, checks = EXCLUDED.checks + `, policy.ID, policy.TenantID, policy.ReleaseID, policy.Result, policy.PolicySet, checks, nonZeroTime(policy.CreatedAt)); err != nil { + return fmt.Errorf("upsert policy evaluation row: %w", err) + } + } + for _, bundle := range state.Bundles { + if bundle.ID == "" || bundle.TenantID == "" || bundle.ReleaseID == "" { + continue + } + manifest, err := json.Marshal(bundle.Manifest) + if err != nil { + return fmt.Errorf("encode release bundle manifest: %w", err) + } + signatureRefs, err := json.Marshal(bundle.SignatureRefs) + if err != nil { + return fmt.Errorf("encode release bundle signature refs: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO release_bundles ( + id, tenant_id, release_id, state, manifest, manifest_hash, + signature_refs, created_at, published_at, revoked_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) + ON CONFLICT (id) DO UPDATE SET + state = EXCLUDED.state, + signature_refs = EXCLUDED.signature_refs, + published_at = EXCLUDED.published_at, + revoked_at = EXCLUDED.revoked_at + `, bundle.ID, bundle.TenantID, bundle.ReleaseID, bundle.State, manifest, bundle.ManifestHash, signatureRefs, nonZeroTime(bundle.CreatedAt), nullableTime(bundle.PublishedAt), nullableTime(bundle.RevokedAt)); err != nil { + return fmt.Errorf("upsert release bundle row: %w", err) + } + } + for _, verification := range state.Verifications { + if verification.ID == "" || verification.TenantID == "" { + continue + } + checks, err := json.Marshal(verification.Checks) + if err != nil { + return fmt.Errorf("encode verification checks: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO verification_results ( + id, tenant_id, subject_type, subject_id, result, checks, verified_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7) + ON CONFLICT (id) DO UPDATE SET result = EXCLUDED.result, checks = EXCLUDED.checks + `, verification.ID, verification.TenantID, verification.SubjectType, verification.SubjectID, verification.Result, checks, nonZeroTime(verification.VerifiedAt)); err != nil { + return fmt.Errorf("upsert verification result row: %w", err) + } + } + return nil +} + func syncIdentityAndIdempotency(ctx context.Context, tx pgx.Tx, state app.PersistedState) error { for _, tenant := range state.Tenants { if tenant.ID == "" { @@ -589,6 +912,27 @@ func nullableTime(value *time.Time) any { return value.UTC() } +func nullableInt64(value int64) any { + if value == 0 { + return nil + } + return value +} + +func nonZeroInt(value, fallback int) int { + if value == 0 { + return fallback + } + return value +} + +func nullableBytes(value []byte) any { + if len(value) == 0 { + return nil + } + return value +} + func nonZeroTime(value time.Time) time.Time { if value.IsZero() { return time.Now().UTC() diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index 5484d56..5db4229 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -56,6 +56,62 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { "sess_test": {ID: "sess_test", TenantID: "ten_test", UserID: "user_test", ProviderID: "sso_test", Prefix: "sess", ExpiresAt: time.Now().UTC().Add(time.Hour), SchemaVersion: domain.SSOSessionSchemaVersion, CreatedAt: time.Now().UTC()}, }, SSOSessionHashes: map[string]string{"sess_test": "session-hash"}, + Products: map[string]domain.Product{ + "prod_test": {ID: "prod_test", TenantID: "ten_test", Name: "Product", Slug: "product", CreatedAt: time.Now().UTC()}, + }, + Projects: map[string]domain.Project{ + "proj_test": {ID: "proj_test", TenantID: "ten_test", ProductID: "prod_test", Name: "API", CreatedAt: time.Now().UTC()}, + }, + Releases: map[string]domain.Release{ + "rel_test": {ID: "rel_test", TenantID: "ten_test", ProductID: "prod_test", Version: "1.0.0", State: "open", CreatedAt: time.Now().UTC()}, + }, + Artifacts: map[string]domain.Artifact{ + "art_test": {ID: "art_test", TenantID: "ten_test", Name: "artifact.tar.gz", MediaType: "application/gzip", Size: 42, Digest: "sha256:" + strings.Repeat("a", 64), CreatedAt: time.Now().UTC()}, + }, + Evidence: map[string]domain.EvidenceItem{ + "ev_test": { + ID: "ev_test", TenantID: "ten_test", ProductID: "prod_test", ProjectID: "proj_test", ReleaseID: "rel_test", + Type: "sbom", Subtype: "cyclonedx", Title: "SBOM", SourceSystem: "test", ObservedAt: time.Now().UTC(), + EvidenceVersion: 1, SchemaVersion: domain.EvidenceItemSchemaVersion, PayloadRef: "object://tenants/ten_test/payloads/sbom/" + strings.Repeat("b", 64), + PayloadHash: "sha256:" + strings.Repeat("b", 64), PayloadMediaType: "application/json", PayloadSize: 123, + CanonicalHash: "sha256:" + strings.Repeat("c", 64), Canonicalization: domain.CanonicalizationProfileVersion, + SubjectRefs: []domain.SubjectRef{{Type: "release", ID: "rel_test"}}, TrustLevel: "uploaded", VerificationStatus: "verified", + Tags: []string{"release"}, Metadata: map[string]any{"parser": "test"}, CreatedAt: time.Now().UTC(), + }, + }, + Chain: map[string][]domain.AuditChainEntry{ + "ten_test": {{ + ID: "chain_test", TenantID: "ten_test", Sequence: 1, EntryType: "evidence.created", SubjectType: "evidence_item", SubjectID: "ev_test", + ActorType: "user", ActorID: "user_test", OccurredAt: time.Now().UTC(), PayloadHash: "sha256:" + strings.Repeat("b", 64), + CanonicalEntryHash: "sha256:" + strings.Repeat("d", 64), PreviousEntryHash: "", EntryHash: "sha256:" + strings.Repeat("e", 64), + SchemaVersion: domain.AuditChainEntrySchemaVersion, + }}, + }, + SigningKeys: map[string]domain.SigningKey{ + "sigkey_test": {ID: "sigkey_test", TenantID: "ten_test", KID: "kid-test", Algorithm: "Ed25519", Status: "active", PublicKey: "public", CreatedAt: time.Now().UTC()}, + }, + SigningKeyPrivate: map[string][]byte{"sigkey_test": []byte("dev-private-key")}, + Signatures: map[string]domain.Signature{ + "sig_test": {ID: "sig_test", TenantID: "ten_test", SubjectType: "release_bundle", SubjectID: "bundle_test", KeyID: "sigkey_test", Algorithm: "Ed25519", Value: "signature", CreatedAt: time.Now().UTC()}, + }, + SBOMs: map[string]domain.SBOM{ + "sbom_test": {ID: "sbom_test", TenantID: "ten_test", EvidenceID: "ev_test", ReleaseID: "rel_test", ArtifactID: "art_test", Format: "cyclonedx", SpecVersion: "1.5", ComponentCount: 1, Components: []domain.SBOMComponent{{Name: "lib", Version: "1.0.0"}}, CreatedAt: time.Now().UTC()}, + }, + Scans: map[string]domain.VulnerabilityScan{ + "scan_test": {ID: "scan_test", TenantID: "ten_test", EvidenceID: "ev_test", ReleaseID: "rel_test", Scanner: "scanner", TargetRef: "artifact.tar.gz", Summary: map[string]int{"critical": 0}, Findings: []domain.VulnerabilityFinding{{ID: "finding_test", Vulnerability: "CVE-0000-0001", Severity: "low", State: "open"}}, CreatedAt: time.Now().UTC()}, + }, + Contracts: map[string]domain.OpenAPIContract{ + "contract_test": {ID: "contract_test", TenantID: "ten_test", ProductID: "prod_test", ReleaseID: "rel_test", Version: "1.0.0", Hash: "sha256:" + strings.Repeat("f", 64), PathCount: 1, Operations: []domain.OpenAPIOperation{{Path: "/v1/test", Method: "get", OperationID: "getTest"}}, EvidenceID: "ev_test", CreatedAt: time.Now().UTC()}, + }, + Policies: map[string]domain.PolicyEvaluation{ + "policy_test": {ID: "policy_test", TenantID: "ten_test", ReleaseID: "rel_test", Result: "pass", PolicySet: domain.PolicySetVersion, Checks: []domain.PolicyCheck{{Name: "sbom", Result: "passed", Severity: "high", Explanation: "test"}}, CreatedAt: time.Now().UTC()}, + }, + Bundles: map[string]domain.ReleaseBundle{ + "bundle_test": {ID: "bundle_test", TenantID: "ten_test", ReleaseID: "rel_test", State: "generated", Manifest: map[string]any{"release_id": "rel_test"}, ManifestHash: "sha256:" + strings.Repeat("1", 64), SignatureRefs: []string{"sig_test"}, CreatedAt: time.Now().UTC()}, + }, + Verifications: map[string]domain.VerificationResult{ + "verify_test": {ID: "verify_test", TenantID: "ten_test", SubjectType: "release_bundle", SubjectID: "bundle_test", Result: "pass", Checks: []domain.VerifyCheck{{Name: "signature", Result: "passed"}}, VerifiedAt: time.Now().UTC()}, + }, Idempotency: map[string]app.IdempotencyRecord{ app.NewIdempotencyRecordKey("ten_test", "user:user_test", "POST", "/v1/products", "idem"): {RequestHash: "sha256:request", Status: 201, Response: map[string]any{"ok": true}, CreatedAt: time.Now().UTC()}, }, @@ -105,6 +161,34 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { if idemActor != "user:user_test" { t.Fatalf("idempotency actor = %q", idemActor) } + coreChecks := []struct { + name string + query string + }{ + {name: "product", query: `SELECT count(*) FROM products WHERE tenant_id = 'ten_test' AND id = 'prod_test'`}, + {name: "project", query: `SELECT count(*) FROM projects WHERE tenant_id = 'ten_test' AND product_id = 'prod_test'`}, + {name: "release", query: `SELECT count(*) FROM releases WHERE tenant_id = 'ten_test' AND id = 'rel_test'`}, + {name: "artifact", query: `SELECT count(*) FROM artifacts WHERE tenant_id = 'ten_test' AND digest LIKE 'sha256:%'`}, + {name: "evidence", query: `SELECT count(*) FROM evidence_items WHERE tenant_id = 'ten_test' AND id = 'ev_test' AND evidence_version = 1 AND product_id = 'prod_test'`}, + {name: "audit chain", query: `SELECT count(*) FROM audit_chain_entries WHERE tenant_id = 'ten_test' AND sequence = 1`}, + {name: "signing key", query: `SELECT count(*) FROM signing_keys WHERE tenant_id = 'ten_test' AND id = 'sigkey_test' AND encrypted_private_key IS NOT NULL`}, + {name: "signature", query: `SELECT count(*) FROM signatures WHERE tenant_id = 'ten_test' AND id = 'sig_test'`}, + {name: "sbom", query: `SELECT count(*) FROM sboms WHERE tenant_id = 'ten_test' AND release_id = 'rel_test' AND component_count = 1`}, + {name: "scan", query: `SELECT count(*) FROM vulnerability_scans WHERE tenant_id = 'ten_test' AND release_id = 'rel_test'`}, + {name: "contract", query: `SELECT count(*) FROM openapi_contracts WHERE tenant_id = 'ten_test' AND id = 'contract_test' AND operations <> '[]'::jsonb`}, + {name: "policy", query: `SELECT count(*) FROM policy_evaluations WHERE tenant_id = 'ten_test' AND id = 'policy_test'`}, + {name: "bundle", query: `SELECT count(*) FROM release_bundles WHERE tenant_id = 'ten_test' AND id = 'bundle_test'`}, + {name: "verification", query: `SELECT count(*) FROM verification_results WHERE tenant_id = 'ten_test' AND id = 'verify_test'`}, + } + for _, check := range coreChecks { + var rows int + if err := store.pool.QueryRow(ctx, check.query).Scan(&rows); err != nil { + t.Fatalf("%s relational row query: %v", check.name, err) + } + if rows != 1 { + t.Fatalf("%s relational rows = %d, want 1", check.name, rows) + } + } job := app.OutboxJob{ID: "job_test_" + time.Now().Format("150405.000000000"), TenantID: "ten_test", Kind: "verify_subject", SubjectType: "audit_chain", SubjectID: "audit_chain", CreatedAt: time.Now().UTC()} if err := store.Enqueue(ctx, job); err != nil { t.Fatal(err) diff --git a/migrations/20260528001400_release_core_relational_columns.down.sql b/migrations/20260528001400_release_core_relational_columns.down.sql new file mode 100644 index 0000000..37b36e5 --- /dev/null +++ b/migrations/20260528001400_release_core_relational_columns.down.sql @@ -0,0 +1,13 @@ +DROP INDEX IF EXISTS evidence_items_tenant_build_idx; +DROP INDEX IF EXISTS vulnerability_scans_tenant_release_idx; + +ALTER TABLE openapi_contracts + DROP COLUMN IF EXISTS operations; + +ALTER TABLE vulnerability_scans + DROP COLUMN IF EXISTS release_id; + +ALTER TABLE evidence_items + DROP COLUMN IF EXISTS evidence_version, + DROP COLUMN IF EXISTS deployment_id, + DROP COLUMN IF EXISTS build_id; diff --git a/migrations/20260528001400_release_core_relational_columns.up.sql b/migrations/20260528001400_release_core_relational_columns.up.sql new file mode 100644 index 0000000..e2400d0 --- /dev/null +++ b/migrations/20260528001400_release_core_relational_columns.up.sql @@ -0,0 +1,17 @@ +ALTER TABLE evidence_items + ADD COLUMN IF NOT EXISTS build_id text, + ADD COLUMN IF NOT EXISTS deployment_id text, + ADD COLUMN IF NOT EXISTS evidence_version integer NOT NULL DEFAULT 1; + +ALTER TABLE vulnerability_scans + ADD COLUMN IF NOT EXISTS release_id text; + +ALTER TABLE openapi_contracts + ADD COLUMN IF NOT EXISTS operations jsonb NOT NULL DEFAULT '[]'::jsonb; + +CREATE INDEX IF NOT EXISTS vulnerability_scans_tenant_release_idx + ON vulnerability_scans(tenant_id, release_id, created_at); + +CREATE INDEX IF NOT EXISTS evidence_items_tenant_build_idx + ON evidence_items(tenant_id, build_id) + WHERE build_id IS NOT NULL; From 544abf015b3bebcd2e123a8038858829e78954e3 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 20:08:41 +0300 Subject: [PATCH 087/287] feat: persist worker parser replay results --- .implementation_increments.md | 2 +- cmd/evydence-worker/main.go | 360 ++++++++++++++++++++++--- cmd/evydence-worker/main_test.go | 63 ++++- docs/architecture.md | 2 +- docs/reference/production-readiness.md | 14 +- 5 files changed, 391 insertions(+), 50 deletions(-) diff --git a/.implementation_increments.md b/.implementation_increments.md index 32c42e3..bef602d 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -22,7 +22,7 @@ Status legend: Core Go API, tenant API keys, evidence, artifacts, products/projects/releases, audit chain, signing keys, release bundles, SBOM, vulnerability scans, OpenAPI upload, policy evaluation, missing evidence, release readiness, docs, migrations, Docker Compose, OpenAPI, and tests. 2. `[x]` Durable Runtime Foundation - PostgreSQL snapshot persistence, filesystem object storage, persisted outbox, worker polling, production config checks, migrations, and Postgres test gates. + PostgreSQL snapshot persistence, filesystem object storage, persisted outbox, worker polling, object-store replay with digest checks, parser-derived field persistence, production config checks, migrations, and Postgres test gates. 3. `[x]` VEX, Vulnerability Decisions, Exceptions OpenVEX ingestion, normalized vulnerability decisions, scoped exceptions, approval flow, and deterministic release-risk handling. diff --git a/cmd/evydence-worker/main.go b/cmd/evydence-worker/main.go index ffc45ec..5c50d3e 100644 --- a/cmd/evydence-worker/main.go +++ b/cmd/evydence-worker/main.go @@ -99,6 +99,11 @@ type jobStateLoader interface { LoadState(context.Context) (app.PersistedState, bool, error) } +type jobStateStore interface { + jobStateLoader + SaveState(context.Context, app.PersistedState) error +} + type jobObjectGetter interface { Get(context.Context, string) (app.Object, error) } @@ -134,6 +139,7 @@ func processJobInternal(ctx context.Context, state jobStateLoader, objects jobOb if !ok { return errors.New("durable state is not initialized") } + stateChanged := false switch job.Kind { case "parse_sbom": sbom, ok := snapshot.SBOMs[job.SubjectID] @@ -141,44 +147,84 @@ func processJobInternal(ctx context.Context, state jobStateLoader, objects jobOb return errors.New("parsed sbom is not available in durable state") } if hasReplayedObject { - if err := verifyReplayedSBOM(replayed.Bytes, sbom); err != nil { + parsed, err := parseReplayedSBOM(replayed.Bytes) + if err != nil { + return err + } + if err := verifyReplayedSBOM(parsed, sbom); err != nil { return err } + if updated, changed := mergeReplayedSBOM(sbom, parsed); changed { + snapshot.SBOMs[job.SubjectID] = updated + stateChanged = true + } + } + if err := requirePayloadHash(job, ""); err != nil { + return err } - return requirePayloadHash(job, "") case "parse_vulnerability_scan": scan, ok := snapshot.Scans[job.SubjectID] if !ok || scan.TenantID != job.TenantID { return errors.New("parsed vulnerability scan is not available in durable state") } if hasReplayedObject { - if err := verifyReplayedVulnerabilityScan(replayed.Bytes, scan); err != nil { + parsed, err := parseReplayedVulnerabilityScan(replayed.Bytes, job.SubjectID) + if err != nil { + return err + } + if err := verifyReplayedVulnerabilityScan(parsed, scan); err != nil { return err } + if updated, changed := mergeReplayedVulnerabilityScan(scan, parsed); changed { + snapshot.Scans[job.SubjectID] = updated + stateChanged = true + } + } + if err := requirePayloadHash(job, ""); err != nil { + return err } - return requirePayloadHash(job, "") case "parse_openapi_contract": contract, ok := snapshot.Contracts[job.SubjectID] if !ok || contract.TenantID != job.TenantID { return errors.New("parsed openapi contract is not available in durable state") } if hasReplayedObject { - if err := verifyReplayedOpenAPIContract(ctx, replayed.Bytes, contract); err != nil { + parsed, err := parseReplayedOpenAPIContract(ctx, replayed.Bytes) + if err != nil { return err } + if err := verifyReplayedOpenAPIContract(replayed.Bytes, parsed, contract); err != nil { + return err + } + if updated, changed := mergeReplayedOpenAPIContract(contract, parsed); changed { + snapshot.Contracts[job.SubjectID] = updated + stateChanged = true + } + } + if err := requirePayloadHash(job, contract.Hash); err != nil { + return err } - return requirePayloadHash(job, contract.Hash) case "parse_vex": vex, ok := snapshot.VEXDocuments[job.SubjectID] if !ok || vex.TenantID != job.TenantID { return errors.New("parsed vex document is not available in durable state") } if hasReplayedObject { - if err := verifyReplayedVEX(replayed.Bytes, vex); err != nil { + parsed, err := parseReplayedVEX(replayed.Bytes) + if err != nil { return err } + if err := verifyReplayedVEX(parsed, vex); err != nil { + return err + } + if updated, changed := mergeReplayedVEX(vex, parsed); changed { + snapshot.VEXDocuments[job.SubjectID] = updated + stateChanged = true + } + } + if err := requirePayloadHash(job, ""); err != nil { + return err } - return requirePayloadHash(job, "") case "sign_bundle": bundle, ok := snapshot.Bundles[job.SubjectID] if !ok || bundle.TenantID != job.TenantID { @@ -210,14 +256,34 @@ func processJobInternal(ctx context.Context, state jobStateLoader, objects jobOb return errors.New("build attestation verification status is incomplete") } if hasReplayedObject { - if err := verifyReplayedAttestation(replayed.Bytes, attestation); err != nil { + parsed, err := parseReplayedAttestation(replayed.Bytes) + if err != nil { + return err + } + if err := verifyReplayedAttestation(replayed.Bytes, parsed, attestation); err != nil { return err } + if updated, changed := mergeReplayedAttestation(attestation, parsed, replayed.Bytes); changed { + snapshot.BuildAttestations[job.SubjectID] = updated + stateChanged = true + } + } + if err := requirePayloadHash(job, attestation.PayloadHash); err != nil { + return err } - return requirePayloadHash(job, attestation.PayloadHash) default: return errors.New("unsupported outbox job kind") } + if stateChanged { + stateStore, ok := state.(jobStateStore) + if !ok { + return errors.New("durable parser side effects require writable state") + } + if err := stateStore.SaveState(ctx, snapshot); err != nil { + return errors.New("persist durable parser side effects") + } + } + return nil } func verifyJobObject(ctx context.Context, objects jobObjectGetter, job postgres.ClaimedJob) (app.Object, bool, error) { @@ -281,13 +347,10 @@ func payloadObjectKey(job postgres.ClaimedJob) string { type replayedSBOM struct { SpecVersion string ComponentCount int + Components []domain.SBOMComponent } -func verifyReplayedSBOM(raw []byte, sbom domain.SBOM) error { - parsed, err := parseReplayedSBOM(raw) - if err != nil { - return err - } +func verifyReplayedSBOM(parsed replayedSBOM, sbom domain.SBOM) error { if sbom.SpecVersion != "" && parsed.SpecVersion != sbom.SpecVersion { return errors.New("replayed sbom payload does not match durable state") } @@ -300,6 +363,23 @@ func verifyReplayedSBOM(raw []byte, sbom domain.SBOM) error { return nil } +func mergeReplayedSBOM(sbom domain.SBOM, parsed replayedSBOM) (domain.SBOM, bool) { + changed := false + if sbom.SpecVersion == "" && parsed.SpecVersion != "" { + sbom.SpecVersion = parsed.SpecVersion + changed = true + } + if sbom.ComponentCount == 0 && parsed.ComponentCount != 0 { + sbom.ComponentCount = parsed.ComponentCount + changed = true + } + if len(sbom.Components) == 0 && len(parsed.Components) != 0 { + sbom.Components = append([]domain.SBOMComponent(nil), parsed.Components...) + changed = true + } + return sbom, changed +} + func parseReplayedSBOM(raw []byte) (replayedSBOM, error) { var doc struct { BOMFormat string `json:"bomFormat"` @@ -313,12 +393,14 @@ func parseReplayedSBOM(raw []byte) (replayedSBOM, error) { if err := strictDecodeWorker(raw, &doc); err != nil || strings.ToLower(strings.TrimSpace(doc.BOMFormat)) != "cyclonedx" { return replayedSBOM{}, errors.New("replayed sbom payload is invalid") } + components := make([]domain.SBOMComponent, 0, len(doc.Components)) for _, component := range doc.Components { if strings.TrimSpace(component.Name) == "" { return replayedSBOM{}, errors.New("replayed sbom payload is invalid") } + components = append(components, domain.SBOMComponent{Name: strings.TrimSpace(component.Name), Version: strings.TrimSpace(component.Version), PURL: strings.TrimSpace(component.PURL)}) } - return replayedSBOM{SpecVersion: strings.TrimSpace(doc.SpecVersion), ComponentCount: len(doc.Components)}, nil + return replayedSBOM{SpecVersion: strings.TrimSpace(doc.SpecVersion), ComponentCount: len(doc.Components), Components: components}, nil } type replayedVulnerabilityScan struct { @@ -326,13 +408,10 @@ type replayedVulnerabilityScan struct { TargetRef string FindingCount int Summary map[string]int + Findings []domain.VulnerabilityFinding } -func verifyReplayedVulnerabilityScan(raw []byte, scan domain.VulnerabilityScan) error { - parsed, err := parseReplayedVulnerabilityScan(raw) - if err != nil { - return err - } +func verifyReplayedVulnerabilityScan(parsed replayedVulnerabilityScan, scan domain.VulnerabilityScan) error { if scan.Scanner != "" && parsed.Scanner != scan.Scanner { return errors.New("replayed vulnerability scan payload does not match durable state") } @@ -350,7 +429,28 @@ func verifyReplayedVulnerabilityScan(raw []byte, scan domain.VulnerabilityScan) return nil } -func parseReplayedVulnerabilityScan(raw []byte) (replayedVulnerabilityScan, error) { +func mergeReplayedVulnerabilityScan(scan domain.VulnerabilityScan, parsed replayedVulnerabilityScan) (domain.VulnerabilityScan, bool) { + changed := false + if scan.Scanner == "" && parsed.Scanner != "" { + scan.Scanner = parsed.Scanner + changed = true + } + if scan.TargetRef == "" && parsed.TargetRef != "" { + scan.TargetRef = parsed.TargetRef + changed = true + } + if scan.Summary == nil && parsed.Summary != nil { + scan.Summary = cloneIntMap(parsed.Summary) + changed = true + } + if len(scan.Findings) == 0 && len(parsed.Findings) != 0 { + scan.Findings = append([]domain.VulnerabilityFinding(nil), parsed.Findings...) + changed = true + } + return scan, changed +} + +func parseReplayedVulnerabilityScan(raw []byte, subjectID string) (replayedVulnerabilityScan, error) { var doc struct { Scanner string `json:"scanner"` TargetRef string `json:"target_ref"` @@ -366,29 +466,74 @@ func parseReplayedVulnerabilityScan(raw []byte) (replayedVulnerabilityScan, erro return replayedVulnerabilityScan{}, errors.New("replayed vulnerability scan payload is invalid") } summary := map[string]int{} - for _, finding := range doc.Findings { + findings := make([]domain.VulnerabilityFinding, 0, len(doc.Findings)) + for i, finding := range doc.Findings { if strings.TrimSpace(finding.Vulnerability) == "" || strings.TrimSpace(finding.Severity) == "" { return replayedVulnerabilityScan{}, errors.New("replayed vulnerability scan payload is invalid") } - summary[strings.ToLower(strings.TrimSpace(finding.Severity))]++ + severity := strings.ToLower(strings.TrimSpace(finding.Severity)) + summary[severity]++ + findings = append(findings, domain.VulnerabilityFinding{ + ID: fmt.Sprintf("%s:finding:%d", strings.TrimSpace(subjectID), i+1), + Vulnerability: strings.TrimSpace(finding.Vulnerability), + Component: strings.TrimSpace(finding.Component), + Severity: severity, + State: nonEmptyWorker(finding.State, "open"), + }) } - return replayedVulnerabilityScan{Scanner: strings.TrimSpace(doc.Scanner), TargetRef: strings.TrimSpace(doc.TargetRef), FindingCount: len(doc.Findings), Summary: summary}, nil + return replayedVulnerabilityScan{Scanner: strings.TrimSpace(doc.Scanner), TargetRef: strings.TrimSpace(doc.TargetRef), FindingCount: len(doc.Findings), Summary: summary, Findings: findings}, nil } -func verifyReplayedOpenAPIContract(ctx context.Context, raw []byte, contract domain.OpenAPIContract) error { +type replayedOpenAPIContract struct { + PathCount int + Operations []domain.OpenAPIOperation +} + +func parseReplayedOpenAPIContract(ctx context.Context, raw []byte) (replayedOpenAPIContract, error) { loader := openapi3.NewLoader() doc, err := loader.LoadFromData(raw) if err != nil { - return errors.New("replayed openapi contract payload is invalid") + return replayedOpenAPIContract{}, errors.New("replayed openapi contract payload is invalid") } if err := doc.Validate(ctx); err != nil { - return errors.New("replayed openapi contract payload is invalid") + return replayedOpenAPIContract{}, errors.New("replayed openapi contract payload is invalid") } pathCount := 0 + operations := []domain.OpenAPIOperation{} if doc.Paths != nil { - pathCount = len(doc.Paths.Map()) + paths := doc.Paths.Map() + pathCount = len(paths) + pathNames := make([]string, 0, len(paths)) + for path := range paths { + pathNames = append(pathNames, path) + } + sort.Strings(pathNames) + for _, path := range pathNames { + item := paths[path] + if item == nil { + continue + } + for _, method := range []string{"get", "put", "post", "delete", "options", "head", "patch", "trace"} { + operation := operationForMethod(item, method) + if operation == nil { + continue + } + statuses := []string{} + if operation.Responses != nil { + for status := range operation.Responses.Map() { + statuses = append(statuses, status) + } + sort.Strings(statuses) + } + operations = append(operations, domain.OpenAPIOperation{Path: path, Method: method, OperationID: operation.OperationID, Deprecated: operation.Deprecated, ResponseStatuses: statuses}) + } + } } - if contract.PathCount != 0 && pathCount != contract.PathCount { + return replayedOpenAPIContract{PathCount: pathCount, Operations: operations}, nil +} + +func verifyReplayedOpenAPIContract(raw []byte, parsed replayedOpenAPIContract, contract domain.OpenAPIContract) error { + if contract.PathCount != 0 && parsed.PathCount != contract.PathCount { return errors.New("replayed openapi contract payload does not match durable state") } if contract.Hash != "" && digestBytes(raw) != contract.Hash { @@ -397,17 +542,26 @@ func verifyReplayedOpenAPIContract(ctx context.Context, raw []byte, contract dom return nil } +func mergeReplayedOpenAPIContract(contract domain.OpenAPIContract, parsed replayedOpenAPIContract) (domain.OpenAPIContract, bool) { + changed := false + if contract.PathCount == 0 && parsed.PathCount != 0 { + contract.PathCount = parsed.PathCount + changed = true + } + if len(contract.Operations) == 0 && len(parsed.Operations) != 0 { + contract.Operations = append([]domain.OpenAPIOperation(nil), parsed.Operations...) + changed = true + } + return contract, changed +} + type replayedVEX struct { Author string StatementCount int StatusSummary map[string]int } -func verifyReplayedVEX(raw []byte, vex domain.VEXDocument) error { - parsed, err := parseReplayedVEX(raw) - if err != nil { - return err - } +func verifyReplayedVEX(parsed replayedVEX, vex domain.VEXDocument) error { if vex.Author != "" && parsed.Author != vex.Author { return errors.New("replayed vex payload does not match durable state") } @@ -422,6 +576,23 @@ func verifyReplayedVEX(raw []byte, vex domain.VEXDocument) error { return nil } +func mergeReplayedVEX(vex domain.VEXDocument, parsed replayedVEX) (domain.VEXDocument, bool) { + changed := false + if vex.Author == "" && parsed.Author != "" { + vex.Author = parsed.Author + changed = true + } + if vex.StatementCount == 0 && parsed.StatementCount != 0 { + vex.StatementCount = parsed.StatementCount + changed = true + } + if vex.StatusSummary == nil && parsed.StatusSummary != nil { + vex.StatusSummary = cloneIntMap(parsed.StatusSummary) + changed = true + } + return vex, changed +} + func parseReplayedVEX(raw []byte) (replayedVEX, error) { var doc struct { Context any `json:"@context"` @@ -459,11 +630,7 @@ func parseReplayedVEX(raw []byte) (replayedVEX, error) { return replayedVEX{Author: strings.TrimSpace(doc.Author), StatementCount: len(doc.Statements), StatusSummary: summary}, nil } -func verifyReplayedAttestation(raw []byte, attestation domain.BuildAttestation) error { - parsed, err := parseReplayedAttestation(raw) - if err != nil { - return err - } +func verifyReplayedAttestation(raw []byte, parsed replayedAttestation, attestation domain.BuildAttestation) error { if attestation.PayloadHash != "" && digestBytes(raw) != attestation.PayloadHash { return errors.New("replayed build attestation payload does not match durable state") } @@ -479,6 +646,11 @@ func verifyReplayedAttestation(raw []byte, attestation domain.BuildAttestation) type replayedAttestation struct { PredicateType string SubjectDigests []string + PayloadType string + SignatureCount int + BuilderID string + BuildType string + MaterialsCount int } func parseReplayedAttestation(raw []byte) (replayedAttestation, error) { @@ -523,7 +695,113 @@ func parseReplayedAttestation(raw []byte) (replayedAttestation, error) { digests = append(digests, digest) } sort.Strings(digests) - return replayedAttestation{PredicateType: strings.TrimSpace(statement.PredicateType), SubjectDigests: digests}, nil + builderID, _ := nestedString(statement.Predicate, "builder", "id") + buildType, _ := statement.Predicate["buildType"].(string) + materialsCount := 0 + if materials, ok := statement.Predicate["materials"].([]any); ok { + materialsCount = len(materials) + } + return replayedAttestation{ + PayloadType: strings.TrimSpace(envelope.PayloadType), + PredicateType: strings.TrimSpace(statement.PredicateType), + SubjectDigests: digests, + SignatureCount: len(envelope.Signatures), + BuilderID: strings.TrimSpace(builderID), + BuildType: strings.TrimSpace(buildType), + MaterialsCount: materialsCount, + }, nil +} + +func mergeReplayedAttestation(attestation domain.BuildAttestation, parsed replayedAttestation, raw []byte) (domain.BuildAttestation, bool) { + changed := false + if attestation.PayloadHash == "" { + attestation.PayloadHash = digestBytes(raw) + changed = true + } + if attestation.PayloadSize == 0 { + attestation.PayloadSize = int64(len(raw)) + changed = true + } + if attestation.PayloadType == "" && parsed.PayloadType != "" { + attestation.PayloadType = parsed.PayloadType + changed = true + } + if attestation.PredicateType == "" && parsed.PredicateType != "" { + attestation.PredicateType = parsed.PredicateType + changed = true + } + if len(attestation.SubjectDigests) == 0 && len(parsed.SubjectDigests) != 0 { + attestation.SubjectDigests = append([]string(nil), parsed.SubjectDigests...) + changed = true + } + if attestation.SignatureCount == 0 && parsed.SignatureCount != 0 { + attestation.SignatureCount = parsed.SignatureCount + changed = true + } + if attestation.BuilderID == "" && parsed.BuilderID != "" { + attestation.BuilderID = parsed.BuilderID + changed = true + } + if attestation.BuildType == "" && parsed.BuildType != "" { + attestation.BuildType = parsed.BuildType + changed = true + } + if attestation.MaterialsCount == 0 && parsed.MaterialsCount != 0 { + attestation.MaterialsCount = parsed.MaterialsCount + changed = true + } + return attestation, changed +} + +func operationForMethod(item *openapi3.PathItem, method string) *openapi3.Operation { + switch method { + case "get": + return item.Get + case "put": + return item.Put + case "post": + return item.Post + case "delete": + return item.Delete + case "options": + return item.Options + case "head": + return item.Head + case "patch": + return item.Patch + case "trace": + return item.Trace + default: + return nil + } +} + +func cloneIntMap(in map[string]int) map[string]int { + if in == nil { + return nil + } + out := make(map[string]int, len(in)) + for key, value := range in { + out[key] = value + } + return out +} + +func nonEmptyWorker(value, fallback string) string { + value = strings.TrimSpace(value) + if value == "" { + return fallback + } + return value +} + +func nestedString(in map[string]any, outer, inner string) (string, bool) { + rawOuter, ok := in[outer].(map[string]any) + if !ok { + return "", false + } + value, ok := rawOuter[inner].(string) + return value, ok } func equalStringSets(a, b []string) bool { diff --git a/cmd/evydence-worker/main_test.go b/cmd/evydence-worker/main_test.go index fe57ef4..b07e5e7 100644 --- a/cmd/evydence-worker/main_test.go +++ b/cmd/evydence-worker/main_test.go @@ -26,6 +26,22 @@ func (f fakeStateLoader) LoadState(context.Context) (app.PersistedState, bool, e return f.state, f.ok, f.err } +type fakeStateStore struct { + state app.PersistedState + saved app.PersistedState + ok bool + err error +} + +func (f *fakeStateStore) LoadState(context.Context) (app.PersistedState, bool, error) { + return f.state, f.ok, f.err +} + +func (f *fakeStateStore) SaveState(_ context.Context, state app.PersistedState) error { + f.saved = state + return nil +} + type fakeObjectGetter struct { object app.Object err error @@ -59,6 +75,50 @@ func TestProcessJobVerifiesConfiguredJobState(t *testing.T) { } } +func TestProcessJobWithObjectsPersistsParserDerivedFields(t *testing.T) { + body := []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","components":[{"name":"api","version":"1.0.0","purl":"pkg:generic/api@1.0.0"}]}`) + hash := digestBytes(body) + job := postgres.ClaimedJob{ + TenantID: "ten_test", + Kind: "parse_sbom", + SubjectID: "sbom_test", + Payload: map[string]any{"payload_ref": "object://tenants/ten_test/payloads/sbom.json", "payload_hash": hash}, + } + store := &fakeStateStore{ + ok: true, + state: app.PersistedState{SBOMs: map[string]domain.SBOM{ + "sbom_test": {ID: "sbom_test", TenantID: "ten_test"}, + }}, + } + object := app.Object{Key: "tenants/ten_test/payloads/sbom.json", TenantID: "ten_test", Digest: hash, Bytes: body} + if err := processJobWithObjects(context.Background(), store, fakeObjectGetter{object: object}, job); err != nil { + t.Fatalf("process object-backed job: %v", err) + } + updated := store.saved.SBOMs["sbom_test"] + if updated.SpecVersion != "1.6" || updated.ComponentCount != 1 || len(updated.Components) != 1 || updated.Components[0].Name != "api" { + t.Fatalf("saved sbom = %#v", updated) + } +} + +func TestProcessJobWithObjectsRequiresWritableStateForParserSideEffects(t *testing.T) { + body := []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","components":[{"name":"api"}]}`) + hash := digestBytes(body) + job := postgres.ClaimedJob{ + TenantID: "ten_test", + Kind: "parse_sbom", + SubjectID: "sbom_test", + Payload: map[string]any{"payload_ref": "tenants/ten_test/payloads/sbom.json", "payload_hash": hash}, + } + state := app.PersistedState{SBOMs: map[string]domain.SBOM{ + "sbom_test": {ID: "sbom_test", TenantID: "ten_test"}, + }} + object := app.Object{Key: "tenants/ten_test/payloads/sbom.json", TenantID: "ten_test", Digest: hash, Bytes: body} + err := processJobWithObjects(context.Background(), fakeStateLoader{state: state, ok: true}, fakeObjectGetter{object: object}, job) + if err == nil || !strings.Contains(err.Error(), "writable state") { + t.Fatalf("err=%v", err) + } +} + func TestProcessJobWithObjectsVerifiesTenantPrefixedPayload(t *testing.T) { body := []byte(`{"bomFormat":"CycloneDX"}`) hash := digestBytes(body) @@ -139,7 +199,8 @@ func TestProcessJobWithObjectsParsesPayloadAndChecksDurableState(t *testing.T) { contract.Hash = hash tt.state.Contracts[tt.job.SubjectID] = contract } - if err := processJobWithObjects(context.Background(), fakeStateLoader{state: tt.state, ok: true}, fakeObjectGetter{object: tt.object}, tt.job); err != nil { + store := &fakeStateStore{state: tt.state, ok: true} + if err := processJobWithObjects(context.Background(), store, fakeObjectGetter{object: tt.object}, tt.job); err != nil { t.Fatalf("process replay payload: %v", err) } }) diff --git a/docs/architecture.md b/docs/architecture.md index ea4affc..798d341 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -26,7 +26,7 @@ When `EVYDENCE_DATABASE_URL` is set, mutations are saved to PostgreSQL before su Evidence, evidence lifecycle events, incidents, remediation tasks, security scans, manual security documents, SBOM diffs, VEX documents, vulnerability decisions/workflow records, organizations, users, role bindings, SSO providers, SSO sessions, legal holds, retention overrides, customer portal access records, questionnaire packages and drafts, evidence summaries, evidence graph snapshots, commercial and marketplace collector definitions, waivers, approvals, customer packages, report templates, evidence bundles, exceptions, build runs, build attestations, release candidates, artifact signatures, source-control records, deployment events, contract diffs, custom policy evaluations, provider verifications, signing operations, control evidence links, public transparency log entries, and release bundle records are append-only in behavior. Changes are represented by supersession, lifecycle events, approval transitions, session revocation, package access records, links, verification receipts, rollback-as-new-event records, or new audit-chain entries. -Outbox jobs are persisted in PostgreSQL and claimed by workers with `FOR UPDATE SKIP LOCKED`. Current parser jobs validate durable state and fail closed on mismatches; production hardening must make parser jobs re-read tenant-prefixed object-store payloads, verify digests, and produce parser side effects independently of the API request path. +Outbox jobs are persisted in PostgreSQL and claimed by workers with `FOR UPDATE SKIP LOCKED`. Parser jobs re-read tenant-prefixed object-store payloads, verify size and digest, validate durable state, persist missing parser-derived normalized fields, and fail closed on mismatches. Upload endpoints still create initial accepted records, so moving every parser-owned side effect fully out of the API request path remains production hardening work. ## Verification And Trust diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index a3c86e2..d97e91f 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -19,9 +19,10 @@ Known hardening work remains: relational identity, idempotency, release-ledger core, audit-chain, signing, bundle, policy, and verification rows alongside the canonical snapshot, but the snapshot remains the runtime load source; -- worker parser jobs re-read raw object-store payloads for key formats and - validate durable state, but parser side effects still need to move - independently out of the request path; +- worker parser jobs re-read raw object-store payloads for key formats, + verify digests, validate durable state, and persist missing parser-derived + normalized fields. Upload paths still create initial accepted records, so + fully worker-owned parsing for every payload remains hardening work; - OpenAPI precision is enforced across the registered public API. The generated matrix remains the source of truth for operation ids, scopes, idempotency, parameters, and request/response schemas; @@ -103,9 +104,10 @@ implemented capabilities: - Split the large application ledger aggregate into focused services or repositories once relational writes are in place, preserving tenant isolation and append-only behavior throughout. -- Move parser-owned side effects for SBOM, vulnerability scan, OpenAPI, VEX, - and attestation payloads fully into worker processors while keeping upload - responses backward compatible. +- Continue moving parser-owned side effects for SBOM, vulnerability scan, + OpenAPI, VEX, and attestation payloads into worker processors. Workers now + persist missing parser-derived fields after object replay, but upload + endpoints still create initial accepted records. - Keep OpenAPI precision at zero broad operations as routes are added or changed, and expand generated SDK coverage from the committed contract. - Add direct cloud KMS/HSM SDK adapters where required. The current HTTPS From 83132f3a07faa9398883e7b124db3838ac1e2009 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 20:26:15 +0300 Subject: [PATCH 088/287] feat: load core state from relational rows --- .implementation_increments.md | 2 +- docs/architecture.md | 2 +- docs/reference/production-readiness.md | 9 +- internal/adapters/postgres/store.go | 559 ++++++++++++++++++++++- internal/adapters/postgres/store_test.go | 28 ++ 5 files changed, 594 insertions(+), 6 deletions(-) diff --git a/.implementation_increments.md b/.implementation_increments.md index bef602d..0e228ed 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -36,7 +36,7 @@ Status legend: ## Remaining Core Product Increments 6. `[x]` Relational Store Split - Added migration-backed relational tables and tenant-scoped resource projection rows for implemented resources, with transactional PostgreSQL saves, relational identity/idempotency rows, relational release-ledger core rows, tenant/release indexes, persisted idempotency state, and outbox row locking. Canonical runtime loading still uses the versioned ledger snapshot while per-resource repository tuning remains future hardening. + Added migration-backed relational tables and tenant-scoped resource projection rows for implemented resources, with transactional PostgreSQL saves, relational identity/idempotency rows, relational release-ledger core rows, missing-snapshot fallback loading for those families, tenant/release indexes, persisted idempotency state, and outbox row locking. Canonical runtime loading still prefers the versioned ledger snapshot while per-resource repository tuning remains future hardening. 7. `[x]` Evidence Search, Filtering, And Timeline Querying Added tenant-scoped evidence search by product, project, release, build, deployment, type, subtype, source, collector, created time, subject refs, tags, and verification status. diff --git a/docs/architecture.md b/docs/architecture.md index 798d341..f8bd6ef 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -10,7 +10,7 @@ Evydence follows a ports-and-adapters shape: - `internal/adapters/objectstore/s3` stores the same tenant-prefixed object keys in S3/MinIO-compatible buckets. - `cmd/*` contains process entry points. -Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity and idempotency records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. +Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity and idempotency records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. If the snapshot row is absent, the Postgres store can rebuild those identity and release-ledger core families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. ## Tenant And Auth Boundaries diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index d97e91f..91ea9d1 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -18,7 +18,9 @@ Known hardening work remains: paths for all high-risk resource families. PostgreSQL now maintains relational identity, idempotency, release-ledger core, audit-chain, signing, bundle, policy, and verification rows alongside the canonical snapshot, but - the snapshot remains the runtime load source; + the snapshot remains the preferred runtime load source. If the snapshot row + is absent, the store can rebuild identity and release-ledger core state from + relational rows; - worker parser jobs re-read raw object-store payloads for key formats, verify digests, validate durable state, and persist missing parser-derived normalized fields. Upload paths still create initial accepted records, so @@ -99,8 +101,9 @@ implemented capabilities: repositories for remaining report, package, portal, retention, and secondary resources. Identity, idempotency, release-ledger core, audit-chain, signing, bundle, policy, and verification rows are synchronized into relational - tables, but runtime loading still uses the canonical snapshot. Keep snapshots - only for export/import and upgrade compatibility. + tables, and missing-snapshot recovery can rebuild those families from + relational rows. Keep snapshots only for export/import and upgrade + compatibility after the remaining families have repository-backed writes. - Split the large application ledger aggregate into focused services or repositories once relational writes are in place, preserving tenant isolation and append-only behavior throughout. diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index 2b2e64b..ac0d115 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -2,6 +2,7 @@ package postgres import ( "context" + "database/sql" "encoding/json" "errors" "fmt" @@ -11,6 +12,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" "github.com/aatuh/evydence/internal/app" + "github.com/aatuh/evydence/internal/domain" ) type Store struct { @@ -49,7 +51,7 @@ func (s *Store) LoadState(ctx context.Context) (app.PersistedState, bool, error) var body []byte err := s.pool.QueryRow(ctx, `SELECT state FROM ledger_state WHERE id = 'default'`).Scan(&body) if errors.Is(err, pgx.ErrNoRows) { - return app.PersistedState{}, false, nil + return s.loadRelationalState(ctx) } if err != nil { return app.PersistedState{}, false, fmt.Errorf("load ledger state: %w", err) @@ -61,6 +63,539 @@ func (s *Store) LoadState(ctx context.Context) (app.PersistedState, bool, error) return state, true, nil } +func (s *Store) loadRelationalState(ctx context.Context) (app.PersistedState, bool, error) { + state := relationalEmptyState() + loaded := false + if err := s.loadRelationalTenants(ctx, &state, &loaded); err != nil { + return app.PersistedState{}, false, err + } + if err := s.loadRelationalAPIKeys(ctx, &state, &loaded); err != nil { + return app.PersistedState{}, false, err + } + if err := s.loadRelationalReleaseCore(ctx, &state, &loaded); err != nil { + return app.PersistedState{}, false, err + } + if err := s.loadRelationalIdempotency(ctx, &state, &loaded); err != nil { + return app.PersistedState{}, false, err + } + return state, loaded, nil +} + +func relationalEmptyState() app.PersistedState { + return app.PersistedState{ + Tenants: map[string]domain.Tenant{}, + APIKeys: map[string]domain.APIKey{}, + APIKeyHashes: map[string]string{}, + Products: map[string]domain.Product{}, + Projects: map[string]domain.Project{}, + Releases: map[string]domain.Release{}, + Artifacts: map[string]domain.Artifact{}, + Evidence: map[string]domain.EvidenceItem{}, + SBOMs: map[string]domain.SBOM{}, + Scans: map[string]domain.VulnerabilityScan{}, + Contracts: map[string]domain.OpenAPIContract{}, + Policies: map[string]domain.PolicyEvaluation{}, + Bundles: map[string]domain.ReleaseBundle{}, + SigningKeys: map[string]domain.SigningKey{}, + SigningKeyPrivate: map[string][]byte{}, + Signatures: map[string]domain.Signature{}, + Verifications: map[string]domain.VerificationResult{}, + Chain: map[string][]domain.AuditChainEntry{}, + Idempotency: map[string]app.IdempotencyRecord{}, + } +} + +func (s *Store) loadRelationalTenants(ctx context.Context, state *app.PersistedState, loaded *bool) error { + rows, err := s.pool.Query(ctx, `SELECT id, name, created_at FROM tenants`) + if err != nil { + return fmt.Errorf("load relational tenants: %w", err) + } + defer rows.Close() + for rows.Next() { + var tenant domain.Tenant + if err := rows.Scan(&tenant.ID, &tenant.Name, &tenant.CreatedAt); err != nil { + return fmt.Errorf("scan relational tenant: %w", err) + } + state.Tenants[tenant.ID] = tenant + *loaded = true + } + return rows.Err() +} + +func (s *Store) loadRelationalAPIKeys(ctx context.Context, state *app.PersistedState, loaded *bool) error { + rows, err := s.pool.Query(ctx, ` + SELECT id, tenant_id, name, prefix, hash, scopes, expires_at, + revoked_at, last_used_at, created_at + FROM api_keys + `) + if err != nil { + return fmt.Errorf("load relational api keys: %w", err) + } + defer rows.Close() + for rows.Next() { + var key domain.APIKey + var hash string + var scopes []byte + var expiresAt, revokedAt, lastUsedAt sql.NullTime + if err := rows.Scan(&key.ID, &key.TenantID, &key.Name, &key.Prefix, &hash, &scopes, &expiresAt, &revokedAt, &lastUsedAt, &key.CreatedAt); err != nil { + return fmt.Errorf("scan relational api key: %w", err) + } + if err := decodeJSON(scopes, &key.Scopes); err != nil { + return fmt.Errorf("decode relational api key scopes: %w", err) + } + key.ExpiresAt = nullableSQLTime(expiresAt) + key.RevokedAt = nullableSQLTime(revokedAt) + key.LastUsedAt = nullableSQLTime(lastUsedAt) + state.APIKeys[key.ID] = key + state.APIKeyHashes[key.ID] = hash + *loaded = true + } + return rows.Err() +} + +func (s *Store) loadRelationalReleaseCore(ctx context.Context, state *app.PersistedState, loaded *bool) error { + if err := s.loadRelationalProducts(ctx, state, loaded); err != nil { + return err + } + if err := s.loadRelationalProjects(ctx, state, loaded); err != nil { + return err + } + if err := s.loadRelationalReleases(ctx, state, loaded); err != nil { + return err + } + if err := s.loadRelationalArtifacts(ctx, state, loaded); err != nil { + return err + } + if err := s.loadRelationalEvidence(ctx, state, loaded); err != nil { + return err + } + if err := s.loadRelationalAuditChain(ctx, state, loaded); err != nil { + return err + } + if err := s.loadRelationalSigning(ctx, state, loaded); err != nil { + return err + } + if err := s.loadRelationalParsedResources(ctx, state, loaded); err != nil { + return err + } + return nil +} + +func (s *Store) loadRelationalProducts(ctx context.Context, state *app.PersistedState, loaded *bool) error { + rows, err := s.pool.Query(ctx, `SELECT id, tenant_id, name, slug, created_at FROM products`) + if err != nil { + return fmt.Errorf("load relational products: %w", err) + } + defer rows.Close() + for rows.Next() { + var product domain.Product + if err := rows.Scan(&product.ID, &product.TenantID, &product.Name, &product.Slug, &product.CreatedAt); err != nil { + return fmt.Errorf("scan relational product: %w", err) + } + state.Products[product.ID] = product + *loaded = true + } + return rows.Err() +} + +func (s *Store) loadRelationalProjects(ctx context.Context, state *app.PersistedState, loaded *bool) error { + rows, err := s.pool.Query(ctx, `SELECT id, tenant_id, product_id, name, created_at FROM projects`) + if err != nil { + return fmt.Errorf("load relational projects: %w", err) + } + defer rows.Close() + for rows.Next() { + var project domain.Project + if err := rows.Scan(&project.ID, &project.TenantID, &project.ProductID, &project.Name, &project.CreatedAt); err != nil { + return fmt.Errorf("scan relational project: %w", err) + } + state.Projects[project.ID] = project + *loaded = true + } + return rows.Err() +} + +func (s *Store) loadRelationalReleases(ctx context.Context, state *app.PersistedState, loaded *bool) error { + rows, err := s.pool.Query(ctx, `SELECT id, tenant_id, product_id, version, state, frozen_at, approved_at, created_at FROM releases`) + if err != nil { + return fmt.Errorf("load relational releases: %w", err) + } + defer rows.Close() + for rows.Next() { + var release domain.Release + var frozenAt, approvedAt sql.NullTime + if err := rows.Scan(&release.ID, &release.TenantID, &release.ProductID, &release.Version, &release.State, &frozenAt, &approvedAt, &release.CreatedAt); err != nil { + return fmt.Errorf("scan relational release: %w", err) + } + release.FrozenAt = nullableSQLTime(frozenAt) + release.ApprovedAt = nullableSQLTime(approvedAt) + state.Releases[release.ID] = release + *loaded = true + } + return rows.Err() +} + +func (s *Store) loadRelationalArtifacts(ctx context.Context, state *app.PersistedState, loaded *bool) error { + rows, err := s.pool.Query(ctx, `SELECT id, tenant_id, name, media_type, size, digest, created_at FROM artifacts`) + if err != nil { + return fmt.Errorf("load relational artifacts: %w", err) + } + defer rows.Close() + for rows.Next() { + var artifact domain.Artifact + if err := rows.Scan(&artifact.ID, &artifact.TenantID, &artifact.Name, &artifact.MediaType, &artifact.Size, &artifact.Digest, &artifact.CreatedAt); err != nil { + return fmt.Errorf("scan relational artifact: %w", err) + } + state.Artifacts[artifact.ID] = artifact + *loaded = true + } + return rows.Err() +} + +func (s *Store) loadRelationalEvidence(ctx context.Context, state *app.PersistedState, loaded *bool) error { + rows, err := s.pool.Query(ctx, ` + SELECT id, tenant_id, product_id, project_id, release_id, build_id, deployment_id, + type, subtype, title, source_system, source_identity, collector_id, + uploaded_by, observed_at, evidence_version, schema_version, payload_ref, + payload_hash, payload_media_type, payload_size, canonical_hash, + canonicalization, subject_refs, related_evidence_refs, supersedes, + superseded_by, trust_level, verification_status, signature_refs, + chain_entry_id, tags, metadata, warnings, limitations, created_at + FROM evidence_items + `) + if err != nil { + return fmt.Errorf("load relational evidence items: %w", err) + } + defer rows.Close() + for rows.Next() { + var evidence domain.EvidenceItem + var productID, projectID, releaseID, buildID, deploymentID, subtype, collectorID, uploadedBy, payloadRef, payloadMediaType, supersedes, supersededBy, chainEntryID sql.NullString + var payloadSize sql.NullInt64 + var sourceIdentity, subjectRefs, relatedRefs, signatureRefs, tags, metadata, warnings, limitations []byte + if err := rows.Scan( + &evidence.ID, &evidence.TenantID, &productID, &projectID, &releaseID, &buildID, &deploymentID, + &evidence.Type, &subtype, &evidence.Title, &evidence.SourceSystem, &sourceIdentity, &collectorID, + &uploadedBy, &evidence.ObservedAt, &evidence.EvidenceVersion, &evidence.SchemaVersion, &payloadRef, + &evidence.PayloadHash, &payloadMediaType, &payloadSize, &evidence.CanonicalHash, + &evidence.Canonicalization, &subjectRefs, &relatedRefs, &supersedes, + &supersededBy, &evidence.TrustLevel, &evidence.VerificationStatus, &signatureRefs, + &chainEntryID, &tags, &metadata, &warnings, &limitations, &evidence.CreatedAt, + ); err != nil { + return fmt.Errorf("scan relational evidence item: %w", err) + } + evidence.ProductID = nullableSQLString(productID) + evidence.ProjectID = nullableSQLString(projectID) + evidence.ReleaseID = nullableSQLString(releaseID) + evidence.BuildID = nullableSQLString(buildID) + evidence.DeploymentID = nullableSQLString(deploymentID) + evidence.Subtype = nullableSQLString(subtype) + evidence.CollectorID = nullableSQLString(collectorID) + evidence.UploadedBy = nullableSQLString(uploadedBy) + evidence.PayloadRef = nullableSQLString(payloadRef) + evidence.PayloadMediaType = nullableSQLString(payloadMediaType) + if payloadSize.Valid { + evidence.PayloadSize = payloadSize.Int64 + } + evidence.Supersedes = nullableSQLString(supersedes) + evidence.SupersededBy = nullableSQLString(supersededBy) + evidence.ChainEntryID = nullableSQLString(chainEntryID) + if err := decodeJSON(sourceIdentity, &evidence.SourceIdentity); err != nil { + return fmt.Errorf("decode relational evidence source identity: %w", err) + } + if err := decodeJSON(subjectRefs, &evidence.SubjectRefs); err != nil { + return fmt.Errorf("decode relational evidence subject refs: %w", err) + } + if err := decodeJSON(relatedRefs, &evidence.RelatedEvidenceRefs); err != nil { + return fmt.Errorf("decode relational evidence related refs: %w", err) + } + if err := decodeJSON(signatureRefs, &evidence.SignatureRefs); err != nil { + return fmt.Errorf("decode relational evidence signature refs: %w", err) + } + if err := decodeJSON(tags, &evidence.Tags); err != nil { + return fmt.Errorf("decode relational evidence tags: %w", err) + } + if err := decodeJSON(metadata, &evidence.Metadata); err != nil { + return fmt.Errorf("decode relational evidence metadata: %w", err) + } + if err := decodeJSON(warnings, &evidence.Warnings); err != nil { + return fmt.Errorf("decode relational evidence warnings: %w", err) + } + if err := decodeJSON(limitations, &evidence.Limitations); err != nil { + return fmt.Errorf("decode relational evidence limitations: %w", err) + } + state.Evidence[evidence.ID] = evidence + *loaded = true + } + return rows.Err() +} + +func (s *Store) loadRelationalAuditChain(ctx context.Context, state *app.PersistedState, loaded *bool) error { + rows, err := s.pool.Query(ctx, ` + SELECT id, tenant_id, sequence, entry_type, subject_type, subject_id, + actor_type, actor_id, occurred_at, payload_hash, + canonical_entry_hash, previous_entry_hash, entry_hash, + signature_ref, metadata, schema_version + FROM audit_chain_entries + ORDER BY tenant_id, sequence + `) + if err != nil { + return fmt.Errorf("load relational audit chain: %w", err) + } + defer rows.Close() + for rows.Next() { + var entry domain.AuditChainEntry + var payloadHash, signatureRef sql.NullString + var metadata []byte + if err := rows.Scan( + &entry.ID, &entry.TenantID, &entry.Sequence, &entry.EntryType, &entry.SubjectType, &entry.SubjectID, + &entry.ActorType, &entry.ActorID, &entry.OccurredAt, &payloadHash, + &entry.CanonicalEntryHash, &entry.PreviousEntryHash, &entry.EntryHash, + &signatureRef, &metadata, &entry.SchemaVersion, + ); err != nil { + return fmt.Errorf("scan relational audit chain entry: %w", err) + } + entry.PayloadHash = nullableSQLString(payloadHash) + entry.SignatureRef = nullableSQLString(signatureRef) + if err := decodeJSON(metadata, &entry.Metadata); err != nil { + return fmt.Errorf("decode relational audit metadata: %w", err) + } + state.Chain[entry.TenantID] = append(state.Chain[entry.TenantID], entry) + *loaded = true + } + return rows.Err() +} + +func (s *Store) loadRelationalSigning(ctx context.Context, state *app.PersistedState, loaded *bool) error { + keyRows, err := s.pool.Query(ctx, ` + SELECT id, tenant_id, kid, algorithm, status, public_key, + encrypted_private_key, created_at, revoked_at + FROM signing_keys + `) + if err != nil { + return fmt.Errorf("load relational signing keys: %w", err) + } + defer keyRows.Close() + for keyRows.Next() { + var key domain.SigningKey + var private []byte + var revokedAt sql.NullTime + if err := keyRows.Scan(&key.ID, &key.TenantID, &key.KID, &key.Algorithm, &key.Status, &key.PublicKey, &private, &key.CreatedAt, &revokedAt); err != nil { + return fmt.Errorf("scan relational signing key: %w", err) + } + key.RevokedAt = nullableSQLTime(revokedAt) + state.SigningKeys[key.ID] = key + if len(private) != 0 { + state.SigningKeyPrivate[key.ID] = append([]byte(nil), private...) + } + *loaded = true + } + if err := keyRows.Err(); err != nil { + return err + } + + sigRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, subject_type, subject_id, key_id, algorithm, value, created_at FROM signatures`) + if err != nil { + return fmt.Errorf("load relational signatures: %w", err) + } + defer sigRows.Close() + for sigRows.Next() { + var signature domain.Signature + if err := sigRows.Scan(&signature.ID, &signature.TenantID, &signature.SubjectType, &signature.SubjectID, &signature.KeyID, &signature.Algorithm, &signature.Value, &signature.CreatedAt); err != nil { + return fmt.Errorf("scan relational signature: %w", err) + } + state.Signatures[signature.ID] = signature + *loaded = true + } + return sigRows.Err() +} + +func (s *Store) loadRelationalParsedResources(ctx context.Context, state *app.PersistedState, loaded *bool) error { + if err := s.loadRelationalSBOMs(ctx, state, loaded); err != nil { + return err + } + if err := s.loadRelationalScans(ctx, state, loaded); err != nil { + return err + } + if err := s.loadRelationalContracts(ctx, state, loaded); err != nil { + return err + } + if err := s.loadRelationalPolicies(ctx, state, loaded); err != nil { + return err + } + if err := s.loadRelationalBundles(ctx, state, loaded); err != nil { + return err + } + if err := s.loadRelationalVerifications(ctx, state, loaded); err != nil { + return err + } + return nil +} + +func (s *Store) loadRelationalSBOMs(ctx context.Context, state *app.PersistedState, loaded *bool) error { + rows, err := s.pool.Query(ctx, `SELECT id, tenant_id, evidence_id, release_id, artifact_id, format, spec_version, component_count, components, created_at FROM sboms`) + if err != nil { + return fmt.Errorf("load relational sboms: %w", err) + } + defer rows.Close() + for rows.Next() { + var sbom domain.SBOM + var releaseID, artifactID sql.NullString + var components []byte + if err := rows.Scan(&sbom.ID, &sbom.TenantID, &sbom.EvidenceID, &releaseID, &artifactID, &sbom.Format, &sbom.SpecVersion, &sbom.ComponentCount, &components, &sbom.CreatedAt); err != nil { + return fmt.Errorf("scan relational sbom: %w", err) + } + sbom.ReleaseID = nullableSQLString(releaseID) + sbom.ArtifactID = nullableSQLString(artifactID) + if err := decodeJSON(components, &sbom.Components); err != nil { + return fmt.Errorf("decode relational sbom components: %w", err) + } + state.SBOMs[sbom.ID] = sbom + *loaded = true + } + return rows.Err() +} + +func (s *Store) loadRelationalScans(ctx context.Context, state *app.PersistedState, loaded *bool) error { + rows, err := s.pool.Query(ctx, `SELECT id, tenant_id, evidence_id, release_id, scanner, target_ref, summary, findings, created_at FROM vulnerability_scans`) + if err != nil { + return fmt.Errorf("load relational vulnerability scans: %w", err) + } + defer rows.Close() + for rows.Next() { + var scan domain.VulnerabilityScan + var releaseID sql.NullString + var summary, findings []byte + if err := rows.Scan(&scan.ID, &scan.TenantID, &scan.EvidenceID, &releaseID, &scan.Scanner, &scan.TargetRef, &summary, &findings, &scan.CreatedAt); err != nil { + return fmt.Errorf("scan relational vulnerability scan: %w", err) + } + scan.ReleaseID = nullableSQLString(releaseID) + if err := decodeJSON(summary, &scan.Summary); err != nil { + return fmt.Errorf("decode relational vulnerability scan summary: %w", err) + } + if err := decodeJSON(findings, &scan.Findings); err != nil { + return fmt.Errorf("decode relational vulnerability scan findings: %w", err) + } + state.Scans[scan.ID] = scan + *loaded = true + } + return rows.Err() +} + +func (s *Store) loadRelationalContracts(ctx context.Context, state *app.PersistedState, loaded *bool) error { + rows, err := s.pool.Query(ctx, `SELECT id, tenant_id, product_id, release_id, version, hash, path_count, operations, evidence_id, created_at FROM openapi_contracts`) + if err != nil { + return fmt.Errorf("load relational openapi contracts: %w", err) + } + defer rows.Close() + for rows.Next() { + var contract domain.OpenAPIContract + var releaseID sql.NullString + var operations []byte + if err := rows.Scan(&contract.ID, &contract.TenantID, &contract.ProductID, &releaseID, &contract.Version, &contract.Hash, &contract.PathCount, &operations, &contract.EvidenceID, &contract.CreatedAt); err != nil { + return fmt.Errorf("scan relational openapi contract: %w", err) + } + contract.ReleaseID = nullableSQLString(releaseID) + if err := decodeJSON(operations, &contract.Operations); err != nil { + return fmt.Errorf("decode relational openapi operations: %w", err) + } + state.Contracts[contract.ID] = contract + *loaded = true + } + return rows.Err() +} + +func (s *Store) loadRelationalPolicies(ctx context.Context, state *app.PersistedState, loaded *bool) error { + rows, err := s.pool.Query(ctx, `SELECT id, tenant_id, release_id, result, policy_set, checks, created_at FROM policy_evaluations`) + if err != nil { + return fmt.Errorf("load relational policy evaluations: %w", err) + } + defer rows.Close() + for rows.Next() { + var policy domain.PolicyEvaluation + var checks []byte + if err := rows.Scan(&policy.ID, &policy.TenantID, &policy.ReleaseID, &policy.Result, &policy.PolicySet, &checks, &policy.CreatedAt); err != nil { + return fmt.Errorf("scan relational policy evaluation: %w", err) + } + if err := decodeJSON(checks, &policy.Checks); err != nil { + return fmt.Errorf("decode relational policy checks: %w", err) + } + state.Policies[policy.ID] = policy + *loaded = true + } + return rows.Err() +} + +func (s *Store) loadRelationalBundles(ctx context.Context, state *app.PersistedState, loaded *bool) error { + rows, err := s.pool.Query(ctx, `SELECT id, tenant_id, release_id, state, manifest, manifest_hash, signature_refs, created_at, published_at, revoked_at FROM release_bundles`) + if err != nil { + return fmt.Errorf("load relational release bundles: %w", err) + } + defer rows.Close() + for rows.Next() { + var bundle domain.ReleaseBundle + var manifest, signatureRefs []byte + var publishedAt, revokedAt sql.NullTime + if err := rows.Scan(&bundle.ID, &bundle.TenantID, &bundle.ReleaseID, &bundle.State, &manifest, &bundle.ManifestHash, &signatureRefs, &bundle.CreatedAt, &publishedAt, &revokedAt); err != nil { + return fmt.Errorf("scan relational release bundle: %w", err) + } + if err := decodeJSON(manifest, &bundle.Manifest); err != nil { + return fmt.Errorf("decode relational release bundle manifest: %w", err) + } + if err := decodeJSON(signatureRefs, &bundle.SignatureRefs); err != nil { + return fmt.Errorf("decode relational release bundle signature refs: %w", err) + } + bundle.PublishedAt = nullableSQLTime(publishedAt) + bundle.RevokedAt = nullableSQLTime(revokedAt) + state.Bundles[bundle.ID] = bundle + *loaded = true + } + return rows.Err() +} + +func (s *Store) loadRelationalVerifications(ctx context.Context, state *app.PersistedState, loaded *bool) error { + rows, err := s.pool.Query(ctx, `SELECT id, tenant_id, subject_type, subject_id, result, checks, verified_at FROM verification_results`) + if err != nil { + return fmt.Errorf("load relational verification results: %w", err) + } + defer rows.Close() + for rows.Next() { + var verification domain.VerificationResult + var checks []byte + if err := rows.Scan(&verification.ID, &verification.TenantID, &verification.SubjectType, &verification.SubjectID, &verification.Result, &checks, &verification.VerifiedAt); err != nil { + return fmt.Errorf("scan relational verification result: %w", err) + } + if err := decodeJSON(checks, &verification.Checks); err != nil { + return fmt.Errorf("decode relational verification checks: %w", err) + } + state.Verifications[verification.ID] = verification + *loaded = true + } + return rows.Err() +} + +func (s *Store) loadRelationalIdempotency(ctx context.Context, state *app.PersistedState, loaded *bool) error { + rows, err := s.pool.Query(ctx, `SELECT tenant_id, actor_key_id, method, path, idempotency_key, request_hash, status, response, created_at FROM idempotency_records`) + if err != nil { + return fmt.Errorf("load relational idempotency records: %w", err) + } + defer rows.Close() + for rows.Next() { + var tenantID, actorID, method, path, idempotencyKey string + var record app.IdempotencyRecord + var response []byte + if err := rows.Scan(&tenantID, &actorID, &method, &path, &idempotencyKey, &record.RequestHash, &record.Status, &response, &record.CreatedAt); err != nil { + return fmt.Errorf("scan relational idempotency record: %w", err) + } + if err := decodeJSON(response, &record.Response); err != nil { + return fmt.Errorf("decode relational idempotency response: %w", err) + } + key := app.NewIdempotencyRecordKey(tenantID, actorID, method, path, idempotencyKey) + state.Idempotency[key] = record + *loaded = true + } + return rows.Err() +} + func (s *Store) SaveState(ctx context.Context, state app.PersistedState) error { body, err := json.Marshal(state) if err != nil { @@ -905,6 +1440,28 @@ func nullableString(value string) any { return value } +func nullableSQLString(value sql.NullString) string { + if !value.Valid { + return "" + } + return value.String +} + +func nullableSQLTime(value sql.NullTime) *time.Time { + if !value.Valid || value.Time.IsZero() { + return nil + } + t := value.Time.UTC() + return &t +} + +func decodeJSON(raw []byte, out any) error { + if len(raw) == 0 || string(raw) == "null" { + return nil + } + return json.Unmarshal(raw, out) +} + func nullableTime(value *time.Time) any { if value == nil || value.IsZero() { return nil diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index 5db4229..36a0d7e 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -189,6 +189,34 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { t.Fatalf("%s relational rows = %d, want 1", check.name, rows) } } + if _, err := store.pool.Exec(ctx, `DELETE FROM ledger_state WHERE id = 'default'`); err != nil { + t.Fatal(err) + } + relational, ok, err := store.LoadState(ctx) + if err != nil { + t.Fatal(err) + } + if !ok { + t.Fatal("expected relational state fallback after removing snapshot") + } + if relational.APIKeyHashes["key_test"] != "hmac-test-hash" { + t.Fatalf("relational api key hash = %q", relational.APIKeyHashes["key_test"]) + } + if relational.Products["prod_test"].Slug != "product" || relational.Evidence["ev_test"].ReleaseID != "rel_test" || relational.SBOMs["sbom_test"].ComponentCount != 1 { + t.Fatalf("relational fallback missing core rows: product=%#v evidence=%#v sbom=%#v", relational.Products["prod_test"], relational.Evidence["ev_test"], relational.SBOMs["sbom_test"]) + } + if relational.Contracts["contract_test"].PathCount != 1 || len(relational.Contracts["contract_test"].Operations) != 1 { + t.Fatalf("relational fallback contract = %#v", relational.Contracts["contract_test"]) + } + if len(relational.Chain["ten_test"]) != 1 || relational.Bundles["bundle_test"].ManifestHash == "" || relational.Verifications["verify_test"].Result != "pass" { + t.Fatalf("relational fallback integrity rows missing: chain=%#v bundle=%#v verification=%#v", relational.Chain["ten_test"], relational.Bundles["bundle_test"], relational.Verifications["verify_test"]) + } + if len(relational.SigningKeyPrivate["sigkey_test"]) == 0 { + t.Fatal("relational fallback missing local dev signing key bytes") + } + if len(relational.Idempotency) != 1 { + t.Fatalf("relational idempotency records = %d, want 1", len(relational.Idempotency)) + } job := app.OutboxJob{ID: "job_test_" + time.Now().Format("150405.000000000"), TenantID: "ten_test", Kind: "verify_subject", SubjectType: "audit_chain", SubjectID: "audit_chain", CreatedAt: time.Now().UTC()} if err := store.Enqueue(ctx, job); err != nil { t.Fatal(err) From 32838ad036c93ccb007e782e6dfb76f2719768d8 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 20:31:03 +0300 Subject: [PATCH 089/287] feat: persist portal token rows relationally --- .implementation_increments.md | 2 +- docs/architecture.md | 2 +- docs/reference/production-readiness.md | 21 ++--- internal/adapters/postgres/store.go | 105 +++++++++++++++++++---- internal/adapters/postgres/store_test.go | 14 +++ 5 files changed, 113 insertions(+), 31 deletions(-) diff --git a/.implementation_increments.md b/.implementation_increments.md index 0e228ed..49b16b7 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -36,7 +36,7 @@ Status legend: ## Remaining Core Product Increments 6. `[x]` Relational Store Split - Added migration-backed relational tables and tenant-scoped resource projection rows for implemented resources, with transactional PostgreSQL saves, relational identity/idempotency rows, relational release-ledger core rows, missing-snapshot fallback loading for those families, tenant/release indexes, persisted idempotency state, and outbox row locking. Canonical runtime loading still prefers the versioned ledger snapshot while per-resource repository tuning remains future hardening. + Added migration-backed relational tables and tenant-scoped resource projection rows for implemented resources, with transactional PostgreSQL saves, relational identity/idempotency/customer-portal-token rows, relational release-ledger core rows, missing-snapshot fallback loading for those families, tenant/release indexes, persisted idempotency state, and outbox row locking. Canonical runtime loading still prefers the versioned ledger snapshot while per-resource repository tuning remains future hardening. 7. `[x]` Evidence Search, Filtering, And Timeline Querying Added tenant-scoped evidence search by product, project, release, build, deployment, type, subtype, source, collector, created time, subject refs, tags, and verification status. diff --git a/docs/architecture.md b/docs/architecture.md index f8bd6ef..e037394 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -10,7 +10,7 @@ Evydence follows a ports-and-adapters shape: - `internal/adapters/objectstore/s3` stores the same tenant-prefixed object keys in S3/MinIO-compatible buckets. - `cmd/*` contains process entry points. -Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity and idempotency records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. If the snapshot row is absent, the Postgres store can rebuild those identity and release-ledger core families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. +Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity, idempotency, and customer portal token records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. If the snapshot row is absent, the Postgres store can rebuild those identity, customer portal token, and release-ledger core families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. ## Tenant And Auth Boundaries diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 91ea9d1..c436811 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -16,11 +16,11 @@ Known hardening work remains: - canonical production persistence still needs hand-tuned relational repository paths for all high-risk resource families. PostgreSQL now maintains - relational identity, idempotency, release-ledger core, audit-chain, signing, - bundle, policy, and verification rows alongside the canonical snapshot, but - the snapshot remains the preferred runtime load source. If the snapshot row - is absent, the store can rebuild identity and release-ledger core state from - relational rows; + relational identity, idempotency, customer portal token, release-ledger core, + audit-chain, signing, bundle, policy, and verification rows alongside the + canonical snapshot, but the snapshot remains the preferred runtime load + source. If the snapshot row is absent, the store can rebuild identity, + customer portal token, and release-ledger core state from relational rows; - worker parser jobs re-read raw object-store payloads for key formats, verify digests, validate durable state, and persist missing parser-derived normalized fields. Upload paths still create initial accepted records, so @@ -99,11 +99,12 @@ implemented capabilities: - Replace canonical snapshot writes with dependency-ordered relational repositories for remaining report, package, portal, retention, and secondary - resources. Identity, idempotency, release-ledger core, audit-chain, signing, - bundle, policy, and verification rows are synchronized into relational - tables, and missing-snapshot recovery can rebuild those families from - relational rows. Keep snapshots only for export/import and upgrade - compatibility after the remaining families have repository-backed writes. + resources. Identity, idempotency, customer portal token, release-ledger core, + audit-chain, signing, bundle, policy, and verification rows are synchronized + into relational tables, and missing-snapshot recovery can rebuild those + families from relational rows. Keep snapshots only for export/import and + upgrade compatibility after the remaining families have repository-backed + writes. - Split the large application ledger aggregate into focused services or repositories once relational writes are in place, preserving tenant isolation and append-only behavior throughout. diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index ac0d115..c68c6c4 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -72,6 +72,9 @@ func (s *Store) loadRelationalState(ctx context.Context) (app.PersistedState, bo if err := s.loadRelationalAPIKeys(ctx, &state, &loaded); err != nil { return app.PersistedState{}, false, err } + if err := s.loadRelationalCustomerPortalAccess(ctx, &state, &loaded); err != nil { + return app.PersistedState{}, false, err + } if err := s.loadRelationalReleaseCore(ctx, &state, &loaded); err != nil { return app.PersistedState{}, false, err } @@ -83,25 +86,27 @@ func (s *Store) loadRelationalState(ctx context.Context) (app.PersistedState, bo func relationalEmptyState() app.PersistedState { return app.PersistedState{ - Tenants: map[string]domain.Tenant{}, - APIKeys: map[string]domain.APIKey{}, - APIKeyHashes: map[string]string{}, - Products: map[string]domain.Product{}, - Projects: map[string]domain.Project{}, - Releases: map[string]domain.Release{}, - Artifacts: map[string]domain.Artifact{}, - Evidence: map[string]domain.EvidenceItem{}, - SBOMs: map[string]domain.SBOM{}, - Scans: map[string]domain.VulnerabilityScan{}, - Contracts: map[string]domain.OpenAPIContract{}, - Policies: map[string]domain.PolicyEvaluation{}, - Bundles: map[string]domain.ReleaseBundle{}, - SigningKeys: map[string]domain.SigningKey{}, - SigningKeyPrivate: map[string][]byte{}, - Signatures: map[string]domain.Signature{}, - Verifications: map[string]domain.VerificationResult{}, - Chain: map[string][]domain.AuditChainEntry{}, - Idempotency: map[string]app.IdempotencyRecord{}, + Tenants: map[string]domain.Tenant{}, + APIKeys: map[string]domain.APIKey{}, + APIKeyHashes: map[string]string{}, + CustomerPortalAccess: map[string]domain.CustomerPortalAccess{}, + CustomerPortalHashes: map[string]string{}, + Products: map[string]domain.Product{}, + Projects: map[string]domain.Project{}, + Releases: map[string]domain.Release{}, + Artifacts: map[string]domain.Artifact{}, + Evidence: map[string]domain.EvidenceItem{}, + SBOMs: map[string]domain.SBOM{}, + Scans: map[string]domain.VulnerabilityScan{}, + Contracts: map[string]domain.OpenAPIContract{}, + Policies: map[string]domain.PolicyEvaluation{}, + Bundles: map[string]domain.ReleaseBundle{}, + SigningKeys: map[string]domain.SigningKey{}, + SigningKeyPrivate: map[string][]byte{}, + Signatures: map[string]domain.Signature{}, + Verifications: map[string]domain.VerificationResult{}, + Chain: map[string][]domain.AuditChainEntry{}, + Idempotency: map[string]app.IdempotencyRecord{}, } } @@ -153,6 +158,38 @@ func (s *Store) loadRelationalAPIKeys(ctx context.Context, state *app.PersistedS return rows.Err() } +func (s *Store) loadRelationalCustomerPortalAccess(ctx context.Context, state *app.PersistedState, loaded *bool) error { + rows, err := s.pool.Query(ctx, ` + SELECT id, tenant_id, package_id, customer_name, prefix, hash, + expires_at, revoked_at, access_count, failed_access_count, + last_accessed_at, last_failed_at, schema_version, created_at + FROM customer_portal_access + `) + if err != nil { + return fmt.Errorf("load relational customer portal access: %w", err) + } + defer rows.Close() + for rows.Next() { + var access domain.CustomerPortalAccess + var hash string + var revokedAt, lastAccessedAt, lastFailedAt sql.NullTime + if err := rows.Scan( + &access.ID, &access.TenantID, &access.PackageID, &access.CustomerName, &access.Prefix, &hash, + &access.ExpiresAt, &revokedAt, &access.AccessCount, &access.FailedAccessCount, + &lastAccessedAt, &lastFailedAt, &access.SchemaVersion, &access.CreatedAt, + ); err != nil { + return fmt.Errorf("scan relational customer portal access: %w", err) + } + access.RevokedAt = nullableSQLTime(revokedAt) + access.LastAccessedAt = nullableSQLTime(lastAccessedAt) + access.LastFailedAt = nullableSQLTime(lastFailedAt) + state.CustomerPortalAccess[access.ID] = access + state.CustomerPortalHashes[access.ID] = hash + *loaded = true + } + return rows.Err() +} + func (s *Store) loadRelationalReleaseCore(ctx context.Context, state *app.PersistedState, loaded *bool) error { if err := s.loadRelationalProducts(ctx, state, loaded); err != nil { return err @@ -1134,6 +1171,36 @@ func syncIdentityAndIdempotency(ctx context.Context, tx pgx.Tx, state app.Persis return fmt.Errorf("upsert sso session row: %w", err) } } + for id, access := range state.CustomerPortalAccess { + if access.ID == "" || access.TenantID == "" { + continue + } + hash := state.CustomerPortalHashes[id] + if hash == "" { + hash = access.Hash + } + if _, err := tx.Exec(ctx, ` + INSERT INTO customer_portal_access ( + id, tenant_id, package_id, customer_name, prefix, hash, + expires_at, revoked_at, access_count, failed_access_count, + last_accessed_at, last_failed_at, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) + ON CONFLICT (id) DO UPDATE SET + customer_name = EXCLUDED.customer_name, + prefix = EXCLUDED.prefix, + hash = EXCLUDED.hash, + expires_at = EXCLUDED.expires_at, + revoked_at = EXCLUDED.revoked_at, + access_count = EXCLUDED.access_count, + failed_access_count = EXCLUDED.failed_access_count, + last_accessed_at = EXCLUDED.last_accessed_at, + last_failed_at = EXCLUDED.last_failed_at, + schema_version = EXCLUDED.schema_version + `, access.ID, access.TenantID, access.PackageID, access.CustomerName, access.Prefix, hash, access.ExpiresAt, nullableTime(access.RevokedAt), access.AccessCount, access.FailedAccessCount, nullableTime(access.LastAccessedAt), nullableTime(access.LastFailedAt), access.SchemaVersion, nonZeroTime(access.CreatedAt)); err != nil { + return fmt.Errorf("upsert customer portal access row: %w", err) + } + } if _, err := tx.Exec(ctx, `DELETE FROM idempotency_records`); err != nil { return fmt.Errorf("clear idempotency records: %w", err) } diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index 36a0d7e..e9db582 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -56,6 +56,10 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { "sess_test": {ID: "sess_test", TenantID: "ten_test", UserID: "user_test", ProviderID: "sso_test", Prefix: "sess", ExpiresAt: time.Now().UTC().Add(time.Hour), SchemaVersion: domain.SSOSessionSchemaVersion, CreatedAt: time.Now().UTC()}, }, SSOSessionHashes: map[string]string{"sess_test": "session-hash"}, + CustomerPortalAccess: map[string]domain.CustomerPortalAccess{ + "cpa_test": {ID: "cpa_test", TenantID: "ten_test", PackageID: "pkg_test", CustomerName: "Customer", Prefix: "evycp_test", ExpiresAt: time.Now().UTC().Add(time.Hour), AccessCount: 2, FailedAccessCount: 1, LastAccessedAt: ptrTime(time.Now().UTC()), LastFailedAt: ptrTime(time.Now().UTC()), SchemaVersion: domain.CustomerPortalAccessVersion, CreatedAt: time.Now().UTC()}, + }, + CustomerPortalHashes: map[string]string{"cpa_test": "portal-token-hash"}, Products: map[string]domain.Product{ "prod_test": {ID: "prod_test", TenantID: "ten_test", Name: "Product", Slug: "product", CreatedAt: time.Now().UTC()}, }, @@ -161,6 +165,13 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { if idemActor != "user:user_test" { t.Fatalf("idempotency actor = %q", idemActor) } + var portalHash string + if err := store.pool.QueryRow(ctx, `SELECT hash FROM customer_portal_access WHERE id = 'cpa_test' AND failed_access_count = 1 AND last_accessed_at IS NOT NULL`).Scan(&portalHash); err != nil { + t.Fatal(err) + } + if portalHash != "portal-token-hash" { + t.Fatalf("portal hash = %q", portalHash) + } coreChecks := []struct { name string query string @@ -217,6 +228,9 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { if len(relational.Idempotency) != 1 { t.Fatalf("relational idempotency records = %d, want 1", len(relational.Idempotency)) } + if relational.CustomerPortalHashes["cpa_test"] != "portal-token-hash" || relational.CustomerPortalAccess["cpa_test"].FailedAccessCount != 1 { + t.Fatalf("relational portal access = %#v hash=%q", relational.CustomerPortalAccess["cpa_test"], relational.CustomerPortalHashes["cpa_test"]) + } job := app.OutboxJob{ID: "job_test_" + time.Now().Format("150405.000000000"), TenantID: "ten_test", Kind: "verify_subject", SubjectType: "audit_chain", SubjectID: "audit_chain", CreatedAt: time.Now().UTC()} if err := store.Enqueue(ctx, job); err != nil { t.Fatal(err) From ff13941a872a48474aeef67fdec42b67fdb9f462 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 20:33:51 +0300 Subject: [PATCH 090/287] feat: synchronize package retention rows --- .implementation_increments.md | 2 +- docs/architecture.md | 2 +- docs/reference/production-readiness.md | 23 +- internal/adapters/postgres/store.go | 318 ++++++++++++++++++ internal/adapters/postgres/store_test.go | 60 ++++ ...kage_retention_relational_columns.down.sql | 6 + ...ackage_retention_relational_columns.up.sql | 6 + 7 files changed, 404 insertions(+), 13 deletions(-) create mode 100644 migrations/20260528001500_package_retention_relational_columns.down.sql create mode 100644 migrations/20260528001500_package_retention_relational_columns.up.sql diff --git a/.implementation_increments.md b/.implementation_increments.md index 49b16b7..99e5d96 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -36,7 +36,7 @@ Status legend: ## Remaining Core Product Increments 6. `[x]` Relational Store Split - Added migration-backed relational tables and tenant-scoped resource projection rows for implemented resources, with transactional PostgreSQL saves, relational identity/idempotency/customer-portal-token rows, relational release-ledger core rows, missing-snapshot fallback loading for those families, tenant/release indexes, persisted idempotency state, and outbox row locking. Canonical runtime loading still prefers the versioned ledger snapshot while per-resource repository tuning remains future hardening. + Added migration-backed relational tables and tenant-scoped resource projection rows for implemented resources, with transactional PostgreSQL saves, relational identity/idempotency/customer-portal-token rows, relational release-ledger core rows, relational package/report/retention rows, missing-snapshot fallback loading for identity and release-ledger families, tenant/release indexes, persisted idempotency state, and outbox row locking. Canonical runtime loading still prefers the versioned ledger snapshot while per-resource repository tuning remains future hardening. 7. `[x]` Evidence Search, Filtering, And Timeline Querying Added tenant-scoped evidence search by product, project, release, build, deployment, type, subtype, source, collector, created time, subject refs, tags, and verification status. diff --git a/docs/architecture.md b/docs/architecture.md index e037394..14b51e9 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -10,7 +10,7 @@ Evydence follows a ports-and-adapters shape: - `internal/adapters/objectstore/s3` stores the same tenant-prefixed object keys in S3/MinIO-compatible buckets. - `cmd/*` contains process entry points. -Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity, idempotency, and customer portal token records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. If the snapshot row is absent, the Postgres store can rebuild those identity, customer portal token, and release-ledger core families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. +Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity, idempotency, and customer portal token records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. Package, report, retention, and backup records are synchronized into their migration-backed relational tables. If the snapshot row is absent, the Postgres store can rebuild identity, customer portal token, and release-ledger core families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. ## Tenant And Auth Boundaries diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index c436811..7dfe151 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -17,10 +17,11 @@ Known hardening work remains: - canonical production persistence still needs hand-tuned relational repository paths for all high-risk resource families. PostgreSQL now maintains relational identity, idempotency, customer portal token, release-ledger core, - audit-chain, signing, bundle, policy, and verification rows alongside the - canonical snapshot, but the snapshot remains the preferred runtime load - source. If the snapshot row is absent, the store can rebuild identity, - customer portal token, and release-ledger core state from relational rows; + audit-chain, signing, bundle, policy, verification, package, report, and + retention rows alongside the canonical snapshot, but the snapshot remains the + preferred runtime load source. If the snapshot row is absent, the store can + rebuild identity, customer portal token, and release-ledger core state from + relational rows; - worker parser jobs re-read raw object-store payloads for key formats, verify digests, validate durable state, and persist missing parser-derived normalized fields. Upload paths still create initial accepted records, so @@ -98,13 +99,13 @@ These items are tracked separately from the feature-completeness checklist in implemented capabilities: - Replace canonical snapshot writes with dependency-ordered relational - repositories for remaining report, package, portal, retention, and secondary - resources. Identity, idempotency, customer portal token, release-ledger core, - audit-chain, signing, bundle, policy, and verification rows are synchronized - into relational tables, and missing-snapshot recovery can rebuild those - families from relational rows. Keep snapshots only for export/import and - upgrade compatibility after the remaining families have repository-backed - writes. + repositories for remaining secondary resources. Identity, idempotency, + customer portal token, release-ledger core, audit-chain, signing, bundle, + policy, verification, package, report, and retention rows are synchronized + into relational tables. Missing-snapshot recovery can rebuild identity, + customer portal token, and release-ledger core families from relational rows. + Keep snapshots only for export/import and upgrade compatibility after the + remaining families have repository-backed reads and writes. - Split the large application ledger aggregate into focused services or repositories once relational writes are in place, preserving tenant isolation and append-only behavior throughout. diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index c68c6c4..3bdba3d 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -660,6 +660,9 @@ func (s *Store) SaveState(ctx context.Context, state app.PersistedState) error { if err := syncReleaseLedgerCore(ctx, tx, state); err != nil { return err } + if err := syncPackageReportRetentionRows(ctx, tx, state); err != nil { + return err + } if err := tx.Commit(ctx); err != nil { return fmt.Errorf("commit save ledger state transaction: %w", err) } @@ -986,6 +989,321 @@ func syncReleaseLedgerCore(ctx context.Context, tx pgx.Tx, state app.PersistedSt return nil } +func syncPackageReportRetentionRows(ctx context.Context, tx pgx.Tx, state app.PersistedState) error { + for _, profile := range state.RedactionProfiles { + if profile.ID == "" || profile.TenantID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO redaction_profiles ( + id, tenant_id, name, description, allowed_types, excluded_fields, + schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8) + ON CONFLICT (id) DO UPDATE SET + name = EXCLUDED.name, + description = EXCLUDED.description, + allowed_types = EXCLUDED.allowed_types, + excluded_fields = EXCLUDED.excluded_fields, + schema_version = EXCLUDED.schema_version + `, profile.ID, profile.TenantID, profile.Name, nullableString(profile.Description), profile.AllowedTypes, profile.ExcludedFields, profile.SchemaVersion, nonZeroTime(profile.CreatedAt)); err != nil { + return fmt.Errorf("upsert redaction profile row: %w", err) + } + } + for _, pkg := range state.CustomerPackages { + if pkg.ID == "" || pkg.TenantID == "" { + continue + } + manifest, err := json.Marshal(pkg.Manifest) + if err != nil { + return fmt.Errorf("encode customer package manifest: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO customer_security_packages ( + id, tenant_id, product_id, release_id, redaction_profile_id, + title, state, manifest, manifest_hash, expires_at, access_count, + schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13) + ON CONFLICT (id) DO UPDATE SET + state = EXCLUDED.state, + manifest = EXCLUDED.manifest, + manifest_hash = EXCLUDED.manifest_hash, + expires_at = EXCLUDED.expires_at, + access_count = EXCLUDED.access_count, + schema_version = EXCLUDED.schema_version + `, pkg.ID, pkg.TenantID, pkg.ProductID, nullableString(pkg.ReleaseID), pkg.RedactionProfileID, pkg.Title, pkg.State, manifest, pkg.ManifestHash, pkg.ExpiresAt, pkg.AccessCount, pkg.SchemaVersion, nonZeroTime(pkg.CreatedAt)); err != nil { + return fmt.Errorf("upsert customer package row: %w", err) + } + } + for _, report := range state.HTMLReports { + if report.ID == "" || report.TenantID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO html_report_packages ( + id, tenant_id, report_type, product_id, release_id, html, hash, + schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + ON CONFLICT (id) DO UPDATE SET html = EXCLUDED.html, hash = EXCLUDED.hash, schema_version = EXCLUDED.schema_version + `, report.ID, report.TenantID, report.ReportType, report.ProductID, nullableString(report.ReleaseID), report.HTML, report.Hash, report.SchemaVersion, nonZeroTime(report.CreatedAt)); err != nil { + return fmt.Errorf("upsert html report row: %w", err) + } + } + for _, template := range state.ReportTemplates { + if template.ID == "" || template.TenantID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO report_templates ( + id, tenant_id, name, version, report_type, allowed_fields, + template, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + ON CONFLICT (id) DO UPDATE SET + report_type = EXCLUDED.report_type, + allowed_fields = EXCLUDED.allowed_fields, + template = EXCLUDED.template, + schema_version = EXCLUDED.schema_version + `, template.ID, template.TenantID, template.Name, template.Version, template.ReportType, template.AllowedFields, template.Template, template.SchemaVersion, nonZeroTime(template.CreatedAt)); err != nil { + return fmt.Errorf("upsert report template row: %w", err) + } + } + for _, report := range state.RenderedReports { + if report.ID == "" || report.TenantID == "" { + continue + } + output, err := json.Marshal(report.Output) + if err != nil { + return fmt.Errorf("encode rendered report output: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO rendered_reports ( + id, tenant_id, template_id, subject_type, subject_id, output, + hash, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + ON CONFLICT (id) DO UPDATE SET output = EXCLUDED.output, hash = EXCLUDED.hash, schema_version = EXCLUDED.schema_version + `, report.ID, report.TenantID, report.TemplateID, report.SubjectType, report.SubjectID, output, report.Hash, report.SchemaVersion, nonZeroTime(report.CreatedAt)); err != nil { + return fmt.Errorf("upsert rendered report row: %w", err) + } + } + for _, bundle := range state.EvidenceBundles { + if bundle.ID == "" || bundle.TenantID == "" { + continue + } + manifest, err := json.Marshal(bundle.Manifest) + if err != nil { + return fmt.Errorf("encode evidence bundle manifest: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO evidence_bundles ( + id, tenant_id, release_id, evidence_ids, manifest, manifest_hash, + signature_refs, verification_text, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) + ON CONFLICT (id) DO UPDATE SET + manifest = EXCLUDED.manifest, + manifest_hash = EXCLUDED.manifest_hash, + signature_refs = EXCLUDED.signature_refs, + verification_text = EXCLUDED.verification_text, + schema_version = EXCLUDED.schema_version + `, bundle.ID, bundle.TenantID, nullableString(bundle.ReleaseID), bundle.EvidenceIDs, manifest, bundle.ManifestHash, bundle.SignatureRefs, bundle.VerificationText, bundle.SchemaVersion, nonZeroTime(bundle.CreatedAt)); err != nil { + return fmt.Errorf("upsert evidence bundle row: %w", err) + } + } + for _, imported := range state.BundleImports { + if imported.ID == "" || imported.TenantID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO evidence_bundle_imports ( + id, tenant_id, bundle_hash, result, imported_count, + schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7) + ON CONFLICT (id) DO UPDATE SET result = EXCLUDED.result, imported_count = EXCLUDED.imported_count, schema_version = EXCLUDED.schema_version + `, imported.ID, imported.TenantID, imported.BundleHash, imported.Result, imported.ImportedCount, imported.SchemaVersion, nonZeroTime(imported.CreatedAt)); err != nil { + return fmt.Errorf("upsert evidence bundle import row: %w", err) + } + } + for _, policy := range state.ObjectRetentionPolicies { + if policy.ID == "" || policy.TenantID == "" { + continue + } + checks, err := json.Marshal(policy.VerificationChecks) + if err != nil { + return fmt.Errorf("encode object retention checks: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO object_retention_policies ( + id, tenant_id, name, object_prefix, mode, retention_days, status, + verified_at, verification_hash, verification_checks, + verification_limitations, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13) + ON CONFLICT (id) DO UPDATE SET + status = EXCLUDED.status, + verified_at = EXCLUDED.verified_at, + verification_hash = EXCLUDED.verification_hash, + verification_checks = EXCLUDED.verification_checks, + verification_limitations = EXCLUDED.verification_limitations, + schema_version = EXCLUDED.schema_version + `, policy.ID, policy.TenantID, policy.Name, policy.ObjectPrefix, policy.Mode, policy.RetentionDays, policy.Status, nullableTime(policy.VerifiedAt), nullableString(policy.VerificationHash), checks, policy.VerificationLimitations, policy.SchemaVersion, nonZeroTime(policy.CreatedAt)); err != nil { + return fmt.Errorf("upsert object retention policy row: %w", err) + } + } + for _, manifest := range state.BackupManifests { + if manifest.ID == "" || manifest.TenantID == "" { + continue + } + counts, err := json.Marshal(manifest.ResourceCounts) + if err != nil { + return fmt.Errorf("encode backup manifest counts: %w", err) + } + checks, err := json.Marshal(manifest.ConsistencyChecks) + if err != nil { + return fmt.Errorf("encode backup manifest checks: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO backup_manifests ( + id, tenant_id, state_hash, resource_counts, consistency_checks, + limitations, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8) + ON CONFLICT (id) DO UPDATE SET + resource_counts = EXCLUDED.resource_counts, + consistency_checks = EXCLUDED.consistency_checks, + limitations = EXCLUDED.limitations, + schema_version = EXCLUDED.schema_version + `, manifest.ID, manifest.TenantID, manifest.StateHash, counts, checks, manifest.Limitations, manifest.SchemaVersion, nonZeroTime(manifest.CreatedAt)); err != nil { + return fmt.Errorf("upsert backup manifest row: %w", err) + } + } + for _, hold := range state.LegalHolds { + if hold.ID == "" || hold.TenantID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO legal_holds ( + id, tenant_id, scope_type, scope_id, reason, owner, released_at, + schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + ON CONFLICT (id) DO UPDATE SET + reason = EXCLUDED.reason, + owner = EXCLUDED.owner, + released_at = EXCLUDED.released_at, + schema_version = EXCLUDED.schema_version + `, hold.ID, hold.TenantID, hold.ScopeType, hold.ScopeID, hold.Reason, hold.Owner, nullableTime(hold.ReleasedAt), hold.SchemaVersion, nonZeroTime(hold.CreatedAt)); err != nil { + return fmt.Errorf("upsert legal hold row: %w", err) + } + } + for _, override := range state.RetentionOverrides { + if override.ID == "" || override.TenantID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO retention_overrides ( + id, tenant_id, scope_type, scope_id, retention_until, reason, + owner, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + ON CONFLICT (id) DO UPDATE SET + retention_until = EXCLUDED.retention_until, + reason = EXCLUDED.reason, + owner = EXCLUDED.owner, + schema_version = EXCLUDED.schema_version + `, override.ID, override.TenantID, override.ScopeType, override.ScopeID, override.RetentionUntil, override.Reason, override.Owner, override.SchemaVersion, nonZeroTime(override.CreatedAt)); err != nil { + return fmt.Errorf("upsert retention override row: %w", err) + } + } + for _, template := range state.QuestionnaireTemplates { + if template.ID == "" || template.TenantID == "" { + continue + } + questions, err := json.Marshal(template.Questions) + if err != nil { + return fmt.Errorf("encode questionnaire template questions: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO questionnaire_templates ( + id, tenant_id, name, version, questions, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7) + ON CONFLICT (id) DO UPDATE SET questions = EXCLUDED.questions, schema_version = EXCLUDED.schema_version + `, template.ID, template.TenantID, template.Name, template.Version, questions, template.SchemaVersion, nonZeroTime(template.CreatedAt)); err != nil { + return fmt.Errorf("upsert questionnaire template row: %w", err) + } + } + for _, pkg := range state.QuestionnairePackages { + if pkg.ID == "" || pkg.TenantID == "" { + continue + } + responses, err := json.Marshal(pkg.Responses) + if err != nil { + return fmt.Errorf("encode questionnaire package responses: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO questionnaire_packages ( + id, tenant_id, template_id, package_id, product_id, release_id, + responses, manifest_hash, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) + ON CONFLICT (id) DO UPDATE SET responses = EXCLUDED.responses, manifest_hash = EXCLUDED.manifest_hash, schema_version = EXCLUDED.schema_version + `, pkg.ID, pkg.TenantID, pkg.TemplateID, nullableString(pkg.PackageID), nullableString(pkg.ProductID), nullableString(pkg.ReleaseID), responses, pkg.ManifestHash, pkg.SchemaVersion, nonZeroTime(pkg.CreatedAt)); err != nil { + return fmt.Errorf("upsert questionnaire package row: %w", err) + } + } + for _, report := range state.PDFReports { + if report.ID == "" || report.TenantID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO pdf_report_packages ( + id, tenant_id, report_type, product_id, release_id, title, + payload_ref, payload_hash, payload_size, limitations, + schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) + ON CONFLICT (id) DO UPDATE SET + payload_ref = EXCLUDED.payload_ref, + payload_hash = EXCLUDED.payload_hash, + payload_size = EXCLUDED.payload_size, + limitations = EXCLUDED.limitations, + schema_version = EXCLUDED.schema_version + `, report.ID, report.TenantID, report.ReportType, nullableString(report.ProductID), nullableString(report.ReleaseID), report.Title, nullableString(report.PayloadRef), report.PayloadHash, report.PayloadSize, report.Limitations, report.SchemaVersion, nonZeroTime(report.CreatedAt)); err != nil { + return fmt.Errorf("upsert pdf report row: %w", err) + } + } + for _, report := range state.AnomalyReports { + if report.ID == "" || report.TenantID == "" { + continue + } + signals, err := json.Marshal(report.Signals) + if err != nil { + return fmt.Errorf("encode anomaly report signals: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO anomaly_reports ( + id, tenant_id, subject_type, subject_id, result, signals, + assumptions, limitations, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) + ON CONFLICT (id) DO UPDATE SET + result = EXCLUDED.result, + signals = EXCLUDED.signals, + assumptions = EXCLUDED.assumptions, + limitations = EXCLUDED.limitations, + schema_version = EXCLUDED.schema_version + `, report.ID, report.TenantID, report.SubjectType, report.SubjectID, report.Result, signals, report.Assumptions, report.Limitations, report.SchemaVersion, nonZeroTime(report.CreatedAt)); err != nil { + return fmt.Errorf("upsert anomaly report row: %w", err) + } + } + return nil +} + func syncIdentityAndIdempotency(ctx context.Context, tx pgx.Tx, state app.PersistedState) error { for _, tenant := range state.Tenants { if tenant.ID == "" { diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index e9db582..1596e94 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -116,6 +116,51 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { Verifications: map[string]domain.VerificationResult{ "verify_test": {ID: "verify_test", TenantID: "ten_test", SubjectType: "release_bundle", SubjectID: "bundle_test", Result: "pass", Checks: []domain.VerifyCheck{{Name: "signature", Result: "passed"}}, VerifiedAt: time.Now().UTC()}, }, + RedactionProfiles: map[string]domain.RedactionProfile{ + "redact_test": {ID: "redact_test", TenantID: "ten_test", Name: "Default", Description: "profile", AllowedTypes: []string{"sbom"}, ExcludedFields: []string{"metadata.secret"}, SchemaVersion: domain.RedactionProfileSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + CustomerPackages: map[string]domain.CustomerSecurityPackage{ + "pkg_test": {ID: "pkg_test", TenantID: "ten_test", ProductID: "prod_test", ReleaseID: "rel_test", RedactionProfileID: "redact_test", Title: "Package", State: "generated", Manifest: map[string]any{"release_id": "rel_test"}, ManifestHash: "sha256:" + strings.Repeat("2", 64), ExpiresAt: time.Now().UTC().Add(24 * time.Hour), AccessCount: 3, SchemaVersion: domain.CustomerPackageSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + HTMLReports: map[string]domain.HTMLReportPackage{ + "html_test": {ID: "html_test", TenantID: "ten_test", ReportType: "cra_readiness", ProductID: "prod_test", ReleaseID: "rel_test", HTML: "", Hash: "sha256:" + strings.Repeat("3", 64), SchemaVersion: "html-report-package.v1.0.0", CreatedAt: time.Now().UTC()}, + }, + ReportTemplates: map[string]domain.CustomReportTemplate{ + "tpl_test": {ID: "tpl_test", TenantID: "ten_test", Name: "report", Version: "1", ReportType: "custom", AllowedFields: []string{"id"}, Template: "{{id}}", SchemaVersion: domain.ReportTemplateSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + RenderedReports: map[string]domain.RenderedCustomReport{ + "render_test": {ID: "render_test", TenantID: "ten_test", TemplateID: "tpl_test", SubjectType: "release", SubjectID: "rel_test", Output: map[string]any{"id": "rel_test"}, Hash: "sha256:" + strings.Repeat("4", 64), SchemaVersion: "rendered-report.v1.0.0", CreatedAt: time.Now().UTC()}, + }, + EvidenceBundles: map[string]domain.EvidenceBundle{ + "eb_test": {ID: "eb_test", TenantID: "ten_test", ReleaseID: "rel_test", EvidenceIDs: []string{"ev_test"}, Manifest: map[string]any{"evidence_ids": []any{"ev_test"}}, ManifestHash: "sha256:" + strings.Repeat("5", 64), SignatureRefs: []string{"sig_test"}, VerificationText: "verify", SchemaVersion: domain.EvidenceBundleSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + BundleImports: map[string]domain.EvidenceBundleImport{ + "ebi_test": {ID: "ebi_test", TenantID: "ten_test", BundleHash: "sha256:" + strings.Repeat("5", 64), Result: "imported", ImportedCount: 1, SchemaVersion: domain.EvidenceBundleImportVersion, CreatedAt: time.Now().UTC()}, + }, + ObjectRetentionPolicies: map[string]domain.ObjectRetentionPolicy{ + "orp_test": {ID: "orp_test", TenantID: "ten_test", Name: "retain", ObjectPrefix: "tenants/ten_test/", Mode: "governance", RetentionDays: 30, Status: "verified", VerifiedAt: ptrTime(time.Now().UTC()), VerificationHash: "sha256:" + strings.Repeat("6", 64), VerificationChecks: []domain.VerifyCheck{{Name: "versioning", Result: "passed"}}, VerificationLimitations: []string{"test"}, SchemaVersion: domain.ObjectRetentionPolicyVersion, CreatedAt: time.Now().UTC()}, + }, + BackupManifests: map[string]domain.BackupManifest{ + "bak_test": {ID: "bak_test", TenantID: "ten_test", StateHash: "sha256:" + strings.Repeat("7", 64), ResourceCounts: map[string]int{"evidence": 1}, ConsistencyChecks: []domain.VerifyCheck{{Name: "chain", Result: "passed"}}, Limitations: []string{"objects separately backed up"}, SchemaVersion: domain.BackupManifestSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + LegalHolds: map[string]domain.LegalHold{ + "hold_test": {ID: "hold_test", TenantID: "ten_test", ScopeType: "release", ScopeID: "rel_test", Reason: "review", Owner: "security", ReleasedAt: ptrTime(time.Now().UTC()), SchemaVersion: domain.LegalHoldSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + RetentionOverrides: map[string]domain.RetentionOverride{ + "ret_test": {ID: "ret_test", TenantID: "ten_test", ScopeType: "release", ScopeID: "rel_test", RetentionUntil: time.Now().UTC().Add(365 * 24 * time.Hour), Reason: "policy", Owner: "security", SchemaVersion: domain.RetentionOverrideSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + QuestionnaireTemplates: map[string]domain.QuestionnaireTemplate{ + "qt_test": {ID: "qt_test", TenantID: "ten_test", Name: "questionnaire", Version: "1", Questions: []domain.QuestionnaireQuestion{{ID: "q1", Prompt: "Evidence?", EvidenceType: "sbom"}}, SchemaVersion: domain.QuestionnaireTemplateVersion, CreatedAt: time.Now().UTC()}, + }, + QuestionnairePackages: map[string]domain.QuestionnairePackage{ + "qp_test": {ID: "qp_test", TenantID: "ten_test", TemplateID: "qt_test", PackageID: "pkg_test", ProductID: "prod_test", ReleaseID: "rel_test", Responses: []domain.QuestionnaireResponse{{QuestionID: "q1", Answer: "See evidence", EvidenceIDs: []string{"ev_test"}}}, ManifestHash: "sha256:" + strings.Repeat("8", 64), SchemaVersion: domain.QuestionnairePackageVersion, CreatedAt: time.Now().UTC()}, + }, + PDFReports: map[string]domain.PDFReportPackage{ + "pdf_test": {ID: "pdf_test", TenantID: "ten_test", ReportType: "cra_readiness", ProductID: "prod_test", ReleaseID: "rel_test", Title: "PDF", PayloadRef: "object://tenants/ten_test/reports/pdf", PayloadHash: "sha256:" + strings.Repeat("9", 64), PayloadSize: 10, Limitations: []string{"test"}, SchemaVersion: domain.PDFReportPackageVersion, CreatedAt: time.Now().UTC()}, + }, + AnomalyReports: map[string]domain.AnomalyReport{ + "anom_test": {ID: "anom_test", TenantID: "ten_test", SubjectType: "release", SubjectID: "rel_test", Result: "review", Signals: []domain.AnomalySignal{{Name: "gap", Severity: "medium", Detail: "test"}}, Assumptions: []string{"heuristic"}, Limitations: []string{"not ML"}, SchemaVersion: domain.AnomalyReportVersion, CreatedAt: time.Now().UTC()}, + }, Idempotency: map[string]app.IdempotencyRecord{ app.NewIdempotencyRecordKey("ten_test", "user:user_test", "POST", "/v1/products", "idem"): {RequestHash: "sha256:request", Status: 201, Response: map[string]any{"ok": true}, CreatedAt: time.Now().UTC()}, }, @@ -190,6 +235,21 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { {name: "policy", query: `SELECT count(*) FROM policy_evaluations WHERE tenant_id = 'ten_test' AND id = 'policy_test'`}, {name: "bundle", query: `SELECT count(*) FROM release_bundles WHERE tenant_id = 'ten_test' AND id = 'bundle_test'`}, {name: "verification", query: `SELECT count(*) FROM verification_results WHERE tenant_id = 'ten_test' AND id = 'verify_test'`}, + {name: "redaction profile", query: `SELECT count(*) FROM redaction_profiles WHERE tenant_id = 'ten_test' AND id = 'redact_test' AND allowed_types = ARRAY['sbom']`}, + {name: "customer package", query: `SELECT count(*) FROM customer_security_packages WHERE tenant_id = 'ten_test' AND id = 'pkg_test' AND access_count = 3`}, + {name: "html report", query: `SELECT count(*) FROM html_report_packages WHERE tenant_id = 'ten_test' AND id = 'html_test'`}, + {name: "report template", query: `SELECT count(*) FROM report_templates WHERE tenant_id = 'ten_test' AND id = 'tpl_test'`}, + {name: "rendered report", query: `SELECT count(*) FROM rendered_reports WHERE tenant_id = 'ten_test' AND id = 'render_test'`}, + {name: "evidence bundle", query: `SELECT count(*) FROM evidence_bundles WHERE tenant_id = 'ten_test' AND id = 'eb_test'`}, + {name: "evidence bundle import", query: `SELECT count(*) FROM evidence_bundle_imports WHERE tenant_id = 'ten_test' AND id = 'ebi_test'`}, + {name: "object retention", query: `SELECT count(*) FROM object_retention_policies WHERE tenant_id = 'ten_test' AND id = 'orp_test' AND verification_checks <> '[]'::jsonb`}, + {name: "backup manifest", query: `SELECT count(*) FROM backup_manifests WHERE tenant_id = 'ten_test' AND id = 'bak_test'`}, + {name: "legal hold", query: `SELECT count(*) FROM legal_holds WHERE tenant_id = 'ten_test' AND id = 'hold_test' AND released_at IS NOT NULL`}, + {name: "retention override", query: `SELECT count(*) FROM retention_overrides WHERE tenant_id = 'ten_test' AND id = 'ret_test'`}, + {name: "questionnaire template", query: `SELECT count(*) FROM questionnaire_templates WHERE tenant_id = 'ten_test' AND id = 'qt_test'`}, + {name: "questionnaire package", query: `SELECT count(*) FROM questionnaire_packages WHERE tenant_id = 'ten_test' AND id = 'qp_test'`}, + {name: "pdf report", query: `SELECT count(*) FROM pdf_report_packages WHERE tenant_id = 'ten_test' AND id = 'pdf_test'`}, + {name: "anomaly report", query: `SELECT count(*) FROM anomaly_reports WHERE tenant_id = 'ten_test' AND id = 'anom_test'`}, } for _, check := range coreChecks { var rows int diff --git a/migrations/20260528001500_package_retention_relational_columns.down.sql b/migrations/20260528001500_package_retention_relational_columns.down.sql new file mode 100644 index 0000000..9e3fe06 --- /dev/null +++ b/migrations/20260528001500_package_retention_relational_columns.down.sql @@ -0,0 +1,6 @@ +ALTER TABLE object_retention_policies + DROP COLUMN IF EXISTS verification_limitations, + DROP COLUMN IF EXISTS verification_checks; + +ALTER TABLE legal_holds + DROP COLUMN IF EXISTS released_at; diff --git a/migrations/20260528001500_package_retention_relational_columns.up.sql b/migrations/20260528001500_package_retention_relational_columns.up.sql new file mode 100644 index 0000000..0899cf1 --- /dev/null +++ b/migrations/20260528001500_package_retention_relational_columns.up.sql @@ -0,0 +1,6 @@ +ALTER TABLE legal_holds + ADD COLUMN IF NOT EXISTS released_at timestamptz; + +ALTER TABLE object_retention_policies + ADD COLUMN IF NOT EXISTS verification_checks jsonb NOT NULL DEFAULT '[]'::jsonb, + ADD COLUMN IF NOT EXISTS verification_limitations text[] NOT NULL DEFAULT '{}'; From 28c6337e5d7136855aac838161ff7e735e81d2fc Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 20:36:40 +0300 Subject: [PATCH 091/287] feat: load package retention rows relationally --- .implementation_increments.md | 2 +- docs/architecture.md | 2 +- docs/reference/production-readiness.md | 7 +- internal/adapters/postgres/store.go | 385 +++++++++++++++++++++-- internal/adapters/postgres/store_test.go | 21 ++ 5 files changed, 391 insertions(+), 26 deletions(-) diff --git a/.implementation_increments.md b/.implementation_increments.md index 99e5d96..a776809 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -36,7 +36,7 @@ Status legend: ## Remaining Core Product Increments 6. `[x]` Relational Store Split - Added migration-backed relational tables and tenant-scoped resource projection rows for implemented resources, with transactional PostgreSQL saves, relational identity/idempotency/customer-portal-token rows, relational release-ledger core rows, relational package/report/retention rows, missing-snapshot fallback loading for identity and release-ledger families, tenant/release indexes, persisted idempotency state, and outbox row locking. Canonical runtime loading still prefers the versioned ledger snapshot while per-resource repository tuning remains future hardening. + Added migration-backed relational tables and tenant-scoped resource projection rows for implemented resources, with transactional PostgreSQL saves, relational identity/idempotency/customer-portal-token rows, relational release-ledger core rows, relational package/report/retention rows, missing-snapshot fallback loading for identity, release-ledger, package, report, and retention families, tenant/release indexes, persisted idempotency state, and outbox row locking. Canonical runtime loading still prefers the versioned ledger snapshot while per-resource repository tuning remains future hardening. 7. `[x]` Evidence Search, Filtering, And Timeline Querying Added tenant-scoped evidence search by product, project, release, build, deployment, type, subtype, source, collector, created time, subject refs, tags, and verification status. diff --git a/docs/architecture.md b/docs/architecture.md index 14b51e9..bb93d35 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -10,7 +10,7 @@ Evydence follows a ports-and-adapters shape: - `internal/adapters/objectstore/s3` stores the same tenant-prefixed object keys in S3/MinIO-compatible buckets. - `cmd/*` contains process entry points. -Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity, idempotency, and customer portal token records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. Package, report, retention, and backup records are synchronized into their migration-backed relational tables. If the snapshot row is absent, the Postgres store can rebuild identity, customer portal token, and release-ledger core families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. +Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity, idempotency, and customer portal token records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. Package, report, retention, and backup records are synchronized into their migration-backed relational tables. If the snapshot row is absent, the Postgres store can rebuild identity, customer portal token, release-ledger core, package, report, and retention families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. ## Tenant And Auth Boundaries diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 7dfe151..10297fc 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -20,8 +20,8 @@ Known hardening work remains: audit-chain, signing, bundle, policy, verification, package, report, and retention rows alongside the canonical snapshot, but the snapshot remains the preferred runtime load source. If the snapshot row is absent, the store can - rebuild identity, customer portal token, and release-ledger core state from - relational rows; + rebuild identity, customer portal token, release-ledger core, package, + report, and retention state from relational rows; - worker parser jobs re-read raw object-store payloads for key formats, verify digests, validate durable state, and persist missing parser-derived normalized fields. Upload paths still create initial accepted records, so @@ -103,7 +103,8 @@ implemented capabilities: customer portal token, release-ledger core, audit-chain, signing, bundle, policy, verification, package, report, and retention rows are synchronized into relational tables. Missing-snapshot recovery can rebuild identity, - customer portal token, and release-ledger core families from relational rows. + customer portal token, release-ledger core, package, report, and retention + families from relational rows. Keep snapshots only for export/import and upgrade compatibility after the remaining families have repository-backed reads and writes. - Split the large application ledger aggregate into focused services or diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index 3bdba3d..cfc9f3e 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -78,6 +78,9 @@ func (s *Store) loadRelationalState(ctx context.Context) (app.PersistedState, bo if err := s.loadRelationalReleaseCore(ctx, &state, &loaded); err != nil { return app.PersistedState{}, false, err } + if err := s.loadRelationalPackageReportRetention(ctx, &state, &loaded); err != nil { + return app.PersistedState{}, false, err + } if err := s.loadRelationalIdempotency(ctx, &state, &loaded); err != nil { return app.PersistedState{}, false, err } @@ -86,27 +89,42 @@ func (s *Store) loadRelationalState(ctx context.Context) (app.PersistedState, bo func relationalEmptyState() app.PersistedState { return app.PersistedState{ - Tenants: map[string]domain.Tenant{}, - APIKeys: map[string]domain.APIKey{}, - APIKeyHashes: map[string]string{}, - CustomerPortalAccess: map[string]domain.CustomerPortalAccess{}, - CustomerPortalHashes: map[string]string{}, - Products: map[string]domain.Product{}, - Projects: map[string]domain.Project{}, - Releases: map[string]domain.Release{}, - Artifacts: map[string]domain.Artifact{}, - Evidence: map[string]domain.EvidenceItem{}, - SBOMs: map[string]domain.SBOM{}, - Scans: map[string]domain.VulnerabilityScan{}, - Contracts: map[string]domain.OpenAPIContract{}, - Policies: map[string]domain.PolicyEvaluation{}, - Bundles: map[string]domain.ReleaseBundle{}, - SigningKeys: map[string]domain.SigningKey{}, - SigningKeyPrivate: map[string][]byte{}, - Signatures: map[string]domain.Signature{}, - Verifications: map[string]domain.VerificationResult{}, - Chain: map[string][]domain.AuditChainEntry{}, - Idempotency: map[string]app.IdempotencyRecord{}, + Tenants: map[string]domain.Tenant{}, + APIKeys: map[string]domain.APIKey{}, + APIKeyHashes: map[string]string{}, + CustomerPortalAccess: map[string]domain.CustomerPortalAccess{}, + CustomerPortalHashes: map[string]string{}, + RedactionProfiles: map[string]domain.RedactionProfile{}, + CustomerPackages: map[string]domain.CustomerSecurityPackage{}, + HTMLReports: map[string]domain.HTMLReportPackage{}, + ReportTemplates: map[string]domain.CustomReportTemplate{}, + RenderedReports: map[string]domain.RenderedCustomReport{}, + EvidenceBundles: map[string]domain.EvidenceBundle{}, + BundleImports: map[string]domain.EvidenceBundleImport{}, + ObjectRetentionPolicies: map[string]domain.ObjectRetentionPolicy{}, + BackupManifests: map[string]domain.BackupManifest{}, + LegalHolds: map[string]domain.LegalHold{}, + RetentionOverrides: map[string]domain.RetentionOverride{}, + QuestionnaireTemplates: map[string]domain.QuestionnaireTemplate{}, + QuestionnairePackages: map[string]domain.QuestionnairePackage{}, + PDFReports: map[string]domain.PDFReportPackage{}, + AnomalyReports: map[string]domain.AnomalyReport{}, + Products: map[string]domain.Product{}, + Projects: map[string]domain.Project{}, + Releases: map[string]domain.Release{}, + Artifacts: map[string]domain.Artifact{}, + Evidence: map[string]domain.EvidenceItem{}, + SBOMs: map[string]domain.SBOM{}, + Scans: map[string]domain.VulnerabilityScan{}, + Contracts: map[string]domain.OpenAPIContract{}, + Policies: map[string]domain.PolicyEvaluation{}, + Bundles: map[string]domain.ReleaseBundle{}, + SigningKeys: map[string]domain.SigningKey{}, + SigningKeyPrivate: map[string][]byte{}, + Signatures: map[string]domain.Signature{}, + Verifications: map[string]domain.VerificationResult{}, + Chain: map[string][]domain.AuditChainEntry{}, + Idempotency: map[string]app.IdempotencyRecord{}, } } @@ -610,6 +628,331 @@ func (s *Store) loadRelationalVerifications(ctx context.Context, state *app.Pers return rows.Err() } +func (s *Store) loadRelationalPackageReportRetention(ctx context.Context, state *app.PersistedState, loaded *bool) error { + if err := s.loadRelationalPackages(ctx, state, loaded); err != nil { + return err + } + if err := s.loadRelationalReports(ctx, state, loaded); err != nil { + return err + } + if err := s.loadRelationalRetention(ctx, state, loaded); err != nil { + return err + } + return nil +} + +func (s *Store) loadRelationalPackages(ctx context.Context, state *app.PersistedState, loaded *bool) error { + profileRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, name, description, allowed_types, excluded_fields, schema_version, created_at FROM redaction_profiles`) + if err != nil { + return fmt.Errorf("load relational redaction profiles: %w", err) + } + defer profileRows.Close() + for profileRows.Next() { + var profile domain.RedactionProfile + var description sql.NullString + if err := profileRows.Scan(&profile.ID, &profile.TenantID, &profile.Name, &description, &profile.AllowedTypes, &profile.ExcludedFields, &profile.SchemaVersion, &profile.CreatedAt); err != nil { + return fmt.Errorf("scan relational redaction profile: %w", err) + } + profile.Description = nullableSQLString(description) + state.RedactionProfiles[profile.ID] = profile + *loaded = true + } + if err := profileRows.Err(); err != nil { + return err + } + + packageRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, product_id, release_id, redaction_profile_id, title, state, manifest, manifest_hash, expires_at, access_count, schema_version, created_at FROM customer_security_packages`) + if err != nil { + return fmt.Errorf("load relational customer packages: %w", err) + } + defer packageRows.Close() + for packageRows.Next() { + var pkg domain.CustomerSecurityPackage + var releaseID sql.NullString + var manifest []byte + if err := packageRows.Scan(&pkg.ID, &pkg.TenantID, &pkg.ProductID, &releaseID, &pkg.RedactionProfileID, &pkg.Title, &pkg.State, &manifest, &pkg.ManifestHash, &pkg.ExpiresAt, &pkg.AccessCount, &pkg.SchemaVersion, &pkg.CreatedAt); err != nil { + return fmt.Errorf("scan relational customer package: %w", err) + } + pkg.ReleaseID = nullableSQLString(releaseID) + if err := decodeJSON(manifest, &pkg.Manifest); err != nil { + return fmt.Errorf("decode relational customer package manifest: %w", err) + } + state.CustomerPackages[pkg.ID] = pkg + *loaded = true + } + if err := packageRows.Err(); err != nil { + return err + } + + bundleRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, release_id, evidence_ids, manifest, manifest_hash, signature_refs, verification_text, schema_version, created_at FROM evidence_bundles`) + if err != nil { + return fmt.Errorf("load relational evidence bundles: %w", err) + } + defer bundleRows.Close() + for bundleRows.Next() { + var bundle domain.EvidenceBundle + var releaseID sql.NullString + var manifest []byte + if err := bundleRows.Scan(&bundle.ID, &bundle.TenantID, &releaseID, &bundle.EvidenceIDs, &manifest, &bundle.ManifestHash, &bundle.SignatureRefs, &bundle.VerificationText, &bundle.SchemaVersion, &bundle.CreatedAt); err != nil { + return fmt.Errorf("scan relational evidence bundle: %w", err) + } + bundle.ReleaseID = nullableSQLString(releaseID) + if err := decodeJSON(manifest, &bundle.Manifest); err != nil { + return fmt.Errorf("decode relational evidence bundle manifest: %w", err) + } + state.EvidenceBundles[bundle.ID] = bundle + *loaded = true + } + if err := bundleRows.Err(); err != nil { + return err + } + + importRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, bundle_hash, result, imported_count, schema_version, created_at FROM evidence_bundle_imports`) + if err != nil { + return fmt.Errorf("load relational evidence bundle imports: %w", err) + } + defer importRows.Close() + for importRows.Next() { + var imported domain.EvidenceBundleImport + if err := importRows.Scan(&imported.ID, &imported.TenantID, &imported.BundleHash, &imported.Result, &imported.ImportedCount, &imported.SchemaVersion, &imported.CreatedAt); err != nil { + return fmt.Errorf("scan relational evidence bundle import: %w", err) + } + state.BundleImports[imported.ID] = imported + *loaded = true + } + return importRows.Err() +} + +func (s *Store) loadRelationalReports(ctx context.Context, state *app.PersistedState, loaded *bool) error { + htmlRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, report_type, product_id, release_id, html, hash, schema_version, created_at FROM html_report_packages`) + if err != nil { + return fmt.Errorf("load relational html reports: %w", err) + } + defer htmlRows.Close() + for htmlRows.Next() { + var report domain.HTMLReportPackage + var releaseID sql.NullString + if err := htmlRows.Scan(&report.ID, &report.TenantID, &report.ReportType, &report.ProductID, &releaseID, &report.HTML, &report.Hash, &report.SchemaVersion, &report.CreatedAt); err != nil { + return fmt.Errorf("scan relational html report: %w", err) + } + report.ReleaseID = nullableSQLString(releaseID) + state.HTMLReports[report.ID] = report + *loaded = true + } + if err := htmlRows.Err(); err != nil { + return err + } + + templateRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, name, version, report_type, allowed_fields, template, schema_version, created_at FROM report_templates`) + if err != nil { + return fmt.Errorf("load relational report templates: %w", err) + } + defer templateRows.Close() + for templateRows.Next() { + var template domain.CustomReportTemplate + if err := templateRows.Scan(&template.ID, &template.TenantID, &template.Name, &template.Version, &template.ReportType, &template.AllowedFields, &template.Template, &template.SchemaVersion, &template.CreatedAt); err != nil { + return fmt.Errorf("scan relational report template: %w", err) + } + state.ReportTemplates[template.ID] = template + *loaded = true + } + if err := templateRows.Err(); err != nil { + return err + } + + renderRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, template_id, subject_type, subject_id, output, hash, schema_version, created_at FROM rendered_reports`) + if err != nil { + return fmt.Errorf("load relational rendered reports: %w", err) + } + defer renderRows.Close() + for renderRows.Next() { + var report domain.RenderedCustomReport + var output []byte + if err := renderRows.Scan(&report.ID, &report.TenantID, &report.TemplateID, &report.SubjectType, &report.SubjectID, &output, &report.Hash, &report.SchemaVersion, &report.CreatedAt); err != nil { + return fmt.Errorf("scan relational rendered report: %w", err) + } + if err := decodeJSON(output, &report.Output); err != nil { + return fmt.Errorf("decode relational rendered report output: %w", err) + } + state.RenderedReports[report.ID] = report + *loaded = true + } + if err := renderRows.Err(); err != nil { + return err + } + + pdfRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, report_type, product_id, release_id, title, payload_ref, payload_hash, payload_size, limitations, schema_version, created_at FROM pdf_report_packages`) + if err != nil { + return fmt.Errorf("load relational pdf reports: %w", err) + } + defer pdfRows.Close() + for pdfRows.Next() { + var report domain.PDFReportPackage + var productID, releaseID, payloadRef sql.NullString + if err := pdfRows.Scan(&report.ID, &report.TenantID, &report.ReportType, &productID, &releaseID, &report.Title, &payloadRef, &report.PayloadHash, &report.PayloadSize, &report.Limitations, &report.SchemaVersion, &report.CreatedAt); err != nil { + return fmt.Errorf("scan relational pdf report: %w", err) + } + report.ProductID = nullableSQLString(productID) + report.ReleaseID = nullableSQLString(releaseID) + report.PayloadRef = nullableSQLString(payloadRef) + state.PDFReports[report.ID] = report + *loaded = true + } + if err := pdfRows.Err(); err != nil { + return err + } + + anomalyRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, subject_type, subject_id, result, signals, assumptions, limitations, schema_version, created_at FROM anomaly_reports`) + if err != nil { + return fmt.Errorf("load relational anomaly reports: %w", err) + } + defer anomalyRows.Close() + for anomalyRows.Next() { + var report domain.AnomalyReport + var signals []byte + if err := anomalyRows.Scan(&report.ID, &report.TenantID, &report.SubjectType, &report.SubjectID, &report.Result, &signals, &report.Assumptions, &report.Limitations, &report.SchemaVersion, &report.CreatedAt); err != nil { + return fmt.Errorf("scan relational anomaly report: %w", err) + } + if err := decodeJSON(signals, &report.Signals); err != nil { + return fmt.Errorf("decode relational anomaly report signals: %w", err) + } + state.AnomalyReports[report.ID] = report + *loaded = true + } + return anomalyRows.Err() +} + +func (s *Store) loadRelationalRetention(ctx context.Context, state *app.PersistedState, loaded *bool) error { + policyRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, name, object_prefix, mode, retention_days, status, verified_at, verification_hash, verification_checks, verification_limitations, schema_version, created_at FROM object_retention_policies`) + if err != nil { + return fmt.Errorf("load relational object retention policies: %w", err) + } + defer policyRows.Close() + for policyRows.Next() { + var policy domain.ObjectRetentionPolicy + var verifiedAt sql.NullTime + var verificationHash sql.NullString + var checks []byte + if err := policyRows.Scan(&policy.ID, &policy.TenantID, &policy.Name, &policy.ObjectPrefix, &policy.Mode, &policy.RetentionDays, &policy.Status, &verifiedAt, &verificationHash, &checks, &policy.VerificationLimitations, &policy.SchemaVersion, &policy.CreatedAt); err != nil { + return fmt.Errorf("scan relational object retention policy: %w", err) + } + policy.VerifiedAt = nullableSQLTime(verifiedAt) + policy.VerificationHash = nullableSQLString(verificationHash) + if err := decodeJSON(checks, &policy.VerificationChecks); err != nil { + return fmt.Errorf("decode relational object retention checks: %w", err) + } + state.ObjectRetentionPolicies[policy.ID] = policy + *loaded = true + } + if err := policyRows.Err(); err != nil { + return err + } + + backupRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, state_hash, resource_counts, consistency_checks, limitations, schema_version, created_at FROM backup_manifests`) + if err != nil { + return fmt.Errorf("load relational backup manifests: %w", err) + } + defer backupRows.Close() + for backupRows.Next() { + var manifest domain.BackupManifest + var counts, checks []byte + if err := backupRows.Scan(&manifest.ID, &manifest.TenantID, &manifest.StateHash, &counts, &checks, &manifest.Limitations, &manifest.SchemaVersion, &manifest.CreatedAt); err != nil { + return fmt.Errorf("scan relational backup manifest: %w", err) + } + if err := decodeJSON(counts, &manifest.ResourceCounts); err != nil { + return fmt.Errorf("decode relational backup manifest counts: %w", err) + } + if err := decodeJSON(checks, &manifest.ConsistencyChecks); err != nil { + return fmt.Errorf("decode relational backup manifest checks: %w", err) + } + state.BackupManifests[manifest.ID] = manifest + *loaded = true + } + if err := backupRows.Err(); err != nil { + return err + } + + holdRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, scope_type, scope_id, reason, owner, released_at, schema_version, created_at FROM legal_holds`) + if err != nil { + return fmt.Errorf("load relational legal holds: %w", err) + } + defer holdRows.Close() + for holdRows.Next() { + var hold domain.LegalHold + var releasedAt sql.NullTime + if err := holdRows.Scan(&hold.ID, &hold.TenantID, &hold.ScopeType, &hold.ScopeID, &hold.Reason, &hold.Owner, &releasedAt, &hold.SchemaVersion, &hold.CreatedAt); err != nil { + return fmt.Errorf("scan relational legal hold: %w", err) + } + hold.ReleasedAt = nullableSQLTime(releasedAt) + state.LegalHolds[hold.ID] = hold + *loaded = true + } + if err := holdRows.Err(); err != nil { + return err + } + + overrideRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, scope_type, scope_id, retention_until, reason, owner, schema_version, created_at FROM retention_overrides`) + if err != nil { + return fmt.Errorf("load relational retention overrides: %w", err) + } + defer overrideRows.Close() + for overrideRows.Next() { + var override domain.RetentionOverride + if err := overrideRows.Scan(&override.ID, &override.TenantID, &override.ScopeType, &override.ScopeID, &override.RetentionUntil, &override.Reason, &override.Owner, &override.SchemaVersion, &override.CreatedAt); err != nil { + return fmt.Errorf("scan relational retention override: %w", err) + } + state.RetentionOverrides[override.ID] = override + *loaded = true + } + if err := overrideRows.Err(); err != nil { + return err + } + + questionRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, name, version, questions, schema_version, created_at FROM questionnaire_templates`) + if err != nil { + return fmt.Errorf("load relational questionnaire templates: %w", err) + } + defer questionRows.Close() + for questionRows.Next() { + var template domain.QuestionnaireTemplate + var questions []byte + if err := questionRows.Scan(&template.ID, &template.TenantID, &template.Name, &template.Version, &questions, &template.SchemaVersion, &template.CreatedAt); err != nil { + return fmt.Errorf("scan relational questionnaire template: %w", err) + } + if err := decodeJSON(questions, &template.Questions); err != nil { + return fmt.Errorf("decode relational questionnaire questions: %w", err) + } + state.QuestionnaireTemplates[template.ID] = template + *loaded = true + } + if err := questionRows.Err(); err != nil { + return err + } + + qpRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, template_id, package_id, product_id, release_id, responses, manifest_hash, schema_version, created_at FROM questionnaire_packages`) + if err != nil { + return fmt.Errorf("load relational questionnaire packages: %w", err) + } + defer qpRows.Close() + for qpRows.Next() { + var pkg domain.QuestionnairePackage + var packageID, productID, releaseID sql.NullString + var responses []byte + if err := qpRows.Scan(&pkg.ID, &pkg.TenantID, &pkg.TemplateID, &packageID, &productID, &releaseID, &responses, &pkg.ManifestHash, &pkg.SchemaVersion, &pkg.CreatedAt); err != nil { + return fmt.Errorf("scan relational questionnaire package: %w", err) + } + pkg.PackageID = nullableSQLString(packageID) + pkg.ProductID = nullableSQLString(productID) + pkg.ReleaseID = nullableSQLString(releaseID) + if err := decodeJSON(responses, &pkg.Responses); err != nil { + return fmt.Errorf("decode relational questionnaire responses: %w", err) + } + state.QuestionnairePackages[pkg.ID] = pkg + *loaded = true + } + return qpRows.Err() +} + func (s *Store) loadRelationalIdempotency(ctx context.Context, state *app.PersistedState, loaded *bool) error { rows, err := s.pool.Query(ctx, `SELECT tenant_id, actor_key_id, method, path, idempotency_key, request_hash, status, response, created_at FROM idempotency_records`) if err != nil { diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index 1596e94..c5b184b 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -291,6 +291,27 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { if relational.CustomerPortalHashes["cpa_test"] != "portal-token-hash" || relational.CustomerPortalAccess["cpa_test"].FailedAccessCount != 1 { t.Fatalf("relational portal access = %#v hash=%q", relational.CustomerPortalAccess["cpa_test"], relational.CustomerPortalHashes["cpa_test"]) } + if relational.RedactionProfiles["redact_test"].Name != "Default" || relational.CustomerPackages["pkg_test"].AccessCount != 3 { + t.Fatalf("relational package rows missing: redaction=%#v package=%#v", relational.RedactionProfiles["redact_test"], relational.CustomerPackages["pkg_test"]) + } + if relational.HTMLReports["html_test"].Hash == "" || relational.ReportTemplates["tpl_test"].Template == "" || relational.RenderedReports["render_test"].Hash == "" { + t.Fatalf("relational report rows missing: html=%#v template=%#v rendered=%#v", relational.HTMLReports["html_test"], relational.ReportTemplates["tpl_test"], relational.RenderedReports["render_test"]) + } + if relational.EvidenceBundles["eb_test"].ManifestHash == "" || relational.BundleImports["ebi_test"].ImportedCount != 1 { + t.Fatalf("relational evidence bundle rows missing: bundle=%#v import=%#v", relational.EvidenceBundles["eb_test"], relational.BundleImports["ebi_test"]) + } + if relational.ObjectRetentionPolicies["orp_test"].Status != "verified" || len(relational.ObjectRetentionPolicies["orp_test"].VerificationChecks) != 1 { + t.Fatalf("relational object retention policy = %#v", relational.ObjectRetentionPolicies["orp_test"]) + } + if relational.BackupManifests["bak_test"].ResourceCounts["evidence"] != 1 || relational.LegalHolds["hold_test"].ReleasedAt == nil || relational.RetentionOverrides["ret_test"].Owner != "security" { + t.Fatalf("relational retention rows missing: backup=%#v hold=%#v override=%#v", relational.BackupManifests["bak_test"], relational.LegalHolds["hold_test"], relational.RetentionOverrides["ret_test"]) + } + if len(relational.QuestionnaireTemplates["qt_test"].Questions) != 1 || len(relational.QuestionnairePackages["qp_test"].Responses) != 1 { + t.Fatalf("relational questionnaire rows missing: template=%#v package=%#v", relational.QuestionnaireTemplates["qt_test"], relational.QuestionnairePackages["qp_test"]) + } + if relational.PDFReports["pdf_test"].PayloadHash == "" || relational.AnomalyReports["anom_test"].Result != "review" { + t.Fatalf("relational generated report rows missing: pdf=%#v anomaly=%#v", relational.PDFReports["pdf_test"], relational.AnomalyReports["anom_test"]) + } job := app.OutboxJob{ID: "job_test_" + time.Now().Format("150405.000000000"), TenantID: "ten_test", Kind: "verify_subject", SubjectType: "audit_chain", SubjectID: "audit_chain", CreatedAt: time.Now().UTC()} if err := store.Enqueue(ctx, job); err != nil { t.Fatal(err) From 6e6c590480358a40f3848ffdf1b8e6f9756f6084 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 20:37:42 +0300 Subject: [PATCH 092/287] feat: recover identity rows relationally --- .implementation_increments.md | 2 +- docs/architecture.md | 2 +- docs/reference/production-readiness.md | 8 +- internal/adapters/postgres/store.go | 168 +++++++++++++++++++++++ internal/adapters/postgres/store_test.go | 9 ++ 5 files changed, 183 insertions(+), 6 deletions(-) diff --git a/.implementation_increments.md b/.implementation_increments.md index a776809..0aa4e14 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -36,7 +36,7 @@ Status legend: ## Remaining Core Product Increments 6. `[x]` Relational Store Split - Added migration-backed relational tables and tenant-scoped resource projection rows for implemented resources, with transactional PostgreSQL saves, relational identity/idempotency/customer-portal-token rows, relational release-ledger core rows, relational package/report/retention rows, missing-snapshot fallback loading for identity, release-ledger, package, report, and retention families, tenant/release indexes, persisted idempotency state, and outbox row locking. Canonical runtime loading still prefers the versioned ledger snapshot while per-resource repository tuning remains future hardening. + Added migration-backed relational tables and tenant-scoped resource projection rows for implemented resources, with transactional PostgreSQL saves, relational identity/idempotency/customer-portal-token rows, relational release-ledger core rows, relational package/report/retention rows, missing-snapshot fallback loading for identity, SSO session, release-ledger, package, report, and retention families, tenant/release indexes, persisted idempotency state, and outbox row locking. Canonical runtime loading still prefers the versioned ledger snapshot while per-resource repository tuning remains future hardening. 7. `[x]` Evidence Search, Filtering, And Timeline Querying Added tenant-scoped evidence search by product, project, release, build, deployment, type, subtype, source, collector, created time, subject refs, tags, and verification status. diff --git a/docs/architecture.md b/docs/architecture.md index bb93d35..741e05e 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -10,7 +10,7 @@ Evydence follows a ports-and-adapters shape: - `internal/adapters/objectstore/s3` stores the same tenant-prefixed object keys in S3/MinIO-compatible buckets. - `cmd/*` contains process entry points. -Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity, idempotency, and customer portal token records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. Package, report, retention, and backup records are synchronized into their migration-backed relational tables. If the snapshot row is absent, the Postgres store can rebuild identity, customer portal token, release-ledger core, package, report, and retention families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. +Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity, idempotency, and customer portal token records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. Package, report, retention, and backup records are synchronized into their migration-backed relational tables. If the snapshot row is absent, the Postgres store can rebuild identity, SSO session, customer portal token, release-ledger core, package, report, and retention families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. ## Tenant And Auth Boundaries diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 10297fc..073f7d5 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -20,8 +20,8 @@ Known hardening work remains: audit-chain, signing, bundle, policy, verification, package, report, and retention rows alongside the canonical snapshot, but the snapshot remains the preferred runtime load source. If the snapshot row is absent, the store can - rebuild identity, customer portal token, release-ledger core, package, - report, and retention state from relational rows; + rebuild identity, SSO session, customer portal token, release-ledger core, + package, report, and retention state from relational rows; - worker parser jobs re-read raw object-store payloads for key formats, verify digests, validate durable state, and persist missing parser-derived normalized fields. Upload paths still create initial accepted records, so @@ -103,8 +103,8 @@ implemented capabilities: customer portal token, release-ledger core, audit-chain, signing, bundle, policy, verification, package, report, and retention rows are synchronized into relational tables. Missing-snapshot recovery can rebuild identity, - customer portal token, release-ledger core, package, report, and retention - families from relational rows. + SSO session, customer portal token, release-ledger core, package, report, + and retention families from relational rows. Keep snapshots only for export/import and upgrade compatibility after the remaining families have repository-backed reads and writes. - Split the large application ledger aggregate into focused services or diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index cfc9f3e..f36929d 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -69,6 +69,9 @@ func (s *Store) loadRelationalState(ctx context.Context) (app.PersistedState, bo if err := s.loadRelationalTenants(ctx, &state, &loaded); err != nil { return app.PersistedState{}, false, err } + if err := s.loadRelationalIdentity(ctx, &state, &loaded); err != nil { + return app.PersistedState{}, false, err + } if err := s.loadRelationalAPIKeys(ctx, &state, &loaded); err != nil { return app.PersistedState{}, false, err } @@ -90,6 +93,13 @@ func (s *Store) loadRelationalState(ctx context.Context) (app.PersistedState, bo func relationalEmptyState() app.PersistedState { return app.PersistedState{ Tenants: map[string]domain.Tenant{}, + Organizations: map[string]domain.Organization{}, + Users: map[string]domain.HumanUser{}, + RoleBindings: map[string]domain.RoleBinding{}, + SSOProviders: map[string]domain.SSOProvider{}, + IdentityLinks: map[string]domain.UserIdentityLink{}, + SSOSessions: map[string]domain.SSOSession{}, + SSOSessionHashes: map[string]string{}, APIKeys: map[string]domain.APIKey{}, APIKeyHashes: map[string]string{}, CustomerPortalAccess: map[string]domain.CustomerPortalAccess{}, @@ -145,6 +155,164 @@ func (s *Store) loadRelationalTenants(ctx context.Context, state *app.PersistedS return rows.Err() } +func (s *Store) loadRelationalIdentity(ctx context.Context, state *app.PersistedState, loaded *bool) error { + if err := s.loadRelationalOrganizations(ctx, state, loaded); err != nil { + return err + } + if err := s.loadRelationalUsers(ctx, state, loaded); err != nil { + return err + } + if err := s.loadRelationalRoleBindings(ctx, state, loaded); err != nil { + return err + } + if err := s.loadRelationalSSOProviders(ctx, state, loaded); err != nil { + return err + } + if err := s.loadRelationalIdentityLinks(ctx, state, loaded); err != nil { + return err + } + if err := s.loadRelationalSSOSessions(ctx, state, loaded); err != nil { + return err + } + return nil +} + +func (s *Store) loadRelationalOrganizations(ctx context.Context, state *app.PersistedState, loaded *bool) error { + rows, err := s.pool.Query(ctx, `SELECT id, tenant_id, name, slug, status, schema_version, created_at FROM organizations`) + if err != nil { + return fmt.Errorf("load relational organizations: %w", err) + } + defer rows.Close() + for rows.Next() { + var org domain.Organization + if err := rows.Scan(&org.ID, &org.TenantID, &org.Name, &org.Slug, &org.Status, &org.SchemaVersion, &org.CreatedAt); err != nil { + return fmt.Errorf("scan relational organization: %w", err) + } + state.Organizations[org.ID] = org + *loaded = true + } + return rows.Err() +} + +func (s *Store) loadRelationalUsers(ctx context.Context, state *app.PersistedState, loaded *bool) error { + rows, err := s.pool.Query(ctx, `SELECT id, tenant_id, organization_id, email, display_name, status, deactivated_at, schema_version, created_at FROM human_users`) + if err != nil { + return fmt.Errorf("load relational users: %w", err) + } + defer rows.Close() + for rows.Next() { + var user domain.HumanUser + var organizationID sql.NullString + var deactivatedAt sql.NullTime + if err := rows.Scan(&user.ID, &user.TenantID, &organizationID, &user.Email, &user.DisplayName, &user.Status, &deactivatedAt, &user.SchemaVersion, &user.CreatedAt); err != nil { + return fmt.Errorf("scan relational user: %w", err) + } + user.OrganizationID = nullableSQLString(organizationID) + user.DeactivatedAt = nullableSQLTime(deactivatedAt) + state.Users[user.ID] = user + *loaded = true + } + return rows.Err() +} + +func (s *Store) loadRelationalRoleBindings(ctx context.Context, state *app.PersistedState, loaded *bool) error { + rows, err := s.pool.Query(ctx, `SELECT id, tenant_id, subject_type, subject_id, role, resource_type, resource_id, schema_version, created_at FROM role_bindings`) + if err != nil { + return fmt.Errorf("load relational role bindings: %w", err) + } + defer rows.Close() + for rows.Next() { + var binding domain.RoleBinding + var resourceType, resourceID sql.NullString + if err := rows.Scan(&binding.ID, &binding.TenantID, &binding.SubjectType, &binding.SubjectID, &binding.Role, &resourceType, &resourceID, &binding.SchemaVersion, &binding.CreatedAt); err != nil { + return fmt.Errorf("scan relational role binding: %w", err) + } + binding.ResourceType = nullableSQLString(resourceType) + binding.ResourceID = nullableSQLString(resourceID) + state.RoleBindings[binding.ID] = binding + *loaded = true + } + return rows.Err() +} + +func (s *Store) loadRelationalSSOProviders(ctx context.Context, state *app.PersistedState, loaded *bool) error { + rows, err := s.pool.Query(ctx, ` + SELECT id, tenant_id, name, type, issuer, client_id, groups_claim, + role_mapping, status, schema_version, created_at, jwks, + saml_signing_certificates, trust_material_updated_at + FROM sso_providers + `) + if err != nil { + return fmt.Errorf("load relational sso providers: %w", err) + } + defer rows.Close() + for rows.Next() { + var provider domain.SSOProvider + var groupsClaim sql.NullString + var roleMapping, jwks, samlCerts []byte + var trustMaterialUpdatedAt sql.NullTime + if err := rows.Scan( + &provider.ID, &provider.TenantID, &provider.Name, &provider.Type, &provider.Issuer, &provider.ClientID, &groupsClaim, + &roleMapping, &provider.Status, &provider.SchemaVersion, &provider.CreatedAt, &jwks, + &samlCerts, &trustMaterialUpdatedAt, + ); err != nil { + return fmt.Errorf("scan relational sso provider: %w", err) + } + provider.GroupsClaim = nullableSQLString(groupsClaim) + provider.TrustMaterialUpdatedAt = nullableSQLTime(trustMaterialUpdatedAt) + if err := decodeJSON(roleMapping, &provider.RoleMapping); err != nil { + return fmt.Errorf("decode relational sso role mapping: %w", err) + } + if err := decodeJSON(jwks, &provider.JWKS); err != nil { + return fmt.Errorf("decode relational sso jwks: %w", err) + } + if err := decodeJSON(samlCerts, &provider.SAMLSigningCertificates); err != nil { + return fmt.Errorf("decode relational sso certificates: %w", err) + } + state.SSOProviders[provider.ID] = provider + *loaded = true + } + return rows.Err() +} + +func (s *Store) loadRelationalIdentityLinks(ctx context.Context, state *app.PersistedState, loaded *bool) error { + rows, err := s.pool.Query(ctx, `SELECT id, tenant_id, user_id, provider_id, subject, email, verified, schema_version, created_at FROM user_identity_links`) + if err != nil { + return fmt.Errorf("load relational identity links: %w", err) + } + defer rows.Close() + for rows.Next() { + var link domain.UserIdentityLink + if err := rows.Scan(&link.ID, &link.TenantID, &link.UserID, &link.ProviderID, &link.Subject, &link.Email, &link.Verified, &link.SchemaVersion, &link.CreatedAt); err != nil { + return fmt.Errorf("scan relational identity link: %w", err) + } + state.IdentityLinks[link.ID] = link + *loaded = true + } + return rows.Err() +} + +func (s *Store) loadRelationalSSOSessions(ctx context.Context, state *app.PersistedState, loaded *bool) error { + rows, err := s.pool.Query(ctx, `SELECT id, tenant_id, user_id, provider_id, prefix, hash, expires_at, revoked_at, schema_version, created_at FROM sso_sessions`) + if err != nil { + return fmt.Errorf("load relational sso sessions: %w", err) + } + defer rows.Close() + for rows.Next() { + var session domain.SSOSession + var hash string + var revokedAt sql.NullTime + if err := rows.Scan(&session.ID, &session.TenantID, &session.UserID, &session.ProviderID, &session.Prefix, &hash, &session.ExpiresAt, &revokedAt, &session.SchemaVersion, &session.CreatedAt); err != nil { + return fmt.Errorf("scan relational sso session: %w", err) + } + session.RevokedAt = nullableSQLTime(revokedAt) + state.SSOSessions[session.ID] = session + state.SSOSessionHashes[session.ID] = hash + *loaded = true + } + return rows.Err() +} + func (s *Store) loadRelationalAPIKeys(ctx context.Context, state *app.PersistedState, loaded *bool) error { rows, err := s.pool.Query(ctx, ` SELECT id, tenant_id, name, prefix, hash, scopes, expires_at, diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index c5b184b..c7eba8a 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -273,6 +273,15 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { if relational.APIKeyHashes["key_test"] != "hmac-test-hash" { t.Fatalf("relational api key hash = %q", relational.APIKeyHashes["key_test"]) } + if relational.Organizations["org_test"].Slug != "org" || relational.Users["user_test"].OrganizationID != "org_test" || relational.RoleBindings["rb_test"].Role != "security_engineer" { + t.Fatalf("relational identity rows missing: org=%#v user=%#v role=%#v", relational.Organizations["org_test"], relational.Users["user_test"], relational.RoleBindings["rb_test"]) + } + if relational.SSOProviders["sso_test"].TrustMaterialUpdatedAt == nil || len(relational.SSOProviders["sso_test"].JWKS) == 0 || !relational.IdentityLinks["link_test"].Verified { + t.Fatalf("relational sso rows missing: provider=%#v link=%#v", relational.SSOProviders["sso_test"], relational.IdentityLinks["link_test"]) + } + if relational.SSOSessionHashes["sess_test"] != "session-hash" || relational.SSOSessions["sess_test"].Prefix != "sess" { + t.Fatalf("relational sso session = %#v hash=%q", relational.SSOSessions["sess_test"], relational.SSOSessionHashes["sess_test"]) + } if relational.Products["prod_test"].Slug != "product" || relational.Evidence["ev_test"].ReleaseID != "rel_test" || relational.SBOMs["sbom_test"].ComponentCount != 1 { t.Fatalf("relational fallback missing core rows: product=%#v evidence=%#v sbom=%#v", relational.Products["prod_test"], relational.Evidence["ev_test"], relational.SBOMs["sbom_test"]) } From 8d94dbb95c46c6f6cc6bd4e8efcd80ff2c9c875b Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 20:41:54 +0300 Subject: [PATCH 093/287] feat: synchronize risk build control rows --- .implementation_increments.md | 2 +- docs/architecture.md | 2 +- docs/reference/production-readiness.md | 19 +- internal/adapters/postgres/store.go | 557 +++++++++++++++++++++++ internal/adapters/postgres/store_test.go | 45 ++ 5 files changed, 615 insertions(+), 10 deletions(-) diff --git a/.implementation_increments.md b/.implementation_increments.md index 0aa4e14..df0bb44 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -36,7 +36,7 @@ Status legend: ## Remaining Core Product Increments 6. `[x]` Relational Store Split - Added migration-backed relational tables and tenant-scoped resource projection rows for implemented resources, with transactional PostgreSQL saves, relational identity/idempotency/customer-portal-token rows, relational release-ledger core rows, relational package/report/retention rows, missing-snapshot fallback loading for identity, SSO session, release-ledger, package, report, and retention families, tenant/release indexes, persisted idempotency state, and outbox row locking. Canonical runtime loading still prefers the versioned ledger snapshot while per-resource repository tuning remains future hardening. + Added migration-backed relational tables and tenant-scoped resource projection rows for implemented resources, with transactional PostgreSQL saves, relational identity/idempotency/customer-portal-token rows, relational release-ledger core rows, relational build provenance/VEX/control rows, relational package/report/retention rows, missing-snapshot fallback loading for identity, SSO session, release-ledger, build provenance, VEX/risk decision, control, package, report, and retention families, tenant/release indexes, persisted idempotency state, and outbox row locking. Canonical runtime loading still prefers the versioned ledger snapshot while per-resource repository tuning remains future hardening. 7. `[x]` Evidence Search, Filtering, And Timeline Querying Added tenant-scoped evidence search by product, project, release, build, deployment, type, subtype, source, collector, created time, subject refs, tags, and verification status. diff --git a/docs/architecture.md b/docs/architecture.md index 741e05e..b49b209 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -10,7 +10,7 @@ Evydence follows a ports-and-adapters shape: - `internal/adapters/objectstore/s3` stores the same tenant-prefixed object keys in S3/MinIO-compatible buckets. - `cmd/*` contains process entry points. -Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity, idempotency, and customer portal token records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. Package, report, retention, and backup records are synchronized into their migration-backed relational tables. If the snapshot row is absent, the Postgres store can rebuild identity, SSO session, customer portal token, release-ledger core, package, report, and retention families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. +Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity, idempotency, and customer portal token records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. Collector/build provenance, VEX/risk decision, control, package, report, retention, and backup records are synchronized into their migration-backed relational tables. If the snapshot row is absent, the Postgres store can rebuild identity, SSO session, customer portal token, release-ledger core, build provenance, VEX/risk decision, control, package, report, and retention families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. ## Tenant And Auth Boundaries diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 073f7d5..984378f 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -17,11 +17,13 @@ Known hardening work remains: - canonical production persistence still needs hand-tuned relational repository paths for all high-risk resource families. PostgreSQL now maintains relational identity, idempotency, customer portal token, release-ledger core, - audit-chain, signing, bundle, policy, verification, package, report, and - retention rows alongside the canonical snapshot, but the snapshot remains the + build provenance, VEX/risk decision, control, audit-chain, signing, bundle, + policy, verification, package, report, and retention rows alongside the + canonical snapshot, but the snapshot remains the preferred runtime load source. If the snapshot row is absent, the store can rebuild identity, SSO session, customer portal token, release-ledger core, - package, report, and retention state from relational rows; + build provenance, VEX/risk decision, control, package, report, and retention + state from relational rows; - worker parser jobs re-read raw object-store payloads for key formats, verify digests, validate durable state, and persist missing parser-derived normalized fields. Upload paths still create initial accepted records, so @@ -100,11 +102,12 @@ implemented capabilities: - Replace canonical snapshot writes with dependency-ordered relational repositories for remaining secondary resources. Identity, idempotency, - customer portal token, release-ledger core, audit-chain, signing, bundle, - policy, verification, package, report, and retention rows are synchronized - into relational tables. Missing-snapshot recovery can rebuild identity, - SSO session, customer portal token, release-ledger core, package, report, - and retention families from relational rows. + customer portal token, release-ledger core, build provenance, VEX/risk + decision, control, audit-chain, signing, bundle, policy, verification, + package, report, and retention rows are synchronized into relational tables. + Missing-snapshot recovery can rebuild identity, SSO session, customer portal + token, release-ledger core, build provenance, VEX/risk decision, control, + package, report, and retention families from relational rows. Keep snapshots only for export/import and upgrade compatibility after the remaining families have repository-backed reads and writes. - Split the large application ledger aggregate into focused services or diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index f36929d..e24c1eb 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -81,6 +81,9 @@ func (s *Store) loadRelationalState(ctx context.Context) (app.PersistedState, bo if err := s.loadRelationalReleaseCore(ctx, &state, &loaded); err != nil { return app.PersistedState{}, false, err } + if err := s.loadRelationalRiskBuildControls(ctx, &state, &loaded); err != nil { + return app.PersistedState{}, false, err + } if err := s.loadRelationalPackageReportRetention(ctx, &state, &loaded); err != nil { return app.PersistedState{}, false, err } @@ -102,6 +105,9 @@ func relationalEmptyState() app.PersistedState { SSOSessionHashes: map[string]string{}, APIKeys: map[string]domain.APIKey{}, APIKeyHashes: map[string]string{}, + Collectors: map[string]domain.Collector{}, + BuildRuns: map[string]domain.BuildRun{}, + BuildAttestations: map[string]domain.BuildAttestation{}, CustomerPortalAccess: map[string]domain.CustomerPortalAccess{}, CustomerPortalHashes: map[string]string{}, RedactionProfiles: map[string]domain.RedactionProfile{}, @@ -119,6 +125,9 @@ func relationalEmptyState() app.PersistedState { QuestionnairePackages: map[string]domain.QuestionnairePackage{}, PDFReports: map[string]domain.PDFReportPackage{}, AnomalyReports: map[string]domain.AnomalyReport{}, + ControlFrameworks: map[string]domain.ControlFramework{}, + SecurityControls: map[string]domain.SecurityControl{}, + ControlEvidence: map[string]domain.ControlEvidence{}, Products: map[string]domain.Product{}, Projects: map[string]domain.Project{}, Releases: map[string]domain.Release{}, @@ -126,8 +135,11 @@ func relationalEmptyState() app.PersistedState { Evidence: map[string]domain.EvidenceItem{}, SBOMs: map[string]domain.SBOM{}, Scans: map[string]domain.VulnerabilityScan{}, + VEXDocuments: map[string]domain.VEXDocument{}, + Decisions: map[string]domain.VulnerabilityDecision{}, Contracts: map[string]domain.OpenAPIContract{}, Policies: map[string]domain.PolicyEvaluation{}, + Exceptions: map[string]domain.Exception{}, Bundles: map[string]domain.ReleaseBundle{}, SigningKeys: map[string]domain.SigningKey{}, SigningKeyPrivate: map[string][]byte{}, @@ -796,6 +808,285 @@ func (s *Store) loadRelationalVerifications(ctx context.Context, state *app.Pers return rows.Err() } +func (s *Store) loadRelationalRiskBuildControls(ctx context.Context, state *app.PersistedState, loaded *bool) error { + if err := s.loadRelationalCollectorsAndBuilds(ctx, state, loaded); err != nil { + return err + } + if err := s.loadRelationalRiskDecisions(ctx, state, loaded); err != nil { + return err + } + if err := s.loadRelationalControls(ctx, state, loaded); err != nil { + return err + } + return nil +} + +func (s *Store) loadRelationalCollectorsAndBuilds(ctx context.Context, state *app.PersistedState, loaded *bool) error { + collectorRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, name, type, version, api_key_id, status, allowed_scopes, last_seen_at, schema_version, created_at FROM collectors`) + if err != nil { + return fmt.Errorf("load relational collectors: %w", err) + } + defer collectorRows.Close() + for collectorRows.Next() { + var collector domain.Collector + var allowedScopes []byte + var lastSeenAt sql.NullTime + if err := collectorRows.Scan(&collector.ID, &collector.TenantID, &collector.Name, &collector.Type, &collector.Version, &collector.APIKeyID, &collector.Status, &allowedScopes, &lastSeenAt, &collector.SchemaVersion, &collector.CreatedAt); err != nil { + return fmt.Errorf("scan relational collector: %w", err) + } + if err := decodeJSON(allowedScopes, &collector.AllowedScopes); err != nil { + return fmt.Errorf("decode relational collector scopes: %w", err) + } + collector.LastSeenAt = nullableSQLTime(lastSeenAt) + state.Collectors[collector.ID] = collector + *loaded = true + } + if err := collectorRows.Err(); err != nil { + return err + } + + buildRows, err := s.pool.Query(ctx, ` + SELECT id, tenant_id, project_id, release_id, collector_id, provider, + commit_sha, repository, workflow_ref, run_id, run_attempt, + job_id, actor, ref, oidc_subject, status, started_at, + finished_at, parameters_hash, environment_hash, source_identity, + outputs, schema_version, created_at + FROM build_runs + `) + if err != nil { + return fmt.Errorf("load relational build runs: %w", err) + } + defer buildRows.Close() + for buildRows.Next() { + var build domain.BuildRun + var collectorID, repository, workflowRef, runID, jobID, actor, ref, oidcSubject, parametersHash, environmentHash sql.NullString + var runAttempt sql.NullInt32 + var finishedAt sql.NullTime + var sourceIdentity, outputs []byte + if err := buildRows.Scan( + &build.ID, &build.TenantID, &build.ProjectID, &build.ReleaseID, &collectorID, &build.Provider, + &build.CommitSHA, &repository, &workflowRef, &runID, &runAttempt, + &jobID, &actor, &ref, &oidcSubject, &build.Status, &build.StartedAt, + &finishedAt, ¶metersHash, &environmentHash, &sourceIdentity, + &outputs, &build.SchemaVersion, &build.CreatedAt, + ); err != nil { + return fmt.Errorf("scan relational build run: %w", err) + } + build.CollectorID = nullableSQLString(collectorID) + build.Repository = nullableSQLString(repository) + build.WorkflowRef = nullableSQLString(workflowRef) + build.RunID = nullableSQLString(runID) + if runAttempt.Valid { + build.RunAttempt = int(runAttempt.Int32) + } + build.JobID = nullableSQLString(jobID) + build.Actor = nullableSQLString(actor) + build.Ref = nullableSQLString(ref) + build.OIDCSubject = nullableSQLString(oidcSubject) + build.FinishedAt = nullableSQLTime(finishedAt) + build.ParametersHash = nullableSQLString(parametersHash) + build.EnvironmentHash = nullableSQLString(environmentHash) + if err := decodeJSON(sourceIdentity, &build.SourceIdentity); err != nil { + return fmt.Errorf("decode relational build source identity: %w", err) + } + if err := decodeJSON(outputs, &build.Outputs); err != nil { + return fmt.Errorf("decode relational build outputs: %w", err) + } + state.BuildRuns[build.ID] = build + *loaded = true + } + if err := buildRows.Err(); err != nil { + return err + } + + attestationRows, err := s.pool.Query(ctx, ` + SELECT id, tenant_id, build_id, evidence_id, payload_ref, payload_hash, + payload_size, payload_type, predicate_type, subject_digests, + builder_id, build_type, materials_count, signature_count, + verification_status, schema_version, created_at + FROM build_attestations + `) + if err != nil { + return fmt.Errorf("load relational build attestations: %w", err) + } + defer attestationRows.Close() + for attestationRows.Next() { + var attestation domain.BuildAttestation + var payloadRef, builderID, buildType sql.NullString + var subjectDigests []byte + if err := attestationRows.Scan( + &attestation.ID, &attestation.TenantID, &attestation.BuildID, &attestation.EvidenceID, &payloadRef, &attestation.PayloadHash, + &attestation.PayloadSize, &attestation.PayloadType, &attestation.PredicateType, &subjectDigests, + &builderID, &buildType, &attestation.MaterialsCount, &attestation.SignatureCount, + &attestation.VerificationStatus, &attestation.SchemaVersion, &attestation.CreatedAt, + ); err != nil { + return fmt.Errorf("scan relational build attestation: %w", err) + } + attestation.PayloadRef = nullableSQLString(payloadRef) + attestation.BuilderID = nullableSQLString(builderID) + attestation.BuildType = nullableSQLString(buildType) + if err := decodeJSON(subjectDigests, &attestation.SubjectDigests); err != nil { + return fmt.Errorf("decode relational attestation subject digests: %w", err) + } + state.BuildAttestations[attestation.ID] = attestation + *loaded = true + } + return attestationRows.Err() +} + +func (s *Store) loadRelationalRiskDecisions(ctx context.Context, state *app.PersistedState, loaded *bool) error { + vexRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, evidence_id, release_id, artifact_id, format, author, version, statement_count, status_summary, schema_version, created_at FROM vex_documents`) + if err != nil { + return fmt.Errorf("load relational vex documents: %w", err) + } + defer vexRows.Close() + for vexRows.Next() { + var document domain.VEXDocument + var releaseID, artifactID, version sql.NullString + var statusSummary []byte + if err := vexRows.Scan(&document.ID, &document.TenantID, &document.EvidenceID, &releaseID, &artifactID, &document.Format, &document.Author, &version, &document.StatementCount, &statusSummary, &document.SchemaVersion, &document.CreatedAt); err != nil { + return fmt.Errorf("scan relational vex document: %w", err) + } + document.ReleaseID = nullableSQLString(releaseID) + document.ArtifactID = nullableSQLString(artifactID) + document.Version = nullableSQLString(version) + if err := decodeJSON(statusSummary, &document.StatusSummary); err != nil { + return fmt.Errorf("decode relational vex summary: %w", err) + } + state.VEXDocuments[document.ID] = document + *loaded = true + } + if err := vexRows.Err(); err != nil { + return err + } + + decisionRows, err := s.pool.Query(ctx, ` + SELECT id, tenant_id, finding_id, scan_id, release_id, vulnerability, + component, status, justification, impact_statement, action_statement, + source, evidence_id, vex_document_id, supersedes, superseded_by, + approved_by, schema_version, created_at + FROM vulnerability_decisions + `) + if err != nil { + return fmt.Errorf("load relational vulnerability decisions: %w", err) + } + defer decisionRows.Close() + for decisionRows.Next() { + var decision domain.VulnerabilityDecision + var releaseID, component, impactStatement, actionStatement, evidenceID, vexDocumentID, supersedes, supersededBy, approvedBy sql.NullString + if err := decisionRows.Scan( + &decision.ID, &decision.TenantID, &decision.FindingID, &decision.ScanID, &releaseID, &decision.Vulnerability, + &component, &decision.Status, &decision.Justification, &impactStatement, &actionStatement, + &decision.Source, &evidenceID, &vexDocumentID, &supersedes, &supersededBy, + &approvedBy, &decision.SchemaVersion, &decision.CreatedAt, + ); err != nil { + return fmt.Errorf("scan relational vulnerability decision: %w", err) + } + decision.ReleaseID = nullableSQLString(releaseID) + decision.Component = nullableSQLString(component) + decision.ImpactStatement = nullableSQLString(impactStatement) + decision.ActionStatement = nullableSQLString(actionStatement) + decision.EvidenceID = nullableSQLString(evidenceID) + decision.VEXDocumentID = nullableSQLString(vexDocumentID) + decision.Supersedes = nullableSQLString(supersedes) + decision.SupersededBy = nullableSQLString(supersededBy) + decision.ApprovedBy = nullableSQLString(approvedBy) + state.Decisions[decision.ID] = decision + *loaded = true + } + if err := decisionRows.Err(); err != nil { + return err + } + + exceptionRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, release_id, finding_id, control_id, reason, owner, expires_at, approved, approved_by, approved_at, created_at FROM exceptions`) + if err != nil { + return fmt.Errorf("load relational exceptions: %w", err) + } + defer exceptionRows.Close() + for exceptionRows.Next() { + var exception domain.Exception + var findingID, controlID, approvedBy sql.NullString + var approvedAt sql.NullTime + if err := exceptionRows.Scan(&exception.ID, &exception.TenantID, &exception.ReleaseID, &findingID, &controlID, &exception.Reason, &exception.Owner, &exception.ExpiresAt, &exception.Approved, &approvedBy, &approvedAt, &exception.CreatedAt); err != nil { + return fmt.Errorf("scan relational exception: %w", err) + } + exception.FindingID = nullableSQLString(findingID) + exception.ControlID = nullableSQLString(controlID) + exception.ApprovedBy = nullableSQLString(approvedBy) + exception.ApprovedAt = nullableSQLTime(approvedAt) + state.Exceptions[exception.ID] = exception + *loaded = true + } + return exceptionRows.Err() +} + +func (s *Store) loadRelationalControls(ctx context.Context, state *app.PersistedState, loaded *bool) error { + frameworkRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, name, slug, version, description, status, schema_version, created_at FROM control_frameworks`) + if err != nil { + return fmt.Errorf("load relational control frameworks: %w", err) + } + defer frameworkRows.Close() + for frameworkRows.Next() { + var framework domain.ControlFramework + var description sql.NullString + if err := frameworkRows.Scan(&framework.ID, &framework.TenantID, &framework.Name, &framework.Slug, &framework.Version, &description, &framework.Status, &framework.SchemaVersion, &framework.CreatedAt); err != nil { + return fmt.Errorf("scan relational control framework: %w", err) + } + framework.Description = nullableSQLString(description) + state.ControlFrameworks[framework.ID] = framework + *loaded = true + } + if err := frameworkRows.Err(); err != nil { + return err + } + + controlRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, framework_id, code, title, objective, evidence_requirements, applicability, limitations, schema_version, created_at FROM security_controls`) + if err != nil { + return fmt.Errorf("load relational security controls: %w", err) + } + defer controlRows.Close() + for controlRows.Next() { + var control domain.SecurityControl + var requirements, applicability, limitations []byte + if err := controlRows.Scan(&control.ID, &control.TenantID, &control.FrameworkID, &control.Code, &control.Title, &control.Objective, &requirements, &applicability, &limitations, &control.SchemaVersion, &control.CreatedAt); err != nil { + return fmt.Errorf("scan relational security control: %w", err) + } + if err := decodeJSON(requirements, &control.EvidenceRequirements); err != nil { + return fmt.Errorf("decode relational control requirements: %w", err) + } + if err := decodeJSON(applicability, &control.Applicability); err != nil { + return fmt.Errorf("decode relational control applicability: %w", err) + } + if err := decodeJSON(limitations, &control.Limitations); err != nil { + return fmt.Errorf("decode relational control limitations: %w", err) + } + state.SecurityControls[control.ID] = control + *loaded = true + } + if err := controlRows.Err(); err != nil { + return err + } + + evidenceRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, control_id, evidence_type, subject_type, subject_id, product_id, release_id, confidence, notes, schema_version, created_at FROM control_evidence`) + if err != nil { + return fmt.Errorf("load relational control evidence: %w", err) + } + defer evidenceRows.Close() + for evidenceRows.Next() { + var evidence domain.ControlEvidence + var productID, releaseID, notes sql.NullString + if err := evidenceRows.Scan(&evidence.ID, &evidence.TenantID, &evidence.ControlID, &evidence.EvidenceType, &evidence.SubjectType, &evidence.SubjectID, &productID, &releaseID, &evidence.Confidence, ¬es, &evidence.SchemaVersion, &evidence.CreatedAt); err != nil { + return fmt.Errorf("scan relational control evidence: %w", err) + } + evidence.ProductID = nullableSQLString(productID) + evidence.ReleaseID = nullableSQLString(releaseID) + evidence.Notes = nullableSQLString(notes) + state.ControlEvidence[evidence.ID] = evidence + *loaded = true + } + return evidenceRows.Err() +} + func (s *Store) loadRelationalPackageReportRetention(ctx context.Context, state *app.PersistedState, loaded *bool) error { if err := s.loadRelationalPackages(ctx, state, loaded); err != nil { return err @@ -1171,6 +1462,9 @@ func (s *Store) SaveState(ctx context.Context, state app.PersistedState) error { if err := syncReleaseLedgerCore(ctx, tx, state); err != nil { return err } + if err := syncRiskBuildControlRows(ctx, tx, state); err != nil { + return err + } if err := syncPackageReportRetentionRows(ctx, tx, state); err != nil { return err } @@ -1500,6 +1794,262 @@ func syncReleaseLedgerCore(ctx context.Context, tx pgx.Tx, state app.PersistedSt return nil } +func syncRiskBuildControlRows(ctx context.Context, tx pgx.Tx, state app.PersistedState) error { + for _, collector := range state.Collectors { + if collector.ID == "" || collector.TenantID == "" || collector.APIKeyID == "" { + continue + } + allowedScopes, err := json.Marshal(collector.AllowedScopes) + if err != nil { + return fmt.Errorf("encode collector scopes: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO collectors ( + id, tenant_id, name, type, version, api_key_id, status, + allowed_scopes, last_seen_at, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) + ON CONFLICT (id) DO UPDATE SET + name = EXCLUDED.name, + version = EXCLUDED.version, + api_key_id = EXCLUDED.api_key_id, + status = EXCLUDED.status, + allowed_scopes = EXCLUDED.allowed_scopes, + last_seen_at = EXCLUDED.last_seen_at, + schema_version = EXCLUDED.schema_version + `, collector.ID, collector.TenantID, collector.Name, collector.Type, collector.Version, collector.APIKeyID, collector.Status, allowedScopes, nullableTime(collector.LastSeenAt), collector.SchemaVersion, nonZeroTime(collector.CreatedAt)); err != nil { + return fmt.Errorf("upsert collector row: %w", err) + } + } + for _, build := range state.BuildRuns { + if build.ID == "" || build.TenantID == "" || build.ProjectID == "" || build.ReleaseID == "" { + continue + } + sourceIdentity, err := json.Marshal(build.SourceIdentity) + if err != nil { + return fmt.Errorf("encode build source identity: %w", err) + } + outputs, err := json.Marshal(build.Outputs) + if err != nil { + return fmt.Errorf("encode build outputs: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO build_runs ( + id, tenant_id, project_id, release_id, collector_id, provider, + commit_sha, repository, workflow_ref, run_id, run_attempt, + job_id, actor, ref, oidc_subject, status, started_at, + finished_at, parameters_hash, environment_hash, source_identity, + outputs, schema_version, created_at + ) + VALUES ( + $1, $2, $3, $4, $5, $6, + $7, $8, $9, $10, $11, + $12, $13, $14, $15, $16, $17, + $18, $19, $20, $21, + $22, $23, $24 + ) + ON CONFLICT (id) DO UPDATE SET + status = EXCLUDED.status, + finished_at = EXCLUDED.finished_at, + parameters_hash = EXCLUDED.parameters_hash, + environment_hash = EXCLUDED.environment_hash, + source_identity = EXCLUDED.source_identity, + outputs = EXCLUDED.outputs + `, build.ID, build.TenantID, build.ProjectID, build.ReleaseID, nullableString(build.CollectorID), build.Provider, + build.CommitSHA, nullableString(build.Repository), nullableString(build.WorkflowRef), nullableString(build.RunID), nullableInt(build.RunAttempt), + nullableString(build.JobID), nullableString(build.Actor), nullableString(build.Ref), nullableString(build.OIDCSubject), build.Status, nonZeroTime(build.StartedAt), + nullableTime(build.FinishedAt), nullableString(build.ParametersHash), nullableString(build.EnvironmentHash), sourceIdentity, + outputs, build.SchemaVersion, nonZeroTime(build.CreatedAt)); err != nil { + return fmt.Errorf("upsert build run row: %w", err) + } + } + for _, attestation := range state.BuildAttestations { + if attestation.ID == "" || attestation.TenantID == "" || attestation.BuildID == "" || attestation.EvidenceID == "" { + continue + } + subjectDigests, err := json.Marshal(attestation.SubjectDigests) + if err != nil { + return fmt.Errorf("encode attestation subject digests: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO build_attestations ( + id, tenant_id, build_id, evidence_id, payload_ref, payload_hash, + payload_size, payload_type, predicate_type, subject_digests, + builder_id, build_type, materials_count, signature_count, + verification_status, schema_version, created_at + ) + VALUES ( + $1, $2, $3, $4, $5, $6, + $7, $8, $9, $10, + $11, $12, $13, $14, + $15, $16, $17 + ) + ON CONFLICT (id) DO UPDATE SET + payload_ref = EXCLUDED.payload_ref, + payload_hash = EXCLUDED.payload_hash, + payload_size = EXCLUDED.payload_size, + predicate_type = EXCLUDED.predicate_type, + subject_digests = EXCLUDED.subject_digests, + builder_id = EXCLUDED.builder_id, + build_type = EXCLUDED.build_type, + materials_count = EXCLUDED.materials_count, + signature_count = EXCLUDED.signature_count, + verification_status = EXCLUDED.verification_status + `, attestation.ID, attestation.TenantID, attestation.BuildID, attestation.EvidenceID, nullableString(attestation.PayloadRef), attestation.PayloadHash, + attestation.PayloadSize, attestation.PayloadType, attestation.PredicateType, subjectDigests, + nullableString(attestation.BuilderID), nullableString(attestation.BuildType), attestation.MaterialsCount, attestation.SignatureCount, + attestation.VerificationStatus, attestation.SchemaVersion, nonZeroTime(attestation.CreatedAt)); err != nil { + return fmt.Errorf("upsert build attestation row: %w", err) + } + } + for _, document := range state.VEXDocuments { + if document.ID == "" || document.TenantID == "" || document.EvidenceID == "" { + continue + } + statusSummary, err := json.Marshal(document.StatusSummary) + if err != nil { + return fmt.Errorf("encode vex status summary: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO vex_documents ( + id, tenant_id, evidence_id, release_id, artifact_id, format, + author, version, statement_count, status_summary, + schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) + ON CONFLICT (id) DO UPDATE SET + statement_count = EXCLUDED.statement_count, + status_summary = EXCLUDED.status_summary + `, document.ID, document.TenantID, document.EvidenceID, nullableString(document.ReleaseID), nullableString(document.ArtifactID), document.Format, + document.Author, nullableString(document.Version), document.StatementCount, statusSummary, + document.SchemaVersion, nonZeroTime(document.CreatedAt)); err != nil { + return fmt.Errorf("upsert vex document row: %w", err) + } + } + for _, decision := range state.Decisions { + if decision.ID == "" || decision.TenantID == "" || decision.FindingID == "" || decision.ScanID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO vulnerability_decisions ( + id, tenant_id, finding_id, scan_id, release_id, vulnerability, + component, status, justification, impact_statement, action_statement, + source, evidence_id, vex_document_id, supersedes, superseded_by, + approved_by, schema_version, created_at + ) + VALUES ( + $1, $2, $3, $4, $5, $6, + $7, $8, $9, $10, $11, + $12, $13, $14, $15, $16, + $17, $18, $19 + ) + ON CONFLICT (id) DO UPDATE SET + superseded_by = EXCLUDED.superseded_by, + approved_by = EXCLUDED.approved_by + `, decision.ID, decision.TenantID, decision.FindingID, decision.ScanID, nullableString(decision.ReleaseID), decision.Vulnerability, + nullableString(decision.Component), decision.Status, decision.Justification, nullableString(decision.ImpactStatement), nullableString(decision.ActionStatement), + decision.Source, nullableString(decision.EvidenceID), nullableString(decision.VEXDocumentID), nullableString(decision.Supersedes), nullableString(decision.SupersededBy), + nullableString(decision.ApprovedBy), decision.SchemaVersion, nonZeroTime(decision.CreatedAt)); err != nil { + return fmt.Errorf("upsert vulnerability decision row: %w", err) + } + } + for _, exception := range state.Exceptions { + if exception.ID == "" || exception.TenantID == "" || exception.ReleaseID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO exceptions ( + id, tenant_id, release_id, finding_id, control_id, reason, + owner, expires_at, approved, approved_by, approved_at, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) + ON CONFLICT (id) DO UPDATE SET + approved = EXCLUDED.approved, + approved_by = EXCLUDED.approved_by, + approved_at = EXCLUDED.approved_at + `, exception.ID, exception.TenantID, exception.ReleaseID, nullableString(exception.FindingID), nullableString(exception.ControlID), exception.Reason, + exception.Owner, exception.ExpiresAt, exception.Approved, nullableString(exception.ApprovedBy), nullableTime(exception.ApprovedAt), nonZeroTime(exception.CreatedAt)); err != nil { + return fmt.Errorf("upsert exception row: %w", err) + } + } + for _, framework := range state.ControlFrameworks { + if framework.ID == "" || framework.TenantID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO control_frameworks ( + id, tenant_id, name, slug, version, description, + status, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + ON CONFLICT (id) DO UPDATE SET + description = EXCLUDED.description, + status = EXCLUDED.status, + schema_version = EXCLUDED.schema_version + `, framework.ID, framework.TenantID, framework.Name, framework.Slug, framework.Version, nullableString(framework.Description), + framework.Status, framework.SchemaVersion, nonZeroTime(framework.CreatedAt)); err != nil { + return fmt.Errorf("upsert control framework row: %w", err) + } + } + for _, control := range state.SecurityControls { + if control.ID == "" || control.TenantID == "" || control.FrameworkID == "" { + continue + } + requirements, err := json.Marshal(control.EvidenceRequirements) + if err != nil { + return fmt.Errorf("encode control requirements: %w", err) + } + applicability, err := json.Marshal(control.Applicability) + if err != nil { + return fmt.Errorf("encode control applicability: %w", err) + } + limitations, err := json.Marshal(control.Limitations) + if err != nil { + return fmt.Errorf("encode control limitations: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO security_controls ( + id, tenant_id, framework_id, code, title, objective, + evidence_requirements, applicability, limitations, + schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) + ON CONFLICT (id) DO UPDATE SET + title = EXCLUDED.title, + objective = EXCLUDED.objective, + evidence_requirements = EXCLUDED.evidence_requirements, + applicability = EXCLUDED.applicability, + limitations = EXCLUDED.limitations, + schema_version = EXCLUDED.schema_version + `, control.ID, control.TenantID, control.FrameworkID, control.Code, control.Title, control.Objective, + requirements, applicability, limitations, control.SchemaVersion, nonZeroTime(control.CreatedAt)); err != nil { + return fmt.Errorf("upsert security control row: %w", err) + } + } + for _, evidence := range state.ControlEvidence { + if evidence.ID == "" || evidence.TenantID == "" || evidence.ControlID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO control_evidence ( + id, tenant_id, control_id, evidence_type, subject_type, + subject_id, product_id, release_id, confidence, notes, + schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) + ON CONFLICT (id) DO UPDATE SET + confidence = EXCLUDED.confidence, + notes = EXCLUDED.notes, + schema_version = EXCLUDED.schema_version + `, evidence.ID, evidence.TenantID, evidence.ControlID, evidence.EvidenceType, evidence.SubjectType, + evidence.SubjectID, nullableString(evidence.ProductID), nullableString(evidence.ReleaseID), evidence.Confidence, nullableString(evidence.Notes), + evidence.SchemaVersion, nonZeroTime(evidence.CreatedAt)); err != nil { + return fmt.Errorf("upsert control evidence row: %w", err) + } + } + return nil +} + func syncPackageReportRetentionRows(ctx context.Context, tx pgx.Tx, state app.PersistedState) error { for _, profile := range state.RedactionProfiles { if profile.ID == "" || profile.TenantID == "" { @@ -2372,6 +2922,13 @@ func nullableInt64(value int64) any { return value } +func nullableInt(value int) any { + if value == 0 { + return nil + } + return value +} + func nonZeroInt(value, fallback int) int { if value == 0 { return fallback diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index c7eba8a..a2eb97a 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -46,6 +46,9 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { "key_test": {ID: "key_test", TenantID: "ten_test", Name: "api", Prefix: "evy_test", Scopes: []string{"evidence:write"}, CreatedAt: time.Now().UTC()}, }, APIKeyHashes: map[string]string{"key_test": "hmac-test-hash"}, + Collectors: map[string]domain.Collector{ + "collector_test": {ID: "collector_test", TenantID: "ten_test", Name: "github", Type: "github_actions", Version: "1.0.0", APIKeyID: "key_test", Status: "active", AllowedScopes: []string{"build:write"}, LastSeenAt: ptrTime(time.Now().UTC()), SchemaVersion: domain.CollectorSchemaVersion, CreatedAt: time.Now().UTC()}, + }, SSOProviders: map[string]domain.SSOProvider{ "sso_test": {ID: "sso_test", TenantID: "ten_test", Name: "OIDC", Type: "oidc", Issuer: "https://idp.example.test", ClientID: "client", Status: "active", JWKS: map[string]any{"keys": []any{map[string]any{"kty": "OKP", "kid": "kid-1", "crv": "Ed25519", "x": "abc"}}}, SchemaVersion: domain.SSOProviderSchemaVersion, CreatedAt: time.Now().UTC(), TrustMaterialUpdatedAt: ptrTime(time.Now().UTC())}, }, @@ -72,6 +75,12 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { Artifacts: map[string]domain.Artifact{ "art_test": {ID: "art_test", TenantID: "ten_test", Name: "artifact.tar.gz", MediaType: "application/gzip", Size: 42, Digest: "sha256:" + strings.Repeat("a", 64), CreatedAt: time.Now().UTC()}, }, + BuildRuns: map[string]domain.BuildRun{ + "build_test": {ID: "build_test", TenantID: "ten_test", ProjectID: "proj_test", ReleaseID: "rel_test", CollectorID: "collector_test", Provider: "github_actions", CommitSHA: strings.Repeat("1", 40), Repository: "org/repo", WorkflowRef: "org/repo/.github/workflows/ci.yml@refs/heads/main", RunID: "123", RunAttempt: 1, Status: "passed", StartedAt: time.Now().UTC(), FinishedAt: ptrTime(time.Now().UTC()), SourceIdentity: map[string]any{"provider": "github_actions"}, Outputs: []domain.BuildOutput{{ArtifactID: "art_test", Digest: "sha256:" + strings.Repeat("a", 64)}}, SchemaVersion: domain.BuildRunSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + BuildAttestations: map[string]domain.BuildAttestation{ + "att_test": {ID: "att_test", TenantID: "ten_test", BuildID: "build_test", EvidenceID: "ev_test", PayloadRef: "object://tenants/ten_test/payloads/attestation/" + strings.Repeat("a", 64), PayloadHash: "sha256:" + strings.Repeat("a", 64), PayloadSize: 100, PayloadType: "application/vnd.dsse.envelope.v1+json", PredicateType: "https://slsa.dev/provenance/v1", SubjectDigests: []string{"sha256:" + strings.Repeat("a", 64)}, BuilderID: "builder", BuildType: "github_actions", MaterialsCount: 1, SignatureCount: 1, VerificationStatus: "structurally_valid", SchemaVersion: domain.BuildAttestationSchemaVersion, CreatedAt: time.Now().UTC()}, + }, Evidence: map[string]domain.EvidenceItem{ "ev_test": { ID: "ev_test", TenantID: "ten_test", ProductID: "prod_test", ProjectID: "proj_test", ReleaseID: "rel_test", @@ -104,6 +113,12 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { Scans: map[string]domain.VulnerabilityScan{ "scan_test": {ID: "scan_test", TenantID: "ten_test", EvidenceID: "ev_test", ReleaseID: "rel_test", Scanner: "scanner", TargetRef: "artifact.tar.gz", Summary: map[string]int{"critical": 0}, Findings: []domain.VulnerabilityFinding{{ID: "finding_test", Vulnerability: "CVE-0000-0001", Severity: "low", State: "open"}}, CreatedAt: time.Now().UTC()}, }, + VEXDocuments: map[string]domain.VEXDocument{ + "vex_test": {ID: "vex_test", TenantID: "ten_test", EvidenceID: "ev_test", ReleaseID: "rel_test", ArtifactID: "art_test", Format: "openvex", Author: "tester", Version: "1", StatementCount: 1, StatusSummary: map[string]int{"not_affected": 1}, SchemaVersion: domain.VEXDocumentSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + Decisions: map[string]domain.VulnerabilityDecision{ + "decision_test": {ID: "decision_test", TenantID: "ten_test", FindingID: "finding_test", ScanID: "scan_test", ReleaseID: "rel_test", Vulnerability: "CVE-0000-0001", Component: "lib", Status: "not_affected", Justification: "not_present", Source: "manual", EvidenceID: "ev_test", VEXDocumentID: "vex_test", SchemaVersion: domain.VulnerabilityDecisionVersion, CreatedAt: time.Now().UTC()}, + }, Contracts: map[string]domain.OpenAPIContract{ "contract_test": {ID: "contract_test", TenantID: "ten_test", ProductID: "prod_test", ReleaseID: "rel_test", Version: "1.0.0", Hash: "sha256:" + strings.Repeat("f", 64), PathCount: 1, Operations: []domain.OpenAPIOperation{{Path: "/v1/test", Method: "get", OperationID: "getTest"}}, EvidenceID: "ev_test", CreatedAt: time.Now().UTC()}, }, @@ -116,6 +131,18 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { Verifications: map[string]domain.VerificationResult{ "verify_test": {ID: "verify_test", TenantID: "ten_test", SubjectType: "release_bundle", SubjectID: "bundle_test", Result: "pass", Checks: []domain.VerifyCheck{{Name: "signature", Result: "passed"}}, VerifiedAt: time.Now().UTC()}, }, + Exceptions: map[string]domain.Exception{ + "exception_test": {ID: "exception_test", TenantID: "ten_test", ReleaseID: "rel_test", FindingID: "finding_test", Reason: "accepted for test", Owner: "security", ExpiresAt: time.Now().UTC().Add(24 * time.Hour), Approved: true, ApprovedBy: "user_test", ApprovedAt: ptrTime(time.Now().UTC()), CreatedAt: time.Now().UTC()}, + }, + ControlFrameworks: map[string]domain.ControlFramework{ + "framework_test": {ID: "framework_test", TenantID: "ten_test", Name: "Framework", Slug: "framework", Version: "1", Description: "test", Status: "active", SchemaVersion: domain.ControlFrameworkSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + SecurityControls: map[string]domain.SecurityControl{ + "control_test": {ID: "control_test", TenantID: "ten_test", FrameworkID: "framework_test", Code: "EVY-1", Title: "Evidence", Objective: "Collect evidence", EvidenceRequirements: []domain.ControlEvidenceRequirement{{Type: "sbom", Required: true}}, Applicability: []string{"release"}, Limitations: []string{"test"}, SchemaVersion: domain.SecurityControlSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + ControlEvidence: map[string]domain.ControlEvidence{ + "control_evidence_test": {ID: "control_evidence_test", TenantID: "ten_test", ControlID: "control_test", EvidenceType: "sbom", SubjectType: "evidence", SubjectID: "ev_test", ProductID: "prod_test", ReleaseID: "rel_test", Confidence: "high", Notes: "linked", SchemaVersion: domain.ControlEvidenceSchemaVersion, CreatedAt: time.Now().UTC()}, + }, RedactionProfiles: map[string]domain.RedactionProfile{ "redact_test": {ID: "redact_test", TenantID: "ten_test", Name: "Default", Description: "profile", AllowedTypes: []string{"sbom"}, ExcludedFields: []string{"metadata.secret"}, SchemaVersion: domain.RedactionProfileSchemaVersion, CreatedAt: time.Now().UTC()}, }, @@ -225,16 +252,25 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { {name: "project", query: `SELECT count(*) FROM projects WHERE tenant_id = 'ten_test' AND product_id = 'prod_test'`}, {name: "release", query: `SELECT count(*) FROM releases WHERE tenant_id = 'ten_test' AND id = 'rel_test'`}, {name: "artifact", query: `SELECT count(*) FROM artifacts WHERE tenant_id = 'ten_test' AND digest LIKE 'sha256:%'`}, + {name: "collector", query: `SELECT count(*) FROM collectors WHERE tenant_id = 'ten_test' AND id = 'collector_test' AND allowed_scopes <> '[]'::jsonb`}, + {name: "build run", query: `SELECT count(*) FROM build_runs WHERE tenant_id = 'ten_test' AND id = 'build_test' AND outputs <> '[]'::jsonb`}, + {name: "build attestation", query: `SELECT count(*) FROM build_attestations WHERE tenant_id = 'ten_test' AND id = 'att_test' AND subject_digests <> '[]'::jsonb`}, {name: "evidence", query: `SELECT count(*) FROM evidence_items WHERE tenant_id = 'ten_test' AND id = 'ev_test' AND evidence_version = 1 AND product_id = 'prod_test'`}, {name: "audit chain", query: `SELECT count(*) FROM audit_chain_entries WHERE tenant_id = 'ten_test' AND sequence = 1`}, {name: "signing key", query: `SELECT count(*) FROM signing_keys WHERE tenant_id = 'ten_test' AND id = 'sigkey_test' AND encrypted_private_key IS NOT NULL`}, {name: "signature", query: `SELECT count(*) FROM signatures WHERE tenant_id = 'ten_test' AND id = 'sig_test'`}, {name: "sbom", query: `SELECT count(*) FROM sboms WHERE tenant_id = 'ten_test' AND release_id = 'rel_test' AND component_count = 1`}, {name: "scan", query: `SELECT count(*) FROM vulnerability_scans WHERE tenant_id = 'ten_test' AND release_id = 'rel_test'`}, + {name: "vex", query: `SELECT count(*) FROM vex_documents WHERE tenant_id = 'ten_test' AND id = 'vex_test' AND statement_count = 1`}, + {name: "decision", query: `SELECT count(*) FROM vulnerability_decisions WHERE tenant_id = 'ten_test' AND id = 'decision_test' AND status = 'not_affected'`}, + {name: "exception", query: `SELECT count(*) FROM exceptions WHERE tenant_id = 'ten_test' AND id = 'exception_test' AND approved = true`}, {name: "contract", query: `SELECT count(*) FROM openapi_contracts WHERE tenant_id = 'ten_test' AND id = 'contract_test' AND operations <> '[]'::jsonb`}, {name: "policy", query: `SELECT count(*) FROM policy_evaluations WHERE tenant_id = 'ten_test' AND id = 'policy_test'`}, {name: "bundle", query: `SELECT count(*) FROM release_bundles WHERE tenant_id = 'ten_test' AND id = 'bundle_test'`}, {name: "verification", query: `SELECT count(*) FROM verification_results WHERE tenant_id = 'ten_test' AND id = 'verify_test'`}, + {name: "control framework", query: `SELECT count(*) FROM control_frameworks WHERE tenant_id = 'ten_test' AND id = 'framework_test'`}, + {name: "security control", query: `SELECT count(*) FROM security_controls WHERE tenant_id = 'ten_test' AND id = 'control_test' AND evidence_requirements <> '[]'::jsonb`}, + {name: "control evidence", query: `SELECT count(*) FROM control_evidence WHERE tenant_id = 'ten_test' AND id = 'control_evidence_test'`}, {name: "redaction profile", query: `SELECT count(*) FROM redaction_profiles WHERE tenant_id = 'ten_test' AND id = 'redact_test' AND allowed_types = ARRAY['sbom']`}, {name: "customer package", query: `SELECT count(*) FROM customer_security_packages WHERE tenant_id = 'ten_test' AND id = 'pkg_test' AND access_count = 3`}, {name: "html report", query: `SELECT count(*) FROM html_report_packages WHERE tenant_id = 'ten_test' AND id = 'html_test'`}, @@ -282,9 +318,18 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { if relational.SSOSessionHashes["sess_test"] != "session-hash" || relational.SSOSessions["sess_test"].Prefix != "sess" { t.Fatalf("relational sso session = %#v hash=%q", relational.SSOSessions["sess_test"], relational.SSOSessionHashes["sess_test"]) } + if relational.Collectors["collector_test"].APIKeyID != "key_test" || relational.BuildRuns["build_test"].Status != "passed" || len(relational.BuildAttestations["att_test"].SubjectDigests) != 1 { + t.Fatalf("relational build rows missing: collector=%#v build=%#v attestation=%#v", relational.Collectors["collector_test"], relational.BuildRuns["build_test"], relational.BuildAttestations["att_test"]) + } if relational.Products["prod_test"].Slug != "product" || relational.Evidence["ev_test"].ReleaseID != "rel_test" || relational.SBOMs["sbom_test"].ComponentCount != 1 { t.Fatalf("relational fallback missing core rows: product=%#v evidence=%#v sbom=%#v", relational.Products["prod_test"], relational.Evidence["ev_test"], relational.SBOMs["sbom_test"]) } + if relational.VEXDocuments["vex_test"].StatusSummary["not_affected"] != 1 || relational.Decisions["decision_test"].Status != "not_affected" || !relational.Exceptions["exception_test"].Approved { + t.Fatalf("relational risk rows missing: vex=%#v decision=%#v exception=%#v", relational.VEXDocuments["vex_test"], relational.Decisions["decision_test"], relational.Exceptions["exception_test"]) + } + if relational.ControlFrameworks["framework_test"].Slug != "framework" || len(relational.SecurityControls["control_test"].EvidenceRequirements) != 1 || relational.ControlEvidence["control_evidence_test"].Confidence != "high" { + t.Fatalf("relational control rows missing: framework=%#v control=%#v evidence=%#v", relational.ControlFrameworks["framework_test"], relational.SecurityControls["control_test"], relational.ControlEvidence["control_evidence_test"]) + } if relational.Contracts["contract_test"].PathCount != 1 || len(relational.Contracts["contract_test"].Operations) != 1 { t.Fatalf("relational fallback contract = %#v", relational.Contracts["contract_test"]) } From 2918f27251ad0491178f90018cca921b2ada7c64 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 20:50:41 +0300 Subject: [PATCH 094/287] feat: synchronize source deployment rows --- .implementation_increments.md | 2 +- docs/architecture.md | 2 +- docs/reference/production-readiness.md | 26 +- internal/adapters/postgres/store.go | 446 +++++++++++++++++++++++ internal/adapters/postgres/store_test.go | 52 +++ 5 files changed, 515 insertions(+), 13 deletions(-) diff --git a/.implementation_increments.md b/.implementation_increments.md index df0bb44..3cbc26d 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -36,7 +36,7 @@ Status legend: ## Remaining Core Product Increments 6. `[x]` Relational Store Split - Added migration-backed relational tables and tenant-scoped resource projection rows for implemented resources, with transactional PostgreSQL saves, relational identity/idempotency/customer-portal-token rows, relational release-ledger core rows, relational build provenance/VEX/control rows, relational package/report/retention rows, missing-snapshot fallback loading for identity, SSO session, release-ledger, build provenance, VEX/risk decision, control, package, report, and retention families, tenant/release indexes, persisted idempotency state, and outbox row locking. Canonical runtime loading still prefers the versioned ledger snapshot while per-resource repository tuning remains future hardening. + Added migration-backed relational tables and tenant-scoped resource projection rows for implemented resources, with transactional PostgreSQL saves, relational identity/idempotency/customer-portal-token rows, relational release-ledger core rows, relational build provenance/source/deployment/evidence-lifecycle/release-candidate/VEX/control rows, relational package/report/retention rows, missing-snapshot fallback loading for identity, SSO session, release-ledger, build provenance, source/deployment, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, and retention families, tenant/release indexes, persisted idempotency state, and outbox row locking. Canonical runtime loading still prefers the versioned ledger snapshot while per-resource repository tuning remains future hardening. 7. `[x]` Evidence Search, Filtering, And Timeline Querying Added tenant-scoped evidence search by product, project, release, build, deployment, type, subtype, source, collector, created time, subject refs, tags, and verification status. diff --git a/docs/architecture.md b/docs/architecture.md index b49b209..765aa6f 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -10,7 +10,7 @@ Evydence follows a ports-and-adapters shape: - `internal/adapters/objectstore/s3` stores the same tenant-prefixed object keys in S3/MinIO-compatible buckets. - `cmd/*` contains process entry points. -Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity, idempotency, and customer portal token records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. Collector/build provenance, VEX/risk decision, control, package, report, retention, and backup records are synchronized into their migration-backed relational tables. If the snapshot row is absent, the Postgres store can rebuild identity, SSO session, customer portal token, release-ledger core, build provenance, VEX/risk decision, control, package, report, and retention families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. +Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity, idempotency, and customer portal token records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. Collector/build provenance, source/deployment, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, and backup records are synchronized into their migration-backed relational tables. If the snapshot row is absent, the Postgres store can rebuild identity, SSO session, customer portal token, release-ledger core, build provenance, source/deployment, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, and retention families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. ## Tenant And Auth Boundaries diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 984378f..6ac3cf3 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -17,13 +17,15 @@ Known hardening work remains: - canonical production persistence still needs hand-tuned relational repository paths for all high-risk resource families. PostgreSQL now maintains relational identity, idempotency, customer portal token, release-ledger core, - build provenance, VEX/risk decision, control, audit-chain, signing, bundle, - policy, verification, package, report, and retention rows alongside the - canonical snapshot, but the snapshot remains the + build provenance, source/deployment, evidence lifecycle, release candidate, + VEX/risk decision, control, audit-chain, signing, bundle, policy, + verification, package, report, and retention rows alongside the canonical + snapshot, but the snapshot remains the preferred runtime load source. If the snapshot row is absent, the store can rebuild identity, SSO session, customer portal token, release-ledger core, - build provenance, VEX/risk decision, control, package, report, and retention - state from relational rows; + build provenance, source/deployment, evidence lifecycle, release candidate, + VEX/risk decision, control, package, report, and retention state from + relational rows; - worker parser jobs re-read raw object-store payloads for key formats, verify digests, validate durable state, and persist missing parser-derived normalized fields. Upload paths still create initial accepted records, so @@ -102,12 +104,14 @@ implemented capabilities: - Replace canonical snapshot writes with dependency-ordered relational repositories for remaining secondary resources. Identity, idempotency, - customer portal token, release-ledger core, build provenance, VEX/risk - decision, control, audit-chain, signing, bundle, policy, verification, - package, report, and retention rows are synchronized into relational tables. - Missing-snapshot recovery can rebuild identity, SSO session, customer portal - token, release-ledger core, build provenance, VEX/risk decision, control, - package, report, and retention families from relational rows. + customer portal token, release-ledger core, build provenance, + source/deployment, evidence lifecycle, release candidate, VEX/risk decision, + control, audit-chain, signing, bundle, policy, verification, package, report, + and retention rows are synchronized into relational tables. Missing-snapshot + recovery can rebuild identity, SSO session, customer portal token, + release-ledger core, build provenance, source/deployment, evidence lifecycle, + release candidate, VEX/risk decision, control, package, report, and + retention families from relational rows. Keep snapshots only for export/import and upgrade compatibility after the remaining families have repository-backed reads and writes. - Split the large application ledger aggregate into focused services or diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index e24c1eb..da04f9f 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -84,6 +84,9 @@ func (s *Store) loadRelationalState(ctx context.Context) (app.PersistedState, bo if err := s.loadRelationalRiskBuildControls(ctx, &state, &loaded); err != nil { return app.PersistedState{}, false, err } + if err := s.loadRelationalSourceDeploymentLifecycle(ctx, &state, &loaded); err != nil { + return app.PersistedState{}, false, err + } if err := s.loadRelationalPackageReportRetention(ctx, &state, &loaded); err != nil { return app.PersistedState{}, false, err } @@ -108,6 +111,16 @@ func relationalEmptyState() app.PersistedState { Collectors: map[string]domain.Collector{}, BuildRuns: map[string]domain.BuildRun{}, BuildAttestations: map[string]domain.BuildAttestation{}, + EvidenceLifecycle: map[string]domain.EvidenceLifecycleEvent{}, + ReleaseCandidates: map[string]domain.ReleaseCandidate{}, + ContainerImages: map[string]domain.ContainerImage{}, + ArtifactSignatures: map[string]domain.ArtifactSignature{}, + Repositories: map[string]domain.SourceRepository{}, + Commits: map[string]domain.SourceCommit{}, + Branches: map[string]domain.SourceBranch{}, + PullRequests: map[string]domain.PullRequest{}, + Environments: map[string]domain.DeploymentEnvironment{}, + Deployments: map[string]domain.DeploymentEvent{}, CustomerPortalAccess: map[string]domain.CustomerPortalAccess{}, CustomerPortalHashes: map[string]string{}, RedactionProfiles: map[string]domain.RedactionProfile{}, @@ -1087,6 +1100,241 @@ func (s *Store) loadRelationalControls(ctx context.Context, state *app.Persisted return evidenceRows.Err() } +func (s *Store) loadRelationalSourceDeploymentLifecycle(ctx context.Context, state *app.PersistedState, loaded *bool) error { + if err := s.loadRelationalLifecycleAndCandidates(ctx, state, loaded); err != nil { + return err + } + if err := s.loadRelationalContainerAndSignatures(ctx, state, loaded); err != nil { + return err + } + if err := s.loadRelationalSource(ctx, state, loaded); err != nil { + return err + } + if err := s.loadRelationalDeployments(ctx, state, loaded); err != nil { + return err + } + return nil +} + +func (s *Store) loadRelationalLifecycleAndCandidates(ctx context.Context, state *app.PersistedState, loaded *bool) error { + lifecycleRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, evidence_id, action, reason, details, replacement_id, actor_id, schema_version, created_at FROM evidence_lifecycle_events`) + if err != nil { + return fmt.Errorf("load relational evidence lifecycle: %w", err) + } + defer lifecycleRows.Close() + for lifecycleRows.Next() { + var event domain.EvidenceLifecycleEvent + var details []byte + var replacementID sql.NullString + if err := lifecycleRows.Scan(&event.ID, &event.TenantID, &event.EvidenceID, &event.Action, &event.Reason, &details, &replacementID, &event.ActorID, &event.SchemaVersion, &event.CreatedAt); err != nil { + return fmt.Errorf("scan relational evidence lifecycle: %w", err) + } + event.ReplacementID = nullableSQLString(replacementID) + if err := decodeJSON(details, &event.Details); err != nil { + return fmt.Errorf("decode relational evidence lifecycle details: %w", err) + } + state.EvidenceLifecycle[event.ID] = event + *loaded = true + } + if err := lifecycleRows.Err(); err != nil { + return err + } + + candidateRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, release_id, name, state, snapshot_hash, document, schema_version, created_at, promoted_at, rejected_at FROM release_candidates`) + if err != nil { + return fmt.Errorf("load relational release candidates: %w", err) + } + defer candidateRows.Close() + for candidateRows.Next() { + var candidate domain.ReleaseCandidate + var document []byte + var promotedAt, rejectedAt sql.NullTime + if err := candidateRows.Scan(&candidate.ID, &candidate.TenantID, &candidate.ReleaseID, &candidate.Name, &candidate.State, &candidate.SnapshotHash, &document, &candidate.SchemaVersion, &candidate.CreatedAt, &promotedAt, &rejectedAt); err != nil { + return fmt.Errorf("scan relational release candidate: %w", err) + } + var embedded domain.ReleaseCandidate + if err := decodeJSON(document, &embedded); err != nil { + return fmt.Errorf("decode relational release candidate document: %w", err) + } + candidate.BuildIDs = embedded.BuildIDs + candidate.ArtifactIDs = embedded.ArtifactIDs + candidate.SBOMIDs = embedded.SBOMIDs + candidate.ScanIDs = embedded.ScanIDs + candidate.VEXIDs = embedded.VEXIDs + candidate.ContractIDs = embedded.ContractIDs + candidate.BundleIDs = embedded.BundleIDs + candidate.PromotedAt = nullableSQLTime(promotedAt) + candidate.RejectedAt = nullableSQLTime(rejectedAt) + state.ReleaseCandidates[candidate.ID] = candidate + *loaded = true + } + return candidateRows.Err() +} + +func (s *Store) loadRelationalContainerAndSignatures(ctx context.Context, state *app.PersistedState, loaded *bool) error { + imageRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, artifact_id, repository, tag, digest, platform, schema_version, created_at FROM container_images`) + if err != nil { + return fmt.Errorf("load relational container images: %w", err) + } + defer imageRows.Close() + for imageRows.Next() { + var image domain.ContainerImage + var artifactID, tag, platform sql.NullString + if err := imageRows.Scan(&image.ID, &image.TenantID, &artifactID, &image.Repository, &tag, &image.Digest, &platform, &image.SchemaVersion, &image.CreatedAt); err != nil { + return fmt.Errorf("scan relational container image: %w", err) + } + image.ArtifactID = nullableSQLString(artifactID) + image.Tag = nullableSQLString(tag) + image.Platform = nullableSQLString(platform) + state.ContainerImages[image.ID] = image + *loaded = true + } + if err := imageRows.Err(); err != nil { + return err + } + + signatureRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, artifact_id, subject_digest, algorithm, key_id, signature, payload_ref, payload_hash, verification_status, schema_version, created_at FROM artifact_signatures`) + if err != nil { + return fmt.Errorf("load relational artifact signatures: %w", err) + } + defer signatureRows.Close() + for signatureRows.Next() { + var signature domain.ArtifactSignature + var keyID, payloadRef, payloadHash sql.NullString + if err := signatureRows.Scan(&signature.ID, &signature.TenantID, &signature.ArtifactID, &signature.SubjectDigest, &signature.Algorithm, &keyID, &signature.Signature, &payloadRef, &payloadHash, &signature.VerificationStatus, &signature.SchemaVersion, &signature.CreatedAt); err != nil { + return fmt.Errorf("scan relational artifact signature: %w", err) + } + signature.KeyID = nullableSQLString(keyID) + signature.PayloadRef = nullableSQLString(payloadRef) + signature.PayloadHash = nullableSQLString(payloadHash) + state.ArtifactSignatures[signature.ID] = signature + *loaded = true + } + return signatureRows.Err() +} + +func (s *Store) loadRelationalSource(ctx context.Context, state *app.PersistedState, loaded *bool) error { + repositoryRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, project_id, provider, full_name, clone_url, default_branch, schema_version, created_at FROM source_repositories`) + if err != nil { + return fmt.Errorf("load relational source repositories: %w", err) + } + defer repositoryRows.Close() + for repositoryRows.Next() { + var repository domain.SourceRepository + var projectID, cloneURL, defaultBranch sql.NullString + if err := repositoryRows.Scan(&repository.ID, &repository.TenantID, &projectID, &repository.Provider, &repository.FullName, &cloneURL, &defaultBranch, &repository.SchemaVersion, &repository.CreatedAt); err != nil { + return fmt.Errorf("scan relational source repository: %w", err) + } + repository.ProjectID = nullableSQLString(projectID) + repository.CloneURL = nullableSQLString(cloneURL) + repository.DefaultBranch = nullableSQLString(defaultBranch) + state.Repositories[repository.ID] = repository + *loaded = true + } + if err := repositoryRows.Err(); err != nil { + return err + } + + commitRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, repository_id, sha, author, message_hash, committed_at, schema_version, created_at FROM source_commits`) + if err != nil { + return fmt.Errorf("load relational source commits: %w", err) + } + defer commitRows.Close() + for commitRows.Next() { + var commit domain.SourceCommit + var author, messageHash sql.NullString + if err := commitRows.Scan(&commit.ID, &commit.TenantID, &commit.RepositoryID, &commit.SHA, &author, &messageHash, &commit.CommittedAt, &commit.SchemaVersion, &commit.CreatedAt); err != nil { + return fmt.Errorf("scan relational source commit: %w", err) + } + commit.Author = nullableSQLString(author) + commit.MessageHash = nullableSQLString(messageHash) + state.Commits[commit.ID] = commit + *loaded = true + } + if err := commitRows.Err(); err != nil { + return err + } + + branchRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, repository_id, name, head_commit_id, protected, protection_hash, schema_version, created_at FROM source_branches`) + if err != nil { + return fmt.Errorf("load relational source branches: %w", err) + } + defer branchRows.Close() + for branchRows.Next() { + var branch domain.SourceBranch + var headCommitID, protectionHash sql.NullString + if err := branchRows.Scan(&branch.ID, &branch.TenantID, &branch.RepositoryID, &branch.Name, &headCommitID, &branch.Protected, &protectionHash, &branch.SchemaVersion, &branch.CreatedAt); err != nil { + return fmt.Errorf("scan relational source branch: %w", err) + } + branch.HeadCommitID = nullableSQLString(headCommitID) + branch.ProtectionHash = nullableSQLString(protectionHash) + state.Branches[branch.ID] = branch + *loaded = true + } + if err := branchRows.Err(); err != nil { + return err + } + + prRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, repository_id, provider, provider_id, title, state, source_branch, target_branch, head_commit_id, review_decision, schema_version, created_at FROM pull_requests`) + if err != nil { + return fmt.Errorf("load relational pull requests: %w", err) + } + defer prRows.Close() + for prRows.Next() { + var pr domain.PullRequest + var sourceBranch, targetBranch, headCommitID, reviewDecision sql.NullString + if err := prRows.Scan(&pr.ID, &pr.TenantID, &pr.RepositoryID, &pr.Provider, &pr.ProviderID, &pr.Title, &pr.State, &sourceBranch, &targetBranch, &headCommitID, &reviewDecision, &pr.SchemaVersion, &pr.CreatedAt); err != nil { + return fmt.Errorf("scan relational pull request: %w", err) + } + pr.SourceBranch = nullableSQLString(sourceBranch) + pr.TargetBranch = nullableSQLString(targetBranch) + pr.HeadCommitID = nullableSQLString(headCommitID) + pr.ReviewDecision = nullableSQLString(reviewDecision) + state.PullRequests[pr.ID] = pr + *loaded = true + } + return prRows.Err() +} + +func (s *Store) loadRelationalDeployments(ctx context.Context, state *app.PersistedState, loaded *bool) error { + environmentRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, product_id, name, kind, schema_version, created_at FROM deployment_environments`) + if err != nil { + return fmt.Errorf("load relational deployment environments: %w", err) + } + defer environmentRows.Close() + for environmentRows.Next() { + var environment domain.DeploymentEnvironment + if err := environmentRows.Scan(&environment.ID, &environment.TenantID, &environment.ProductID, &environment.Name, &environment.Kind, &environment.SchemaVersion, &environment.CreatedAt); err != nil { + return fmt.Errorf("scan relational deployment environment: %w", err) + } + state.Environments[environment.ID] = environment + *loaded = true + } + if err := environmentRows.Err(); err != nil { + return err + } + + deploymentRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, environment_id, release_id, artifact_ids, status, started_at, finished_at, rollback_of, evidence_id, schema_version, created_at FROM deployment_events`) + if err != nil { + return fmt.Errorf("load relational deployment events: %w", err) + } + defer deploymentRows.Close() + for deploymentRows.Next() { + var deployment domain.DeploymentEvent + var finishedAt sql.NullTime + var rollbackOf, evidenceID sql.NullString + if err := deploymentRows.Scan(&deployment.ID, &deployment.TenantID, &deployment.EnvironmentID, &deployment.ReleaseID, &deployment.ArtifactIDs, &deployment.Status, &deployment.StartedAt, &finishedAt, &rollbackOf, &evidenceID, &deployment.SchemaVersion, &deployment.CreatedAt); err != nil { + return fmt.Errorf("scan relational deployment event: %w", err) + } + deployment.FinishedAt = nullableSQLTime(finishedAt) + deployment.RollbackOf = nullableSQLString(rollbackOf) + deployment.EvidenceID = nullableSQLString(evidenceID) + state.Deployments[deployment.ID] = deployment + *loaded = true + } + return deploymentRows.Err() +} + func (s *Store) loadRelationalPackageReportRetention(ctx context.Context, state *app.PersistedState, loaded *bool) error { if err := s.loadRelationalPackages(ctx, state, loaded); err != nil { return err @@ -1465,6 +1713,9 @@ func (s *Store) SaveState(ctx context.Context, state app.PersistedState) error { if err := syncRiskBuildControlRows(ctx, tx, state); err != nil { return err } + if err := syncSourceDeploymentLifecycleRows(ctx, tx, state); err != nil { + return err + } if err := syncPackageReportRetentionRows(ctx, tx, state); err != nil { return err } @@ -2050,6 +2301,201 @@ func syncRiskBuildControlRows(ctx context.Context, tx pgx.Tx, state app.Persiste return nil } +func syncSourceDeploymentLifecycleRows(ctx context.Context, tx pgx.Tx, state app.PersistedState) error { + for _, event := range state.EvidenceLifecycle { + if event.ID == "" || event.TenantID == "" || event.EvidenceID == "" { + continue + } + details, err := json.Marshal(event.Details) + if err != nil { + return fmt.Errorf("encode evidence lifecycle details: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO evidence_lifecycle_events ( + id, tenant_id, evidence_id, action, reason, details, + replacement_id, actor_id, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) + ON CONFLICT (id) DO NOTHING + `, event.ID, event.TenantID, event.EvidenceID, event.Action, event.Reason, details, + nullableString(event.ReplacementID), event.ActorID, event.SchemaVersion, nonZeroTime(event.CreatedAt)); err != nil { + return fmt.Errorf("insert evidence lifecycle row: %w", err) + } + } + for _, candidate := range state.ReleaseCandidates { + if candidate.ID == "" || candidate.TenantID == "" || candidate.ReleaseID == "" { + continue + } + document, err := json.Marshal(candidate) + if err != nil { + return fmt.Errorf("encode release candidate document: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO release_candidates ( + id, tenant_id, release_id, name, state, snapshot_hash, + document, schema_version, created_at, promoted_at, rejected_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) + ON CONFLICT (id) DO UPDATE SET + state = EXCLUDED.state, + document = EXCLUDED.document, + promoted_at = EXCLUDED.promoted_at, + rejected_at = EXCLUDED.rejected_at + `, candidate.ID, candidate.TenantID, candidate.ReleaseID, candidate.Name, candidate.State, candidate.SnapshotHash, + document, candidate.SchemaVersion, nonZeroTime(candidate.CreatedAt), nullableTime(candidate.PromotedAt), nullableTime(candidate.RejectedAt)); err != nil { + return fmt.Errorf("upsert release candidate row: %w", err) + } + } + for _, image := range state.ContainerImages { + if image.ID == "" || image.TenantID == "" || image.Repository == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO container_images ( + id, tenant_id, artifact_id, repository, tag, digest, + platform, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + ON CONFLICT (id) DO UPDATE SET + tag = EXCLUDED.tag, + platform = EXCLUDED.platform + `, image.ID, image.TenantID, nullableString(image.ArtifactID), image.Repository, nullableString(image.Tag), image.Digest, + nullableString(image.Platform), image.SchemaVersion, nonZeroTime(image.CreatedAt)); err != nil { + return fmt.Errorf("upsert container image row: %w", err) + } + } + for _, signature := range state.ArtifactSignatures { + if signature.ID == "" || signature.TenantID == "" || signature.ArtifactID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO artifact_signatures ( + id, tenant_id, artifact_id, subject_digest, algorithm, key_id, + signature, payload_ref, payload_hash, verification_status, + schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) + ON CONFLICT (id) DO UPDATE SET + payload_ref = EXCLUDED.payload_ref, + payload_hash = EXCLUDED.payload_hash, + verification_status = EXCLUDED.verification_status + `, signature.ID, signature.TenantID, signature.ArtifactID, signature.SubjectDigest, signature.Algorithm, nullableString(signature.KeyID), + signature.Signature, nullableString(signature.PayloadRef), nullableString(signature.PayloadHash), signature.VerificationStatus, + signature.SchemaVersion, nonZeroTime(signature.CreatedAt)); err != nil { + return fmt.Errorf("upsert artifact signature row: %w", err) + } + } + for _, repository := range state.Repositories { + if repository.ID == "" || repository.TenantID == "" || repository.FullName == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO source_repositories ( + id, tenant_id, project_id, provider, full_name, clone_url, + default_branch, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + ON CONFLICT (id) DO UPDATE SET + clone_url = EXCLUDED.clone_url, + default_branch = EXCLUDED.default_branch + `, repository.ID, repository.TenantID, nullableString(repository.ProjectID), repository.Provider, repository.FullName, nullableString(repository.CloneURL), + nullableString(repository.DefaultBranch), repository.SchemaVersion, nonZeroTime(repository.CreatedAt)); err != nil { + return fmt.Errorf("upsert source repository row: %w", err) + } + } + for _, commit := range state.Commits { + if commit.ID == "" || commit.TenantID == "" || commit.RepositoryID == "" || commit.SHA == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO source_commits ( + id, tenant_id, repository_id, sha, author, message_hash, + committed_at, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + ON CONFLICT (id) DO UPDATE SET message_hash = EXCLUDED.message_hash + `, commit.ID, commit.TenantID, commit.RepositoryID, commit.SHA, nullableString(commit.Author), nullableString(commit.MessageHash), + nonZeroTime(commit.CommittedAt), commit.SchemaVersion, nonZeroTime(commit.CreatedAt)); err != nil { + return fmt.Errorf("upsert source commit row: %w", err) + } + } + for _, branch := range state.Branches { + if branch.ID == "" || branch.TenantID == "" || branch.RepositoryID == "" || branch.Name == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO source_branches ( + id, tenant_id, repository_id, name, head_commit_id, protected, + protection_hash, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + ON CONFLICT (id) DO UPDATE SET + head_commit_id = EXCLUDED.head_commit_id, + protected = EXCLUDED.protected, + protection_hash = EXCLUDED.protection_hash + `, branch.ID, branch.TenantID, branch.RepositoryID, branch.Name, nullableString(branch.HeadCommitID), branch.Protected, + nullableString(branch.ProtectionHash), branch.SchemaVersion, nonZeroTime(branch.CreatedAt)); err != nil { + return fmt.Errorf("upsert source branch row: %w", err) + } + } + for _, pr := range state.PullRequests { + if pr.ID == "" || pr.TenantID == "" || pr.RepositoryID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO pull_requests ( + id, tenant_id, repository_id, provider, provider_id, title, + state, source_branch, target_branch, head_commit_id, + review_decision, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13) + ON CONFLICT (id) DO UPDATE SET + state = EXCLUDED.state, + head_commit_id = EXCLUDED.head_commit_id, + review_decision = EXCLUDED.review_decision + `, pr.ID, pr.TenantID, pr.RepositoryID, pr.Provider, pr.ProviderID, pr.Title, + pr.State, nullableString(pr.SourceBranch), nullableString(pr.TargetBranch), nullableString(pr.HeadCommitID), + nullableString(pr.ReviewDecision), pr.SchemaVersion, nonZeroTime(pr.CreatedAt)); err != nil { + return fmt.Errorf("upsert pull request row: %w", err) + } + } + for _, environment := range state.Environments { + if environment.ID == "" || environment.TenantID == "" || environment.ProductID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO deployment_environments ( + id, tenant_id, product_id, name, kind, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7) + ON CONFLICT (id) DO UPDATE SET kind = EXCLUDED.kind + `, environment.ID, environment.TenantID, environment.ProductID, environment.Name, environment.Kind, environment.SchemaVersion, nonZeroTime(environment.CreatedAt)); err != nil { + return fmt.Errorf("upsert deployment environment row: %w", err) + } + } + for _, deployment := range state.Deployments { + if deployment.ID == "" || deployment.TenantID == "" || deployment.EnvironmentID == "" || deployment.ReleaseID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO deployment_events ( + id, tenant_id, environment_id, release_id, artifact_ids, + status, started_at, finished_at, rollback_of, evidence_id, + schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) + ON CONFLICT (id) DO UPDATE SET + status = EXCLUDED.status, + finished_at = EXCLUDED.finished_at + `, deployment.ID, deployment.TenantID, deployment.EnvironmentID, deployment.ReleaseID, deployment.ArtifactIDs, + deployment.Status, nonZeroTime(deployment.StartedAt), nullableTime(deployment.FinishedAt), nullableString(deployment.RollbackOf), nullableString(deployment.EvidenceID), + deployment.SchemaVersion, nonZeroTime(deployment.CreatedAt)); err != nil { + return fmt.Errorf("upsert deployment event row: %w", err) + } + } + return nil +} + func syncPackageReportRetentionRows(ctx context.Context, tx pgx.Tx, state app.PersistedState) error { for _, profile := range state.RedactionProfiles { if profile.ID == "" || profile.TenantID == "" { diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index a2eb97a..32305aa 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -92,6 +92,36 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { Tags: []string{"release"}, Metadata: map[string]any{"parser": "test"}, CreatedAt: time.Now().UTC(), }, }, + EvidenceLifecycle: map[string]domain.EvidenceLifecycleEvent{ + "life_test": {ID: "life_test", TenantID: "ten_test", EvidenceID: "ev_test", Action: "amended", Reason: "test", Details: map[string]any{"field": "metadata"}, ActorID: "user_test", SchemaVersion: domain.EvidenceLifecycleSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + ReleaseCandidates: map[string]domain.ReleaseCandidate{ + "rc_test": {ID: "rc_test", TenantID: "ten_test", ReleaseID: "rel_test", Name: "rc1", State: "open", BuildIDs: []string{"build_test"}, ArtifactIDs: []string{"art_test"}, SBOMIDs: []string{"sbom_test"}, ScanIDs: []string{"scan_test"}, VEXIDs: []string{"vex_test"}, ContractIDs: []string{"contract_test"}, BundleIDs: []string{"bundle_test"}, SnapshotHash: "sha256:" + strings.Repeat("0", 64), SchemaVersion: domain.ReleaseCandidateSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + ContainerImages: map[string]domain.ContainerImage{ + "image_test": {ID: "image_test", TenantID: "ten_test", ArtifactID: "art_test", Repository: "registry.example.test/product", Tag: "1.0.0", Digest: "sha256:" + strings.Repeat("a", 64), Platform: "linux/amd64", SchemaVersion: domain.ContainerImageSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + ArtifactSignatures: map[string]domain.ArtifactSignature{ + "artsig_test": {ID: "artsig_test", TenantID: "ten_test", ArtifactID: "art_test", SubjectDigest: "sha256:" + strings.Repeat("a", 64), Algorithm: "cosign", KeyID: "sigkey_test", Signature: "signature", PayloadRef: "object://tenants/ten_test/signatures/art", PayloadHash: "sha256:" + strings.Repeat("a", 64), VerificationStatus: "verified", SchemaVersion: domain.ArtifactSignatureSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + Repositories: map[string]domain.SourceRepository{ + "repo_test": {ID: "repo_test", TenantID: "ten_test", ProjectID: "proj_test", Provider: "github", FullName: "org/repo", CloneURL: "https://github.com/org/repo.git", DefaultBranch: "main", SchemaVersion: domain.SourceRepositorySchemaVersion, CreatedAt: time.Now().UTC()}, + }, + Commits: map[string]domain.SourceCommit{ + "commit_test": {ID: "commit_test", TenantID: "ten_test", RepositoryID: "repo_test", SHA: strings.Repeat("1", 40), Author: "tester", MessageHash: "sha256:" + strings.Repeat("2", 64), CommittedAt: time.Now().UTC(), SchemaVersion: domain.SourceCommitSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + Branches: map[string]domain.SourceBranch{ + "branch_test": {ID: "branch_test", TenantID: "ten_test", RepositoryID: "repo_test", Name: "main", HeadCommitID: "commit_test", Protected: true, ProtectionHash: "sha256:" + strings.Repeat("3", 64), SchemaVersion: domain.SourceBranchSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + PullRequests: map[string]domain.PullRequest{ + "pr_test": {ID: "pr_test", TenantID: "ten_test", RepositoryID: "repo_test", Provider: "github", ProviderID: "42", Title: "Change", State: "merged", SourceBranch: "feature", TargetBranch: "main", HeadCommitID: "commit_test", ReviewDecision: "approved", SchemaVersion: domain.PullRequestSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + Environments: map[string]domain.DeploymentEnvironment{ + "env_test": {ID: "env_test", TenantID: "ten_test", ProductID: "prod_test", Name: "production", Kind: "production", SchemaVersion: domain.DeploymentEnvironmentVersion, CreatedAt: time.Now().UTC()}, + }, + Deployments: map[string]domain.DeploymentEvent{ + "deploy_test": {ID: "deploy_test", TenantID: "ten_test", EnvironmentID: "env_test", ReleaseID: "rel_test", ArtifactIDs: []string{"art_test"}, Status: "succeeded", StartedAt: time.Now().UTC(), FinishedAt: ptrTime(time.Now().UTC()), EvidenceID: "ev_test", SchemaVersion: domain.DeploymentEventSchemaVersion, CreatedAt: time.Now().UTC()}, + }, Chain: map[string][]domain.AuditChainEntry{ "ten_test": {{ ID: "chain_test", TenantID: "ten_test", Sequence: 1, EntryType: "evidence.created", SubjectType: "evidence_item", SubjectID: "ev_test", @@ -256,6 +286,16 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { {name: "build run", query: `SELECT count(*) FROM build_runs WHERE tenant_id = 'ten_test' AND id = 'build_test' AND outputs <> '[]'::jsonb`}, {name: "build attestation", query: `SELECT count(*) FROM build_attestations WHERE tenant_id = 'ten_test' AND id = 'att_test' AND subject_digests <> '[]'::jsonb`}, {name: "evidence", query: `SELECT count(*) FROM evidence_items WHERE tenant_id = 'ten_test' AND id = 'ev_test' AND evidence_version = 1 AND product_id = 'prod_test'`}, + {name: "evidence lifecycle", query: `SELECT count(*) FROM evidence_lifecycle_events WHERE tenant_id = 'ten_test' AND id = 'life_test' AND details <> '{}'::jsonb`}, + {name: "release candidate", query: `SELECT count(*) FROM release_candidates WHERE tenant_id = 'ten_test' AND id = 'rc_test' AND document <> '{}'::jsonb`}, + {name: "container image", query: `SELECT count(*) FROM container_images WHERE tenant_id = 'ten_test' AND id = 'image_test'`}, + {name: "artifact signature", query: `SELECT count(*) FROM artifact_signatures WHERE tenant_id = 'ten_test' AND id = 'artsig_test'`}, + {name: "source repository", query: `SELECT count(*) FROM source_repositories WHERE tenant_id = 'ten_test' AND id = 'repo_test'`}, + {name: "source commit", query: `SELECT count(*) FROM source_commits WHERE tenant_id = 'ten_test' AND id = 'commit_test'`}, + {name: "source branch", query: `SELECT count(*) FROM source_branches WHERE tenant_id = 'ten_test' AND id = 'branch_test' AND protected = true`}, + {name: "pull request", query: `SELECT count(*) FROM pull_requests WHERE tenant_id = 'ten_test' AND id = 'pr_test' AND review_decision = 'approved'`}, + {name: "deployment environment", query: `SELECT count(*) FROM deployment_environments WHERE tenant_id = 'ten_test' AND id = 'env_test'`}, + {name: "deployment event", query: `SELECT count(*) FROM deployment_events WHERE tenant_id = 'ten_test' AND id = 'deploy_test' AND artifact_ids = ARRAY['art_test']`}, {name: "audit chain", query: `SELECT count(*) FROM audit_chain_entries WHERE tenant_id = 'ten_test' AND sequence = 1`}, {name: "signing key", query: `SELECT count(*) FROM signing_keys WHERE tenant_id = 'ten_test' AND id = 'sigkey_test' AND encrypted_private_key IS NOT NULL`}, {name: "signature", query: `SELECT count(*) FROM signatures WHERE tenant_id = 'ten_test' AND id = 'sig_test'`}, @@ -321,6 +361,18 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { if relational.Collectors["collector_test"].APIKeyID != "key_test" || relational.BuildRuns["build_test"].Status != "passed" || len(relational.BuildAttestations["att_test"].SubjectDigests) != 1 { t.Fatalf("relational build rows missing: collector=%#v build=%#v attestation=%#v", relational.Collectors["collector_test"], relational.BuildRuns["build_test"], relational.BuildAttestations["att_test"]) } + if relational.EvidenceLifecycle["life_test"].Details["field"] != "metadata" || len(relational.ReleaseCandidates["rc_test"].BuildIDs) != 1 { + t.Fatalf("relational lifecycle/candidate rows missing: lifecycle=%#v candidate=%#v", relational.EvidenceLifecycle["life_test"], relational.ReleaseCandidates["rc_test"]) + } + if relational.ContainerImages["image_test"].Repository == "" || relational.ArtifactSignatures["artsig_test"].VerificationStatus != "verified" { + t.Fatalf("relational artifact image rows missing: image=%#v signature=%#v", relational.ContainerImages["image_test"], relational.ArtifactSignatures["artsig_test"]) + } + if relational.Repositories["repo_test"].FullName != "org/repo" || relational.Commits["commit_test"].SHA == "" || !relational.Branches["branch_test"].Protected || relational.PullRequests["pr_test"].ReviewDecision != "approved" { + t.Fatalf("relational source rows missing: repo=%#v commit=%#v branch=%#v pr=%#v", relational.Repositories["repo_test"], relational.Commits["commit_test"], relational.Branches["branch_test"], relational.PullRequests["pr_test"]) + } + if relational.Environments["env_test"].Name != "production" || relational.Deployments["deploy_test"].Status != "succeeded" { + t.Fatalf("relational deployment rows missing: env=%#v deployment=%#v", relational.Environments["env_test"], relational.Deployments["deploy_test"]) + } if relational.Products["prod_test"].Slug != "product" || relational.Evidence["ev_test"].ReleaseID != "rel_test" || relational.SBOMs["sbom_test"].ComponentCount != 1 { t.Fatalf("relational fallback missing core rows: product=%#v evidence=%#v sbom=%#v", relational.Products["prod_test"], relational.Evidence["ev_test"], relational.SBOMs["sbom_test"]) } From 49ddd76562f728fcdd3ee1d429481a62eaee9087 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 20:53:43 +0300 Subject: [PATCH 095/287] feat: synchronize incident security rows --- .implementation_increments.md | 2 +- docs/architecture.md | 2 +- docs/reference/production-readiness.md | 32 +- internal/adapters/postgres/store.go | 803 +++++++++++++++++++++-- internal/adapters/postgres/store_test.go | 88 +++ 5 files changed, 850 insertions(+), 77 deletions(-) diff --git a/.implementation_increments.md b/.implementation_increments.md index 3cbc26d..ad63cde 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -36,7 +36,7 @@ Status legend: ## Remaining Core Product Increments 6. `[x]` Relational Store Split - Added migration-backed relational tables and tenant-scoped resource projection rows for implemented resources, with transactional PostgreSQL saves, relational identity/idempotency/customer-portal-token rows, relational release-ledger core rows, relational build provenance/source/deployment/evidence-lifecycle/release-candidate/VEX/control rows, relational package/report/retention rows, missing-snapshot fallback loading for identity, SSO session, release-ledger, build provenance, source/deployment, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, and retention families, tenant/release indexes, persisted idempotency state, and outbox row locking. Canonical runtime loading still prefers the versioned ledger snapshot while per-resource repository tuning remains future hardening. + Added migration-backed relational tables and tenant-scoped resource projection rows for implemented resources, with transactional PostgreSQL saves, relational identity/idempotency/customer-portal-token rows, relational release-ledger core rows, relational build provenance/source/deployment/incident/security-evidence/SBOM-diff/vulnerability-workflow/contract-diff/custom-policy/waiver/approval/DSSE-trust-root/evidence-lifecycle/release-candidate/VEX/control rows, relational package/report/retention rows, missing-snapshot fallback loading for identity, SSO session, release-ledger, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, and retention families, tenant/release indexes, persisted idempotency state, and outbox row locking. Canonical runtime loading still prefers the versioned ledger snapshot while per-resource repository tuning remains future hardening. 7. `[x]` Evidence Search, Filtering, And Timeline Querying Added tenant-scoped evidence search by product, project, release, build, deployment, type, subtype, source, collector, created time, subject refs, tags, and verification status. diff --git a/docs/architecture.md b/docs/architecture.md index 765aa6f..7ed5b8b 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -10,7 +10,7 @@ Evydence follows a ports-and-adapters shape: - `internal/adapters/objectstore/s3` stores the same tenant-prefixed object keys in S3/MinIO-compatible buckets. - `cmd/*` contains process entry points. -Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity, idempotency, and customer portal token records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. Collector/build provenance, source/deployment, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, and backup records are synchronized into their migration-backed relational tables. If the snapshot row is absent, the Postgres store can rebuild identity, SSO session, customer portal token, release-ledger core, build provenance, source/deployment, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, and retention families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. +Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity, idempotency, and customer portal token records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. Collector/build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, and backup records are synchronized into their migration-backed relational tables. If the snapshot row is absent, the Postgres store can rebuild identity, SSO session, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, and retention families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. ## Tenant And Auth Boundaries diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 6ac3cf3..66476ba 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -17,15 +17,17 @@ Known hardening work remains: - canonical production persistence still needs hand-tuned relational repository paths for all high-risk resource families. PostgreSQL now maintains relational identity, idempotency, customer portal token, release-ledger core, - build provenance, source/deployment, evidence lifecycle, release candidate, - VEX/risk decision, control, audit-chain, signing, bundle, policy, - verification, package, report, and retention rows alongside the canonical - snapshot, but the snapshot remains the + build provenance, source/deployment, incident, security evidence, SBOM diff, + vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE + trust-root, evidence lifecycle, release candidate, VEX/risk decision, + control, audit-chain, signing, bundle, policy, verification, package, report, + and retention rows alongside the canonical snapshot, but the snapshot remains the preferred runtime load source. If the snapshot row is absent, the store can rebuild identity, SSO session, customer portal token, release-ledger core, - build provenance, source/deployment, evidence lifecycle, release candidate, - VEX/risk decision, control, package, report, and retention state from - relational rows; + build provenance, source/deployment, incident, security evidence, SBOM diff, + vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE + trust-root, evidence lifecycle, release candidate, VEX/risk decision, control, + package, report, and retention state from relational rows; - worker parser jobs re-read raw object-store payloads for key formats, verify digests, validate durable state, and persist missing parser-derived normalized fields. Upload paths still create initial accepted records, so @@ -105,13 +107,17 @@ implemented capabilities: - Replace canonical snapshot writes with dependency-ordered relational repositories for remaining secondary resources. Identity, idempotency, customer portal token, release-ledger core, build provenance, - source/deployment, evidence lifecycle, release candidate, VEX/risk decision, - control, audit-chain, signing, bundle, policy, verification, package, report, - and retention rows are synchronized into relational tables. Missing-snapshot + source/deployment, incident, security evidence, SBOM diff, vulnerability + workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, + evidence lifecycle, release candidate, VEX/risk decision, control, + audit-chain, signing, bundle, policy, verification, package, report, and + retention rows are synchronized into relational tables. Missing-snapshot recovery can rebuild identity, SSO session, customer portal token, - release-ledger core, build provenance, source/deployment, evidence lifecycle, - release candidate, VEX/risk decision, control, package, report, and - retention families from relational rows. + release-ledger core, build provenance, source/deployment, incident, security + evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, + waiver, approval, DSSE trust-root, evidence lifecycle, release candidate, + VEX/risk decision, control, package, report, and retention families from + relational rows. Keep snapshots only for export/import and upgrade compatibility after the remaining families have repository-backed reads and writes. - Split the large application ledger aggregate into focused services or diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index da04f9f..304fe93 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -87,6 +87,9 @@ func (s *Store) loadRelationalState(ctx context.Context) (app.PersistedState, bo if err := s.loadRelationalSourceDeploymentLifecycle(ctx, &state, &loaded); err != nil { return app.PersistedState{}, false, err } + if err := s.loadRelationalIncidentSecurityGovernance(ctx, &state, &loaded); err != nil { + return app.PersistedState{}, false, err + } if err := s.loadRelationalPackageReportRetention(ctx, &state, &loaded); err != nil { return app.PersistedState{}, false, err } @@ -98,68 +101,84 @@ func (s *Store) loadRelationalState(ctx context.Context) (app.PersistedState, bo func relationalEmptyState() app.PersistedState { return app.PersistedState{ - Tenants: map[string]domain.Tenant{}, - Organizations: map[string]domain.Organization{}, - Users: map[string]domain.HumanUser{}, - RoleBindings: map[string]domain.RoleBinding{}, - SSOProviders: map[string]domain.SSOProvider{}, - IdentityLinks: map[string]domain.UserIdentityLink{}, - SSOSessions: map[string]domain.SSOSession{}, - SSOSessionHashes: map[string]string{}, - APIKeys: map[string]domain.APIKey{}, - APIKeyHashes: map[string]string{}, - Collectors: map[string]domain.Collector{}, - BuildRuns: map[string]domain.BuildRun{}, - BuildAttestations: map[string]domain.BuildAttestation{}, - EvidenceLifecycle: map[string]domain.EvidenceLifecycleEvent{}, - ReleaseCandidates: map[string]domain.ReleaseCandidate{}, - ContainerImages: map[string]domain.ContainerImage{}, - ArtifactSignatures: map[string]domain.ArtifactSignature{}, - Repositories: map[string]domain.SourceRepository{}, - Commits: map[string]domain.SourceCommit{}, - Branches: map[string]domain.SourceBranch{}, - PullRequests: map[string]domain.PullRequest{}, - Environments: map[string]domain.DeploymentEnvironment{}, - Deployments: map[string]domain.DeploymentEvent{}, - CustomerPortalAccess: map[string]domain.CustomerPortalAccess{}, - CustomerPortalHashes: map[string]string{}, - RedactionProfiles: map[string]domain.RedactionProfile{}, - CustomerPackages: map[string]domain.CustomerSecurityPackage{}, - HTMLReports: map[string]domain.HTMLReportPackage{}, - ReportTemplates: map[string]domain.CustomReportTemplate{}, - RenderedReports: map[string]domain.RenderedCustomReport{}, - EvidenceBundles: map[string]domain.EvidenceBundle{}, - BundleImports: map[string]domain.EvidenceBundleImport{}, - ObjectRetentionPolicies: map[string]domain.ObjectRetentionPolicy{}, - BackupManifests: map[string]domain.BackupManifest{}, - LegalHolds: map[string]domain.LegalHold{}, - RetentionOverrides: map[string]domain.RetentionOverride{}, - QuestionnaireTemplates: map[string]domain.QuestionnaireTemplate{}, - QuestionnairePackages: map[string]domain.QuestionnairePackage{}, - PDFReports: map[string]domain.PDFReportPackage{}, - AnomalyReports: map[string]domain.AnomalyReport{}, - ControlFrameworks: map[string]domain.ControlFramework{}, - SecurityControls: map[string]domain.SecurityControl{}, - ControlEvidence: map[string]domain.ControlEvidence{}, - Products: map[string]domain.Product{}, - Projects: map[string]domain.Project{}, - Releases: map[string]domain.Release{}, - Artifacts: map[string]domain.Artifact{}, - Evidence: map[string]domain.EvidenceItem{}, - SBOMs: map[string]domain.SBOM{}, - Scans: map[string]domain.VulnerabilityScan{}, - VEXDocuments: map[string]domain.VEXDocument{}, - Decisions: map[string]domain.VulnerabilityDecision{}, - Contracts: map[string]domain.OpenAPIContract{}, - Policies: map[string]domain.PolicyEvaluation{}, - Exceptions: map[string]domain.Exception{}, - Bundles: map[string]domain.ReleaseBundle{}, - SigningKeys: map[string]domain.SigningKey{}, - SigningKeyPrivate: map[string][]byte{}, - Signatures: map[string]domain.Signature{}, - Verifications: map[string]domain.VerificationResult{}, - Chain: map[string][]domain.AuditChainEntry{}, - Idempotency: map[string]app.IdempotencyRecord{}, + Tenants: map[string]domain.Tenant{}, + Organizations: map[string]domain.Organization{}, + Users: map[string]domain.HumanUser{}, + RoleBindings: map[string]domain.RoleBinding{}, + SSOProviders: map[string]domain.SSOProvider{}, + IdentityLinks: map[string]domain.UserIdentityLink{}, + SSOSessions: map[string]domain.SSOSession{}, + SSOSessionHashes: map[string]string{}, + APIKeys: map[string]domain.APIKey{}, + APIKeyHashes: map[string]string{}, + Collectors: map[string]domain.Collector{}, + BuildRuns: map[string]domain.BuildRun{}, + BuildAttestations: map[string]domain.BuildAttestation{}, + EvidenceLifecycle: map[string]domain.EvidenceLifecycleEvent{}, + ReleaseCandidates: map[string]domain.ReleaseCandidate{}, + ContainerImages: map[string]domain.ContainerImage{}, + ArtifactSignatures: map[string]domain.ArtifactSignature{}, + Repositories: map[string]domain.SourceRepository{}, + Commits: map[string]domain.SourceCommit{}, + Branches: map[string]domain.SourceBranch{}, + PullRequests: map[string]domain.PullRequest{}, + Environments: map[string]domain.DeploymentEnvironment{}, + Deployments: map[string]domain.DeploymentEvent{}, + Incidents: map[string]domain.Incident{}, + TimelineEvents: map[string]domain.IncidentTimelineEvent{}, + IncidentWebhookReceivers: map[string]domain.IncidentWebhookReceiver{}, + IncidentWebhookEvents: map[string]domain.IncidentWebhookEvent{}, + RemediationTasks: map[string]domain.RemediationTask{}, + SecurityScans: map[string]domain.SecurityScan{}, + ManualSecurityDocs: map[string]domain.ManualSecurityDocument{}, + SBOMDiffs: map[string]domain.SBOMDiff{}, + DependencyChanges: map[string]domain.DependencyChange{}, + VulnerabilityWorkflow: map[string]domain.VulnerabilityWorkflowRecord{}, + ContractDiffs: map[string]domain.ContractDiff{}, + CustomPolicies: map[string]domain.CustomPolicy{}, + CustomPolicyEvaluations: map[string]domain.CustomPolicyEvaluation{}, + Waivers: map[string]domain.Waiver{}, + Approvals: map[string]domain.ApprovalRecord{}, + DSSETrustRoots: map[string]domain.DSSETrustRoot{}, + CustomerPortalAccess: map[string]domain.CustomerPortalAccess{}, + CustomerPortalHashes: map[string]string{}, + RedactionProfiles: map[string]domain.RedactionProfile{}, + CustomerPackages: map[string]domain.CustomerSecurityPackage{}, + HTMLReports: map[string]domain.HTMLReportPackage{}, + ReportTemplates: map[string]domain.CustomReportTemplate{}, + RenderedReports: map[string]domain.RenderedCustomReport{}, + EvidenceBundles: map[string]domain.EvidenceBundle{}, + BundleImports: map[string]domain.EvidenceBundleImport{}, + ObjectRetentionPolicies: map[string]domain.ObjectRetentionPolicy{}, + BackupManifests: map[string]domain.BackupManifest{}, + LegalHolds: map[string]domain.LegalHold{}, + RetentionOverrides: map[string]domain.RetentionOverride{}, + QuestionnaireTemplates: map[string]domain.QuestionnaireTemplate{}, + QuestionnairePackages: map[string]domain.QuestionnairePackage{}, + PDFReports: map[string]domain.PDFReportPackage{}, + AnomalyReports: map[string]domain.AnomalyReport{}, + ControlFrameworks: map[string]domain.ControlFramework{}, + SecurityControls: map[string]domain.SecurityControl{}, + ControlEvidence: map[string]domain.ControlEvidence{}, + Products: map[string]domain.Product{}, + Projects: map[string]domain.Project{}, + Releases: map[string]domain.Release{}, + Artifacts: map[string]domain.Artifact{}, + Evidence: map[string]domain.EvidenceItem{}, + SBOMs: map[string]domain.SBOM{}, + Scans: map[string]domain.VulnerabilityScan{}, + VEXDocuments: map[string]domain.VEXDocument{}, + Decisions: map[string]domain.VulnerabilityDecision{}, + Contracts: map[string]domain.OpenAPIContract{}, + Policies: map[string]domain.PolicyEvaluation{}, + Exceptions: map[string]domain.Exception{}, + Bundles: map[string]domain.ReleaseBundle{}, + SigningKeys: map[string]domain.SigningKey{}, + SigningKeyPrivate: map[string][]byte{}, + Signatures: map[string]domain.Signature{}, + Verifications: map[string]domain.VerificationResult{}, + Chain: map[string][]domain.AuditChainEntry{}, + Idempotency: map[string]app.IdempotencyRecord{}, } } @@ -1335,6 +1354,367 @@ func (s *Store) loadRelationalDeployments(ctx context.Context, state *app.Persis return deploymentRows.Err() } +func (s *Store) loadRelationalIncidentSecurityGovernance(ctx context.Context, state *app.PersistedState, loaded *bool) error { + if err := s.loadRelationalIncidents(ctx, state, loaded); err != nil { + return err + } + if err := s.loadRelationalSecurityEvidence(ctx, state, loaded); err != nil { + return err + } + if err := s.loadRelationalDiffsAndPolicies(ctx, state, loaded); err != nil { + return err + } + if err := s.loadRelationalWaiversApprovalsTrust(ctx, state, loaded); err != nil { + return err + } + return nil +} + +func (s *Store) loadRelationalIncidents(ctx context.Context, state *app.PersistedState, loaded *bool) error { + incidentRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, product_id, release_id, title, severity, status, opened_at, closed_at, schema_version, created_at FROM incidents`) + if err != nil { + return fmt.Errorf("load relational incidents: %w", err) + } + defer incidentRows.Close() + for incidentRows.Next() { + var incident domain.Incident + var releaseID sql.NullString + var closedAt sql.NullTime + if err := incidentRows.Scan(&incident.ID, &incident.TenantID, &incident.ProductID, &releaseID, &incident.Title, &incident.Severity, &incident.Status, &incident.OpenedAt, &closedAt, &incident.SchemaVersion, &incident.CreatedAt); err != nil { + return fmt.Errorf("scan relational incident: %w", err) + } + incident.ReleaseID = nullableSQLString(releaseID) + incident.ClosedAt = nullableSQLTime(closedAt) + state.Incidents[incident.ID] = incident + *loaded = true + } + if err := incidentRows.Err(); err != nil { + return err + } + + timelineRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, incident_id, event_type, summary, evidence_id, occurred_at, schema_version, created_at FROM incident_timeline_events`) + if err != nil { + return fmt.Errorf("load relational incident timeline: %w", err) + } + defer timelineRows.Close() + for timelineRows.Next() { + var event domain.IncidentTimelineEvent + var evidenceID sql.NullString + if err := timelineRows.Scan(&event.ID, &event.TenantID, &event.IncidentID, &event.EventType, &event.Summary, &evidenceID, &event.OccurredAt, &event.SchemaVersion, &event.CreatedAt); err != nil { + return fmt.Errorf("scan relational incident timeline: %w", err) + } + event.EvidenceID = nullableSQLString(evidenceID) + state.TimelineEvents[event.ID] = event + *loaded = true + } + if err := timelineRows.Err(); err != nil { + return err + } + + receiverRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, incident_id, name, provider, public_key, status, schema_version, created_at FROM incident_webhook_receivers`) + if err != nil { + return fmt.Errorf("load relational incident webhook receivers: %w", err) + } + defer receiverRows.Close() + for receiverRows.Next() { + var receiver domain.IncidentWebhookReceiver + if err := receiverRows.Scan(&receiver.ID, &receiver.TenantID, &receiver.IncidentID, &receiver.Name, &receiver.Provider, &receiver.PublicKey, &receiver.Status, &receiver.SchemaVersion, &receiver.CreatedAt); err != nil { + return fmt.Errorf("scan relational incident webhook receiver: %w", err) + } + state.IncidentWebhookReceivers[receiver.ID] = receiver + *loaded = true + } + if err := receiverRows.Err(); err != nil { + return err + } + + webhookRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, receiver_id, incident_id, provider, event_id, payload_hash, signature_hash, timeline_event_id, result, schema_version, created_at FROM incident_webhook_events`) + if err != nil { + return fmt.Errorf("load relational incident webhook events: %w", err) + } + defer webhookRows.Close() + for webhookRows.Next() { + var event domain.IncidentWebhookEvent + var timelineEventID sql.NullString + if err := webhookRows.Scan(&event.ID, &event.TenantID, &event.ReceiverID, &event.IncidentID, &event.Provider, &event.EventID, &event.PayloadHash, &event.SignatureHash, &timelineEventID, &event.Result, &event.SchemaVersion, &event.CreatedAt); err != nil { + return fmt.Errorf("scan relational incident webhook event: %w", err) + } + event.TimelineEventID = nullableSQLString(timelineEventID) + state.IncidentWebhookEvents[event.ID] = event + *loaded = true + } + if err := webhookRows.Err(); err != nil { + return err + } + + taskRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, incident_id, release_id, title, owner, status, due_at, evidence_id, schema_version, created_at FROM remediation_tasks`) + if err != nil { + return fmt.Errorf("load relational remediation tasks: %w", err) + } + defer taskRows.Close() + for taskRows.Next() { + var task domain.RemediationTask + var incidentID, releaseID, evidenceID sql.NullString + var dueAt sql.NullTime + if err := taskRows.Scan(&task.ID, &task.TenantID, &incidentID, &releaseID, &task.Title, &task.Owner, &task.Status, &dueAt, &evidenceID, &task.SchemaVersion, &task.CreatedAt); err != nil { + return fmt.Errorf("scan relational remediation task: %w", err) + } + task.IncidentID = nullableSQLString(incidentID) + task.ReleaseID = nullableSQLString(releaseID) + task.DueAt = nullableSQLTime(dueAt) + task.EvidenceID = nullableSQLString(evidenceID) + state.RemediationTasks[task.ID] = task + *loaded = true + } + return taskRows.Err() +} + +func (s *Store) loadRelationalSecurityEvidence(ctx context.Context, state *app.PersistedState, loaded *bool) error { + scanRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, product_id, release_id, artifact_id, category, format, scanner, target_ref, evidence_id, payload_ref, payload_hash, finding_count, summary, redacted, quarantined, schema_version, created_at FROM security_scans`) + if err != nil { + return fmt.Errorf("load relational security scans: %w", err) + } + defer scanRows.Close() + for scanRows.Next() { + var scan domain.SecurityScan + var productID, releaseID, artifactID, payloadRef sql.NullString + var summary []byte + if err := scanRows.Scan(&scan.ID, &scan.TenantID, &productID, &releaseID, &artifactID, &scan.Category, &scan.Format, &scan.Scanner, &scan.TargetRef, &scan.EvidenceID, &payloadRef, &scan.PayloadHash, &scan.FindingCount, &summary, &scan.Redacted, &scan.Quarantined, &scan.SchemaVersion, &scan.CreatedAt); err != nil { + return fmt.Errorf("scan relational security scan: %w", err) + } + scan.ProductID = nullableSQLString(productID) + scan.ReleaseID = nullableSQLString(releaseID) + scan.ArtifactID = nullableSQLString(artifactID) + scan.PayloadRef = nullableSQLString(payloadRef) + if err := decodeJSON(summary, &scan.Summary); err != nil { + return fmt.Errorf("decode relational security scan summary: %w", err) + } + state.SecurityScans[scan.ID] = scan + *loaded = true + } + if err := scanRows.Err(); err != nil { + return err + } + + docRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, product_id, release_id, document_type, title, sensitivity, evidence_id, payload_ref, payload_hash, schema_version, created_at FROM manual_security_documents`) + if err != nil { + return fmt.Errorf("load relational manual security documents: %w", err) + } + defer docRows.Close() + for docRows.Next() { + var document domain.ManualSecurityDocument + var productID, releaseID, payloadRef sql.NullString + if err := docRows.Scan(&document.ID, &document.TenantID, &productID, &releaseID, &document.DocumentType, &document.Title, &document.Sensitivity, &document.EvidenceID, &payloadRef, &document.PayloadHash, &document.SchemaVersion, &document.CreatedAt); err != nil { + return fmt.Errorf("scan relational manual security document: %w", err) + } + document.ProductID = nullableSQLString(productID) + document.ReleaseID = nullableSQLString(releaseID) + document.PayloadRef = nullableSQLString(payloadRef) + state.ManualSecurityDocs[document.ID] = document + *loaded = true + } + return docRows.Err() +} + +func (s *Store) loadRelationalDiffsAndPolicies(ctx context.Context, state *app.PersistedState, loaded *bool) error { + sbomRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, base_sbom_id, target_sbom_id, release_id, document, schema_version, created_at FROM sbom_diffs`) + if err != nil { + return fmt.Errorf("load relational sbom diffs: %w", err) + } + defer sbomRows.Close() + for sbomRows.Next() { + var diff domain.SBOMDiff + var releaseID sql.NullString + var document []byte + if err := sbomRows.Scan(&diff.ID, &diff.TenantID, &diff.BaseSBOMID, &diff.TargetSBOMID, &releaseID, &document, &diff.SchemaVersion, &diff.CreatedAt); err != nil { + return fmt.Errorf("scan relational sbom diff: %w", err) + } + diff.ReleaseID = nullableSQLString(releaseID) + var embedded domain.SBOMDiff + if err := decodeJSON(document, &embedded); err != nil { + return fmt.Errorf("decode relational sbom diff document: %w", err) + } + diff.AddedComponents = embedded.AddedComponents + diff.RemovedComponents = embedded.RemovedComponents + diff.UnchangedCount = embedded.UnchangedCount + diff.DependencyChanges = embedded.DependencyChanges + state.SBOMDiffs[diff.ID] = diff + *loaded = true + } + if err := sbomRows.Err(); err != nil { + return err + } + + dependencyRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, sbom_diff_id, change_type, component, schema_version, created_at FROM dependency_changes`) + if err != nil { + return fmt.Errorf("load relational dependency changes: %w", err) + } + defer dependencyRows.Close() + for dependencyRows.Next() { + var change domain.DependencyChange + var component []byte + if err := dependencyRows.Scan(&change.ID, &change.TenantID, &change.SBOMDiffID, &change.ChangeType, &component, &change.SchemaVersion, &change.CreatedAt); err != nil { + return fmt.Errorf("scan relational dependency change: %w", err) + } + if err := decodeJSON(component, &change.Component); err != nil { + return fmt.Errorf("decode relational dependency component: %w", err) + } + state.DependencyChanges[change.ID] = change + *loaded = true + } + if err := dependencyRows.Err(); err != nil { + return err + } + + workflowRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, finding_id, release_id, action, reason, actor_id, schema_version, created_at FROM vulnerability_workflow_records`) + if err != nil { + return fmt.Errorf("load relational vulnerability workflow: %w", err) + } + defer workflowRows.Close() + for workflowRows.Next() { + var record domain.VulnerabilityWorkflowRecord + var releaseID sql.NullString + if err := workflowRows.Scan(&record.ID, &record.TenantID, &record.FindingID, &releaseID, &record.Action, &record.Reason, &record.ActorID, &record.SchemaVersion, &record.CreatedAt); err != nil { + return fmt.Errorf("scan relational vulnerability workflow: %w", err) + } + record.ReleaseID = nullableSQLString(releaseID) + state.VulnerabilityWorkflow[record.ID] = record + *loaded = true + } + if err := workflowRows.Err(); err != nil { + return err + } + + contractRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, base_contract_id, target_contract_id, product_id, release_id, result, document, schema_version, created_at FROM contract_diffs`) + if err != nil { + return fmt.Errorf("load relational contract diffs: %w", err) + } + defer contractRows.Close() + for contractRows.Next() { + var diff domain.ContractDiff + var releaseID sql.NullString + var document []byte + if err := contractRows.Scan(&diff.ID, &diff.TenantID, &diff.BaseContractID, &diff.TargetContractID, &diff.ProductID, &releaseID, &diff.Result, &document, &diff.SchemaVersion, &diff.CreatedAt); err != nil { + return fmt.Errorf("scan relational contract diff: %w", err) + } + diff.ReleaseID = nullableSQLString(releaseID) + var embedded domain.ContractDiff + if err := decodeJSON(document, &embedded); err != nil { + return fmt.Errorf("decode relational contract diff document: %w", err) + } + diff.BreakingChanges = embedded.BreakingChanges + diff.NonBreakingChanges = embedded.NonBreakingChanges + state.ContractDiffs[diff.ID] = diff + *loaded = true + } + if err := contractRows.Err(); err != nil { + return err + } + + policyRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, name, version, description, rules, schema_version, created_at FROM custom_policies`) + if err != nil { + return fmt.Errorf("load relational custom policies: %w", err) + } + defer policyRows.Close() + for policyRows.Next() { + var policy domain.CustomPolicy + var description sql.NullString + var rules []byte + if err := policyRows.Scan(&policy.ID, &policy.TenantID, &policy.Name, &policy.Version, &description, &rules, &policy.SchemaVersion, &policy.CreatedAt); err != nil { + return fmt.Errorf("scan relational custom policy: %w", err) + } + policy.Description = nullableSQLString(description) + if err := decodeJSON(rules, &policy.Rules); err != nil { + return fmt.Errorf("decode relational custom policy rules: %w", err) + } + state.CustomPolicies[policy.ID] = policy + *loaded = true + } + if err := policyRows.Err(); err != nil { + return err + } + + evalRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, policy_id, release_id, result, checks, input_hash, schema_version, created_at FROM custom_policy_evaluations`) + if err != nil { + return fmt.Errorf("load relational custom policy evaluations: %w", err) + } + defer evalRows.Close() + for evalRows.Next() { + var evaluation domain.CustomPolicyEvaluation + var checks []byte + if err := evalRows.Scan(&evaluation.ID, &evaluation.TenantID, &evaluation.PolicyID, &evaluation.ReleaseID, &evaluation.Result, &checks, &evaluation.InputHash, &evaluation.SchemaVersion, &evaluation.CreatedAt); err != nil { + return fmt.Errorf("scan relational custom policy evaluation: %w", err) + } + if err := decodeJSON(checks, &evaluation.Checks); err != nil { + return fmt.Errorf("decode relational custom policy checks: %w", err) + } + state.CustomPolicyEvaluations[evaluation.ID] = evaluation + *loaded = true + } + return evalRows.Err() +} + +func (s *Store) loadRelationalWaiversApprovalsTrust(ctx context.Context, state *app.PersistedState, loaded *bool) error { + waiverRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, scope_type, scope_id, control_id, policy_id, owner, risk, reason, expires_at, approved, approved_by, approved_at, supersedes, superseded_by, schema_version, created_at FROM waivers`) + if err != nil { + return fmt.Errorf("load relational waivers: %w", err) + } + defer waiverRows.Close() + for waiverRows.Next() { + var waiver domain.Waiver + var controlID, policyID, approvedBy, supersedes, supersededBy sql.NullString + var approvedAt sql.NullTime + if err := waiverRows.Scan(&waiver.ID, &waiver.TenantID, &waiver.ScopeType, &waiver.ScopeID, &controlID, &policyID, &waiver.Owner, &waiver.Risk, &waiver.Reason, &waiver.ExpiresAt, &waiver.Approved, &approvedBy, &approvedAt, &supersedes, &supersededBy, &waiver.SchemaVersion, &waiver.CreatedAt); err != nil { + return fmt.Errorf("scan relational waiver: %w", err) + } + waiver.ControlID = nullableSQLString(controlID) + waiver.PolicyID = nullableSQLString(policyID) + waiver.ApprovedBy = nullableSQLString(approvedBy) + waiver.ApprovedAt = nullableSQLTime(approvedAt) + waiver.Supersedes = nullableSQLString(supersedes) + waiver.SupersededBy = nullableSQLString(supersededBy) + state.Waivers[waiver.ID] = waiver + *loaded = true + } + if err := waiverRows.Err(); err != nil { + return err + } + + approvalRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, subject_type, subject_id, decision, reason, approver_id, evidence_id, schema_version, created_at FROM approval_records`) + if err != nil { + return fmt.Errorf("load relational approvals: %w", err) + } + defer approvalRows.Close() + for approvalRows.Next() { + var approval domain.ApprovalRecord + var evidenceID sql.NullString + if err := approvalRows.Scan(&approval.ID, &approval.TenantID, &approval.SubjectType, &approval.SubjectID, &approval.Decision, &approval.Reason, &approval.ApproverID, &evidenceID, &approval.SchemaVersion, &approval.CreatedAt); err != nil { + return fmt.Errorf("scan relational approval: %w", err) + } + approval.EvidenceID = nullableSQLString(evidenceID) + state.Approvals[approval.ID] = approval + *loaded = true + } + if err := approvalRows.Err(); err != nil { + return err + } + + trustRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, name, key_id, algorithm, public_key, status, schema_version, created_at FROM dsse_trust_roots`) + if err != nil { + return fmt.Errorf("load relational dsse trust roots: %w", err) + } + defer trustRows.Close() + for trustRows.Next() { + var root domain.DSSETrustRoot + if err := trustRows.Scan(&root.ID, &root.TenantID, &root.Name, &root.KeyID, &root.Algorithm, &root.PublicKey, &root.Status, &root.SchemaVersion, &root.CreatedAt); err != nil { + return fmt.Errorf("scan relational dsse trust root: %w", err) + } + state.DSSETrustRoots[root.ID] = root + *loaded = true + } + return trustRows.Err() +} + func (s *Store) loadRelationalPackageReportRetention(ctx context.Context, state *app.PersistedState, loaded *bool) error { if err := s.loadRelationalPackages(ctx, state, loaded); err != nil { return err @@ -1716,6 +2096,9 @@ func (s *Store) SaveState(ctx context.Context, state app.PersistedState) error { if err := syncSourceDeploymentLifecycleRows(ctx, tx, state); err != nil { return err } + if err := syncIncidentSecurityGovernanceRows(ctx, tx, state); err != nil { + return err + } if err := syncPackageReportRetentionRows(ctx, tx, state); err != nil { return err } @@ -2496,6 +2879,302 @@ func syncSourceDeploymentLifecycleRows(ctx context.Context, tx pgx.Tx, state app return nil } +func syncIncidentSecurityGovernanceRows(ctx context.Context, tx pgx.Tx, state app.PersistedState) error { + for _, incident := range state.Incidents { + if incident.ID == "" || incident.TenantID == "" || incident.ProductID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO incidents ( + id, tenant_id, product_id, release_id, title, severity, status, + opened_at, closed_at, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) + ON CONFLICT (id) DO UPDATE SET + status = EXCLUDED.status, + closed_at = EXCLUDED.closed_at + `, incident.ID, incident.TenantID, incident.ProductID, nullableString(incident.ReleaseID), incident.Title, incident.Severity, incident.Status, + nonZeroTime(incident.OpenedAt), nullableTime(incident.ClosedAt), incident.SchemaVersion, nonZeroTime(incident.CreatedAt)); err != nil { + return fmt.Errorf("upsert incident row: %w", err) + } + } + for _, event := range state.TimelineEvents { + if event.ID == "" || event.TenantID == "" || event.IncidentID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO incident_timeline_events ( + id, tenant_id, incident_id, event_type, summary, evidence_id, + occurred_at, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + ON CONFLICT (id) DO NOTHING + `, event.ID, event.TenantID, event.IncidentID, event.EventType, event.Summary, nullableString(event.EvidenceID), + nonZeroTime(event.OccurredAt), event.SchemaVersion, nonZeroTime(event.CreatedAt)); err != nil { + return fmt.Errorf("insert incident timeline row: %w", err) + } + } + for _, receiver := range state.IncidentWebhookReceivers { + if receiver.ID == "" || receiver.TenantID == "" || receiver.IncidentID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO incident_webhook_receivers ( + id, tenant_id, incident_id, name, provider, public_key, status, + schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + ON CONFLICT (id) DO UPDATE SET status = EXCLUDED.status + `, receiver.ID, receiver.TenantID, receiver.IncidentID, receiver.Name, receiver.Provider, receiver.PublicKey, receiver.Status, receiver.SchemaVersion, nonZeroTime(receiver.CreatedAt)); err != nil { + return fmt.Errorf("upsert incident webhook receiver row: %w", err) + } + } + for _, event := range state.IncidentWebhookEvents { + if event.ID == "" || event.TenantID == "" || event.ReceiverID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO incident_webhook_events ( + id, tenant_id, receiver_id, incident_id, provider, event_id, + payload_hash, signature_hash, timeline_event_id, result, + schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) + ON CONFLICT (id) DO UPDATE SET result = EXCLUDED.result, timeline_event_id = EXCLUDED.timeline_event_id + `, event.ID, event.TenantID, event.ReceiverID, event.IncidentID, event.Provider, event.EventID, + event.PayloadHash, event.SignatureHash, nullableString(event.TimelineEventID), event.Result, event.SchemaVersion, nonZeroTime(event.CreatedAt)); err != nil { + return fmt.Errorf("upsert incident webhook event row: %w", err) + } + } + for _, task := range state.RemediationTasks { + if task.ID == "" || task.TenantID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO remediation_tasks ( + id, tenant_id, incident_id, release_id, title, owner, status, + due_at, evidence_id, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) + ON CONFLICT (id) DO UPDATE SET status = EXCLUDED.status, evidence_id = EXCLUDED.evidence_id + `, task.ID, task.TenantID, nullableString(task.IncidentID), nullableString(task.ReleaseID), task.Title, task.Owner, task.Status, + nullableTime(task.DueAt), nullableString(task.EvidenceID), task.SchemaVersion, nonZeroTime(task.CreatedAt)); err != nil { + return fmt.Errorf("upsert remediation task row: %w", err) + } + } + for _, scan := range state.SecurityScans { + if scan.ID == "" || scan.TenantID == "" || scan.EvidenceID == "" { + continue + } + summary, err := json.Marshal(scan.Summary) + if err != nil { + return fmt.Errorf("encode security scan summary: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO security_scans ( + id, tenant_id, product_id, release_id, artifact_id, category, + format, scanner, target_ref, evidence_id, payload_ref, + payload_hash, finding_count, summary, redacted, quarantined, + schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18) + ON CONFLICT (id) DO UPDATE SET + finding_count = EXCLUDED.finding_count, + summary = EXCLUDED.summary, + redacted = EXCLUDED.redacted, + quarantined = EXCLUDED.quarantined + `, scan.ID, scan.TenantID, nullableString(scan.ProductID), nullableString(scan.ReleaseID), nullableString(scan.ArtifactID), scan.Category, + scan.Format, scan.Scanner, scan.TargetRef, scan.EvidenceID, nullableString(scan.PayloadRef), + scan.PayloadHash, scan.FindingCount, summary, scan.Redacted, scan.Quarantined, + scan.SchemaVersion, nonZeroTime(scan.CreatedAt)); err != nil { + return fmt.Errorf("upsert security scan row: %w", err) + } + } + for _, document := range state.ManualSecurityDocs { + if document.ID == "" || document.TenantID == "" || document.EvidenceID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO manual_security_documents ( + id, tenant_id, product_id, release_id, document_type, title, + sensitivity, evidence_id, payload_ref, payload_hash, + schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) + ON CONFLICT (id) DO UPDATE SET sensitivity = EXCLUDED.sensitivity + `, document.ID, document.TenantID, nullableString(document.ProductID), nullableString(document.ReleaseID), document.DocumentType, document.Title, + document.Sensitivity, document.EvidenceID, nullableString(document.PayloadRef), document.PayloadHash, document.SchemaVersion, nonZeroTime(document.CreatedAt)); err != nil { + return fmt.Errorf("upsert manual security document row: %w", err) + } + } + for _, diff := range state.SBOMDiffs { + if diff.ID == "" || diff.TenantID == "" || diff.BaseSBOMID == "" || diff.TargetSBOMID == "" { + continue + } + document, err := json.Marshal(diff) + if err != nil { + return fmt.Errorf("encode sbom diff document: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO sbom_diffs ( + id, tenant_id, base_sbom_id, target_sbom_id, release_id, + document, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8) + ON CONFLICT (id) DO UPDATE SET document = EXCLUDED.document + `, diff.ID, diff.TenantID, diff.BaseSBOMID, diff.TargetSBOMID, nullableString(diff.ReleaseID), + document, diff.SchemaVersion, nonZeroTime(diff.CreatedAt)); err != nil { + return fmt.Errorf("upsert sbom diff row: %w", err) + } + } + for _, change := range state.DependencyChanges { + if change.ID == "" || change.TenantID == "" || change.SBOMDiffID == "" { + continue + } + component, err := json.Marshal(change.Component) + if err != nil { + return fmt.Errorf("encode dependency component: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO dependency_changes ( + id, tenant_id, sbom_diff_id, change_type, component, + schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7) + ON CONFLICT (id) DO UPDATE SET component = EXCLUDED.component + `, change.ID, change.TenantID, change.SBOMDiffID, change.ChangeType, component, change.SchemaVersion, nonZeroTime(change.CreatedAt)); err != nil { + return fmt.Errorf("upsert dependency change row: %w", err) + } + } + for _, record := range state.VulnerabilityWorkflow { + if record.ID == "" || record.TenantID == "" || record.FindingID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO vulnerability_workflow_records ( + id, tenant_id, finding_id, release_id, action, reason, + actor_id, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + ON CONFLICT (id) DO NOTHING + `, record.ID, record.TenantID, record.FindingID, nullableString(record.ReleaseID), record.Action, record.Reason, record.ActorID, record.SchemaVersion, nonZeroTime(record.CreatedAt)); err != nil { + return fmt.Errorf("insert vulnerability workflow row: %w", err) + } + } + for _, diff := range state.ContractDiffs { + if diff.ID == "" || diff.TenantID == "" || diff.BaseContractID == "" || diff.TargetContractID == "" { + continue + } + document, err := json.Marshal(diff) + if err != nil { + return fmt.Errorf("encode contract diff document: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO contract_diffs ( + id, tenant_id, base_contract_id, target_contract_id, product_id, + release_id, result, document, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) + ON CONFLICT (id) DO UPDATE SET result = EXCLUDED.result, document = EXCLUDED.document + `, diff.ID, diff.TenantID, diff.BaseContractID, diff.TargetContractID, diff.ProductID, + nullableString(diff.ReleaseID), diff.Result, document, diff.SchemaVersion, nonZeroTime(diff.CreatedAt)); err != nil { + return fmt.Errorf("upsert contract diff row: %w", err) + } + } + for _, policy := range state.CustomPolicies { + if policy.ID == "" || policy.TenantID == "" { + continue + } + rules, err := json.Marshal(policy.Rules) + if err != nil { + return fmt.Errorf("encode custom policy rules: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO custom_policies ( + id, tenant_id, name, version, description, rules, + schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8) + ON CONFLICT (id) DO UPDATE SET description = EXCLUDED.description, rules = EXCLUDED.rules + `, policy.ID, policy.TenantID, policy.Name, policy.Version, nullableString(policy.Description), rules, policy.SchemaVersion, nonZeroTime(policy.CreatedAt)); err != nil { + return fmt.Errorf("upsert custom policy row: %w", err) + } + } + for _, evaluation := range state.CustomPolicyEvaluations { + if evaluation.ID == "" || evaluation.TenantID == "" || evaluation.PolicyID == "" { + continue + } + checks, err := json.Marshal(evaluation.Checks) + if err != nil { + return fmt.Errorf("encode custom policy checks: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO custom_policy_evaluations ( + id, tenant_id, policy_id, release_id, result, checks, + input_hash, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + ON CONFLICT (id) DO UPDATE SET result = EXCLUDED.result, checks = EXCLUDED.checks + `, evaluation.ID, evaluation.TenantID, evaluation.PolicyID, evaluation.ReleaseID, evaluation.Result, checks, evaluation.InputHash, evaluation.SchemaVersion, nonZeroTime(evaluation.CreatedAt)); err != nil { + return fmt.Errorf("upsert custom policy evaluation row: %w", err) + } + } + for _, waiver := range state.Waivers { + if waiver.ID == "" || waiver.TenantID == "" || waiver.ScopeID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO waivers ( + id, tenant_id, scope_type, scope_id, control_id, policy_id, + owner, risk, reason, expires_at, approved, approved_by, + approved_at, supersedes, superseded_by, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17) + ON CONFLICT (id) DO UPDATE SET + approved = EXCLUDED.approved, + approved_by = EXCLUDED.approved_by, + approved_at = EXCLUDED.approved_at, + superseded_by = EXCLUDED.superseded_by + `, waiver.ID, waiver.TenantID, waiver.ScopeType, waiver.ScopeID, nullableString(waiver.ControlID), nullableString(waiver.PolicyID), + waiver.Owner, waiver.Risk, waiver.Reason, waiver.ExpiresAt, waiver.Approved, nullableString(waiver.ApprovedBy), + nullableTime(waiver.ApprovedAt), nullableString(waiver.Supersedes), nullableString(waiver.SupersededBy), waiver.SchemaVersion, nonZeroTime(waiver.CreatedAt)); err != nil { + return fmt.Errorf("upsert waiver row: %w", err) + } + } + for _, approval := range state.Approvals { + if approval.ID == "" || approval.TenantID == "" || approval.SubjectID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO approval_records ( + id, tenant_id, subject_type, subject_id, decision, reason, + approver_id, evidence_id, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) + ON CONFLICT (id) DO NOTHING + `, approval.ID, approval.TenantID, approval.SubjectType, approval.SubjectID, approval.Decision, approval.Reason, + approval.ApproverID, nullableString(approval.EvidenceID), approval.SchemaVersion, nonZeroTime(approval.CreatedAt)); err != nil { + return fmt.Errorf("insert approval row: %w", err) + } + } + for _, root := range state.DSSETrustRoots { + if root.ID == "" || root.TenantID == "" || root.KeyID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO dsse_trust_roots ( + id, tenant_id, name, key_id, algorithm, public_key, status, + schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + ON CONFLICT (id) DO UPDATE SET status = EXCLUDED.status, public_key = EXCLUDED.public_key + `, root.ID, root.TenantID, root.Name, root.KeyID, root.Algorithm, root.PublicKey, root.Status, root.SchemaVersion, nonZeroTime(root.CreatedAt)); err != nil { + return fmt.Errorf("upsert dsse trust root row: %w", err) + } + } + return nil +} + func syncPackageReportRetentionRows(ctx context.Context, tx pgx.Tx, state app.PersistedState) error { for _, profile := range state.RedactionProfiles { if profile.ID == "" || profile.TenantID == "" { diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index 32305aa..8cdef3d 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -122,6 +122,54 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { Deployments: map[string]domain.DeploymentEvent{ "deploy_test": {ID: "deploy_test", TenantID: "ten_test", EnvironmentID: "env_test", ReleaseID: "rel_test", ArtifactIDs: []string{"art_test"}, Status: "succeeded", StartedAt: time.Now().UTC(), FinishedAt: ptrTime(time.Now().UTC()), EvidenceID: "ev_test", SchemaVersion: domain.DeploymentEventSchemaVersion, CreatedAt: time.Now().UTC()}, }, + Incidents: map[string]domain.Incident{ + "incident_test": {ID: "incident_test", TenantID: "ten_test", ProductID: "prod_test", ReleaseID: "rel_test", Title: "Incident", Severity: "medium", Status: "resolved", OpenedAt: time.Now().UTC(), ClosedAt: ptrTime(time.Now().UTC()), SchemaVersion: domain.IncidentSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + TimelineEvents: map[string]domain.IncidentTimelineEvent{ + "timeline_test": {ID: "timeline_test", TenantID: "ten_test", IncidentID: "incident_test", EventType: "detected", Summary: "detected", EvidenceID: "ev_test", OccurredAt: time.Now().UTC(), SchemaVersion: domain.IncidentTimelineSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + IncidentWebhookReceivers: map[string]domain.IncidentWebhookReceiver{ + "receiver_test": {ID: "receiver_test", TenantID: "ten_test", IncidentID: "incident_test", Name: "pager", Provider: "generic", PublicKey: "pub", Status: "active", SchemaVersion: domain.IncidentWebhookReceiverVersion, CreatedAt: time.Now().UTC()}, + }, + IncidentWebhookEvents: map[string]domain.IncidentWebhookEvent{ + "webhook_event_test": {ID: "webhook_event_test", TenantID: "ten_test", ReceiverID: "receiver_test", IncidentID: "incident_test", Provider: "generic", EventID: "evt-1", PayloadHash: "sha256:" + strings.Repeat("a", 64), SignatureHash: "sha256:" + strings.Repeat("b", 64), TimelineEventID: "timeline_test", Result: "accepted", SchemaVersion: domain.IncidentWebhookEventVersion, CreatedAt: time.Now().UTC()}, + }, + RemediationTasks: map[string]domain.RemediationTask{ + "remediation_test": {ID: "remediation_test", TenantID: "ten_test", IncidentID: "incident_test", ReleaseID: "rel_test", Title: "Patch", Owner: "security", Status: "done", DueAt: ptrTime(time.Now().UTC().Add(24 * time.Hour)), EvidenceID: "ev_test", SchemaVersion: domain.RemediationTaskSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + SecurityScans: map[string]domain.SecurityScan{ + "secscan_test": {ID: "secscan_test", TenantID: "ten_test", ProductID: "prod_test", ReleaseID: "rel_test", ArtifactID: "art_test", Category: "sast", Format: "sarif", Scanner: "scanner", TargetRef: "repo", EvidenceID: "ev_test", PayloadRef: "object://tenants/ten_test/security/sarif", PayloadHash: "sha256:" + strings.Repeat("c", 64), FindingCount: 1, Summary: map[string]int{"high": 1}, Redacted: true, SchemaVersion: domain.SecurityScanSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + ManualSecurityDocs: map[string]domain.ManualSecurityDocument{ + "manual_doc_test": {ID: "manual_doc_test", TenantID: "ten_test", ProductID: "prod_test", ReleaseID: "rel_test", DocumentType: "security_review", Title: "Review", Sensitivity: "restricted", EvidenceID: "ev_test", PayloadRef: "object://tenants/ten_test/manual/review", PayloadHash: "sha256:" + strings.Repeat("d", 64), SchemaVersion: domain.ManualSecurityDocSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + SBOMDiffs: map[string]domain.SBOMDiff{ + "sbomdiff_test": {ID: "sbomdiff_test", TenantID: "ten_test", BaseSBOMID: "sbom_test", TargetSBOMID: "sbom_test", ReleaseID: "rel_test", AddedComponents: []domain.SBOMComponent{{Name: "lib2"}}, UnchangedCount: 1, SchemaVersion: domain.SBOMDiffSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + DependencyChanges: map[string]domain.DependencyChange{ + "depchange_test": {ID: "depchange_test", TenantID: "ten_test", SBOMDiffID: "sbomdiff_test", ChangeType: "added", Component: domain.SBOMComponent{Name: "lib2"}, SchemaVersion: domain.DependencyChangeSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + VulnerabilityWorkflow: map[string]domain.VulnerabilityWorkflowRecord{ + "vulnwf_test": {ID: "vulnwf_test", TenantID: "ten_test", FindingID: "finding_test", ReleaseID: "rel_test", Action: "reopened", Reason: "new evidence", ActorID: "user_test", SchemaVersion: "vulnerability-workflow.v1.0.0", CreatedAt: time.Now().UTC()}, + }, + ContractDiffs: map[string]domain.ContractDiff{ + "contractdiff_test": {ID: "contractdiff_test", TenantID: "ten_test", BaseContractID: "contract_test", TargetContractID: "contract_test", ProductID: "prod_test", ReleaseID: "rel_test", Result: "non_breaking", NonBreakingChanges: []string{"metadata"}, SchemaVersion: domain.ContractDiffSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + CustomPolicies: map[string]domain.CustomPolicy{ + "custom_policy_test": {ID: "custom_policy_test", TenantID: "ten_test", Name: "policy", Version: "1", Description: "test", Rules: []domain.PolicyRule{{Name: "sbom", EvidenceType: "sbom", Severity: "high", Required: true}}, SchemaVersion: domain.CustomPolicySchemaVersion, CreatedAt: time.Now().UTC()}, + }, + CustomPolicyEvaluations: map[string]domain.CustomPolicyEvaluation{ + "custom_policy_eval_test": {ID: "custom_policy_eval_test", TenantID: "ten_test", PolicyID: "custom_policy_test", ReleaseID: "rel_test", Result: "pass", Checks: []domain.PolicyCheck{{Name: "sbom", Result: "passed", Severity: "high"}}, InputHash: "sha256:" + strings.Repeat("e", 64), SchemaVersion: domain.CustomPolicyEvalSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + Waivers: map[string]domain.Waiver{ + "waiver_test": {ID: "waiver_test", TenantID: "ten_test", ScopeType: "release", ScopeID: "rel_test", ControlID: "control_test", PolicyID: "custom_policy_test", Owner: "security", Risk: "accepted", Reason: "test", ExpiresAt: time.Now().UTC().Add(24 * time.Hour), Approved: true, ApprovedBy: "user_test", ApprovedAt: ptrTime(time.Now().UTC()), SchemaVersion: domain.WaiverSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + Approvals: map[string]domain.ApprovalRecord{ + "approval_test": {ID: "approval_test", TenantID: "ten_test", SubjectType: "release", SubjectID: "rel_test", Decision: "approved", Reason: "test", ApproverID: "user_test", EvidenceID: "ev_test", SchemaVersion: domain.ApprovalRecordSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + DSSETrustRoots: map[string]domain.DSSETrustRoot{ + "dsse_root_test": {ID: "dsse_root_test", TenantID: "ten_test", Name: "root", KeyID: "key-1", Algorithm: "Ed25519", PublicKey: "pub", Status: "active", SchemaVersion: domain.DSSETrustRootSchemaVersion, CreatedAt: time.Now().UTC()}, + }, Chain: map[string][]domain.AuditChainEntry{ "ten_test": {{ ID: "chain_test", TenantID: "ten_test", Sequence: 1, EntryType: "evidence.created", SubjectType: "evidence_item", SubjectID: "ev_test", @@ -296,6 +344,22 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { {name: "pull request", query: `SELECT count(*) FROM pull_requests WHERE tenant_id = 'ten_test' AND id = 'pr_test' AND review_decision = 'approved'`}, {name: "deployment environment", query: `SELECT count(*) FROM deployment_environments WHERE tenant_id = 'ten_test' AND id = 'env_test'`}, {name: "deployment event", query: `SELECT count(*) FROM deployment_events WHERE tenant_id = 'ten_test' AND id = 'deploy_test' AND artifact_ids = ARRAY['art_test']`}, + {name: "incident", query: `SELECT count(*) FROM incidents WHERE tenant_id = 'ten_test' AND id = 'incident_test' AND status = 'resolved'`}, + {name: "incident timeline", query: `SELECT count(*) FROM incident_timeline_events WHERE tenant_id = 'ten_test' AND id = 'timeline_test' AND evidence_id = 'ev_test'`}, + {name: "incident webhook receiver", query: `SELECT count(*) FROM incident_webhook_receivers WHERE tenant_id = 'ten_test' AND id = 'receiver_test' AND status = 'active'`}, + {name: "incident webhook event", query: `SELECT count(*) FROM incident_webhook_events WHERE tenant_id = 'ten_test' AND id = 'webhook_event_test' AND timeline_event_id = 'timeline_test'`}, + {name: "remediation task", query: `SELECT count(*) FROM remediation_tasks WHERE tenant_id = 'ten_test' AND id = 'remediation_test' AND status = 'done'`}, + {name: "security scan", query: `SELECT count(*) FROM security_scans WHERE tenant_id = 'ten_test' AND id = 'secscan_test' AND summary <> '{}'::jsonb`}, + {name: "manual security doc", query: `SELECT count(*) FROM manual_security_documents WHERE tenant_id = 'ten_test' AND id = 'manual_doc_test' AND sensitivity = 'restricted'`}, + {name: "sbom diff", query: `SELECT count(*) FROM sbom_diffs WHERE tenant_id = 'ten_test' AND id = 'sbomdiff_test' AND document <> '{}'::jsonb`}, + {name: "dependency change", query: `SELECT count(*) FROM dependency_changes WHERE tenant_id = 'ten_test' AND id = 'depchange_test' AND component <> '{}'::jsonb`}, + {name: "vulnerability workflow", query: `SELECT count(*) FROM vulnerability_workflow_records WHERE tenant_id = 'ten_test' AND id = 'vulnwf_test' AND action = 'reopened'`}, + {name: "contract diff", query: `SELECT count(*) FROM contract_diffs WHERE tenant_id = 'ten_test' AND id = 'contractdiff_test' AND document <> '{}'::jsonb`}, + {name: "custom policy", query: `SELECT count(*) FROM custom_policies WHERE tenant_id = 'ten_test' AND id = 'custom_policy_test' AND rules <> '[]'::jsonb`}, + {name: "custom policy evaluation", query: `SELECT count(*) FROM custom_policy_evaluations WHERE tenant_id = 'ten_test' AND id = 'custom_policy_eval_test' AND checks <> '[]'::jsonb`}, + {name: "waiver", query: `SELECT count(*) FROM waivers WHERE tenant_id = 'ten_test' AND id = 'waiver_test' AND approved = true`}, + {name: "approval", query: `SELECT count(*) FROM approval_records WHERE tenant_id = 'ten_test' AND id = 'approval_test' AND evidence_id = 'ev_test'`}, + {name: "dsse trust root", query: `SELECT count(*) FROM dsse_trust_roots WHERE tenant_id = 'ten_test' AND id = 'dsse_root_test' AND status = 'active'`}, {name: "audit chain", query: `SELECT count(*) FROM audit_chain_entries WHERE tenant_id = 'ten_test' AND sequence = 1`}, {name: "signing key", query: `SELECT count(*) FROM signing_keys WHERE tenant_id = 'ten_test' AND id = 'sigkey_test' AND encrypted_private_key IS NOT NULL`}, {name: "signature", query: `SELECT count(*) FROM signatures WHERE tenant_id = 'ten_test' AND id = 'sig_test'`}, @@ -373,6 +437,30 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { if relational.Environments["env_test"].Name != "production" || relational.Deployments["deploy_test"].Status != "succeeded" { t.Fatalf("relational deployment rows missing: env=%#v deployment=%#v", relational.Environments["env_test"], relational.Deployments["deploy_test"]) } + if relational.Incidents["incident_test"].Status != "resolved" || relational.TimelineEvents["timeline_test"].EvidenceID != "ev_test" { + t.Fatalf("relational incident rows missing: incident=%#v timeline=%#v", relational.Incidents["incident_test"], relational.TimelineEvents["timeline_test"]) + } + if relational.IncidentWebhookReceivers["receiver_test"].Status != "active" || relational.IncidentWebhookEvents["webhook_event_test"].TimelineEventID != "timeline_test" { + t.Fatalf("relational incident webhook rows missing: receiver=%#v event=%#v", relational.IncidentWebhookReceivers["receiver_test"], relational.IncidentWebhookEvents["webhook_event_test"]) + } + if relational.RemediationTasks["remediation_test"].Status != "done" { + t.Fatalf("relational remediation task missing: task=%#v", relational.RemediationTasks["remediation_test"]) + } + if relational.SecurityScans["secscan_test"].Summary["high"] != 1 || relational.ManualSecurityDocs["manual_doc_test"].Sensitivity != "restricted" { + t.Fatalf("relational security evidence rows missing: scan=%#v doc=%#v", relational.SecurityScans["secscan_test"], relational.ManualSecurityDocs["manual_doc_test"]) + } + if len(relational.SBOMDiffs["sbomdiff_test"].AddedComponents) != 1 || relational.DependencyChanges["depchange_test"].Component.Name != "lib2" { + t.Fatalf("relational sbom diff rows missing: diff=%#v change=%#v", relational.SBOMDiffs["sbomdiff_test"], relational.DependencyChanges["depchange_test"]) + } + if relational.VulnerabilityWorkflow["vulnwf_test"].Action != "reopened" || relational.ContractDiffs["contractdiff_test"].Result != "non_breaking" { + t.Fatalf("relational workflow/diff rows missing: workflow=%#v diff=%#v", relational.VulnerabilityWorkflow["vulnwf_test"], relational.ContractDiffs["contractdiff_test"]) + } + if len(relational.CustomPolicies["custom_policy_test"].Rules) != 1 || relational.CustomPolicyEvaluations["custom_policy_eval_test"].Result != "pass" { + t.Fatalf("relational custom policy rows missing: policy=%#v eval=%#v", relational.CustomPolicies["custom_policy_test"], relational.CustomPolicyEvaluations["custom_policy_eval_test"]) + } + if !relational.Waivers["waiver_test"].Approved || relational.Approvals["approval_test"].EvidenceID != "ev_test" || relational.DSSETrustRoots["dsse_root_test"].Status != "active" { + t.Fatalf("relational governance/trust rows missing: waiver=%#v approval=%#v trust=%#v", relational.Waivers["waiver_test"], relational.Approvals["approval_test"], relational.DSSETrustRoots["dsse_root_test"]) + } if relational.Products["prod_test"].Slug != "product" || relational.Evidence["ev_test"].ReleaseID != "rel_test" || relational.SBOMs["sbom_test"].ComponentCount != 1 { t.Fatalf("relational fallback missing core rows: product=%#v evidence=%#v sbom=%#v", relational.Products["prod_test"], relational.Evidence["ev_test"], relational.SBOMs["sbom_test"]) } From ba7f6c385b751a82c4090d02539dd48779aff27f Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 20:58:06 +0300 Subject: [PATCH 096/287] feat: recover future extension rows relationally --- .implementation_increments.md | 2 +- cmd/evydence-worker/main_test.go | 82 +++ docs/architecture.md | 2 +- docs/reference/production-readiness.md | 28 +- internal/adapters/postgres/store.go | 642 ++++++++++++++++++ internal/adapters/postgres/store_test.go | 87 +++ ...ining_relational_recovery_columns.down.sql | 6 + ...maining_relational_recovery_columns.up.sql | 6 + 8 files changed, 843 insertions(+), 12 deletions(-) create mode 100644 migrations/20260528001600_remaining_relational_recovery_columns.down.sql create mode 100644 migrations/20260528001600_remaining_relational_recovery_columns.up.sql diff --git a/.implementation_increments.md b/.implementation_increments.md index ad63cde..3aa51a7 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -36,7 +36,7 @@ Status legend: ## Remaining Core Product Increments 6. `[x]` Relational Store Split - Added migration-backed relational tables and tenant-scoped resource projection rows for implemented resources, with transactional PostgreSQL saves, relational identity/idempotency/customer-portal-token rows, relational release-ledger core rows, relational build provenance/source/deployment/incident/security-evidence/SBOM-diff/vulnerability-workflow/contract-diff/custom-policy/waiver/approval/DSSE-trust-root/evidence-lifecycle/release-candidate/VEX/control rows, relational package/report/retention rows, missing-snapshot fallback loading for identity, SSO session, release-ledger, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, and retention families, tenant/release indexes, persisted idempotency state, and outbox row locking. Canonical runtime loading still prefers the versioned ledger snapshot while per-resource repository tuning remains future hardening. + Added migration-backed relational tables and tenant-scoped resource projection rows for implemented resources, with transactional PostgreSQL saves, relational identity/idempotency/customer-portal-token rows, relational release-ledger core rows, relational build provenance/source/deployment/incident/security-evidence/SBOM-diff/vulnerability-workflow/contract-diff/custom-policy/waiver/approval/DSSE-trust-root/collector-release/Cosign-verification/signing-provider/Merkle-batch/transparency-checkpoint/evidence-lifecycle/release-candidate/VEX/control rows, relational package/report/retention/provider-verification/signing-operation/future-extension rows, missing-snapshot fallback loading for identity, SSO session, release-ledger, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension families, tenant/release indexes, persisted idempotency state, and outbox row locking. Canonical runtime loading still prefers the versioned ledger snapshot while per-resource repository tuning remains future hardening. 7. `[x]` Evidence Search, Filtering, And Timeline Querying Added tenant-scoped evidence search by product, project, release, build, deployment, type, subtype, source, collector, created time, subject refs, tags, and verification status. diff --git a/cmd/evydence-worker/main_test.go b/cmd/evydence-worker/main_test.go index b07e5e7..636b613 100644 --- a/cmd/evydence-worker/main_test.go +++ b/cmd/evydence-worker/main_test.go @@ -11,6 +11,8 @@ import ( "testing" "time" + "github.com/getkin/kin-openapi/openapi3" + "github.com/aatuh/evydence/internal/adapters/postgres" "github.com/aatuh/evydence/internal/app" "github.com/aatuh/evydence/internal/domain" @@ -444,6 +446,86 @@ func TestWorkerHelpersValidatePayloadHashAndEnv(t *testing.T) { } } +func TestReplayMergeHelpersCoverParserSideEffects(t *testing.T) { + sbom, changed := mergeReplayedSBOM(domain.SBOM{}, replayedSBOM{ + SpecVersion: "1.6", + ComponentCount: 1, + Components: []domain.SBOMComponent{{Name: "api"}}, + }) + if !changed || sbom.SpecVersion != "1.6" || sbom.ComponentCount != 1 || len(sbom.Components) != 1 { + t.Fatalf("merged sbom = %#v changed=%v", sbom, changed) + } + if _, changed := mergeReplayedSBOM(sbom, replayedSBOM{SpecVersion: "1.6"}); changed { + t.Fatal("complete sbom should not be changed") + } + + scan, changed := mergeReplayedVulnerabilityScan(domain.VulnerabilityScan{}, replayedVulnerabilityScan{ + Scanner: "grype", + TargetRef: "pkg:oci/api", + Summary: map[string]int{"high": 1}, + Findings: []domain.VulnerabilityFinding{{ID: "finding_1", Severity: "high"}}, + }) + if !changed || scan.Scanner != "grype" || scan.TargetRef == "" || scan.Summary["high"] != 1 || len(scan.Findings) != 1 { + t.Fatalf("merged scan = %#v changed=%v", scan, changed) + } + scan.Summary["high"] = 2 + if err := verifyReplayedVulnerabilityScan(replayedVulnerabilityScan{Scanner: "grype", TargetRef: "pkg:oci/api", Summary: map[string]int{"high": 1}}, scan); err == nil { + t.Fatal("expected vulnerability scan summary mismatch") + } + + vex, changed := mergeReplayedVEX(domain.VEXDocument{}, replayedVEX{Author: "security@example.test", StatementCount: 1, StatusSummary: map[string]int{"fixed": 1}}) + if !changed || vex.Author == "" || vex.StatementCount != 1 || vex.StatusSummary["fixed"] != 1 { + t.Fatalf("merged vex = %#v changed=%v", vex, changed) + } + if err := verifyReplayedVEX(replayedVEX{Author: "other", StatementCount: 1, StatusSummary: map[string]int{"fixed": 1}}, vex); err == nil { + t.Fatal("expected vex author mismatch") + } + + contract, changed := mergeReplayedOpenAPIContract(domain.OpenAPIContract{}, replayedOpenAPIContract{ + PathCount: 1, + Operations: []domain.OpenAPIOperation{{Path: "/v1/test", Method: "get"}}, + }) + if !changed || contract.PathCount != 1 || len(contract.Operations) != 1 { + t.Fatalf("merged contract = %#v changed=%v", contract, changed) + } + if err := verifyReplayedOpenAPIContract([]byte("raw"), replayedOpenAPIContract{PathCount: 2}, contract); err == nil { + t.Fatal("expected openapi path-count mismatch") + } + + raw := dsseEnvelopeForTest(t, "sha256:"+strings.Repeat("a", 64)) + attestation, changed := mergeReplayedAttestation(domain.BuildAttestation{}, replayedAttestation{ + PayloadType: "application/vnd.in-toto+json", + PredicateType: "https://slsa.dev/provenance/v1", + SubjectDigests: []string{"sha256:" + strings.Repeat("a", 64)}, + SignatureCount: 1, + BuilderID: "github-actions", + BuildType: "test", + MaterialsCount: 2, + }, raw) + if !changed || attestation.PayloadHash == "" || attestation.PayloadSize == 0 || attestation.PredicateType == "" || len(attestation.SubjectDigests) != 1 || attestation.SignatureCount != 1 || attestation.BuilderID == "" || attestation.BuildType == "" || attestation.MaterialsCount != 2 { + t.Fatalf("merged attestation = %#v changed=%v", attestation, changed) + } + if err := verifyReplayedAttestation(raw, replayedAttestation{PredicateType: "other", SubjectDigests: attestation.SubjectDigests}, attestation); err == nil { + t.Fatal("expected attestation predicate mismatch") + } + + if operationForMethod(&openapi3.PathItem{Get: &openapi3.Operation{}}, "get") == nil || operationForMethod(&openapi3.PathItem{Trace: &openapi3.Operation{}}, "trace") == nil || operationForMethod(&openapi3.PathItem{}, "unknown") != nil { + t.Fatal("operationForMethod did not route methods as expected") + } + if cloned := cloneIntMap(map[string]int{"high": 1}); cloned["high"] != 1 { + t.Fatalf("cloneIntMap = %#v", cloned) + } + if cloneIntMap(nil) != nil { + t.Fatal("nil cloneIntMap should stay nil") + } + if got, ok := nestedString(map[string]any{"outer": map[string]any{"inner": "value"}}, "outer", "inner"); !ok || got != "value" { + t.Fatalf("nestedString = %q %v", got, ok) + } + if equalStringSets([]string{"b", "a"}, []string{"a", "b"}) != true || equalStringSets([]string{"a"}, []string{"b"}) != false { + t.Fatal("equalStringSets mismatch") + } +} + func TestRunRequiresDatabaseURLAndWrapsOpenFailure(t *testing.T) { t.Setenv("EVYDENCE_DATABASE_URL", "") err := run() diff --git a/docs/architecture.md b/docs/architecture.md index 7ed5b8b..b3bc0bd 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -10,7 +10,7 @@ Evydence follows a ports-and-adapters shape: - `internal/adapters/objectstore/s3` stores the same tenant-prefixed object keys in S3/MinIO-compatible buckets. - `cmd/*` contains process entry points. -Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity, idempotency, and customer portal token records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. Collector/build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, and backup records are synchronized into their migration-backed relational tables. If the snapshot row is absent, the Postgres store can rebuild identity, SSO session, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, and retention families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. +Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity, idempotency, and customer portal token records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. Collector/build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension records are synchronized into their migration-backed relational tables. If the snapshot row is absent, the Postgres store can rebuild identity, SSO session, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. ## Tenant And Auth Boundaries diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 66476ba..e01298b 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -19,15 +19,19 @@ Known hardening work remains: relational identity, idempotency, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE - trust-root, evidence lifecycle, release candidate, VEX/risk decision, - control, audit-chain, signing, bundle, policy, verification, package, report, - and retention rows alongside the canonical snapshot, but the snapshot remains the + trust-root, collector release, Cosign verification, signing provider, Merkle + batch, transparency checkpoint, evidence lifecycle, release candidate, + VEX/risk decision, control, audit-chain, signing, bundle, policy, + verification, package, report, retention, provider verification, signing + operation, and future-extension rows alongside the canonical snapshot, but the snapshot remains the preferred runtime load source. If the snapshot row is absent, the store can rebuild identity, SSO session, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE - trust-root, evidence lifecycle, release candidate, VEX/risk decision, control, - package, report, and retention state from relational rows; + trust-root, collector release, Cosign verification, signing provider, Merkle + batch, transparency checkpoint, evidence lifecycle, release candidate, + VEX/risk decision, control, package, report, retention, provider verification, + signing operation, and future-extension state from relational rows; - worker parser jobs re-read raw object-store payloads for key formats, verify digests, validate durable state, and persist missing parser-derived normalized fields. Upload paths still create initial accepted records, so @@ -109,14 +113,18 @@ implemented capabilities: customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, - evidence lifecycle, release candidate, VEX/risk decision, control, - audit-chain, signing, bundle, policy, verification, package, report, and - retention rows are synchronized into relational tables. Missing-snapshot + collector release, Cosign verification, signing provider, Merkle batch, + transparency checkpoint, evidence lifecycle, release candidate, VEX/risk + decision, control, audit-chain, signing, bundle, policy, verification, + package, report, retention, provider verification, signing operation, and + future-extension rows are synchronized into relational tables. Missing-snapshot recovery can rebuild identity, SSO session, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, - waiver, approval, DSSE trust-root, evidence lifecycle, release candidate, - VEX/risk decision, control, package, report, and retention families from + waiver, approval, DSSE trust-root, collector release, Cosign verification, + signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, + release candidate, VEX/risk decision, control, package, report, retention, + provider verification, signing operation, and future-extension families from relational rows. Keep snapshots only for export/import and upgrade compatibility after the remaining families have repository-backed reads and writes. diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index 304fe93..2de6cef 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -90,9 +90,15 @@ func (s *Store) loadRelationalState(ctx context.Context) (app.PersistedState, bo if err := s.loadRelationalIncidentSecurityGovernance(ctx, &state, &loaded); err != nil { return app.PersistedState{}, false, err } + if err := s.loadRelationalIntegrityProviderRows(ctx, &state, &loaded); err != nil { + return app.PersistedState{}, false, err + } if err := s.loadRelationalPackageReportRetention(ctx, &state, &loaded); err != nil { return app.PersistedState{}, false, err } + if err := s.loadRelationalFutureExtensionRows(ctx, &state, &loaded); err != nil { + return app.PersistedState{}, false, err + } if err := s.loadRelationalIdempotency(ctx, &state, &loaded); err != nil { return app.PersistedState{}, false, err } @@ -112,6 +118,7 @@ func relationalEmptyState() app.PersistedState { APIKeys: map[string]domain.APIKey{}, APIKeyHashes: map[string]string{}, Collectors: map[string]domain.Collector{}, + CollectorReleases: map[string]domain.CollectorRelease{}, BuildRuns: map[string]domain.BuildRun{}, BuildAttestations: map[string]domain.BuildAttestation{}, EvidenceLifecycle: map[string]domain.EvidenceLifecycleEvent{}, @@ -140,6 +147,10 @@ func relationalEmptyState() app.PersistedState { Waivers: map[string]domain.Waiver{}, Approvals: map[string]domain.ApprovalRecord{}, DSSETrustRoots: map[string]domain.DSSETrustRoot{}, + CosignVerifications: map[string]domain.CosignVerification{}, + SigningProviders: map[string]domain.SigningProvider{}, + MerkleBatches: map[string]domain.MerkleBatch{}, + TransparencyCheckpoints: map[string]domain.TransparencyCheckpoint{}, CustomerPortalAccess: map[string]domain.CustomerPortalAccess{}, CustomerPortalHashes: map[string]string{}, RedactionProfiles: map[string]domain.RedactionProfile{}, @@ -155,8 +166,18 @@ func relationalEmptyState() app.PersistedState { RetentionOverrides: map[string]domain.RetentionOverride{}, QuestionnaireTemplates: map[string]domain.QuestionnaireTemplate{}, QuestionnairePackages: map[string]domain.QuestionnairePackage{}, + CommercialCollectors: map[string]domain.CommercialCollectorDefinition{}, + EvidenceSummaries: map[string]domain.EvidenceSummary{}, + QuestionnaireDrafts: map[string]domain.QuestionnaireDraft{}, + GraphSnapshots: map[string]domain.EvidenceGraphSnapshot{}, + SaaSProfiles: map[string]domain.SaaSEditionProfile{}, + PublicTransparencyLogs: map[string]domain.PublicTransparencyLog{}, + PublicTransparencyItems: map[string]domain.PublicTransparencyLogEntry{}, + MarketplaceCollectors: map[string]domain.MarketplaceCollector{}, PDFReports: map[string]domain.PDFReportPackage{}, AnomalyReports: map[string]domain.AnomalyReport{}, + ProviderVerifications: map[string]domain.ProviderVerification{}, + SigningOperations: map[string]domain.SigningOperation{}, ControlFrameworks: map[string]domain.ControlFramework{}, SecurityControls: map[string]domain.SecurityControl{}, ControlEvidence: map[string]domain.ControlEvidence{}, @@ -1715,6 +1736,109 @@ func (s *Store) loadRelationalWaiversApprovalsTrust(ctx context.Context, state * return trustRows.Err() } +func (s *Store) loadRelationalIntegrityProviderRows(ctx context.Context, state *app.PersistedState, loaded *bool) error { + collectorRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, collector_id, version, artifact_digest, signature_id, sbom_id, scan_id, pinned, verification_status, health_status, limitations, schema_version, created_at FROM collector_releases`) + if err != nil { + return fmt.Errorf("load relational collector releases: %w", err) + } + defer collectorRows.Close() + for collectorRows.Next() { + var release domain.CollectorRelease + var signatureID, sbomID, scanID sql.NullString + if err := collectorRows.Scan(&release.ID, &release.TenantID, &release.CollectorID, &release.Version, &release.ArtifactDigest, &signatureID, &sbomID, &scanID, &release.Pinned, &release.VerificationStatus, &release.HealthStatus, &release.Limitations, &release.SchemaVersion, &release.CreatedAt); err != nil { + return fmt.Errorf("scan relational collector release: %w", err) + } + release.SignatureID = nullableSQLString(signatureID) + release.SBOMID = nullableSQLString(sbomID) + release.ScanID = nullableSQLString(scanID) + state.CollectorReleases[release.ID] = release + *loaded = true + } + if err := collectorRows.Err(); err != nil { + return err + } + + cosignRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, artifact_id, container_image_id, artifact_signature_id, subject_digest, rekor_uuid, rekor_log_index, certificate_identity, certificate_issuer, result, checks, schema_version, created_at FROM cosign_verifications`) + if err != nil { + return fmt.Errorf("load relational cosign verifications: %w", err) + } + defer cosignRows.Close() + for cosignRows.Next() { + var verification domain.CosignVerification + var artifactID, imageID, rekorUUID, rekorLogIndex, certIdentity, certIssuer sql.NullString + var checks []byte + if err := cosignRows.Scan(&verification.ID, &verification.TenantID, &artifactID, &imageID, &verification.ArtifactSignatureID, &verification.SubjectDigest, &rekorUUID, &rekorLogIndex, &certIdentity, &certIssuer, &verification.Result, &checks, &verification.SchemaVersion, &verification.CreatedAt); err != nil { + return fmt.Errorf("scan relational cosign verification: %w", err) + } + verification.ArtifactID = nullableSQLString(artifactID) + verification.ContainerImageID = nullableSQLString(imageID) + verification.RekorUUID = nullableSQLString(rekorUUID) + verification.RekorLogIndex = nullableSQLString(rekorLogIndex) + verification.CertificateIdentity = nullableSQLString(certIdentity) + verification.CertificateIssuer = nullableSQLString(certIssuer) + if err := decodeJSON(checks, &verification.Checks); err != nil { + return fmt.Errorf("decode relational cosign checks: %w", err) + } + state.CosignVerifications[verification.ID] = verification + *loaded = true + } + if err := cosignRows.Err(); err != nil { + return err + } + + providerRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, name, type, status, key_ref, encrypted, schema_version, created_at FROM signing_providers`) + if err != nil { + return fmt.Errorf("load relational signing providers: %w", err) + } + defer providerRows.Close() + for providerRows.Next() { + var provider domain.SigningProvider + if err := providerRows.Scan(&provider.ID, &provider.TenantID, &provider.Name, &provider.Type, &provider.Status, &provider.KeyRef, &provider.Encrypted, &provider.SchemaVersion, &provider.CreatedAt); err != nil { + return fmt.Errorf("scan relational signing provider: %w", err) + } + state.SigningProviders[provider.ID] = provider + *loaded = true + } + if err := providerRows.Err(); err != nil { + return err + } + + batchRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, from_sequence, to_sequence, entry_count, leaf_hashes, root_hash, signature_refs, schema_version, created_at FROM merkle_batches`) + if err != nil { + return fmt.Errorf("load relational merkle batches: %w", err) + } + defer batchRows.Close() + for batchRows.Next() { + var batch domain.MerkleBatch + if err := batchRows.Scan(&batch.ID, &batch.TenantID, &batch.FromSequence, &batch.ToSequence, &batch.EntryCount, &batch.LeafHashes, &batch.RootHash, &batch.SignatureRefs, &batch.SchemaVersion, &batch.CreatedAt); err != nil { + return fmt.Errorf("scan relational merkle batch: %w", err) + } + state.MerkleBatches[batch.ID] = batch + *loaded = true + } + if err := batchRows.Err(); err != nil { + return err + } + + checkpointRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, batch_id, provider, external_url, external_id, timestamp_hash, state, schema_version, created_at FROM transparency_checkpoints`) + if err != nil { + return fmt.Errorf("load relational transparency checkpoints: %w", err) + } + defer checkpointRows.Close() + for checkpointRows.Next() { + var checkpoint domain.TransparencyCheckpoint + var externalURL, externalID sql.NullString + if err := checkpointRows.Scan(&checkpoint.ID, &checkpoint.TenantID, &checkpoint.BatchID, &checkpoint.Provider, &externalURL, &externalID, &checkpoint.TimestampHash, &checkpoint.State, &checkpoint.SchemaVersion, &checkpoint.CreatedAt); err != nil { + return fmt.Errorf("scan relational transparency checkpoint: %w", err) + } + checkpoint.ExternalURL = nullableSQLString(externalURL) + checkpoint.ExternalID = nullableSQLString(externalID) + state.TransparencyCheckpoints[checkpoint.ID] = checkpoint + *loaded = true + } + return checkpointRows.Err() +} + func (s *Store) loadRelationalPackageReportRetention(ctx context.Context, state *app.PersistedState, loaded *bool) error { if err := s.loadRelationalPackages(ctx, state, loaded); err != nil { return err @@ -2040,6 +2164,220 @@ func (s *Store) loadRelationalRetention(ctx context.Context, state *app.Persiste return qpRows.Err() } +func (s *Store) loadRelationalFutureExtensionRows(ctx context.Context, state *app.PersistedState, loaded *bool) error { + commercialRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, name, provider, version, manifest_hash, allowed_scopes, status, schema_version, created_at FROM commercial_collectors`) + if err != nil { + return fmt.Errorf("load relational commercial collectors: %w", err) + } + defer commercialRows.Close() + for commercialRows.Next() { + var collector domain.CommercialCollectorDefinition + if err := commercialRows.Scan(&collector.ID, &collector.TenantID, &collector.Name, &collector.Provider, &collector.Version, &collector.ManifestHash, &collector.AllowedScopes, &collector.Status, &collector.SchemaVersion, &collector.CreatedAt); err != nil { + return fmt.Errorf("scan relational commercial collector: %w", err) + } + state.CommercialCollectors[collector.ID] = collector + *loaded = true + } + if err := commercialRows.Err(); err != nil { + return err + } + + summaryRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, subject_type, subject_id, evidence_ids, summary, citations, assumptions, limitations, schema_version, created_at FROM evidence_summaries`) + if err != nil { + return fmt.Errorf("load relational evidence summaries: %w", err) + } + defer summaryRows.Close() + for summaryRows.Next() { + var summary domain.EvidenceSummary + var citations []byte + if err := summaryRows.Scan(&summary.ID, &summary.TenantID, &summary.SubjectType, &summary.SubjectID, &summary.EvidenceIDs, &summary.Summary, &citations, &summary.Assumptions, &summary.Limitations, &summary.SchemaVersion, &summary.CreatedAt); err != nil { + return fmt.Errorf("scan relational evidence summary: %w", err) + } + if err := decodeJSON(citations, &summary.Citations); err != nil { + return fmt.Errorf("decode relational evidence summary citations: %w", err) + } + state.EvidenceSummaries[summary.ID] = summary + *loaded = true + } + if err := summaryRows.Err(); err != nil { + return err + } + + draftRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, template_id, product_id, release_id, responses, manifest_hash, limitations, schema_version, created_at FROM questionnaire_drafts`) + if err != nil { + return fmt.Errorf("load relational questionnaire drafts: %w", err) + } + defer draftRows.Close() + for draftRows.Next() { + var draft domain.QuestionnaireDraft + var productID, releaseID sql.NullString + var responses []byte + if err := draftRows.Scan(&draft.ID, &draft.TenantID, &draft.TemplateID, &productID, &releaseID, &responses, &draft.ManifestHash, &draft.Limitations, &draft.SchemaVersion, &draft.CreatedAt); err != nil { + return fmt.Errorf("scan relational questionnaire draft: %w", err) + } + draft.ProductID = nullableSQLString(productID) + draft.ReleaseID = nullableSQLString(releaseID) + if err := decodeJSON(responses, &draft.Responses); err != nil { + return fmt.Errorf("decode relational questionnaire draft responses: %w", err) + } + state.QuestionnaireDrafts[draft.ID] = draft + *loaded = true + } + if err := draftRows.Err(); err != nil { + return err + } + + graphRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, product_id, release_id, nodes, edges, graph_hash, limitations, schema_version, created_at FROM evidence_graph_snapshots`) + if err != nil { + return fmt.Errorf("load relational graph snapshots: %w", err) + } + defer graphRows.Close() + for graphRows.Next() { + var graph domain.EvidenceGraphSnapshot + var productID, releaseID sql.NullString + var nodes, edges []byte + if err := graphRows.Scan(&graph.ID, &graph.TenantID, &productID, &releaseID, &nodes, &edges, &graph.GraphHash, &graph.Limitations, &graph.SchemaVersion, &graph.CreatedAt); err != nil { + return fmt.Errorf("scan relational graph snapshot: %w", err) + } + graph.ProductID = nullableSQLString(productID) + graph.ReleaseID = nullableSQLString(releaseID) + if err := decodeJSON(nodes, &graph.Nodes); err != nil { + return fmt.Errorf("decode relational graph nodes: %w", err) + } + if err := decodeJSON(edges, &graph.Edges); err != nil { + return fmt.Errorf("decode relational graph edges: %w", err) + } + state.GraphSnapshots[graph.ID] = graph + *loaded = true + } + if err := graphRows.Err(); err != nil { + return err + } + + saasRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, name, region, admin_tenant_id, isolation_model, status, config_hash, limitations, schema_version, created_at FROM saas_edition_profiles`) + if err != nil { + return fmt.Errorf("load relational saas profiles: %w", err) + } + defer saasRows.Close() + for saasRows.Next() { + var profile domain.SaaSEditionProfile + if err := saasRows.Scan(&profile.ID, &profile.TenantID, &profile.Name, &profile.Region, &profile.AdminTenantID, &profile.IsolationModel, &profile.Status, &profile.ConfigHash, &profile.Limitations, &profile.SchemaVersion, &profile.CreatedAt); err != nil { + return fmt.Errorf("scan relational saas profile: %w", err) + } + state.SaaSProfiles[profile.ID] = profile + *loaded = true + } + if err := saasRows.Err(); err != nil { + return err + } + + logRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, name, endpoint, public_key, state, schema_version, created_at FROM public_transparency_logs`) + if err != nil { + return fmt.Errorf("load relational public transparency logs: %w", err) + } + defer logRows.Close() + for logRows.Next() { + var log domain.PublicTransparencyLog + if err := logRows.Scan(&log.ID, &log.TenantID, &log.Name, &log.Endpoint, &log.PublicKey, &log.State, &log.SchemaVersion, &log.CreatedAt); err != nil { + return fmt.Errorf("scan relational public transparency log: %w", err) + } + state.PublicTransparencyLogs[log.ID] = log + *loaded = true + } + if err := logRows.Err(); err != nil { + return err + } + + entryRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, log_id, checkpoint_id, merkle_batch_id, external_id, entry_hash, inclusion_root_hash, inclusion_proof_hash, inclusion_verified_at, verification_checks, verification_limitations, state, schema_version, created_at FROM public_transparency_log_entries`) + if err != nil { + return fmt.Errorf("load relational public transparency entries: %w", err) + } + defer entryRows.Close() + for entryRows.Next() { + var entry domain.PublicTransparencyLogEntry + var rootHash, proofHash sql.NullString + var verifiedAt sql.NullTime + var checks []byte + if err := entryRows.Scan(&entry.ID, &entry.TenantID, &entry.LogID, &entry.CheckpointID, &entry.MerkleBatchID, &entry.ExternalID, &entry.EntryHash, &rootHash, &proofHash, &verifiedAt, &checks, &entry.VerificationLimitations, &entry.State, &entry.SchemaVersion, &entry.CreatedAt); err != nil { + return fmt.Errorf("scan relational public transparency entry: %w", err) + } + entry.InclusionRootHash = nullableSQLString(rootHash) + entry.InclusionProofHash = nullableSQLString(proofHash) + entry.InclusionVerifiedAt = nullableSQLTime(verifiedAt) + if err := decodeJSON(checks, &entry.VerificationChecks); err != nil { + return fmt.Errorf("decode relational transparency checks: %w", err) + } + state.PublicTransparencyItems[entry.ID] = entry + *loaded = true + } + if err := entryRows.Err(); err != nil { + return err + } + + marketRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, name, provider, version, publisher, manifest_hash, signature_id, sbom_id, scan_id, state, limitations, schema_version, created_at FROM marketplace_collectors`) + if err != nil { + return fmt.Errorf("load relational marketplace collectors: %w", err) + } + defer marketRows.Close() + for marketRows.Next() { + var collector domain.MarketplaceCollector + var signatureID, sbomID, scanID sql.NullString + if err := marketRows.Scan(&collector.ID, &collector.TenantID, &collector.Name, &collector.Provider, &collector.Version, &collector.Publisher, &collector.ManifestHash, &signatureID, &sbomID, &scanID, &collector.State, &collector.Limitations, &collector.SchemaVersion, &collector.CreatedAt); err != nil { + return fmt.Errorf("scan relational marketplace collector: %w", err) + } + collector.SignatureID = nullableSQLString(signatureID) + collector.SBOMID = nullableSQLString(sbomID) + collector.ScanID = nullableSQLString(scanID) + state.MarketplaceCollectors[collector.ID] = collector + *loaded = true + } + if err := marketRows.Err(); err != nil { + return err + } + + providerRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, provider_type, provider_id, subject, result, checks, limitations, schema_version, created_at FROM provider_verifications`) + if err != nil { + return fmt.Errorf("load relational provider verifications: %w", err) + } + defer providerRows.Close() + for providerRows.Next() { + var verification domain.ProviderVerification + var checks []byte + if err := providerRows.Scan(&verification.ID, &verification.TenantID, &verification.ProviderType, &verification.ProviderID, &verification.Subject, &verification.Result, &checks, &verification.Limitations, &verification.SchemaVersion, &verification.CreatedAt); err != nil { + return fmt.Errorf("scan relational provider verification: %w", err) + } + if err := decodeJSON(checks, &verification.Checks); err != nil { + return fmt.Errorf("decode relational provider verification checks: %w", err) + } + state.ProviderVerifications[verification.ID] = verification + *loaded = true + } + if err := providerRows.Err(); err != nil { + return err + } + + signingRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, provider_id, subject_type, subject_id, payload_hash, signature_ref, result, checks, schema_version, created_at FROM signing_operations`) + if err != nil { + return fmt.Errorf("load relational signing operations: %w", err) + } + defer signingRows.Close() + for signingRows.Next() { + var operation domain.SigningOperation + var signatureRef sql.NullString + var checks []byte + if err := signingRows.Scan(&operation.ID, &operation.TenantID, &operation.ProviderID, &operation.SubjectType, &operation.SubjectID, &operation.PayloadHash, &signatureRef, &operation.Result, &checks, &operation.SchemaVersion, &operation.CreatedAt); err != nil { + return fmt.Errorf("scan relational signing operation: %w", err) + } + operation.SignatureRef = nullableSQLString(signatureRef) + if err := decodeJSON(checks, &operation.Checks); err != nil { + return fmt.Errorf("decode relational signing operation checks: %w", err) + } + state.SigningOperations[operation.ID] = operation + *loaded = true + } + return signingRows.Err() +} + func (s *Store) loadRelationalIdempotency(ctx context.Context, state *app.PersistedState, loaded *bool) error { rows, err := s.pool.Query(ctx, `SELECT tenant_id, actor_key_id, method, path, idempotency_key, request_hash, status, response, created_at FROM idempotency_records`) if err != nil { @@ -2099,9 +2437,15 @@ func (s *Store) SaveState(ctx context.Context, state app.PersistedState) error { if err := syncIncidentSecurityGovernanceRows(ctx, tx, state); err != nil { return err } + if err := syncIntegrityProviderRows(ctx, tx, state); err != nil { + return err + } if err := syncPackageReportRetentionRows(ctx, tx, state); err != nil { return err } + if err := syncFutureExtensionRows(ctx, tx, state); err != nil { + return err + } if err := tx.Commit(ctx); err != nil { return fmt.Errorf("commit save ledger state transaction: %w", err) } @@ -3175,6 +3519,104 @@ func syncIncidentSecurityGovernanceRows(ctx context.Context, tx pgx.Tx, state ap return nil } +func syncIntegrityProviderRows(ctx context.Context, tx pgx.Tx, state app.PersistedState) error { + for _, release := range state.CollectorReleases { + if release.ID == "" || release.TenantID == "" || release.CollectorID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO collector_releases ( + id, tenant_id, collector_id, version, artifact_digest, + signature_id, sbom_id, scan_id, pinned, verification_status, + health_status, limitations, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) + ON CONFLICT (id) DO UPDATE SET + pinned = EXCLUDED.pinned, + verification_status = EXCLUDED.verification_status, + health_status = EXCLUDED.health_status, + limitations = EXCLUDED.limitations, + schema_version = EXCLUDED.schema_version + `, release.ID, release.TenantID, release.CollectorID, release.Version, release.ArtifactDigest, + nullableString(release.SignatureID), nullableString(release.SBOMID), nullableString(release.ScanID), + release.Pinned, release.VerificationStatus, release.HealthStatus, release.Limitations, + release.SchemaVersion, nonZeroTime(release.CreatedAt)); err != nil { + return fmt.Errorf("upsert collector release row: %w", err) + } + } + for _, verification := range state.CosignVerifications { + if verification.ID == "" || verification.TenantID == "" || verification.ArtifactSignatureID == "" { + continue + } + checks, err := json.Marshal(verification.Checks) + if err != nil { + return fmt.Errorf("encode cosign checks: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO cosign_verifications ( + id, tenant_id, artifact_id, container_image_id, + artifact_signature_id, subject_digest, rekor_uuid, rekor_log_index, + certificate_identity, certificate_issuer, result, checks, + schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) + ON CONFLICT (id) DO UPDATE SET result = EXCLUDED.result, checks = EXCLUDED.checks, schema_version = EXCLUDED.schema_version + `, verification.ID, verification.TenantID, nullableString(verification.ArtifactID), nullableString(verification.ContainerImageID), + verification.ArtifactSignatureID, verification.SubjectDigest, nullableString(verification.RekorUUID), + nullableString(verification.RekorLogIndex), nullableString(verification.CertificateIdentity), + nullableString(verification.CertificateIssuer), verification.Result, checks, verification.SchemaVersion, + nonZeroTime(verification.CreatedAt)); err != nil { + return fmt.Errorf("upsert cosign verification row: %w", err) + } + } + for _, provider := range state.SigningProviders { + if provider.ID == "" || provider.TenantID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO signing_providers ( + id, tenant_id, name, type, status, key_ref, encrypted, + schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + ON CONFLICT (id) DO UPDATE SET status = EXCLUDED.status, key_ref = EXCLUDED.key_ref, encrypted = EXCLUDED.encrypted, schema_version = EXCLUDED.schema_version + `, provider.ID, provider.TenantID, provider.Name, provider.Type, provider.Status, provider.KeyRef, provider.Encrypted, provider.SchemaVersion, nonZeroTime(provider.CreatedAt)); err != nil { + return fmt.Errorf("upsert signing provider row: %w", err) + } + } + for _, batch := range state.MerkleBatches { + if batch.ID == "" || batch.TenantID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO merkle_batches ( + id, tenant_id, from_sequence, to_sequence, entry_count, + leaf_hashes, root_hash, signature_refs, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) + ON CONFLICT (id) DO UPDATE SET signature_refs = EXCLUDED.signature_refs, schema_version = EXCLUDED.schema_version + `, batch.ID, batch.TenantID, batch.FromSequence, batch.ToSequence, batch.EntryCount, batch.LeafHashes, batch.RootHash, batch.SignatureRefs, batch.SchemaVersion, nonZeroTime(batch.CreatedAt)); err != nil { + return fmt.Errorf("upsert merkle batch row: %w", err) + } + } + for _, checkpoint := range state.TransparencyCheckpoints { + if checkpoint.ID == "" || checkpoint.TenantID == "" || checkpoint.BatchID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO transparency_checkpoints ( + id, tenant_id, batch_id, provider, external_url, external_id, + timestamp_hash, state, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) + ON CONFLICT (id) DO UPDATE SET state = EXCLUDED.state, external_url = EXCLUDED.external_url, external_id = EXCLUDED.external_id, schema_version = EXCLUDED.schema_version + `, checkpoint.ID, checkpoint.TenantID, checkpoint.BatchID, checkpoint.Provider, nullableString(checkpoint.ExternalURL), nullableString(checkpoint.ExternalID), checkpoint.TimestampHash, checkpoint.State, checkpoint.SchemaVersion, nonZeroTime(checkpoint.CreatedAt)); err != nil { + return fmt.Errorf("upsert transparency checkpoint row: %w", err) + } + } + return nil +} + func syncPackageReportRetentionRows(ctx context.Context, tx pgx.Tx, state app.PersistedState) error { for _, profile := range state.RedactionProfiles { if profile.ID == "" || profile.TenantID == "" { @@ -3490,6 +3932,206 @@ func syncPackageReportRetentionRows(ctx context.Context, tx pgx.Tx, state app.Pe return nil } +func syncFutureExtensionRows(ctx context.Context, tx pgx.Tx, state app.PersistedState) error { + for _, collector := range state.CommercialCollectors { + if collector.ID == "" || collector.TenantID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO commercial_collectors ( + id, tenant_id, name, provider, version, manifest_hash, + allowed_scopes, status, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) + ON CONFLICT (id) DO UPDATE SET + allowed_scopes = EXCLUDED.allowed_scopes, + status = EXCLUDED.status, + schema_version = EXCLUDED.schema_version + `, collector.ID, collector.TenantID, collector.Name, collector.Provider, collector.Version, collector.ManifestHash, collector.AllowedScopes, collector.Status, collector.SchemaVersion, nonZeroTime(collector.CreatedAt)); err != nil { + return fmt.Errorf("upsert commercial collector row: %w", err) + } + } + for _, summary := range state.EvidenceSummaries { + if summary.ID == "" || summary.TenantID == "" { + continue + } + citations, err := json.Marshal(summary.Citations) + if err != nil { + return fmt.Errorf("encode evidence summary citations: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO evidence_summaries ( + id, tenant_id, subject_type, subject_id, evidence_ids, summary, + citations, assumptions, limitations, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) + ON CONFLICT (id) DO UPDATE SET summary = EXCLUDED.summary, citations = EXCLUDED.citations, assumptions = EXCLUDED.assumptions, limitations = EXCLUDED.limitations, schema_version = EXCLUDED.schema_version + `, summary.ID, summary.TenantID, summary.SubjectType, summary.SubjectID, summary.EvidenceIDs, summary.Summary, citations, summary.Assumptions, summary.Limitations, summary.SchemaVersion, nonZeroTime(summary.CreatedAt)); err != nil { + return fmt.Errorf("upsert evidence summary row: %w", err) + } + } + for _, draft := range state.QuestionnaireDrafts { + if draft.ID == "" || draft.TenantID == "" { + continue + } + responses, err := json.Marshal(draft.Responses) + if err != nil { + return fmt.Errorf("encode questionnaire draft responses: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO questionnaire_drafts ( + id, tenant_id, template_id, product_id, release_id, responses, + manifest_hash, limitations, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) + ON CONFLICT (id) DO UPDATE SET responses = EXCLUDED.responses, manifest_hash = EXCLUDED.manifest_hash, limitations = EXCLUDED.limitations, schema_version = EXCLUDED.schema_version + `, draft.ID, draft.TenantID, draft.TemplateID, nullableString(draft.ProductID), nullableString(draft.ReleaseID), responses, draft.ManifestHash, draft.Limitations, draft.SchemaVersion, nonZeroTime(draft.CreatedAt)); err != nil { + return fmt.Errorf("upsert questionnaire draft row: %w", err) + } + } + for _, graph := range state.GraphSnapshots { + if graph.ID == "" || graph.TenantID == "" { + continue + } + nodes, err := json.Marshal(graph.Nodes) + if err != nil { + return fmt.Errorf("encode graph nodes: %w", err) + } + edges, err := json.Marshal(graph.Edges) + if err != nil { + return fmt.Errorf("encode graph edges: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO evidence_graph_snapshots ( + id, tenant_id, product_id, release_id, nodes, edges, + graph_hash, limitations, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) + ON CONFLICT (id) DO UPDATE SET nodes = EXCLUDED.nodes, edges = EXCLUDED.edges, graph_hash = EXCLUDED.graph_hash, limitations = EXCLUDED.limitations, schema_version = EXCLUDED.schema_version + `, graph.ID, graph.TenantID, nullableString(graph.ProductID), nullableString(graph.ReleaseID), nodes, edges, graph.GraphHash, graph.Limitations, graph.SchemaVersion, nonZeroTime(graph.CreatedAt)); err != nil { + return fmt.Errorf("upsert graph snapshot row: %w", err) + } + } + for _, profile := range state.SaaSProfiles { + if profile.ID == "" || profile.TenantID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO saas_edition_profiles ( + id, tenant_id, name, region, admin_tenant_id, isolation_model, + status, config_hash, limitations, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) + ON CONFLICT (id) DO UPDATE SET status = EXCLUDED.status, config_hash = EXCLUDED.config_hash, limitations = EXCLUDED.limitations, schema_version = EXCLUDED.schema_version + `, profile.ID, profile.TenantID, profile.Name, profile.Region, profile.AdminTenantID, profile.IsolationModel, profile.Status, profile.ConfigHash, profile.Limitations, profile.SchemaVersion, nonZeroTime(profile.CreatedAt)); err != nil { + return fmt.Errorf("upsert saas profile row: %w", err) + } + } + for _, log := range state.PublicTransparencyLogs { + if log.ID == "" || log.TenantID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO public_transparency_logs ( + id, tenant_id, name, endpoint, public_key, state, + schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8) + ON CONFLICT (id) DO UPDATE SET state = EXCLUDED.state, schema_version = EXCLUDED.schema_version + `, log.ID, log.TenantID, log.Name, log.Endpoint, log.PublicKey, log.State, log.SchemaVersion, nonZeroTime(log.CreatedAt)); err != nil { + return fmt.Errorf("upsert public transparency log row: %w", err) + } + } + for _, entry := range state.PublicTransparencyItems { + if entry.ID == "" || entry.TenantID == "" { + continue + } + checks, err := json.Marshal(entry.VerificationChecks) + if err != nil { + return fmt.Errorf("encode public transparency checks: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO public_transparency_log_entries ( + id, tenant_id, log_id, checkpoint_id, merkle_batch_id, + external_id, entry_hash, inclusion_root_hash, + inclusion_proof_hash, inclusion_verified_at, verification_checks, + verification_limitations, state, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15) + ON CONFLICT (id) DO UPDATE SET + inclusion_root_hash = EXCLUDED.inclusion_root_hash, + inclusion_proof_hash = EXCLUDED.inclusion_proof_hash, + inclusion_verified_at = EXCLUDED.inclusion_verified_at, + verification_checks = EXCLUDED.verification_checks, + verification_limitations = EXCLUDED.verification_limitations, + state = EXCLUDED.state, + schema_version = EXCLUDED.schema_version + `, entry.ID, entry.TenantID, entry.LogID, entry.CheckpointID, entry.MerkleBatchID, entry.ExternalID, entry.EntryHash, + nullableString(entry.InclusionRootHash), nullableString(entry.InclusionProofHash), nullableTime(entry.InclusionVerifiedAt), + checks, entry.VerificationLimitations, entry.State, entry.SchemaVersion, nonZeroTime(entry.CreatedAt)); err != nil { + return fmt.Errorf("upsert public transparency entry row: %w", err) + } + } + for _, collector := range state.MarketplaceCollectors { + if collector.ID == "" || collector.TenantID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO marketplace_collectors ( + id, tenant_id, name, provider, version, publisher, + manifest_hash, signature_id, sbom_id, scan_id, state, + limitations, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) + ON CONFLICT (id) DO UPDATE SET state = EXCLUDED.state, limitations = EXCLUDED.limitations, schema_version = EXCLUDED.schema_version + `, collector.ID, collector.TenantID, collector.Name, collector.Provider, collector.Version, collector.Publisher, collector.ManifestHash, + nullableString(collector.SignatureID), nullableString(collector.SBOMID), nullableString(collector.ScanID), collector.State, + collector.Limitations, collector.SchemaVersion, nonZeroTime(collector.CreatedAt)); err != nil { + return fmt.Errorf("upsert marketplace collector row: %w", err) + } + } + for _, verification := range state.ProviderVerifications { + if verification.ID == "" || verification.TenantID == "" { + continue + } + checks, err := json.Marshal(verification.Checks) + if err != nil { + return fmt.Errorf("encode provider verification checks: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO provider_verifications ( + id, tenant_id, provider_type, provider_id, subject, result, + checks, limitations, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) + ON CONFLICT (id) DO UPDATE SET result = EXCLUDED.result, checks = EXCLUDED.checks, limitations = EXCLUDED.limitations, schema_version = EXCLUDED.schema_version + `, verification.ID, verification.TenantID, verification.ProviderType, verification.ProviderID, verification.Subject, verification.Result, checks, verification.Limitations, verification.SchemaVersion, nonZeroTime(verification.CreatedAt)); err != nil { + return fmt.Errorf("upsert provider verification row: %w", err) + } + } + for _, operation := range state.SigningOperations { + if operation.ID == "" || operation.TenantID == "" { + continue + } + checks, err := json.Marshal(operation.Checks) + if err != nil { + return fmt.Errorf("encode signing operation checks: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO signing_operations ( + id, tenant_id, provider_id, subject_type, subject_id, + payload_hash, signature_ref, result, checks, + schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) + ON CONFLICT (id) DO UPDATE SET signature_ref = EXCLUDED.signature_ref, result = EXCLUDED.result, checks = EXCLUDED.checks, schema_version = EXCLUDED.schema_version + `, operation.ID, operation.TenantID, operation.ProviderID, operation.SubjectType, operation.SubjectID, operation.PayloadHash, nullableString(operation.SignatureRef), operation.Result, checks, operation.SchemaVersion, nonZeroTime(operation.CreatedAt)); err != nil { + return fmt.Errorf("upsert signing operation row: %w", err) + } + } + return nil +} + func syncIdentityAndIdempotency(ctx context.Context, tx pgx.Tx, state app.PersistedState) error { for _, tenant := range state.Tenants { if tenant.ID == "" { diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index 8cdef3d..d351983 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -49,6 +49,9 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { Collectors: map[string]domain.Collector{ "collector_test": {ID: "collector_test", TenantID: "ten_test", Name: "github", Type: "github_actions", Version: "1.0.0", APIKeyID: "key_test", Status: "active", AllowedScopes: []string{"build:write"}, LastSeenAt: ptrTime(time.Now().UTC()), SchemaVersion: domain.CollectorSchemaVersion, CreatedAt: time.Now().UTC()}, }, + CollectorReleases: map[string]domain.CollectorRelease{ + "collector_release_test": {ID: "collector_release_test", TenantID: "ten_test", CollectorID: "collector_test", Version: "1.0.0", ArtifactDigest: "sha256:" + strings.Repeat("a", 64), SignatureID: "artsig_test", SBOMID: "sbom_test", ScanID: "scan_test", Pinned: true, VerificationStatus: "verified", HealthStatus: "healthy", Limitations: []string{"test"}, SchemaVersion: domain.CollectorReleaseSchemaVersion, CreatedAt: time.Now().UTC()}, + }, SSOProviders: map[string]domain.SSOProvider{ "sso_test": {ID: "sso_test", TenantID: "ten_test", Name: "OIDC", Type: "oidc", Issuer: "https://idp.example.test", ClientID: "client", Status: "active", JWKS: map[string]any{"keys": []any{map[string]any{"kty": "OKP", "kid": "kid-1", "crv": "Ed25519", "x": "abc"}}}, SchemaVersion: domain.SSOProviderSchemaVersion, CreatedAt: time.Now().UTC(), TrustMaterialUpdatedAt: ptrTime(time.Now().UTC())}, }, @@ -170,6 +173,18 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { DSSETrustRoots: map[string]domain.DSSETrustRoot{ "dsse_root_test": {ID: "dsse_root_test", TenantID: "ten_test", Name: "root", KeyID: "key-1", Algorithm: "Ed25519", PublicKey: "pub", Status: "active", SchemaVersion: domain.DSSETrustRootSchemaVersion, CreatedAt: time.Now().UTC()}, }, + CosignVerifications: map[string]domain.CosignVerification{ + "cosign_test": {ID: "cosign_test", TenantID: "ten_test", ArtifactID: "art_test", ContainerImageID: "image_test", ArtifactSignatureID: "artsig_test", SubjectDigest: "sha256:" + strings.Repeat("a", 64), RekorUUID: "rekor", RekorLogIndex: "1", CertificateIdentity: "repo", CertificateIssuer: "issuer", Result: "pass", Checks: []domain.VerifyCheck{{Name: "digest", Result: "passed"}}, SchemaVersion: domain.CosignVerificationSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + SigningProviders: map[string]domain.SigningProvider{ + "sign_provider_test": {ID: "sign_provider_test", TenantID: "ten_test", Name: "kms", Type: "aws_kms", Status: "active", KeyRef: "arn:aws:kms:test", Encrypted: true, SchemaVersion: domain.SigningProviderSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + MerkleBatches: map[string]domain.MerkleBatch{ + "merkle_test": {ID: "merkle_test", TenantID: "ten_test", FromSequence: 1, ToSequence: 1, EntryCount: 1, LeafHashes: []string{"sha256:" + strings.Repeat("e", 64)}, RootHash: "sha256:" + strings.Repeat("f", 64), SignatureRefs: []string{"sig_test"}, SchemaVersion: domain.MerkleBatchSchemaVersion, CreatedAt: time.Now().UTC()}, + }, + TransparencyCheckpoints: map[string]domain.TransparencyCheckpoint{ + "transparency_test": {ID: "transparency_test", TenantID: "ten_test", BatchID: "merkle_test", Provider: "internal", ExternalURL: "https://transparency.example.test", ExternalID: "ts-1", TimestampHash: "sha256:" + strings.Repeat("0", 64), State: "recorded", SchemaVersion: domain.TransparencyCheckpointVersion, CreatedAt: time.Now().UTC()}, + }, Chain: map[string][]domain.AuditChainEntry{ "ten_test": {{ ID: "chain_test", TenantID: "ten_test", Sequence: 1, EntryType: "evidence.created", SubjectType: "evidence_item", SubjectID: "ev_test", @@ -260,12 +275,42 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { QuestionnairePackages: map[string]domain.QuestionnairePackage{ "qp_test": {ID: "qp_test", TenantID: "ten_test", TemplateID: "qt_test", PackageID: "pkg_test", ProductID: "prod_test", ReleaseID: "rel_test", Responses: []domain.QuestionnaireResponse{{QuestionID: "q1", Answer: "See evidence", EvidenceIDs: []string{"ev_test"}}}, ManifestHash: "sha256:" + strings.Repeat("8", 64), SchemaVersion: domain.QuestionnairePackageVersion, CreatedAt: time.Now().UTC()}, }, + CommercialCollectors: map[string]domain.CommercialCollectorDefinition{ + "commercial_collector_test": {ID: "commercial_collector_test", TenantID: "ten_test", Name: "scanner", Provider: "scannerco", Version: "1.0.0", ManifestHash: "sha256:" + strings.Repeat("a", 64), AllowedScopes: []string{"evidence:write"}, Status: "active", SchemaVersion: domain.CommercialCollectorVersion, CreatedAt: time.Now().UTC()}, + }, + EvidenceSummaries: map[string]domain.EvidenceSummary{ + "summary_test": {ID: "summary_test", TenantID: "ten_test", SubjectType: "release", SubjectID: "rel_test", EvidenceIDs: []string{"ev_test"}, Summary: "Evidence summary.", Citations: []domain.EvidenceCitation{{EvidenceID: "ev_test", Type: "sbom", Title: "SBOM", CanonicalHash: "sha256:" + strings.Repeat("c", 64)}}, Assumptions: []string{"stored evidence only"}, Limitations: []string{"not a compliance conclusion"}, SchemaVersion: domain.EvidenceSummaryVersion, CreatedAt: time.Now().UTC()}, + }, + QuestionnaireDrafts: map[string]domain.QuestionnaireDraft{ + "draft_test": {ID: "draft_test", TenantID: "ten_test", TemplateID: "qt_test", ProductID: "prod_test", ReleaseID: "rel_test", Responses: []domain.QuestionnaireResponse{{QuestionID: "q1", Answer: "Draft", EvidenceIDs: []string{"ev_test"}}}, ManifestHash: "sha256:" + strings.Repeat("b", 64), Limitations: []string{"draft"}, SchemaVersion: domain.QuestionnaireDraftVersion, CreatedAt: time.Now().UTC()}, + }, + GraphSnapshots: map[string]domain.EvidenceGraphSnapshot{ + "graph_test": {ID: "graph_test", TenantID: "ten_test", ProductID: "prod_test", ReleaseID: "rel_test", Nodes: []domain.GraphNode{{ID: "ev_test", Type: "evidence", Label: "SBOM"}}, Edges: []domain.GraphEdge{{From: "rel_test", To: "ev_test", Relationship: "has_evidence"}}, GraphHash: "sha256:" + strings.Repeat("c", 64), Limitations: []string{"snapshot"}, SchemaVersion: domain.EvidenceGraphSnapshotVersion, CreatedAt: time.Now().UTC()}, + }, + SaaSProfiles: map[string]domain.SaaSEditionProfile{ + "saas_test": {ID: "saas_test", TenantID: "ten_test", Name: "hosted", Region: "eu", AdminTenantID: "ten_test", IsolationModel: "shared-control-plane", Status: "draft", ConfigHash: "sha256:" + strings.Repeat("d", 64), Limitations: []string{"not production"}, SchemaVersion: domain.SaaSEditionProfileVersion, CreatedAt: time.Now().UTC()}, + }, + PublicTransparencyLogs: map[string]domain.PublicTransparencyLog{ + "public_log_test": {ID: "public_log_test", TenantID: "ten_test", Name: "log", Endpoint: "https://log.example.test", PublicKey: "pub", State: "active", SchemaVersion: domain.PublicTransparencyLogVersion, CreatedAt: time.Now().UTC()}, + }, + PublicTransparencyItems: map[string]domain.PublicTransparencyLogEntry{ + "public_entry_test": {ID: "public_entry_test", TenantID: "ten_test", LogID: "public_log_test", CheckpointID: "transparency_test", MerkleBatchID: "merkle_test", ExternalID: "entry-1", EntryHash: "sha256:" + strings.Repeat("e", 64), InclusionRootHash: "sha256:" + strings.Repeat("f", 64), InclusionProofHash: "sha256:" + strings.Repeat("1", 64), InclusionVerifiedAt: ptrTime(time.Now().UTC()), VerificationChecks: []domain.VerifyCheck{{Name: "inclusion", Result: "passed"}}, VerificationLimitations: []string{"operator proof"}, State: "verified", SchemaVersion: domain.PublicTransparencyEntryVersion, CreatedAt: time.Now().UTC()}, + }, + MarketplaceCollectors: map[string]domain.MarketplaceCollector{ + "market_collector_test": {ID: "market_collector_test", TenantID: "ten_test", Name: "scanner", Provider: "scannerco", Version: "1.0.0", Publisher: "scannerco", ManifestHash: "sha256:" + strings.Repeat("a", 64), SignatureID: "artsig_test", SBOMID: "sbom_test", ScanID: "scan_test", State: "published", Limitations: []string{"external distribution"}, SchemaVersion: domain.MarketplaceCollectorVersion, CreatedAt: time.Now().UTC()}, + }, PDFReports: map[string]domain.PDFReportPackage{ "pdf_test": {ID: "pdf_test", TenantID: "ten_test", ReportType: "cra_readiness", ProductID: "prod_test", ReleaseID: "rel_test", Title: "PDF", PayloadRef: "object://tenants/ten_test/reports/pdf", PayloadHash: "sha256:" + strings.Repeat("9", 64), PayloadSize: 10, Limitations: []string{"test"}, SchemaVersion: domain.PDFReportPackageVersion, CreatedAt: time.Now().UTC()}, }, AnomalyReports: map[string]domain.AnomalyReport{ "anom_test": {ID: "anom_test", TenantID: "ten_test", SubjectType: "release", SubjectID: "rel_test", Result: "review", Signals: []domain.AnomalySignal{{Name: "gap", Severity: "medium", Detail: "test"}}, Assumptions: []string{"heuristic"}, Limitations: []string{"not ML"}, SchemaVersion: domain.AnomalyReportVersion, CreatedAt: time.Now().UTC()}, }, + ProviderVerifications: map[string]domain.ProviderVerification{ + "provider_verification_test": {ID: "provider_verification_test", TenantID: "ten_test", ProviderType: "oidc", ProviderID: "sso_test", Subject: "sub", Result: "verified", Checks: []domain.VerifyCheck{{Name: "subject", Result: "passed"}}, Limitations: []string{"static trust material"}, SchemaVersion: domain.ProviderVerificationVersion, CreatedAt: time.Now().UTC()}, + }, + SigningOperations: map[string]domain.SigningOperation{ + "signing_operation_test": {ID: "signing_operation_test", TenantID: "ten_test", ProviderID: "sign_provider_test", SubjectType: "release", SubjectID: "rel_test", PayloadHash: "sha256:" + strings.Repeat("2", 64), SignatureRef: "sig_test", Result: "signed", Checks: []domain.VerifyCheck{{Name: "provider", Result: "passed"}}, SchemaVersion: domain.SigningOperationVersion, CreatedAt: time.Now().UTC()}, + }, Idempotency: map[string]app.IdempotencyRecord{ app.NewIdempotencyRecordKey("ten_test", "user:user_test", "POST", "/v1/products", "idem"): {RequestHash: "sha256:request", Status: 201, Response: map[string]any{"ok": true}, CreatedAt: time.Now().UTC()}, }, @@ -331,6 +376,7 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { {name: "release", query: `SELECT count(*) FROM releases WHERE tenant_id = 'ten_test' AND id = 'rel_test'`}, {name: "artifact", query: `SELECT count(*) FROM artifacts WHERE tenant_id = 'ten_test' AND digest LIKE 'sha256:%'`}, {name: "collector", query: `SELECT count(*) FROM collectors WHERE tenant_id = 'ten_test' AND id = 'collector_test' AND allowed_scopes <> '[]'::jsonb`}, + {name: "collector release", query: `SELECT count(*) FROM collector_releases WHERE tenant_id = 'ten_test' AND id = 'collector_release_test' AND pinned = true`}, {name: "build run", query: `SELECT count(*) FROM build_runs WHERE tenant_id = 'ten_test' AND id = 'build_test' AND outputs <> '[]'::jsonb`}, {name: "build attestation", query: `SELECT count(*) FROM build_attestations WHERE tenant_id = 'ten_test' AND id = 'att_test' AND subject_digests <> '[]'::jsonb`}, {name: "evidence", query: `SELECT count(*) FROM evidence_items WHERE tenant_id = 'ten_test' AND id = 'ev_test' AND evidence_version = 1 AND product_id = 'prod_test'`}, @@ -360,6 +406,10 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { {name: "waiver", query: `SELECT count(*) FROM waivers WHERE tenant_id = 'ten_test' AND id = 'waiver_test' AND approved = true`}, {name: "approval", query: `SELECT count(*) FROM approval_records WHERE tenant_id = 'ten_test' AND id = 'approval_test' AND evidence_id = 'ev_test'`}, {name: "dsse trust root", query: `SELECT count(*) FROM dsse_trust_roots WHERE tenant_id = 'ten_test' AND id = 'dsse_root_test' AND status = 'active'`}, + {name: "cosign verification", query: `SELECT count(*) FROM cosign_verifications WHERE tenant_id = 'ten_test' AND id = 'cosign_test' AND checks <> '[]'::jsonb`}, + {name: "signing provider", query: `SELECT count(*) FROM signing_providers WHERE tenant_id = 'ten_test' AND id = 'sign_provider_test' AND encrypted = true`}, + {name: "merkle batch", query: `SELECT count(*) FROM merkle_batches WHERE tenant_id = 'ten_test' AND id = 'merkle_test' AND signature_refs = ARRAY['sig_test']`}, + {name: "transparency checkpoint", query: `SELECT count(*) FROM transparency_checkpoints WHERE tenant_id = 'ten_test' AND id = 'transparency_test' AND external_id = 'ts-1'`}, {name: "audit chain", query: `SELECT count(*) FROM audit_chain_entries WHERE tenant_id = 'ten_test' AND sequence = 1`}, {name: "signing key", query: `SELECT count(*) FROM signing_keys WHERE tenant_id = 'ten_test' AND id = 'sigkey_test' AND encrypted_private_key IS NOT NULL`}, {name: "signature", query: `SELECT count(*) FROM signatures WHERE tenant_id = 'ten_test' AND id = 'sig_test'`}, @@ -388,8 +438,18 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { {name: "retention override", query: `SELECT count(*) FROM retention_overrides WHERE tenant_id = 'ten_test' AND id = 'ret_test'`}, {name: "questionnaire template", query: `SELECT count(*) FROM questionnaire_templates WHERE tenant_id = 'ten_test' AND id = 'qt_test'`}, {name: "questionnaire package", query: `SELECT count(*) FROM questionnaire_packages WHERE tenant_id = 'ten_test' AND id = 'qp_test'`}, + {name: "commercial collector", query: `SELECT count(*) FROM commercial_collectors WHERE tenant_id = 'ten_test' AND id = 'commercial_collector_test' AND allowed_scopes = ARRAY['evidence:write']`}, + {name: "evidence summary", query: `SELECT count(*) FROM evidence_summaries WHERE tenant_id = 'ten_test' AND id = 'summary_test' AND citations <> '[]'::jsonb`}, + {name: "questionnaire draft", query: `SELECT count(*) FROM questionnaire_drafts WHERE tenant_id = 'ten_test' AND id = 'draft_test' AND responses <> '[]'::jsonb`}, + {name: "graph snapshot", query: `SELECT count(*) FROM evidence_graph_snapshots WHERE tenant_id = 'ten_test' AND id = 'graph_test' AND nodes <> '[]'::jsonb`}, + {name: "saas profile", query: `SELECT count(*) FROM saas_edition_profiles WHERE tenant_id = 'ten_test' AND id = 'saas_test' AND status = 'draft'`}, + {name: "public transparency log", query: `SELECT count(*) FROM public_transparency_logs WHERE tenant_id = 'ten_test' AND id = 'public_log_test' AND state = 'active'`}, + {name: "public transparency entry", query: `SELECT count(*) FROM public_transparency_log_entries WHERE tenant_id = 'ten_test' AND id = 'public_entry_test' AND inclusion_verified_at IS NOT NULL AND verification_checks <> '[]'::jsonb`}, + {name: "marketplace collector", query: `SELECT count(*) FROM marketplace_collectors WHERE tenant_id = 'ten_test' AND id = 'market_collector_test' AND state = 'published'`}, {name: "pdf report", query: `SELECT count(*) FROM pdf_report_packages WHERE tenant_id = 'ten_test' AND id = 'pdf_test'`}, {name: "anomaly report", query: `SELECT count(*) FROM anomaly_reports WHERE tenant_id = 'ten_test' AND id = 'anom_test'`}, + {name: "provider verification", query: `SELECT count(*) FROM provider_verifications WHERE tenant_id = 'ten_test' AND id = 'provider_verification_test' AND checks <> '[]'::jsonb`}, + {name: "signing operation", query: `SELECT count(*) FROM signing_operations WHERE tenant_id = 'ten_test' AND id = 'signing_operation_test' AND signature_ref = 'sig_test'`}, } for _, check := range coreChecks { var rows int @@ -425,6 +485,9 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { if relational.Collectors["collector_test"].APIKeyID != "key_test" || relational.BuildRuns["build_test"].Status != "passed" || len(relational.BuildAttestations["att_test"].SubjectDigests) != 1 { t.Fatalf("relational build rows missing: collector=%#v build=%#v attestation=%#v", relational.Collectors["collector_test"], relational.BuildRuns["build_test"], relational.BuildAttestations["att_test"]) } + if !relational.CollectorReleases["collector_release_test"].Pinned || relational.CollectorReleases["collector_release_test"].HealthStatus != "healthy" { + t.Fatalf("relational collector release missing: release=%#v", relational.CollectorReleases["collector_release_test"]) + } if relational.EvidenceLifecycle["life_test"].Details["field"] != "metadata" || len(relational.ReleaseCandidates["rc_test"].BuildIDs) != 1 { t.Fatalf("relational lifecycle/candidate rows missing: lifecycle=%#v candidate=%#v", relational.EvidenceLifecycle["life_test"], relational.ReleaseCandidates["rc_test"]) } @@ -461,6 +524,12 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { if !relational.Waivers["waiver_test"].Approved || relational.Approvals["approval_test"].EvidenceID != "ev_test" || relational.DSSETrustRoots["dsse_root_test"].Status != "active" { t.Fatalf("relational governance/trust rows missing: waiver=%#v approval=%#v trust=%#v", relational.Waivers["waiver_test"], relational.Approvals["approval_test"], relational.DSSETrustRoots["dsse_root_test"]) } + if len(relational.CosignVerifications["cosign_test"].Checks) != 1 || !relational.SigningProviders["sign_provider_test"].Encrypted { + t.Fatalf("relational signing provider rows missing: cosign=%#v provider=%#v", relational.CosignVerifications["cosign_test"], relational.SigningProviders["sign_provider_test"]) + } + if relational.MerkleBatches["merkle_test"].RootHash == "" || relational.TransparencyCheckpoints["transparency_test"].ExternalID != "ts-1" { + t.Fatalf("relational integrity checkpoint rows missing: batch=%#v checkpoint=%#v", relational.MerkleBatches["merkle_test"], relational.TransparencyCheckpoints["transparency_test"]) + } if relational.Products["prod_test"].Slug != "product" || relational.Evidence["ev_test"].ReleaseID != "rel_test" || relational.SBOMs["sbom_test"].ComponentCount != 1 { t.Fatalf("relational fallback missing core rows: product=%#v evidence=%#v sbom=%#v", relational.Products["prod_test"], relational.Evidence["ev_test"], relational.SBOMs["sbom_test"]) } @@ -503,6 +572,24 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { if len(relational.QuestionnaireTemplates["qt_test"].Questions) != 1 || len(relational.QuestionnairePackages["qp_test"].Responses) != 1 { t.Fatalf("relational questionnaire rows missing: template=%#v package=%#v", relational.QuestionnaireTemplates["qt_test"], relational.QuestionnairePackages["qp_test"]) } + if relational.CommercialCollectors["commercial_collector_test"].Status != "active" || len(relational.EvidenceSummaries["summary_test"].Citations) != 1 { + t.Fatalf("relational commercial/summary rows missing: collector=%#v summary=%#v", relational.CommercialCollectors["commercial_collector_test"], relational.EvidenceSummaries["summary_test"]) + } + if len(relational.QuestionnaireDrafts["draft_test"].Responses) != 1 || len(relational.GraphSnapshots["graph_test"].Nodes) != 1 { + t.Fatalf("relational draft/graph rows missing: draft=%#v graph=%#v", relational.QuestionnaireDrafts["draft_test"], relational.GraphSnapshots["graph_test"]) + } + if relational.SaaSProfiles["saas_test"].Status != "draft" || relational.PublicTransparencyLogs["public_log_test"].State != "active" { + t.Fatalf("relational saas/public log rows missing: saas=%#v log=%#v", relational.SaaSProfiles["saas_test"], relational.PublicTransparencyLogs["public_log_test"]) + } + if relational.PublicTransparencyItems["public_entry_test"].InclusionVerifiedAt == nil || len(relational.PublicTransparencyItems["public_entry_test"].VerificationChecks) != 1 { + t.Fatalf("relational public transparency entry missing: entry=%#v", relational.PublicTransparencyItems["public_entry_test"]) + } + if relational.MarketplaceCollectors["market_collector_test"].State != "published" || relational.ProviderVerifications["provider_verification_test"].Result != "verified" { + t.Fatalf("relational marketplace/provider rows missing: market=%#v provider=%#v", relational.MarketplaceCollectors["market_collector_test"], relational.ProviderVerifications["provider_verification_test"]) + } + if relational.SigningOperations["signing_operation_test"].SignatureRef != "sig_test" || len(relational.SigningOperations["signing_operation_test"].Checks) != 1 { + t.Fatalf("relational signing operation missing: operation=%#v", relational.SigningOperations["signing_operation_test"]) + } if relational.PDFReports["pdf_test"].PayloadHash == "" || relational.AnomalyReports["anom_test"].Result != "review" { t.Fatalf("relational generated report rows missing: pdf=%#v anomaly=%#v", relational.PDFReports["pdf_test"], relational.AnomalyReports["anom_test"]) } diff --git a/migrations/20260528001600_remaining_relational_recovery_columns.down.sql b/migrations/20260528001600_remaining_relational_recovery_columns.down.sql new file mode 100644 index 0000000..2d5520e --- /dev/null +++ b/migrations/20260528001600_remaining_relational_recovery_columns.down.sql @@ -0,0 +1,6 @@ +ALTER TABLE public_transparency_log_entries + DROP COLUMN IF EXISTS verification_limitations, + DROP COLUMN IF EXISTS verification_checks, + DROP COLUMN IF EXISTS inclusion_verified_at, + DROP COLUMN IF EXISTS inclusion_proof_hash, + DROP COLUMN IF EXISTS inclusion_root_hash; diff --git a/migrations/20260528001600_remaining_relational_recovery_columns.up.sql b/migrations/20260528001600_remaining_relational_recovery_columns.up.sql new file mode 100644 index 0000000..dcc161f --- /dev/null +++ b/migrations/20260528001600_remaining_relational_recovery_columns.up.sql @@ -0,0 +1,6 @@ +ALTER TABLE public_transparency_log_entries + ADD COLUMN IF NOT EXISTS inclusion_root_hash text, + ADD COLUMN IF NOT EXISTS inclusion_proof_hash text, + ADD COLUMN IF NOT EXISTS inclusion_verified_at timestamptz, + ADD COLUMN IF NOT EXISTS verification_checks jsonb NOT NULL DEFAULT '[]'::jsonb, + ADD COLUMN IF NOT EXISTS verification_limitations text[] NOT NULL DEFAULT '{}'; From a656e0df6a74fdfe583a6f99289a4f1eb6099762 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 20:59:44 +0300 Subject: [PATCH 097/287] docs: align production readiness status --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8af9e32..2f5ca75 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ This repository contains a Go implementation under module `github.com/aatuh/evyd - AGPL license, commercial licensing, governance, contribution, security, support, trademark, release-evidence, and changelog metadata. -Implemented-but-partial areas are documented explicitly: signing-provider operation receipts do not replace production KMS/HSM adapters, local OIDC/SAML verification does not replace live provider discovery/API validation or browser login callbacks, and public transparency records require operator-supplied inclusion proof material before Evydence can verify local inclusion receipts. +Implemented-but-partial areas are documented explicitly: signing-provider operation receipts do not replace direct production KMS/HSM SDK adapters, local OIDC/SAML verification does not replace live provider discovery/API validation or browser login callbacks, and public transparency records verify operator-supplied inclusion proof material without fetching live provider proofs. ## License, Security, Support, And Governance @@ -107,4 +107,4 @@ make postgres-integration-test `make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. -`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required production-readiness evidence, but it does not by itself close the remaining relational persistence, worker side-effect, SDK, backup/restore, KMS/HSM, SSO, live provider-fetching, object-lock, and exit-review work. +`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required production-readiness evidence, but it does not by itself close the remaining repository-split, worker side-effect, direct KMS/HSM SDK, browser SSO, live provider-fetching, object-lock enforcement, and exit-review work. From b38ba20f2bc7f81557131be2f8d61aa9bbdd12bd Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 21:00:46 +0300 Subject: [PATCH 098/287] feat: prefer relational postgres loads in production --- .api.env.example | 2 + README.md | 2 +- cmd/evydence-api/main.go | 10 ++-- cmd/evydence-api/main_test.go | 20 +++++++ cmd/evydence-worker/main.go | 11 ++-- docs/architecture.md | 2 +- docs/reference/configuration.md | 9 ++++ docs/reference/production-readiness.md | 10 ++-- internal/adapters/postgres/store.go | 67 ++++++++++++++++++++++-- internal/adapters/postgres/store_test.go | 53 +++++++++++++++++++ 10 files changed, 172 insertions(+), 14 deletions(-) diff --git a/.api.env.example b/.api.env.example index 10cb7d6..5c78b5a 100644 --- a/.api.env.example +++ b/.api.env.example @@ -1,6 +1,8 @@ EVYDENCE_ADDR=:8080 EVYDENCE_API_KEY_PEPPER=change-me-long-random-pepper EVYDENCE_DATABASE_URL=postgres://evydence:change-me@localhost:5432/evydence?sslmode=disable +# Local default is snapshot_preferred. Production defaults to relational_preferred when unset. +# EVYDENCE_POSTGRES_LOAD_MODE=relational_preferred EVYDENCE_OBJECT_STORE=filesystem EVYDENCE_OBJECT_DIR=./tmp/objects EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE=0 diff --git a/README.md b/README.md index 2f5ca75..a070e27 100644 --- a/README.md +++ b/README.md @@ -107,4 +107,4 @@ make postgres-integration-test `make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. -`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required production-readiness evidence, but it does not by itself close the remaining repository-split, worker side-effect, direct KMS/HSM SDK, browser SSO, live provider-fetching, object-lock enforcement, and exit-review work. +`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required production-readiness evidence, but it does not by itself close the remaining repository-split, worker side-effect, direct KMS/HSM SDK, browser SSO, live provider-fetching, object-lock enforcement, and exit-review work. Production API and worker processes default to relational-preferred PostgreSQL loads; the compatibility snapshot remains for migration, recovery, and local workflows. diff --git a/cmd/evydence-api/main.go b/cmd/evydence-api/main.go index 036f392..4b1d222 100644 --- a/cmd/evydence-api/main.go +++ b/cmd/evydence-api/main.go @@ -44,7 +44,11 @@ func run() error { if databaseURL != "" { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - pgStore, err := postgres.Open(ctx, databaseURL) + loadMode, err := postgres.ResolveLoadMode(os.Getenv("EVYDENCE_POSTGRES_LOAD_MODE"), production) + if err != nil { + return err + } + pgStore, err := postgres.OpenWithOptions(ctx, databaseURL, postgres.StoreOptions{LoadMode: loadMode}) if err != nil { return err } @@ -59,7 +63,7 @@ func run() error { closeStore() return fmt.Errorf("check migrations: %w", err) } - objectStore, objectDescription, err := openObjectStore(ctx) + objectStore, _, err := openObjectStore(ctx) if err != nil { closeStore() return err @@ -67,7 +71,7 @@ func run() error { cfg.Store = pgStore cfg.Outbox = pgStore cfg.ObjectStore = objectStore - log.Printf("evydence api using postgres state store and %s object store", objectDescription) + log.Print("evydence api using postgres state store and configured object store") } if closeStore != nil { defer closeStore() diff --git a/cmd/evydence-api/main_test.go b/cmd/evydence-api/main_test.go index abb3b3b..72ee925 100644 --- a/cmd/evydence-api/main_test.go +++ b/cmd/evydence-api/main_test.go @@ -3,6 +3,8 @@ package main import ( "strings" "testing" + + "github.com/aatuh/evydence/internal/adapters/postgres" ) func TestValidateRuntimeConfigRejectsProductionBootstrapSecretPrinting(t *testing.T) { @@ -44,6 +46,24 @@ func TestValidateRuntimeConfigRejectsProductionDefaults(t *testing.T) { } } +func TestPostgresLoadModeDefaultsToRelationalPreferredInProduction(t *testing.T) { + mode, err := postgres.ResolveLoadMode("", true) + if err != nil { + t.Fatalf("resolve production load mode: %v", err) + } + if mode != postgres.LoadModeRelationalPreferred { + t.Fatalf("production load mode = %q, want %q", mode, postgres.LoadModeRelationalPreferred) + } + + mode, err = postgres.ResolveLoadMode("", false) + if err != nil { + t.Fatalf("resolve local load mode: %v", err) + } + if mode != postgres.LoadModeSnapshotPreferred { + t.Fatalf("local load mode = %q, want %q", mode, postgres.LoadModeSnapshotPreferred) + } +} + func TestEnvDefaultAndObjectStoreSelection(t *testing.T) { t.Setenv("EVYDENCE_TEST_VALUE", " configured ") if got := envDefault("EVYDENCE_TEST_VALUE", "fallback"); got != "configured" { diff --git a/cmd/evydence-worker/main.go b/cmd/evydence-worker/main.go index 5c50d3e..0aa060b 100644 --- a/cmd/evydence-worker/main.go +++ b/cmd/evydence-worker/main.go @@ -36,12 +36,17 @@ func main() { } func run() error { + production := strings.EqualFold(os.Getenv("ENV"), "production") databaseURL := strings.TrimSpace(os.Getenv("EVYDENCE_DATABASE_URL")) if databaseURL == "" { return errors.New("worker requires EVYDENCE_DATABASE_URL") } ctx := context.Background() - store, err := postgres.Open(ctx, databaseURL) + loadMode, err := postgres.ResolveLoadMode(os.Getenv("EVYDENCE_POSTGRES_LOAD_MODE"), production) + if err != nil { + return err + } + store, err := postgres.OpenWithOptions(ctx, databaseURL, postgres.StoreOptions{LoadMode: loadMode}) if err != nil { return err } @@ -58,13 +63,13 @@ func run() error { return fmt.Errorf("check migrations: %w", err) } cancel() - objectStore, objectDescription, err := openObjectStore(ctx) + objectStore, _, err := openObjectStore(ctx) if err != nil { return err } pollInterval := durationEnv("EVYDENCE_WORKER_POLL_INTERVAL", time.Second) batchSize := intEnv("EVYDENCE_WORKER_BATCH_SIZE", 10) - log.Printf("evydence worker started with postgres outbox, %s object store, polling interval %s", objectDescription, pollInterval) + log.Printf("evydence worker started with postgres outbox, configured object store, polling interval %s", pollInterval) for { if err := ctx.Err(); err != nil { return err diff --git a/docs/architecture.md b/docs/architecture.md index b3bc0bd..71baa83 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -10,7 +10,7 @@ Evydence follows a ports-and-adapters shape: - `internal/adapters/objectstore/s3` stores the same tenant-prefixed object keys in S3/MinIO-compatible buckets. - `cmd/*` contains process entry points. -Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity, idempotency, and customer portal token records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. Collector/build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension records are synchronized into their migration-backed relational tables. If the snapshot row is absent, the Postgres store can rebuild identity, SSO session, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. +Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity, idempotency, and customer portal token records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. Collector/build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension records are synchronized into their migration-backed relational tables. Production API and worker startup defaults to relational-preferred reconstruction; local development defaults to snapshot-preferred compatibility. If the snapshot row is absent, the Postgres store can rebuild identity, SSO session, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. ## Tenant And Auth Boundaries diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index bfe05aa..25738b3 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -27,6 +27,7 @@ The example secrets are placeholders. Replace them before using shared or produc | `EVYDENCE_ADDR` | No | `:8080` | API bind address. | | `EVYDENCE_API_KEY_PEPPER` | Production yes | `change-me-long-random-pepper` | HMAC pepper for API key, session, and portal-token hashes. Use a long random value. | | `EVYDENCE_DATABASE_URL` | Production yes | `postgres://evydence:change-me@localhost:5432/evydence?sslmode=disable` | Enables PostgreSQL durable state, projections, migrations, and persisted outbox jobs. If unset, the API uses in-process state. | +| `EVYDENCE_POSTGRES_LOAD_MODE` | No | `snapshot_preferred` locally, `relational_preferred` when `ENV=production` | PostgreSQL state load mode. Supported values are `snapshot_preferred`, `relational_preferred`, and `relational_only`. Production defaults to relational-preferred startup reads while snapshots remain available for compatibility. | | `EVYDENCE_OBJECT_STORE` | No | `filesystem` | Supported values are `filesystem`, `s3`, and `minio`. | | `EVYDENCE_OBJECT_DIR` | Filesystem object store | `./tmp/objects` | Local raw payload storage root. | | `EVYDENCE_S3_ENDPOINT` | S3/MinIO object store | `localhost:9000` | Endpoint for S3-compatible object storage. | @@ -62,6 +63,14 @@ When `ENV=production`, the API refuses to start unless: These checks reduce unsafe runtime defaults. They do not replace secret management, network controls, backup validation, or external signing operations. +When `ENV=production` and `EVYDENCE_POSTGRES_LOAD_MODE` is unset, API and worker +processes prefer reconstructing state from tenant-scoped relational rows before +falling back to the compatibility snapshot. Local development keeps +`snapshot_preferred` by default to preserve existing workflows. Use +`relational_only` only for controlled migration or recovery checks where a +missing relational row should fail closed instead of falling back to the +snapshot. + ## S3/MinIO Object-Retention Verification When `EVYDENCE_OBJECT_STORE=s3` or `minio`, object-retention policy verification diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index e01298b..2a8c129 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -23,8 +23,11 @@ Known hardening work remains: batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, audit-chain, signing, bundle, policy, verification, package, report, retention, provider verification, signing - operation, and future-extension rows alongside the canonical snapshot, but the snapshot remains the - preferred runtime load source. If the snapshot row is absent, the store can + operation, and future-extension rows alongside the compatibility snapshot. + When `ENV=production` and `EVYDENCE_POSTGRES_LOAD_MODE` is unset, API and + worker startup prefer relational reconstruction before falling back to the + snapshot. Local development still defaults to snapshot-preferred loading. If + the snapshot row is absent, the store can rebuild identity, SSO session, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE @@ -117,7 +120,8 @@ implemented capabilities: transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, audit-chain, signing, bundle, policy, verification, package, report, retention, provider verification, signing operation, and - future-extension rows are synchronized into relational tables. Missing-snapshot + future-extension rows are synchronized into relational tables. Production + startup defaults to relational-preferred loading, and missing-snapshot recovery can rebuild identity, SSO session, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index 2de6cef..0e8f409 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "strings" "time" "github.com/jackc/pgx/v5" @@ -16,7 +17,20 @@ import ( ) type Store struct { - pool *pgxpool.Pool + pool *pgxpool.Pool + loadMode LoadMode +} + +type LoadMode string + +const ( + LoadModeSnapshotPreferred LoadMode = "snapshot_preferred" + LoadModeRelationalPreferred LoadMode = "relational_preferred" + LoadModeRelationalOnly LoadMode = "relational_only" +) + +type StoreOptions struct { + LoadMode LoadMode } type ClaimedJob struct { @@ -30,6 +44,14 @@ type ClaimedJob struct { } func Open(ctx context.Context, databaseURL string) (*Store, error) { + return OpenWithOptions(ctx, databaseURL, StoreOptions{}) +} + +func OpenWithOptions(ctx context.Context, databaseURL string, opts StoreOptions) (*Store, error) { + loadMode, err := normalizeLoadMode(opts.LoadMode) + if err != nil { + return nil, err + } pool, err := pgxpool.New(ctx, databaseURL) if err != nil { return nil, fmt.Errorf("open postgres pool: %w", err) @@ -38,7 +60,7 @@ func Open(ctx context.Context, databaseURL string) (*Store, error) { pool.Close() return nil, fmt.Errorf("ping postgres: %w", err) } - return &Store{pool: pool}, nil + return &Store{pool: pool, loadMode: loadMode}, nil } func (s *Store) Close() { @@ -48,10 +70,49 @@ func (s *Store) Close() { } func (s *Store) LoadState(ctx context.Context) (app.PersistedState, bool, error) { + switch s.loadMode { + case LoadModeRelationalPreferred: + state, ok, err := s.loadRelationalState(ctx) + if err != nil || ok { + return state, ok, err + } + return s.loadSnapshotState(ctx) + case LoadModeRelationalOnly: + return s.loadRelationalState(ctx) + default: + state, ok, err := s.loadSnapshotState(ctx) + if err != nil || ok { + return state, ok, err + } + return s.loadRelationalState(ctx) + } +} + +func ResolveLoadMode(raw string, production bool) (LoadMode, error) { + if strings.TrimSpace(raw) == "" && production { + return LoadModeRelationalPreferred, nil + } + return normalizeLoadMode(LoadMode(raw)) +} + +func normalizeLoadMode(mode LoadMode) (LoadMode, error) { + switch strings.ToLower(strings.TrimSpace(string(mode))) { + case "", "snapshot", "snapshot_preferred", "snapshot-preferred": + return LoadModeSnapshotPreferred, nil + case "relational", "relational_preferred", "relational-preferred": + return LoadModeRelationalPreferred, nil + case "relational_only", "relational-only": + return LoadModeRelationalOnly, nil + default: + return "", fmt.Errorf("unsupported postgres load mode %q", mode) + } +} + +func (s *Store) loadSnapshotState(ctx context.Context) (app.PersistedState, bool, error) { var body []byte err := s.pool.QueryRow(ctx, `SELECT state FROM ledger_state WHERE id = 'default'`).Scan(&body) if errors.Is(err, pgx.ErrNoRows) { - return s.loadRelationalState(ctx) + return app.PersistedState{}, false, nil } if err != nil { return app.PersistedState{}, false, fmt.Errorf("load ledger state: %w", err) diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index d351983..5439a48 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -14,6 +14,40 @@ import ( "github.com/aatuh/evydence/internal/domain" ) +func TestResolveLoadMode(t *testing.T) { + tests := []struct { + name string + raw string + production bool + want LoadMode + wantErr bool + }{ + {name: "local default", want: LoadModeSnapshotPreferred}, + {name: "production default", production: true, want: LoadModeRelationalPreferred}, + {name: "snapshot alias", raw: "snapshot", production: true, want: LoadModeSnapshotPreferred}, + {name: "relational alias", raw: "relational", want: LoadModeRelationalPreferred}, + {name: "relational only", raw: "relational-only", want: LoadModeRelationalOnly}, + {name: "invalid", raw: "unsafe", wantErr: true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := ResolveLoadMode(tt.raw, tt.production) + if tt.wantErr { + if err == nil { + t.Fatal("expected error") + } + return + } + if err != nil { + t.Fatalf("ResolveLoadMode: %v", err) + } + if got != tt.want { + t.Fatalf("mode = %q, want %q", got, tt.want) + } + }) + } +} + func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { databaseURL := os.Getenv("EVYDENCE_TEST_DATABASE_URL") if databaseURL == "" { @@ -325,6 +359,25 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { if !ok || got.Tenants["ten_test"].ID != "ten_test" { t.Fatalf("unexpected loaded state: ok=%v state=%#v", ok, got.Tenants) } + if _, err := store.pool.Exec(ctx, `UPDATE products SET name = $1 WHERE tenant_id = 'ten_test' AND id = 'prod_test'`, "Relational Product"); err != nil { + t.Fatal(err) + } + store.loadMode = LoadModeRelationalPreferred + relationalPreferred, ok, err := store.LoadState(ctx) + if err != nil || !ok { + t.Fatalf("load relational-preferred state ok=%v err=%v", ok, err) + } + if relationalPreferred.Products["prod_test"].Name != "Relational Product" { + t.Fatalf("relational-preferred product name = %q", relationalPreferred.Products["prod_test"].Name) + } + store.loadMode = LoadModeSnapshotPreferred + snapshotPreferred, ok, err := store.LoadState(ctx) + if err != nil || !ok { + t.Fatalf("load snapshot-preferred state ok=%v err=%v", ok, err) + } + if snapshotPreferred.Products["prod_test"].Name != "Product" { + t.Fatalf("snapshot-preferred product name = %q", snapshotPreferred.Products["prod_test"].Name) + } var indexed int if err := store.pool.QueryRow(ctx, `SELECT count(*) FROM resource_index WHERE tenant_id = 'ten_test' AND resource_type = 'tenant'`).Scan(&indexed); err != nil { t.Fatal(err) From 0c9cd2fafc7aa2f66bf25344d05c9a4619f04b57 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 21:09:30 +0300 Subject: [PATCH 099/287] feat: version outbox parser jobs --- cmd/evydence-worker/main.go | 26 ++++++++++++++++++ cmd/evydence-worker/main_test.go | 16 ++++++++++++ docs/reference/worker-outbox.md | 4 +++ internal/app/builds.go | 2 +- internal/app/ledger.go | 6 ++--- internal/app/ledger_test.go | 45 ++++++++++++++++++++++++++++++++ internal/app/parser_versions.go | 9 +++++++ internal/app/vex.go | 2 +- 8 files changed, 105 insertions(+), 5 deletions(-) create mode 100644 internal/app/parser_versions.go diff --git a/cmd/evydence-worker/main.go b/cmd/evydence-worker/main.go index 0aa060b..493acab 100644 --- a/cmd/evydence-worker/main.go +++ b/cmd/evydence-worker/main.go @@ -29,6 +29,14 @@ import ( const defaultMaxWorkerPayloadBytes = 20 << 20 +var expectedParserVersions = map[string]string{ + "parse_sbom": app.ParserVersionCycloneDXJSON, + "parse_vulnerability_scan": app.ParserVersionGenericVulnerabilityJSON, + "parse_openapi_contract": app.ParserVersionOpenAPIJSON, + "parse_vex": app.ParserVersionOpenVEXJSON, + "verify_attestation": app.ParserVersionDSSEInTotoJSON, +} + func main() { if err := run(); err != nil { log.Fatal(err) @@ -144,6 +152,9 @@ func processJobInternal(ctx context.Context, state jobStateLoader, objects jobOb if !ok { return errors.New("durable state is not initialized") } + if err := requireParserVersion(job); err != nil { + return err + } stateChanged := false switch job.Kind { case "parse_sbom": @@ -291,6 +302,21 @@ func processJobInternal(ctx context.Context, state jobStateLoader, objects jobOb return nil } +func requireParserVersion(job postgres.ClaimedJob) error { + expected, ok := expectedParserVersions[job.Kind] + if !ok { + return nil + } + got := payloadString(job, "parser_version") + if got == "" { + return nil + } + if got != expected { + return errors.New("unsupported outbox parser version") + } + return nil +} + func verifyJobObject(ctx context.Context, objects jobObjectGetter, job postgres.ClaimedJob) (app.Object, bool, error) { key := payloadObjectKey(job) if key == "" { diff --git a/cmd/evydence-worker/main_test.go b/cmd/evydence-worker/main_test.go index 636b613..af10dd9 100644 --- a/cmd/evydence-worker/main_test.go +++ b/cmd/evydence-worker/main_test.go @@ -121,6 +121,22 @@ func TestProcessJobWithObjectsRequiresWritableStateForParserSideEffects(t *testi } } +func TestProcessJobRejectsUnsupportedParserVersion(t *testing.T) { + job := postgres.ClaimedJob{ + TenantID: "ten_test", + Kind: "parse_sbom", + SubjectID: "sbom_test", + Payload: map[string]any{"parser_version": "cyclonedx-json.v0.0.1"}, + } + state := app.PersistedState{SBOMs: map[string]domain.SBOM{ + "sbom_test": {ID: "sbom_test", TenantID: "ten_test"}, + }} + err := processJob(context.Background(), fakeStateLoader{state: state, ok: true}, job) + if err == nil || !strings.Contains(err.Error(), "unsupported outbox parser version") { + t.Fatalf("err=%v", err) + } +} + func TestProcessJobWithObjectsVerifiesTenantPrefixedPayload(t *testing.T) { body := []byte(`{"bomFormat":"CycloneDX"}`) hash := digestBytes(body) diff --git a/docs/reference/worker-outbox.md b/docs/reference/worker-outbox.md index 77cf2ca..872217e 100644 --- a/docs/reference/worker-outbox.md +++ b/docs/reference/worker-outbox.md @@ -14,6 +14,10 @@ Configured job kinds: Current behavior is intentionally conservative. The API still records normalized parser, signing, and verification results before enqueueing jobs for the implemented upload paths. The worker independently replays tenant-prefixed payload objects when `payload_ref` is present, verifies object metadata and byte digests when `payload_hash` is present, parses SBOM, vulnerability-scan, OpenAPI, OpenVEX, and DSSE attestation payloads, and checks that replayed payload summaries match the expected durable state. Missing objects, wrong tenant prefixes, tenant mismatches, oversized payload objects, malformed replay payloads, durable-state mismatches, incomplete verification, missing signatures, hash mismatch, uninitialized storage, and unsupported job kinds fail the job safely. +Parser and attestation jobs include a deterministic `parser_version` payload +field for new uploads. Workers reject unsupported parser versions and accept +older jobs with no parser version for upgrade compatibility. + Parser replay currently validates durable side effects instead of being the only writer of normalized records. Moving parser side effects fully out of the request path remains production hardening work. Workers use the same object-store environment variables as the API. The default worker payload replay limit is 20 MiB and can be adjusted with `EVYDENCE_WORKER_MAX_PAYLOAD_BYTES`. diff --git a/internal/app/builds.go b/internal/app/builds.go index bc6229f..67b7577 100644 --- a/internal/app/builds.go +++ b/internal/app/builds.go @@ -445,7 +445,7 @@ func (l *Ledger) UploadBuildAttestation(ctx context.Context, actor domain.Actor, } l.attestations[attestation.ID] = attestation _, _ = l.appendChainLocked(actor.TenantID, "build_attestation.created", "build_attestation", attestation.ID, actorType(actor), actorID(actor), payloadHash, "") - if err := l.enqueue(ctx, actor.TenantID, "verify_attestation", "build_attestation", attestation.ID, map[string]any{"payload_ref": payloadRef, "payload_hash": payloadHash}); err != nil { + if err := l.enqueue(ctx, actor.TenantID, "verify_attestation", "build_attestation", attestation.ID, map[string]any{"payload_ref": payloadRef, "payload_hash": payloadHash, "parser_version": ParserVersionDSSEInTotoJSON}); err != nil { return domain.BuildAttestation{}, err } if err := l.persistLocked(ctx); err != nil { diff --git a/internal/app/ledger.go b/internal/app/ledger.go index 420c814..b9abe1c 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -972,7 +972,7 @@ func (l *Ledger) UploadSBOM(ctx context.Context, actor domain.Actor, releaseID, sbom := domain.SBOM{ID: newID("sbom"), TenantID: actor.TenantID, EvidenceID: item.ID, ReleaseID: releaseID, ArtifactID: artifactID, Format: "cyclonedx", SpecVersion: doc.SpecVersion, ComponentCount: len(components), Components: components, CreatedAt: l.now()} l.sboms[sbom.ID] = sbom _, _ = l.appendChainLocked(actor.TenantID, "sbom.parsed", "sbom", sbom.ID, "api_key", actor.KeyID, payloadHash, "") - if err := l.enqueue(ctx, actor.TenantID, "parse_sbom", "sbom", sbom.ID, map[string]any{"payload_ref": payloadRef, "payload_hash": payloadHash}); err != nil { + if err := l.enqueue(ctx, actor.TenantID, "parse_sbom", "sbom", sbom.ID, map[string]any{"payload_ref": payloadRef, "payload_hash": payloadHash, "parser_version": ParserVersionCycloneDXJSON}); err != nil { return domain.SBOM{}, err } if err := l.persistLocked(ctx); err != nil { @@ -1058,7 +1058,7 @@ func (l *Ledger) UploadVulnerabilityScan(ctx context.Context, actor domain.Actor scan := domain.VulnerabilityScan{ID: newID("scan"), TenantID: actor.TenantID, EvidenceID: item.ID, ReleaseID: doc.ReleaseID, Scanner: doc.Scanner, TargetRef: doc.TargetRef, Summary: summary, Findings: findings, CreatedAt: l.now()} l.scans[scan.ID] = scan _, _ = l.appendChainLocked(actor.TenantID, "vulnerability_scan.parsed", "vulnerability_scan", scan.ID, "api_key", actor.KeyID, payloadHash, "") - if err := l.enqueue(ctx, actor.TenantID, "parse_vulnerability_scan", "vulnerability_scan", scan.ID, map[string]any{"payload_ref": payloadRef, "payload_hash": payloadHash}); err != nil { + if err := l.enqueue(ctx, actor.TenantID, "parse_vulnerability_scan", "vulnerability_scan", scan.ID, map[string]any{"payload_ref": payloadRef, "payload_hash": payloadHash, "parser_version": ParserVersionGenericVulnerabilityJSON}); err != nil { return domain.VulnerabilityScan{}, err } if err := l.persistLocked(ctx); err != nil { @@ -1120,7 +1120,7 @@ func (l *Ledger) UploadOpenAPIContract(ctx context.Context, actor domain.Actor, contract := domain.OpenAPIContract{ID: newID("oas"), TenantID: actor.TenantID, ProductID: productID, ReleaseID: releaseID, Version: version, Hash: payloadHash, PathCount: len(doc.Paths.Map()), Operations: operations, EvidenceID: item.ID, CreatedAt: l.now()} l.contracts[contract.ID] = contract _, _ = l.appendChainLocked(actor.TenantID, "openapi_contract.parsed", "openapi_contract", contract.ID, "api_key", actor.KeyID, contract.Hash, "") - if err := l.enqueue(ctx, actor.TenantID, "parse_openapi_contract", "openapi_contract", contract.ID, map[string]any{"payload_ref": payloadRef, "payload_hash": payloadHash}); err != nil { + if err := l.enqueue(ctx, actor.TenantID, "parse_openapi_contract", "openapi_contract", contract.ID, map[string]any{"payload_ref": payloadRef, "payload_hash": payloadHash, "parser_version": ParserVersionOpenAPIJSON}); err != nil { return domain.OpenAPIContract{}, err } if err := l.persistLocked(ctx); err != nil { diff --git a/internal/app/ledger_test.go b/internal/app/ledger_test.go index 01f2b11..6676c6d 100644 --- a/internal/app/ledger_test.go +++ b/internal/app/ledger_test.go @@ -12,6 +12,15 @@ import ( "github.com/aatuh/evydence/internal/domain" ) +type recordingOutbox struct { + jobs []OutboxJob +} + +func (r *recordingOutbox) Enqueue(_ context.Context, job OutboxJob) error { + r.jobs = append(r.jobs, job) + return nil +} + func TestTenantScopedEvidenceAndAPIKeyAuth(t *testing.T) { ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) ctx := context.Background() @@ -91,6 +100,42 @@ func TestScopedAPIKeyCannotWriteEvidence(t *testing.T) { } } +func TestUploadSBOMEnqueuesParserVersion(t *testing.T) { + outbox := &recordingOutbox{} + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow, Outbox: outbox}) + ctx := context.Background() + _, _, secret, err := ledger.BootstrapTenant(ctx, "Tenant", "admin", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap: %v", err) + } + actor, err := ledger.Authenticate(ctx, secret) + if err != nil { + t.Fatalf("auth: %v", err) + } + product, err := ledger.CreateProduct(ctx, actor, "Payments API", "payments-parser-version") + if err != nil { + t.Fatalf("create product: %v", err) + } + release, err := ledger.CreateRelease(ctx, actor, product.ID, "1.0.0") + if err != nil { + t.Fatalf("create release: %v", err) + } + artifact, err := ledger.RegisterArtifact(ctx, actor, "api.tar.gz", "application/gzip", sampleDigest("api"), 42) + if err != nil { + t.Fatalf("artifact: %v", err) + } + if _, err := ledger.UploadSBOM(ctx, actor, release.ID, artifact.ID, []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","components":[{"name":"api"}]}`)); err != nil { + t.Fatalf("upload sbom: %v", err) + } + if len(outbox.jobs) != 1 { + t.Fatalf("outbox jobs = %d, want 1", len(outbox.jobs)) + } + job := outbox.jobs[0] + if job.Kind != "parse_sbom" || job.Payload["parser_version"] != ParserVersionCycloneDXJSON { + t.Fatalf("outbox job = %#v", job) + } +} + func TestIdempotencyReplayAndConflict(t *testing.T) { ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) ctx := context.Background() diff --git a/internal/app/parser_versions.go b/internal/app/parser_versions.go new file mode 100644 index 0000000..7a4bd21 --- /dev/null +++ b/internal/app/parser_versions.go @@ -0,0 +1,9 @@ +package app + +const ( + ParserVersionCycloneDXJSON = "cyclonedx-json.v1.0.0" + ParserVersionGenericVulnerabilityJSON = "generic-vulnerability-scan-json.v1.0.0" + ParserVersionOpenAPIJSON = "openapi-json.v1.0.0" + ParserVersionOpenVEXJSON = "openvex-json.v1.0.0" + ParserVersionDSSEInTotoJSON = "dsse-in-toto-json.v1.0.0" +) diff --git a/internal/app/vex.go b/internal/app/vex.go index 17911d1..18bde22 100644 --- a/internal/app/vex.go +++ b/internal/app/vex.go @@ -162,7 +162,7 @@ func (l *Ledger) UploadVEX(ctx context.Context, actor domain.Actor, releaseID, a } } _, _ = l.appendChainLocked(actor.TenantID, "vex.parsed", "vex_document", vex.ID, "api_key", actor.KeyID, payloadHash, "") - if err := l.enqueue(ctx, actor.TenantID, "parse_vex", "vex_document", vex.ID, map[string]any{"payload_ref": payloadRef, "payload_hash": payloadHash, "decisions_created": createdDecisions}); err != nil { + if err := l.enqueue(ctx, actor.TenantID, "parse_vex", "vex_document", vex.ID, map[string]any{"payload_ref": payloadRef, "payload_hash": payloadHash, "parser_version": ParserVersionOpenVEXJSON, "decisions_created": createdDecisions}); err != nil { return domain.VEXDocument{}, err } if err := l.persistLocked(ctx); err != nil { From d0ed7e77d0dcdfa2f63b0c37ac4184fa0d6f7c2d Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 21:23:17 +0300 Subject: [PATCH 100/287] fix: reject snapshot postgres loads in production --- cmd/evydence-api/main.go | 5 +++++ cmd/evydence-api/main_test.go | 4 ++++ cmd/evydence-worker/main.go | 5 +++++ docs/reference/configuration.md | 13 +++++++------ docs/reference/production-readiness.md | 4 ++-- internal/adapters/postgres/store.go | 7 +++++++ internal/adapters/postgres/store_test.go | 13 +++++++++++++ 7 files changed, 43 insertions(+), 8 deletions(-) diff --git a/cmd/evydence-api/main.go b/cmd/evydence-api/main.go index 4b1d222..cbda514 100644 --- a/cmd/evydence-api/main.go +++ b/cmd/evydence-api/main.go @@ -48,6 +48,11 @@ func run() error { if err != nil { return err } + if production { + if err := postgres.ValidateProductionLoadMode(loadMode); err != nil { + return err + } + } pgStore, err := postgres.OpenWithOptions(ctx, databaseURL, postgres.StoreOptions{LoadMode: loadMode}) if err != nil { return err diff --git a/cmd/evydence-api/main_test.go b/cmd/evydence-api/main_test.go index 72ee925..2a333e5 100644 --- a/cmd/evydence-api/main_test.go +++ b/cmd/evydence-api/main_test.go @@ -62,6 +62,10 @@ func TestPostgresLoadModeDefaultsToRelationalPreferredInProduction(t *testing.T) if mode != postgres.LoadModeSnapshotPreferred { t.Fatalf("local load mode = %q, want %q", mode, postgres.LoadModeSnapshotPreferred) } + + if err := postgres.ValidateProductionLoadMode(postgres.LoadModeSnapshotPreferred); err == nil || !strings.Contains(err.Error(), "EVYDENCE_POSTGRES_LOAD_MODE") { + t.Fatalf("snapshot-preferred production validation err=%v", err) + } } func TestEnvDefaultAndObjectStoreSelection(t *testing.T) { diff --git a/cmd/evydence-worker/main.go b/cmd/evydence-worker/main.go index 493acab..bcd080e 100644 --- a/cmd/evydence-worker/main.go +++ b/cmd/evydence-worker/main.go @@ -54,6 +54,11 @@ func run() error { if err != nil { return err } + if production { + if err := postgres.ValidateProductionLoadMode(loadMode); err != nil { + return err + } + } store, err := postgres.OpenWithOptions(ctx, databaseURL, postgres.StoreOptions{LoadMode: loadMode}) if err != nil { return err diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 25738b3..6bdc7ab 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -27,7 +27,7 @@ The example secrets are placeholders. Replace them before using shared or produc | `EVYDENCE_ADDR` | No | `:8080` | API bind address. | | `EVYDENCE_API_KEY_PEPPER` | Production yes | `change-me-long-random-pepper` | HMAC pepper for API key, session, and portal-token hashes. Use a long random value. | | `EVYDENCE_DATABASE_URL` | Production yes | `postgres://evydence:change-me@localhost:5432/evydence?sslmode=disable` | Enables PostgreSQL durable state, projections, migrations, and persisted outbox jobs. If unset, the API uses in-process state. | -| `EVYDENCE_POSTGRES_LOAD_MODE` | No | `snapshot_preferred` locally, `relational_preferred` when `ENV=production` | PostgreSQL state load mode. Supported values are `snapshot_preferred`, `relational_preferred`, and `relational_only`. Production defaults to relational-preferred startup reads while snapshots remain available for compatibility. | +| `EVYDENCE_POSTGRES_LOAD_MODE` | No | `snapshot_preferred` locally, `relational_preferred` when `ENV=production` | PostgreSQL state load mode. Supported values are `snapshot_preferred`, `relational_preferred`, and `relational_only`. Production defaults to relational-preferred startup reads and refuses `snapshot_preferred`; snapshots remain available for local compatibility and non-production migration checks. | | `EVYDENCE_OBJECT_STORE` | No | `filesystem` | Supported values are `filesystem`, `s3`, and `minio`. | | `EVYDENCE_OBJECT_DIR` | Filesystem object store | `./tmp/objects` | Local raw payload storage root. | | `EVYDENCE_S3_ENDPOINT` | S3/MinIO object store | `localhost:9000` | Endpoint for S3-compatible object storage. | @@ -60,16 +60,17 @@ When `ENV=production`, the API refuses to start unless: - `EVYDENCE_API_KEY_PEPPER` is non-empty and not the local default. - `EVYDENCE_SIGNING_KEY_MODE=external`. - `EVYDENCE_PRINT_BOOTSTRAP_SECRET` is not `true`. +- `EVYDENCE_POSTGRES_LOAD_MODE`, when set, is not `snapshot_preferred`. These checks reduce unsafe runtime defaults. They do not replace secret management, network controls, backup validation, or external signing operations. When `ENV=production` and `EVYDENCE_POSTGRES_LOAD_MODE` is unset, API and worker processes prefer reconstructing state from tenant-scoped relational rows before -falling back to the compatibility snapshot. Local development keeps -`snapshot_preferred` by default to preserve existing workflows. Use -`relational_only` only for controlled migration or recovery checks where a -missing relational row should fail closed instead of falling back to the -snapshot. +falling back to the compatibility snapshot. Production refuses +`snapshot_preferred`. Local development keeps `snapshot_preferred` by default to +preserve existing workflows. Use `relational_only` only for controlled migration +or recovery checks where a missing relational row should fail closed instead of +falling back to the snapshot. ## S3/MinIO Object-Retention Verification diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 2a8c129..46990a3 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -26,8 +26,8 @@ Known hardening work remains: operation, and future-extension rows alongside the compatibility snapshot. When `ENV=production` and `EVYDENCE_POSTGRES_LOAD_MODE` is unset, API and worker startup prefer relational reconstruction before falling back to the - snapshot. Local development still defaults to snapshot-preferred loading. If - the snapshot row is absent, the store can + snapshot. Production refuses `snapshot_preferred`; local development still + defaults to snapshot-preferred loading. If the snapshot row is absent, the store can rebuild identity, SSO session, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index 0e8f409..d394d2a 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -95,6 +95,13 @@ func ResolveLoadMode(raw string, production bool) (LoadMode, error) { return normalizeLoadMode(LoadMode(raw)) } +func ValidateProductionLoadMode(mode LoadMode) error { + if mode == LoadModeSnapshotPreferred { + return errors.New("production refuses EVYDENCE_POSTGRES_LOAD_MODE=snapshot_preferred") + } + return nil +} + func normalizeLoadMode(mode LoadMode) (LoadMode, error) { switch strings.ToLower(strings.TrimSpace(string(mode))) { case "", "snapshot", "snapshot_preferred", "snapshot-preferred": diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index 5439a48..4d44996 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -48,6 +48,19 @@ func TestResolveLoadMode(t *testing.T) { } } +func TestValidateProductionLoadModeRejectsSnapshotPreferred(t *testing.T) { + if err := ValidateProductionLoadMode(LoadModeRelationalPreferred); err != nil { + t.Fatalf("relational-preferred production mode: %v", err) + } + if err := ValidateProductionLoadMode(LoadModeRelationalOnly); err != nil { + t.Fatalf("relational-only production mode: %v", err) + } + err := ValidateProductionLoadMode(LoadModeSnapshotPreferred) + if err == nil || !strings.Contains(err.Error(), "EVYDENCE_POSTGRES_LOAD_MODE") { + t.Fatalf("snapshot-preferred production err=%v", err) + } +} + func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { databaseURL := os.Getenv("EVYDENCE_TEST_DATABASE_URL") if databaseURL == "" { From 895cc557b894e5d929886f1040ec5c977a5200b7 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 21:23:33 +0300 Subject: [PATCH 101/287] feat: disable production snapshot writes --- README.md | 2 +- cmd/evydence-api/main.go | 2 +- cmd/evydence-worker/main.go | 2 +- docs/architecture.md | 2 +- docs/reference/configuration.md | 13 +++--- docs/reference/production-readiness.md | 7 +-- internal/adapters/postgres/store.go | 34 +++++++------- internal/adapters/postgres/store_test.go | 56 ++++++++++++++++++++++++ 8 files changed, 90 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index a070e27..b6d2911 100644 --- a/README.md +++ b/README.md @@ -107,4 +107,4 @@ make postgres-integration-test `make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. -`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required production-readiness evidence, but it does not by itself close the remaining repository-split, worker side-effect, direct KMS/HSM SDK, browser SSO, live provider-fetching, object-lock enforcement, and exit-review work. Production API and worker processes default to relational-preferred PostgreSQL loads; the compatibility snapshot remains for migration, recovery, and local workflows. +`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required production-readiness evidence, but it does not by itself close the remaining repository-split, worker side-effect, direct KMS/HSM SDK, browser SSO, live provider-fetching, object-lock enforcement, and exit-review work. Production API and worker processes default to relational-preferred PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. diff --git a/cmd/evydence-api/main.go b/cmd/evydence-api/main.go index cbda514..d37187a 100644 --- a/cmd/evydence-api/main.go +++ b/cmd/evydence-api/main.go @@ -53,7 +53,7 @@ func run() error { return err } } - pgStore, err := postgres.OpenWithOptions(ctx, databaseURL, postgres.StoreOptions{LoadMode: loadMode}) + pgStore, err := postgres.OpenWithOptions(ctx, databaseURL, postgres.StoreOptions{LoadMode: loadMode, DisableSnapshotWrites: production}) if err != nil { return err } diff --git a/cmd/evydence-worker/main.go b/cmd/evydence-worker/main.go index bcd080e..9be5979 100644 --- a/cmd/evydence-worker/main.go +++ b/cmd/evydence-worker/main.go @@ -59,7 +59,7 @@ func run() error { return err } } - store, err := postgres.OpenWithOptions(ctx, databaseURL, postgres.StoreOptions{LoadMode: loadMode}) + store, err := postgres.OpenWithOptions(ctx, databaseURL, postgres.StoreOptions{LoadMode: loadMode, DisableSnapshotWrites: production}) if err != nil { return err } diff --git a/docs/architecture.md b/docs/architecture.md index 71baa83..fe2e3af 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -10,7 +10,7 @@ Evydence follows a ports-and-adapters shape: - `internal/adapters/objectstore/s3` stores the same tenant-prefixed object keys in S3/MinIO-compatible buckets. - `cmd/*` contains process entry points. -Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity, idempotency, and customer portal token records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. Collector/build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension records are synchronized into their migration-backed relational tables. Production API and worker startup defaults to relational-preferred reconstruction; local development defaults to snapshot-preferred compatibility. If the snapshot row is absent, the Postgres store can rebuild identity, SSO session, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. +Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity, idempotency, and customer portal token records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. Collector/build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension records are synchronized into their migration-backed relational tables. Production API and worker startup defaults to relational-preferred reconstruction and disables compatibility snapshot writes; local development defaults to snapshot-preferred compatibility. If the snapshot row is absent, the Postgres store can rebuild identity, SSO session, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. ## Tenant And Auth Boundaries diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 6bdc7ab..05ac91d 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -27,7 +27,7 @@ The example secrets are placeholders. Replace them before using shared or produc | `EVYDENCE_ADDR` | No | `:8080` | API bind address. | | `EVYDENCE_API_KEY_PEPPER` | Production yes | `change-me-long-random-pepper` | HMAC pepper for API key, session, and portal-token hashes. Use a long random value. | | `EVYDENCE_DATABASE_URL` | Production yes | `postgres://evydence:change-me@localhost:5432/evydence?sslmode=disable` | Enables PostgreSQL durable state, projections, migrations, and persisted outbox jobs. If unset, the API uses in-process state. | -| `EVYDENCE_POSTGRES_LOAD_MODE` | No | `snapshot_preferred` locally, `relational_preferred` when `ENV=production` | PostgreSQL state load mode. Supported values are `snapshot_preferred`, `relational_preferred`, and `relational_only`. Production defaults to relational-preferred startup reads and refuses `snapshot_preferred`; snapshots remain available for local compatibility and non-production migration checks. | +| `EVYDENCE_POSTGRES_LOAD_MODE` | No | `snapshot_preferred` locally, `relational_preferred` when `ENV=production` | PostgreSQL state load mode. Supported values are `snapshot_preferred`, `relational_preferred`, and `relational_only`. Production defaults to relational-preferred startup reads, refuses `snapshot_preferred`, and disables compatibility snapshot writes; snapshots remain available for local compatibility and non-production migration checks. | | `EVYDENCE_OBJECT_STORE` | No | `filesystem` | Supported values are `filesystem`, `s3`, and `minio`. | | `EVYDENCE_OBJECT_DIR` | Filesystem object store | `./tmp/objects` | Local raw payload storage root. | | `EVYDENCE_S3_ENDPOINT` | S3/MinIO object store | `localhost:9000` | Endpoint for S3-compatible object storage. | @@ -66,11 +66,12 @@ These checks reduce unsafe runtime defaults. They do not replace secret manageme When `ENV=production` and `EVYDENCE_POSTGRES_LOAD_MODE` is unset, API and worker processes prefer reconstructing state from tenant-scoped relational rows before -falling back to the compatibility snapshot. Production refuses -`snapshot_preferred`. Local development keeps `snapshot_preferred` by default to -preserve existing workflows. Use `relational_only` only for controlled migration -or recovery checks where a missing relational row should fail closed instead of -falling back to the snapshot. +falling back to the compatibility snapshot and do not write new compatibility +snapshots. Production refuses `snapshot_preferred`. Local development keeps +`snapshot_preferred` and snapshot writes by default to preserve existing +workflows. Use `relational_only` only for controlled migration or recovery +checks where a missing relational row should fail closed instead of falling back +to the snapshot. ## S3/MinIO Object-Retention Verification diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 46990a3..ac5f73b 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -26,9 +26,10 @@ Known hardening work remains: operation, and future-extension rows alongside the compatibility snapshot. When `ENV=production` and `EVYDENCE_POSTGRES_LOAD_MODE` is unset, API and worker startup prefer relational reconstruction before falling back to the - snapshot. Production refuses `snapshot_preferred`; local development still - defaults to snapshot-preferred loading. If the snapshot row is absent, the store can - rebuild identity, SSO session, customer portal token, release-ledger core, + snapshot. Production refuses `snapshot_preferred` and disables compatibility + snapshot writes; local development still defaults to snapshot-preferred loading + and snapshot writes. If the snapshot row is absent, the store can rebuild + identity, SSO session, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index d394d2a..9d5a74d 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -17,8 +17,9 @@ import ( ) type Store struct { - pool *pgxpool.Pool - loadMode LoadMode + pool *pgxpool.Pool + loadMode LoadMode + disableSnapshotWrites bool } type LoadMode string @@ -30,7 +31,8 @@ const ( ) type StoreOptions struct { - LoadMode LoadMode + LoadMode LoadMode + DisableSnapshotWrites bool } type ClaimedJob struct { @@ -60,7 +62,7 @@ func OpenWithOptions(ctx context.Context, databaseURL string, opts StoreOptions) pool.Close() return nil, fmt.Errorf("ping postgres: %w", err) } - return &Store{pool: pool, loadMode: loadMode}, nil + return &Store{pool: pool, loadMode: loadMode, disableSnapshotWrites: opts.DisableSnapshotWrites}, nil } func (s *Store) Close() { @@ -2470,22 +2472,24 @@ func (s *Store) loadRelationalIdempotency(ctx context.Context, state *app.Persis } func (s *Store) SaveState(ctx context.Context, state app.PersistedState) error { - body, err := json.Marshal(state) - if err != nil { - return fmt.Errorf("encode ledger state: %w", err) - } tx, err := s.pool.BeginTx(ctx, pgx.TxOptions{}) if err != nil { return fmt.Errorf("begin save ledger state transaction: %w", err) } defer func() { _ = tx.Rollback(ctx) }() - _, err = tx.Exec(ctx, ` - INSERT INTO ledger_state (id, state, updated_at) - VALUES ('default', $1, now()) - ON CONFLICT (id) DO UPDATE SET state = EXCLUDED.state, updated_at = EXCLUDED.updated_at - `, body) - if err != nil { - return fmt.Errorf("save ledger state: %w", err) + if !s.disableSnapshotWrites { + body, err := json.Marshal(state) + if err != nil { + return fmt.Errorf("encode ledger state: %w", err) + } + _, err = tx.Exec(ctx, ` + INSERT INTO ledger_state (id, state, updated_at) + VALUES ('default', $1, now()) + ON CONFLICT (id) DO UPDATE SET state = EXCLUDED.state, updated_at = EXCLUDED.updated_at + `, body) + if err != nil { + return fmt.Errorf("save ledger state: %w", err) + } } if err := syncResourceIndex(ctx, tx, state); err != nil { return err diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index 4d44996..19c1b4c 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -61,6 +61,62 @@ func TestValidateProductionLoadModeRejectsSnapshotPreferred(t *testing.T) { } } +func TestStoreCanDisableSnapshotWritesAndLoadRelationalState(t *testing.T) { + databaseURL := os.Getenv("EVYDENCE_TEST_DATABASE_URL") + if databaseURL == "" { + t.Skip("EVYDENCE_TEST_DATABASE_URL is not set") + } + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + admin, err := Open(ctx, databaseURL) + if err != nil { + t.Fatal(err) + } + defer admin.Close() + schema := "evydence_snapshot_disabled_" + strings.ReplaceAll(strings.ToLower(time.Now().Format("20060102150405.000000000")), ".", "_") + quotedSchema := pgx.Identifier{schema}.Sanitize() + if _, err := admin.pool.Exec(ctx, "CREATE SCHEMA "+quotedSchema); err != nil { + t.Fatal(err) + } + defer func(cleanupCtx context.Context) { + _, _ = admin.pool.Exec(cleanupCtx, "DROP SCHEMA "+quotedSchema+" CASCADE") + }(context.WithoutCancel(ctx)) + + store, err := OpenWithOptions(ctx, databaseURLWithSearchPath(t, databaseURL, schema), StoreOptions{LoadMode: LoadModeRelationalPreferred, DisableSnapshotWrites: true}) + if err != nil { + t.Fatal(err) + } + defer store.Close() + if _, err := store.ApplyMigrations(ctx, "../../../migrations"); err != nil { + t.Fatal(err) + } + state := app.PersistedState{ + Tenants: map[string]domain.Tenant{ + "ten_snapshot_disabled": {ID: "ten_snapshot_disabled", Name: "No Snapshot", CreatedAt: time.Now().UTC()}, + }, + Products: map[string]domain.Product{ + "prod_snapshot_disabled": {ID: "prod_snapshot_disabled", TenantID: "ten_snapshot_disabled", Name: "Relational Product", Slug: "relational-product", CreatedAt: time.Now().UTC()}, + }, + } + if err := store.SaveState(ctx, state); err != nil { + t.Fatal(err) + } + var snapshotRows int + if err := store.pool.QueryRow(ctx, `SELECT count(*) FROM ledger_state`).Scan(&snapshotRows); err != nil { + t.Fatal(err) + } + if snapshotRows != 0 { + t.Fatalf("ledger_state rows = %d, want 0", snapshotRows) + } + loaded, ok, err := store.LoadState(ctx) + if err != nil || !ok { + t.Fatalf("load relational state ok=%v err=%v", ok, err) + } + if loaded.Products["prod_snapshot_disabled"].Name != "Relational Product" { + t.Fatalf("loaded products = %#v", loaded.Products) + } +} + func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { databaseURL := os.Getenv("EVYDENCE_TEST_DATABASE_URL") if databaseURL == "" { From 98cba52635a5c3213976eb2513a21ee5bc436b8e Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 21:25:11 +0300 Subject: [PATCH 102/287] docs: clarify remaining production hardening --- docs/reference/production-readiness.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index ac5f73b..09681d7 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -112,9 +112,9 @@ These items are tracked separately from the feature-completeness checklist in `.implementation_increments.md` because they are hardening work on already implemented capabilities: -- Replace canonical snapshot writes with dependency-ordered relational - repositories for remaining secondary resources. Identity, idempotency, - customer portal token, release-ledger core, build provenance, +- Continue replacing aggregate `SaveState` synchronization with + dependency-ordered relational repositories for focused resource families. + Identity, idempotency, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, @@ -122,17 +122,17 @@ implemented capabilities: decision, control, audit-chain, signing, bundle, policy, verification, package, report, retention, provider verification, signing operation, and future-extension rows are synchronized into relational tables. Production - startup defaults to relational-preferred loading, and missing-snapshot - recovery can rebuild identity, SSO session, customer portal token, + startup defaults to relational-preferred loading, production writes skip the + compatibility snapshot, and missing-snapshot recovery can rebuild identity, + SSO session, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension families from - relational rows. - Keep snapshots only for export/import and upgrade compatibility after the - remaining families have repository-backed reads and writes. + relational rows. Snapshots remain for local compatibility, export/import, and + non-production migration checks. - Split the large application ledger aggregate into focused services or repositories once relational writes are in place, preserving tenant isolation and append-only behavior throughout. From b77482ed0af61f737a234e523047656f30802f26 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 21:25:53 +0300 Subject: [PATCH 103/287] fix: require relational-only production loads --- .api.env.example | 4 ++-- README.md | 2 +- cmd/evydence-api/main_test.go | 10 +++++----- docs/architecture.md | 2 +- docs/reference/configuration.md | 17 ++++++++--------- docs/reference/production-readiness.md | 12 ++++++------ internal/adapters/postgres/store.go | 6 +++--- internal/adapters/postgres/store_test.go | 15 +++++++-------- 8 files changed, 33 insertions(+), 35 deletions(-) diff --git a/.api.env.example b/.api.env.example index 5c78b5a..9be6b5b 100644 --- a/.api.env.example +++ b/.api.env.example @@ -1,8 +1,8 @@ EVYDENCE_ADDR=:8080 EVYDENCE_API_KEY_PEPPER=change-me-long-random-pepper EVYDENCE_DATABASE_URL=postgres://evydence:change-me@localhost:5432/evydence?sslmode=disable -# Local default is snapshot_preferred. Production defaults to relational_preferred when unset. -# EVYDENCE_POSTGRES_LOAD_MODE=relational_preferred +# Local default is snapshot_preferred. Production defaults to relational_only when unset. +# EVYDENCE_POSTGRES_LOAD_MODE=relational_only EVYDENCE_OBJECT_STORE=filesystem EVYDENCE_OBJECT_DIR=./tmp/objects EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE=0 diff --git a/README.md b/README.md index b6d2911..cad9098 100644 --- a/README.md +++ b/README.md @@ -107,4 +107,4 @@ make postgres-integration-test `make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. -`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required production-readiness evidence, but it does not by itself close the remaining repository-split, worker side-effect, direct KMS/HSM SDK, browser SSO, live provider-fetching, object-lock enforcement, and exit-review work. Production API and worker processes default to relational-preferred PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. +`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required production-readiness evidence, but it does not by itself close the remaining repository-split, worker side-effect, direct KMS/HSM SDK, browser SSO, live provider-fetching, object-lock enforcement, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. diff --git a/cmd/evydence-api/main_test.go b/cmd/evydence-api/main_test.go index 2a333e5..9259829 100644 --- a/cmd/evydence-api/main_test.go +++ b/cmd/evydence-api/main_test.go @@ -46,13 +46,13 @@ func TestValidateRuntimeConfigRejectsProductionDefaults(t *testing.T) { } } -func TestPostgresLoadModeDefaultsToRelationalPreferredInProduction(t *testing.T) { +func TestPostgresLoadModeDefaultsToRelationalOnlyInProduction(t *testing.T) { mode, err := postgres.ResolveLoadMode("", true) if err != nil { t.Fatalf("resolve production load mode: %v", err) } - if mode != postgres.LoadModeRelationalPreferred { - t.Fatalf("production load mode = %q, want %q", mode, postgres.LoadModeRelationalPreferred) + if mode != postgres.LoadModeRelationalOnly { + t.Fatalf("production load mode = %q, want %q", mode, postgres.LoadModeRelationalOnly) } mode, err = postgres.ResolveLoadMode("", false) @@ -63,8 +63,8 @@ func TestPostgresLoadModeDefaultsToRelationalPreferredInProduction(t *testing.T) t.Fatalf("local load mode = %q, want %q", mode, postgres.LoadModeSnapshotPreferred) } - if err := postgres.ValidateProductionLoadMode(postgres.LoadModeSnapshotPreferred); err == nil || !strings.Contains(err.Error(), "EVYDENCE_POSTGRES_LOAD_MODE") { - t.Fatalf("snapshot-preferred production validation err=%v", err) + if err := postgres.ValidateProductionLoadMode(postgres.LoadModeRelationalPreferred); err == nil || !strings.Contains(err.Error(), "EVYDENCE_POSTGRES_LOAD_MODE") { + t.Fatalf("relational-preferred production validation err=%v", err) } } diff --git a/docs/architecture.md b/docs/architecture.md index fe2e3af..c67f647 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -10,7 +10,7 @@ Evydence follows a ports-and-adapters shape: - `internal/adapters/objectstore/s3` stores the same tenant-prefixed object keys in S3/MinIO-compatible buckets. - `cmd/*` contains process entry points. -Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity, idempotency, and customer portal token records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. Collector/build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension records are synchronized into their migration-backed relational tables. Production API and worker startup defaults to relational-preferred reconstruction and disables compatibility snapshot writes; local development defaults to snapshot-preferred compatibility. If the snapshot row is absent, the Postgres store can rebuild identity, SSO session, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. +Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity, idempotency, and customer portal token records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. Collector/build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension records are synchronized into their migration-backed relational tables. Production API and worker startup defaults to relational-only reconstruction and disables compatibility snapshot writes; local development defaults to snapshot-preferred compatibility. If the snapshot row is absent, the Postgres store can rebuild identity, SSO session, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. ## Tenant And Auth Boundaries diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 05ac91d..53acda7 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -27,7 +27,7 @@ The example secrets are placeholders. Replace them before using shared or produc | `EVYDENCE_ADDR` | No | `:8080` | API bind address. | | `EVYDENCE_API_KEY_PEPPER` | Production yes | `change-me-long-random-pepper` | HMAC pepper for API key, session, and portal-token hashes. Use a long random value. | | `EVYDENCE_DATABASE_URL` | Production yes | `postgres://evydence:change-me@localhost:5432/evydence?sslmode=disable` | Enables PostgreSQL durable state, projections, migrations, and persisted outbox jobs. If unset, the API uses in-process state. | -| `EVYDENCE_POSTGRES_LOAD_MODE` | No | `snapshot_preferred` locally, `relational_preferred` when `ENV=production` | PostgreSQL state load mode. Supported values are `snapshot_preferred`, `relational_preferred`, and `relational_only`. Production defaults to relational-preferred startup reads, refuses `snapshot_preferred`, and disables compatibility snapshot writes; snapshots remain available for local compatibility and non-production migration checks. | +| `EVYDENCE_POSTGRES_LOAD_MODE` | No | `snapshot_preferred` locally, `relational_only` when `ENV=production` | PostgreSQL state load mode. Supported values are `snapshot_preferred`, `relational_preferred`, and `relational_only`. Production defaults to relational-only startup reads, refuses snapshot fallback modes, and disables compatibility snapshot writes; snapshots remain available for local compatibility and non-production migration checks. | | `EVYDENCE_OBJECT_STORE` | No | `filesystem` | Supported values are `filesystem`, `s3`, and `minio`. | | `EVYDENCE_OBJECT_DIR` | Filesystem object store | `./tmp/objects` | Local raw payload storage root. | | `EVYDENCE_S3_ENDPOINT` | S3/MinIO object store | `localhost:9000` | Endpoint for S3-compatible object storage. | @@ -60,18 +60,17 @@ When `ENV=production`, the API refuses to start unless: - `EVYDENCE_API_KEY_PEPPER` is non-empty and not the local default. - `EVYDENCE_SIGNING_KEY_MODE=external`. - `EVYDENCE_PRINT_BOOTSTRAP_SECRET` is not `true`. -- `EVYDENCE_POSTGRES_LOAD_MODE`, when set, is not `snapshot_preferred`. +- `EVYDENCE_POSTGRES_LOAD_MODE`, when set, is `relational_only`. These checks reduce unsafe runtime defaults. They do not replace secret management, network controls, backup validation, or external signing operations. When `ENV=production` and `EVYDENCE_POSTGRES_LOAD_MODE` is unset, API and worker -processes prefer reconstructing state from tenant-scoped relational rows before -falling back to the compatibility snapshot and do not write new compatibility -snapshots. Production refuses `snapshot_preferred`. Local development keeps -`snapshot_preferred` and snapshot writes by default to preserve existing -workflows. Use `relational_only` only for controlled migration or recovery -checks where a missing relational row should fail closed instead of falling back -to the snapshot. +processes load only from tenant-scoped relational rows and do not write new +compatibility snapshots. Production refuses snapshot fallback modes. Local +development keeps `snapshot_preferred` and snapshot writes by default to +preserve existing workflows. Use `relational_preferred` only for controlled +non-production migration or recovery checks that intentionally fall back to the +snapshot. ## S3/MinIO Object-Retention Verification diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 09681d7..cc7ba7d 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -25,11 +25,11 @@ Known hardening work remains: verification, package, report, retention, provider verification, signing operation, and future-extension rows alongside the compatibility snapshot. When `ENV=production` and `EVYDENCE_POSTGRES_LOAD_MODE` is unset, API and - worker startup prefer relational reconstruction before falling back to the - snapshot. Production refuses `snapshot_preferred` and disables compatibility - snapshot writes; local development still defaults to snapshot-preferred loading - and snapshot writes. If the snapshot row is absent, the store can rebuild - identity, SSO session, customer portal token, release-ledger core, + worker startup load from relational reconstruction only. Production refuses + snapshot fallback modes and disables compatibility snapshot writes; local + development still defaults to snapshot-preferred loading and snapshot writes. + If the snapshot row is absent, the store can rebuild identity, SSO session, + customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle @@ -122,7 +122,7 @@ implemented capabilities: decision, control, audit-chain, signing, bundle, policy, verification, package, report, retention, provider verification, signing operation, and future-extension rows are synchronized into relational tables. Production - startup defaults to relational-preferred loading, production writes skip the + startup defaults to relational-only loading, production writes skip the compatibility snapshot, and missing-snapshot recovery can rebuild identity, SSO session, customer portal token, release-ledger core, build provenance, source/deployment, incident, security diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index 9d5a74d..f7172b9 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -92,14 +92,14 @@ func (s *Store) LoadState(ctx context.Context) (app.PersistedState, bool, error) func ResolveLoadMode(raw string, production bool) (LoadMode, error) { if strings.TrimSpace(raw) == "" && production { - return LoadModeRelationalPreferred, nil + return LoadModeRelationalOnly, nil } return normalizeLoadMode(LoadMode(raw)) } func ValidateProductionLoadMode(mode LoadMode) error { - if mode == LoadModeSnapshotPreferred { - return errors.New("production refuses EVYDENCE_POSTGRES_LOAD_MODE=snapshot_preferred") + if mode != LoadModeRelationalOnly { + return errors.New("production requires EVYDENCE_POSTGRES_LOAD_MODE=relational_only or unset") } return nil } diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index 19c1b4c..7ee67db 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -23,7 +23,7 @@ func TestResolveLoadMode(t *testing.T) { wantErr bool }{ {name: "local default", want: LoadModeSnapshotPreferred}, - {name: "production default", production: true, want: LoadModeRelationalPreferred}, + {name: "production default", production: true, want: LoadModeRelationalOnly}, {name: "snapshot alias", raw: "snapshot", production: true, want: LoadModeSnapshotPreferred}, {name: "relational alias", raw: "relational", want: LoadModeRelationalPreferred}, {name: "relational only", raw: "relational-only", want: LoadModeRelationalOnly}, @@ -48,16 +48,15 @@ func TestResolveLoadMode(t *testing.T) { } } -func TestValidateProductionLoadModeRejectsSnapshotPreferred(t *testing.T) { - if err := ValidateProductionLoadMode(LoadModeRelationalPreferred); err != nil { - t.Fatalf("relational-preferred production mode: %v", err) - } +func TestValidateProductionLoadModeRequiresRelationalOnly(t *testing.T) { if err := ValidateProductionLoadMode(LoadModeRelationalOnly); err != nil { t.Fatalf("relational-only production mode: %v", err) } - err := ValidateProductionLoadMode(LoadModeSnapshotPreferred) - if err == nil || !strings.Contains(err.Error(), "EVYDENCE_POSTGRES_LOAD_MODE") { - t.Fatalf("snapshot-preferred production err=%v", err) + for _, mode := range []LoadMode{LoadModeSnapshotPreferred, LoadModeRelationalPreferred} { + err := ValidateProductionLoadMode(mode) + if err == nil || !strings.Contains(err.Error(), "EVYDENCE_POSTGRES_LOAD_MODE") { + t.Fatalf("%s production err=%v", mode, err) + } } } From 01964b327cdcd8c2f94c5b8cd7e981a5bc832b78 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 21:25:56 +0300 Subject: [PATCH 104/287] feat: add sso session logout --- docs/api.md | 3 ++- docs/operations.md | 2 +- docs/reference/api-contract-matrix.md | 3 ++- docs/reference/production-readiness.md | 7 ++--- .../adapters/httpapi/identity_handlers.go | 7 +++++ .../adapters/httpapi/openapi_operations.go | 4 +++ .../adapters/httpapi/route_registration.go | 1 + internal/adapters/httpapi/router.go | 7 +++++ internal/adapters/httpapi/router_test.go | 6 ++++- internal/app/enterprise.go | 27 +++++++++++++++++++ internal/app/enterprise_test.go | 20 ++++++++++++-- internal/app/ledger.go | 2 +- internal/domain/domain.go | 1 + openapi.yaml | 2 +- sdk/openapi-route-catalog.json | 17 +++++++++++- 15 files changed, 97 insertions(+), 12 deletions(-) diff --git a/docs/api.md b/docs/api.md index 43b2bc0..c3fc4c4 100644 --- a/docs/api.md +++ b/docs/api.md @@ -245,10 +245,11 @@ Important scope boundaries: | `POST` | `/v1/sso/identity-links` | Link verified provider subject to user. | | `POST` | `/v1/sso/sessions` | Issue one-time session secret. | | `POST` | `/v1/sso/sessions/{id}/revoke` | Revoke session. | +| `POST` | `/v1/sso/logout` | Revoke the currently authenticated SSO session. | | `POST` | `/v1/api-keys` | Create one-time API key secret. | | `GET` | `/v1/api-keys` | List keys without secret hashes. | -Current SSO endpoints model admin-managed provider, identity-link, trust-material, and session records. OIDC provider records can include public JWKS material, and SAML provider records can include PEM-encoded assertion signing certificates; both can be rotated through `POST /v1/sso/providers/{id}/trust-material`. `POST /v1/provider-verifications` can verify a supplied OIDC ID token or SAML assertion locally for issuer, audience, subject, time bounds, and signature. Live OIDC discovery, live provider API calls, full browser login callbacks, and group synchronization are not implemented in this slice. +Current SSO endpoints model admin-managed provider, identity-link, trust-material, and session records plus API-first session logout. OIDC provider records can include public JWKS material, and SAML provider records can include PEM-encoded assertion signing certificates; both can be rotated through `POST /v1/sso/providers/{id}/trust-material`. `POST /v1/provider-verifications` can verify a supplied OIDC ID token or SAML assertion locally for issuer, audience, subject, time bounds, and signature. Live OIDC discovery, live provider API calls, full browser login callbacks, and group synchronization are not implemented in this slice. ### Products, Releases, Evidence, And Risk diff --git a/docs/operations.md b/docs/operations.md index d850adb..07c8182 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -30,7 +30,7 @@ This operator index points to the canonical references for running Evydence. Kee - API keys, collector keys, SSO session tokens, and customer portal access tokens are bearer secrets. Do not place them in logs, documentation, long-lived build output, or customer packages. - Customer portal access tokens are returned once by `POST /v1/customer-portal/access`, expire, and are stored as hashes. Deployments should still use reverse-proxy or API-gateway throttling for the unauthenticated portal endpoint. -- Human SSO session records are admin-managed. Current endpoints can verify supplied OIDC tokens and SAML assertions against tenant-configured local trust material, but they do not implement production browser login callbacks, live provider discovery/API validation, group synchronization, or browser session handling. +- Human SSO session records are admin-managed, and authenticated SSO sessions can revoke themselves through API-first logout. Current endpoints can verify supplied OIDC tokens and SAML assertions against tenant-configured local trust material, but they do not implement production browser login callbacks, live provider discovery/API validation, group synchronization, or browser cookie/session handling. - Object-retention APIs record and verify retention intent for tenant-prefixed object paths. Enforcing WORM or object-lock settings remains the responsibility of the configured object store and deployment policy. Evydence operations support evidence organization, review, and tamper-evident records. Operational checks do not replace external audit review, secret management, backup testing, or provider verification. diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index 7595a47..5e247ee 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 162 operations: 162 precise, 0 broad. +Generated from 163 operations: 163 precise, 0 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -151,6 +151,7 @@ Generated from 162 operations: 162 precise, 0 broad. | GET | /v1/source/repositories | listSourceRepositories | Bearer | source:read | - | query:project_id | - | 200:application/json:SourceRepositoryListEnvelope | precise | | POST | /v1/source/repositories | createSourceRepository | Bearer | source:write | required | - | application/json:CreateSourceRepositoryRequest | 201:application/json:SourceRepositoryEnvelope | precise | | POST | /v1/sso/identity-links | linkSSOIdentity | Bearer | identity:admin | required | - | application/json:LinkSSOIdentityRequest | 201:application/json:UserIdentityLinkEnvelope | precise | +| POST | /v1/sso/logout | logoutSSOSession | Bearer | - | required | - | application/json:EmptyObject | 200:application/json:SSOSessionEnvelope | precise | | POST | /v1/sso/providers | createSSOProvider | Bearer | identity:admin | required | - | application/json:CreateSSOProviderRequest | 201:application/json:SSOProviderEnvelope | precise | | POST | /v1/sso/providers/{id}/trust-material | updateSSOProviderTrustMaterial | Bearer | identity:admin | required | path:id | application/json:UpdateSSOProviderTrustMaterialRequest | 200:application/json:SSOProviderEnvelope | precise | | POST | /v1/sso/sessions | createSSOSession | Bearer | identity:admin | required | - | application/json:CreateSSOSessionRequest | 201:application/json:SSOSessionCreateEnvelope | precise | diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index cc7ba7d..ac0e4e1 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -146,9 +146,10 @@ implemented capabilities: signing gateway executor covers deployments that put KMS/HSM custody behind a tenant-controlled signing service and do not send raw payload bytes. - Complete live OIDC/SAML browser login callbacks, provider discovery, JWKS - fetching, logout, and optional group mapping where those profiles are - enabled. Manual JWKS and SAML signing-certificate rotation is implemented - through the SSO provider trust-material endpoint. + fetching, browser cookie/session handling, and optional group mapping where + those profiles are enabled. Manual JWKS and SAML signing-certificate rotation + is implemented through the SSO provider trust-material endpoint, and API-first + session logout can revoke the current SSO bearer session. - Extend object-lock/WORM verification beyond current S3/MinIO bucket-level checks where deployments require object-level legal hold proofs or provider policy evidence, and add live provider fetching for public transparency proofs diff --git a/internal/adapters/httpapi/identity_handlers.go b/internal/adapters/httpapi/identity_handlers.go index 94a8677..413128e 100644 --- a/internal/adapters/httpapi/identity_handlers.go +++ b/internal/adapters/httpapi/identity_handlers.go @@ -159,3 +159,10 @@ func (s *Server) revokeSSOSession(w http.ResponseWriter, r *http.Request) { return http.StatusOK, session, err }) } + +func (s *Server) logoutSSOSession(w http.ResponseWriter, r *http.Request) { + s.create(w, r, func(actor domain.Actor, _ []byte) (int, any, error) { + session, err := s.ledger.RevokeCurrentSSOSession(r.Context(), actor) + return http.StatusOK, session, err + }) +} diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 13e0a35..7fdb1f3 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -71,6 +71,10 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Parameters = append(operation.Parameters, pathParam("id", "SSO session id.")) operation.RequestBody = jsonRequest("Empty JSON object.", "#/components/schemas/EmptyObject") operation.Responses[http.StatusOK] = jsonResponse("Revoked SSO session envelope.", "#/components/schemas/SSOSessionEnvelope") + case "logoutSSOSession": + operation.Description = "Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route." + operation.RequestBody = jsonRequest("Empty JSON object.", "#/components/schemas/EmptyObject") + operation.Responses[http.StatusOK] = jsonResponse("Revoked current SSO session envelope.", "#/components/schemas/SSOSessionEnvelope") case "createSSOProvider": operation.Description = "Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls." operation.RequestBody = jsonRequest("SSO provider creation request.", "#/components/schemas/CreateSSOProviderRequest") diff --git a/internal/adapters/httpapi/route_registration.go b/internal/adapters/httpapi/route_registration.go index 2fb89aa..548787b 100644 --- a/internal/adapters/httpapi/route_registration.go +++ b/internal/adapters/httpapi/route_registration.go @@ -69,6 +69,7 @@ func (s *Server) identityRoutes() []routeDef { {http.MethodPost, "/v1/sso/identity-links", op("linkSSOIdentity", http.MethodPost, "/v1/sso/identity-links", "Link SSO identity", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.linkSSOIdentity)}, {http.MethodPost, "/v1/sso/sessions", op("createSSOSession", http.MethodPost, "/v1/sso/sessions", "Create SSO session", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.createSSOSession)}, {http.MethodPost, "/v1/sso/sessions/{id}/revoke", op("revokeSSOSession", http.MethodPost, "/v1/sso/sessions/{id}/revoke", "Revoke SSO session", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.revokeSSOSession)}, + {http.MethodPost, "/v1/sso/logout", authenticatedOp("logoutSSOSession", http.MethodPost, "/v1/sso/logout", "Logout SSO session"), http.HandlerFunc(s.logoutSSOSession)}, } } diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index b7d4a15..03d624e 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -2291,6 +2291,12 @@ func op(id, method, path, summary string, scopes []string) specs.Operation { return withCriticalOperationDetails(operation) } +func authenticatedOp(id, method, path, summary string) specs.Operation { + operation := op(id, method, path, summary, nil) + operation.Security = []specs.SecurityRequirement{{Name: "BearerAuth"}} + return operation +} + func defaultSuccessStatus(operationID, method string) int { if method == http.MethodGet { return http.StatusOK @@ -2300,6 +2306,7 @@ func defaultSuccessStatus(operationID, method string) int { } switch operationID { case "deactivateUser", + "logoutSSOSession", "revokeSSOSession", "updateSSOProviderTrustMaterial", "freezeRelease", diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 5037a4e..5dd6aeb 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -972,7 +972,11 @@ func TestEnterprisePortalRetentionAndCommercialCollectorHTTPFlow(t *testing.T) { t.Fatalf("commercial collector list missing id: %s", collectors) } sessionID := dataFieldFromNestedObject(t, sessionBody, "session", "id") - postJSON(t, server, secret, "/v1/sso/sessions/"+sessionID+"/revoke", "ent-session-revoke", map[string]any{}, http.StatusOK) + postJSON(t, server, secret, "/v1/sso/logout", "ent-api-logout", map[string]any{}, http.StatusForbidden) + logoutBody := postJSON(t, server, sessionSecret, "/v1/sso/logout", "ent-session-logout", map[string]any{}, http.StatusOK) + if !strings.Contains(logoutBody, sessionID) || !strings.Contains(logoutBody, `"revoked_at"`) { + t.Fatalf("logout response did not revoke current session: %s", logoutBody) + } getJSON(t, server, sessionSecret, "/v1/admin/instance", http.StatusUnauthorized) postJSON(t, server, secret, "/v1/users/"+userID+"/deactivate", "ent-user-deactivate", map[string]any{}, http.StatusOK) } diff --git a/internal/app/enterprise.go b/internal/app/enterprise.go index b872381..749a37e 100644 --- a/internal/app/enterprise.go +++ b/internal/app/enterprise.go @@ -422,6 +422,33 @@ func (l *Ledger) RevokeSSOSession(ctx context.Context, actor domain.Actor, id st return session, nil } +func (l *Ledger) RevokeCurrentSSOSession(ctx context.Context, actor domain.Actor) (domain.SSOSession, error) { + if err := ctx.Err(); err != nil { + return domain.SSOSession{}, err + } + if strings.TrimSpace(actor.UserID) == "" || strings.TrimSpace(actor.SessionID) == "" { + return domain.SSOSession{}, ErrForbidden + } + l.mu.Lock() + defer l.mu.Unlock() + session, ok := l.ssoSessions[strings.TrimSpace(actor.SessionID)] + if !ok || session.TenantID != actor.TenantID || session.UserID != actor.UserID { + return domain.SSOSession{}, ErrNotFound + } + if session.RevokedAt != nil { + return domain.SSOSession{}, ErrConflict + } + now := l.now() + session.RevokedAt = &now + l.ssoSessions[session.ID] = session + _, _ = l.appendChainLocked(actor.TenantID, "sso_session.revoked", "sso_session", session.ID, actorType(actor), actorID(actor), "", "") + if err := l.persistLocked(ctx); err != nil { + return domain.SSOSession{}, err + } + session.Hash = "" + return session, nil +} + func (l *Ledger) InstanceAdminSnapshot(ctx context.Context, actor domain.Actor) (domain.InstanceAdminSnapshot, error) { if err := ctx.Err(); err != nil { return domain.InstanceAdminSnapshot{}, err diff --git a/internal/app/enterprise_test.go b/internal/app/enterprise_test.go index 925f26c..b0a202a 100644 --- a/internal/app/enterprise_test.go +++ b/internal/app/enterprise_test.go @@ -71,12 +71,28 @@ func TestEnterpriseIdentityRBACSSOAndAdminSnapshot(t *testing.T) { if sessionActor.UserID != user.ID || !sessionActor.HasScope(ScopeEvidenceWrite) || sessionActor.HasScope(ScopeIdentityAdmin) { t.Fatalf("session actor scopes = %#v", sessionActor) } - if _, err := ledger.RevokeSSOSession(ctx, actor, session.ID); err != nil { - t.Fatalf("revoke session: %v", err) + if sessionActor.SessionID != session.ID { + t.Fatalf("session actor session id = %q, want %q", sessionActor.SessionID, session.ID) + } + if _, err := ledger.RevokeCurrentSSOSession(ctx, actor); !errors.Is(err, ErrForbidden) { + t.Fatalf("api key current session revoke err=%v, want forbidden", err) + } + if _, err := ledger.RevokeCurrentSSOSession(ctx, sessionActor); err != nil { + t.Fatalf("revoke current session: %v", err) } if _, err := ledger.Authenticate(ctx, secret); !errors.Is(err, ErrUnauthorized) { t.Fatalf("revoked session auth err=%v, want unauthorized", err) } + session, secret, err = ledger.CreateSSOSession(ctx, actor, CreateSSOSessionInput{UserID: user.ID, ProviderID: provider.ID, ExpiresAt: fixedNow().Add(time.Hour)}) + if err != nil { + t.Fatalf("second sso session: %v", err) + } + if _, err := ledger.RevokeSSOSession(ctx, actor, session.ID); err != nil { + t.Fatalf("admin revoke session: %v", err) + } + if _, err := ledger.Authenticate(ctx, secret); !errors.Is(err, ErrUnauthorized) { + t.Fatalf("admin-revoked session auth err=%v, want unauthorized", err) + } snapshot, err := ledger.InstanceAdminSnapshot(ctx, actor) if err != nil { t.Fatalf("instance snapshot: %v", err) diff --git a/internal/app/ledger.go b/internal/app/ledger.go index b9abe1c..d9bc3d1 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -395,7 +395,7 @@ func (l *Ledger) Authenticate(ctx context.Context, secret string) (domain.Actor, } l.ssoSessions[id] = session _ = l.persistLocked(ctx) - return domain.Actor{TenantID: user.TenantID, UserID: user.ID, Name: user.Email, Scopes: scopes, ResourceGrants: grants}, nil + return domain.Actor{TenantID: user.TenantID, UserID: user.ID, SessionID: session.ID, Name: user.Email, Scopes: scopes, ResourceGrants: grants}, nil } return domain.Actor{}, ErrUnauthorized } diff --git a/internal/domain/domain.go b/internal/domain/domain.go index bcca054..9199617 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -84,6 +84,7 @@ type Actor struct { TenantID string KeyID string UserID string + SessionID string Name string Scopes []string CollectorID string diff --git a/openapi.yaml b/openapi.yaml index 5c5d43f..1419479 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/sdk/openapi-route-catalog.json b/sdk/openapi-route-catalog.json index 6b86a4d..1d67b53 100644 --- a/sdk/openapi-route-catalog.json +++ b/sdk/openapi-route-catalog.json @@ -1,5 +1,5 @@ { - "route_count": 162, + "route_count": 163, "routes": [ { "idempotency_key_required": false, @@ -2435,6 +2435,21 @@ "201" ] }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "logoutSSOSession", + "path": "/v1/sso/logout", + "request_schema": "#/components/schemas/EmptyObject", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SSOSessionEnvelope" + ], + "scopes": [], + "success_statuses": [ + "200" + ] + }, { "idempotency_key_required": true, "method": "POST", From 4f085817962ce0bd692b2b8ffa8c3516b74aaa45 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 21:28:35 +0300 Subject: [PATCH 105/287] feat: add oidc discovery trust refresh --- .api.env.example | 3 + .implementation_increments.md | 6 +- README.md | 4 +- cmd/evydence-api/main.go | 5 + docs/api.md | 3 +- docs/operations.md | 2 +- docs/reference/api-contract-matrix.md | 3 +- docs/reference/production-readiness.md | 11 +- internal/adapters/httpapi/future_handlers.go | 48 +-- .../adapters/httpapi/identity_handlers.go | 47 +-- .../adapters/httpapi/openapi_operations.go | 5 + internal/adapters/httpapi/ops_handlers.go | 8 +- internal/adapters/httpapi/portal_handlers.go | 12 +- .../adapters/httpapi/route_registration.go | 1 + internal/adapters/httpapi/router.go | 315 +++++++++--------- internal/adapters/httpapi/router_test.go | 47 +++ .../identity/oidcdiscovery/oidcdiscovery.go | 144 ++++++++ .../oidcdiscovery/oidcdiscovery_test.go | 73 ++++ internal/app/enterprise.go | 77 +++++ internal/app/enterprise_test.go | 75 +++++ internal/app/ledger.go | 3 + internal/app/ports.go | 17 + openapi.yaml | 2 +- sdk/openapi-route-catalog.json | 19 +- 24 files changed, 706 insertions(+), 224 deletions(-) create mode 100644 internal/adapters/identity/oidcdiscovery/oidcdiscovery.go create mode 100644 internal/adapters/identity/oidcdiscovery/oidcdiscovery_test.go diff --git a/.api.env.example b/.api.env.example index 9be6b5b..4cde829 100644 --- a/.api.env.example +++ b/.api.env.example @@ -11,6 +11,9 @@ EVYDENCE_SIGNING_KEY_MODE=external # EVYDENCE_SIGNING_EXECUTOR_URL=https://signer.example.test/sign # EVYDENCE_SIGNING_EXECUTOR_TOKEN=replace-with-signing-gateway-token # EVYDENCE_SIGNING_EXECUTOR_TIMEOUT_SECONDS=10 +# Optional OIDC discovery refresh tuning. HTTP is allowed only for localhost when explicitly enabled. +# EVYDENCE_OIDC_DISCOVERY_TIMEOUT_SECONDS=10 +# EVYDENCE_OIDC_DISCOVERY_ALLOW_INSECURE_LOCALHOST=false # For MinIO/S3, set EVYDENCE_OBJECT_STORE=minio and provide: # EVYDENCE_S3_ENDPOINT=localhost:9000 # EVYDENCE_S3_BUCKET=evydence diff --git a/.implementation_increments.md b/.implementation_increments.md index 3aa51a7..60bc7e4 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -36,7 +36,7 @@ Status legend: ## Remaining Core Product Increments 6. `[x]` Relational Store Split - Added migration-backed relational tables and tenant-scoped resource projection rows for implemented resources, with transactional PostgreSQL saves, relational identity/idempotency/customer-portal-token rows, relational release-ledger core rows, relational build provenance/source/deployment/incident/security-evidence/SBOM-diff/vulnerability-workflow/contract-diff/custom-policy/waiver/approval/DSSE-trust-root/collector-release/Cosign-verification/signing-provider/Merkle-batch/transparency-checkpoint/evidence-lifecycle/release-candidate/VEX/control rows, relational package/report/retention/provider-verification/signing-operation/future-extension rows, missing-snapshot fallback loading for identity, SSO session, release-ledger, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension families, tenant/release indexes, persisted idempotency state, and outbox row locking. Canonical runtime loading still prefers the versioned ledger snapshot while per-resource repository tuning remains future hardening. + Added migration-backed relational tables and tenant-scoped resource projection rows for implemented resources, with transactional PostgreSQL saves, relational identity/idempotency/customer-portal-token rows, relational release-ledger core rows, relational build provenance/source/deployment/incident/security-evidence/SBOM-diff/vulnerability-workflow/contract-diff/custom-policy/waiver/approval/DSSE-trust-root/collector-release/Cosign-verification/signing-provider/Merkle-batch/transparency-checkpoint/evidence-lifecycle/release-candidate/VEX/control rows, relational package/report/retention/provider-verification/signing-operation/future-extension rows, missing-snapshot fallback loading for identity, SSO session, release-ledger, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension families, tenant/release indexes, persisted idempotency state, and outbox row locking. Production runtime loading defaults to relational-only and disables compatibility snapshot writes while per-resource repository tuning remains future hardening. 7. `[x]` Evidence Search, Filtering, And Timeline Querying Added tenant-scoped evidence search by product, project, release, build, deployment, type, subtype, source, collector, created time, subject refs, tags, and verification status. @@ -203,7 +203,7 @@ Status legend: Added role bindings for users and collectors, role-to-scope enforcement for human sessions, admin/customer/collector roles, tenant isolation checks, API routes, and tests. 59. `[x]` Enterprise SSO/SAML/OIDC - Added OIDC/SAML provider records, verified identity links, one-time hashed SSO session tokens, session revocation, role mapping metadata, static JWKS-backed local OIDC ID-token verification, local SAML assertion verification against configured signing certificates, audit entries, API routes, and tests. Live provider discovery, API calls, browser login callbacks, and group synchronization remain external/provider work. + Added OIDC/SAML provider records, verified identity links, one-time hashed SSO session tokens, session revocation, role mapping metadata, static JWKS-backed local OIDC ID-token verification, OIDC discovery/JWKS refresh, local SAML assertion verification against configured signing certificates, audit entries, API routes, and tests. Live provider API validation, browser login callbacks, browser cookie/session handling, and group synchronization remain external/provider work. 60. `[x]` Multi-Tenant Admin Console API Added low-detail instance admin snapshot API with tenant/resource counts and no raw evidence, token, or secret exposure. @@ -253,7 +253,7 @@ Status legend: - `[x]` Object-retention verification receipts now record a reproducible verification hash, while WORM/object-lock enforcement remains a deployment and object-store control. - `[x]` External signing-provider operation receipts now record payload hashes, checks, and signature references, while production KMS/HSM adapter execution remains deployment hardening work. -- `[x]` Stored OIDC/SAML identity-link verification records provider-verification receipts, and OIDC ID tokens plus SAML assertions can be verified locally against configured tenant trust material. Public JWKS and SAML signing certificates can be rotated without recreating the provider. Live provider discovery/API calls, browser login callbacks, and group synchronization remain external/provider work. +- `[x]` Stored OIDC/SAML identity-link verification records provider-verification receipts, and OIDC ID tokens plus SAML assertions can be verified locally against configured tenant trust material. Public OIDC JWKS can be refreshed from discovery metadata, and public JWKS plus SAML signing certificates can be rotated without recreating the provider. Live provider API calls, browser login callbacks, browser cookie/session handling, and group synchronization remain external/provider work. - `[x]` Public transparency log records now link local Merkle checkpoints to external entry metadata and can verify operator-supplied inclusion proof material locally. Live provider fetching remains deployment hardening work. - `[x]` Marketplace collector records now capture package metadata and evidence references, and expose package health reports for signature, SBOM, and vulnerability scan evidence gaps. Marketplace distribution remains external operational hardening. - `[x]` Docker/Helm runtime packaging now includes the worker binary and migrations and uses commands that match the image PATH. diff --git a/README.md b/README.md index cad9098..4ccc486 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ This repository contains a Go implementation under module `github.com/aatuh/evyd - AGPL license, commercial licensing, governance, contribution, security, support, trademark, release-evidence, and changelog metadata. -Implemented-but-partial areas are documented explicitly: signing-provider operation receipts do not replace direct production KMS/HSM SDK adapters, local OIDC/SAML verification does not replace live provider discovery/API validation or browser login callbacks, and public transparency records verify operator-supplied inclusion proof material without fetching live provider proofs. +Implemented-but-partial areas are documented explicitly: signing-provider operation receipts do not replace direct production KMS/HSM SDK adapters, OIDC discovery refreshes public JWKS trust material but does not replace full browser login callbacks or provider API validation, and public transparency records verify operator-supplied inclusion proof material without fetching live provider proofs. ## License, Security, Support, And Governance @@ -107,4 +107,4 @@ make postgres-integration-test `make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. -`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required production-readiness evidence, but it does not by itself close the remaining repository-split, worker side-effect, direct KMS/HSM SDK, browser SSO, live provider-fetching, object-lock enforcement, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. +`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required production-readiness evidence, but it does not by itself close the remaining repository-split, worker side-effect, direct KMS/HSM SDK, browser SSO, provider API validation, object-lock enforcement, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. diff --git a/cmd/evydence-api/main.go b/cmd/evydence-api/main.go index d37187a..41f9de0 100644 --- a/cmd/evydence-api/main.go +++ b/cmd/evydence-api/main.go @@ -14,6 +14,7 @@ import ( "time" "github.com/aatuh/evydence/internal/adapters/httpapi" + "github.com/aatuh/evydence/internal/adapters/identity/oidcdiscovery" "github.com/aatuh/evydence/internal/adapters/objectstore/filesystem" s3store "github.com/aatuh/evydence/internal/adapters/objectstore/s3" "github.com/aatuh/evydence/internal/adapters/postgres" @@ -35,6 +36,10 @@ func run() error { return err } cfg := app.Config{APIKeyPepper: pepper} + cfg.OIDC = oidcdiscovery.New(oidcdiscovery.Config{ + AllowInsecureForLocalhost: strings.EqualFold(os.Getenv("EVYDENCE_OIDC_DISCOVERY_ALLOW_INSECURE_LOCALHOST"), "true"), + Timeout: time.Duration(intEnv("EVYDENCE_OIDC_DISCOVERY_TIMEOUT_SECONDS", 10)) * time.Second, + }) if signer, err := openSigningExecutor(); err != nil { return err } else { diff --git a/docs/api.md b/docs/api.md index c3fc4c4..ceeba1a 100644 --- a/docs/api.md +++ b/docs/api.md @@ -242,6 +242,7 @@ Important scope boundaries: | `GET` | `/v1/role-bindings` | List tenant-scoped bindings. | | `POST` | `/v1/sso/providers` | Record OIDC or SAML provider metadata. | | `POST` | `/v1/sso/providers/{id}/trust-material` | Rotate OIDC JWKS or SAML signing certificates used for local verification. | +| `POST` | `/v1/sso/providers/{id}/discover-oidc` | Fetch OIDC discovery metadata and refresh public JWKS trust material. | | `POST` | `/v1/sso/identity-links` | Link verified provider subject to user. | | `POST` | `/v1/sso/sessions` | Issue one-time session secret. | | `POST` | `/v1/sso/sessions/{id}/revoke` | Revoke session. | @@ -249,7 +250,7 @@ Important scope boundaries: | `POST` | `/v1/api-keys` | Create one-time API key secret. | | `GET` | `/v1/api-keys` | List keys without secret hashes. | -Current SSO endpoints model admin-managed provider, identity-link, trust-material, and session records plus API-first session logout. OIDC provider records can include public JWKS material, and SAML provider records can include PEM-encoded assertion signing certificates; both can be rotated through `POST /v1/sso/providers/{id}/trust-material`. `POST /v1/provider-verifications` can verify a supplied OIDC ID token or SAML assertion locally for issuer, audience, subject, time bounds, and signature. Live OIDC discovery, live provider API calls, full browser login callbacks, and group synchronization are not implemented in this slice. +Current SSO endpoints model admin-managed provider, identity-link, trust-material, and session records plus API-first session logout. OIDC provider records can include public JWKS material, and SAML provider records can include PEM-encoded assertion signing certificates; both can be rotated through `POST /v1/sso/providers/{id}/trust-material`. OIDC public JWKS can also be refreshed from the configured issuer with `POST /v1/sso/providers/{id}/discover-oidc`. `POST /v1/provider-verifications` can verify a supplied OIDC ID token or SAML assertion locally for issuer, audience, subject, time bounds, and signature. Live provider API calls, full browser login callbacks, browser cookie/session handling, and group synchronization are not implemented in this slice. ### Products, Releases, Evidence, And Risk diff --git a/docs/operations.md b/docs/operations.md index 07c8182..584fe46 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -30,7 +30,7 @@ This operator index points to the canonical references for running Evydence. Kee - API keys, collector keys, SSO session tokens, and customer portal access tokens are bearer secrets. Do not place them in logs, documentation, long-lived build output, or customer packages. - Customer portal access tokens are returned once by `POST /v1/customer-portal/access`, expire, and are stored as hashes. Deployments should still use reverse-proxy or API-gateway throttling for the unauthenticated portal endpoint. -- Human SSO session records are admin-managed, and authenticated SSO sessions can revoke themselves through API-first logout. Current endpoints can verify supplied OIDC tokens and SAML assertions against tenant-configured local trust material, but they do not implement production browser login callbacks, live provider discovery/API validation, group synchronization, or browser cookie/session handling. +- Human SSO session records are admin-managed, and authenticated SSO sessions can revoke themselves through API-first logout. Current endpoints can refresh OIDC public JWKS from discovery metadata and verify supplied OIDC tokens and SAML assertions against tenant-configured local trust material, but they do not implement production browser login callbacks, live provider API validation, group synchronization, or browser cookie/session handling. - Object-retention APIs record and verify retention intent for tenant-prefixed object paths. Enforcing WORM or object-lock settings remains the responsibility of the configured object store and deployment policy. Evydence operations support evidence organization, review, and tamper-evident records. Operational checks do not replace external audit review, secret management, backup testing, or provider verification. diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index 5e247ee..b28b4c5 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 163 operations: 163 precise, 0 broad. +Generated from 164 operations: 164 precise, 0 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -153,6 +153,7 @@ Generated from 163 operations: 163 precise, 0 broad. | POST | /v1/sso/identity-links | linkSSOIdentity | Bearer | identity:admin | required | - | application/json:LinkSSOIdentityRequest | 201:application/json:UserIdentityLinkEnvelope | precise | | POST | /v1/sso/logout | logoutSSOSession | Bearer | - | required | - | application/json:EmptyObject | 200:application/json:SSOSessionEnvelope | precise | | POST | /v1/sso/providers | createSSOProvider | Bearer | identity:admin | required | - | application/json:CreateSSOProviderRequest | 201:application/json:SSOProviderEnvelope | precise | +| POST | /v1/sso/providers/{id}/discover-oidc | refreshSSOProviderOIDCTrustMaterial | Bearer | identity:admin | required | path:id | application/json:EmptyObject | 200:application/json:SSOProviderEnvelope | precise | | POST | /v1/sso/providers/{id}/trust-material | updateSSOProviderTrustMaterial | Bearer | identity:admin | required | path:id | application/json:UpdateSSOProviderTrustMaterialRequest | 200:application/json:SSOProviderEnvelope | precise | | POST | /v1/sso/sessions | createSSOSession | Bearer | identity:admin | required | - | application/json:CreateSSOSessionRequest | 201:application/json:SSOSessionCreateEnvelope | precise | | POST | /v1/sso/sessions/{id}/revoke | revokeSSOSession | Bearer | identity:admin | required | path:id | application/json:EmptyObject | 200:application/json:SSOSessionEnvelope | precise | diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index ac0e4e1..022af31 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -45,7 +45,7 @@ Known hardening work remains: parameters, and request/response schemas; - production signing can use the HTTPS signing gateway executor, but direct cloud KMS/HSM SDK adapters, full browser OIDC/SAML login flows, provider - discovery/group sync, object-lock enforcement proof, and live + API validation/group sync, object-lock enforcement proof, and live transparency-proof fetching remain provider- and deployment-dependent hardening areas; - the broader production exit review remains incomplete. @@ -145,10 +145,11 @@ implemented capabilities: - Add direct cloud KMS/HSM SDK adapters where required. The current HTTPS signing gateway executor covers deployments that put KMS/HSM custody behind a tenant-controlled signing service and do not send raw payload bytes. -- Complete live OIDC/SAML browser login callbacks, provider discovery, JWKS - fetching, browser cookie/session handling, and optional group mapping where - those profiles are enabled. Manual JWKS and SAML signing-certificate rotation - is implemented through the SSO provider trust-material endpoint, and API-first +- Complete live OIDC/SAML browser login callbacks, browser cookie/session + handling, provider API validation, and optional group mapping where those + profiles are enabled. OIDC discovery/JWKS refresh is implemented for public + trust-material updates, manual JWKS and SAML signing-certificate rotation is + implemented through the SSO provider trust-material endpoint, and API-first session logout can revoke the current SSO bearer session. - Extend object-lock/WORM verification beyond current S3/MinIO bucket-level checks where deployments require object-level legal hold proofs or provider diff --git a/internal/adapters/httpapi/future_handlers.go b/internal/adapters/httpapi/future_handlers.go index 8cb7fb3..995d1f3 100644 --- a/internal/adapters/httpapi/future_handlers.go +++ b/internal/adapters/httpapi/future_handlers.go @@ -13,11 +13,11 @@ func (s *Server) createEvidenceSummary(w http.ResponseWriter, r *http.Request) { SubjectID string `json:"subject_id"` EvidenceIDs []string `json:"evidence_ids"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - summary, err := s.ledger.CreateEvidenceSummary(r.Context(), actor, app.CreateEvidenceSummaryInput{SubjectType: req.SubjectType, SubjectID: req.SubjectID, EvidenceIDs: req.EvidenceIDs}) + summary, err := s.ledger.CreateEvidenceSummary(ctx, actor, app.CreateEvidenceSummaryInput{SubjectType: req.SubjectType, SubjectID: req.SubjectID, EvidenceIDs: req.EvidenceIDs}) return http.StatusCreated, summary, err }) } @@ -28,11 +28,11 @@ func (s *Server) createQuestionnaireDraft(w http.ResponseWriter, r *http.Request ProductID string `json:"product_id"` ReleaseID string `json:"release_id"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - draft, err := s.ledger.CreateQuestionnaireDraft(r.Context(), actor, app.CreateQuestionnaireDraftInput{TemplateID: req.TemplateID, ProductID: req.ProductID, ReleaseID: req.ReleaseID}) + draft, err := s.ledger.CreateQuestionnaireDraft(ctx, actor, app.CreateQuestionnaireDraftInput{TemplateID: req.TemplateID, ProductID: req.ProductID, ReleaseID: req.ReleaseID}) return http.StatusCreated, draft, err }) } @@ -42,11 +42,11 @@ func (s *Server) createGraphSnapshot(w http.ResponseWriter, r *http.Request) { ProductID string `json:"product_id"` ReleaseID string `json:"release_id"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - graph, err := s.ledger.CreateGraphSnapshot(r.Context(), actor, app.CreateGraphSnapshotInput{ProductID: req.ProductID, ReleaseID: req.ReleaseID}) + graph, err := s.ledger.CreateGraphSnapshot(ctx, actor, app.CreateGraphSnapshotInput{ProductID: req.ProductID, ReleaseID: req.ReleaseID}) return http.StatusCreated, graph, err }) } @@ -58,11 +58,11 @@ func (s *Server) createSaaSEditionProfile(w http.ResponseWriter, r *http.Request AdminTenantID string `json:"admin_tenant_id"` IsolationModel string `json:"isolation_model"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - profile, err := s.ledger.CreateSaaSEditionProfile(r.Context(), actor, app.CreateSaaSEditionProfileInput{Name: req.Name, Region: req.Region, AdminTenantID: req.AdminTenantID, IsolationModel: req.IsolationModel}) + profile, err := s.ledger.CreateSaaSEditionProfile(ctx, actor, app.CreateSaaSEditionProfileInput{Name: req.Name, Region: req.Region, AdminTenantID: req.AdminTenantID, IsolationModel: req.IsolationModel}) return http.StatusCreated, profile, err }) } @@ -73,11 +73,11 @@ func (s *Server) createPublicTransparencyLog(w http.ResponseWriter, r *http.Requ Endpoint string `json:"endpoint"` PublicKey string `json:"public_key"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - log, err := s.ledger.CreatePublicTransparencyLog(r.Context(), actor, app.CreatePublicTransparencyLogInput{Name: req.Name, Endpoint: req.Endpoint, PublicKey: req.PublicKey}) + log, err := s.ledger.CreatePublicTransparencyLog(ctx, actor, app.CreatePublicTransparencyLogInput{Name: req.Name, Endpoint: req.Endpoint, PublicKey: req.PublicKey}) return http.StatusCreated, log, err }) } @@ -88,11 +88,11 @@ func (s *Server) publishPublicTransparencyLogEntry(w http.ResponseWriter, r *htt CheckpointID string `json:"checkpoint_id"` ExternalID string `json:"external_id"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - entry, err := s.ledger.PublishPublicTransparencyLogEntry(r.Context(), actor, app.PublishPublicTransparencyLogEntryInput{LogID: req.LogID, CheckpointID: req.CheckpointID, ExternalID: req.ExternalID}) + entry, err := s.ledger.PublishPublicTransparencyLogEntry(ctx, actor, app.PublishPublicTransparencyLogEntryInput{LogID: req.LogID, CheckpointID: req.CheckpointID, ExternalID: req.ExternalID}) return http.StatusCreated, entry, err }) } @@ -105,11 +105,11 @@ func (s *Server) verifyPublicTransparencyLogEntry(w http.ResponseWriter, r *http TreeSize int `json:"tree_size"` InclusionProof []string `json:"inclusion_proof"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - entry, err := s.ledger.VerifyPublicTransparencyLogEntry(r.Context(), actor, r.PathValue("id"), app.VerifyPublicTransparencyLogEntryInput{ + entry, err := s.ledger.VerifyPublicTransparencyLogEntry(ctx, actor, r.PathValue("id"), app.VerifyPublicTransparencyLogEntryInput{ LeafHash: req.LeafHash, RootHash: req.RootHash, LeafIndex: req.LeafIndex, @@ -131,11 +131,11 @@ func (s *Server) createMarketplaceCollector(w http.ResponseWriter, r *http.Reque SBOMID string `json:"sbom_id"` ScanID string `json:"scan_id"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - collector, err := s.ledger.CreateMarketplaceCollector(r.Context(), actor, app.CreateMarketplaceCollectorInput{Name: req.Name, Provider: req.Provider, Version: req.Version, Publisher: req.Publisher, ManifestHash: req.ManifestHash, SignatureID: req.SignatureID, SBOMID: req.SBOMID, ScanID: req.ScanID}) + collector, err := s.ledger.CreateMarketplaceCollector(ctx, actor, app.CreateMarketplaceCollectorInput{Name: req.Name, Provider: req.Provider, Version: req.Version, Publisher: req.Publisher, ManifestHash: req.ManifestHash, SignatureID: req.SignatureID, SBOMID: req.SBOMID, ScanID: req.ScanID}) return http.StatusCreated, collector, err }) } @@ -173,11 +173,11 @@ func (s *Server) createPDFReportPackage(w http.ResponseWriter, r *http.Request) ReleaseID string `json:"release_id"` Title string `json:"title"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - pkg, err := s.ledger.CreatePDFReportPackage(r.Context(), actor, app.CreatePDFReportPackageInput{ReportType: req.ReportType, ProductID: req.ProductID, ReleaseID: req.ReleaseID, Title: req.Title}) + pkg, err := s.ledger.CreatePDFReportPackage(ctx, actor, app.CreatePDFReportPackageInput{ReportType: req.ReportType, ProductID: req.ProductID, ReleaseID: req.ReleaseID, Title: req.Title}) return http.StatusCreated, pkg, err }) } @@ -187,11 +187,11 @@ func (s *Server) generateAnomalyReport(w http.ResponseWriter, r *http.Request) { SubjectType string `json:"subject_type"` SubjectID string `json:"subject_id"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - report, err := s.ledger.GenerateAnomalyReport(r.Context(), actor, app.AnomalyReportInput{SubjectType: req.SubjectType, SubjectID: req.SubjectID}) + report, err := s.ledger.GenerateAnomalyReport(ctx, actor, app.AnomalyReportInput{SubjectType: req.SubjectType, SubjectID: req.SubjectID}) return http.StatusCreated, report, err }) } @@ -204,11 +204,11 @@ func (s *Server) createSigningOperation(w http.ResponseWriter, r *http.Request) PayloadHash string `json:"payload_hash"` ExternalSignature string `json:"external_signature"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - op, err := s.ledger.CreateSigningOperation(r.Context(), actor, app.CreateSigningOperationInput{ProviderID: req.ProviderID, SubjectType: req.SubjectType, SubjectID: req.SubjectID, PayloadHash: req.PayloadHash, ExternalSignature: req.ExternalSignature}) + op, err := s.ledger.CreateSigningOperation(ctx, actor, app.CreateSigningOperationInput{ProviderID: req.ProviderID, SubjectType: req.SubjectType, SubjectID: req.SubjectID, PayloadHash: req.PayloadHash, ExternalSignature: req.ExternalSignature}) return http.StatusCreated, op, err }) } @@ -221,11 +221,11 @@ func (s *Server) verifyProviderIdentity(w http.ResponseWriter, r *http.Request) IDToken string `json:"id_token"` SAMLAssertion string `json:"saml_assertion"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - record, err := s.ledger.VerifyProviderIdentity(r.Context(), actor, app.VerifyProviderIdentityInput{ProviderType: req.ProviderType, ProviderID: req.ProviderID, Subject: req.Subject, IDToken: req.IDToken, SAMLAssertion: req.SAMLAssertion}) + record, err := s.ledger.VerifyProviderIdentity(ctx, actor, app.VerifyProviderIdentityInput{ProviderType: req.ProviderType, ProviderID: req.ProviderID, Subject: req.Subject, IDToken: req.IDToken, SAMLAssertion: req.SAMLAssertion}) return http.StatusCreated, record, err }) } diff --git a/internal/adapters/httpapi/identity_handlers.go b/internal/adapters/httpapi/identity_handlers.go index 413128e..dcb5207 100644 --- a/internal/adapters/httpapi/identity_handlers.go +++ b/internal/adapters/httpapi/identity_handlers.go @@ -26,11 +26,11 @@ func (s *Server) createOrganization(w http.ResponseWriter, r *http.Request) { Name string `json:"name"` Slug string `json:"slug"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - org, err := s.ledger.CreateOrganization(r.Context(), actor, app.CreateOrganizationInput{Name: req.Name, Slug: req.Slug}) + org, err := s.ledger.CreateOrganization(ctx, actor, app.CreateOrganizationInput{Name: req.Name, Slug: req.Slug}) return http.StatusCreated, org, err }) } @@ -41,18 +41,18 @@ func (s *Server) createUser(w http.ResponseWriter, r *http.Request) { Email string `json:"email"` DisplayName string `json:"display_name"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - user, err := s.ledger.CreateUser(r.Context(), actor, app.CreateUserInput{OrganizationID: req.OrganizationID, Email: req.Email, DisplayName: req.DisplayName}) + user, err := s.ledger.CreateUser(ctx, actor, app.CreateUserInput{OrganizationID: req.OrganizationID, Email: req.Email, DisplayName: req.DisplayName}) return http.StatusCreated, user, err }) } func (s *Server) deactivateUser(w http.ResponseWriter, r *http.Request) { - s.create(w, r, func(actor domain.Actor, _ []byte) (int, any, error) { - user, err := s.ledger.DeactivateUser(r.Context(), actor, r.PathValue("id")) + s.create(w, r, func(ctx requestContext, actor domain.Actor, _ []byte) (int, any, error) { + user, err := s.ledger.DeactivateUser(ctx, actor, r.PathValue("id")) return http.StatusOK, user, err }) } @@ -65,11 +65,11 @@ func (s *Server) createRoleBinding(w http.ResponseWriter, r *http.Request) { ResourceType string `json:"resource_type"` ResourceID string `json:"resource_id"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - binding, err := s.ledger.CreateRoleBinding(r.Context(), actor, app.CreateRoleBindingInput{SubjectType: req.SubjectType, SubjectID: req.SubjectID, Role: req.Role, ResourceType: req.ResourceType, ResourceID: req.ResourceID}) + binding, err := s.ledger.CreateRoleBinding(ctx, actor, app.CreateRoleBindingInput{SubjectType: req.SubjectType, SubjectID: req.SubjectID, Role: req.Role, ResourceType: req.ResourceType, ResourceID: req.ResourceID}) return http.StatusCreated, binding, err }) } @@ -98,11 +98,11 @@ func (s *Server) createSSOProvider(w http.ResponseWriter, r *http.Request) { JWKS map[string]any `json:"jwks"` SAMLSigningCertificates []string `json:"saml_signing_certificates"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - provider, err := s.ledger.CreateSSOProvider(r.Context(), actor, app.CreateSSOProviderInput{Name: req.Name, Type: req.Type, Issuer: req.Issuer, ClientID: req.ClientID, GroupsClaim: req.GroupsClaim, RoleMapping: req.RoleMapping, JWKS: req.JWKS, SAMLSigningCertificates: req.SAMLSigningCertificates}) + provider, err := s.ledger.CreateSSOProvider(ctx, actor, app.CreateSSOProviderInput{Name: req.Name, Type: req.Type, Issuer: req.Issuer, ClientID: req.ClientID, GroupsClaim: req.GroupsClaim, RoleMapping: req.RoleMapping, JWKS: req.JWKS, SAMLSigningCertificates: req.SAMLSigningCertificates}) return http.StatusCreated, provider, err }) } @@ -112,11 +112,18 @@ func (s *Server) updateSSOProviderTrustMaterial(w http.ResponseWriter, r *http.R JWKS map[string]any `json:"jwks"` SAMLSigningCertificates []string `json:"saml_signing_certificates"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - provider, err := s.ledger.UpdateSSOProviderTrustMaterial(r.Context(), actor, r.PathValue("id"), app.UpdateSSOProviderTrustMaterialInput{JWKS: req.JWKS, SAMLSigningCertificates: req.SAMLSigningCertificates}) + provider, err := s.ledger.UpdateSSOProviderTrustMaterial(ctx, actor, r.PathValue("id"), app.UpdateSSOProviderTrustMaterialInput{JWKS: req.JWKS, SAMLSigningCertificates: req.SAMLSigningCertificates}) + return http.StatusOK, provider, err + }) +} + +func (s *Server) refreshSSOProviderOIDCTrustMaterial(w http.ResponseWriter, r *http.Request) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, _ []byte) (int, any, error) { + provider, err := s.ledger.RefreshSSOProviderOIDCTrustMaterial(ctx, actor, r.PathValue("id")) return http.StatusOK, provider, err }) } @@ -129,11 +136,11 @@ func (s *Server) linkSSOIdentity(w http.ResponseWriter, r *http.Request) { Email string `json:"email"` Verified bool `json:"verified"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - link, err := s.ledger.LinkSSOIdentity(r.Context(), actor, app.LinkSSOIdentityInput{UserID: req.UserID, ProviderID: req.ProviderID, Subject: req.Subject, Email: req.Email, Verified: req.Verified}) + link, err := s.ledger.LinkSSOIdentity(ctx, actor, app.LinkSSOIdentityInput{UserID: req.UserID, ProviderID: req.ProviderID, Subject: req.Subject, Email: req.Email, Verified: req.Verified}) return http.StatusCreated, link, err }) } @@ -144,25 +151,25 @@ func (s *Server) createSSOSession(w http.ResponseWriter, r *http.Request) { ProviderID string `json:"provider_id"` ExpiresAt time.Time `json:"expires_at"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - session, secret, err := s.ledger.CreateSSOSession(r.Context(), actor, app.CreateSSOSessionInput{UserID: req.UserID, ProviderID: req.ProviderID, ExpiresAt: req.ExpiresAt}) + session, secret, err := s.ledger.CreateSSOSession(ctx, actor, app.CreateSSOSessionInput{UserID: req.UserID, ProviderID: req.ProviderID, ExpiresAt: req.ExpiresAt}) return http.StatusCreated, map[string]any{"session": session, "secret": secret}, err }) } func (s *Server) revokeSSOSession(w http.ResponseWriter, r *http.Request) { - s.create(w, r, func(actor domain.Actor, _ []byte) (int, any, error) { - session, err := s.ledger.RevokeSSOSession(r.Context(), actor, r.PathValue("id")) + s.create(w, r, func(ctx requestContext, actor domain.Actor, _ []byte) (int, any, error) { + session, err := s.ledger.RevokeSSOSession(ctx, actor, r.PathValue("id")) return http.StatusOK, session, err }) } func (s *Server) logoutSSOSession(w http.ResponseWriter, r *http.Request) { - s.create(w, r, func(actor domain.Actor, _ []byte) (int, any, error) { - session, err := s.ledger.RevokeCurrentSSOSession(r.Context(), actor) + s.create(w, r, func(ctx requestContext, actor domain.Actor, _ []byte) (int, any, error) { + session, err := s.ledger.RevokeCurrentSSOSession(ctx, actor) return http.StatusOK, session, err }) } diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 7fdb1f3..9f9715a 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -84,6 +84,11 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Parameters = append(operation.Parameters, pathParam("id", "SSO provider id.")) operation.RequestBody = jsonRequest("SSO provider trust material update request.", "#/components/schemas/UpdateSSOProviderTrustMaterialRequest") operation.Responses[http.StatusOK] = jsonResponse("Updated SSO provider envelope.", "#/components/schemas/SSOProviderEnvelope") + case "refreshSSOProviderOIDCTrustMaterial": + operation.Description = "Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups." + operation.Parameters = append(operation.Parameters, pathParam("id", "SSO provider id.")) + operation.RequestBody = jsonRequest("Empty JSON object.", "#/components/schemas/EmptyObject") + operation.Responses[http.StatusOK] = jsonResponse("Refreshed SSO provider envelope.", "#/components/schemas/SSOProviderEnvelope") case "verifyProviderIdentity": operation.Description = "Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material." operation.RequestBody = jsonRequest("Provider identity verification request.", "#/components/schemas/VerifyProviderIdentityRequest") diff --git a/internal/adapters/httpapi/ops_handlers.go b/internal/adapters/httpapi/ops_handlers.go index 2d07cc6..bd10ed6 100644 --- a/internal/adapters/httpapi/ops_handlers.go +++ b/internal/adapters/httpapi/ops_handlers.go @@ -15,11 +15,11 @@ func (s *Server) createLegalHold(w http.ResponseWriter, r *http.Request) { Reason string `json:"reason"` Owner string `json:"owner"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - hold, err := s.ledger.CreateLegalHold(r.Context(), actor, app.CreateLegalHoldInput{ScopeType: req.ScopeType, ScopeID: req.ScopeID, Reason: req.Reason, Owner: req.Owner}) + hold, err := s.ledger.CreateLegalHold(ctx, actor, app.CreateLegalHoldInput{ScopeType: req.ScopeType, ScopeID: req.ScopeID, Reason: req.Reason, Owner: req.Owner}) return http.StatusCreated, hold, err }) } @@ -32,11 +32,11 @@ func (s *Server) createRetentionOverride(w http.ResponseWriter, r *http.Request) Reason string `json:"reason"` Owner string `json:"owner"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - override, err := s.ledger.CreateRetentionOverride(r.Context(), actor, app.CreateRetentionOverrideInput{ScopeType: req.ScopeType, ScopeID: req.ScopeID, RetentionUntil: req.RetentionUntil, Reason: req.Reason, Owner: req.Owner}) + override, err := s.ledger.CreateRetentionOverride(ctx, actor, app.CreateRetentionOverrideInput{ScopeType: req.ScopeType, ScopeID: req.ScopeID, RetentionUntil: req.RetentionUntil, Reason: req.Reason, Owner: req.Owner}) return http.StatusCreated, override, err }) } diff --git a/internal/adapters/httpapi/portal_handlers.go b/internal/adapters/httpapi/portal_handlers.go index fbee39f..3d3c7cf 100644 --- a/internal/adapters/httpapi/portal_handlers.go +++ b/internal/adapters/httpapi/portal_handlers.go @@ -14,11 +14,11 @@ func (s *Server) createCustomerPortalAccess(w http.ResponseWriter, r *http.Reque CustomerName string `json:"customer_name"` ExpiresAt time.Time `json:"expires_at"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - access, secret, err := s.ledger.CreateCustomerPortalAccess(r.Context(), actor, app.CreateCustomerPortalAccessInput{PackageID: req.PackageID, CustomerName: req.CustomerName, ExpiresAt: req.ExpiresAt}) + access, secret, err := s.ledger.CreateCustomerPortalAccess(ctx, actor, app.CreateCustomerPortalAccessInput{PackageID: req.PackageID, CustomerName: req.CustomerName, ExpiresAt: req.ExpiresAt}) return http.StatusCreated, map[string]any{"access": access, "secret": secret}, err }) } @@ -71,11 +71,11 @@ func (s *Server) createQuestionnaireTemplate(w http.ResponseWriter, r *http.Requ Version string `json:"version"` Questions []domain.QuestionnaireQuestion `json:"questions"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - tpl, err := s.ledger.CreateQuestionnaireTemplate(r.Context(), actor, app.CreateQuestionnaireTemplateInput{Name: req.Name, Version: req.Version, Questions: req.Questions}) + tpl, err := s.ledger.CreateQuestionnaireTemplate(ctx, actor, app.CreateQuestionnaireTemplateInput{Name: req.Name, Version: req.Version, Questions: req.Questions}) return http.StatusCreated, tpl, err }) } @@ -87,11 +87,11 @@ func (s *Server) createQuestionnairePackage(w http.ResponseWriter, r *http.Reque ProductID string `json:"product_id"` ReleaseID string `json:"release_id"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - pkg, err := s.ledger.CreateQuestionnairePackage(r.Context(), actor, app.CreateQuestionnairePackageInput{TemplateID: req.TemplateID, PackageID: req.PackageID, ProductID: req.ProductID, ReleaseID: req.ReleaseID}) + pkg, err := s.ledger.CreateQuestionnairePackage(ctx, actor, app.CreateQuestionnairePackageInput{TemplateID: req.TemplateID, PackageID: req.PackageID, ProductID: req.ProductID, ReleaseID: req.ReleaseID}) return http.StatusCreated, pkg, err }) } diff --git a/internal/adapters/httpapi/route_registration.go b/internal/adapters/httpapi/route_registration.go index 548787b..be9494f 100644 --- a/internal/adapters/httpapi/route_registration.go +++ b/internal/adapters/httpapi/route_registration.go @@ -66,6 +66,7 @@ func (s *Server) identityRoutes() []routeDef { {http.MethodGet, "/v1/role-bindings", op("listRoleBindings", http.MethodGet, "/v1/role-bindings", "List role bindings", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.listRoleBindings)}, {http.MethodPost, "/v1/sso/providers", op("createSSOProvider", http.MethodPost, "/v1/sso/providers", "Create SSO provider", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.createSSOProvider)}, {http.MethodPost, "/v1/sso/providers/{id}/trust-material", op("updateSSOProviderTrustMaterial", http.MethodPost, "/v1/sso/providers/{id}/trust-material", "Update SSO provider trust material", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.updateSSOProviderTrustMaterial)}, + {http.MethodPost, "/v1/sso/providers/{id}/discover-oidc", op("refreshSSOProviderOIDCTrustMaterial", http.MethodPost, "/v1/sso/providers/{id}/discover-oidc", "Refresh SSO provider OIDC trust material", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.refreshSSOProviderOIDCTrustMaterial)}, {http.MethodPost, "/v1/sso/identity-links", op("linkSSOIdentity", http.MethodPost, "/v1/sso/identity-links", "Link SSO identity", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.linkSSOIdentity)}, {http.MethodPost, "/v1/sso/sessions", op("createSSOSession", http.MethodPost, "/v1/sso/sessions", "Create SSO session", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.createSSOSession)}, {http.MethodPost, "/v1/sso/sessions/{id}/revoke", op("revokeSSOSession", http.MethodPost, "/v1/sso/sessions/{id}/revoke", "Revoke SSO session", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.revokeSSOSession)}, diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index 03d624e..26136b4 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -2,6 +2,7 @@ package httpapi import ( "bytes" + "context" "crypto/rand" "encoding/hex" "encoding/json" @@ -23,6 +24,8 @@ import ( "github.com/aatuh/evydence/internal/domain" ) +type requestContext = context.Context + const maxJSONBody = 2 << 20 const requestIDHeader = "X-Request-ID" @@ -76,11 +79,11 @@ func (s *Server) createCollector(w http.ResponseWriter, r *http.Request) { Version string `json:"version"` Scopes []string `json:"scopes"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - collector, key, secret, err := s.ledger.CreateCollector(r.Context(), actor, app.CreateCollectorInput{ + collector, key, secret, err := s.ledger.CreateCollector(ctx, actor, app.CreateCollectorInput{ Name: req.Name, Type: req.Type, Version: req.Version, @@ -112,11 +115,11 @@ func (s *Server) recordCollectorRelease(w http.ResponseWriter, r *http.Request) ScanID string `json:"scan_id"` Pinned bool `json:"pinned"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - release, err := s.ledger.RecordCollectorRelease(r.Context(), actor, app.RecordCollectorReleaseInput{ + release, err := s.ledger.RecordCollectorRelease(ctx, actor, app.RecordCollectorReleaseInput{ CollectorID: r.PathValue("id"), Version: req.Version, ArtifactDigest: req.ArtifactDigest, @@ -149,11 +152,11 @@ func (s *Server) createControlFramework(w http.ResponseWriter, r *http.Request) Version string `json:"version"` Description string `json:"description"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - framework, err := s.ledger.CreateControlFramework(r.Context(), actor, app.CreateControlFrameworkInput{ + framework, err := s.ledger.CreateControlFramework(ctx, actor, app.CreateControlFrameworkInput{ Name: req.Name, Slug: req.Slug, Version: req.Version, @@ -190,8 +193,8 @@ func (s *Server) listControlFrameworkTemplatePacks(w http.ResponseWriter, r *htt } func (s *Server) installControlFrameworkTemplatePack(w http.ResponseWriter, r *http.Request) { - s.create(w, r, func(actor domain.Actor, _ []byte) (int, any, error) { - framework, err := s.ledger.InstallControlFrameworkTemplatePack(r.Context(), actor, r.PathValue("slug")) + s.create(w, r, func(ctx requestContext, actor domain.Actor, _ []byte) (int, any, error) { + framework, err := s.ledger.InstallControlFrameworkTemplatePack(ctx, actor, r.PathValue("slug")) return http.StatusCreated, framework, err }) } @@ -206,11 +209,11 @@ func (s *Server) createSecurityControl(w http.ResponseWriter, r *http.Request) { Applicability []string `json:"applicability"` Limitations []string `json:"limitations"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - control, err := s.ledger.CreateSecurityControl(r.Context(), actor, app.CreateSecurityControlInput{ + control, err := s.ledger.CreateSecurityControl(ctx, actor, app.CreateSecurityControlInput{ FrameworkID: req.FrameworkID, Code: req.Code, Title: req.Title, @@ -246,11 +249,11 @@ func (s *Server) linkControlEvidence(w http.ResponseWriter, r *http.Request) { Confidence string `json:"confidence"` Notes string `json:"notes"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - link, err := s.ledger.LinkControlEvidence(r.Context(), actor, r.PathValue("id"), app.LinkControlEvidenceInput{ + link, err := s.ledger.LinkControlEvidence(ctx, actor, r.PathValue("id"), app.LinkControlEvidenceInput{ EvidenceType: req.EvidenceType, SubjectType: req.SubjectType, SubjectID: req.SubjectID, @@ -278,11 +281,11 @@ func (s *Server) listControlEvidence(w http.ResponseWriter, r *http.Request) { func (s *Server) createProduct(w http.ResponseWriter, r *http.Request) { var req struct{ Name, Slug string } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - product, err := s.ledger.CreateProduct(r.Context(), actor, req.Name, req.Slug) + product, err := s.ledger.CreateProduct(ctx, actor, req.Name, req.Slug) return http.StatusCreated, product, err }) } @@ -305,11 +308,11 @@ func (s *Server) createProject(w http.ResponseWriter, r *http.Request) { ProductID string `json:"product_id"` Name string `json:"name"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - project, err := s.ledger.CreateProject(r.Context(), actor, req.ProductID, req.Name) + project, err := s.ledger.CreateProject(ctx, actor, req.ProductID, req.Name) return http.StatusCreated, project, err }) } @@ -319,11 +322,11 @@ func (s *Server) createRelease(w http.ResponseWriter, r *http.Request) { ProductID string `json:"product_id"` Version string `json:"version"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - release, err := s.ledger.CreateRelease(r.Context(), actor, req.ProductID, req.Version) + release, err := s.ledger.CreateRelease(ctx, actor, req.ProductID, req.Version) return http.StatusCreated, release, err }) } @@ -342,15 +345,15 @@ func (s *Server) getRelease(w http.ResponseWriter, r *http.Request) { } func (s *Server) freezeRelease(w http.ResponseWriter, r *http.Request) { - s.create(w, r, func(actor domain.Actor, _ []byte) (int, any, error) { - release, err := s.ledger.FreezeRelease(r.Context(), actor, r.PathValue("id")) + s.create(w, r, func(ctx requestContext, actor domain.Actor, _ []byte) (int, any, error) { + release, err := s.ledger.FreezeRelease(ctx, actor, r.PathValue("id")) return http.StatusOK, release, err }) } func (s *Server) approveRelease(w http.ResponseWriter, r *http.Request) { - s.create(w, r, func(actor domain.Actor, _ []byte) (int, any, error) { - release, err := s.ledger.ApproveRelease(r.Context(), actor, r.PathValue("id")) + s.create(w, r, func(ctx requestContext, actor domain.Actor, _ []byte) (int, any, error) { + release, err := s.ledger.ApproveRelease(ctx, actor, r.PathValue("id")) return http.StatusOK, release, err }) } @@ -367,11 +370,11 @@ func (s *Server) createReleaseCandidate(w http.ResponseWriter, r *http.Request) ContractIDs []string `json:"contract_ids"` BundleIDs []string `json:"bundle_ids"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - candidate, err := s.ledger.CreateReleaseCandidate(r.Context(), actor, app.CreateReleaseCandidateInput{ + candidate, err := s.ledger.CreateReleaseCandidate(ctx, actor, app.CreateReleaseCandidateInput{ ReleaseID: req.ReleaseID, Name: req.Name, BuildIDs: req.BuildIDs, ArtifactIDs: req.ArtifactIDs, SBOMIDs: req.SBOMIDs, ScanIDs: req.ScanIDs, VEXIDs: req.VEXIDs, ContractIDs: req.ContractIDs, BundleIDs: req.BundleIDs, }) @@ -417,11 +420,11 @@ func (s *Server) transitionReleaseCandidate(w http.ResponseWriter, r *http.Reque var req struct { Reason string `json:"reason"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - candidate, err := s.ledger.UpdateReleaseCandidateState(r.Context(), actor, r.PathValue("id"), state, req.Reason) + candidate, err := s.ledger.UpdateReleaseCandidateState(ctx, actor, r.PathValue("id"), state, req.Reason) return http.StatusOK, candidate, err }) } @@ -433,11 +436,11 @@ func (s *Server) registerArtifact(w http.ResponseWriter, r *http.Request) { Digest string `json:"digest"` Size int64 `json:"size"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - artifact, err := s.ledger.RegisterArtifact(r.Context(), actor, req.Name, req.MediaType, req.Digest, req.Size) + artifact, err := s.ledger.RegisterArtifact(ctx, actor, req.Name, req.MediaType, req.Digest, req.Size) return http.StatusCreated, artifact, err }) } @@ -450,11 +453,11 @@ func (s *Server) registerContainerImage(w http.ResponseWriter, r *http.Request) Digest string `json:"digest"` Platform string `json:"platform"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - image, err := s.ledger.RegisterContainerImage(r.Context(), actor, app.RegisterContainerImageInput{ + image, err := s.ledger.RegisterContainerImage(ctx, actor, app.RegisterContainerImageInput{ ArtifactID: req.ArtifactID, Repository: req.Repository, Tag: req.Tag, Digest: req.Digest, Platform: req.Platform, }) return http.StatusCreated, image, err @@ -470,11 +473,11 @@ func (s *Server) createArtifactSignature(w http.ResponseWriter, r *http.Request) Payload json.RawMessage `json:"payload"` PayloadMediaType string `json:"payload_media_type"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - sig, err := s.ledger.CreateArtifactSignature(r.Context(), actor, app.CreateArtifactSignatureInput{ + sig, err := s.ledger.CreateArtifactSignature(ctx, actor, app.CreateArtifactSignatureInput{ ArtifactID: req.ArtifactID, Algorithm: req.Algorithm, KeyID: req.KeyID, Signature: req.Signature, RawPayload: req.Payload, PayloadMediaType: req.PayloadMediaType, }) @@ -502,11 +505,11 @@ func (s *Server) verifyCosignSignature(w http.ResponseWriter, r *http.Request) { CertificateIdentity string `json:"certificate_identity"` CertificateIssuer string `json:"certificate_issuer"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - result, err := s.ledger.VerifyCosignSignature(r.Context(), actor, app.VerifyCosignInput{ + result, err := s.ledger.VerifyCosignSignature(ctx, actor, app.VerifyCosignInput{ ArtifactSignatureID: r.PathValue("id"), RekorUUID: req.RekorUUID, RekorLogIndex: req.RekorLogIndex, @@ -539,11 +542,11 @@ func (s *Server) createBuild(w http.ResponseWriter, r *http.Request) { ProviderMetadata map[string]any `json:"provider_metadata"` Outputs []domain.BuildOutput `json:"outputs"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - build, err := s.ledger.CreateBuildRun(r.Context(), actor, app.CreateBuildRunInput{ + build, err := s.ledger.CreateBuildRun(ctx, actor, app.CreateBuildRunInput{ ProjectID: req.ProjectID, ReleaseID: req.ReleaseID, Provider: req.Provider, @@ -582,15 +585,15 @@ func (s *Server) getBuild(w http.ResponseWriter, r *http.Request) { } func (s *Server) uploadBuildAttestation(w http.ResponseWriter, r *http.Request) { - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { - attestation, err := s.ledger.UploadBuildAttestation(r.Context(), actor, r.PathValue("id"), body) + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { + attestation, err := s.ledger.UploadBuildAttestation(ctx, actor, r.PathValue("id"), body) return http.StatusCreated, attestation, err }) } func (s *Server) verifyBuildAttestationSignature(w http.ResponseWriter, r *http.Request) { - s.create(w, r, func(actor domain.Actor, _ []byte) (int, any, error) { - result, err := s.ledger.VerifyDSSEAttestationSignature(r.Context(), actor, r.PathValue("id")) + s.create(w, r, func(ctx requestContext, actor domain.Actor, _ []byte) (int, any, error) { + result, err := s.ledger.VerifyDSSEAttestationSignature(ctx, actor, r.PathValue("id")) return http.StatusOK, result, err }) } @@ -602,11 +605,11 @@ func (s *Server) createDSSETrustRoot(w http.ResponseWriter, r *http.Request) { Algorithm string `json:"algorithm"` PublicKey string `json:"public_key"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - root, err := s.ledger.CreateDSSETrustRoot(r.Context(), actor, app.CreateDSSETrustRootInput{Name: req.Name, KeyID: req.KeyID, Algorithm: req.Algorithm, PublicKey: req.PublicKey}) + root, err := s.ledger.CreateDSSETrustRoot(ctx, actor, app.CreateDSSETrustRootInput{Name: req.Name, KeyID: req.KeyID, Algorithm: req.Algorithm, PublicKey: req.PublicKey}) return http.StatusCreated, root, err }) } @@ -619,11 +622,11 @@ func (s *Server) createSourceRepository(w http.ResponseWriter, r *http.Request) CloneURL string `json:"clone_url"` DefaultBranch string `json:"default_branch"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - repo, err := s.ledger.CreateSourceRepository(r.Context(), actor, app.CreateRepositoryInput{ + repo, err := s.ledger.CreateSourceRepository(ctx, actor, app.CreateRepositoryInput{ ProjectID: req.ProjectID, Provider: req.Provider, FullName: req.FullName, CloneURL: req.CloneURL, DefaultBranch: req.DefaultBranch, }) return http.StatusCreated, repo, err @@ -651,11 +654,11 @@ func (s *Server) recordSourceCommit(w http.ResponseWriter, r *http.Request) { Message string `json:"message"` CommittedAt time.Time `json:"committed_at"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - commit, err := s.ledger.RecordSourceCommit(r.Context(), actor, app.RecordCommitInput{ + commit, err := s.ledger.RecordSourceCommit(ctx, actor, app.RecordCommitInput{ RepositoryID: req.RepositoryID, SHA: req.SHA, Author: req.Author, Message: req.Message, CommittedAt: req.CommittedAt, }) return http.StatusCreated, commit, err @@ -670,11 +673,11 @@ func (s *Server) upsertSourceBranch(w http.ResponseWriter, r *http.Request) { Protected bool `json:"protected"` ProtectionHash string `json:"protection_hash"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - branch, err := s.ledger.UpsertSourceBranch(r.Context(), actor, app.UpsertBranchInput{ + branch, err := s.ledger.UpsertSourceBranch(ctx, actor, app.UpsertBranchInput{ RepositoryID: req.RepositoryID, Name: req.Name, HeadCommitID: req.HeadCommitID, Protected: req.Protected, ProtectionHash: req.ProtectionHash, }) return http.StatusCreated, branch, err @@ -693,11 +696,11 @@ func (s *Server) recordPullRequest(w http.ResponseWriter, r *http.Request) { HeadCommitID string `json:"head_commit_id"` ReviewDecision string `json:"review_decision"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - pr, err := s.ledger.RecordPullRequest(r.Context(), actor, app.RecordPullRequestInput{ + pr, err := s.ledger.RecordPullRequest(ctx, actor, app.RecordPullRequestInput{ RepositoryID: req.RepositoryID, Provider: req.Provider, ProviderID: req.ProviderID, Title: req.Title, State: req.State, SourceBranch: req.SourceBranch, TargetBranch: req.TargetBranch, HeadCommitID: req.HeadCommitID, ReviewDecision: req.ReviewDecision, }) @@ -706,15 +709,15 @@ func (s *Server) recordPullRequest(w http.ResponseWriter, r *http.Request) { } func (s *Server) uploadGitHubSourceSnapshot(w http.ResponseWriter, r *http.Request) { - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { - result, err := s.ledger.UploadGitHubSourceSnapshot(r.Context(), actor, body) + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { + result, err := s.ledger.UploadGitHubSourceSnapshot(ctx, actor, body) return http.StatusCreated, result, err }) } func (s *Server) uploadGitLabSourceSnapshot(w http.ResponseWriter, r *http.Request) { - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { - result, err := s.ledger.UploadGitLabSourceSnapshot(r.Context(), actor, body) + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { + result, err := s.ledger.UploadGitLabSourceSnapshot(ctx, actor, body) return http.StatusCreated, result, err }) } @@ -725,11 +728,11 @@ func (s *Server) createDeploymentEnvironment(w http.ResponseWriter, r *http.Requ Name string `json:"name"` Kind string `json:"kind"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - env, err := s.ledger.CreateDeploymentEnvironment(r.Context(), actor, app.CreateEnvironmentInput{ProductID: req.ProductID, Name: req.Name, Kind: req.Kind}) + env, err := s.ledger.CreateDeploymentEnvironment(ctx, actor, app.CreateEnvironmentInput{ProductID: req.ProductID, Name: req.Name, Kind: req.Kind}) return http.StatusCreated, env, err }) } @@ -757,11 +760,11 @@ func (s *Server) recordDeployment(w http.ResponseWriter, r *http.Request) { FinishedAt *time.Time `json:"finished_at"` RollbackOf string `json:"rollback_of"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - deployment, err := s.ledger.RecordDeployment(r.Context(), actor, app.RecordDeploymentInput{ + deployment, err := s.ledger.RecordDeployment(ctx, actor, app.RecordDeploymentInput{ EnvironmentID: req.EnvironmentID, ReleaseID: req.ReleaseID, ArtifactIDs: req.ArtifactIDs, Status: req.Status, StartedAt: req.StartedAt, FinishedAt: req.FinishedAt, RollbackOf: req.RollbackOf, }) @@ -803,11 +806,11 @@ func (s *Server) createIncident(w http.ResponseWriter, r *http.Request) { Severity string `json:"severity"` OpenedAt time.Time `json:"opened_at"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - incident, err := s.ledger.CreateIncident(r.Context(), actor, app.CreateIncidentInput{ProductID: req.ProductID, ReleaseID: req.ReleaseID, Title: req.Title, Severity: req.Severity, OpenedAt: req.OpenedAt}) + incident, err := s.ledger.CreateIncident(ctx, actor, app.CreateIncidentInput{ProductID: req.ProductID, ReleaseID: req.ReleaseID, Title: req.Title, Severity: req.Severity, OpenedAt: req.OpenedAt}) return http.StatusCreated, incident, err }) } @@ -819,11 +822,11 @@ func (s *Server) recordIncidentTimeline(w http.ResponseWriter, r *http.Request) EvidenceID string `json:"evidence_id"` OccurredAt time.Time `json:"occurred_at"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - event, err := s.ledger.RecordIncidentTimelineEvent(r.Context(), actor, r.PathValue("id"), app.RecordIncidentTimelineInput{EventType: req.EventType, Summary: req.Summary, EvidenceID: req.EvidenceID, OccurredAt: req.OccurredAt}) + event, err := s.ledger.RecordIncidentTimelineEvent(ctx, actor, r.PathValue("id"), app.RecordIncidentTimelineInput{EventType: req.EventType, Summary: req.Summary, EvidenceID: req.EvidenceID, OccurredAt: req.OccurredAt}) return http.StatusCreated, event, err }) } @@ -834,11 +837,11 @@ func (s *Server) createIncidentWebhookReceiver(w http.ResponseWriter, r *http.Re Provider string `json:"provider"` PublicKey string `json:"public_key"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - receiver, err := s.ledger.CreateIncidentWebhookReceiver(r.Context(), actor, app.CreateIncidentWebhookReceiverInput{IncidentID: r.PathValue("id"), Name: req.Name, Provider: req.Provider, PublicKey: req.PublicKey}) + receiver, err := s.ledger.CreateIncidentWebhookReceiver(ctx, actor, app.CreateIncidentWebhookReceiverInput{IncidentID: r.PathValue("id"), Name: req.Name, Provider: req.Provider, PublicKey: req.PublicKey}) return http.StatusCreated, receiver, err }) } @@ -877,11 +880,11 @@ func (s *Server) createRemediationTask(w http.ResponseWriter, r *http.Request) { DueAt *time.Time `json:"due_at"` EvidenceID string `json:"evidence_id"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - task, err := s.ledger.CreateRemediationTask(r.Context(), actor, app.CreateRemediationTaskInput{IncidentID: req.IncidentID, ReleaseID: req.ReleaseID, Title: req.Title, Owner: req.Owner, DueAt: req.DueAt, EvidenceID: req.EvidenceID}) + task, err := s.ledger.CreateRemediationTask(ctx, actor, app.CreateRemediationTaskInput{IncidentID: req.IncidentID, ReleaseID: req.ReleaseID, Title: req.Title, Owner: req.Owner, DueAt: req.DueAt, EvidenceID: req.EvidenceID}) return http.StatusCreated, task, err }) } @@ -910,11 +913,11 @@ func (s *Server) uploadSecurityScan(w http.ResponseWriter, r *http.Request) { TargetRef string `json:"target_ref"` Payload json.RawMessage `json:"payload"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - scan, err := s.ledger.UploadSecurityScan(r.Context(), actor, app.UploadSecurityScanInput{ProductID: req.ProductID, ReleaseID: req.ReleaseID, ArtifactID: req.ArtifactID, Category: req.Category, Format: req.Format, Scanner: req.Scanner, TargetRef: req.TargetRef, Raw: req.Payload}) + scan, err := s.ledger.UploadSecurityScan(ctx, actor, app.UploadSecurityScanInput{ProductID: req.ProductID, ReleaseID: req.ReleaseID, ArtifactID: req.ArtifactID, Category: req.Category, Format: req.Format, Scanner: req.Scanner, TargetRef: req.TargetRef, Raw: req.Payload}) return http.StatusCreated, scan, err }) } @@ -929,11 +932,11 @@ func (s *Server) uploadAPISecurityScan(w http.ResponseWriter, r *http.Request) { TargetRef string `json:"target_ref"` Payload json.RawMessage `json:"payload"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - scan, err := s.ledger.UploadAPISecurityScan(r.Context(), actor, app.UploadSecurityScanInput{ProductID: req.ProductID, ReleaseID: req.ReleaseID, ArtifactID: req.ArtifactID, Format: req.Format, Scanner: req.Scanner, TargetRef: req.TargetRef, Raw: req.Payload}) + scan, err := s.ledger.UploadAPISecurityScan(ctx, actor, app.UploadSecurityScanInput{ProductID: req.ProductID, ReleaseID: req.ReleaseID, ArtifactID: req.ArtifactID, Format: req.Format, Scanner: req.Scanner, TargetRef: req.TargetRef, Raw: req.Payload}) return http.StatusCreated, scan, err }) } @@ -948,11 +951,11 @@ func (s *Server) uploadManualSecurityDocument(w http.ResponseWriter, r *http.Req MediaType string `json:"media_type"` Payload json.RawMessage `json:"payload"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - doc, err := s.ledger.UploadManualSecurityDocument(r.Context(), actor, app.UploadManualSecurityDocumentInput{ProductID: req.ProductID, ReleaseID: req.ReleaseID, DocumentType: req.DocumentType, Title: req.Title, Sensitivity: req.Sensitivity, Raw: req.Payload, MediaType: req.MediaType}) + doc, err := s.ledger.UploadManualSecurityDocument(ctx, actor, app.UploadManualSecurityDocumentInput{ProductID: req.ProductID, ReleaseID: req.ReleaseID, DocumentType: req.DocumentType, Title: req.Title, Sensitivity: req.Sensitivity, Raw: req.Payload, MediaType: req.MediaType}) return http.StatusCreated, doc, err }) } @@ -969,18 +972,18 @@ func (s *Server) createWaiver(w http.ResponseWriter, r *http.Request) { ExpiresAt time.Time `json:"expires_at"` Supersedes string `json:"supersedes"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - waiver, err := s.ledger.CreateWaiver(r.Context(), actor, app.CreateWaiverInput{ScopeType: req.ScopeType, ScopeID: req.ScopeID, ControlID: req.ControlID, PolicyID: req.PolicyID, Owner: req.Owner, Risk: req.Risk, Reason: req.Reason, ExpiresAt: req.ExpiresAt, Supersedes: req.Supersedes}) + waiver, err := s.ledger.CreateWaiver(ctx, actor, app.CreateWaiverInput{ScopeType: req.ScopeType, ScopeID: req.ScopeID, ControlID: req.ControlID, PolicyID: req.PolicyID, Owner: req.Owner, Risk: req.Risk, Reason: req.Reason, ExpiresAt: req.ExpiresAt, Supersedes: req.Supersedes}) return http.StatusCreated, waiver, err }) } func (s *Server) approveWaiver(w http.ResponseWriter, r *http.Request) { - s.create(w, r, func(actor domain.Actor, _ []byte) (int, any, error) { - waiver, err := s.ledger.ApproveWaiver(r.Context(), actor, r.PathValue("id")) + s.create(w, r, func(ctx requestContext, actor domain.Actor, _ []byte) (int, any, error) { + waiver, err := s.ledger.ApproveWaiver(ctx, actor, r.PathValue("id")) return http.StatusOK, waiver, err }) } @@ -993,11 +996,11 @@ func (s *Server) createApproval(w http.ResponseWriter, r *http.Request) { Reason string `json:"reason"` EvidenceID string `json:"evidence_id"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - approval, err := s.ledger.CreateApprovalRecord(r.Context(), actor, app.CreateApprovalInput{SubjectType: req.SubjectType, SubjectID: req.SubjectID, Decision: req.Decision, Reason: req.Reason, EvidenceID: req.EvidenceID}) + approval, err := s.ledger.CreateApprovalRecord(ctx, actor, app.CreateApprovalInput{SubjectType: req.SubjectType, SubjectID: req.SubjectID, Decision: req.Decision, Reason: req.Reason, EvidenceID: req.EvidenceID}) return http.StatusCreated, approval, err }) } @@ -1009,11 +1012,11 @@ func (s *Server) createRedactionProfile(w http.ResponseWriter, r *http.Request) AllowedTypes []string `json:"allowed_types"` ExcludedFields []string `json:"excluded_fields"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - profile, err := s.ledger.CreateRedactionProfile(r.Context(), actor, app.CreateRedactionProfileInput{Name: req.Name, Description: req.Description, AllowedTypes: req.AllowedTypes, ExcludedFields: req.ExcludedFields}) + profile, err := s.ledger.CreateRedactionProfile(ctx, actor, app.CreateRedactionProfileInput{Name: req.Name, Description: req.Description, AllowedTypes: req.AllowedTypes, ExcludedFields: req.ExcludedFields}) return http.StatusCreated, profile, err }) } @@ -1026,11 +1029,11 @@ func (s *Server) createCustomerPackage(w http.ResponseWriter, r *http.Request) { Title string `json:"title"` ExpiresAt time.Time `json:"expires_at"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - pkg, err := s.ledger.CreateCustomerSecurityPackage(r.Context(), actor, app.CreateCustomerPackageInput{ProductID: req.ProductID, ReleaseID: req.ReleaseID, RedactionProfileID: req.RedactionProfileID, Title: req.Title, ExpiresAt: req.ExpiresAt}) + pkg, err := s.ledger.CreateCustomerSecurityPackage(ctx, actor, app.CreateCustomerPackageInput{ProductID: req.ProductID, ReleaseID: req.ReleaseID, RedactionProfileID: req.RedactionProfileID, Title: req.Title, ExpiresAt: req.ExpiresAt}) return http.StatusCreated, pkg, err }) } @@ -1095,11 +1098,11 @@ func (s *Server) createReportTemplate(w http.ResponseWriter, r *http.Request) { AllowedFields []string `json:"allowed_fields"` Template string `json:"template"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - tpl, err := s.ledger.CreateCustomReportTemplate(r.Context(), actor, app.CreateReportTemplateInput{Name: req.Name, Version: req.Version, ReportType: req.ReportType, AllowedFields: req.AllowedFields, Template: req.Template}) + tpl, err := s.ledger.CreateCustomReportTemplate(ctx, actor, app.CreateReportTemplateInput{Name: req.Name, Version: req.Version, ReportType: req.ReportType, AllowedFields: req.AllowedFields, Template: req.Template}) return http.StatusCreated, tpl, err }) } @@ -1109,11 +1112,11 @@ func (s *Server) renderReportTemplate(w http.ResponseWriter, r *http.Request) { SubjectType string `json:"subject_type"` SubjectID string `json:"subject_id"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - report, err := s.ledger.RenderCustomReport(r.Context(), actor, app.RenderReportInput{TemplateID: r.PathValue("id"), SubjectType: req.SubjectType, SubjectID: req.SubjectID}) + report, err := s.ledger.RenderCustomReport(ctx, actor, app.RenderReportInput{TemplateID: r.PathValue("id"), SubjectType: req.SubjectType, SubjectID: req.SubjectID}) return http.StatusCreated, report, err }) } @@ -1123,22 +1126,22 @@ func (s *Server) exportEvidenceBundle(w http.ResponseWriter, r *http.Request) { ReleaseID string `json:"release_id"` EvidenceIDs []string `json:"evidence_ids"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - bundle, err := s.ledger.ExportEvidenceBundle(r.Context(), actor, req.ReleaseID, req.EvidenceIDs) + bundle, err := s.ledger.ExportEvidenceBundle(ctx, actor, req.ReleaseID, req.EvidenceIDs) return http.StatusCreated, bundle, err }) } func (s *Server) importEvidenceBundle(w http.ResponseWriter, r *http.Request) { var req domain.EvidenceBundle - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - record, err := s.ledger.ImportEvidenceBundle(r.Context(), actor, req) + record, err := s.ledger.ImportEvidenceBundle(ctx, actor, req) return http.StatusCreated, record, err }) } @@ -1149,11 +1152,11 @@ func (s *Server) uploadSPDXSBOM(w http.ResponseWriter, r *http.Request) { ArtifactID string `json:"artifact_id"` Payload json.RawMessage `json:"payload"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - sbom, err := s.ledger.UploadSPDXSBOM(r.Context(), actor, req.ReleaseID, req.ArtifactID, req.Payload) + sbom, err := s.ledger.UploadSPDXSBOM(ctx, actor, req.ReleaseID, req.ArtifactID, req.Payload) return http.StatusCreated, sbom, err }) } @@ -1164,11 +1167,11 @@ func (s *Server) createSBOMDiff(w http.ResponseWriter, r *http.Request) { TargetSBOMID string `json:"target_sbom_id"` ReleaseID string `json:"release_id"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - diff, err := s.ledger.CreateSBOMDiff(r.Context(), actor, app.CreateSBOMDiffInput{BaseSBOMID: req.BaseSBOMID, TargetSBOMID: req.TargetSBOMID, ReleaseID: req.ReleaseID}) + diff, err := s.ledger.CreateSBOMDiff(ctx, actor, app.CreateSBOMDiffInput{BaseSBOMID: req.BaseSBOMID, TargetSBOMID: req.TargetSBOMID, ReleaseID: req.ReleaseID}) return http.StatusCreated, diff, err }) } @@ -1194,11 +1197,11 @@ func (s *Server) createEvidence(w http.ResponseWriter, r *http.Request) { Tags []string `json:"tags"` Limitations []string `json:"limitations"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - item, err := s.ledger.CreateEvidence(r.Context(), actor, app.CreateEvidenceInput{ + item, err := s.ledger.CreateEvidence(ctx, actor, app.CreateEvidenceInput{ ProductID: req.ProductID, ProjectID: req.ProjectID, ReleaseID: req.ReleaseID, Type: req.Type, Subtype: req.Subtype, Title: req.Title, SourceSystem: req.SourceSystem, SourceIdentity: req.SourceIdentity, CollectorID: req.CollectorID, ObservedAt: req.ObservedAt, PayloadRef: req.PayloadRef, PayloadHash: req.PayloadHash, PayloadMediaType: req.PayloadMediaType, PayloadSize: req.PayloadSize, @@ -1289,11 +1292,11 @@ func (s *Server) supersedeEvidence(w http.ResponseWriter, r *http.Request) { ReplacementEvidenceID string `json:"replacement_evidence_id"` Reason string `json:"reason"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - item, err := s.ledger.SupersedeEvidence(r.Context(), actor, r.PathValue("id"), req.ReplacementEvidenceID, req.Reason) + item, err := s.ledger.SupersedeEvidence(ctx, actor, r.PathValue("id"), req.ReplacementEvidenceID, req.Reason) return http.StatusCreated, item, err }) } @@ -1303,11 +1306,11 @@ func (s *Server) linkEvidence(w http.ResponseWriter, r *http.Request) { TargetType string `json:"target_type"` TargetID string `json:"target_id"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - item, err := s.ledger.LinkEvidence(r.Context(), actor, r.PathValue("id"), req.TargetType, req.TargetID) + item, err := s.ledger.LinkEvidence(ctx, actor, r.PathValue("id"), req.TargetType, req.TargetID) return http.StatusCreated, item, err }) } @@ -1319,11 +1322,11 @@ func (s *Server) recordEvidenceLifecycleEvent(w http.ResponseWriter, r *http.Req Details map[string]any `json:"details"` ReplacementID string `json:"replacement_id"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - event, err := s.ledger.RecordEvidenceLifecycleEvent(r.Context(), actor, r.PathValue("id"), app.RecordEvidenceLifecycleInput{ + event, err := s.ledger.RecordEvidenceLifecycleEvent(ctx, actor, r.PathValue("id"), app.RecordEvidenceLifecycleInput{ Action: req.Action, Reason: req.Reason, Details: req.Details, ReplacementID: req.ReplacementID, }) return http.StatusCreated, event, err @@ -1349,11 +1352,11 @@ func (s *Server) uploadSBOM(w http.ResponseWriter, r *http.Request) { ArtifactID string `json:"artifact_id"` Payload json.RawMessage `json:"payload"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - sbom, err := s.ledger.UploadSBOM(r.Context(), actor, req.ReleaseID, req.ArtifactID, req.Payload) + sbom, err := s.ledger.UploadSBOM(ctx, actor, req.ReleaseID, req.ArtifactID, req.Payload) return http.StatusCreated, sbom, err }) } @@ -1407,11 +1410,11 @@ func (s *Server) uploadVEX(w http.ResponseWriter, r *http.Request) { ArtifactID string `json:"artifact_id"` Payload json.RawMessage `json:"payload"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - vex, err := s.ledger.UploadVEX(r.Context(), actor, req.ReleaseID, req.ArtifactID, req.Payload) + vex, err := s.ledger.UploadVEX(ctx, actor, req.ReleaseID, req.ArtifactID, req.Payload) return http.StatusCreated, vex, err }) } @@ -1435,18 +1438,18 @@ func (s *Server) uploadCycloneDXVEX(w http.ResponseWriter, r *http.Request) { ArtifactID string `json:"artifact_id"` Payload json.RawMessage `json:"payload"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - vex, err := s.ledger.UploadCycloneDXVEX(r.Context(), actor, req.ReleaseID, req.ArtifactID, req.Payload) + vex, err := s.ledger.UploadCycloneDXVEX(ctx, actor, req.ReleaseID, req.ArtifactID, req.Payload) return http.StatusCreated, vex, err }) } func (s *Server) uploadVulnerabilityScan(w http.ResponseWriter, r *http.Request) { - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { - scan, err := s.ledger.UploadVulnerabilityScan(r.Context(), actor, body) + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { + scan, err := s.ledger.UploadVulnerabilityScan(ctx, actor, body) return http.StatusCreated, scan, err }) } @@ -1471,11 +1474,11 @@ func (s *Server) createVulnerabilityDecision(w http.ResponseWriter, r *http.Requ ImpactStatement string `json:"impact_statement"` ActionStatement string `json:"action_statement"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - decision, err := s.ledger.CreateVulnerabilityDecision(r.Context(), actor, r.PathValue("id"), app.CreateVulnerabilityDecisionInput{ + decision, err := s.ledger.CreateVulnerabilityDecision(ctx, actor, r.PathValue("id"), app.CreateVulnerabilityDecisionInput{ Status: req.Status, Justification: req.Justification, ImpactStatement: req.ImpactStatement, @@ -1490,11 +1493,11 @@ func (s *Server) recordVulnerabilityWorkflow(w http.ResponseWriter, r *http.Requ Action string `json:"action"` Reason string `json:"reason"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - record, err := s.ledger.RecordVulnerabilityWorkflow(r.Context(), actor, app.RecordVulnerabilityWorkflowInput{FindingID: r.PathValue("id"), Action: req.Action, Reason: req.Reason}) + record, err := s.ledger.RecordVulnerabilityWorkflow(ctx, actor, app.RecordVulnerabilityWorkflowInput{FindingID: r.PathValue("id"), Action: req.Action, Reason: req.Reason}) return http.StatusCreated, record, err }) } @@ -1519,11 +1522,11 @@ func (s *Server) uploadOpenAPIContract(w http.ResponseWriter, r *http.Request) { Version string `json:"version"` Spec json.RawMessage `json:"spec"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - contract, err := s.ledger.UploadOpenAPIContract(r.Context(), actor, req.ProductID, req.ReleaseID, req.Version, req.Spec) + contract, err := s.ledger.UploadOpenAPIContract(ctx, actor, req.ProductID, req.ReleaseID, req.Version, req.Spec) return http.StatusCreated, contract, err }) } @@ -1547,11 +1550,11 @@ func (s *Server) createOpenAPIDiff(w http.ResponseWriter, r *http.Request) { TargetContractID string `json:"target_contract_id"` ReleaseID string `json:"release_id"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - diff, err := s.ledger.CreateContractDiff(r.Context(), actor, app.CreateContractDiffInput{BaseContractID: req.BaseContractID, TargetContractID: req.TargetContractID, ReleaseID: req.ReleaseID}) + diff, err := s.ledger.CreateContractDiff(ctx, actor, app.CreateContractDiffInput{BaseContractID: req.BaseContractID, TargetContractID: req.TargetContractID, ReleaseID: req.ReleaseID}) return http.StatusCreated, diff, err }) } @@ -1560,11 +1563,11 @@ func (s *Server) evaluatePolicy(w http.ResponseWriter, r *http.Request) { var req struct { ReleaseID string `json:"release_id"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - eval, err := s.ledger.EvaluateRelease(r.Context(), actor, req.ReleaseID) + eval, err := s.ledger.EvaluateRelease(ctx, actor, req.ReleaseID) return http.StatusCreated, eval, err }) } @@ -1576,11 +1579,11 @@ func (s *Server) createCustomPolicy(w http.ResponseWriter, r *http.Request) { Description string `json:"description"` Rules []domain.PolicyRule `json:"rules"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - policy, err := s.ledger.CreateCustomPolicy(r.Context(), actor, app.CreateCustomPolicyInput{Name: req.Name, Version: req.Version, Description: req.Description, Rules: req.Rules}) + policy, err := s.ledger.CreateCustomPolicy(ctx, actor, app.CreateCustomPolicyInput{Name: req.Name, Version: req.Version, Description: req.Description, Rules: req.Rules}) return http.StatusCreated, policy, err }) } @@ -1589,11 +1592,11 @@ func (s *Server) evaluateCustomPolicy(w http.ResponseWriter, r *http.Request) { var req struct { ReleaseID string `json:"release_id"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - eval, err := s.ledger.EvaluateCustomPolicy(r.Context(), actor, r.PathValue("id"), req.ReleaseID) + eval, err := s.ledger.EvaluateCustomPolicy(ctx, actor, r.PathValue("id"), req.ReleaseID) return http.StatusCreated, eval, err }) } @@ -1620,11 +1623,11 @@ func (s *Server) createException(w http.ResponseWriter, r *http.Request) { Owner string `json:"owner"` ExpiresAt time.Time `json:"expires_at"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - exception, err := s.ledger.CreateException(r.Context(), actor, app.CreateExceptionInput{ + exception, err := s.ledger.CreateException(ctx, actor, app.CreateExceptionInput{ ReleaseID: req.ReleaseID, FindingID: req.FindingID, ControlID: req.ControlID, @@ -1650,8 +1653,8 @@ func (s *Server) listExceptions(w http.ResponseWriter, r *http.Request) { } func (s *Server) approveException(w http.ResponseWriter, r *http.Request) { - s.create(w, r, func(actor domain.Actor, _ []byte) (int, any, error) { - exception, err := s.ledger.ApproveException(r.Context(), actor, r.PathValue("id")) + s.create(w, r, func(ctx requestContext, actor domain.Actor, _ []byte) (int, any, error) { + exception, err := s.ledger.ApproveException(ctx, actor, r.PathValue("id")) return http.StatusOK, exception, err }) } @@ -1706,11 +1709,11 @@ func (s *Server) createReleaseBundle(w http.ResponseWriter, r *http.Request) { var req struct { ReleaseID string `json:"release_id"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - bundle, err := s.ledger.CreateReleaseBundle(r.Context(), actor, req.ReleaseID) + bundle, err := s.ledger.CreateReleaseBundle(ctx, actor, req.ReleaseID) return http.StatusCreated, bundle, err }) } @@ -1808,11 +1811,11 @@ func (s *Server) createMerkleBatch(w http.ResponseWriter, r *http.Request) { FromSequence int64 `json:"from_sequence"` ToSequence int64 `json:"to_sequence"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - batch, err := s.ledger.CreateMerkleBatch(r.Context(), actor, app.CreateMerkleBatchInput{FromSequence: req.FromSequence, ToSequence: req.ToSequence}) + batch, err := s.ledger.CreateMerkleBatch(ctx, actor, app.CreateMerkleBatchInput{FromSequence: req.FromSequence, ToSequence: req.ToSequence}) return http.StatusCreated, batch, err }) } @@ -1837,11 +1840,11 @@ func (s *Server) createTransparencyCheckpoint(w http.ResponseWriter, r *http.Req ExternalURL string `json:"external_url"` ExternalID string `json:"external_id"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - checkpoint, err := s.ledger.CreateTransparencyCheckpoint(r.Context(), actor, app.CreateTransparencyCheckpointInput{BatchID: req.BatchID, Provider: req.Provider, ExternalURL: req.ExternalURL, ExternalID: req.ExternalID}) + checkpoint, err := s.ledger.CreateTransparencyCheckpoint(ctx, actor, app.CreateTransparencyCheckpointInput{BatchID: req.BatchID, Provider: req.Provider, ExternalURL: req.ExternalURL, ExternalID: req.ExternalID}) return http.StatusCreated, checkpoint, err }) } @@ -1853,25 +1856,25 @@ func (s *Server) createObjectRetentionPolicy(w http.ResponseWriter, r *http.Requ Mode string `json:"mode"` RetentionDays int `json:"retention_days"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - policy, err := s.ledger.CreateObjectRetentionPolicy(r.Context(), actor, app.CreateObjectRetentionPolicyInput{Name: req.Name, ObjectPrefix: req.ObjectPrefix, Mode: req.Mode, RetentionDays: req.RetentionDays}) + policy, err := s.ledger.CreateObjectRetentionPolicy(ctx, actor, app.CreateObjectRetentionPolicyInput{Name: req.Name, ObjectPrefix: req.ObjectPrefix, Mode: req.Mode, RetentionDays: req.RetentionDays}) return http.StatusCreated, policy, err }) } func (s *Server) verifyObjectRetentionPolicy(w http.ResponseWriter, r *http.Request) { - s.create(w, r, func(actor domain.Actor, _ []byte) (int, any, error) { - policy, err := s.ledger.VerifyObjectRetentionPolicy(r.Context(), actor, r.PathValue("id")) + s.create(w, r, func(ctx requestContext, actor domain.Actor, _ []byte) (int, any, error) { + policy, err := s.ledger.VerifyObjectRetentionPolicy(ctx, actor, r.PathValue("id")) return http.StatusOK, policy, err }) } func (s *Server) generateBackupManifest(w http.ResponseWriter, r *http.Request) { - s.create(w, r, func(actor domain.Actor, _ []byte) (int, any, error) { - manifest, err := s.ledger.GenerateBackupManifest(r.Context(), actor) + s.create(w, r, func(ctx requestContext, actor domain.Actor, _ []byte) (int, any, error) { + manifest, err := s.ledger.GenerateBackupManifest(ctx, actor) return http.StatusCreated, manifest, err }) } @@ -1906,13 +1909,13 @@ func (s *Server) rotateSigningKey(w http.ResponseWriter, r *http.Request) { var req struct { Reason string `json:"reason"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if len(bytes.TrimSpace(body)) > 0 { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } } - key, err := s.ledger.RotateSigningKey(r.Context(), actor, req.Reason) + key, err := s.ledger.RotateSigningKey(ctx, actor, req.Reason) return http.StatusCreated, key, err }) } @@ -1921,13 +1924,13 @@ func (s *Server) revokeSigningKey(w http.ResponseWriter, r *http.Request) { var req struct { Reason string `json:"reason"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if len(bytes.TrimSpace(body)) > 0 { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } } - key, err := s.ledger.RevokeSigningKey(r.Context(), actor, r.PathValue("id"), req.Reason) + key, err := s.ledger.RevokeSigningKey(ctx, actor, r.PathValue("id"), req.Reason) return http.StatusOK, key, err }) } @@ -1939,11 +1942,11 @@ func (s *Server) createSigningProvider(w http.ResponseWriter, r *http.Request) { KeyRef string `json:"key_ref"` Encrypted bool `json:"encrypted"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - provider, err := s.ledger.CreateSigningProvider(r.Context(), actor, app.CreateSigningProviderInput{Name: req.Name, Type: req.Type, KeyRef: req.KeyRef, Encrypted: req.Encrypted}) + provider, err := s.ledger.CreateSigningProvider(ctx, actor, app.CreateSigningProviderInput{Name: req.Name, Type: req.Type, KeyRef: req.KeyRef, Encrypted: req.Encrypted}) return http.StatusCreated, provider, err }) } @@ -1956,11 +1959,11 @@ func (s *Server) createCommercialCollector(w http.ResponseWriter, r *http.Reques ManifestHash string `json:"manifest_hash"` AllowedScopes []string `json:"allowed_scopes"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - definition, err := s.ledger.CreateCommercialCollectorDefinition(r.Context(), actor, app.CreateCommercialCollectorInput{ + definition, err := s.ledger.CreateCommercialCollectorDefinition(ctx, actor, app.CreateCommercialCollectorInput{ Name: req.Name, Provider: req.Provider, Version: req.Version, @@ -1989,11 +1992,11 @@ func (s *Server) verifySubject(w http.ResponseWriter, r *http.Request) { SubjectType string `json:"subject_type"` SubjectID string `json:"subject_id"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - result, err := s.ledger.VerifySubject(r.Context(), actor, req.SubjectType, req.SubjectID) + result, err := s.ledger.VerifySubject(ctx, actor, req.SubjectType, req.SubjectID) return http.StatusOK, result, err }) } @@ -2004,11 +2007,11 @@ func (s *Server) createAPIKey(w http.ResponseWriter, r *http.Request) { Scopes []string `json:"scopes"` ExpiresAt *time.Time `json:"expires_at"` } - s.create(w, r, func(actor domain.Actor, body []byte) (int, any, error) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - key, secret, err := s.ledger.CreateAPIKey(r.Context(), actor, req.Name, req.Scopes, req.ExpiresAt) + key, secret, err := s.ledger.CreateAPIKey(ctx, actor, req.Name, req.Scopes, req.ExpiresAt) return http.StatusCreated, map[string]any{"api_key": key, "secret": secret}, err }) } @@ -2026,18 +2029,19 @@ func (s *Server) listAPIKeys(w http.ResponseWriter, r *http.Request) { writeData(w, http.StatusOK, keys) } -func (s *Server) create(w http.ResponseWriter, r *http.Request, run func(domain.Actor, []byte) (int, any, error)) { +func (s *Server) create(w http.ResponseWriter, r *http.Request, run func(requestContext, domain.Actor, []byte) (int, any, error)) { actor, ok := s.authenticate(w, r) if !ok { return } + ctx := r.Context() body, err := readBody(r) if err != nil { writeProblem(w, r, err) return } - status, response, err := s.ledger.WithIdempotency(r.Context(), actor, r.Method, r.URL.Path, r.Header.Get("Idempotency-Key"), body, func() (int, any, error) { - return run(actor, body) + status, response, err := s.ledger.WithIdempotency(ctx, actor, r.Method, r.URL.Path, r.Header.Get("Idempotency-Key"), body, func() (int, any, error) { + return run(ctx, actor, body) }) if err != nil { writeProblem(w, r, err) @@ -2308,6 +2312,7 @@ func defaultSuccessStatus(operationID, method string) int { case "deactivateUser", "logoutSSOSession", "revokeSSOSession", + "refreshSSOProviderOIDCTrustMaterial", "updateSSOProviderTrustMaterial", "freezeRelease", "approveRelease", diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 5dd6aeb..0110526 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -2,6 +2,7 @@ package httpapi import ( "bytes" + "context" "crypto/ed25519" "crypto/rand" "encoding/base64" @@ -170,6 +171,9 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { updateProviderTrust := operationMap(t, paths, "/v1/sso/providers/{id}/trust-material", "post") assertRequestRef(t, updateProviderTrust, "#/components/schemas/UpdateSSOProviderTrustMaterialRequest") assertResponseRef(t, updateProviderTrust, "200", "#/components/schemas/SSOProviderEnvelope") + refreshProviderTrust := operationMap(t, paths, "/v1/sso/providers/{id}/discover-oidc", "post") + assertRequestRef(t, refreshProviderTrust, "#/components/schemas/EmptyObject") + assertResponseRef(t, refreshProviderTrust, "200", "#/components/schemas/SSOProviderEnvelope") verifyProvider := operationMap(t, paths, "/v1/provider-verifications", "post") assertRequestRef(t, verifyProvider, "#/components/schemas/VerifyProviderIdentityRequest") assertResponseRef(t, verifyProvider, "201", "#/components/schemas/ProviderVerificationEnvelope") @@ -182,6 +186,35 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { } } +func TestSSOProviderOIDCDiscoveryRefreshRoute(t *testing.T) { + pub, _, err := ed25519.GenerateKey(rand.Reader) + if err != nil { + t.Fatalf("keygen: %v", err) + } + discovery := &fakeOIDCDiscoveryHTTP{result: app.OIDCDiscoveryResult{ + Issuer: "https://idp.example.test", + JWKS: map[string]any{"keys": []any{map[string]any{"kty": "OKP", "crv": "Ed25519", "kid": "kid-route", "x": base64.RawURLEncoding.EncodeToString(pub)}}}, + }} + ledger := app.NewLedger(app.Config{APIKeyPepper: "test", OIDC: discovery}) + _, _, secret, err := ledger.BootstrapTenant(t.Context(), "Tenant", "admin", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap: %v", err) + } + server, err := NewServer(ledger) + if err != nil { + t.Fatalf("server: %v", err) + } + body := postJSON(t, server, secret, "/v1/sso/providers", "sso-discovery-provider", map[string]any{"name": "OIDC", "type": "oidc", "issuer": "https://idp.example.test", "client_id": "client"}, http.StatusCreated) + providerID := dataField(t, body, "id") + refreshed := postJSON(t, server, secret, "/v1/sso/providers/"+providerID+"/discover-oidc", "sso-discovery-refresh", map[string]any{}, http.StatusOK) + if !strings.Contains(refreshed, `"trust_material_updated_at"`) || !strings.Contains(refreshed, `"kid-route"`) { + t.Fatalf("refreshed response missing public trust material: %s", refreshed) + } + if discovery.request.ProviderID != providerID || discovery.request.Issuer != "https://idp.example.test" { + t.Fatalf("discovery request = %#v", discovery.request) + } +} + func TestOpenAPIDoesNotAdvertiseImpossibleSuccessStatusCodes(t *testing.T) { server, _ := testServer(t) docBytes, err := server.OpenAPI() @@ -1178,6 +1211,20 @@ func testServer(t *testing.T) (*Server, string) { return server, secret } +type fakeOIDCDiscoveryHTTP struct { + request app.OIDCDiscoveryRequest + result app.OIDCDiscoveryResult + err error +} + +func (f *fakeOIDCDiscoveryHTTP) FetchOIDCTrustMaterial(_ context.Context, req app.OIDCDiscoveryRequest) (app.OIDCDiscoveryResult, error) { + f.request = req + if f.err != nil { + return app.OIDCDiscoveryResult{}, f.err + } + return f.result, nil +} + func postJSON(t *testing.T, server *Server, secret, path, idem string, payload any, want int) string { t.Helper() body, err := json.Marshal(payload) diff --git a/internal/adapters/identity/oidcdiscovery/oidcdiscovery.go b/internal/adapters/identity/oidcdiscovery/oidcdiscovery.go new file mode 100644 index 0000000..8b4f6ab --- /dev/null +++ b/internal/adapters/identity/oidcdiscovery/oidcdiscovery.go @@ -0,0 +1,144 @@ +package oidcdiscovery + +import ( + "context" + "encoding/json" + "errors" + "io" + "net" + "net/http" + "net/url" + "strings" + "time" + + "github.com/aatuh/evydence/internal/app" + "github.com/aatuh/evydence/internal/domain" +) + +const ( + defaultTimeout = 10 * time.Second + maxDiscoveryBodySize = 256 * 1024 + maxJWKSBodySize = 256 * 1024 +) + +type Config struct { + Timeout time.Duration + AllowInsecureForLocalhost bool + Client *http.Client +} + +type Client struct { + httpClient *http.Client + allowInsecureForLocalhost bool +} + +type discoveryDocument struct { + Issuer string `json:"issuer"` + JWKSURI string `json:"jwks_uri"` +} + +func New(cfg Config) *Client { + timeout := cfg.Timeout + if timeout <= 0 { + timeout = defaultTimeout + } + httpClient := cfg.Client + if httpClient == nil { + httpClient = &http.Client{ + Timeout: timeout, + CheckRedirect: func(_ *http.Request, _ []*http.Request) error { + return http.ErrUseLastResponse + }, + } + } + return &Client{httpClient: httpClient, allowInsecureForLocalhost: cfg.AllowInsecureForLocalhost} +} + +func (c *Client) FetchOIDCTrustMaterial(ctx context.Context, req app.OIDCDiscoveryRequest) (app.OIDCDiscoveryResult, error) { + if c == nil || c.httpClient == nil { + return app.OIDCDiscoveryResult{}, app.ErrValidation + } + issuer := strings.TrimRight(strings.TrimSpace(req.Issuer), "/") + issuerURL, err := parseProviderURL(issuer, c.allowInsecureForLocalhost) + if err != nil { + return app.OIDCDiscoveryResult{}, err + } + discoveryURL := *issuerURL + discoveryURL.Path = strings.TrimRight(discoveryURL.Path, "/") + "/.well-known/openid-configuration" + discoveryURL.RawQuery = "" + discoveryURL.Fragment = "" + + var doc discoveryDocument + if err := c.getJSON(ctx, discoveryURL.String(), maxDiscoveryBodySize, &doc); err != nil { + return app.OIDCDiscoveryResult{}, err + } + doc.Issuer = strings.TrimRight(strings.TrimSpace(doc.Issuer), "/") + doc.JWKSURI = strings.TrimSpace(doc.JWKSURI) + if doc.Issuer != issuer || doc.JWKSURI == "" { + return app.OIDCDiscoveryResult{}, app.ErrVerificationFailed + } + jwksURL, err := parseProviderURL(doc.JWKSURI, c.allowInsecureForLocalhost) + if err != nil { + return app.OIDCDiscoveryResult{}, err + } + var jwks map[string]any + if err := c.getJSON(ctx, jwksURL.String(), maxJWKSBodySize, &jwks); err != nil { + return app.OIDCDiscoveryResult{}, err + } + return app.OIDCDiscoveryResult{ + Issuer: doc.Issuer, + JWKS: jwks, + Checks: []domain.VerifyCheck{ + {Name: "oidc_discovery_document", Result: "passed"}, + {Name: "oidc_jwks_fetch", Result: "passed"}, + }, + Limitations: []string{"OIDC discovery refreshes public JWKS trust material only; it does not authenticate users or synchronize provider groups."}, + }, nil +} + +func (c *Client) getJSON(ctx context.Context, endpoint string, maxBytes int64, out any) error { + httpReq, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil) + if err != nil { + return app.ErrValidation + } + httpReq.Header.Set("Accept", "application/json") + resp, err := c.httpClient.Do(httpReq) + if err != nil { + return errors.New("fetch oidc metadata") + } + defer resp.Body.Close() + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + _, _ = io.Copy(io.Discard, io.LimitReader(resp.Body, 4096)) + return app.ErrVerificationFailed + } + decoder := json.NewDecoder(io.LimitReader(resp.Body, maxBytes+1)) + if err := decoder.Decode(out); err != nil { + return app.ErrVerificationFailed + } + if decoder.InputOffset() > maxBytes { + return app.ErrVerificationFailed + } + return nil +} + +func parseProviderURL(raw string, allowInsecureLocalhost bool) (*url.URL, error) { + parsed, err := url.Parse(strings.TrimSpace(raw)) + if err != nil || parsed.Scheme == "" || parsed.Host == "" || parsed.User != nil { + return nil, app.ErrValidation + } + if parsed.Scheme == "https" { + return parsed, nil + } + if parsed.Scheme == "http" && allowInsecureLocalhost && localhostHost(parsed.Hostname()) { + return parsed, nil + } + return nil, app.ErrValidation +} + +func localhostHost(host string) bool { + if strings.EqualFold(host, "localhost") { + return true + } + ip := net.ParseIP(host) + return ip != nil && ip.IsLoopback() +} diff --git a/internal/adapters/identity/oidcdiscovery/oidcdiscovery_test.go b/internal/adapters/identity/oidcdiscovery/oidcdiscovery_test.go new file mode 100644 index 0000000..aec7e95 --- /dev/null +++ b/internal/adapters/identity/oidcdiscovery/oidcdiscovery_test.go @@ -0,0 +1,73 @@ +package oidcdiscovery + +import ( + "encoding/base64" + "encoding/json" + "net/http" + "net/http/httptest" + "strings" + "testing" + + "github.com/aatuh/evydence/internal/app" +) + +func TestFetchOIDCTrustMaterialFetchesDiscoveryAndJWKS(t *testing.T) { + jwks := map[string]any{"keys": []any{map[string]any{"kty": "OKP", "crv": "Ed25519", "kid": "kid-1", "x": base64.RawURLEncoding.EncodeToString([]byte("public-key"))}}} + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case "/issuer/.well-known/openid-configuration": + _ = json.NewEncoder(w).Encode(map[string]any{"issuer": "http://" + r.Host + "/issuer", "jwks_uri": "http://" + r.Host + "/keys"}) + case "/keys": + _ = json.NewEncoder(w).Encode(jwks) + default: + http.NotFound(w, r) + } + })) + defer server.Close() + + client := New(Config{AllowInsecureForLocalhost: true}) + result, err := client.FetchOIDCTrustMaterial(t.Context(), app.OIDCDiscoveryRequest{TenantID: "ten_1", ProviderID: "sso_1", Issuer: server.URL + "/issuer"}) + if err != nil { + t.Fatalf("FetchOIDCTrustMaterial: %v", err) + } + if result.Issuer != server.URL+"/issuer" || len(result.JWKS) == 0 || len(result.Checks) != 2 { + t.Fatalf("result = %#v", result) + } +} + +func TestFetchOIDCTrustMaterialRejectsMismatchedIssuer(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + _ = json.NewEncoder(w).Encode(map[string]any{"issuer": "http://localhost/other", "jwks_uri": "http://localhost/keys"}) + })) + defer server.Close() + + client := New(Config{AllowInsecureForLocalhost: true}) + if _, err := client.FetchOIDCTrustMaterial(t.Context(), app.OIDCDiscoveryRequest{Issuer: server.URL}); err == nil { + t.Fatal("FetchOIDCTrustMaterial err=nil, want error") + } +} + +func TestFetchOIDCTrustMaterialRequiresHTTPSUnlessLocalAllowed(t *testing.T) { + client := New(Config{}) + if _, err := client.FetchOIDCTrustMaterial(t.Context(), app.OIDCDiscoveryRequest{Issuer: "http://127.0.0.1:8080/issuer"}); err == nil { + t.Fatal("FetchOIDCTrustMaterial err=nil, want insecure issuer rejection") + } +} + +func TestFetchOIDCTrustMaterialDoesNotReturnRawProviderBodies(t *testing.T) { + secretBody := `{"issuer":"bad","jwks_uri":"token-secret-value"}` + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(http.StatusInternalServerError) + _, _ = w.Write([]byte(secretBody)) + })) + defer server.Close() + + client := New(Config{AllowInsecureForLocalhost: true}) + _, err := client.FetchOIDCTrustMaterial(t.Context(), app.OIDCDiscoveryRequest{Issuer: server.URL}) + if err == nil { + t.Fatal("FetchOIDCTrustMaterial err=nil, want error") + } + if strings.Contains(err.Error(), "token-secret-value") { + t.Fatalf("error leaked provider body: %v", err) + } +} diff --git a/internal/app/enterprise.go b/internal/app/enterprise.go index 749a37e..8ae4401 100644 --- a/internal/app/enterprise.go +++ b/internal/app/enterprise.go @@ -333,6 +333,83 @@ func (l *Ledger) UpdateSSOProviderTrustMaterial(ctx context.Context, actor domai return provider, nil } +func (l *Ledger) RefreshSSOProviderOIDCTrustMaterial(ctx context.Context, actor domain.Actor, id string) (domain.SSOProvider, error) { + if err := ctx.Err(); err != nil { + return domain.SSOProvider{}, err + } + if err := require(actor, ScopeIdentityAdmin); err != nil { + return domain.SSOProvider{}, err + } + id = strings.TrimSpace(id) + if id == "" { + return domain.SSOProvider{}, ErrValidation + } + discovery := l.oidc + if discovery == nil { + return domain.SSOProvider{}, ErrValidation + } + l.mu.Lock() + provider, ok := l.ssoProviders[id] + if !ok || provider.TenantID != actor.TenantID { + l.mu.Unlock() + return domain.SSOProvider{}, ErrNotFound + } + if provider.Type != "oidc" { + l.mu.Unlock() + return domain.SSOProvider{}, ErrValidation + } + l.mu.Unlock() + + result, err := discovery.FetchOIDCTrustMaterial(ctx, OIDCDiscoveryRequest{TenantID: actor.TenantID, ProviderID: provider.ID, Issuer: provider.Issuer}) + if err != nil { + return domain.SSOProvider{}, ErrVerificationFailed + } + if strings.TrimRight(strings.TrimSpace(result.Issuer), "/") != strings.TrimRight(provider.Issuer, "/") { + return domain.SSOProvider{}, ErrVerificationFailed + } + jwks, err := normalizeJWKS(result.JWKS) + if err != nil { + return domain.SSOProvider{}, ErrVerificationFailed + } + if len(jwks) == 0 { + return domain.SSOProvider{}, ErrVerificationFailed + } + + l.mu.Lock() + defer l.mu.Unlock() + current, ok := l.ssoProviders[id] + if !ok || current.TenantID != actor.TenantID { + return domain.SSOProvider{}, ErrNotFound + } + if current.Type != "oidc" || current.Issuer != provider.Issuer { + return domain.SSOProvider{}, ErrVerificationFailed + } + now := l.now() + current.JWKS = jwks + current.SAMLSigningCertificates = nil + current.TrustMaterialUpdatedAt = &now + materialHash, err := canonicalAnyHash(struct { + ProviderID string `json:"provider_id"` + Issuer string `json:"issuer"` + JWKS map[string]any `json:"jwks"` + UpdatedAt string `json:"updated_at"` + }{ + ProviderID: current.ID, + Issuer: current.Issuer, + JWKS: current.JWKS, + UpdatedAt: now.Format(time.RFC3339Nano), + }) + if err != nil { + return domain.SSOProvider{}, err + } + l.ssoProviders[current.ID] = current + _, _ = l.appendChainLocked(actor.TenantID, "sso_provider.oidc_trust_material_refreshed", "sso_provider", current.ID, actorType(actor), actorID(actor), materialHash, "") + if err := l.persistLocked(ctx); err != nil { + return domain.SSOProvider{}, err + } + return current, nil +} + func (l *Ledger) LinkSSOIdentity(ctx context.Context, actor domain.Actor, in LinkSSOIdentityInput) (domain.UserIdentityLink, error) { if err := ctx.Err(); err != nil { return domain.UserIdentityLink{}, err diff --git a/internal/app/enterprise_test.go b/internal/app/enterprise_test.go index b0a202a..c861922 100644 --- a/internal/app/enterprise_test.go +++ b/internal/app/enterprise_test.go @@ -278,6 +278,54 @@ func TestOIDCProviderIdentityVerificationUsesStaticJWKS(t *testing.T) { } } +func TestOIDCProviderDiscoveryRefreshesTenantTrustMaterial(t *testing.T) { + pub, _, err := ed25519.GenerateKey(rand.Reader) + if err != nil { + t.Fatalf("keygen: %v", err) + } + jwks := map[string]any{"keys": []any{map[string]any{"kty": "OKP", "crv": "Ed25519", "kid": "kid-refresh", "x": base64.RawURLEncoding.EncodeToString(pub)}}} + discovery := &fakeOIDCDiscovery{result: OIDCDiscoveryResult{Issuer: "https://idp.example.test", JWKS: jwks}} + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow, OIDC: discovery}) + ctx := context.Background() + _, _, _, actor := bootstrapEnterpriseTestTenant(t, ledger) + provider, err := ledger.CreateSSOProvider(ctx, actor, CreateSSOProviderInput{Name: "OIDC", Type: "oidc", Issuer: "https://idp.example.test", ClientID: "client"}) + if err != nil { + t.Fatalf("provider: %v", err) + } + refreshed, err := ledger.RefreshSSOProviderOIDCTrustMaterial(ctx, actor, provider.ID) + if err != nil { + t.Fatalf("refresh: %v", err) + } + if refreshed.TrustMaterialUpdatedAt == nil || len(refreshed.JWKS) == 0 || len(refreshed.SAMLSigningCertificates) != 0 { + t.Fatalf("refreshed provider = %#v", refreshed) + } + if discovery.request.TenantID != actor.TenantID || discovery.request.ProviderID != provider.ID || discovery.request.Issuer != provider.Issuer { + t.Fatalf("discovery request = %#v", discovery.request) + } + _, _, _, other := bootstrapEnterpriseTestTenant(t, ledger) + if _, err := ledger.RefreshSSOProviderOIDCTrustMaterial(ctx, other, provider.ID); !errors.Is(err, ErrNotFound) { + t.Fatalf("cross tenant refresh err=%v, want not found", err) + } +} + +func TestOIDCProviderDiscoveryRefreshRejectsMismatchedIssuer(t *testing.T) { + pub, _, err := ed25519.GenerateKey(rand.Reader) + if err != nil { + t.Fatalf("keygen: %v", err) + } + jwks := map[string]any{"keys": []any{map[string]any{"kty": "OKP", "crv": "Ed25519", "kid": "kid", "x": base64.RawURLEncoding.EncodeToString(pub)}}} + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow, OIDC: &fakeOIDCDiscovery{result: OIDCDiscoveryResult{Issuer: "https://other-idp.example.test", JWKS: jwks}}}) + ctx := context.Background() + _, _, _, actor := bootstrapEnterpriseTestTenant(t, ledger) + provider, err := ledger.CreateSSOProvider(ctx, actor, CreateSSOProviderInput{Name: "OIDC", Type: "oidc", Issuer: "https://idp.example.test", ClientID: "client"}) + if err != nil { + t.Fatalf("provider: %v", err) + } + if _, err := ledger.RefreshSSOProviderOIDCTrustMaterial(ctx, actor, provider.ID); !errors.Is(err, ErrVerificationFailed) { + t.Fatalf("refresh err=%v, want verification failed", err) + } +} + func TestInstanceAdminRequiresExplicitScope(t *testing.T) { ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) ctx := context.Background() @@ -1020,6 +1068,33 @@ func hasVerifyCheck(checks []domain.VerifyCheck, name, result string) bool { return false } +type fakeOIDCDiscovery struct { + request OIDCDiscoveryRequest + result OIDCDiscoveryResult + err error +} + +func (f *fakeOIDCDiscovery) FetchOIDCTrustMaterial(_ context.Context, req OIDCDiscoveryRequest) (OIDCDiscoveryResult, error) { + f.request = req + if f.err != nil { + return OIDCDiscoveryResult{}, f.err + } + return f.result, nil +} + +func bootstrapEnterpriseTestTenant(t *testing.T, ledger *Ledger) (domain.Tenant, domain.APIKey, string, domain.Actor) { + t.Helper() + tenant, key, secret, err := ledger.BootstrapTenant(t.Context(), "Tenant", "admin", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap: %v", err) + } + actor, err := ledger.Authenticate(t.Context(), secret) + if err != nil { + t.Fatalf("auth: %v", err) + } + return tenant, key, secret, actor +} + func bigEndianExponent(value int) []byte { if value == 0 { return []byte{0} diff --git a/internal/app/ledger.go b/internal/app/ledger.go index d9bc3d1..3b5eadd 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -68,6 +68,7 @@ type Config struct { ObjectStore ObjectStore Retention ObjectRetentionVerifier Signer SigningExecutor + OIDC OIDCDiscoveryClient Outbox Outbox } @@ -80,6 +81,7 @@ type Ledger struct { objects ObjectStore retention ObjectRetentionVerifier signer SigningExecutor + oidc OIDCDiscoveryClient outbox Outbox tenants map[string]domain.Tenant @@ -203,6 +205,7 @@ func NewLedgerWithError(cfg Config) (*Ledger, error) { objects: cfg.ObjectStore, retention: retention, signer: cfg.Signer, + oidc: cfg.OIDC, outbox: cfg.Outbox, tenants: map[string]domain.Tenant{}, organizations: map[string]domain.Organization{}, diff --git a/internal/app/ports.go b/internal/app/ports.go index d791bb6..744dddb 100644 --- a/internal/app/ports.go +++ b/internal/app/ports.go @@ -25,6 +25,10 @@ type SigningExecutor interface { Sign(context.Context, SigningRequest) (SigningResult, error) } +type OIDCDiscoveryClient interface { + FetchOIDCTrustMaterial(context.Context, OIDCDiscoveryRequest) (OIDCDiscoveryResult, error) +} + type Outbox interface { Enqueue(context.Context, OutboxJob) error } @@ -46,6 +50,19 @@ type SigningResult struct { Checks []domain.VerifyCheck } +type OIDCDiscoveryRequest struct { + TenantID string + ProviderID string + Issuer string +} + +type OIDCDiscoveryResult struct { + Issuer string + JWKS map[string]any + Checks []domain.VerifyCheck + Limitations []string +} + type ObjectRetentionRequest struct { TenantID string ObjectPrefix string diff --git a/openapi.yaml b/openapi.yaml index 1419479..de22eef 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/sdk/openapi-route-catalog.json b/sdk/openapi-route-catalog.json index 1d67b53..5d99985 100644 --- a/sdk/openapi-route-catalog.json +++ b/sdk/openapi-route-catalog.json @@ -1,5 +1,5 @@ { - "route_count": 163, + "route_count": 164, "routes": [ { "idempotency_key_required": false, @@ -2467,6 +2467,23 @@ "201" ] }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "refreshSSOProviderOIDCTrustMaterial", + "path": "/v1/sso/providers/{id}/discover-oidc", + "request_schema": "#/components/schemas/EmptyObject", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SSOProviderEnvelope" + ], + "scopes": [ + "identity:admin" + ], + "success_statuses": [ + "200" + ] + }, { "idempotency_key_required": true, "method": "POST", From 1fc6eae91508115afbfb58f8d9d5e9a7a7a0cd42 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 21:33:12 +0300 Subject: [PATCH 106/287] feat: verify object-level retention samples --- .implementation_increments.md | 4 +- docs/api.md | 4 +- docs/architecture.md | 2 +- docs/reference/production-readiness.md | 9 +-- internal/adapters/httpapi/openapi.go | 2 + internal/adapters/httpapi/router.go | 3 +- internal/adapters/objectstore/s3/s3.go | 57 +++++++++++++++---- internal/adapters/objectstore/s3/s3_test.go | 26 ++++++++- internal/adapters/postgres/store.go | 11 ++-- internal/app/integrity_runtime.go | 11 +++- internal/app/integrity_runtime_test.go | 8 ++- internal/app/ports.go | 1 + internal/domain/domain.go | 1 + ...00100_object_retention_object_key.down.sql | 4 ++ ...9000100_object_retention_object_key.up.sql | 6 ++ openapi.yaml | 2 +- 16 files changed, 120 insertions(+), 31 deletions(-) create mode 100644 migrations/20260529000100_object_retention_object_key.down.sql create mode 100644 migrations/20260529000100_object_retention_object_key.up.sql diff --git a/.implementation_increments.md b/.implementation_increments.md index 60bc7e4..ca53706 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -143,7 +143,7 @@ Status legend: Added optional external transparency/timestamp checkpoint records for Merkle batches without requiring public transparency for local trust. 41. `[x]` WORM/Object Lock Integration - Added tenant-prefixed object-retention policy records and verification transitions. Enforcement depends on the configured object store and deployment policy. + Added tenant-prefixed object-retention policy records, optional sample object keys, S3/MinIO bucket and sample-object retention checks, and verification transitions. Broader enforcement still depends on configured object store policy and deployment review. ## Runtime, Operations, And Deployment Increments @@ -251,7 +251,7 @@ Status legend: ## Implemented-But-Partial Areas -- `[x]` Object-retention verification receipts now record a reproducible verification hash, while WORM/object-lock enforcement remains a deployment and object-store control. +- `[x]` Object-retention verification receipts now record a reproducible verification hash with bucket-level and optional sample-object checks, while broad WORM/object-lock enforcement remains a deployment and object-store control. - `[x]` External signing-provider operation receipts now record payload hashes, checks, and signature references, while production KMS/HSM adapter execution remains deployment hardening work. - `[x]` Stored OIDC/SAML identity-link verification records provider-verification receipts, and OIDC ID tokens plus SAML assertions can be verified locally against configured tenant trust material. Public OIDC JWKS can be refreshed from discovery metadata, and public JWKS plus SAML signing certificates can be rotated without recreating the provider. Live provider API calls, browser login callbacks, browser cookie/session handling, and group synchronization remain external/provider work. - `[x]` Public transparency log records now link local Merkle checkpoints to external entry metadata and can verify operator-supplied inclusion proof material locally. Live provider fetching remains deployment hardening work. diff --git a/docs/api.md b/docs/api.md index ceeba1a..f0610f3 100644 --- a/docs/api.md +++ b/docs/api.md @@ -398,8 +398,8 @@ Source snapshots capture submitted provider metadata. They do not call provider | `POST` | `/v1/public-transparency-logs` | Record optional public transparency log configuration. | | `POST` | `/v1/public-transparency-log-entries` | Record published public transparency log entry metadata. | | `POST` | `/v1/public-transparency-log-entries/{id}/verify` | Verify operator-supplied RFC6962-style public transparency inclusion proof material. | -| `POST` | `/v1/object-retention-policies` | Record retention policy intent. | -| `POST` | `/v1/object-retention-policies/{id}/verify` | Record verification transition. | +| `POST` | `/v1/object-retention-policies` | Record retention policy intent with optional tenant-prefixed sample object key. | +| `POST` | `/v1/object-retention-policies/{id}/verify` | Record provider verification transition. | | `POST` | `/v1/legal-holds` | Record legal hold. | | `POST` | `/v1/retention-overrides` | Record retention override. | | `GET` | `/v1/reports/retention` | List retention records. | diff --git a/docs/architecture.md b/docs/architecture.md index c67f647..809f67c 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -48,7 +48,7 @@ Evidence summaries, questionnaire drafts, graph snapshots, PDF packages, and ano GitHub OIDC subject metadata can be captured, and stored OIDC/SAML identity links can be verified against tenant metadata. OIDC provider records can include public JWKS material for local EdDSA or RS256 ID-token signature and claim verification, and SAML provider records can include PEM signing certificates for local assertion signature and claim verification. Trust material can be rotated without recreating the provider. Live provider API verification, discovery, browser login callbacks, and group synchronization remain trust boundaries outside those records. Collector supply-chain records track pinned collector versions with signature, SBOM, and scan evidence where available; commercial and marketplace collector definitions add extension metadata without granting provider trust. -Air-gapped import-bundle workflows preserve the same tenant-scoped import path after controlled transfer. Object-retention policy APIs record tenant-scoped retention intent and, when the S3/MinIO object-store adapter is configured, verify bucket versioning plus default object-lock mode and duration. Those checks are bucket-level evidence; WORM/object-lock enforcement, IAM policy, lifecycle rules, and deployment-specific retention review remain operator responsibilities. +Air-gapped import-bundle workflows preserve the same tenant-scoped import path after controlled transfer. Object-retention policy APIs record tenant-scoped retention intent and, when the S3/MinIO object-store adapter is configured, verify bucket versioning plus default object-lock mode and duration. Policies can also name a tenant-prefixed sample object key for object-level retention checks where the provider supports them. Those checks are evidence for the configured bucket and sample object only; WORM/object-lock enforcement, IAM policy, lifecycle rules, and deployment-specific retention review remain operator responsibilities. ## Limitations diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 022af31..49593d0 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -151,10 +151,11 @@ implemented capabilities: trust-material updates, manual JWKS and SAML signing-certificate rotation is implemented through the SSO provider trust-material endpoint, and API-first session logout can revoke the current SSO bearer session. -- Extend object-lock/WORM verification beyond current S3/MinIO bucket-level - checks where deployments require object-level legal hold proofs or provider - policy evidence, and add live provider fetching for public transparency proofs - where deployments require it. +- Extend object-lock/WORM verification beyond the current S3/MinIO bucket-level + checks plus optional sample-object retention checks where deployments require + broader object-level legal hold proofs or provider policy evidence, and add + live provider fetching for public transparency proofs where deployments + require it. - Run final product, codebase, security, documentation, and test audits before changing release status beyond controlled self-hosted production candidate. diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 98e7c05..52e5334 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -190,6 +190,7 @@ func registerCriticalSchemas(registry *specs.Registry) { registry.RegisterSchema("CreateObjectRetentionPolicyRequest", objectSchema(map[string]any{ "name": map[string]any{"type": "string"}, "object_prefix": map[string]any{"type": "string"}, + "object_key": map[string]any{"type": "string", "description": "Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store."}, "mode": map[string]any{"type": "string", "enum": []string{"governance", "compliance"}}, "retention_days": map[string]any{"type": "integer", "minimum": 1}, }, "name", "mode", "retention_days")) @@ -198,6 +199,7 @@ func registerCriticalSchemas(registry *specs.Registry) { "tenant_id": map[string]any{"type": "string"}, "name": map[string]any{"type": "string"}, "object_prefix": map[string]any{"type": "string"}, + "object_key": map[string]any{"type": "string"}, "mode": map[string]any{"type": "string"}, "retention_days": map[string]any{"type": "integer"}, "status": map[string]any{"type": "string"}, diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index 26136b4..eeb53d0 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -1853,6 +1853,7 @@ func (s *Server) createObjectRetentionPolicy(w http.ResponseWriter, r *http.Requ var req struct { Name string `json:"name"` ObjectPrefix string `json:"object_prefix"` + ObjectKey string `json:"object_key"` Mode string `json:"mode"` RetentionDays int `json:"retention_days"` } @@ -1860,7 +1861,7 @@ func (s *Server) createObjectRetentionPolicy(w http.ResponseWriter, r *http.Requ if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - policy, err := s.ledger.CreateObjectRetentionPolicy(ctx, actor, app.CreateObjectRetentionPolicyInput{Name: req.Name, ObjectPrefix: req.ObjectPrefix, Mode: req.Mode, RetentionDays: req.RetentionDays}) + policy, err := s.ledger.CreateObjectRetentionPolicy(ctx, actor, app.CreateObjectRetentionPolicyInput{Name: req.Name, ObjectPrefix: req.ObjectPrefix, ObjectKey: req.ObjectKey, Mode: req.Mode, RetentionDays: req.RetentionDays}) return http.StatusCreated, policy, err }) } diff --git a/internal/adapters/objectstore/s3/s3.go b/internal/adapters/objectstore/s3/s3.go index fb68ad2..ecb6580 100644 --- a/internal/adapters/objectstore/s3/s3.go +++ b/internal/adapters/objectstore/s3/s3.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "strings" + "time" "github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7/pkg/credentials" @@ -104,7 +105,13 @@ func (s *Store) VerifyObjectRetention(ctx context.Context, req app.ObjectRetenti if s == nil || s.client == nil { return app.ObjectRetentionResult{}, app.ErrValidation } - if strings.TrimSpace(req.TenantID) == "" || !strings.HasPrefix(strings.TrimSpace(req.ObjectPrefix), "tenants/"+strings.TrimSpace(req.TenantID)+"/") { + tenantPrefix := "tenants/" + strings.TrimSpace(req.TenantID) + "/" + objectPrefix := strings.TrimSpace(req.ObjectPrefix) + objectKey := strings.TrimSpace(req.ObjectKey) + if strings.TrimSpace(req.TenantID) == "" || !strings.HasPrefix(objectPrefix, tenantPrefix) { + return app.ObjectRetentionResult{}, app.ErrValidation + } + if objectKey != "" && (!strings.HasPrefix(objectKey, tenantPrefix) || !strings.HasPrefix(objectKey, objectPrefix)) { return app.ObjectRetentionResult{}, app.ErrValidation } versioning, err := s.client.GetBucketVersioning(ctx, s.bucket) @@ -115,7 +122,15 @@ func (s *Store) VerifyObjectRetention(ctx context.Context, req app.ObjectRetenti if err != nil && !objectLockConfigMissing(err) { return app.ObjectRetentionResult{}, fmt.Errorf("check s3 object lock: %w", err) } - return evaluateObjectRetention(req, versioning.Enabled(), mode, validity, unit), nil + var objectMode *minio.RetentionMode + var retainUntil *time.Time + if objectKey != "" { + objectMode, retainUntil, err = s.client.GetObjectRetention(ctx, s.bucket, objectKey, "") + if err != nil && !objectLockConfigMissing(err) { + return app.ObjectRetentionResult{}, fmt.Errorf("check s3 object retention: %w", err) + } + } + return evaluateObjectRetention(req, versioning.Enabled(), mode, validity, unit, objectMode, retainUntil, time.Now().UTC()), nil } func metadataValue(metadata map[string]string, keys ...string) string { @@ -132,31 +147,53 @@ func objectLockConfigMissing(err error) bool { return resp.Code == "NoSuchObjectLockConfiguration" || resp.Code == "ObjectLockConfigurationNotFoundError" } -func evaluateObjectRetention(req app.ObjectRetentionRequest, versioningEnabled bool, mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit) app.ObjectRetentionResult { +func evaluateObjectRetention(req app.ObjectRetentionRequest, versioningEnabled bool, mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, objectMode *minio.RetentionMode, retainUntil *time.Time, now time.Time) app.ObjectRetentionResult { expectedPrefix := "tenants/" + strings.TrimSpace(req.TenantID) + "/" prefixOK := strings.HasPrefix(strings.TrimSpace(req.ObjectPrefix), expectedPrefix) + objectKey := strings.TrimSpace(req.ObjectKey) + objectKeyOK := objectKey == "" || (strings.HasPrefix(objectKey, expectedPrefix) && strings.HasPrefix(objectKey, strings.TrimSpace(req.ObjectPrefix))) expectedMode := retentionMode(req.Mode) actualMode := "" if mode != nil { actualMode = strings.ToUpper(mode.String()) } + actualObjectMode := "" + if objectMode != nil { + actualObjectMode = strings.ToUpper(objectMode.String()) + } retentionDays := retentionDays(validity, unit) modeOK := expectedMode != "" && actualMode == expectedMode retentionOK := req.RetentionDays > 0 && retentionDays >= uint(req.RetentionDays) + objectModeOK := objectKey == "" || (expectedMode != "" && actualObjectMode == expectedMode) + objectRetainUntilOK := objectKey == "" || (retainUntil != nil && retainUntil.UTC().After(now.Add(time.Duration(req.RetentionDays)*24*time.Hour-time.Second))) checks := []domain.VerifyCheck{ {Name: "s3_bucket_versioning", Result: checkResult(versioningEnabled), Detail: "Bucket versioning must be enabled for object-lock retention."}, {Name: "s3_object_lock_mode", Result: checkResult(modeOK), Detail: "Bucket default object-lock mode must match the policy mode."}, {Name: "s3_object_lock_retention", Result: checkResult(retentionOK), Detail: "Bucket default object-lock retention must meet or exceed the policy duration."}, {Name: "tenant_object_prefix", Result: checkResult(prefixOK), Detail: "Object prefix must stay under the tenant namespace."}, } + if objectKey != "" { + checks = append(checks, + domain.VerifyCheck{Name: "tenant_object_key", Result: checkResult(objectKeyOK), Detail: "Sample object key must stay under the tenant namespace and configured prefix."}, + domain.VerifyCheck{Name: "s3_object_retention_mode", Result: checkResult(objectModeOK), Detail: "Sample object retention mode must match the policy mode."}, + domain.VerifyCheck{Name: "s3_object_retention_until", Result: checkResult(objectRetainUntilOK), Detail: "Sample object retain-until timestamp must meet or exceed the policy duration."}, + ) + } + enforced := versioningEnabled && modeOK && retentionOK && prefixOK && objectKeyOK && objectModeOK && objectRetainUntilOK + limitations := []string{ + "S3/MinIO checks validate bucket-level versioning and default object-lock settings.", + "Operators remain responsible for bucket creation mode, IAM policy, lifecycle rules, backups, and deployment-specific retention review.", + } + if objectKey == "" { + limitations = append(limitations, "No sample object key was supplied, so object-level retention was not verified.") + } else { + limitations = append(limitations, "Object-level retention was checked for the configured sample object key only.") + } return app.ObjectRetentionResult{ - Provider: "s3", - Enforced: versioningEnabled && modeOK && retentionOK && prefixOK, - Checks: checks, - Limitations: []string{ - "S3/MinIO checks validate bucket-level versioning and default object-lock settings only.", - "Operators remain responsible for bucket creation mode, IAM policy, lifecycle rules, backups, and deployment-specific retention review.", - }, + Provider: "s3", + Enforced: enforced, + Checks: checks, + Limitations: limitations, } } diff --git a/internal/adapters/objectstore/s3/s3_test.go b/internal/adapters/objectstore/s3/s3_test.go index cbbbb16..b73769c 100644 --- a/internal/adapters/objectstore/s3/s3_test.go +++ b/internal/adapters/objectstore/s3/s3_test.go @@ -4,6 +4,7 @@ import ( "context" "errors" "testing" + "time" "github.com/minio/minio-go/v7" @@ -61,7 +62,7 @@ func TestEvaluateObjectRetentionRequiresVersioningLockAndTenantPrefix(t *testing ObjectPrefix: "tenants/ten_1/raw/", Mode: "compliance", RetentionDays: 30, - }, true, &mode, &validity, &unit) + }, true, &mode, &validity, &unit, nil, nil, time.Date(2026, 5, 29, 0, 0, 0, 0, time.UTC)) if !result.Enforced { t.Fatalf("expected enforced retention: %#v", result) } @@ -82,7 +83,7 @@ func TestEvaluateObjectRetentionReportsMissingProviderControls(t *testing.T) { ObjectPrefix: "tenants/other/raw/", Mode: "compliance", RetentionDays: 30, - }, false, &mode, &validity, &unit) + }, false, &mode, &validity, &unit, nil, nil, time.Date(2026, 5, 29, 0, 0, 0, 0, time.UTC)) if result.Enforced { t.Fatalf("unexpected enforced retention: %#v", result) } @@ -97,6 +98,27 @@ func TestEvaluateObjectRetentionReportsMissingProviderControls(t *testing.T) { } } +func TestEvaluateObjectRetentionChecksSampleObjectRetention(t *testing.T) { + mode := minio.Compliance + validity := uint(90) + unit := minio.Days + now := time.Date(2026, 5, 29, 0, 0, 0, 0, time.UTC) + retainUntil := now.Add(45 * 24 * time.Hour) + result := evaluateObjectRetention(app.ObjectRetentionRequest{ + TenantID: "ten_1", + ObjectPrefix: "tenants/ten_1/raw/", + ObjectKey: "tenants/ten_1/raw/sample.json", + Mode: "compliance", + RetentionDays: 30, + }, true, &mode, &validity, &unit, &mode, &retainUntil, now) + if !result.Enforced { + t.Fatalf("expected object-level enforced retention: %#v", result) + } + if len(result.Checks) != 7 { + t.Fatalf("checks = %#v", result.Checks) + } +} + func TestRetentionDaysConvertsYears(t *testing.T) { validity := uint(2) unit := minio.Years diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index f7172b9..12ff145 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -2104,7 +2104,7 @@ func (s *Store) loadRelationalReports(ctx context.Context, state *app.PersistedS } func (s *Store) loadRelationalRetention(ctx context.Context, state *app.PersistedState, loaded *bool) error { - policyRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, name, object_prefix, mode, retention_days, status, verified_at, verification_hash, verification_checks, verification_limitations, schema_version, created_at FROM object_retention_policies`) + policyRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, name, object_prefix, COALESCE(object_key, ''), mode, retention_days, status, verified_at, verification_hash, verification_checks, verification_limitations, schema_version, created_at FROM object_retention_policies`) if err != nil { return fmt.Errorf("load relational object retention policies: %w", err) } @@ -2114,7 +2114,7 @@ func (s *Store) loadRelationalRetention(ctx context.Context, state *app.Persiste var verifiedAt sql.NullTime var verificationHash sql.NullString var checks []byte - if err := policyRows.Scan(&policy.ID, &policy.TenantID, &policy.Name, &policy.ObjectPrefix, &policy.Mode, &policy.RetentionDays, &policy.Status, &verifiedAt, &verificationHash, &checks, &policy.VerificationLimitations, &policy.SchemaVersion, &policy.CreatedAt); err != nil { + if err := policyRows.Scan(&policy.ID, &policy.TenantID, &policy.Name, &policy.ObjectPrefix, &policy.ObjectKey, &policy.Mode, &policy.RetentionDays, &policy.Status, &verifiedAt, &verificationHash, &checks, &policy.VerificationLimitations, &policy.SchemaVersion, &policy.CreatedAt); err != nil { return fmt.Errorf("scan relational object retention policy: %w", err) } policy.VerifiedAt = nullableSQLTime(verifiedAt) @@ -3838,19 +3838,20 @@ func syncPackageReportRetentionRows(ctx context.Context, tx pgx.Tx, state app.Pe } if _, err := tx.Exec(ctx, ` INSERT INTO object_retention_policies ( - id, tenant_id, name, object_prefix, mode, retention_days, status, + id, tenant_id, name, object_prefix, object_key, mode, retention_days, status, verified_at, verification_hash, verification_checks, verification_limitations, schema_version, created_at ) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) ON CONFLICT (id) DO UPDATE SET + object_key = EXCLUDED.object_key, status = EXCLUDED.status, verified_at = EXCLUDED.verified_at, verification_hash = EXCLUDED.verification_hash, verification_checks = EXCLUDED.verification_checks, verification_limitations = EXCLUDED.verification_limitations, schema_version = EXCLUDED.schema_version - `, policy.ID, policy.TenantID, policy.Name, policy.ObjectPrefix, policy.Mode, policy.RetentionDays, policy.Status, nullableTime(policy.VerifiedAt), nullableString(policy.VerificationHash), checks, policy.VerificationLimitations, policy.SchemaVersion, nonZeroTime(policy.CreatedAt)); err != nil { + `, policy.ID, policy.TenantID, policy.Name, policy.ObjectPrefix, policy.ObjectKey, policy.Mode, policy.RetentionDays, policy.Status, nullableTime(policy.VerifiedAt), nullableString(policy.VerificationHash), checks, policy.VerificationLimitations, policy.SchemaVersion, nonZeroTime(policy.CreatedAt)); err != nil { return fmt.Errorf("upsert object retention policy row: %w", err) } } diff --git a/internal/app/integrity_runtime.go b/internal/app/integrity_runtime.go index c931016..b2eb3d3 100644 --- a/internal/app/integrity_runtime.go +++ b/internal/app/integrity_runtime.go @@ -38,6 +38,7 @@ type CreateTransparencyCheckpointInput struct { type CreateObjectRetentionPolicyInput struct { Name string ObjectPrefix string + ObjectKey string Mode string RetentionDays int } @@ -293,7 +294,7 @@ func (l *Ledger) CreateObjectRetentionPolicy(ctx context.Context, actor domain.A if err := require(actor, ScopeAdmin); err != nil { return domain.ObjectRetentionPolicy{}, err } - in.Name, in.ObjectPrefix, in.Mode = strings.TrimSpace(in.Name), strings.TrimSpace(in.ObjectPrefix), strings.TrimSpace(in.Mode) + in.Name, in.ObjectPrefix, in.ObjectKey, in.Mode = strings.TrimSpace(in.Name), strings.TrimSpace(in.ObjectPrefix), strings.TrimSpace(in.ObjectKey), strings.TrimSpace(in.Mode) if in.Name == "" || in.RetentionDays <= 0 || (in.Mode != "governance" && in.Mode != "compliance") { return domain.ObjectRetentionPolicy{}, ErrValidation } @@ -304,9 +305,12 @@ func (l *Ledger) CreateObjectRetentionPolicy(ctx context.Context, actor domain.A if !strings.HasPrefix(in.ObjectPrefix, expectedPrefix) { return domain.ObjectRetentionPolicy{}, ErrValidation } + if in.ObjectKey != "" && (!strings.HasPrefix(in.ObjectKey, expectedPrefix) || !strings.HasPrefix(in.ObjectKey, in.ObjectPrefix)) { + return domain.ObjectRetentionPolicy{}, ErrValidation + } l.mu.Lock() defer l.mu.Unlock() - policy := domain.ObjectRetentionPolicy{ID: newID("orp"), TenantID: actor.TenantID, Name: in.Name, ObjectPrefix: in.ObjectPrefix, Mode: in.Mode, RetentionDays: in.RetentionDays, Status: "configured", SchemaVersion: domain.ObjectRetentionPolicyVersion, CreatedAt: l.now()} + policy := domain.ObjectRetentionPolicy{ID: newID("orp"), TenantID: actor.TenantID, Name: in.Name, ObjectPrefix: in.ObjectPrefix, ObjectKey: in.ObjectKey, Mode: in.Mode, RetentionDays: in.RetentionDays, Status: "configured", SchemaVersion: domain.ObjectRetentionPolicyVersion, CreatedAt: l.now()} l.retentionPolicies[policy.ID] = policy _, _ = l.appendChainLocked(actor.TenantID, "object_retention_policy.created", "object_retention_policy", policy.ID, actorType(actor), actorID(actor), "", "") if err := l.persistLocked(ctx); err != nil { @@ -346,6 +350,7 @@ func (l *Ledger) VerifyObjectRetentionPolicy(ctx context.Context, actor domain.A result, err := verifier.VerifyObjectRetention(ctx, ObjectRetentionRequest{ TenantID: policy.TenantID, ObjectPrefix: policy.ObjectPrefix, + ObjectKey: policy.ObjectKey, Mode: policy.Mode, RetentionDays: policy.RetentionDays, }) @@ -367,6 +372,7 @@ func (l *Ledger) VerifyObjectRetentionPolicy(ctx context.Context, actor domain.A ID string `json:"id"` TenantID string `json:"tenant_id"` ObjectPrefix string `json:"object_prefix"` + ObjectKey string `json:"object_key,omitempty"` Mode string `json:"mode"` Provider string `json:"provider"` RetentionDays int `json:"retention_days"` @@ -378,6 +384,7 @@ func (l *Ledger) VerifyObjectRetentionPolicy(ctx context.Context, actor domain.A ID: policy.ID, TenantID: policy.TenantID, ObjectPrefix: policy.ObjectPrefix, + ObjectKey: policy.ObjectKey, Mode: policy.Mode, Provider: retentionResult.Provider, RetentionDays: policy.RetentionDays, diff --git a/internal/app/integrity_runtime_test.go b/internal/app/integrity_runtime_test.go index 64a3204..e7bfe0c 100644 --- a/internal/app/integrity_runtime_test.go +++ b/internal/app/integrity_runtime_test.go @@ -73,10 +73,16 @@ func TestRuntimeRetentionBackupReadinessMetricsAndAudit(t *testing.T) { if _, err := ledger.CreateSigningProvider(ctx, actor, CreateSigningProviderInput{Name: "dev", Type: "local_encrypted_dev", KeyRef: "file://dev.keys", Encrypted: true}); err != nil { t.Fatalf("signing provider: %v", err) } - policy, err := ledger.CreateObjectRetentionPolicy(ctx, actor, CreateObjectRetentionPolicyInput{Name: "tenant payload lock", Mode: "governance", RetentionDays: 30}) + policy, err := ledger.CreateObjectRetentionPolicy(ctx, actor, CreateObjectRetentionPolicyInput{Name: "tenant payload lock", ObjectKey: "tenants/" + actor.TenantID + "/raw/sample.json", Mode: "governance", RetentionDays: 30}) if err != nil { t.Fatalf("retention policy: %v", err) } + if policy.ObjectKey == "" { + t.Fatalf("policy missing object key: %#v", policy) + } + if _, err := ledger.CreateObjectRetentionPolicy(ctx, actor, CreateObjectRetentionPolicyInput{Name: "bad key", ObjectKey: "tenants/other/raw/sample.json", Mode: "governance", RetentionDays: 30}); !errors.Is(err, ErrValidation) { + t.Fatalf("foreign object key err=%v, want validation", err) + } verifiedPolicy, err := ledger.VerifyObjectRetentionPolicy(ctx, actor, policy.ID) if err != nil { t.Fatalf("verify retention: %v", err) diff --git a/internal/app/ports.go b/internal/app/ports.go index 744dddb..1e8799e 100644 --- a/internal/app/ports.go +++ b/internal/app/ports.go @@ -66,6 +66,7 @@ type OIDCDiscoveryResult struct { type ObjectRetentionRequest struct { TenantID string ObjectPrefix string + ObjectKey string Mode string RetentionDays int } diff --git a/internal/domain/domain.go b/internal/domain/domain.go index 9199617..cecae55 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -696,6 +696,7 @@ type ObjectRetentionPolicy struct { TenantID string `json:"tenant_id"` Name string `json:"name"` ObjectPrefix string `json:"object_prefix"` + ObjectKey string `json:"object_key,omitempty"` Mode string `json:"mode"` RetentionDays int `json:"retention_days"` Status string `json:"status"` diff --git a/migrations/20260529000100_object_retention_object_key.down.sql b/migrations/20260529000100_object_retention_object_key.down.sql new file mode 100644 index 0000000..2a45da7 --- /dev/null +++ b/migrations/20260529000100_object_retention_object_key.down.sql @@ -0,0 +1,4 @@ +DROP INDEX IF EXISTS object_retention_policies_tenant_object_key_idx; + +ALTER TABLE object_retention_policies + DROP COLUMN IF EXISTS object_key; diff --git a/migrations/20260529000100_object_retention_object_key.up.sql b/migrations/20260529000100_object_retention_object_key.up.sql new file mode 100644 index 0000000..bcd7dae --- /dev/null +++ b/migrations/20260529000100_object_retention_object_key.up.sql @@ -0,0 +1,6 @@ +ALTER TABLE object_retention_policies + ADD COLUMN IF NOT EXISTS object_key text NOT NULL DEFAULT ''; + +CREATE INDEX IF NOT EXISTS object_retention_policies_tenant_object_key_idx + ON object_retention_policies (tenant_id, object_key) + WHERE object_key <> ''; diff --git a/openapi.yaml b/openapi.yaml index de22eef..e701cb9 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From 5f704d4096da64a99a73d800f28b635e41c9a61a Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 21:34:49 +0300 Subject: [PATCH 107/287] feat: fetch transparency inclusion proofs --- .api.env.example | 3 + .implementation_increments.md | 4 +- README.md | 2 +- cmd/evydence-api/main.go | 5 + docs/api.md | 1 + docs/architecture.md | 2 +- docs/reference/api-contract-matrix.md | 3 +- docs/reference/production-readiness.md | 12 +- internal/adapters/httpapi/future_handlers.go | 7 + .../adapters/httpapi/openapi_operations.go | 5 + .../adapters/httpapi/route_registration.go | 1 + internal/adapters/httpapi/router.go | 1 + internal/adapters/httpapi/router_test.go | 44 +++++ .../transparency/httpfetcher/httpfetcher.go | 157 ++++++++++++++++++ .../httpfetcher/httpfetcher_test.go | 59 +++++++ internal/app/future_extensions.go | 67 +++++++- internal/app/future_extensions_test.go | 52 ++++++ internal/app/ledger.go | 19 ++- internal/app/ports.go | 24 +++ openapi.yaml | 2 +- sdk/openapi-route-catalog.json | 19 ++- 21 files changed, 467 insertions(+), 22 deletions(-) create mode 100644 internal/adapters/transparency/httpfetcher/httpfetcher.go create mode 100644 internal/adapters/transparency/httpfetcher/httpfetcher_test.go diff --git a/.api.env.example b/.api.env.example index 4cde829..3ae2a83 100644 --- a/.api.env.example +++ b/.api.env.example @@ -14,6 +14,9 @@ EVYDENCE_SIGNING_KEY_MODE=external # Optional OIDC discovery refresh tuning. HTTP is allowed only for localhost when explicitly enabled. # EVYDENCE_OIDC_DISCOVERY_TIMEOUT_SECONDS=10 # EVYDENCE_OIDC_DISCOVERY_ALLOW_INSECURE_LOCALHOST=false +# Optional public transparency proof fetch tuning. HTTP is allowed only for localhost when explicitly enabled. +# EVYDENCE_TRANSPARENCY_FETCH_TIMEOUT_SECONDS=10 +# EVYDENCE_TRANSPARENCY_FETCH_ALLOW_INSECURE_LOCALHOST=false # For MinIO/S3, set EVYDENCE_OBJECT_STORE=minio and provide: # EVYDENCE_S3_ENDPOINT=localhost:9000 # EVYDENCE_S3_BUCKET=evydence diff --git a/.implementation_increments.md b/.implementation_increments.md index ca53706..609c705 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -238,7 +238,7 @@ Status legend: Added explicit-instance-admin SaaS edition profile records with configuration hashes, limitations, persistence, migrations, API route, OpenAPI entry, docs, and tests. 70. `[x]` Public Transparency Log - Added optional public transparency log and published-entry records linked to local Merkle batches and transparency checkpoints, with entry hashes, operator-supplied RFC6962-style inclusion proof verification receipts, persistence, migrations, API routes, OpenAPI entries, docs, and tests. + Added optional public transparency log and published-entry records linked to local Merkle batches and transparency checkpoints, with entry hashes, operator-supplied and fetched RFC6962-style inclusion proof verification receipts, persistence, migrations, API routes, OpenAPI entries, docs, and tests. 71. `[x]` Marketplace Collectors Added marketplace collector package records with publisher, provider/version, manifest digest, optional signature/SBOM/scan references, tenant isolation, persistence, migrations, API routes, OpenAPI entries, docs, and tests. @@ -254,7 +254,7 @@ Status legend: - `[x]` Object-retention verification receipts now record a reproducible verification hash with bucket-level and optional sample-object checks, while broad WORM/object-lock enforcement remains a deployment and object-store control. - `[x]` External signing-provider operation receipts now record payload hashes, checks, and signature references, while production KMS/HSM adapter execution remains deployment hardening work. - `[x]` Stored OIDC/SAML identity-link verification records provider-verification receipts, and OIDC ID tokens plus SAML assertions can be verified locally against configured tenant trust material. Public OIDC JWKS can be refreshed from discovery metadata, and public JWKS plus SAML signing certificates can be rotated without recreating the provider. Live provider API calls, browser login callbacks, browser cookie/session handling, and group synchronization remain external/provider work. -- `[x]` Public transparency log records now link local Merkle checkpoints to external entry metadata and can verify operator-supplied inclusion proof material locally. Live provider fetching remains deployment hardening work. +- `[x]` Public transparency log records now link local Merkle checkpoints to external entry metadata and can verify operator-supplied or fetched inclusion proof material locally. Provider-specific trust semantics and availability remain deployment responsibilities. - `[x]` Marketplace collector records now capture package metadata and evidence references, and expose package health reports for signature, SBOM, and vulnerability scan evidence gaps. Marketplace distribution remains external operational hardening. - `[x]` Docker/Helm runtime packaging now includes the worker binary and migrations and uses commands that match the image PATH. - `[x]` GitHub Actions example now passes the digest computed in the workflow instead of an unrelated repository variable. diff --git a/README.md b/README.md index 4ccc486..b049a5f 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ This repository contains a Go implementation under module `github.com/aatuh/evyd - AGPL license, commercial licensing, governance, contribution, security, support, trademark, release-evidence, and changelog metadata. -Implemented-but-partial areas are documented explicitly: signing-provider operation receipts do not replace direct production KMS/HSM SDK adapters, OIDC discovery refreshes public JWKS trust material but does not replace full browser login callbacks or provider API validation, and public transparency records verify operator-supplied inclusion proof material without fetching live provider proofs. +Implemented-but-partial areas are documented explicitly: signing-provider operation receipts do not replace direct production KMS/HSM SDK adapters, OIDC discovery refreshes public JWKS trust material but does not replace full browser login callbacks or provider API validation, and public transparency records can verify operator-supplied or fetched inclusion proof material without replacing provider-specific trust review. ## License, Security, Support, And Governance diff --git a/cmd/evydence-api/main.go b/cmd/evydence-api/main.go index 41f9de0..35cf6de 100644 --- a/cmd/evydence-api/main.go +++ b/cmd/evydence-api/main.go @@ -19,6 +19,7 @@ import ( s3store "github.com/aatuh/evydence/internal/adapters/objectstore/s3" "github.com/aatuh/evydence/internal/adapters/postgres" "github.com/aatuh/evydence/internal/adapters/signing/httpgateway" + "github.com/aatuh/evydence/internal/adapters/transparency/httpfetcher" "github.com/aatuh/evydence/internal/app" ) @@ -40,6 +41,10 @@ func run() error { AllowInsecureForLocalhost: strings.EqualFold(os.Getenv("EVYDENCE_OIDC_DISCOVERY_ALLOW_INSECURE_LOCALHOST"), "true"), Timeout: time.Duration(intEnv("EVYDENCE_OIDC_DISCOVERY_TIMEOUT_SECONDS", 10)) * time.Second, }) + cfg.Transparency = httpfetcher.New(httpfetcher.Config{ + AllowInsecureForLocalhost: strings.EqualFold(os.Getenv("EVYDENCE_TRANSPARENCY_FETCH_ALLOW_INSECURE_LOCALHOST"), "true"), + Timeout: time.Duration(intEnv("EVYDENCE_TRANSPARENCY_FETCH_TIMEOUT_SECONDS", 10)) * time.Second, + }) if signer, err := openSigningExecutor(); err != nil { return err } else { diff --git a/docs/api.md b/docs/api.md index f0610f3..77be639 100644 --- a/docs/api.md +++ b/docs/api.md @@ -398,6 +398,7 @@ Source snapshots capture submitted provider metadata. They do not call provider | `POST` | `/v1/public-transparency-logs` | Record optional public transparency log configuration. | | `POST` | `/v1/public-transparency-log-entries` | Record published public transparency log entry metadata. | | `POST` | `/v1/public-transparency-log-entries/{id}/verify` | Verify operator-supplied RFC6962-style public transparency inclusion proof material. | +| `POST` | `/v1/public-transparency-log-entries/{id}/fetch-proof` | Fetch proof material from the configured transparency endpoint and verify it locally. | | `POST` | `/v1/object-retention-policies` | Record retention policy intent with optional tenant-prefixed sample object key. | | `POST` | `/v1/object-retention-policies/{id}/verify` | Record provider verification transition. | | `POST` | `/v1/legal-holds` | Record legal hold. | diff --git a/docs/architecture.md b/docs/architecture.md index 809f67c..a14767a 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -34,7 +34,7 @@ Release readiness is deterministic and evidence-scoped. Open critical vulnerabil DSSE attestation signatures can be verified against configured Ed25519 trust roots when raw attestation bytes are available. Cosign-style artifact verification records digest binding, signature presence, and optional Rekor metadata without overstating full Sigstore trust-chain validation. Signing keys support revocation and valid-at-signing semantics for historical signatures. -Merkle batches, signed checkpoints, optional transparency checkpoint/public transparency records with operator-supplied inclusion proof verification, backup manifests, object-retention policy records with verification hashes, legal holds, retention overrides, readiness, metrics, instance admin diagnostics, external signing gateway receipts, and admin audit queries provide operational integrity and review surfaces. +Merkle batches, signed checkpoints, optional transparency checkpoint/public transparency records with operator-supplied or fetched inclusion proof verification, backup manifests, object-retention policy records with verification hashes, legal holds, retention overrides, readiness, metrics, instance admin diagnostics, external signing gateway receipts, and admin audit queries provide operational integrity and review surfaces. ## Reports And Customer-Facing Packages diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index b28b4c5..11109a4 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 164 operations: 164 precise, 0 broad. +Generated from 165 operations: 165 precise, 0 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -95,6 +95,7 @@ Generated from 164 operations: 164 precise, 0 broad. | POST | /v1/projects | createProject | Bearer | project:write | required | - | application/json:CreateProjectRequest | 201:application/json:ProjectEnvelope | precise | | POST | /v1/provider-verifications | verifyProviderIdentity | Bearer | identity:admin | required | - | application/json:VerifyProviderIdentityRequest | 201:application/json:ProviderVerificationEnvelope | precise | | POST | /v1/public-transparency-log-entries | publishPublicTransparencyLogEntry | Bearer | keys:admin | required | - | application/json:PublishPublicTransparencyLogEntryRequest | 201:application/json:PublicTransparencyLogEntryEnvelope | precise | +| POST | /v1/public-transparency-log-entries/{id}/fetch-proof | fetchPublicTransparencyLogEntryProof | Bearer | keys:admin | required | path:id | application/json:EmptyObject | 200:application/json:PublicTransparencyLogEntryEnvelope | precise | | POST | /v1/public-transparency-log-entries/{id}/verify | verifyPublicTransparencyLogEntry | Bearer | keys:admin | required | path:id | application/json:VerifyPublicTransparencyLogEntryRequest | 200:application/json:PublicTransparencyLogEntryEnvelope | precise | | POST | /v1/public-transparency-logs | createPublicTransparencyLog | Bearer | keys:admin | required | - | application/json:CreatePublicTransparencyLogRequest | 201:application/json:PublicTransparencyLogEnvelope | precise | | POST | /v1/questionnaire-drafts | createQuestionnaireDraft | Bearer | package:read | required | - | application/json:CreateQuestionnaireDraftRequest | 201:application/json:QuestionnaireDraftEnvelope | precise | diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 49593d0..03d913a 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -45,9 +45,11 @@ Known hardening work remains: parameters, and request/response schemas; - production signing can use the HTTPS signing gateway executor, but direct cloud KMS/HSM SDK adapters, full browser OIDC/SAML login flows, provider - API validation/group sync, object-lock enforcement proof, and live - transparency-proof fetching remain provider- and deployment-dependent - hardening areas; + API validation/group sync, and broad object-lock enforcement proof remain + provider- and deployment-dependent hardening areas. Public transparency proof + material can be fetched from a configured endpoint and verified locally, but + provider-specific trust semantics and availability remain deployment + responsibilities; - the broader production exit review remains incomplete. ## Production Profiles @@ -153,9 +155,7 @@ implemented capabilities: session logout can revoke the current SSO bearer session. - Extend object-lock/WORM verification beyond the current S3/MinIO bucket-level checks plus optional sample-object retention checks where deployments require - broader object-level legal hold proofs or provider policy evidence, and add - live provider fetching for public transparency proofs where deployments - require it. + broader object-level legal hold proofs or provider policy evidence. - Run final product, codebase, security, documentation, and test audits before changing release status beyond controlled self-hosted production candidate. diff --git a/internal/adapters/httpapi/future_handlers.go b/internal/adapters/httpapi/future_handlers.go index 995d1f3..d8c229a 100644 --- a/internal/adapters/httpapi/future_handlers.go +++ b/internal/adapters/httpapi/future_handlers.go @@ -120,6 +120,13 @@ func (s *Server) verifyPublicTransparencyLogEntry(w http.ResponseWriter, r *http }) } +func (s *Server) fetchPublicTransparencyLogEntryProof(w http.ResponseWriter, r *http.Request) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, _ []byte) (int, any, error) { + entry, err := s.ledger.FetchAndVerifyPublicTransparencyLogEntry(ctx, actor, r.PathValue("id")) + return http.StatusOK, entry, err + }) +} + func (s *Server) createMarketplaceCollector(w http.ResponseWriter, r *http.Request) { var req struct { Name string `json:"name"` diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 9f9715a..a3a9611 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -613,6 +613,11 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Parameters = append(operation.Parameters, pathParam("id", "Public transparency log entry id.")) operation.RequestBody = jsonRequest("Public transparency log inclusion proof verification request.", "#/components/schemas/VerifyPublicTransparencyLogEntryRequest") operation.Responses[http.StatusOK] = jsonResponse("Verified public transparency log entry envelope.", "#/components/schemas/PublicTransparencyLogEntryEnvelope") + case "fetchPublicTransparencyLogEntryProof": + operation.Description = "Fetches public transparency inclusion proof material from the configured log endpoint and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities." + operation.Parameters = append(operation.Parameters, pathParam("id", "Public transparency log entry id.")) + operation.RequestBody = jsonRequest("Empty JSON object.", "#/components/schemas/EmptyObject") + operation.Responses[http.StatusOK] = jsonResponse("Fetched and verified public transparency log entry envelope.", "#/components/schemas/PublicTransparencyLogEntryEnvelope") case "createObjectRetentionPolicy": operation.Description = "Creates an object retention policy record for storage immutability verification." operation.RequestBody = jsonRequest("Object retention policy creation request.", "#/components/schemas/CreateObjectRetentionPolicyRequest") diff --git a/internal/adapters/httpapi/route_registration.go b/internal/adapters/httpapi/route_registration.go index be9494f..27d97ea 100644 --- a/internal/adapters/httpapi/route_registration.go +++ b/internal/adapters/httpapi/route_registration.go @@ -240,6 +240,7 @@ func (s *Server) integrityOpsRoutes() []routeDef { {http.MethodPost, "/v1/public-transparency-logs", op("createPublicTransparencyLog", http.MethodPost, "/v1/public-transparency-logs", "Create public transparency log record", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.createPublicTransparencyLog)}, {http.MethodPost, "/v1/public-transparency-log-entries", op("publishPublicTransparencyLogEntry", http.MethodPost, "/v1/public-transparency-log-entries", "Publish public transparency log entry record", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.publishPublicTransparencyLogEntry)}, {http.MethodPost, "/v1/public-transparency-log-entries/{id}/verify", op("verifyPublicTransparencyLogEntry", http.MethodPost, "/v1/public-transparency-log-entries/{id}/verify", "Verify public transparency log inclusion proof", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.verifyPublicTransparencyLogEntry)}, + {http.MethodPost, "/v1/public-transparency-log-entries/{id}/fetch-proof", op("fetchPublicTransparencyLogEntryProof", http.MethodPost, "/v1/public-transparency-log-entries/{id}/fetch-proof", "Fetch and verify public transparency log inclusion proof", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.fetchPublicTransparencyLogEntryProof)}, {http.MethodPost, "/v1/object-retention-policies", op("createObjectRetentionPolicy", http.MethodPost, "/v1/object-retention-policies", "Create object retention policy record", []string{app.ScopeAdmin}), http.HandlerFunc(s.createObjectRetentionPolicy)}, {http.MethodPost, "/v1/object-retention-policies/{id}/verify", op("verifyObjectRetentionPolicy", http.MethodPost, "/v1/object-retention-policies/{id}/verify", "Verify object retention policy record", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.verifyObjectRetentionPolicy)}, {http.MethodPost, "/v1/legal-holds", op("createLegalHold", http.MethodPost, "/v1/legal-holds", "Create legal hold", []string{app.ScopeAdmin}), http.HandlerFunc(s.createLegalHold)}, diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index eeb53d0..7a17295 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -2327,6 +2327,7 @@ func defaultSuccessStatus(operationID, method string) int { "approveException", "verifyObjectRetentionPolicy", "verifyPublicTransparencyLogEntry", + "fetchPublicTransparencyLogEntryProof", "revokeSigningKey", "verify": return http.StatusOK diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 0110526..49be956 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -177,6 +177,9 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { verifyProvider := operationMap(t, paths, "/v1/provider-verifications", "post") assertRequestRef(t, verifyProvider, "#/components/schemas/VerifyProviderIdentityRequest") assertResponseRef(t, verifyProvider, "201", "#/components/schemas/ProviderVerificationEnvelope") + fetchTransparencyProof := operationMap(t, paths, "/v1/public-transparency-log-entries/{id}/fetch-proof", "post") + assertRequestRef(t, fetchTransparencyProof, "#/components/schemas/EmptyObject") + assertResponseRef(t, fetchTransparencyProof, "200", "#/components/schemas/PublicTransparencyLogEntryEnvelope") verifyBundle := operationMap(t, paths, "/v1/release-bundles/{id}/verify", "get") assertQueryParams(t, verifyBundle, "id") assertResponseRef(t, verifyBundle, "200", "#/components/schemas/VerificationResultEnvelope") @@ -215,6 +218,33 @@ func TestSSOProviderOIDCDiscoveryRefreshRoute(t *testing.T) { } } +func TestPublicTransparencyProofFetchRoute(t *testing.T) { + fetcher := &fakeTransparencyProofHTTP{} + ledger := app.NewLedger(app.Config{APIKeyPepper: "test", Transparency: fetcher}) + _, _, secret, err := ledger.BootstrapTenant(t.Context(), "Tenant", "admin", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap: %v", err) + } + server, err := NewServer(ledger) + if err != nil { + t.Fatalf("server: %v", err) + } + logBody := postJSON(t, server, secret, "/v1/public-transparency-logs", "fetch-log", map[string]any{"name": "public", "endpoint": "https://transparency.example.test", "public_key": "pub"}, http.StatusCreated) + batchBody := postJSON(t, server, secret, "/v1/merkle-batches", "fetch-batch", map[string]any{}, http.StatusCreated) + checkpointBody := postJSON(t, server, secret, "/v1/transparency-checkpoints", "fetch-checkpoint", map[string]any{"batch_id": dataField(t, batchBody, "id"), "provider": "internal", "external_id": "ts"}, http.StatusCreated) + entryBody := postJSON(t, server, secret, "/v1/public-transparency-log-entries", "fetch-entry", map[string]any{"log_id": dataField(t, logBody, "id"), "checkpoint_id": dataField(t, checkpointBody, "id"), "external_id": "entry"}, http.StatusCreated) + entryID := dataField(t, entryBody, "id") + entryHash := dataField(t, entryBody, "entry_hash") + fetcher.result = app.TransparencyProofResult{ExternalID: "entry", RootHash: entryHash, LeafIndex: 0, TreeSize: 1, InclusionProof: []string{}} + fetched := postJSON(t, server, secret, "/v1/public-transparency-log-entries/"+entryID+"/fetch-proof", "fetch-proof", map[string]any{}, http.StatusOK) + if !strings.Contains(fetched, `"state":"inclusion_verified"`) || !strings.Contains(fetched, `"public_log_proof_source"`) { + t.Fatalf("fetched transparency proof response: %s", fetched) + } + if fetcher.request.ExternalID != "entry" || fetcher.request.EntryHash != entryHash { + t.Fatalf("fetch request = %#v", fetcher.request) + } +} + func TestOpenAPIDoesNotAdvertiseImpossibleSuccessStatusCodes(t *testing.T) { server, _ := testServer(t) docBytes, err := server.OpenAPI() @@ -1225,6 +1255,20 @@ func (f *fakeOIDCDiscoveryHTTP) FetchOIDCTrustMaterial(_ context.Context, req ap return f.result, nil } +type fakeTransparencyProofHTTP struct { + request app.TransparencyProofRequest + result app.TransparencyProofResult + err error +} + +func (f *fakeTransparencyProofHTTP) FetchTransparencyProof(_ context.Context, req app.TransparencyProofRequest) (app.TransparencyProofResult, error) { + f.request = req + if f.err != nil { + return app.TransparencyProofResult{}, f.err + } + return f.result, nil +} + func postJSON(t *testing.T, server *Server, secret, path, idem string, payload any, want int) string { t.Helper() body, err := json.Marshal(payload) diff --git a/internal/adapters/transparency/httpfetcher/httpfetcher.go b/internal/adapters/transparency/httpfetcher/httpfetcher.go new file mode 100644 index 0000000..92a4c7a --- /dev/null +++ b/internal/adapters/transparency/httpfetcher/httpfetcher.go @@ -0,0 +1,157 @@ +package httpfetcher + +import ( + "context" + "encoding/hex" + "encoding/json" + "errors" + "io" + "net" + "net/http" + "net/url" + "strings" + "time" + + "github.com/aatuh/evydence/internal/app" + "github.com/aatuh/evydence/internal/domain" +) + +const ( + defaultTimeout = 10 * time.Second + maxProofBytes = 128 * 1024 +) + +type Config struct { + Timeout time.Duration + AllowInsecureForLocalhost bool + Client *http.Client +} + +type Fetcher struct { + client *http.Client + allowInsecureForLocalhost bool +} + +type proofResponse struct { + ExternalID string `json:"external_id"` + LeafHash string `json:"leaf_hash"` + RootHash string `json:"root_hash"` + LeafIndex int `json:"leaf_index"` + TreeSize int `json:"tree_size"` + InclusionProof []string `json:"inclusion_proof"` +} + +func New(cfg Config) *Fetcher { + timeout := cfg.Timeout + if timeout <= 0 { + timeout = defaultTimeout + } + client := cfg.Client + if client == nil { + client = &http.Client{ + Timeout: timeout, + CheckRedirect: func(_ *http.Request, _ []*http.Request) error { + return http.ErrUseLastResponse + }, + } + } + return &Fetcher{client: client, allowInsecureForLocalhost: cfg.AllowInsecureForLocalhost} +} + +func (f *Fetcher) FetchTransparencyProof(ctx context.Context, req app.TransparencyProofRequest) (app.TransparencyProofResult, error) { + if f == nil || f.client == nil { + return app.TransparencyProofResult{}, app.ErrValidation + } + externalID := strings.TrimSpace(req.ExternalID) + if externalID == "" { + return app.TransparencyProofResult{}, app.ErrValidation + } + endpoint, err := parseEndpoint(req.Endpoint, f.allowInsecureForLocalhost) + if err != nil { + return app.TransparencyProofResult{}, err + } + endpoint.Path = strings.TrimRight(endpoint.Path, "/") + "/entries/" + url.PathEscape(externalID) + "/inclusion-proof" + endpoint.RawQuery = "" + endpoint.Fragment = "" + + httpReq, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil) + if err != nil { + return app.TransparencyProofResult{}, app.ErrValidation + } + httpReq.Header.Set("Accept", "application/json") + resp, err := f.client.Do(httpReq) + if err != nil { + return app.TransparencyProofResult{}, errors.New("fetch transparency proof") + } + defer resp.Body.Close() + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + _, _ = io.Copy(io.Discard, io.LimitReader(resp.Body, 4096)) + return app.TransparencyProofResult{}, app.ErrVerificationFailed + } + var decoded proofResponse + decoder := json.NewDecoder(io.LimitReader(resp.Body, maxProofBytes+1)) + decoder.DisallowUnknownFields() + if err := decoder.Decode(&decoded); err != nil { + return app.TransparencyProofResult{}, app.ErrVerificationFailed + } + if decoder.InputOffset() > maxProofBytes { + return app.TransparencyProofResult{}, app.ErrVerificationFailed + } + decoded.ExternalID = strings.TrimSpace(decoded.ExternalID) + decoded.LeafHash = strings.TrimSpace(decoded.LeafHash) + decoded.RootHash = strings.TrimSpace(decoded.RootHash) + if decoded.ExternalID != "" && decoded.ExternalID != externalID { + return app.TransparencyProofResult{}, app.ErrVerificationFailed + } + if !validSHA256Digest(decoded.RootHash) || (decoded.LeafHash != "" && !validSHA256Digest(decoded.LeafHash)) || decoded.TreeSize <= 0 || decoded.LeafIndex < 0 || decoded.LeafIndex >= decoded.TreeSize || len(decoded.InclusionProof) > 64 { + return app.TransparencyProofResult{}, app.ErrVerificationFailed + } + proof := make([]string, 0, len(decoded.InclusionProof)) + for _, hash := range decoded.InclusionProof { + hash = strings.TrimSpace(hash) + if !validSHA256Digest(hash) { + return app.TransparencyProofResult{}, app.ErrVerificationFailed + } + proof = append(proof, hash) + } + return app.TransparencyProofResult{ + ExternalID: decoded.ExternalID, + LeafHash: decoded.LeafHash, + RootHash: decoded.RootHash, + LeafIndex: decoded.LeafIndex, + TreeSize: decoded.TreeSize, + InclusionProof: proof, + Checks: []domain.VerifyCheck{{Name: "public_log_proof_fetch", Result: "passed"}}, + Limitations: []string{"Fetched public-log proof material is validated locally; endpoint trust and provider semantics remain deployment responsibilities."}, + }, nil +} + +func validSHA256Digest(value string) bool { + if !strings.HasPrefix(value, "sha256:") { + return false + } + raw, err := hex.DecodeString(strings.TrimPrefix(value, "sha256:")) + return err == nil && len(raw) == 32 +} + +func parseEndpoint(raw string, allowInsecureLocalhost bool) (*url.URL, error) { + parsed, err := url.Parse(strings.TrimSpace(raw)) + if err != nil || parsed.Scheme == "" || parsed.Host == "" || parsed.User != nil { + return nil, app.ErrValidation + } + if parsed.Scheme == "https" { + return parsed, nil + } + if parsed.Scheme == "http" && allowInsecureLocalhost && localhostHost(parsed.Hostname()) { + return parsed, nil + } + return nil, app.ErrValidation +} + +func localhostHost(host string) bool { + if strings.EqualFold(host, "localhost") { + return true + } + ip := net.ParseIP(host) + return ip != nil && ip.IsLoopback() +} diff --git a/internal/adapters/transparency/httpfetcher/httpfetcher_test.go b/internal/adapters/transparency/httpfetcher/httpfetcher_test.go new file mode 100644 index 0000000..f7545ee --- /dev/null +++ b/internal/adapters/transparency/httpfetcher/httpfetcher_test.go @@ -0,0 +1,59 @@ +package httpfetcher + +import ( + "encoding/json" + "net/http" + "net/http/httptest" + "strings" + "testing" + + "github.com/aatuh/evydence/internal/app" +) + +func TestFetchTransparencyProofFetchesStrictJSON(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/log/entries/entry-1/inclusion-proof" { + t.Fatalf("path = %s", r.URL.Path) + } + _ = json.NewEncoder(w).Encode(map[string]any{ + "external_id": "entry-1", + "root_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "leaf_index": 0, + "tree_size": 1, + "inclusion_proof": []string{}, + }) + })) + defer server.Close() + + fetcher := New(Config{AllowInsecureForLocalhost: true}) + result, err := fetcher.FetchTransparencyProof(t.Context(), app.TransparencyProofRequest{Endpoint: server.URL + "/log", ExternalID: "entry-1"}) + if err != nil { + t.Fatalf("FetchTransparencyProof: %v", err) + } + if result.ExternalID != "entry-1" || result.RootHash == "" || len(result.Checks) == 0 { + t.Fatalf("result = %#v", result) + } +} + +func TestFetchTransparencyProofRejectsInsecureRemoteEndpoint(t *testing.T) { + fetcher := New(Config{}) + if _, err := fetcher.FetchTransparencyProof(t.Context(), app.TransparencyProofRequest{Endpoint: "http://example.test/log", ExternalID: "entry-1"}); err == nil { + t.Fatal("FetchTransparencyProof err=nil, want insecure endpoint rejection") + } +} + +func TestFetchTransparencyProofRejectsUnknownFieldsAndDoesNotLeakBody(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + _, _ = w.Write([]byte(`{"root_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","leaf_index":0,"tree_size":1,"inclusion_proof":[],"provider_secret":"secret-value"}`)) + })) + defer server.Close() + + fetcher := New(Config{AllowInsecureForLocalhost: true}) + _, err := fetcher.FetchTransparencyProof(t.Context(), app.TransparencyProofRequest{Endpoint: server.URL, ExternalID: "entry-1"}) + if err == nil { + t.Fatal("FetchTransparencyProof err=nil, want strict JSON error") + } + if strings.Contains(err.Error(), "secret-value") { + t.Fatalf("error leaked provider body: %v", err) + } +} diff --git a/internal/app/future_extensions.go b/internal/app/future_extensions.go index 92062d0..b936a6e 100644 --- a/internal/app/future_extensions.go +++ b/internal/app/future_extensions.go @@ -63,6 +63,7 @@ type VerifyPublicTransparencyLogEntryInput struct { LeafIndex int TreeSize int InclusionProof []string + Source string } type CreateMarketplaceCollectorInput struct { @@ -458,6 +459,10 @@ func (l *Ledger) VerifyPublicTransparencyLogEntry(ctx context.Context, actor dom {Name: "public_log_leaf_binding", Result: checkResultString(leafBound), Detail: "The supplied leaf hash must match the published Evydence entry hash."}, {Name: "public_log_inclusion_proof", Result: checkResultString(proofOK), Detail: "The supplied proof must recompute the supplied public-log root hash."}, } + source := strings.TrimSpace(in.Source) + if source == "fetched" { + checks = append(checks, domain.VerifyCheck{Name: "public_log_proof_source", Result: "passed", Detail: "Inclusion proof material was fetched through the configured transparency proof fetcher."}) + } proofHash, err := canonicalAnyHash(struct { EntryID string `json:"entry_id"` LeafHash string `json:"leaf_hash"` @@ -465,6 +470,7 @@ func (l *Ledger) VerifyPublicTransparencyLogEntry(ctx context.Context, actor dom LeafIndex int `json:"leaf_index"` TreeSize int `json:"tree_size"` InclusionProof []string `json:"inclusion_proof"` + Source string `json:"source,omitempty"` }{ EntryID: entry.ID, LeafHash: leafHash, @@ -472,6 +478,7 @@ func (l *Ledger) VerifyPublicTransparencyLogEntry(ctx context.Context, actor dom LeafIndex: in.LeafIndex, TreeSize: in.TreeSize, InclusionProof: append([]string(nil), in.InclusionProof...), + Source: source, }) if err != nil { return domain.PublicTransparencyLogEntry{}, err @@ -482,9 +489,12 @@ func (l *Ledger) VerifyPublicTransparencyLogEntry(ctx context.Context, actor dom entry.InclusionVerifiedAt = &now entry.VerificationChecks = checks entry.VerificationLimitations = []string{ - "Evydence verifies the supplied RFC6962-style proof material locally; it does not fetch proof material or prove public-log availability.", + "Evydence verifies RFC6962-style proof material locally; the material may be supplied by an operator or fetched through a configured transparency proof fetcher.", "Operators remain responsible for public-log trust, endpoint availability, and any provider-specific inclusion semantics.", } + if source == "fetched" { + entry.VerificationLimitations = append(entry.VerificationLimitations, "Fetched proof material is trusted only as input to local verification; provider identity and availability remain deployment responsibilities.") + } entry.State = "inclusion_verified" if !proofOK { entry.State = "inclusion_not_verified" @@ -504,6 +514,61 @@ func (l *Ledger) VerifyPublicTransparencyLogEntry(ctx context.Context, actor dom return entry, nil } +func (l *Ledger) FetchAndVerifyPublicTransparencyLogEntry(ctx context.Context, actor domain.Actor, id string) (domain.PublicTransparencyLogEntry, error) { + if err := ctx.Err(); err != nil { + return domain.PublicTransparencyLogEntry{}, err + } + if err := require(actor, ScopeKeysAdmin); err != nil { + return domain.PublicTransparencyLogEntry{}, err + } + id = strings.TrimSpace(id) + if id == "" { + return domain.PublicTransparencyLogEntry{}, ErrValidation + } + fetcher := l.transparencyProofs + if fetcher == nil { + return domain.PublicTransparencyLogEntry{}, ErrValidation + } + l.mu.Lock() + entry, ok := l.publicLogEntries[id] + if !ok || entry.TenantID != actor.TenantID { + l.mu.Unlock() + return domain.PublicTransparencyLogEntry{}, ErrNotFound + } + logRecord, ok := l.publicLogs[entry.LogID] + if !ok || logRecord.TenantID != actor.TenantID { + l.mu.Unlock() + return domain.PublicTransparencyLogEntry{}, ErrNotFound + } + l.mu.Unlock() + + proof, err := fetcher.FetchTransparencyProof(ctx, TransparencyProofRequest{ + TenantID: actor.TenantID, + LogID: logRecord.ID, + EntryID: entry.ID, + Endpoint: logRecord.Endpoint, + ExternalID: entry.ExternalID, + EntryHash: entry.EntryHash, + }) + if err != nil { + return domain.PublicTransparencyLogEntry{}, ErrVerificationFailed + } + if proof.ExternalID != "" && proof.ExternalID != entry.ExternalID { + return domain.PublicTransparencyLogEntry{}, ErrVerificationFailed + } + if strings.TrimSpace(proof.LeafHash) == "" { + proof.LeafHash = entry.EntryHash + } + return l.VerifyPublicTransparencyLogEntry(ctx, actor, entry.ID, VerifyPublicTransparencyLogEntryInput{ + LeafHash: proof.LeafHash, + RootHash: proof.RootHash, + LeafIndex: proof.LeafIndex, + TreeSize: proof.TreeSize, + InclusionProof: proof.InclusionProof, + Source: "fetched", + }) +} + func verifyRFC6962StyleProof(leafHash, rootHash string, leafIndex, treeSize int, proof []string) bool { if treeSize == 1 { return leafIndex == 0 && len(proof) == 0 && leafHash == rootHash diff --git a/internal/app/future_extensions_test.go b/internal/app/future_extensions_test.go index 231f7e6..46bbcf9 100644 --- a/internal/app/future_extensions_test.go +++ b/internal/app/future_extensions_test.go @@ -92,6 +92,44 @@ func TestFutureExtensionsAreEvidenceBackedAndTenantScoped(t *testing.T) { _ = artifact } +func TestFetchAndVerifyPublicTransparencyLogEntryUsesFetcher(t *testing.T) { + fetcher := &fakeTransparencyProofFetcher{} + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow, Transparency: fetcher}) + ctx := context.Background() + actor, _, _ := setupReleaseRiskFixture(t, ledger) + batch, err := ledger.CreateMerkleBatch(ctx, actor, CreateMerkleBatchInput{}) + if err != nil { + t.Fatalf("merkle batch: %v", err) + } + log, err := ledger.CreatePublicTransparencyLog(ctx, actor, CreatePublicTransparencyLogInput{Name: "public-test", Endpoint: "https://transparency.example.test", PublicKey: "pub"}) + if err != nil { + t.Fatalf("public log: %v", err) + } + checkpoint, err := ledger.CreateTransparencyCheckpoint(ctx, actor, CreateTransparencyCheckpointInput{BatchID: batch.ID, Provider: "internal", ExternalID: "ts-1"}) + if err != nil { + t.Fatalf("checkpoint: %v", err) + } + entry, err := ledger.PublishPublicTransparencyLogEntry(ctx, actor, PublishPublicTransparencyLogEntryInput{LogID: log.ID, CheckpointID: checkpoint.ID, ExternalID: "entry-1"}) + if err != nil { + t.Fatalf("entry: %v", err) + } + fetcher.result = TransparencyProofResult{ExternalID: "entry-1", RootHash: entry.EntryHash, LeafIndex: 0, TreeSize: 1, InclusionProof: []string{}} + verified, err := ledger.FetchAndVerifyPublicTransparencyLogEntry(ctx, actor, entry.ID) + if err != nil { + t.Fatalf("fetch verify: %v", err) + } + if verified.State != "inclusion_verified" || !hasVerifyCheck(verified.VerificationChecks, "public_log_proof_source", "passed") { + t.Fatalf("verified = %#v", verified) + } + if fetcher.request.Endpoint != log.Endpoint || fetcher.request.ExternalID != entry.ExternalID || fetcher.request.EntryHash != entry.EntryHash { + t.Fatalf("fetch request = %#v", fetcher.request) + } + _, _, _, other := bootstrapEnterpriseTestTenant(t, ledger) + if _, err := ledger.FetchAndVerifyPublicTransparencyLogEntry(ctx, other, entry.ID); !errors.Is(err, ErrNotFound) { + t.Fatalf("cross tenant fetch err=%v, want not found", err) + } +} + func TestFutureOperationalExtensionsAndPartialTrustClosures(t *testing.T) { ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) ctx := context.Background() @@ -259,6 +297,20 @@ func (f *fakeSigningExecutor) Sign(_ context.Context, request SigningRequest) (S }, nil } +type fakeTransparencyProofFetcher struct { + request TransparencyProofRequest + result TransparencyProofResult + err error +} + +func (f *fakeTransparencyProofFetcher) FetchTransparencyProof(_ context.Context, request TransparencyProofRequest) (TransparencyProofResult, error) { + f.request = request + if f.err != nil { + return TransparencyProofResult{}, f.err + } + return f.result, nil +} + func TestSigningOperationCanExecuteConfiguredSignerWithoutPrivateKey(t *testing.T) { signer := &fakeSigningExecutor{} ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow, Signer: signer}) diff --git a/internal/app/ledger.go b/internal/app/ledger.go index 3b5eadd..6a62b50 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -69,20 +69,22 @@ type Config struct { Retention ObjectRetentionVerifier Signer SigningExecutor OIDC OIDCDiscoveryClient + Transparency TransparencyProofFetcher Outbox Outbox } type Ledger struct { mu sync.Mutex - pepper []byte - now func() time.Time - store Store - objects ObjectStore - retention ObjectRetentionVerifier - signer SigningExecutor - oidc OIDCDiscoveryClient - outbox Outbox + pepper []byte + now func() time.Time + store Store + objects ObjectStore + retention ObjectRetentionVerifier + signer SigningExecutor + oidc OIDCDiscoveryClient + transparencyProofs TransparencyProofFetcher + outbox Outbox tenants map[string]domain.Tenant organizations map[string]domain.Organization @@ -206,6 +208,7 @@ func NewLedgerWithError(cfg Config) (*Ledger, error) { retention: retention, signer: cfg.Signer, oidc: cfg.OIDC, + transparencyProofs: cfg.Transparency, outbox: cfg.Outbox, tenants: map[string]domain.Tenant{}, organizations: map[string]domain.Organization{}, diff --git a/internal/app/ports.go b/internal/app/ports.go index 1e8799e..4fc0e19 100644 --- a/internal/app/ports.go +++ b/internal/app/ports.go @@ -29,6 +29,10 @@ type OIDCDiscoveryClient interface { FetchOIDCTrustMaterial(context.Context, OIDCDiscoveryRequest) (OIDCDiscoveryResult, error) } +type TransparencyProofFetcher interface { + FetchTransparencyProof(context.Context, TransparencyProofRequest) (TransparencyProofResult, error) +} + type Outbox interface { Enqueue(context.Context, OutboxJob) error } @@ -63,6 +67,26 @@ type OIDCDiscoveryResult struct { Limitations []string } +type TransparencyProofRequest struct { + TenantID string + LogID string + EntryID string + Endpoint string + ExternalID string + EntryHash string +} + +type TransparencyProofResult struct { + ExternalID string + LeafHash string + RootHash string + LeafIndex int + TreeSize int + InclusionProof []string + Checks []domain.VerifyCheck + Limitations []string +} + type ObjectRetentionRequest struct { TenantID string ObjectPrefix string diff --git a/openapi.yaml b/openapi.yaml index e701cb9..16ea5ef 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/sdk/openapi-route-catalog.json b/sdk/openapi-route-catalog.json index 5d99985..89b378e 100644 --- a/sdk/openapi-route-catalog.json +++ b/sdk/openapi-route-catalog.json @@ -1,5 +1,5 @@ { - "route_count": 164, + "route_count": 165, "routes": [ { "idempotency_key_required": false, @@ -1485,6 +1485,23 @@ "201" ] }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "fetchPublicTransparencyLogEntryProof", + "path": "/v1/public-transparency-log-entries/{id}/fetch-proof", + "request_schema": "#/components/schemas/EmptyObject", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/PublicTransparencyLogEntryEnvelope" + ], + "scopes": [ + "keys:admin" + ], + "success_statuses": [ + "200" + ] + }, { "idempotency_key_required": true, "method": "POST", From 9daa5070171d592bc829cc16a15bd1811c337067 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 21:35:20 +0300 Subject: [PATCH 108/287] feat: add sso credential exchange --- README.md | 4 +- docs/api.md | 3 +- docs/architecture.md | 2 +- docs/operations.md | 2 +- docs/reference/api-contract-matrix.md | 3 +- docs/reference/production-readiness.md | 22 ++-- .../adapters/httpapi/identity_handlers.go | 56 +++++++++ internal/adapters/httpapi/openapi.go | 13 +++ .../adapters/httpapi/openapi_operations.go | 6 + .../adapters/httpapi/route_registration.go | 1 + internal/adapters/httpapi/router.go | 17 ++- internal/adapters/httpapi/router_test.go | 78 ++++++++++++- internal/app/enterprise.go | 110 ++++++++++++++++++ internal/app/enterprise_test.go | 60 ++++++++++ openapi.yaml | 2 +- sdk/openapi-route-catalog.json | 17 ++- 16 files changed, 376 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index b049a5f..b1364b8 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ This repository contains a Go implementation under module `github.com/aatuh/evyd - AGPL license, commercial licensing, governance, contribution, security, support, trademark, release-evidence, and changelog metadata. -Implemented-but-partial areas are documented explicitly: signing-provider operation receipts do not replace direct production KMS/HSM SDK adapters, OIDC discovery refreshes public JWKS trust material but does not replace full browser login callbacks or provider API validation, and public transparency records can verify operator-supplied or fetched inclusion proof material without replacing provider-specific trust review. +Implemented-but-partial areas are documented explicitly: signing-provider operation receipts do not replace direct production KMS/HSM SDK adapters, SSO credential exchange uses configured local OIDC/SAML trust material but does not replace live provider API validation or group synchronization, and public transparency records can verify operator-supplied or fetched inclusion proof material without replacing provider-specific trust review. ## License, Security, Support, And Governance @@ -107,4 +107,4 @@ make postgres-integration-test `make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. -`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required production-readiness evidence, but it does not by itself close the remaining repository-split, worker side-effect, direct KMS/HSM SDK, browser SSO, provider API validation, object-lock enforcement, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. +`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required production-readiness evidence, but it does not by itself close the remaining repository-split, worker side-effect, direct KMS/HSM SDK, provider API/group validation, object-lock enforcement, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. diff --git a/docs/api.md b/docs/api.md index 77be639..1ef1ba7 100644 --- a/docs/api.md +++ b/docs/api.md @@ -245,12 +245,13 @@ Important scope boundaries: | `POST` | `/v1/sso/providers/{id}/discover-oidc` | Fetch OIDC discovery metadata and refresh public JWKS trust material. | | `POST` | `/v1/sso/identity-links` | Link verified provider subject to user. | | `POST` | `/v1/sso/sessions` | Issue one-time session secret. | +| `POST` | `/v1/sso/session-exchanges` | Exchange a locally verified OIDC ID token or SAML assertion for a session secret and HttpOnly cookie. | | `POST` | `/v1/sso/sessions/{id}/revoke` | Revoke session. | | `POST` | `/v1/sso/logout` | Revoke the currently authenticated SSO session. | | `POST` | `/v1/api-keys` | Create one-time API key secret. | | `GET` | `/v1/api-keys` | List keys without secret hashes. | -Current SSO endpoints model admin-managed provider, identity-link, trust-material, and session records plus API-first session logout. OIDC provider records can include public JWKS material, and SAML provider records can include PEM-encoded assertion signing certificates; both can be rotated through `POST /v1/sso/providers/{id}/trust-material`. OIDC public JWKS can also be refreshed from the configured issuer with `POST /v1/sso/providers/{id}/discover-oidc`. `POST /v1/provider-verifications` can verify a supplied OIDC ID token or SAML assertion locally for issuer, audience, subject, time bounds, and signature. Live provider API calls, full browser login callbacks, browser cookie/session handling, and group synchronization are not implemented in this slice. +Current SSO endpoints model admin-managed provider, identity-link, trust-material, and session records plus API-first session logout. OIDC provider records can include public JWKS material, and SAML provider records can include PEM-encoded assertion signing certificates; both can be rotated through `POST /v1/sso/providers/{id}/trust-material`. OIDC public JWKS can also be refreshed from the configured issuer with `POST /v1/sso/providers/{id}/discover-oidc`. `POST /v1/provider-verifications` can verify a supplied OIDC ID token or SAML assertion locally for issuer, audience, subject, time bounds, and signature. `POST /v1/sso/session-exchanges` uses the same local verification and a verified identity link to issue a one-time SSO bearer secret and an HttpOnly cookie for browser clients. Live provider API validation and group synchronization are not implemented in this slice. ### Products, Releases, Evidence, And Risk diff --git a/docs/architecture.md b/docs/architecture.md index a14767a..20d6033 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -52,6 +52,6 @@ Air-gapped import-bundle workflows preserve the same tenant-scoped import path a ## Limitations -The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts and an optional HTTPS signing gateway executor are implemented, but direct cloud KMS/HSM SDK adapters, live Sigstore verification, and live public-transparency proof fetching remain deployment hardening work. Hand-tuned per-resource repository implementations and moving parser side effects fully out of request paths remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. +The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, OIDC discovery refresh, SSO credential exchange, and public-transparency proof fetching are implemented, but direct cloud KMS/HSM SDK adapters, live Sigstore verification, live provider API validation, and group synchronization remain deployment hardening work. Hand-tuned per-resource repository implementations and moving parser side effects fully out of request paths remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. Evydence does not prove provider truth, scanner authority, runtime security, legal compliance, or release security by itself. diff --git a/docs/operations.md b/docs/operations.md index 584fe46..d32ba60 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -30,7 +30,7 @@ This operator index points to the canonical references for running Evydence. Kee - API keys, collector keys, SSO session tokens, and customer portal access tokens are bearer secrets. Do not place them in logs, documentation, long-lived build output, or customer packages. - Customer portal access tokens are returned once by `POST /v1/customer-portal/access`, expire, and are stored as hashes. Deployments should still use reverse-proxy or API-gateway throttling for the unauthenticated portal endpoint. -- Human SSO session records are admin-managed, and authenticated SSO sessions can revoke themselves through API-first logout. Current endpoints can refresh OIDC public JWKS from discovery metadata and verify supplied OIDC tokens and SAML assertions against tenant-configured local trust material, but they do not implement production browser login callbacks, live provider API validation, group synchronization, or browser cookie/session handling. +- Human SSO session records are admin-managed, authenticated SSO sessions can revoke themselves through API-first logout, and SSO credential exchange can set an HttpOnly session cookie after locally verifying an OIDC ID token or SAML assertion against tenant-configured trust material. Current endpoints can refresh OIDC public JWKS from discovery metadata, but they do not implement live provider API validation or group synchronization. - Object-retention APIs record and verify retention intent for tenant-prefixed object paths. Enforcing WORM or object-lock settings remains the responsibility of the configured object store and deployment policy. Evydence operations support evidence organization, review, and tamper-evident records. Operational checks do not replace external audit review, secret management, backup testing, or provider verification. diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index 11109a4..dde446b 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 165 operations: 165 precise, 0 broad. +Generated from 166 operations: 166 precise, 0 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -156,6 +156,7 @@ Generated from 165 operations: 165 precise, 0 broad. | POST | /v1/sso/providers | createSSOProvider | Bearer | identity:admin | required | - | application/json:CreateSSOProviderRequest | 201:application/json:SSOProviderEnvelope | precise | | POST | /v1/sso/providers/{id}/discover-oidc | refreshSSOProviderOIDCTrustMaterial | Bearer | identity:admin | required | path:id | application/json:EmptyObject | 200:application/json:SSOProviderEnvelope | precise | | POST | /v1/sso/providers/{id}/trust-material | updateSSOProviderTrustMaterial | Bearer | identity:admin | required | path:id | application/json:UpdateSSOProviderTrustMaterialRequest | 200:application/json:SSOProviderEnvelope | precise | +| POST | /v1/sso/session-exchanges | exchangeSSOCredential | public | - | not required | - | application/json:ExchangeSSOCredentialRequest | 201:application/json:SSOCredentialExchangeEnvelope | precise | | POST | /v1/sso/sessions | createSSOSession | Bearer | identity:admin | required | - | application/json:CreateSSOSessionRequest | 201:application/json:SSOSessionCreateEnvelope | precise | | POST | /v1/sso/sessions/{id}/revoke | revokeSSOSession | Bearer | identity:admin | required | path:id | application/json:EmptyObject | 200:application/json:SSOSessionEnvelope | precise | | POST | /v1/transparency-checkpoints | createTransparencyCheckpoint | Bearer | keys:admin | required | - | application/json:CreateTransparencyCheckpointRequest | 201:application/json:TransparencyCheckpointEnvelope | precise | diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 03d913a..6bd343b 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -44,12 +44,13 @@ Known hardening work remains: matrix remains the source of truth for operation ids, scopes, idempotency, parameters, and request/response schemas; - production signing can use the HTTPS signing gateway executor, but direct - cloud KMS/HSM SDK adapters, full browser OIDC/SAML login flows, provider - API validation/group sync, and broad object-lock enforcement proof remain - provider- and deployment-dependent hardening areas. Public transparency proof - material can be fetched from a configured endpoint and verified locally, but - provider-specific trust semantics and availability remain deployment - responsibilities; + cloud KMS/HSM SDK adapters, live provider API validation/group sync, and + broad object-lock enforcement proof remain provider- and deployment-dependent + hardening areas. SSO credential exchange can issue bearer sessions and + HttpOnly cookies after local OIDC/SAML verification against configured trust + material, and public transparency proof material can be fetched from a + configured endpoint and verified locally, but provider-specific trust + semantics and availability remain deployment responsibilities; - the broader production exit review remains incomplete. ## Production Profiles @@ -147,12 +148,13 @@ implemented capabilities: - Add direct cloud KMS/HSM SDK adapters where required. The current HTTPS signing gateway executor covers deployments that put KMS/HSM custody behind a tenant-controlled signing service and do not send raw payload bytes. -- Complete live OIDC/SAML browser login callbacks, browser cookie/session - handling, provider API validation, and optional group mapping where those +- Complete live provider API validation and optional group mapping where those profiles are enabled. OIDC discovery/JWKS refresh is implemented for public trust-material updates, manual JWKS and SAML signing-certificate rotation is - implemented through the SSO provider trust-material endpoint, and API-first - session logout can revoke the current SSO bearer session. + implemented through the SSO provider trust-material endpoint, SSO credential + exchange can issue bearer sessions plus HttpOnly cookies after local token or + assertion verification, and API-first session logout can revoke the current + SSO bearer session. - Extend object-lock/WORM verification beyond the current S3/MinIO bucket-level checks plus optional sample-object retention checks where deployments require broader object-level legal hold proofs or provider policy evidence. diff --git a/internal/adapters/httpapi/identity_handlers.go b/internal/adapters/httpapi/identity_handlers.go index dcb5207..d580571 100644 --- a/internal/adapters/httpapi/identity_handlers.go +++ b/internal/adapters/httpapi/identity_handlers.go @@ -8,6 +8,8 @@ import ( "github.com/aatuh/evydence/internal/domain" ) +const ssoSessionCookieName = "evydence_session" + func (s *Server) instanceAdminSnapshot(w http.ResponseWriter, r *http.Request) { actor, ok := s.authenticate(w, r) if !ok { @@ -160,6 +162,32 @@ func (s *Server) createSSOSession(w http.ResponseWriter, r *http.Request) { }) } +func (s *Server) exchangeSSOCredential(w http.ResponseWriter, r *http.Request) { + var req struct { + ProviderID string `json:"provider_id"` + Subject string `json:"subject"` + IDToken string `json:"id_token"` + SAMLAssertion string `json:"saml_assertion"` + ExpiresAt time.Time `json:"expires_at"` + } + body, err := readBody(r) + if err != nil { + writeProblem(w, r, err) + return + } + if err := decodeJSON(body, &req); err != nil { + writeProblem(w, r, err) + return + } + verification, session, secret, err := s.ledger.ExchangeSSOCredential(r.Context(), app.ExchangeSSOCredentialInput{ProviderID: req.ProviderID, Subject: req.Subject, IDToken: req.IDToken, SAMLAssertion: req.SAMLAssertion, ExpiresAt: req.ExpiresAt}) + if err != nil { + writeProblem(w, r, err) + return + } + setSSOSessionCookie(w, secret, session.ExpiresAt) + writeData(w, http.StatusCreated, map[string]any{"verification": verification, "session": session, "secret": secret}) +} + func (s *Server) revokeSSOSession(w http.ResponseWriter, r *http.Request) { s.create(w, r, func(ctx requestContext, actor domain.Actor, _ []byte) (int, any, error) { session, err := s.ledger.RevokeSSOSession(ctx, actor, r.PathValue("id")) @@ -170,6 +198,34 @@ func (s *Server) revokeSSOSession(w http.ResponseWriter, r *http.Request) { func (s *Server) logoutSSOSession(w http.ResponseWriter, r *http.Request) { s.create(w, r, func(ctx requestContext, actor domain.Actor, _ []byte) (int, any, error) { session, err := s.ledger.RevokeCurrentSSOSession(ctx, actor) + if err == nil { + clearSSOSessionCookie(w) + } return http.StatusOK, session, err }) } + +func setSSOSessionCookie(w http.ResponseWriter, secret string, expiresAt time.Time) { + http.SetCookie(w, &http.Cookie{ + Name: ssoSessionCookieName, + Value: secret, + Path: "/v1", + Expires: expiresAt.UTC(), + HttpOnly: true, + Secure: true, + SameSite: http.SameSiteStrictMode, + }) +} + +func clearSSOSessionCookie(w http.ResponseWriter) { + http.SetCookie(w, &http.Cookie{ + Name: ssoSessionCookieName, + Value: "", + Path: "/v1", + Expires: time.Unix(0, 0).UTC(), + MaxAge: -1, + HttpOnly: true, + Secure: true, + SameSite: http.SameSiteStrictMode, + }) +} diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 52e5334..68860ab 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -75,6 +75,13 @@ func registerCriticalSchemas(registry *specs.Registry) { "provider_id": map[string]any{"type": "string"}, "expires_at": map[string]any{"type": "string", "format": "date-time"}, }, "user_id", "provider_id", "expires_at")) + registry.RegisterSchema("ExchangeSSOCredentialRequest", objectSchema(map[string]any{ + "provider_id": map[string]any{"type": "string"}, + "subject": map[string]any{"type": "string"}, + "id_token": map[string]any{"type": "string", "description": "OIDC ID token verified locally against configured public JWKS trust material."}, + "saml_assertion": map[string]any{"type": "string", "description": "SAML assertion verified locally against configured SAML signing certificates."}, + "expires_at": map[string]any{"type": "string", "format": "date-time", "description": "Optional session expiry, capped by the server."}, + }, "provider_id", "subject")) registry.RegisterSchema("CreateSSOProviderRequest", objectSchema(map[string]any{ "name": map[string]any{"type": "string"}, "type": map[string]any{"type": "string", "enum": []string{"oidc", "saml"}}, @@ -1325,6 +1332,12 @@ func registerCriticalSchemas(registry *specs.Registry) { "secret": map[string]any{"type": "string", "description": "One-time SSO session bearer secret; not returned by list/read operations."}, }, "session", "secret")) registry.RegisterSchema("SSOSessionCreateEnvelope", dataEnvelopeSchema("#/components/schemas/SSOSessionCreateResponse")) + registry.RegisterSchema("SSOCredentialExchangeResponse", objectSchema(map[string]any{ + "verification": map[string]any{"$ref": "#/components/schemas/ProviderVerification"}, + "session": map[string]any{"$ref": "#/components/schemas/SSOSession"}, + "secret": map[string]any{"type": "string", "description": "One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients."}, + }, "verification", "session", "secret")) + registry.RegisterSchema("SSOCredentialExchangeEnvelope", dataEnvelopeSchema("#/components/schemas/SSOCredentialExchangeResponse")) registry.RegisterSchema("CreateAPIKeyRequest", objectSchema(map[string]any{ "name": map[string]any{"type": "string"}, "scopes": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index a3a9611..1062056 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -66,6 +66,12 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Description = "Creates an admin-managed human SSO session record and returns a one-time bearer secret." operation.RequestBody = jsonRequest("SSO session creation request.", "#/components/schemas/CreateSSOSessionRequest") operation.Responses[http.StatusCreated] = jsonResponse("Created SSO session and one-time secret envelope.", "#/components/schemas/SSOSessionCreateEnvelope") + case "exchangeSSOCredential": + operation.Description = "Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made." + operation.Security = nil + operation.Scopes = nil + operation.RequestBody = jsonRequest("SSO credential exchange request.", "#/components/schemas/ExchangeSSOCredentialRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created SSO session, verification receipt, and one-time secret envelope.", "#/components/schemas/SSOCredentialExchangeEnvelope") case "revokeSSOSession": operation.Description = "Revokes a tenant-scoped SSO session as an audited lifecycle transition." operation.Parameters = append(operation.Parameters, pathParam("id", "SSO session id.")) diff --git a/internal/adapters/httpapi/route_registration.go b/internal/adapters/httpapi/route_registration.go index 27d97ea..ff667d1 100644 --- a/internal/adapters/httpapi/route_registration.go +++ b/internal/adapters/httpapi/route_registration.go @@ -69,6 +69,7 @@ func (s *Server) identityRoutes() []routeDef { {http.MethodPost, "/v1/sso/providers/{id}/discover-oidc", op("refreshSSOProviderOIDCTrustMaterial", http.MethodPost, "/v1/sso/providers/{id}/discover-oidc", "Refresh SSO provider OIDC trust material", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.refreshSSOProviderOIDCTrustMaterial)}, {http.MethodPost, "/v1/sso/identity-links", op("linkSSOIdentity", http.MethodPost, "/v1/sso/identity-links", "Link SSO identity", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.linkSSOIdentity)}, {http.MethodPost, "/v1/sso/sessions", op("createSSOSession", http.MethodPost, "/v1/sso/sessions", "Create SSO session", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.createSSOSession)}, + {http.MethodPost, "/v1/sso/session-exchanges", publicPostOp("exchangeSSOCredential", http.MethodPost, "/v1/sso/session-exchanges", "Exchange SSO credential"), http.HandlerFunc(s.exchangeSSOCredential)}, {http.MethodPost, "/v1/sso/sessions/{id}/revoke", op("revokeSSOSession", http.MethodPost, "/v1/sso/sessions/{id}/revoke", "Revoke SSO session", []string{app.ScopeIdentityAdmin}), http.HandlerFunc(s.revokeSSOSession)}, {http.MethodPost, "/v1/sso/logout", authenticatedOp("logoutSSOSession", http.MethodPost, "/v1/sso/logout", "Logout SSO session"), http.HandlerFunc(s.logoutSSOSession)}, } diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index 7a17295..97c5781 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -2055,7 +2055,14 @@ func (s *Server) create(w http.ResponseWriter, r *http.Request, run func(request } func (s *Server) authenticate(w http.ResponseWriter, r *http.Request) (domain.Actor, bool) { - actor, err := s.ledger.Authenticate(r.Context(), strings.TrimSpace(strings.TrimPrefix(r.Header.Get("Authorization"), "Bearer "))) + authHeader := strings.TrimSpace(r.Header.Get("Authorization")) + token := strings.TrimSpace(strings.TrimPrefix(authHeader, "Bearer ")) + if authHeader == "" { + if cookie, err := r.Cookie(ssoSessionCookieName); err == nil { + token = strings.TrimSpace(cookie.Value) + } + } + actor, err := s.ledger.Authenticate(r.Context(), token) if err != nil { writeProblem(w, r, err) return domain.Actor{}, false @@ -2302,6 +2309,14 @@ func authenticatedOp(id, method, path, summary string) specs.Operation { return operation } +func publicPostOp(id, method, path, summary string) specs.Operation { + operation := op(id, method, path, summary, nil) + operation.Security = nil + operation.Scopes = nil + operation.Extensions = nil + return operation +} + func defaultSuccessStatus(operationID, method string) int { if method == http.MethodGet { return http.StatusOK diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 49be956..0ae6786 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -85,7 +85,7 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { if _, ok := problemProps["request_id"]; !ok { t.Fatalf("Problem schema missing request_id: %#v", problemProps) } - for _, schemaName := range []string{"ReadinessStatusEnvelope", "BackupManifestEnvelope", "VerificationResultEnvelope", "ReadinessReportEnvelope", "CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "UpdateSSOProviderTrustMaterialRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "DataEnvelope"} { + for _, schemaName := range []string{"ReadinessStatusEnvelope", "BackupManifestEnvelope", "VerificationResultEnvelope", "ReadinessReportEnvelope", "CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "UpdateSSOProviderTrustMaterialRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "ExchangeSSOCredentialRequest", "SSOCredentialExchangeEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "DataEnvelope"} { if _, ok := schemas[schemaName]; !ok { t.Fatalf("schema %s missing from OpenAPI components", schemaName) } @@ -177,6 +177,12 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { verifyProvider := operationMap(t, paths, "/v1/provider-verifications", "post") assertRequestRef(t, verifyProvider, "#/components/schemas/VerifyProviderIdentityRequest") assertResponseRef(t, verifyProvider, "201", "#/components/schemas/ProviderVerificationEnvelope") + exchangeSSO := operationMap(t, paths, "/v1/sso/session-exchanges", "post") + assertRequestRef(t, exchangeSSO, "#/components/schemas/ExchangeSSOCredentialRequest") + assertResponseRef(t, exchangeSSO, "201", "#/components/schemas/SSOCredentialExchangeEnvelope") + if _, ok := exchangeSSO["security"]; ok { + t.Fatalf("public SSO credential exchange should not require bearer auth in OpenAPI: %#v", exchangeSSO) + } fetchTransparencyProof := operationMap(t, paths, "/v1/public-transparency-log-entries/{id}/fetch-proof", "post") assertRequestRef(t, fetchTransparencyProof, "#/components/schemas/EmptyObject") assertResponseRef(t, fetchTransparencyProof, "200", "#/components/schemas/PublicTransparencyLogEntryEnvelope") @@ -218,6 +224,76 @@ func TestSSOProviderOIDCDiscoveryRefreshRoute(t *testing.T) { } } +func TestSSOCredentialExchangeRouteSetsSessionCookie(t *testing.T) { + pub, priv, err := ed25519.GenerateKey(rand.Reader) + if err != nil { + t.Fatalf("keygen: %v", err) + } + ledger := app.NewLedger(app.Config{APIKeyPepper: "test"}) + _, _, secret, err := ledger.BootstrapTenant(t.Context(), "Tenant", "admin", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap: %v", err) + } + admin, err := ledger.Authenticate(t.Context(), secret) + if err != nil { + t.Fatalf("auth: %v", err) + } + jwks := map[string]any{"keys": []any{map[string]any{"kty": "OKP", "crv": "Ed25519", "kid": "kid-login", "x": base64.RawURLEncoding.EncodeToString(pub)}}} + provider, err := ledger.CreateSSOProvider(t.Context(), admin, app.CreateSSOProviderInput{Name: "OIDC", Type: "oidc", Issuer: "https://idp.example.test", ClientID: "client", JWKS: jwks}) + if err != nil { + t.Fatalf("provider: %v", err) + } + org, err := ledger.CreateOrganization(t.Context(), admin, app.CreateOrganizationInput{Name: "Example", Slug: "example"}) + if err != nil { + t.Fatalf("org: %v", err) + } + user, err := ledger.CreateUser(t.Context(), admin, app.CreateUserInput{OrganizationID: org.ID, Email: "user@example.test", DisplayName: "User"}) + if err != nil { + t.Fatalf("user: %v", err) + } + if _, err := ledger.LinkSSOIdentity(t.Context(), admin, app.LinkSSOIdentityInput{UserID: user.ID, ProviderID: provider.ID, Subject: "sub-1", Email: user.Email, Verified: true}); err != nil { + t.Fatalf("link: %v", err) + } + if _, err := ledger.CreateRoleBinding(t.Context(), admin, app.CreateRoleBindingInput{SubjectType: "user", SubjectID: user.ID, Role: "security_engineer"}); err != nil { + t.Fatalf("role binding: %v", err) + } + server, err := NewServer(ledger) + if err != nil { + t.Fatalf("server: %v", err) + } + idToken := signedRouterIDToken(t, priv, "kid-login", map[string]any{"iss": provider.Issuer, "aud": provider.ClientID, "sub": "sub-1", "email": user.Email, "email_verified": true, "exp": time.Now().Add(time.Hour).Unix()}) + body, err := json.Marshal(map[string]any{"provider_id": provider.ID, "subject": "sub-1", "id_token": idToken}) + if err != nil { + t.Fatalf("marshal body: %v", err) + } + rec := httptest.NewRecorder() + req := httptest.NewRequest(http.MethodPost, "/v1/sso/session-exchanges", bytes.NewReader(body)) + req.Header.Set("Content-Type", "application/json") + server.Handler().ServeHTTP(rec, req) + if rec.Code != http.StatusCreated { + t.Fatalf("exchange status=%d body=%s", rec.Code, rec.Body.String()) + } + cookie := rec.Result().Cookies()[0] + if cookie.Name != ssoSessionCookieName || !cookie.HttpOnly || cookie.Value == "" { + t.Fatalf("session cookie = %#v", cookie) + } + if strings.Contains(rec.Body.String(), idToken) { + t.Fatalf("exchange response leaked id token: %s", rec.Body.String()) + } + rec = httptest.NewRecorder() + req = httptest.NewRequest(http.MethodPost, "/v1/sso/logout", strings.NewReader(`{}`)) + req.AddCookie(cookie) + req.Header.Set("Idempotency-Key", "logout-cookie-session") + server.Handler().ServeHTTP(rec, req) + if rec.Code != http.StatusOK { + t.Fatalf("cookie logout status=%d body=%s", rec.Code, rec.Body.String()) + } + cleared := rec.Result().Cookies()[0] + if cleared.Name != ssoSessionCookieName || cleared.MaxAge != -1 { + t.Fatalf("cleared cookie = %#v", cleared) + } +} + func TestPublicTransparencyProofFetchRoute(t *testing.T) { fetcher := &fakeTransparencyProofHTTP{} ledger := app.NewLedger(app.Config{APIKeyPepper: "test", Transparency: fetcher}) diff --git a/internal/app/enterprise.go b/internal/app/enterprise.go index 8ae4401..95379df 100644 --- a/internal/app/enterprise.go +++ b/internal/app/enterprise.go @@ -61,6 +61,14 @@ type CreateSSOSessionInput struct { ExpiresAt time.Time } +type ExchangeSSOCredentialInput struct { + ProviderID string + Subject string + IDToken string + SAMLAssertion string + ExpiresAt time.Time +} + type CreateLegalHoldInput struct { ScopeType string ScopeID string @@ -472,6 +480,108 @@ func (l *Ledger) CreateSSOSession(ctx context.Context, actor domain.Actor, in Cr return session, secret, nil } +func (l *Ledger) ExchangeSSOCredential(ctx context.Context, in ExchangeSSOCredentialInput) (domain.ProviderVerification, domain.SSOSession, string, error) { + if err := ctx.Err(); err != nil { + return domain.ProviderVerification{}, domain.SSOSession{}, "", err + } + providerID, subject := strings.TrimSpace(in.ProviderID), strings.TrimSpace(in.Subject) + idToken, samlAssertion := strings.TrimSpace(in.IDToken), strings.TrimSpace(in.SAMLAssertion) + if providerID == "" || subject == "" || (idToken == "" && samlAssertion == "") || (idToken != "" && samlAssertion != "") { + return domain.ProviderVerification{}, domain.SSOSession{}, "", ErrValidation + } + expiresAt := in.ExpiresAt.UTC() + now := l.now() + if expiresAt.IsZero() { + expiresAt = now.Add(8 * time.Hour) + } + if !expiresAt.After(now) || expiresAt.After(now.Add(12*time.Hour)) { + return domain.ProviderVerification{}, domain.SSOSession{}, "", ErrValidation + } + + l.mu.Lock() + defer l.mu.Unlock() + provider, ok := l.ssoProviders[providerID] + if !ok || provider.Status != "active" { + return domain.ProviderVerification{}, domain.SSOSession{}, "", ErrNotFound + } + if (provider.Type == "oidc" && samlAssertion != "") || (provider.Type == "saml" && idToken != "") { + return domain.ProviderVerification{}, domain.SSOSession{}, "", ErrValidation + } + checks := []domain.VerifyCheck{} + result := "passed" + if idToken != "" { + tokenChecks, err := verifyOIDCIDToken(provider, subject, idToken, now) + checks = append(checks, tokenChecks...) + if err != nil { + result = "failed" + } + } + if samlAssertion != "" { + assertionChecks, err := verifySAMLAssertion(provider, subject, samlAssertion, now) + checks = append(checks, assertionChecks...) + if err != nil { + result = "failed" + } + } + + var link domain.UserIdentityLink + for _, candidate := range l.identityLinks { + if candidate.TenantID == provider.TenantID && candidate.ProviderID == provider.ID && candidate.Subject == subject && candidate.Verified { + link = candidate + break + } + } + if link.ID == "" { + result = "failed" + checks = append(checks, domain.VerifyCheck{Name: "verified_identity_link", Result: "failed"}) + } else { + checks = append(checks, domain.VerifyCheck{Name: "verified_identity_link", Result: "passed"}) + } + + verification := domain.ProviderVerification{ + ID: newID("pvr"), + TenantID: provider.TenantID, + ProviderType: provider.Type, + ProviderID: provider.ID, + Subject: subject, + Result: result, + Checks: checks, + Limitations: []string{"Credential exchange uses configured local token/assertion trust roots and verified identity links; no live provider API or group synchronization call is made."}, + SchemaVersion: domain.ProviderVerificationVersion, + CreatedAt: now, + } + l.providerVerifications[verification.ID] = verification + _, _ = l.appendChainLocked(provider.TenantID, "provider_identity.verified", "provider_identity", verification.ID, "sso_provider", provider.ID, "", "") + if result != "passed" { + if err := l.persistLocked(ctx); err != nil { + return domain.ProviderVerification{}, domain.SSOSession{}, "", err + } + return verification, domain.SSOSession{}, "", ErrVerificationFailed + } + user, ok := l.users[link.UserID] + if !ok || user.TenantID != provider.TenantID || user.Status != "active" { + verification.Result = "failed" + verification.Checks = append(verification.Checks, domain.VerifyCheck{Name: "active_user", Result: "failed"}) + l.providerVerifications[verification.ID] = verification + if err := l.persistLocked(ctx); err != nil { + return domain.ProviderVerification{}, domain.SSOSession{}, "", err + } + return verification, domain.SSOSession{}, "", ErrVerificationFailed + } + verification.Checks = append(verification.Checks, domain.VerifyCheck{Name: "active_user", Result: "passed"}) + l.providerVerifications[verification.ID] = verification + + secret := "evysso_" + randomToken(32) + session := domain.SSOSession{ID: newID("sess"), TenantID: provider.TenantID, UserID: user.ID, ProviderID: provider.ID, Prefix: secretPrefix(secret), ExpiresAt: expiresAt, SchemaVersion: domain.SSOSessionSchemaVersion, CreatedAt: now, Hash: l.hashSecret(secret)} + l.ssoSessions[session.ID] = session + _, _ = l.appendChainLocked(provider.TenantID, "sso_session.created", "human_user", user.ID, "sso_provider", provider.ID, "", "") + if err := l.persistLocked(ctx); err != nil { + return domain.ProviderVerification{}, domain.SSOSession{}, "", err + } + session.Hash = "" + return verification, session, secret, nil +} + func (l *Ledger) RevokeSSOSession(ctx context.Context, actor domain.Actor, id string) (domain.SSOSession, error) { if err := ctx.Err(); err != nil { return domain.SSOSession{}, err diff --git a/internal/app/enterprise_test.go b/internal/app/enterprise_test.go index c861922..3cdeda3 100644 --- a/internal/app/enterprise_test.go +++ b/internal/app/enterprise_test.go @@ -278,6 +278,66 @@ func TestOIDCProviderIdentityVerificationUsesStaticJWKS(t *testing.T) { } } +func TestExchangeSSOCredentialIssuesSessionFromVerifiedOIDCToken(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + _, _, _, actor := bootstrapEnterpriseTestTenant(t, ledger) + pub, priv, err := ed25519.GenerateKey(rand.Reader) + if err != nil { + t.Fatalf("keygen: %v", err) + } + jwks := map[string]any{"keys": []any{map[string]any{"kty": "OKP", "crv": "Ed25519", "kid": "kid-login", "alg": "EdDSA", "x": base64.RawURLEncoding.EncodeToString(pub)}}} + provider, err := ledger.CreateSSOProvider(ctx, actor, CreateSSOProviderInput{Name: "OIDC Login", Type: "oidc", Issuer: "https://login-idp.example.test", ClientID: "login-client", JWKS: jwks}) + if err != nil { + t.Fatalf("sso provider: %v", err) + } + org, err := ledger.CreateOrganization(ctx, actor, CreateOrganizationInput{Name: "Login Example", Slug: "login-example"}) + if err != nil { + t.Fatalf("org: %v", err) + } + user, err := ledger.CreateUser(ctx, actor, CreateUserInput{OrganizationID: org.ID, Email: "login@example.test", DisplayName: "Login User"}) + if err != nil { + t.Fatalf("user: %v", err) + } + if _, err := ledger.LinkSSOIdentity(ctx, actor, LinkSSOIdentityInput{UserID: user.ID, ProviderID: provider.ID, Subject: "login-sub", Email: user.Email, Verified: true}); err != nil { + t.Fatalf("identity link: %v", err) + } + if _, err := ledger.CreateRoleBinding(ctx, actor, CreateRoleBindingInput{SubjectType: "user", SubjectID: user.ID, Role: "security_engineer"}); err != nil { + t.Fatalf("role binding: %v", err) + } + idToken := signedTestIDToken(t, priv, "kid-login", map[string]any{ + "iss": provider.Issuer, + "aud": provider.ClientID, + "sub": "login-sub", + "email": user.Email, + "email_verified": true, + "exp": fixedNow().Add(time.Hour).Unix(), + }) + verification, session, secret, err := ledger.ExchangeSSOCredential(ctx, ExchangeSSOCredentialInput{ProviderID: provider.ID, Subject: "login-sub", IDToken: idToken}) + if err != nil { + t.Fatalf("exchange credential: %v", err) + } + if verification.Result != "passed" || session.UserID != user.ID || session.ProviderID != provider.ID || secret == "" || session.Hash != "" { + t.Fatalf("exchange result verification=%#v session=%#v secret=%q", verification, session, secret) + } + sessionActor, err := ledger.Authenticate(ctx, secret) + if err != nil { + t.Fatalf("authenticate exchanged session: %v", err) + } + if sessionActor.UserID != user.ID || sessionActor.SessionID != session.ID || !sessionActor.HasScope(ScopeEvidenceWrite) { + t.Fatalf("session actor = %#v", sessionActor) + } + bad, badSession, badSecret, err := ledger.ExchangeSSOCredential(ctx, ExchangeSSOCredentialInput{ProviderID: provider.ID, Subject: "other-sub", IDToken: idToken}) + if !errors.Is(err, ErrVerificationFailed) || bad.Result != "failed" || badSession.ID != "" || badSecret != "" { + t.Fatalf("bad exchange verification=%#v session=%#v secret=%q err=%v", bad, badSession, badSecret, err) + } + for _, check := range bad.Checks { + if strings.Contains(check.Detail, idToken) { + t.Fatalf("exchange leaked token in check detail: %#v", bad) + } + } +} + func TestOIDCProviderDiscoveryRefreshesTenantTrustMaterial(t *testing.T) { pub, _, err := ed25519.GenerateKey(rand.Reader) if err != nil { diff --git a/openapi.yaml b/openapi.yaml index 16ea5ef..70deeec 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/sdk/openapi-route-catalog.json b/sdk/openapi-route-catalog.json index 89b378e..71bf057 100644 --- a/sdk/openapi-route-catalog.json +++ b/sdk/openapi-route-catalog.json @@ -1,5 +1,5 @@ { - "route_count": 165, + "route_count": 166, "routes": [ { "idempotency_key_required": false, @@ -2518,6 +2518,21 @@ "200" ] }, + { + "idempotency_key_required": false, + "method": "POST", + "operation_id": "exchangeSSOCredential", + "path": "/v1/sso/session-exchanges", + "request_schema": "#/components/schemas/ExchangeSSOCredentialRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SSOCredentialExchangeEnvelope" + ], + "scopes": [], + "success_statuses": [ + "201" + ] + }, { "idempotency_key_required": true, "method": "POST", From 81818639dc0277fcb7b256993d338f97c0b91ffc Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 21:44:02 +0300 Subject: [PATCH 109/287] feat: map oidc groups to sso sessions --- README.md | 2 +- docs/api.md | 2 +- docs/architecture.md | 2 +- docs/operations.md | 2 +- docs/reference/production-readiness.md | 12 ++- internal/adapters/httpapi/openapi.go | 1 + internal/adapters/httpapi/router_test.go | 7 +- internal/adapters/postgres/store.go | 21 ++++- internal/adapters/postgres/store_test.go | 4 +- internal/app/enterprise.go | 94 ++++++++++++++++++- internal/app/enterprise_test.go | 68 +++++++++++++- internal/app/ledger.go | 2 +- internal/domain/domain.go | 1 + ...20260529000200_sso_session_groups.down.sql | 2 + .../20260529000200_sso_session_groups.up.sql | 2 + openapi.yaml | 2 +- 16 files changed, 195 insertions(+), 29 deletions(-) create mode 100644 migrations/20260529000200_sso_session_groups.down.sql create mode 100644 migrations/20260529000200_sso_session_groups.up.sql diff --git a/README.md b/README.md index b1364b8..4128550 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ This repository contains a Go implementation under module `github.com/aatuh/evyd - AGPL license, commercial licensing, governance, contribution, security, support, trademark, release-evidence, and changelog metadata. -Implemented-but-partial areas are documented explicitly: signing-provider operation receipts do not replace direct production KMS/HSM SDK adapters, SSO credential exchange uses configured local OIDC/SAML trust material but does not replace live provider API validation or group synchronization, and public transparency records can verify operator-supplied or fetched inclusion proof material without replacing provider-specific trust review. +Implemented-but-partial areas are documented explicitly: signing-provider operation receipts do not replace direct production KMS/HSM SDK adapters, SSO credential exchange uses configured local OIDC/SAML trust material and session-scoped OIDC group-role mappings but does not replace live provider API validation or external group synchronization, and public transparency records can verify operator-supplied or fetched inclusion proof material without replacing provider-specific trust review. ## License, Security, Support, And Governance diff --git a/docs/api.md b/docs/api.md index 1ef1ba7..fcf8001 100644 --- a/docs/api.md +++ b/docs/api.md @@ -251,7 +251,7 @@ Important scope boundaries: | `POST` | `/v1/api-keys` | Create one-time API key secret. | | `GET` | `/v1/api-keys` | List keys without secret hashes. | -Current SSO endpoints model admin-managed provider, identity-link, trust-material, and session records plus API-first session logout. OIDC provider records can include public JWKS material, and SAML provider records can include PEM-encoded assertion signing certificates; both can be rotated through `POST /v1/sso/providers/{id}/trust-material`. OIDC public JWKS can also be refreshed from the configured issuer with `POST /v1/sso/providers/{id}/discover-oidc`. `POST /v1/provider-verifications` can verify a supplied OIDC ID token or SAML assertion locally for issuer, audience, subject, time bounds, and signature. `POST /v1/sso/session-exchanges` uses the same local verification and a verified identity link to issue a one-time SSO bearer secret and an HttpOnly cookie for browser clients. Live provider API validation and group synchronization are not implemented in this slice. +Current SSO endpoints model admin-managed provider, identity-link, trust-material, and session records plus API-first session logout. OIDC provider records can include public JWKS material, and SAML provider records can include PEM-encoded assertion signing certificates; both can be rotated through `POST /v1/sso/providers/{id}/trust-material`. OIDC public JWKS can also be refreshed from the configured issuer with `POST /v1/sso/providers/{id}/discover-oidc`. `POST /v1/provider-verifications` can verify a supplied OIDC ID token or SAML assertion locally for issuer, audience, subject, time bounds, and signature. `POST /v1/sso/session-exchanges` uses the same local verification and a verified identity link to issue a one-time SSO bearer secret and an HttpOnly cookie for browser clients. OIDC group claim values can map to session-scoped roles through the provider `groups_claim` and `role_mapping`; no permanent role binding is created from token claims. Live provider API validation and external group synchronization are not implemented in this slice. ### Products, Releases, Evidence, And Risk diff --git a/docs/architecture.md b/docs/architecture.md index 20d6033..cd480f7 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -52,6 +52,6 @@ Air-gapped import-bundle workflows preserve the same tenant-scoped import path a ## Limitations -The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, OIDC discovery refresh, SSO credential exchange, and public-transparency proof fetching are implemented, but direct cloud KMS/HSM SDK adapters, live Sigstore verification, live provider API validation, and group synchronization remain deployment hardening work. Hand-tuned per-resource repository implementations and moving parser side effects fully out of request paths remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. +The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, OIDC discovery refresh, SSO credential exchange with session-scoped OIDC group-role mapping, and public-transparency proof fetching are implemented, but direct cloud KMS/HSM SDK adapters, live Sigstore verification, live provider API validation, and external group synchronization remain deployment hardening work. Hand-tuned per-resource repository implementations and moving parser side effects fully out of request paths remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. Evydence does not prove provider truth, scanner authority, runtime security, legal compliance, or release security by itself. diff --git a/docs/operations.md b/docs/operations.md index d32ba60..9f2417f 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -30,7 +30,7 @@ This operator index points to the canonical references for running Evydence. Kee - API keys, collector keys, SSO session tokens, and customer portal access tokens are bearer secrets. Do not place them in logs, documentation, long-lived build output, or customer packages. - Customer portal access tokens are returned once by `POST /v1/customer-portal/access`, expire, and are stored as hashes. Deployments should still use reverse-proxy or API-gateway throttling for the unauthenticated portal endpoint. -- Human SSO session records are admin-managed, authenticated SSO sessions can revoke themselves through API-first logout, and SSO credential exchange can set an HttpOnly session cookie after locally verifying an OIDC ID token or SAML assertion against tenant-configured trust material. Current endpoints can refresh OIDC public JWKS from discovery metadata, but they do not implement live provider API validation or group synchronization. +- Human SSO session records are admin-managed, authenticated SSO sessions can revoke themselves through API-first logout, and SSO credential exchange can set an HttpOnly session cookie after locally verifying an OIDC ID token or SAML assertion against tenant-configured trust material. OIDC group claim values can be captured on the session and mapped to configured roles without creating permanent role bindings from token claims. Current endpoints can refresh OIDC public JWKS from discovery metadata, but they do not implement live provider API validation or external group synchronization. - Object-retention APIs record and verify retention intent for tenant-prefixed object paths. Enforcing WORM or object-lock settings remains the responsibility of the configured object store and deployment policy. Evydence operations support evidence organization, review, and tamper-evident records. Operational checks do not replace external audit review, secret management, backup testing, or provider verification. diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 6bd343b..724995b 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -48,9 +48,11 @@ Known hardening work remains: broad object-lock enforcement proof remain provider- and deployment-dependent hardening areas. SSO credential exchange can issue bearer sessions and HttpOnly cookies after local OIDC/SAML verification against configured trust - material, and public transparency proof material can be fetched from a - configured endpoint and verified locally, but provider-specific trust - semantics and availability remain deployment responsibilities; + material, OIDC group claim values can map to session-scoped roles without + creating permanent role bindings, and public transparency proof material can + be fetched from a configured endpoint and verified locally, but + provider-specific trust semantics and availability remain deployment + responsibilities; - the broader production exit review remains incomplete. ## Production Profiles @@ -153,8 +155,8 @@ implemented capabilities: trust-material updates, manual JWKS and SAML signing-certificate rotation is implemented through the SSO provider trust-material endpoint, SSO credential exchange can issue bearer sessions plus HttpOnly cookies after local token or - assertion verification, and API-first session logout can revoke the current - SSO bearer session. + assertion verification, OIDC group claim values can map to session-scoped + roles, and API-first session logout can revoke the current SSO bearer session. - Extend object-lock/WORM verification beyond the current S3/MinIO bucket-level checks plus optional sample-object retention checks where deployments require broader object-level legal hold proofs or provider policy evidence. diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 68860ab..d57a1e6 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -1321,6 +1321,7 @@ func registerCriticalSchemas(registry *specs.Registry) { "user_id": map[string]any{"type": "string"}, "provider_id": map[string]any{"type": "string"}, "prefix": map[string]any{"type": "string", "description": "Non-secret session token prefix for audit displays."}, + "groups": map[string]any{"type": "array", "items": map[string]any{"type": "string"}, "description": "Provider group claim values captured for session-scoped role mapping."}, "expires_at": map[string]any{"type": "string", "format": "date-time"}, "revoked_at": map[string]any{"type": "string", "format": "date-time"}, "schema_version": map[string]any{"type": "string"}, diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 0ae6786..f72f833 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -239,7 +239,7 @@ func TestSSOCredentialExchangeRouteSetsSessionCookie(t *testing.T) { t.Fatalf("auth: %v", err) } jwks := map[string]any{"keys": []any{map[string]any{"kty": "OKP", "crv": "Ed25519", "kid": "kid-login", "x": base64.RawURLEncoding.EncodeToString(pub)}}} - provider, err := ledger.CreateSSOProvider(t.Context(), admin, app.CreateSSOProviderInput{Name: "OIDC", Type: "oidc", Issuer: "https://idp.example.test", ClientID: "client", JWKS: jwks}) + provider, err := ledger.CreateSSOProvider(t.Context(), admin, app.CreateSSOProviderInput{Name: "OIDC", Type: "oidc", Issuer: "https://idp.example.test", ClientID: "client", GroupsClaim: "groups", RoleMapping: map[string]string{"security": "security_engineer"}, JWKS: jwks}) if err != nil { t.Fatalf("provider: %v", err) } @@ -254,14 +254,11 @@ func TestSSOCredentialExchangeRouteSetsSessionCookie(t *testing.T) { if _, err := ledger.LinkSSOIdentity(t.Context(), admin, app.LinkSSOIdentityInput{UserID: user.ID, ProviderID: provider.ID, Subject: "sub-1", Email: user.Email, Verified: true}); err != nil { t.Fatalf("link: %v", err) } - if _, err := ledger.CreateRoleBinding(t.Context(), admin, app.CreateRoleBindingInput{SubjectType: "user", SubjectID: user.ID, Role: "security_engineer"}); err != nil { - t.Fatalf("role binding: %v", err) - } server, err := NewServer(ledger) if err != nil { t.Fatalf("server: %v", err) } - idToken := signedRouterIDToken(t, priv, "kid-login", map[string]any{"iss": provider.Issuer, "aud": provider.ClientID, "sub": "sub-1", "email": user.Email, "email_verified": true, "exp": time.Now().Add(time.Hour).Unix()}) + idToken := signedRouterIDToken(t, priv, "kid-login", map[string]any{"iss": provider.Issuer, "aud": provider.ClientID, "sub": "sub-1", "email": user.Email, "email_verified": true, "groups": []string{"security"}, "exp": time.Now().Add(time.Hour).Unix()}) body, err := json.Marshal(map[string]any{"provider_id": provider.ID, "subject": "sub-1", "id_token": idToken}) if err != nil { t.Fatalf("marshal body: %v", err) diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index 12ff145..f11d3ee 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -428,7 +428,7 @@ func (s *Store) loadRelationalIdentityLinks(ctx context.Context, state *app.Pers } func (s *Store) loadRelationalSSOSessions(ctx context.Context, state *app.PersistedState, loaded *bool) error { - rows, err := s.pool.Query(ctx, `SELECT id, tenant_id, user_id, provider_id, prefix, hash, expires_at, revoked_at, schema_version, created_at FROM sso_sessions`) + rows, err := s.pool.Query(ctx, `SELECT id, tenant_id, user_id, provider_id, prefix, hash, COALESCE(groups, '[]'::jsonb), expires_at, revoked_at, schema_version, created_at FROM sso_sessions`) if err != nil { return fmt.Errorf("load relational sso sessions: %w", err) } @@ -436,10 +436,16 @@ func (s *Store) loadRelationalSSOSessions(ctx context.Context, state *app.Persis for rows.Next() { var session domain.SSOSession var hash string + var groups []byte var revokedAt sql.NullTime - if err := rows.Scan(&session.ID, &session.TenantID, &session.UserID, &session.ProviderID, &session.Prefix, &hash, &session.ExpiresAt, &revokedAt, &session.SchemaVersion, &session.CreatedAt); err != nil { + if err := rows.Scan(&session.ID, &session.TenantID, &session.UserID, &session.ProviderID, &session.Prefix, &hash, &groups, &session.ExpiresAt, &revokedAt, &session.SchemaVersion, &session.CreatedAt); err != nil { return fmt.Errorf("scan relational sso session: %w", err) } + if len(groups) > 0 { + if err := json.Unmarshal(groups, &session.Groups); err != nil { + return fmt.Errorf("decode relational sso session groups: %w", err) + } + } session.RevokedAt = nullableSQLTime(revokedAt) state.SSOSessions[session.ID] = session state.SSOSessionHashes[session.ID] = hash @@ -4374,19 +4380,24 @@ func syncIdentityAndIdempotency(ctx context.Context, tx pgx.Tx, state app.Persis if hash == "" { hash = session.Hash } + groups, err := json.Marshal(session.Groups) + if err != nil { + return fmt.Errorf("encode sso session groups: %w", err) + } if _, err := tx.Exec(ctx, ` INSERT INTO sso_sessions ( - id, tenant_id, user_id, provider_id, prefix, hash, expires_at, + id, tenant_id, user_id, provider_id, prefix, hash, groups, expires_at, revoked_at, schema_version, created_at ) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) + VALUES ($1, $2, $3, $4, $5, $6, $7::jsonb, $8, $9, $10, $11) ON CONFLICT (id) DO UPDATE SET prefix = EXCLUDED.prefix, hash = EXCLUDED.hash, + groups = EXCLUDED.groups, expires_at = EXCLUDED.expires_at, revoked_at = EXCLUDED.revoked_at, schema_version = EXCLUDED.schema_version - `, session.ID, session.TenantID, session.UserID, session.ProviderID, session.Prefix, hash, session.ExpiresAt, nullableTime(session.RevokedAt), session.SchemaVersion, nonZeroTime(session.CreatedAt)); err != nil { + `, session.ID, session.TenantID, session.UserID, session.ProviderID, session.Prefix, hash, string(groups), session.ExpiresAt, nullableTime(session.RevokedAt), session.SchemaVersion, nonZeroTime(session.CreatedAt)); err != nil { return fmt.Errorf("upsert sso session row: %w", err) } } diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index 7ee67db..f02cc64 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -161,7 +161,7 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { "link_test": {ID: "link_test", TenantID: "ten_test", UserID: "user_test", ProviderID: "sso_test", Subject: "sub", Email: "user@example.test", Verified: true, SchemaVersion: "user-identity-link.v1.0.0", CreatedAt: time.Now().UTC()}, }, SSOSessions: map[string]domain.SSOSession{ - "sess_test": {ID: "sess_test", TenantID: "ten_test", UserID: "user_test", ProviderID: "sso_test", Prefix: "sess", ExpiresAt: time.Now().UTC().Add(time.Hour), SchemaVersion: domain.SSOSessionSchemaVersion, CreatedAt: time.Now().UTC()}, + "sess_test": {ID: "sess_test", TenantID: "ten_test", UserID: "user_test", ProviderID: "sso_test", Prefix: "sess", Groups: []string{"security"}, ExpiresAt: time.Now().UTC().Add(time.Hour), SchemaVersion: domain.SSOSessionSchemaVersion, CreatedAt: time.Now().UTC()}, }, SSOSessionHashes: map[string]string{"sess_test": "session-hash"}, CustomerPortalAccess: map[string]domain.CustomerPortalAccess{ @@ -600,7 +600,7 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { if relational.SSOProviders["sso_test"].TrustMaterialUpdatedAt == nil || len(relational.SSOProviders["sso_test"].JWKS) == 0 || !relational.IdentityLinks["link_test"].Verified { t.Fatalf("relational sso rows missing: provider=%#v link=%#v", relational.SSOProviders["sso_test"], relational.IdentityLinks["link_test"]) } - if relational.SSOSessionHashes["sess_test"] != "session-hash" || relational.SSOSessions["sess_test"].Prefix != "sess" { + if relational.SSOSessionHashes["sess_test"] != "session-hash" || relational.SSOSessions["sess_test"].Prefix != "sess" || len(relational.SSOSessions["sess_test"].Groups) != 1 || relational.SSOSessions["sess_test"].Groups[0] != "security" { t.Fatalf("relational sso session = %#v hash=%q", relational.SSOSessions["sess_test"], relational.SSOSessionHashes["sess_test"]) } if relational.Collectors["collector_test"].APIKeyID != "key_test" || relational.BuildRuns["build_test"].Status != "passed" || len(relational.BuildAttestations["att_test"].SubjectDigests) != 1 { diff --git a/internal/app/enterprise.go b/internal/app/enterprise.go index 95379df..f117d64 100644 --- a/internal/app/enterprise.go +++ b/internal/app/enterprise.go @@ -4,8 +4,10 @@ import ( "context" "crypto/rsa" "crypto/x509" + "encoding/base64" "encoding/json" "encoding/pem" + "fmt" "strings" "time" @@ -571,8 +573,24 @@ func (l *Ledger) ExchangeSSOCredential(ctx context.Context, in ExchangeSSOCreden verification.Checks = append(verification.Checks, domain.VerifyCheck{Name: "active_user", Result: "passed"}) l.providerVerifications[verification.ID] = verification + groups := oidcGroupsFromVerifiedToken(provider, idToken) + grants := append(l.resourceGrantsForUserLocked(user.ID), resourceGrantsForProviderGroups(provider, groups)...) + if len(scopesFromResourceGrants(grants)) == 0 { + verification.Result = "failed" + verification.Checks = append(verification.Checks, domain.VerifyCheck{Name: "authorization_grant", Result: "failed"}) + l.providerVerifications[verification.ID] = verification + if err := l.persistLocked(ctx); err != nil { + return domain.ProviderVerification{}, domain.SSOSession{}, "", err + } + return verification, domain.SSOSession{}, "", ErrForbidden + } + if len(groups) > 0 && len(resourceGrantsForProviderGroups(provider, groups)) > 0 { + verification.Checks = append(verification.Checks, domain.VerifyCheck{Name: "mapped_group_roles", Result: "passed", Detail: fmt.Sprintf("%d session-scoped provider group role mapping(s) applied", len(resourceGrantsForProviderGroups(provider, groups)))}) + } + l.providerVerifications[verification.ID] = verification + secret := "evysso_" + randomToken(32) - session := domain.SSOSession{ID: newID("sess"), TenantID: provider.TenantID, UserID: user.ID, ProviderID: provider.ID, Prefix: secretPrefix(secret), ExpiresAt: expiresAt, SchemaVersion: domain.SSOSessionSchemaVersion, CreatedAt: now, Hash: l.hashSecret(secret)} + session := domain.SSOSession{ID: newID("sess"), TenantID: provider.TenantID, UserID: user.ID, ProviderID: provider.ID, Prefix: secretPrefix(secret), Groups: groups, ExpiresAt: expiresAt, SchemaVersion: domain.SSOSessionSchemaVersion, CreatedAt: now, Hash: l.hashSecret(secret)} l.ssoSessions[session.ID] = session _, _ = l.appendChainLocked(provider.TenantID, "sso_session.created", "human_user", user.ID, "sso_provider", provider.ID, "", "") if err := l.persistLocked(ctx); err != nil { @@ -1042,6 +1060,33 @@ func (l *Ledger) resourceGrantsForUserLocked(userID string) []domain.ResourceGra return grants } +func (l *Ledger) resourceGrantsForSSOSessionLocked(session domain.SSOSession) []domain.ResourceGrant { + provider, ok := l.ssoProviders[session.ProviderID] + if !ok || provider.TenantID != session.TenantID { + return nil + } + return resourceGrantsForProviderGroups(provider, session.Groups) +} + +func resourceGrantsForProviderGroups(provider domain.SSOProvider, groups []string) []domain.ResourceGrant { + if provider.GroupsClaim == "" || len(provider.RoleMapping) == 0 || len(groups) == 0 { + return nil + } + grants := []domain.ResourceGrant{} + for _, group := range groups { + role := strings.TrimSpace(provider.RoleMapping[group]) + if !validRole(role) { + continue + } + scopes := scopesForRole(role) + if len(scopes) == 0 { + continue + } + grants = append(grants, domain.ResourceGrant{Role: role, Scopes: scopes}) + } + return grants +} + func scopesFromResourceGrants(grants []domain.ResourceGrant) []string { scopes := map[string]struct{}{} for _, grant := range grants { @@ -1371,6 +1416,53 @@ func scopesForRole(role string) []string { } } +func oidcGroupsFromVerifiedToken(provider domain.SSOProvider, token string) []string { + claimName := strings.TrimSpace(provider.GroupsClaim) + if claimName == "" || token == "" || provider.Type != "oidc" { + return nil + } + parts := strings.Split(token, ".") + if len(parts) != 3 { + return nil + } + body, err := base64.RawURLEncoding.DecodeString(parts[1]) + if err != nil { + return nil + } + var claims map[string]any + if err := json.Unmarshal(body, &claims); err != nil { + return nil + } + return sortedStrings(stringClaimValues(claims[claimName])) +} + +func stringClaimValues(value any) []string { + seen := map[string]struct{}{} + out := []string{} + add := func(raw string) { + item := strings.TrimSpace(raw) + if item == "" { + return + } + if _, ok := seen[item]; ok { + return + } + seen[item] = struct{}{} + out = append(out, item) + } + switch got := value.(type) { + case string: + add(got) + case []any: + for _, item := range got { + if text, ok := item.(string); ok { + add(text) + } + } + } + return out +} + func validSSOType(value string) bool { return value == "oidc" || value == "saml" } diff --git a/internal/app/enterprise_test.go b/internal/app/enterprise_test.go index 3cdeda3..65635ed 100644 --- a/internal/app/enterprise_test.go +++ b/internal/app/enterprise_test.go @@ -1,6 +1,7 @@ package app import ( + "bytes" "context" "crypto" "crypto/ed25519" @@ -287,7 +288,7 @@ func TestExchangeSSOCredentialIssuesSessionFromVerifiedOIDCToken(t *testing.T) { t.Fatalf("keygen: %v", err) } jwks := map[string]any{"keys": []any{map[string]any{"kty": "OKP", "crv": "Ed25519", "kid": "kid-login", "alg": "EdDSA", "x": base64.RawURLEncoding.EncodeToString(pub)}}} - provider, err := ledger.CreateSSOProvider(ctx, actor, CreateSSOProviderInput{Name: "OIDC Login", Type: "oidc", Issuer: "https://login-idp.example.test", ClientID: "login-client", JWKS: jwks}) + provider, err := ledger.CreateSSOProvider(ctx, actor, CreateSSOProviderInput{Name: "OIDC Login", Type: "oidc", Issuer: "https://login-idp.example.test", ClientID: "login-client", GroupsClaim: "groups", RoleMapping: map[string]string{"security": "security_engineer"}, JWKS: jwks}) if err != nil { t.Fatalf("sso provider: %v", err) } @@ -302,22 +303,20 @@ func TestExchangeSSOCredentialIssuesSessionFromVerifiedOIDCToken(t *testing.T) { if _, err := ledger.LinkSSOIdentity(ctx, actor, LinkSSOIdentityInput{UserID: user.ID, ProviderID: provider.ID, Subject: "login-sub", Email: user.Email, Verified: true}); err != nil { t.Fatalf("identity link: %v", err) } - if _, err := ledger.CreateRoleBinding(ctx, actor, CreateRoleBindingInput{SubjectType: "user", SubjectID: user.ID, Role: "security_engineer"}); err != nil { - t.Fatalf("role binding: %v", err) - } idToken := signedTestIDToken(t, priv, "kid-login", map[string]any{ "iss": provider.Issuer, "aud": provider.ClientID, "sub": "login-sub", "email": user.Email, "email_verified": true, + "groups": []string{"security"}, "exp": fixedNow().Add(time.Hour).Unix(), }) verification, session, secret, err := ledger.ExchangeSSOCredential(ctx, ExchangeSSOCredentialInput{ProviderID: provider.ID, Subject: "login-sub", IDToken: idToken}) if err != nil { t.Fatalf("exchange credential: %v", err) } - if verification.Result != "passed" || session.UserID != user.ID || session.ProviderID != provider.ID || secret == "" || session.Hash != "" { + if verification.Result != "passed" || session.UserID != user.ID || session.ProviderID != provider.ID || secret == "" || session.Hash != "" || len(session.Groups) != 1 || session.Groups[0] != "security" { t.Fatalf("exchange result verification=%#v session=%#v secret=%q", verification, session, secret) } sessionActor, err := ledger.Authenticate(ctx, secret) @@ -338,6 +337,65 @@ func TestExchangeSSOCredentialIssuesSessionFromVerifiedOIDCToken(t *testing.T) { } } +func TestExchangeSSOCredentialRejectsSessionWithoutAuthorizationGrant(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + _, _, _, actor := bootstrapEnterpriseTestTenant(t, ledger) + pub, priv, err := ed25519.GenerateKey(rand.Reader) + if err != nil { + t.Fatalf("keygen: %v", err) + } + jwks := map[string]any{"keys": []any{map[string]any{"kty": "OKP", "crv": "Ed25519", "kid": "kid-no-grant", "alg": "EdDSA", "x": base64.RawURLEncoding.EncodeToString(pub)}}} + provider, err := ledger.CreateSSOProvider(ctx, actor, CreateSSOProviderInput{Name: "OIDC Login", Type: "oidc", Issuer: "https://login-idp.example.test", ClientID: "login-client", GroupsClaim: "groups", RoleMapping: map[string]string{"security": "security_engineer"}, JWKS: jwks}) + if err != nil { + t.Fatalf("sso provider: %v", err) + } + org, err := ledger.CreateOrganization(ctx, actor, CreateOrganizationInput{Name: "Login Example", Slug: "login-example-no-grant"}) + if err != nil { + t.Fatalf("org: %v", err) + } + user, err := ledger.CreateUser(ctx, actor, CreateUserInput{OrganizationID: org.ID, Email: "nogrant@example.test", DisplayName: "No Grant User"}) + if err != nil { + t.Fatalf("user: %v", err) + } + if _, err := ledger.LinkSSOIdentity(ctx, actor, LinkSSOIdentityInput{UserID: user.ID, ProviderID: provider.ID, Subject: "login-sub", Email: user.Email, Verified: true}); err != nil { + t.Fatalf("identity link: %v", err) + } + idToken := signedTestIDToken(t, priv, "kid-no-grant", map[string]any{ + "iss": provider.Issuer, + "aud": provider.ClientID, + "sub": "login-sub", + "email": user.Email, + "email_verified": true, + "groups": []string{"unmapped"}, + "exp": fixedNow().Add(time.Hour).Unix(), + }) + verification, session, secret, err := ledger.ExchangeSSOCredential(ctx, ExchangeSSOCredentialInput{ProviderID: provider.ID, Subject: "login-sub", IDToken: idToken}) + if !errors.Is(err, ErrForbidden) || verification.Result != "failed" || session.ID != "" || secret != "" { + t.Fatalf("exchange without grant verification=%#v session=%#v secret=%q err=%v", verification, session, secret, err) + } + if !hasVerifyCheck(verification.Checks, "authorization_grant", "failed") { + t.Fatalf("verification missing authorization_grant failure: %#v", verification) + } +} + +func TestOIDCGroupClaimHelpersNormalizeSupportedClaimShapes(t *testing.T) { + token := signedTestIDToken(t, ed25519.NewKeyFromSeed(bytes.Repeat([]byte{1}, ed25519.SeedSize)), "kid", map[string]any{ + "groups": []string{"security", "release", "security", " "}, + }) + provider := domain.SSOProvider{Type: "oidc", GroupsClaim: "groups"} + groups := oidcGroupsFromVerifiedToken(provider, token) + if strings.Join(groups, ",") != "release,security" { + t.Fatalf("groups = %#v", groups) + } + if got := stringClaimValues("security"); len(got) != 1 || got[0] != "security" { + t.Fatalf("string claim values = %#v", got) + } + if grants := resourceGrantsForProviderGroups(domain.SSOProvider{GroupsClaim: "groups", RoleMapping: map[string]string{"security": "security_engineer", "bad": "not-a-role"}}, []string{"bad", "security"}); len(grants) != 1 || grants[0].Role != "security_engineer" { + t.Fatalf("mapped grants = %#v", grants) + } +} + func TestOIDCProviderDiscoveryRefreshesTenantTrustMaterial(t *testing.T) { pub, _, err := ed25519.GenerateKey(rand.Reader) if err != nil { diff --git a/internal/app/ledger.go b/internal/app/ledger.go index 6a62b50..e6a7a0a 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -394,7 +394,7 @@ func (l *Ledger) Authenticate(ctx context.Context, secret string) (domain.Actor, if !ok || user.TenantID != session.TenantID || user.Status != "active" { return domain.Actor{}, ErrUnauthorized } - grants := l.resourceGrantsForUserLocked(user.ID) + grants := append(l.resourceGrantsForUserLocked(user.ID), l.resourceGrantsForSSOSessionLocked(session)...) scopes := scopesFromResourceGrants(grants) if len(scopes) == 0 { return domain.Actor{}, ErrForbidden diff --git a/internal/domain/domain.go b/internal/domain/domain.go index cecae55..957f8f5 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -182,6 +182,7 @@ type SSOSession struct { UserID string `json:"user_id"` ProviderID string `json:"provider_id"` Prefix string `json:"prefix"` + Groups []string `json:"groups,omitempty"` ExpiresAt time.Time `json:"expires_at"` RevokedAt *time.Time `json:"revoked_at,omitempty"` SchemaVersion string `json:"schema_version"` diff --git a/migrations/20260529000200_sso_session_groups.down.sql b/migrations/20260529000200_sso_session_groups.down.sql new file mode 100644 index 0000000..ccf7267 --- /dev/null +++ b/migrations/20260529000200_sso_session_groups.down.sql @@ -0,0 +1,2 @@ +ALTER TABLE sso_sessions + DROP COLUMN IF EXISTS groups; diff --git a/migrations/20260529000200_sso_session_groups.up.sql b/migrations/20260529000200_sso_session_groups.up.sql new file mode 100644 index 0000000..c508667 --- /dev/null +++ b/migrations/20260529000200_sso_session_groups.up.sql @@ -0,0 +1,2 @@ +ALTER TABLE sso_sessions + ADD COLUMN IF NOT EXISTS groups jsonb NOT NULL DEFAULT '[]'::jsonb; diff --git a/openapi.yaml b/openapi.yaml index 70deeec..36241c8 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From 5d1843ecf27467bd01632b1d5b7c3f56a6d5b030 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 21:46:08 +0300 Subject: [PATCH 110/287] feat: support worker-owned sbom parsing --- .api.env.example | 3 ++ README.md | 3 +- cmd/evydence-api/main.go | 5 ++ cmd/evydence-api/main_test.go | 11 +++++ docs/architecture.md | 4 +- docs/reference/configuration.md | 1 + docs/reference/production-readiness.md | 16 +++--- docs/reference/worker-outbox.md | 9 +++- internal/app/ledger.go | 17 ++++++- internal/app/ledger_test.go | 67 ++++++++++++++++++++++++++ 10 files changed, 123 insertions(+), 13 deletions(-) diff --git a/.api.env.example b/.api.env.example index 3ae2a83..08471cc 100644 --- a/.api.env.example +++ b/.api.env.example @@ -6,6 +6,9 @@ EVYDENCE_DATABASE_URL=postgres://evydence:change-me@localhost:5432/evydence?sslm EVYDENCE_OBJECT_STORE=filesystem EVYDENCE_OBJECT_DIR=./tmp/objects EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE=0 +# Optional hardening mode for CycloneDX SBOM uploads. When true, the API stores +# an accepted SBOM record and the outbox worker writes parser-derived fields. +EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=false EVYDENCE_SIGNING_KEY_MODE=external # Optional external signing gateway. Use HTTPS outside localhost. # EVYDENCE_SIGNING_EXECUTOR_URL=https://signer.example.test/sign diff --git a/README.md b/README.md index 4128550..fce9d85 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ This repository contains a Go implementation under module `github.com/aatuh/evyd - PostgreSQL-backed durable ledger state, tenant-scoped relational projections, migrations, and persisted outbox jobs when `EVYDENCE_DATABASE_URL` is set. - Filesystem or S3/MinIO-compatible object storage for raw upload payload bytes under tenant-prefixed paths. - Polling `cmd/evydence-worker` process that claims persisted outbox jobs with PostgreSQL row locking and records retry or terminal status. +- Optional worker-owned CycloneDX SBOM parser side effects through `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; other parser-backed upload families still create initial normalized records before worker replay validates or backfills them. ### Tooling, Deployment, And Examples @@ -107,4 +108,4 @@ make postgres-integration-test `make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. -`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required production-readiness evidence, but it does not by itself close the remaining repository-split, worker side-effect, direct KMS/HSM SDK, provider API/group validation, object-lock enforcement, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. +`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required production-readiness evidence, but it does not by itself close the remaining repository-split, remaining worker side-effect, direct KMS/HSM SDK, provider API/group validation, object-lock enforcement, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. diff --git a/cmd/evydence-api/main.go b/cmd/evydence-api/main.go index 35cf6de..11395da 100644 --- a/cmd/evydence-api/main.go +++ b/cmd/evydence-api/main.go @@ -37,6 +37,7 @@ func run() error { return err } cfg := app.Config{APIKeyPepper: pepper} + cfg.WorkerOwnedParserSideEffects = boolEnv("EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS") cfg.OIDC = oidcdiscovery.New(oidcdiscovery.Config{ AllowInsecureForLocalhost: strings.EqualFold(os.Getenv("EVYDENCE_OIDC_DISCOVERY_ALLOW_INSECURE_LOCALHOST"), "true"), Timeout: time.Duration(intEnv("EVYDENCE_OIDC_DISCOVERY_TIMEOUT_SECONDS", 10)) * time.Second, @@ -181,6 +182,10 @@ func intEnv(name string, fallback int) int { return parsed } +func boolEnv(name string) bool { + return strings.EqualFold(strings.TrimSpace(os.Getenv(name)), "true") +} + func openObjectStore(ctx context.Context) (app.ObjectStore, string, error) { switch strings.ToLower(strings.TrimSpace(os.Getenv("EVYDENCE_OBJECT_STORE"))) { case "", "file", "filesystem": diff --git a/cmd/evydence-api/main_test.go b/cmd/evydence-api/main_test.go index 9259829..3407c2a 100644 --- a/cmd/evydence-api/main_test.go +++ b/cmd/evydence-api/main_test.go @@ -104,6 +104,17 @@ func TestIntEnvParsesRateLimitConfiguration(t *testing.T) { } } +func TestBoolEnvRequiresExplicitTrue(t *testing.T) { + t.Setenv("EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS", " true ") + if !boolEnv("EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS") { + t.Fatal("expected explicit true env to be enabled") + } + t.Setenv("EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS", "yes") + if boolEnv("EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS") { + t.Fatal("expected non-true env value to be disabled") + } +} + func TestOpenObjectStoreRejectsIncompleteS3Config(t *testing.T) { t.Setenv("EVYDENCE_OBJECT_STORE", "s3") t.Setenv("EVYDENCE_S3_ENDPOINT", "localhost:9000") diff --git a/docs/architecture.md b/docs/architecture.md index cd480f7..10e2a1d 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -26,7 +26,7 @@ When `EVYDENCE_DATABASE_URL` is set, mutations are saved to PostgreSQL before su Evidence, evidence lifecycle events, incidents, remediation tasks, security scans, manual security documents, SBOM diffs, VEX documents, vulnerability decisions/workflow records, organizations, users, role bindings, SSO providers, SSO sessions, legal holds, retention overrides, customer portal access records, questionnaire packages and drafts, evidence summaries, evidence graph snapshots, commercial and marketplace collector definitions, waivers, approvals, customer packages, report templates, evidence bundles, exceptions, build runs, build attestations, release candidates, artifact signatures, source-control records, deployment events, contract diffs, custom policy evaluations, provider verifications, signing operations, control evidence links, public transparency log entries, and release bundle records are append-only in behavior. Changes are represented by supersession, lifecycle events, approval transitions, session revocation, package access records, links, verification receipts, rollback-as-new-event records, or new audit-chain entries. -Outbox jobs are persisted in PostgreSQL and claimed by workers with `FOR UPDATE SKIP LOCKED`. Parser jobs re-read tenant-prefixed object-store payloads, verify size and digest, validate durable state, persist missing parser-derived normalized fields, and fail closed on mismatches. Upload endpoints still create initial accepted records, so moving every parser-owned side effect fully out of the API request path remains production hardening work. +Outbox jobs are persisted in PostgreSQL and claimed by workers with `FOR UPDATE SKIP LOCKED`. Parser jobs re-read tenant-prefixed object-store payloads, verify size and digest, validate durable state, persist missing parser-derived normalized fields, and fail closed on mismatches. With `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, CycloneDX SBOM uploads store an accepted record and workers populate normalized SBOM fields from replayed payloads. Other parser-backed upload endpoints still create initial normalized records, so moving every parser-owned side effect fully out of the API request path remains production hardening work. ## Verification And Trust @@ -52,6 +52,6 @@ Air-gapped import-bundle workflows preserve the same tenant-scoped import path a ## Limitations -The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, OIDC discovery refresh, SSO credential exchange with session-scoped OIDC group-role mapping, and public-transparency proof fetching are implemented, but direct cloud KMS/HSM SDK adapters, live Sigstore verification, live provider API validation, and external group synchronization remain deployment hardening work. Hand-tuned per-resource repository implementations and moving parser side effects fully out of request paths remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. +The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, OIDC discovery refresh, SSO credential exchange with session-scoped OIDC group-role mapping, public-transparency proof fetching, and optional worker-owned CycloneDX SBOM parser side effects are implemented, but direct cloud KMS/HSM SDK adapters, live Sigstore verification, live provider API validation, external group synchronization, and worker-owned parsing for every upload family remain deployment hardening work. Hand-tuned per-resource repository implementations and moving all remaining parser side effects fully out of request paths remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. Evydence does not prove provider truth, scanner authority, runtime security, legal compliance, or release security by itself. diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 53acda7..8f46315 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -37,6 +37,7 @@ The example secrets are placeholders. Replace them before using shared or produc | `EVYDENCE_S3_REGION` | No | empty | Optional S3 region. | | `EVYDENCE_S3_USE_SSL` | No | `false` locally, `true` in chart values | Use TLS for remote object storage. | | `EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE` | No | `0` disabled | Optional in-process per-client request limit using the TCP remote address. Use reverse-proxy or ingress rate limiting for production edge controls. | +| `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS` | No | `false` | Optional hardening mode for CycloneDX SBOM uploads. When set to `true`, the API stores an accepted SBOM record and the outbox worker populates parser-derived SBOM fields from the tenant-prefixed raw payload after digest verification. | | `EVYDENCE_SKIP_MIGRATIONS` | No | unset | Set to `true` only when migrations are applied by a separate release process. API and worker startup still verify that no committed migrations are pending and fail closed if the database is behind. | | `EVYDENCE_MIGRATIONS_DIR` | No | `migrations` | Migration directory for API startup and `cmd/evydence-migrate`. | | `EVYDENCE_BOOTSTRAP_TENANT` | No | `Local Tenant` | Tenant name used when bootstrapping an empty store. | diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 724995b..ab2cd78 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -38,8 +38,11 @@ Known hardening work remains: signing operation, and future-extension state from relational rows; - worker parser jobs re-read raw object-store payloads for key formats, verify digests, validate durable state, and persist missing parser-derived - normalized fields. Upload paths still create initial accepted records, so - fully worker-owned parsing for every payload remains hardening work; + normalized fields. CycloneDX SBOM uploads can run with worker-owned + normalized SBOM side effects by setting + `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; the other parser-backed + upload paths still create initial normalized records, so fully worker-owned + parsing for every payload remains hardening work; - OpenAPI precision is enforced across the registered public API. The generated matrix remains the source of truth for operation ids, scopes, idempotency, parameters, and request/response schemas; @@ -141,10 +144,11 @@ implemented capabilities: - Split the large application ledger aggregate into focused services or repositories once relational writes are in place, preserving tenant isolation and append-only behavior throughout. -- Continue moving parser-owned side effects for SBOM, vulnerability scan, - OpenAPI, VEX, and attestation payloads into worker processors. Workers now - persist missing parser-derived fields after object replay, but upload - endpoints still create initial accepted records. +- Continue moving parser-owned side effects for vulnerability scan, OpenAPI, + VEX, and attestation payloads into worker processors. CycloneDX SBOM + normalized fields can be worker-owned behind + `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; workers also persist + missing parser-derived fields for replay-compatible records. - Keep OpenAPI precision at zero broad operations as routes are added or changed, and expand generated SDK coverage from the committed contract. - Add direct cloud KMS/HSM SDK adapters where required. The current HTTPS diff --git a/docs/reference/worker-outbox.md b/docs/reference/worker-outbox.md index 872217e..bd0d3f9 100644 --- a/docs/reference/worker-outbox.md +++ b/docs/reference/worker-outbox.md @@ -12,13 +12,18 @@ Configured job kinds: - `verify_subject` - `verify_attestation` -Current behavior is intentionally conservative. The API still records normalized parser, signing, and verification results before enqueueing jobs for the implemented upload paths. The worker independently replays tenant-prefixed payload objects when `payload_ref` is present, verifies object metadata and byte digests when `payload_hash` is present, parses SBOM, vulnerability-scan, OpenAPI, OpenVEX, and DSSE attestation payloads, and checks that replayed payload summaries match the expected durable state. Missing objects, wrong tenant prefixes, tenant mismatches, oversized payload objects, malformed replay payloads, durable-state mismatches, incomplete verification, missing signatures, hash mismatch, uninitialized storage, and unsupported job kinds fail the job safely. +Current behavior is intentionally conservative. The API still records normalized signing and verification results before enqueueing jobs for the implemented paths. Parser jobs independently replay tenant-prefixed payload objects when `payload_ref` is present, verify object metadata and byte digests when `payload_hash` is present, parse SBOM, vulnerability-scan, OpenAPI, OpenVEX, and DSSE attestation payloads, and check that replayed payload summaries match the expected durable state. When `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, CycloneDX SBOM uploads store an accepted SBOM record first and the `parse_sbom` worker writes parser-derived SBOM fields after replay. Missing objects, wrong tenant prefixes, tenant mismatches, oversized payload objects, malformed replay payloads, durable-state mismatches, incomplete verification, missing signatures, hash mismatch, uninitialized storage, and unsupported job kinds fail the job safely. Parser and attestation jobs include a deterministic `parser_version` payload field for new uploads. Workers reject unsupported parser versions and accept older jobs with no parser version for upgrade compatibility. -Parser replay currently validates durable side effects instead of being the only writer of normalized records. Moving parser side effects fully out of the request path remains production hardening work. +Parser replay is worker-owned for CycloneDX SBOM normalized fields when +`EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`. Vulnerability-scan, +OpenAPI, OpenVEX, and attestation upload paths still create initial normalized +records before worker replay validates and backfills missing fields. Moving +those remaining parser side effects fully out of the request path remains +production hardening work. Workers use the same object-store environment variables as the API. The default worker payload replay limit is 20 MiB and can be adjusted with `EVYDENCE_WORKER_MAX_PAYLOAD_BYTES`. diff --git a/internal/app/ledger.go b/internal/app/ledger.go index e6a7a0a..b37f3c4 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -71,6 +71,9 @@ type Config struct { OIDC OIDCDiscoveryClient Transparency TransparencyProofFetcher Outbox Outbox + // WorkerOwnedParserSideEffects stores accepted parser records first and + // lets outbox workers populate parser-derived fields from raw payloads. + WorkerOwnedParserSideEffects bool } type Ledger struct { @@ -85,6 +88,7 @@ type Ledger struct { oidc OIDCDiscoveryClient transparencyProofs TransparencyProofFetcher outbox Outbox + workerOwnedParsers bool tenants map[string]domain.Tenant organizations map[string]domain.Organization @@ -210,6 +214,7 @@ func NewLedgerWithError(cfg Config) (*Ledger, error) { oidc: cfg.OIDC, transparencyProofs: cfg.Transparency, outbox: cfg.Outbox, + workerOwnedParsers: cfg.WorkerOwnedParserSideEffects, tenants: map[string]domain.Tenant{}, organizations: map[string]domain.Organization{}, users: map[string]domain.HumanUser{}, @@ -976,8 +981,16 @@ func (l *Ledger) UploadSBOM(ctx context.Context, actor domain.Actor, releaseID, l.mu.Lock() defer l.mu.Unlock() sbom := domain.SBOM{ID: newID("sbom"), TenantID: actor.TenantID, EvidenceID: item.ID, ReleaseID: releaseID, ArtifactID: artifactID, Format: "cyclonedx", SpecVersion: doc.SpecVersion, ComponentCount: len(components), Components: components, CreatedAt: l.now()} - l.sboms[sbom.ID] = sbom - _, _ = l.appendChainLocked(actor.TenantID, "sbom.parsed", "sbom", sbom.ID, "api_key", actor.KeyID, payloadHash, "") + persistedSBOM := sbom + chainAction := "sbom.parsed" + if l.workerOwnedParsers { + persistedSBOM.SpecVersion = "" + persistedSBOM.ComponentCount = 0 + persistedSBOM.Components = nil + chainAction = "sbom.accepted" + } + l.sboms[sbom.ID] = persistedSBOM + _, _ = l.appendChainLocked(actor.TenantID, chainAction, "sbom", sbom.ID, "api_key", actor.KeyID, payloadHash, "") if err := l.enqueue(ctx, actor.TenantID, "parse_sbom", "sbom", sbom.ID, map[string]any{"payload_ref": payloadRef, "payload_hash": payloadHash, "parser_version": ParserVersionCycloneDXJSON}); err != nil { return domain.SBOM{}, err } diff --git a/internal/app/ledger_test.go b/internal/app/ledger_test.go index 6676c6d..9a2417c 100644 --- a/internal/app/ledger_test.go +++ b/internal/app/ledger_test.go @@ -136,6 +136,73 @@ func TestUploadSBOMEnqueuesParserVersion(t *testing.T) { } } +func TestUploadSBOMCanDeferParserSideEffectsToWorker(t *testing.T) { + outbox := &recordingOutbox{} + store := NewMemoryStore() + objects := newTestObjectStore() + ledger := NewLedger(Config{ + APIKeyPepper: "test-pepper", + Now: fixedNow, + Store: store, + ObjectStore: objects, + Outbox: outbox, + WorkerOwnedParserSideEffects: true, + }) + ctx := context.Background() + _, _, secret, err := ledger.BootstrapTenant(ctx, "Tenant", "admin", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap: %v", err) + } + actor, err := ledger.Authenticate(ctx, secret) + if err != nil { + t.Fatalf("auth: %v", err) + } + product, err := ledger.CreateProduct(ctx, actor, "Payments API", "payments-worker-parser") + if err != nil { + t.Fatalf("create product: %v", err) + } + release, err := ledger.CreateRelease(ctx, actor, product.ID, "1.0.0") + if err != nil { + t.Fatalf("create release: %v", err) + } + artifact, err := ledger.RegisterArtifact(ctx, actor, "api.tar.gz", "application/gzip", sampleDigest("api"), 42) + if err != nil { + t.Fatalf("artifact: %v", err) + } + + sbom, err := ledger.UploadSBOM(ctx, actor, release.ID, artifact.ID, []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","components":[{"name":"api","purl":"pkg:oci/api"}]}`)) + if err != nil { + t.Fatalf("upload sbom: %v", err) + } + if sbom.SpecVersion != "1.6" || sbom.ComponentCount != 1 || len(sbom.Components) != 1 { + t.Fatalf("upload response should keep parsed fields: %#v", sbom) + } + + state, ok, err := store.LoadState(ctx) + if err != nil || !ok { + t.Fatalf("load state ok=%v err=%v", ok, err) + } + persisted := state.SBOMs[sbom.ID] + if persisted.SpecVersion != "" || persisted.ComponentCount != 0 || len(persisted.Components) != 0 { + t.Fatalf("persisted sbom should wait for worker parser side effects: %#v", persisted) + } + if len(outbox.jobs) != 1 { + t.Fatalf("outbox jobs = %d, want 1", len(outbox.jobs)) + } + job := outbox.jobs[0] + if job.Kind != "parse_sbom" || job.Payload["payload_ref"] == "" || job.Payload["payload_hash"] == "" { + t.Fatalf("outbox job missing replay metadata: %#v", job) + } + payloadRef, ok := job.Payload["payload_ref"].(string) + payloadKey := strings.TrimPrefix(payloadRef, "object://") + if !ok || !strings.HasPrefix(payloadKey, "tenants/"+actor.TenantID+"/") { + t.Fatalf("payload ref %q is not tenant-prefixed", job.Payload["payload_ref"]) + } + if _, err := objects.Get(ctx, payloadKey); err != nil { + t.Fatalf("stored payload missing: %v", err) + } +} + func TestIdempotencyReplayAndConflict(t *testing.T) { ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) ctx := context.Background() From c807c67aba666f8b61dd0f14f65d8d018afdcdb6 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 21:59:06 +0300 Subject: [PATCH 111/287] feat: defer vulnerability scan parsing to workers --- .api.env.example | 5 +- README.md | 2 +- docs/architecture.md | 4 +- docs/reference/configuration.md | 2 +- docs/reference/production-readiness.md | 10 ++-- docs/reference/worker-outbox.md | 6 +-- internal/app/ledger.go | 38 ++++++++++------ internal/app/ledger_test.go | 63 ++++++++++++++++++++++++++ 8 files changed, 102 insertions(+), 28 deletions(-) diff --git a/.api.env.example b/.api.env.example index 08471cc..955d783 100644 --- a/.api.env.example +++ b/.api.env.example @@ -6,8 +6,9 @@ EVYDENCE_DATABASE_URL=postgres://evydence:change-me@localhost:5432/evydence?sslm EVYDENCE_OBJECT_STORE=filesystem EVYDENCE_OBJECT_DIR=./tmp/objects EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE=0 -# Optional hardening mode for CycloneDX SBOM uploads. When true, the API stores -# an accepted SBOM record and the outbox worker writes parser-derived fields. +# Optional hardening mode for CycloneDX SBOM and generic vulnerability-scan +# uploads. When true, the API stores accepted records and the outbox worker +# writes parser-derived fields. EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=false EVYDENCE_SIGNING_KEY_MODE=external # Optional external signing gateway. Use HTTPS outside localhost. diff --git a/README.md b/README.md index fce9d85..0e25f95 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ This repository contains a Go implementation under module `github.com/aatuh/evyd - PostgreSQL-backed durable ledger state, tenant-scoped relational projections, migrations, and persisted outbox jobs when `EVYDENCE_DATABASE_URL` is set. - Filesystem or S3/MinIO-compatible object storage for raw upload payload bytes under tenant-prefixed paths. - Polling `cmd/evydence-worker` process that claims persisted outbox jobs with PostgreSQL row locking and records retry or terminal status. -- Optional worker-owned CycloneDX SBOM parser side effects through `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; other parser-backed upload families still create initial normalized records before worker replay validates or backfills them. +- Optional worker-owned CycloneDX SBOM and generic vulnerability-scan parser side effects through `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; other parser-backed upload families still create initial normalized records before worker replay validates or backfills them. ### Tooling, Deployment, And Examples diff --git a/docs/architecture.md b/docs/architecture.md index 10e2a1d..391db62 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -26,7 +26,7 @@ When `EVYDENCE_DATABASE_URL` is set, mutations are saved to PostgreSQL before su Evidence, evidence lifecycle events, incidents, remediation tasks, security scans, manual security documents, SBOM diffs, VEX documents, vulnerability decisions/workflow records, organizations, users, role bindings, SSO providers, SSO sessions, legal holds, retention overrides, customer portal access records, questionnaire packages and drafts, evidence summaries, evidence graph snapshots, commercial and marketplace collector definitions, waivers, approvals, customer packages, report templates, evidence bundles, exceptions, build runs, build attestations, release candidates, artifact signatures, source-control records, deployment events, contract diffs, custom policy evaluations, provider verifications, signing operations, control evidence links, public transparency log entries, and release bundle records are append-only in behavior. Changes are represented by supersession, lifecycle events, approval transitions, session revocation, package access records, links, verification receipts, rollback-as-new-event records, or new audit-chain entries. -Outbox jobs are persisted in PostgreSQL and claimed by workers with `FOR UPDATE SKIP LOCKED`. Parser jobs re-read tenant-prefixed object-store payloads, verify size and digest, validate durable state, persist missing parser-derived normalized fields, and fail closed on mismatches. With `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, CycloneDX SBOM uploads store an accepted record and workers populate normalized SBOM fields from replayed payloads. Other parser-backed upload endpoints still create initial normalized records, so moving every parser-owned side effect fully out of the API request path remains production hardening work. +Outbox jobs are persisted in PostgreSQL and claimed by workers with `FOR UPDATE SKIP LOCKED`. Parser jobs re-read tenant-prefixed object-store payloads, verify size and digest, validate durable state, persist missing parser-derived normalized fields, and fail closed on mismatches. With `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, CycloneDX SBOM and generic vulnerability-scan uploads store accepted records and workers populate normalized fields from replayed payloads. Other parser-backed upload endpoints still create initial normalized records, so moving every parser-owned side effect fully out of the API request path remains production hardening work. ## Verification And Trust @@ -52,6 +52,6 @@ Air-gapped import-bundle workflows preserve the same tenant-scoped import path a ## Limitations -The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, OIDC discovery refresh, SSO credential exchange with session-scoped OIDC group-role mapping, public-transparency proof fetching, and optional worker-owned CycloneDX SBOM parser side effects are implemented, but direct cloud KMS/HSM SDK adapters, live Sigstore verification, live provider API validation, external group synchronization, and worker-owned parsing for every upload family remain deployment hardening work. Hand-tuned per-resource repository implementations and moving all remaining parser side effects fully out of request paths remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. +The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, OIDC discovery refresh, SSO credential exchange with session-scoped OIDC group-role mapping, public-transparency proof fetching, and optional worker-owned CycloneDX SBOM and generic vulnerability-scan parser side effects are implemented, but direct cloud KMS/HSM SDK adapters, live Sigstore verification, live provider API validation, external group synchronization, and worker-owned parsing for every upload family remain deployment hardening work. Hand-tuned per-resource repository implementations and moving all remaining parser side effects fully out of request paths remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. Evydence does not prove provider truth, scanner authority, runtime security, legal compliance, or release security by itself. diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 8f46315..745fd97 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -37,7 +37,7 @@ The example secrets are placeholders. Replace them before using shared or produc | `EVYDENCE_S3_REGION` | No | empty | Optional S3 region. | | `EVYDENCE_S3_USE_SSL` | No | `false` locally, `true` in chart values | Use TLS for remote object storage. | | `EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE` | No | `0` disabled | Optional in-process per-client request limit using the TCP remote address. Use reverse-proxy or ingress rate limiting for production edge controls. | -| `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS` | No | `false` | Optional hardening mode for CycloneDX SBOM uploads. When set to `true`, the API stores an accepted SBOM record and the outbox worker populates parser-derived SBOM fields from the tenant-prefixed raw payload after digest verification. | +| `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS` | No | `false` | Optional hardening mode for CycloneDX SBOM and generic vulnerability-scan uploads. When set to `true`, the API stores accepted records and the outbox worker populates parser-derived fields from tenant-prefixed raw payloads after digest verification. | | `EVYDENCE_SKIP_MIGRATIONS` | No | unset | Set to `true` only when migrations are applied by a separate release process. API and worker startup still verify that no committed migrations are pending and fail closed if the database is behind. | | `EVYDENCE_MIGRATIONS_DIR` | No | `migrations` | Migration directory for API startup and `cmd/evydence-migrate`. | | `EVYDENCE_BOOTSTRAP_TENANT` | No | `Local Tenant` | Tenant name used when bootstrapping an empty store. | diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index ab2cd78..ac742c9 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -38,8 +38,8 @@ Known hardening work remains: signing operation, and future-extension state from relational rows; - worker parser jobs re-read raw object-store payloads for key formats, verify digests, validate durable state, and persist missing parser-derived - normalized fields. CycloneDX SBOM uploads can run with worker-owned - normalized SBOM side effects by setting + normalized fields. CycloneDX SBOM and generic vulnerability-scan uploads can + run with worker-owned normalized side effects by setting `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; the other parser-backed upload paths still create initial normalized records, so fully worker-owned parsing for every payload remains hardening work; @@ -144,9 +144,9 @@ implemented capabilities: - Split the large application ledger aggregate into focused services or repositories once relational writes are in place, preserving tenant isolation and append-only behavior throughout. -- Continue moving parser-owned side effects for vulnerability scan, OpenAPI, - VEX, and attestation payloads into worker processors. CycloneDX SBOM - normalized fields can be worker-owned behind +- Continue moving parser-owned side effects for OpenAPI, VEX, and attestation + payloads into worker processors. CycloneDX SBOM and generic vulnerability + scan normalized fields can be worker-owned behind `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; workers also persist missing parser-derived fields for replay-compatible records. - Keep OpenAPI precision at zero broad operations as routes are added or diff --git a/docs/reference/worker-outbox.md b/docs/reference/worker-outbox.md index bd0d3f9..3d37521 100644 --- a/docs/reference/worker-outbox.md +++ b/docs/reference/worker-outbox.md @@ -12,14 +12,14 @@ Configured job kinds: - `verify_subject` - `verify_attestation` -Current behavior is intentionally conservative. The API still records normalized signing and verification results before enqueueing jobs for the implemented paths. Parser jobs independently replay tenant-prefixed payload objects when `payload_ref` is present, verify object metadata and byte digests when `payload_hash` is present, parse SBOM, vulnerability-scan, OpenAPI, OpenVEX, and DSSE attestation payloads, and check that replayed payload summaries match the expected durable state. When `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, CycloneDX SBOM uploads store an accepted SBOM record first and the `parse_sbom` worker writes parser-derived SBOM fields after replay. Missing objects, wrong tenant prefixes, tenant mismatches, oversized payload objects, malformed replay payloads, durable-state mismatches, incomplete verification, missing signatures, hash mismatch, uninitialized storage, and unsupported job kinds fail the job safely. +Current behavior is intentionally conservative. The API still records normalized signing and verification results before enqueueing jobs for the implemented paths. Parser jobs independently replay tenant-prefixed payload objects when `payload_ref` is present, verify object metadata and byte digests when `payload_hash` is present, parse SBOM, vulnerability-scan, OpenAPI, OpenVEX, and DSSE attestation payloads, and check that replayed payload summaries match the expected durable state. When `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, CycloneDX SBOM and generic vulnerability-scan uploads store accepted records first, and the `parse_sbom` and `parse_vulnerability_scan` workers write parser-derived fields after replay. Missing objects, wrong tenant prefixes, tenant mismatches, oversized payload objects, malformed replay payloads, durable-state mismatches, incomplete verification, missing signatures, hash mismatch, uninitialized storage, and unsupported job kinds fail the job safely. Parser and attestation jobs include a deterministic `parser_version` payload field for new uploads. Workers reject unsupported parser versions and accept older jobs with no parser version for upgrade compatibility. -Parser replay is worker-owned for CycloneDX SBOM normalized fields when -`EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`. Vulnerability-scan, +Parser replay is worker-owned for CycloneDX SBOM and generic vulnerability-scan +normalized fields when `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`. OpenAPI, OpenVEX, and attestation upload paths still create initial normalized records before worker replay validates and backfills missing fields. Moving those remaining parser side effects fully out of the request path remains diff --git a/internal/app/ledger.go b/internal/app/ledger.go index b37f3c4..7f3b6b1 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -1040,6 +1040,18 @@ func (l *Ledger) UploadVulnerabilityScan(ctx context.Context, actor domain.Actor return domain.VulnerabilityScan{}, err } l.mu.Unlock() + scanID := newID("scan") + summary := map[string]int{} + findings := make([]domain.VulnerabilityFinding, 0, len(doc.Findings)) + for i, finding := range doc.Findings { + if finding.Vulnerability == "" || finding.Severity == "" { + return domain.VulnerabilityScan{}, ErrValidation + } + severity := strings.ToLower(finding.Severity) + summary[severity]++ + state := nonEmpty(finding.State, "open") + findings = append(findings, domain.VulnerabilityFinding{ID: fmt.Sprintf("%s:finding:%d", scanID, i+1), Vulnerability: finding.Vulnerability, Component: finding.Component, Severity: severity, State: state}) + } payloadHash := hashBytes(raw) payloadRef, err := l.storePayload(ctx, actor.TenantID, "vulnerability-scan", "application/json", payloadHash, raw) if err != nil { @@ -1061,22 +1073,20 @@ func (l *Ledger) UploadVulnerabilityScan(ctx context.Context, actor domain.Actor if err != nil { return domain.VulnerabilityScan{}, err } - summary := map[string]int{} - findings := make([]domain.VulnerabilityFinding, 0, len(doc.Findings)) - for _, finding := range doc.Findings { - if finding.Vulnerability == "" || finding.Severity == "" { - return domain.VulnerabilityScan{}, ErrValidation - } - severity := strings.ToLower(finding.Severity) - summary[severity]++ - state := nonEmpty(finding.State, "open") - findings = append(findings, domain.VulnerabilityFinding{ID: newID("vf"), Vulnerability: finding.Vulnerability, Component: finding.Component, Severity: severity, State: state}) - } l.mu.Lock() defer l.mu.Unlock() - scan := domain.VulnerabilityScan{ID: newID("scan"), TenantID: actor.TenantID, EvidenceID: item.ID, ReleaseID: doc.ReleaseID, Scanner: doc.Scanner, TargetRef: doc.TargetRef, Summary: summary, Findings: findings, CreatedAt: l.now()} - l.scans[scan.ID] = scan - _, _ = l.appendChainLocked(actor.TenantID, "vulnerability_scan.parsed", "vulnerability_scan", scan.ID, "api_key", actor.KeyID, payloadHash, "") + scan := domain.VulnerabilityScan{ID: scanID, TenantID: actor.TenantID, EvidenceID: item.ID, ReleaseID: doc.ReleaseID, Scanner: doc.Scanner, TargetRef: doc.TargetRef, Summary: summary, Findings: findings, CreatedAt: l.now()} + persistedScan := scan + chainAction := "vulnerability_scan.parsed" + if l.workerOwnedParsers { + persistedScan.Scanner = "" + persistedScan.TargetRef = "" + persistedScan.Summary = nil + persistedScan.Findings = nil + chainAction = "vulnerability_scan.accepted" + } + l.scans[scan.ID] = persistedScan + _, _ = l.appendChainLocked(actor.TenantID, chainAction, "vulnerability_scan", scan.ID, "api_key", actor.KeyID, payloadHash, "") if err := l.enqueue(ctx, actor.TenantID, "parse_vulnerability_scan", "vulnerability_scan", scan.ID, map[string]any{"payload_ref": payloadRef, "payload_hash": payloadHash, "parser_version": ParserVersionGenericVulnerabilityJSON}); err != nil { return domain.VulnerabilityScan{}, err } diff --git a/internal/app/ledger_test.go b/internal/app/ledger_test.go index 9a2417c..283ffcc 100644 --- a/internal/app/ledger_test.go +++ b/internal/app/ledger_test.go @@ -203,6 +203,69 @@ func TestUploadSBOMCanDeferParserSideEffectsToWorker(t *testing.T) { } } +func TestUploadVulnerabilityScanCanDeferParserSideEffectsToWorker(t *testing.T) { + outbox := &recordingOutbox{} + store := NewMemoryStore() + objects := newTestObjectStore() + ledger := NewLedger(Config{ + APIKeyPepper: "test-pepper", + Now: fixedNow, + Store: store, + ObjectStore: objects, + Outbox: outbox, + WorkerOwnedParserSideEffects: true, + }) + ctx := context.Background() + _, _, secret, err := ledger.BootstrapTenant(ctx, "Tenant", "admin", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap: %v", err) + } + actor, err := ledger.Authenticate(ctx, secret) + if err != nil { + t.Fatalf("auth: %v", err) + } + product, err := ledger.CreateProduct(ctx, actor, "Payments API", "payments-worker-scan") + if err != nil { + t.Fatalf("create product: %v", err) + } + release, err := ledger.CreateRelease(ctx, actor, product.ID, "1.0.0") + if err != nil { + t.Fatalf("create release: %v", err) + } + + scan, err := ledger.UploadVulnerabilityScan(ctx, actor, []byte(`{"scanner":"grype","target_ref":"pkg:oci/api","release_id":"`+release.ID+`","findings":[{"vulnerability":"CVE-2026-0001","component":"api","severity":"critical","state":"open"}]}`)) + if err != nil { + t.Fatalf("upload scan: %v", err) + } + if scan.Scanner != "grype" || scan.Summary["critical"] != 1 || len(scan.Findings) != 1 || !strings.HasPrefix(scan.Findings[0].ID, scan.ID+":finding:") { + t.Fatalf("upload response should keep parsed scan fields with stable finding ids: %#v", scan) + } + + state, ok, err := store.LoadState(ctx) + if err != nil || !ok { + t.Fatalf("load state ok=%v err=%v", ok, err) + } + persisted := state.Scans[scan.ID] + if persisted.Scanner != "" || persisted.TargetRef != "" || persisted.Summary != nil || len(persisted.Findings) != 0 { + t.Fatalf("persisted scan should wait for worker parser side effects: %#v", persisted) + } + if len(outbox.jobs) != 1 { + t.Fatalf("outbox jobs = %d, want 1", len(outbox.jobs)) + } + job := outbox.jobs[0] + if job.Kind != "parse_vulnerability_scan" || job.Payload["payload_ref"] == "" || job.Payload["payload_hash"] == "" || job.Payload["parser_version"] != ParserVersionGenericVulnerabilityJSON { + t.Fatalf("outbox job missing replay metadata: %#v", job) + } + payloadRef, ok := job.Payload["payload_ref"].(string) + payloadKey := strings.TrimPrefix(payloadRef, "object://") + if !ok || !strings.HasPrefix(payloadKey, "tenants/"+actor.TenantID+"/") { + t.Fatalf("payload ref %q is not tenant-prefixed", job.Payload["payload_ref"]) + } + if _, err := objects.Get(ctx, payloadKey); err != nil { + t.Fatalf("stored payload missing: %v", err) + } +} + func TestIdempotencyReplayAndConflict(t *testing.T) { ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) ctx := context.Background() From de08970aa83c564a9f4997522dbd7081d6ee30d0 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 22:00:32 +0300 Subject: [PATCH 112/287] feat: defer openapi parsing to workers --- .api.env.example | 6 +-- README.md | 2 +- docs/architecture.md | 4 +- docs/reference/configuration.md | 2 +- docs/reference/production-readiness.md | 10 ++-- docs/reference/worker-outbox.md | 14 +++--- internal/app/ledger.go | 11 ++++- internal/app/ledger_test.go | 63 ++++++++++++++++++++++++++ 8 files changed, 91 insertions(+), 21 deletions(-) diff --git a/.api.env.example b/.api.env.example index 955d783..1c227b7 100644 --- a/.api.env.example +++ b/.api.env.example @@ -6,9 +6,9 @@ EVYDENCE_DATABASE_URL=postgres://evydence:change-me@localhost:5432/evydence?sslm EVYDENCE_OBJECT_STORE=filesystem EVYDENCE_OBJECT_DIR=./tmp/objects EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE=0 -# Optional hardening mode for CycloneDX SBOM and generic vulnerability-scan -# uploads. When true, the API stores accepted records and the outbox worker -# writes parser-derived fields. +# Optional hardening mode for CycloneDX SBOM, generic vulnerability-scan, and +# OpenAPI contract uploads. When true, the API stores accepted records and the +# outbox worker writes parser-derived fields. EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=false EVYDENCE_SIGNING_KEY_MODE=external # Optional external signing gateway. Use HTTPS outside localhost. diff --git a/README.md b/README.md index 0e25f95..16d2623 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ This repository contains a Go implementation under module `github.com/aatuh/evyd - PostgreSQL-backed durable ledger state, tenant-scoped relational projections, migrations, and persisted outbox jobs when `EVYDENCE_DATABASE_URL` is set. - Filesystem or S3/MinIO-compatible object storage for raw upload payload bytes under tenant-prefixed paths. - Polling `cmd/evydence-worker` process that claims persisted outbox jobs with PostgreSQL row locking and records retry or terminal status. -- Optional worker-owned CycloneDX SBOM and generic vulnerability-scan parser side effects through `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; other parser-backed upload families still create initial normalized records before worker replay validates or backfills them. +- Optional worker-owned CycloneDX SBOM, generic vulnerability-scan, and OpenAPI contract parser side effects through `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; other parser-backed upload families still create initial normalized records before worker replay validates or backfills them. ### Tooling, Deployment, And Examples diff --git a/docs/architecture.md b/docs/architecture.md index 391db62..d56bb74 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -26,7 +26,7 @@ When `EVYDENCE_DATABASE_URL` is set, mutations are saved to PostgreSQL before su Evidence, evidence lifecycle events, incidents, remediation tasks, security scans, manual security documents, SBOM diffs, VEX documents, vulnerability decisions/workflow records, organizations, users, role bindings, SSO providers, SSO sessions, legal holds, retention overrides, customer portal access records, questionnaire packages and drafts, evidence summaries, evidence graph snapshots, commercial and marketplace collector definitions, waivers, approvals, customer packages, report templates, evidence bundles, exceptions, build runs, build attestations, release candidates, artifact signatures, source-control records, deployment events, contract diffs, custom policy evaluations, provider verifications, signing operations, control evidence links, public transparency log entries, and release bundle records are append-only in behavior. Changes are represented by supersession, lifecycle events, approval transitions, session revocation, package access records, links, verification receipts, rollback-as-new-event records, or new audit-chain entries. -Outbox jobs are persisted in PostgreSQL and claimed by workers with `FOR UPDATE SKIP LOCKED`. Parser jobs re-read tenant-prefixed object-store payloads, verify size and digest, validate durable state, persist missing parser-derived normalized fields, and fail closed on mismatches. With `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, CycloneDX SBOM and generic vulnerability-scan uploads store accepted records and workers populate normalized fields from replayed payloads. Other parser-backed upload endpoints still create initial normalized records, so moving every parser-owned side effect fully out of the API request path remains production hardening work. +Outbox jobs are persisted in PostgreSQL and claimed by workers with `FOR UPDATE SKIP LOCKED`. Parser jobs re-read tenant-prefixed object-store payloads, verify size and digest, validate durable state, persist missing parser-derived normalized fields, and fail closed on mismatches. With `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, CycloneDX SBOM, generic vulnerability-scan, and OpenAPI contract uploads store accepted records and workers populate normalized fields from replayed payloads. Other parser-backed upload endpoints still create initial normalized records, so moving every parser-owned side effect fully out of the API request path remains production hardening work. ## Verification And Trust @@ -52,6 +52,6 @@ Air-gapped import-bundle workflows preserve the same tenant-scoped import path a ## Limitations -The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, OIDC discovery refresh, SSO credential exchange with session-scoped OIDC group-role mapping, public-transparency proof fetching, and optional worker-owned CycloneDX SBOM and generic vulnerability-scan parser side effects are implemented, but direct cloud KMS/HSM SDK adapters, live Sigstore verification, live provider API validation, external group synchronization, and worker-owned parsing for every upload family remain deployment hardening work. Hand-tuned per-resource repository implementations and moving all remaining parser side effects fully out of request paths remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. +The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, OIDC discovery refresh, SSO credential exchange with session-scoped OIDC group-role mapping, public-transparency proof fetching, and optional worker-owned CycloneDX SBOM, generic vulnerability-scan, and OpenAPI parser side effects are implemented, but direct cloud KMS/HSM SDK adapters, live Sigstore verification, live provider API validation, external group synchronization, and worker-owned parsing for every upload family remain deployment hardening work. Hand-tuned per-resource repository implementations and moving all remaining parser side effects fully out of request paths remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. Evydence does not prove provider truth, scanner authority, runtime security, legal compliance, or release security by itself. diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 745fd97..2ef1a67 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -37,7 +37,7 @@ The example secrets are placeholders. Replace them before using shared or produc | `EVYDENCE_S3_REGION` | No | empty | Optional S3 region. | | `EVYDENCE_S3_USE_SSL` | No | `false` locally, `true` in chart values | Use TLS for remote object storage. | | `EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE` | No | `0` disabled | Optional in-process per-client request limit using the TCP remote address. Use reverse-proxy or ingress rate limiting for production edge controls. | -| `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS` | No | `false` | Optional hardening mode for CycloneDX SBOM and generic vulnerability-scan uploads. When set to `true`, the API stores accepted records and the outbox worker populates parser-derived fields from tenant-prefixed raw payloads after digest verification. | +| `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS` | No | `false` | Optional hardening mode for CycloneDX SBOM, generic vulnerability-scan, and OpenAPI contract uploads. When set to `true`, the API stores accepted records and the outbox worker populates parser-derived fields from tenant-prefixed raw payloads after digest verification. | | `EVYDENCE_SKIP_MIGRATIONS` | No | unset | Set to `true` only when migrations are applied by a separate release process. API and worker startup still verify that no committed migrations are pending and fail closed if the database is behind. | | `EVYDENCE_MIGRATIONS_DIR` | No | `migrations` | Migration directory for API startup and `cmd/evydence-migrate`. | | `EVYDENCE_BOOTSTRAP_TENANT` | No | `Local Tenant` | Tenant name used when bootstrapping an empty store. | diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index ac742c9..5b62cfc 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -38,8 +38,8 @@ Known hardening work remains: signing operation, and future-extension state from relational rows; - worker parser jobs re-read raw object-store payloads for key formats, verify digests, validate durable state, and persist missing parser-derived - normalized fields. CycloneDX SBOM and generic vulnerability-scan uploads can - run with worker-owned normalized side effects by setting + normalized fields. CycloneDX SBOM, generic vulnerability-scan, and OpenAPI + contract uploads can run with worker-owned normalized side effects by setting `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; the other parser-backed upload paths still create initial normalized records, so fully worker-owned parsing for every payload remains hardening work; @@ -144,9 +144,9 @@ implemented capabilities: - Split the large application ledger aggregate into focused services or repositories once relational writes are in place, preserving tenant isolation and append-only behavior throughout. -- Continue moving parser-owned side effects for OpenAPI, VEX, and attestation - payloads into worker processors. CycloneDX SBOM and generic vulnerability - scan normalized fields can be worker-owned behind +- Continue moving parser-owned side effects for VEX and attestation payloads + into worker processors. CycloneDX SBOM, generic vulnerability scan, and + OpenAPI contract normalized fields can be worker-owned behind `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; workers also persist missing parser-derived fields for replay-compatible records. - Keep OpenAPI precision at zero broad operations as routes are added or diff --git a/docs/reference/worker-outbox.md b/docs/reference/worker-outbox.md index 3d37521..3136d31 100644 --- a/docs/reference/worker-outbox.md +++ b/docs/reference/worker-outbox.md @@ -12,18 +12,18 @@ Configured job kinds: - `verify_subject` - `verify_attestation` -Current behavior is intentionally conservative. The API still records normalized signing and verification results before enqueueing jobs for the implemented paths. Parser jobs independently replay tenant-prefixed payload objects when `payload_ref` is present, verify object metadata and byte digests when `payload_hash` is present, parse SBOM, vulnerability-scan, OpenAPI, OpenVEX, and DSSE attestation payloads, and check that replayed payload summaries match the expected durable state. When `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, CycloneDX SBOM and generic vulnerability-scan uploads store accepted records first, and the `parse_sbom` and `parse_vulnerability_scan` workers write parser-derived fields after replay. Missing objects, wrong tenant prefixes, tenant mismatches, oversized payload objects, malformed replay payloads, durable-state mismatches, incomplete verification, missing signatures, hash mismatch, uninitialized storage, and unsupported job kinds fail the job safely. +Current behavior is intentionally conservative. The API still records normalized signing and verification results before enqueueing jobs for the implemented paths. Parser jobs independently replay tenant-prefixed payload objects when `payload_ref` is present, verify object metadata and byte digests when `payload_hash` is present, parse SBOM, vulnerability-scan, OpenAPI, OpenVEX, and DSSE attestation payloads, and check that replayed payload summaries match the expected durable state. When `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, CycloneDX SBOM, generic vulnerability-scan, and OpenAPI contract uploads store accepted records first, and the `parse_sbom`, `parse_vulnerability_scan`, and `parse_openapi_contract` workers write parser-derived fields after replay. Missing objects, wrong tenant prefixes, tenant mismatches, oversized payload objects, malformed replay payloads, durable-state mismatches, incomplete verification, missing signatures, hash mismatch, uninitialized storage, and unsupported job kinds fail the job safely. Parser and attestation jobs include a deterministic `parser_version` payload field for new uploads. Workers reject unsupported parser versions and accept older jobs with no parser version for upgrade compatibility. -Parser replay is worker-owned for CycloneDX SBOM and generic vulnerability-scan -normalized fields when `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`. -OpenAPI, OpenVEX, and attestation upload paths still create initial normalized -records before worker replay validates and backfills missing fields. Moving -those remaining parser side effects fully out of the request path remains -production hardening work. +Parser replay is worker-owned for CycloneDX SBOM, generic vulnerability-scan, +and OpenAPI contract normalized fields when +`EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`. OpenVEX and attestation +upload paths still create initial normalized records before worker replay +validates and backfills missing fields. Moving those remaining parser side +effects fully out of the request path remains production hardening work. Workers use the same object-store environment variables as the API. The default worker payload replay limit is 20 MiB and can be adjusted with `EVYDENCE_WORKER_MAX_PAYLOAD_BYTES`. diff --git a/internal/app/ledger.go b/internal/app/ledger.go index 7f3b6b1..0428d7d 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -1147,8 +1147,15 @@ func (l *Ledger) UploadOpenAPIContract(ctx context.Context, actor domain.Actor, l.mu.Lock() defer l.mu.Unlock() contract := domain.OpenAPIContract{ID: newID("oas"), TenantID: actor.TenantID, ProductID: productID, ReleaseID: releaseID, Version: version, Hash: payloadHash, PathCount: len(doc.Paths.Map()), Operations: operations, EvidenceID: item.ID, CreatedAt: l.now()} - l.contracts[contract.ID] = contract - _, _ = l.appendChainLocked(actor.TenantID, "openapi_contract.parsed", "openapi_contract", contract.ID, "api_key", actor.KeyID, contract.Hash, "") + persistedContract := contract + chainAction := "openapi_contract.parsed" + if l.workerOwnedParsers { + persistedContract.PathCount = 0 + persistedContract.Operations = nil + chainAction = "openapi_contract.accepted" + } + l.contracts[contract.ID] = persistedContract + _, _ = l.appendChainLocked(actor.TenantID, chainAction, "openapi_contract", contract.ID, "api_key", actor.KeyID, contract.Hash, "") if err := l.enqueue(ctx, actor.TenantID, "parse_openapi_contract", "openapi_contract", contract.ID, map[string]any{"payload_ref": payloadRef, "payload_hash": payloadHash, "parser_version": ParserVersionOpenAPIJSON}); err != nil { return domain.OpenAPIContract{}, err } diff --git a/internal/app/ledger_test.go b/internal/app/ledger_test.go index 283ffcc..e1420dc 100644 --- a/internal/app/ledger_test.go +++ b/internal/app/ledger_test.go @@ -266,6 +266,69 @@ func TestUploadVulnerabilityScanCanDeferParserSideEffectsToWorker(t *testing.T) } } +func TestUploadOpenAPIContractCanDeferParserSideEffectsToWorker(t *testing.T) { + outbox := &recordingOutbox{} + store := NewMemoryStore() + objects := newTestObjectStore() + ledger := NewLedger(Config{ + APIKeyPepper: "test-pepper", + Now: fixedNow, + Store: store, + ObjectStore: objects, + Outbox: outbox, + WorkerOwnedParserSideEffects: true, + }) + ctx := context.Background() + _, _, secret, err := ledger.BootstrapTenant(ctx, "Tenant", "admin", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap: %v", err) + } + actor, err := ledger.Authenticate(ctx, secret) + if err != nil { + t.Fatalf("auth: %v", err) + } + product, err := ledger.CreateProduct(ctx, actor, "Payments API", "payments-worker-openapi") + if err != nil { + t.Fatalf("create product: %v", err) + } + release, err := ledger.CreateRelease(ctx, actor, product.ID, "1.0.0") + if err != nil { + t.Fatalf("create release: %v", err) + } + + contract, err := ledger.UploadOpenAPIContract(ctx, actor, product.ID, release.ID, "v1", []byte(`{"openapi":"3.1.0","info":{"title":"API","version":"1"},"paths":{"/v1/a":{"get":{"responses":{"200":{"description":"ok"}}}}}}`)) + if err != nil { + t.Fatalf("upload contract: %v", err) + } + if contract.PathCount != 1 || len(contract.Operations) != 1 { + t.Fatalf("upload response should keep parsed contract fields: %#v", contract) + } + + state, ok, err := store.LoadState(ctx) + if err != nil || !ok { + t.Fatalf("load state ok=%v err=%v", ok, err) + } + persisted := state.Contracts[contract.ID] + if persisted.PathCount != 0 || len(persisted.Operations) != 0 || persisted.Hash == "" { + t.Fatalf("persisted contract should wait for worker parser side effects but keep hash: %#v", persisted) + } + if len(outbox.jobs) != 1 { + t.Fatalf("outbox jobs = %d, want 1", len(outbox.jobs)) + } + job := outbox.jobs[0] + if job.Kind != "parse_openapi_contract" || job.Payload["payload_ref"] == "" || job.Payload["payload_hash"] == "" || job.Payload["parser_version"] != ParserVersionOpenAPIJSON { + t.Fatalf("outbox job missing replay metadata: %#v", job) + } + payloadRef, ok := job.Payload["payload_ref"].(string) + payloadKey := strings.TrimPrefix(payloadRef, "object://") + if !ok || !strings.HasPrefix(payloadKey, "tenants/"+actor.TenantID+"/") { + t.Fatalf("payload ref %q is not tenant-prefixed", job.Payload["payload_ref"]) + } + if _, err := objects.Get(ctx, payloadKey); err != nil { + t.Fatalf("stored payload missing: %v", err) + } +} + func TestIdempotencyReplayAndConflict(t *testing.T) { ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) ctx := context.Background() From 7ba2b3fdcd4938fb49ebcdc76524bcc181bff8eb Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 22:01:58 +0300 Subject: [PATCH 113/287] feat: defer attestation parsing to workers --- .api.env.example | 6 +- README.md | 2 +- cmd/evydence-worker/main.go | 4 ++ cmd/evydence-worker/main_test.go | 6 +- docs/architecture.md | 4 +- docs/reference/configuration.md | 2 +- docs/reference/production-readiness.md | 15 ++--- docs/reference/worker-outbox.md | 12 ++-- internal/app/builds.go | 17 +++++- internal/app/ledger_test.go | 79 ++++++++++++++++++++++++++ 10 files changed, 124 insertions(+), 23 deletions(-) diff --git a/.api.env.example b/.api.env.example index 1c227b7..8a05f6c 100644 --- a/.api.env.example +++ b/.api.env.example @@ -6,9 +6,9 @@ EVYDENCE_DATABASE_URL=postgres://evydence:change-me@localhost:5432/evydence?sslm EVYDENCE_OBJECT_STORE=filesystem EVYDENCE_OBJECT_DIR=./tmp/objects EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE=0 -# Optional hardening mode for CycloneDX SBOM, generic vulnerability-scan, and -# OpenAPI contract uploads. When true, the API stores accepted records and the -# outbox worker writes parser-derived fields. +# Optional hardening mode for CycloneDX SBOM, generic vulnerability-scan, +# OpenAPI contract, and DSSE build-attestation uploads. When true, the API +# stores accepted records and the outbox worker writes parser-derived fields. EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=false EVYDENCE_SIGNING_KEY_MODE=external # Optional external signing gateway. Use HTTPS outside localhost. diff --git a/README.md b/README.md index 16d2623..29e3a2b 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ This repository contains a Go implementation under module `github.com/aatuh/evyd - PostgreSQL-backed durable ledger state, tenant-scoped relational projections, migrations, and persisted outbox jobs when `EVYDENCE_DATABASE_URL` is set. - Filesystem or S3/MinIO-compatible object storage for raw upload payload bytes under tenant-prefixed paths. - Polling `cmd/evydence-worker` process that claims persisted outbox jobs with PostgreSQL row locking and records retry or terminal status. -- Optional worker-owned CycloneDX SBOM, generic vulnerability-scan, and OpenAPI contract parser side effects through `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; other parser-backed upload families still create initial normalized records before worker replay validates or backfills them. +- Optional worker-owned CycloneDX SBOM, generic vulnerability-scan, OpenAPI contract, and DSSE build-attestation parser side effects through `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; OpenVEX upload still creates initial normalized records before worker replay validates or backfills it. ### Tooling, Deployment, And Examples diff --git a/cmd/evydence-worker/main.go b/cmd/evydence-worker/main.go index 9be5979..655fa3f 100644 --- a/cmd/evydence-worker/main.go +++ b/cmd/evydence-worker/main.go @@ -786,6 +786,10 @@ func mergeReplayedAttestation(attestation domain.BuildAttestation, parsed replay attestation.MaterialsCount = parsed.MaterialsCount changed = true } + if attestation.VerificationStatus == "" || attestation.VerificationStatus == "accepted" { + attestation.VerificationStatus = "structurally_valid" + changed = true + } return attestation, changed } diff --git a/cmd/evydence-worker/main_test.go b/cmd/evydence-worker/main_test.go index af10dd9..9667d0a 100644 --- a/cmd/evydence-worker/main_test.go +++ b/cmd/evydence-worker/main_test.go @@ -518,9 +518,13 @@ func TestReplayMergeHelpersCoverParserSideEffects(t *testing.T) { BuildType: "test", MaterialsCount: 2, }, raw) - if !changed || attestation.PayloadHash == "" || attestation.PayloadSize == 0 || attestation.PredicateType == "" || len(attestation.SubjectDigests) != 1 || attestation.SignatureCount != 1 || attestation.BuilderID == "" || attestation.BuildType == "" || attestation.MaterialsCount != 2 { + if !changed || attestation.PayloadHash == "" || attestation.PayloadSize == 0 || attestation.PredicateType == "" || len(attestation.SubjectDigests) != 1 || attestation.SignatureCount != 1 || attestation.BuilderID == "" || attestation.BuildType == "" || attestation.MaterialsCount != 2 || attestation.VerificationStatus != "structurally_valid" { t.Fatalf("merged attestation = %#v changed=%v", attestation, changed) } + accepted, changed := mergeReplayedAttestation(domain.BuildAttestation{VerificationStatus: "accepted"}, replayedAttestation{}, raw) + if !changed || accepted.VerificationStatus != "structurally_valid" { + t.Fatalf("accepted attestation status was not completed: %#v changed=%v", accepted, changed) + } if err := verifyReplayedAttestation(raw, replayedAttestation{PredicateType: "other", SubjectDigests: attestation.SubjectDigests}, attestation); err == nil { t.Fatal("expected attestation predicate mismatch") } diff --git a/docs/architecture.md b/docs/architecture.md index d56bb74..c1e0548 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -26,7 +26,7 @@ When `EVYDENCE_DATABASE_URL` is set, mutations are saved to PostgreSQL before su Evidence, evidence lifecycle events, incidents, remediation tasks, security scans, manual security documents, SBOM diffs, VEX documents, vulnerability decisions/workflow records, organizations, users, role bindings, SSO providers, SSO sessions, legal holds, retention overrides, customer portal access records, questionnaire packages and drafts, evidence summaries, evidence graph snapshots, commercial and marketplace collector definitions, waivers, approvals, customer packages, report templates, evidence bundles, exceptions, build runs, build attestations, release candidates, artifact signatures, source-control records, deployment events, contract diffs, custom policy evaluations, provider verifications, signing operations, control evidence links, public transparency log entries, and release bundle records are append-only in behavior. Changes are represented by supersession, lifecycle events, approval transitions, session revocation, package access records, links, verification receipts, rollback-as-new-event records, or new audit-chain entries. -Outbox jobs are persisted in PostgreSQL and claimed by workers with `FOR UPDATE SKIP LOCKED`. Parser jobs re-read tenant-prefixed object-store payloads, verify size and digest, validate durable state, persist missing parser-derived normalized fields, and fail closed on mismatches. With `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, CycloneDX SBOM, generic vulnerability-scan, and OpenAPI contract uploads store accepted records and workers populate normalized fields from replayed payloads. Other parser-backed upload endpoints still create initial normalized records, so moving every parser-owned side effect fully out of the API request path remains production hardening work. +Outbox jobs are persisted in PostgreSQL and claimed by workers with `FOR UPDATE SKIP LOCKED`. Parser jobs re-read tenant-prefixed object-store payloads, verify size and digest, validate durable state, persist missing parser-derived normalized fields, and fail closed on mismatches. With `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, CycloneDX SBOM, generic vulnerability-scan, OpenAPI contract, and DSSE build-attestation uploads store accepted records and workers populate normalized fields from replayed payloads. OpenVEX upload still creates initial normalized records, so moving every parser-owned side effect fully out of the API request path remains production hardening work. ## Verification And Trust @@ -52,6 +52,6 @@ Air-gapped import-bundle workflows preserve the same tenant-scoped import path a ## Limitations -The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, OIDC discovery refresh, SSO credential exchange with session-scoped OIDC group-role mapping, public-transparency proof fetching, and optional worker-owned CycloneDX SBOM, generic vulnerability-scan, and OpenAPI parser side effects are implemented, but direct cloud KMS/HSM SDK adapters, live Sigstore verification, live provider API validation, external group synchronization, and worker-owned parsing for every upload family remain deployment hardening work. Hand-tuned per-resource repository implementations and moving all remaining parser side effects fully out of request paths remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. +The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, OIDC discovery refresh, SSO credential exchange with session-scoped OIDC group-role mapping, public-transparency proof fetching, and optional worker-owned CycloneDX SBOM, generic vulnerability-scan, OpenAPI, and DSSE build-attestation parser side effects are implemented, but direct cloud KMS/HSM SDK adapters, live Sigstore verification, live provider API validation, external group synchronization, and worker-owned parsing for every upload family remain deployment hardening work. Hand-tuned per-resource repository implementations and moving all remaining parser side effects fully out of request paths remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. Evydence does not prove provider truth, scanner authority, runtime security, legal compliance, or release security by itself. diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 2ef1a67..6b1cb07 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -37,7 +37,7 @@ The example secrets are placeholders. Replace them before using shared or produc | `EVYDENCE_S3_REGION` | No | empty | Optional S3 region. | | `EVYDENCE_S3_USE_SSL` | No | `false` locally, `true` in chart values | Use TLS for remote object storage. | | `EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE` | No | `0` disabled | Optional in-process per-client request limit using the TCP remote address. Use reverse-proxy or ingress rate limiting for production edge controls. | -| `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS` | No | `false` | Optional hardening mode for CycloneDX SBOM, generic vulnerability-scan, and OpenAPI contract uploads. When set to `true`, the API stores accepted records and the outbox worker populates parser-derived fields from tenant-prefixed raw payloads after digest verification. | +| `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS` | No | `false` | Optional hardening mode for CycloneDX SBOM, generic vulnerability-scan, OpenAPI contract, and DSSE build-attestation uploads. When set to `true`, the API stores accepted records and the outbox worker populates parser-derived fields from tenant-prefixed raw payloads after digest verification. | | `EVYDENCE_SKIP_MIGRATIONS` | No | unset | Set to `true` only when migrations are applied by a separate release process. API and worker startup still verify that no committed migrations are pending and fail closed if the database is behind. | | `EVYDENCE_MIGRATIONS_DIR` | No | `migrations` | Migration directory for API startup and `cmd/evydence-migrate`. | | `EVYDENCE_BOOTSTRAP_TENANT` | No | `Local Tenant` | Tenant name used when bootstrapping an empty store. | diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 5b62cfc..40a4351 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -39,10 +39,11 @@ Known hardening work remains: - worker parser jobs re-read raw object-store payloads for key formats, verify digests, validate durable state, and persist missing parser-derived normalized fields. CycloneDX SBOM, generic vulnerability-scan, and OpenAPI - contract uploads can run with worker-owned normalized side effects by setting - `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; the other parser-backed - upload paths still create initial normalized records, so fully worker-owned - parsing for every payload remains hardening work; + contract and DSSE build-attestation uploads can run with worker-owned + normalized side effects by setting + `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; OpenVEX upload still + creates initial normalized records, so fully worker-owned parsing for every + payload remains hardening work; - OpenAPI precision is enforced across the registered public API. The generated matrix remains the source of truth for operation ids, scopes, idempotency, parameters, and request/response schemas; @@ -144,9 +145,9 @@ implemented capabilities: - Split the large application ledger aggregate into focused services or repositories once relational writes are in place, preserving tenant isolation and append-only behavior throughout. -- Continue moving parser-owned side effects for VEX and attestation payloads - into worker processors. CycloneDX SBOM, generic vulnerability scan, and - OpenAPI contract normalized fields can be worker-owned behind +- Continue moving parser-owned side effects for VEX payloads into worker + processors. CycloneDX SBOM, generic vulnerability scan, OpenAPI contract, and + DSSE build-attestation normalized fields can be worker-owned behind `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; workers also persist missing parser-derived fields for replay-compatible records. - Keep OpenAPI precision at zero broad operations as routes are added or diff --git a/docs/reference/worker-outbox.md b/docs/reference/worker-outbox.md index 3136d31..8db3351 100644 --- a/docs/reference/worker-outbox.md +++ b/docs/reference/worker-outbox.md @@ -12,18 +12,18 @@ Configured job kinds: - `verify_subject` - `verify_attestation` -Current behavior is intentionally conservative. The API still records normalized signing and verification results before enqueueing jobs for the implemented paths. Parser jobs independently replay tenant-prefixed payload objects when `payload_ref` is present, verify object metadata and byte digests when `payload_hash` is present, parse SBOM, vulnerability-scan, OpenAPI, OpenVEX, and DSSE attestation payloads, and check that replayed payload summaries match the expected durable state. When `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, CycloneDX SBOM, generic vulnerability-scan, and OpenAPI contract uploads store accepted records first, and the `parse_sbom`, `parse_vulnerability_scan`, and `parse_openapi_contract` workers write parser-derived fields after replay. Missing objects, wrong tenant prefixes, tenant mismatches, oversized payload objects, malformed replay payloads, durable-state mismatches, incomplete verification, missing signatures, hash mismatch, uninitialized storage, and unsupported job kinds fail the job safely. +Current behavior is intentionally conservative. The API still records normalized signing and verification results before enqueueing jobs for the implemented paths. Parser jobs independently replay tenant-prefixed payload objects when `payload_ref` is present, verify object metadata and byte digests when `payload_hash` is present, parse SBOM, vulnerability-scan, OpenAPI, OpenVEX, and DSSE attestation payloads, and check that replayed payload summaries match the expected durable state. When `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, CycloneDX SBOM, generic vulnerability-scan, OpenAPI contract, and DSSE build-attestation uploads store accepted records first, and the `parse_sbom`, `parse_vulnerability_scan`, `parse_openapi_contract`, and `verify_attestation` workers write parser-derived fields after replay. Missing objects, wrong tenant prefixes, tenant mismatches, oversized payload objects, malformed replay payloads, durable-state mismatches, incomplete verification, missing signatures, hash mismatch, uninitialized storage, and unsupported job kinds fail the job safely. Parser and attestation jobs include a deterministic `parser_version` payload field for new uploads. Workers reject unsupported parser versions and accept older jobs with no parser version for upgrade compatibility. Parser replay is worker-owned for CycloneDX SBOM, generic vulnerability-scan, -and OpenAPI contract normalized fields when -`EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`. OpenVEX and attestation -upload paths still create initial normalized records before worker replay -validates and backfills missing fields. Moving those remaining parser side -effects fully out of the request path remains production hardening work. +OpenAPI contract, and DSSE build-attestation normalized fields when +`EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`. OpenVEX upload paths still +create initial normalized records before worker replay validates and backfills +missing fields. Moving that remaining parser side effect fully out of the +request path remains production hardening work. Workers use the same object-store environment variables as the API. The default worker payload replay limit is 20 MiB and can be adjusted with `EVYDENCE_WORKER_MAX_PAYLOAD_BYTES`. diff --git a/internal/app/builds.go b/internal/app/builds.go index 67b7577..9100f62 100644 --- a/internal/app/builds.go +++ b/internal/app/builds.go @@ -443,8 +443,21 @@ func (l *Ledger) UploadBuildAttestation(ctx context.Context, actor domain.Actor, SchemaVersion: domain.BuildAttestationSchemaVersion, CreatedAt: l.now(), } - l.attestations[attestation.ID] = attestation - _, _ = l.appendChainLocked(actor.TenantID, "build_attestation.created", "build_attestation", attestation.ID, actorType(actor), actorID(actor), payloadHash, "") + persistedAttestation := attestation + chainAction := "build_attestation.created" + if l.workerOwnedParsers { + persistedAttestation.PayloadType = "" + persistedAttestation.PredicateType = "" + persistedAttestation.SubjectDigests = nil + persistedAttestation.BuilderID = "" + persistedAttestation.BuildType = "" + persistedAttestation.MaterialsCount = 0 + persistedAttestation.SignatureCount = 0 + persistedAttestation.VerificationStatus = "accepted" + chainAction = "build_attestation.accepted" + } + l.attestations[attestation.ID] = persistedAttestation + _, _ = l.appendChainLocked(actor.TenantID, chainAction, "build_attestation", attestation.ID, actorType(actor), actorID(actor), payloadHash, "") if err := l.enqueue(ctx, actor.TenantID, "verify_attestation", "build_attestation", attestation.ID, map[string]any{"payload_ref": payloadRef, "payload_hash": payloadHash, "parser_version": ParserVersionDSSEInTotoJSON}); err != nil { return domain.BuildAttestation{}, err } diff --git a/internal/app/ledger_test.go b/internal/app/ledger_test.go index e1420dc..8e7f2a0 100644 --- a/internal/app/ledger_test.go +++ b/internal/app/ledger_test.go @@ -329,6 +329,85 @@ func TestUploadOpenAPIContractCanDeferParserSideEffectsToWorker(t *testing.T) { } } +func TestUploadBuildAttestationCanDeferParserSideEffectsToWorker(t *testing.T) { + outbox := &recordingOutbox{} + store := NewMemoryStore() + objects := newTestObjectStore() + ledger := NewLedger(Config{ + APIKeyPepper: "test-pepper", + Now: fixedNow, + Store: store, + ObjectStore: objects, + Outbox: outbox, + WorkerOwnedParserSideEffects: true, + }) + ctx := context.Background() + actor, release, artifact := setupReleaseRiskFixture(t, ledger) + project, err := ledger.CreateProject(ctx, actor, release.ProductID, "api") + if err != nil { + t.Fatalf("project: %v", err) + } + _, _, secret, err := ledger.CreateCollector(ctx, actor, CreateCollectorInput{Name: "gha", Type: "github_actions", Version: "1.0.0"}) + if err != nil { + t.Fatalf("collector: %v", err) + } + collectorActor, err := ledger.Authenticate(ctx, secret) + if err != nil { + t.Fatalf("auth collector: %v", err) + } + build, err := ledger.CreateBuildRun(ctx, collectorActor, CreateBuildRunInput{ + ProjectID: project.ID, + ReleaseID: release.ID, + Provider: "github_actions", + CommitSHA: "0123456789abcdef0123456789abcdef01234567", + Repository: "aatuh/evydence", + WorkflowRef: "aatuh/evydence/.github/workflows/release.yml@refs/heads/main", + RunID: "123456789", + RunAttempt: 1, + Status: "passed", + StartedAt: fixedNow(), + Outputs: []domain.BuildOutput{{ArtifactID: artifact.ID, Digest: artifact.Digest}}, + }) + if err != nil { + t.Fatalf("build: %v", err) + } + + attestation, err := ledger.UploadBuildAttestation(ctx, collectorActor, build.ID, dsseForDigest(t, artifact.Digest)) + if err != nil { + t.Fatalf("attestation: %v", err) + } + if attestation.PredicateType == "" || len(attestation.SubjectDigests) != 1 || attestation.SignatureCount != 1 || attestation.VerificationStatus != "structurally_valid" { + t.Fatalf("upload response should keep parsed attestation fields: %#v", attestation) + } + + state, ok, err := store.LoadState(ctx) + if err != nil || !ok { + t.Fatalf("load state ok=%v err=%v", ok, err) + } + persisted := state.BuildAttestations[attestation.ID] + if persisted.TenantID != actor.TenantID || persisted.PayloadHash == "" || persisted.PayloadSize == 0 || persisted.VerificationStatus != "accepted" { + t.Fatalf("persisted attestation should keep accepted metadata: %#v", persisted) + } + if persisted.PredicateType != "" || len(persisted.SubjectDigests) != 0 || persisted.SignatureCount != 0 { + t.Fatalf("persisted attestation should wait for worker parser side effects: %#v", persisted) + } + if len(outbox.jobs) != 1 { + t.Fatalf("outbox jobs = %d, want 1", len(outbox.jobs)) + } + job := outbox.jobs[0] + if job.Kind != "verify_attestation" || job.Payload["payload_ref"] == "" || job.Payload["payload_hash"] == "" || job.Payload["parser_version"] != ParserVersionDSSEInTotoJSON { + t.Fatalf("outbox job missing replay metadata: %#v", job) + } + payloadRef, ok := job.Payload["payload_ref"].(string) + payloadKey := strings.TrimPrefix(payloadRef, "object://") + if !ok || !strings.HasPrefix(payloadKey, "tenants/"+actor.TenantID+"/") { + t.Fatalf("payload ref %q is not tenant-prefixed", job.Payload["payload_ref"]) + } + if _, err := objects.Get(ctx, payloadKey); err != nil { + t.Fatalf("stored payload missing: %v", err) + } +} + func TestIdempotencyReplayAndConflict(t *testing.T) { ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) ctx := context.Background() From b76925c8fb7c32592955d1d23a8ecd01ed886ed1 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 22:07:04 +0300 Subject: [PATCH 114/287] feat: defer vex document parsing to workers --- .api.env.example | 6 +- README.md | 2 +- docs/architecture.md | 4 +- docs/reference/configuration.md | 2 +- docs/reference/production-readiness.md | 21 ++++--- docs/reference/worker-outbox.md | 12 ++-- internal/app/ledger_test.go | 84 ++++++++++++++++++++++++++ internal/app/vex.go | 12 +++- 8 files changed, 118 insertions(+), 25 deletions(-) diff --git a/.api.env.example b/.api.env.example index 8a05f6c..d773472 100644 --- a/.api.env.example +++ b/.api.env.example @@ -6,9 +6,9 @@ EVYDENCE_DATABASE_URL=postgres://evydence:change-me@localhost:5432/evydence?sslm EVYDENCE_OBJECT_STORE=filesystem EVYDENCE_OBJECT_DIR=./tmp/objects EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE=0 -# Optional hardening mode for CycloneDX SBOM, generic vulnerability-scan, -# OpenAPI contract, and DSSE build-attestation uploads. When true, the API -# stores accepted records and the outbox worker writes parser-derived fields. +# Optional hardening mode for parser-backed uploads. When true, the API stores +# accepted records and the outbox worker writes parser-derived fields. OpenVEX +# vulnerability decisions are still created in the request path. EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=false EVYDENCE_SIGNING_KEY_MODE=external # Optional external signing gateway. Use HTTPS outside localhost. diff --git a/README.md b/README.md index 29e3a2b..05b2b10 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ This repository contains a Go implementation under module `github.com/aatuh/evyd - PostgreSQL-backed durable ledger state, tenant-scoped relational projections, migrations, and persisted outbox jobs when `EVYDENCE_DATABASE_URL` is set. - Filesystem or S3/MinIO-compatible object storage for raw upload payload bytes under tenant-prefixed paths. - Polling `cmd/evydence-worker` process that claims persisted outbox jobs with PostgreSQL row locking and records retry or terminal status. -- Optional worker-owned CycloneDX SBOM, generic vulnerability-scan, OpenAPI contract, and DSSE build-attestation parser side effects through `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; OpenVEX upload still creates initial normalized records before worker replay validates or backfills it. +- Optional worker-owned parser document side effects through `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; OpenVEX-derived vulnerability decisions still run in the request path so readiness decisions stay deterministic before workers finish. ### Tooling, Deployment, And Examples diff --git a/docs/architecture.md b/docs/architecture.md index c1e0548..57df17f 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -26,7 +26,7 @@ When `EVYDENCE_DATABASE_URL` is set, mutations are saved to PostgreSQL before su Evidence, evidence lifecycle events, incidents, remediation tasks, security scans, manual security documents, SBOM diffs, VEX documents, vulnerability decisions/workflow records, organizations, users, role bindings, SSO providers, SSO sessions, legal holds, retention overrides, customer portal access records, questionnaire packages and drafts, evidence summaries, evidence graph snapshots, commercial and marketplace collector definitions, waivers, approvals, customer packages, report templates, evidence bundles, exceptions, build runs, build attestations, release candidates, artifact signatures, source-control records, deployment events, contract diffs, custom policy evaluations, provider verifications, signing operations, control evidence links, public transparency log entries, and release bundle records are append-only in behavior. Changes are represented by supersession, lifecycle events, approval transitions, session revocation, package access records, links, verification receipts, rollback-as-new-event records, or new audit-chain entries. -Outbox jobs are persisted in PostgreSQL and claimed by workers with `FOR UPDATE SKIP LOCKED`. Parser jobs re-read tenant-prefixed object-store payloads, verify size and digest, validate durable state, persist missing parser-derived normalized fields, and fail closed on mismatches. With `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, CycloneDX SBOM, generic vulnerability-scan, OpenAPI contract, and DSSE build-attestation uploads store accepted records and workers populate normalized fields from replayed payloads. OpenVEX upload still creates initial normalized records, so moving every parser-owned side effect fully out of the API request path remains production hardening work. +Outbox jobs are persisted in PostgreSQL and claimed by workers with `FOR UPDATE SKIP LOCKED`. Parser jobs re-read tenant-prefixed object-store payloads, verify size and digest, validate durable state, persist missing parser-derived normalized fields, and fail closed on mismatches. With `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, parser-backed uploads store accepted records and workers populate normalized document fields from replayed payloads. OpenVEX-derived vulnerability decision creation still runs in the request path, so moving every parser-owned side effect fully out of the API request path remains production hardening work. ## Verification And Trust @@ -52,6 +52,6 @@ Air-gapped import-bundle workflows preserve the same tenant-scoped import path a ## Limitations -The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, OIDC discovery refresh, SSO credential exchange with session-scoped OIDC group-role mapping, public-transparency proof fetching, and optional worker-owned CycloneDX SBOM, generic vulnerability-scan, OpenAPI, and DSSE build-attestation parser side effects are implemented, but direct cloud KMS/HSM SDK adapters, live Sigstore verification, live provider API validation, external group synchronization, and worker-owned parsing for every upload family remain deployment hardening work. Hand-tuned per-resource repository implementations and moving all remaining parser side effects fully out of request paths remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. +The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, OIDC discovery refresh, SSO credential exchange with session-scoped OIDC group-role mapping, public-transparency proof fetching, and optional worker-owned parser document side effects are implemented, but direct cloud KMS/HSM SDK adapters, live Sigstore verification, live provider API validation, external group synchronization, and worker-owned OpenVEX decision creation remain deployment hardening work. Hand-tuned per-resource repository implementations and moving all remaining parser side effects fully out of request paths remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. Evydence does not prove provider truth, scanner authority, runtime security, legal compliance, or release security by itself. diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 6b1cb07..413b3aa 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -37,7 +37,7 @@ The example secrets are placeholders. Replace them before using shared or produc | `EVYDENCE_S3_REGION` | No | empty | Optional S3 region. | | `EVYDENCE_S3_USE_SSL` | No | `false` locally, `true` in chart values | Use TLS for remote object storage. | | `EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE` | No | `0` disabled | Optional in-process per-client request limit using the TCP remote address. Use reverse-proxy or ingress rate limiting for production edge controls. | -| `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS` | No | `false` | Optional hardening mode for CycloneDX SBOM, generic vulnerability-scan, OpenAPI contract, and DSSE build-attestation uploads. When set to `true`, the API stores accepted records and the outbox worker populates parser-derived fields from tenant-prefixed raw payloads after digest verification. | +| `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS` | No | `false` | Optional hardening mode for parser-backed uploads. When set to `true`, the API stores accepted records and the outbox worker populates parser-derived fields from tenant-prefixed raw payloads after digest verification. OpenVEX vulnerability decisions are still created in the request path. | | `EVYDENCE_SKIP_MIGRATIONS` | No | unset | Set to `true` only when migrations are applied by a separate release process. API and worker startup still verify that no committed migrations are pending and fail closed if the database is behind. | | `EVYDENCE_MIGRATIONS_DIR` | No | `migrations` | Migration directory for API startup and `cmd/evydence-migrate`. | | `EVYDENCE_BOOTSTRAP_TENANT` | No | `Local Tenant` | Tenant name used when bootstrapping an empty store. | diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 40a4351..541019e 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -39,11 +39,11 @@ Known hardening work remains: - worker parser jobs re-read raw object-store payloads for key formats, verify digests, validate durable state, and persist missing parser-derived normalized fields. CycloneDX SBOM, generic vulnerability-scan, and OpenAPI - contract and DSSE build-attestation uploads can run with worker-owned - normalized side effects by setting - `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; OpenVEX upload still - creates initial normalized records, so fully worker-owned parsing for every - payload remains hardening work; + contract, DSSE build-attestation, and OpenVEX document uploads can run with + worker-owned document side effects by setting + `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; OpenVEX-derived + vulnerability decisions still run in the request path, so fully worker-owned + decision creation remains hardening work; - OpenAPI precision is enforced across the registered public API. The generated matrix remains the source of truth for operation ids, scopes, idempotency, parameters, and request/response schemas; @@ -145,11 +145,12 @@ implemented capabilities: - Split the large application ledger aggregate into focused services or repositories once relational writes are in place, preserving tenant isolation and append-only behavior throughout. -- Continue moving parser-owned side effects for VEX payloads into worker - processors. CycloneDX SBOM, generic vulnerability scan, OpenAPI contract, and - DSSE build-attestation normalized fields can be worker-owned behind - `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; workers also persist - missing parser-derived fields for replay-compatible records. +- Continue moving OpenVEX-derived vulnerability decision creation into an + idempotent worker processor. CycloneDX SBOM, generic vulnerability scan, + OpenAPI contract, DSSE build-attestation, and OpenVEX document metadata can + be worker-owned behind `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; + workers also persist missing parser-derived fields for replay-compatible + records. - Keep OpenAPI precision at zero broad operations as routes are added or changed, and expand generated SDK coverage from the committed contract. - Add direct cloud KMS/HSM SDK adapters where required. The current HTTPS diff --git a/docs/reference/worker-outbox.md b/docs/reference/worker-outbox.md index 8db3351..1981519 100644 --- a/docs/reference/worker-outbox.md +++ b/docs/reference/worker-outbox.md @@ -12,18 +12,18 @@ Configured job kinds: - `verify_subject` - `verify_attestation` -Current behavior is intentionally conservative. The API still records normalized signing and verification results before enqueueing jobs for the implemented paths. Parser jobs independently replay tenant-prefixed payload objects when `payload_ref` is present, verify object metadata and byte digests when `payload_hash` is present, parse SBOM, vulnerability-scan, OpenAPI, OpenVEX, and DSSE attestation payloads, and check that replayed payload summaries match the expected durable state. When `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, CycloneDX SBOM, generic vulnerability-scan, OpenAPI contract, and DSSE build-attestation uploads store accepted records first, and the `parse_sbom`, `parse_vulnerability_scan`, `parse_openapi_contract`, and `verify_attestation` workers write parser-derived fields after replay. Missing objects, wrong tenant prefixes, tenant mismatches, oversized payload objects, malformed replay payloads, durable-state mismatches, incomplete verification, missing signatures, hash mismatch, uninitialized storage, and unsupported job kinds fail the job safely. +Current behavior is intentionally conservative. The API still records normalized signing and verification results before enqueueing jobs for the implemented paths. Parser jobs independently replay tenant-prefixed payload objects when `payload_ref` is present, verify object metadata and byte digests when `payload_hash` is present, parse SBOM, vulnerability-scan, OpenAPI, OpenVEX, and DSSE attestation payloads, and check that replayed payload summaries match the expected durable state. When `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, parser-backed uploads store accepted records first and workers write parser-derived document fields after replay. OpenVEX-derived vulnerability decisions are still created in the request path so release-readiness decisions stay deterministic before the `parse_vex` worker runs. Missing objects, wrong tenant prefixes, tenant mismatches, oversized payload objects, malformed replay payloads, durable-state mismatches, incomplete verification, missing signatures, hash mismatch, uninitialized storage, and unsupported job kinds fail the job safely. Parser and attestation jobs include a deterministic `parser_version` payload field for new uploads. Workers reject unsupported parser versions and accept older jobs with no parser version for upgrade compatibility. Parser replay is worker-owned for CycloneDX SBOM, generic vulnerability-scan, -OpenAPI contract, and DSSE build-attestation normalized fields when -`EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`. OpenVEX upload paths still -create initial normalized records before worker replay validates and backfills -missing fields. Moving that remaining parser side effect fully out of the -request path remains production hardening work. +OpenAPI contract, DSSE build-attestation, and OpenVEX document metadata when +`EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`. OpenVEX-derived +vulnerability decision creation still runs in the request path. Moving that +decision side effect into an idempotent worker processor remains production +hardening work. Workers use the same object-store environment variables as the API. The default worker payload replay limit is 20 MiB and can be adjusted with `EVYDENCE_WORKER_MAX_PAYLOAD_BYTES`. diff --git a/internal/app/ledger_test.go b/internal/app/ledger_test.go index 8e7f2a0..2e982ab 100644 --- a/internal/app/ledger_test.go +++ b/internal/app/ledger_test.go @@ -712,6 +712,90 @@ func TestOpenVEXIngestionCreatesDecisionAndRejectsMalformedInput(t *testing.T) { } } +func TestUploadVEXCanDeferDocumentParserSideEffectsToWorker(t *testing.T) { + outbox := &recordingOutbox{} + store := NewMemoryStore() + objects := newTestObjectStore() + ledger := NewLedger(Config{ + APIKeyPepper: "test-pepper", + Now: fixedNow, + Store: store, + ObjectStore: objects, + Outbox: outbox, + WorkerOwnedParserSideEffects: true, + }) + ctx := context.Background() + actor, release, artifact := setupReleaseRiskFixture(t, ledger) + scan, err := ledger.UploadVulnerabilityScan(ctx, actor, []byte(`{ + "scanner":"grype", + "target_ref":"pkg:oci/payments-api", + "release_id":"`+release.ID+`", + "findings":[{"vulnerability":"CVE-2026-0002","component":"pkg:apk/openssl@3.1.0","severity":"critical","state":"open"}] + }`)) + if err != nil { + t.Fatalf("scan: %v", err) + } + ledger.mu.Lock() + ledger.scans[scan.ID] = scan + ledger.mu.Unlock() + outbox.jobs = nil + + vex, err := ledger.UploadVEX(ctx, actor, release.ID, artifact.ID, []byte(`{ + "@context":"https://openvex.dev/ns/v0.2.0", + "@id":"https://example.test/vex/worker", + "author":"security@example.test", + "timestamp":"2026-05-27T12:00:00Z", + "version":1, + "statements":[{ + "vulnerability":{"name":"CVE-2026-0002"}, + "products":[{"@id":"pkg:apk/openssl@3.1.0"}], + "status":"fixed", + "justification":"fixed in release candidate", + "impact_statement":"patched before release", + "action_statement":"ship fixed artifact" + }] + }`)) + if err != nil { + t.Fatalf("vex: %v", err) + } + if vex.Author != "security@example.test" || vex.StatementCount != 1 || vex.StatusSummary["fixed"] != 1 { + t.Fatalf("upload response should keep parsed VEX fields: %#v", vex) + } + + state, ok, err := store.LoadState(ctx) + if err != nil || !ok { + t.Fatalf("load state ok=%v err=%v", ok, err) + } + persisted := state.VEXDocuments[vex.ID] + if persisted.Author != "" || persisted.StatementCount != 0 || persisted.StatusSummary != nil { + t.Fatalf("persisted vex document should wait for worker parser side effects: %#v", persisted) + } + decisionFound := false + for _, decision := range state.Decisions { + if decision.FindingID == scan.Findings[0].ID && decision.VEXDocumentID == vex.ID && decision.Status == decisionStatusFixed { + decisionFound = true + } + } + if !decisionFound { + t.Fatal("request path should still create OpenVEX-derived vulnerability decisions") + } + if len(outbox.jobs) != 1 { + t.Fatalf("outbox jobs = %d, want 1", len(outbox.jobs)) + } + job := outbox.jobs[0] + if job.Kind != "parse_vex" || job.Payload["payload_ref"] == "" || job.Payload["payload_hash"] == "" || job.Payload["parser_version"] != ParserVersionOpenVEXJSON { + t.Fatalf("outbox job missing replay metadata: %#v", job) + } + payloadRef, ok := job.Payload["payload_ref"].(string) + payloadKey := strings.TrimPrefix(payloadRef, "object://") + if !ok || !strings.HasPrefix(payloadKey, "tenants/"+actor.TenantID+"/") { + t.Fatalf("payload ref %q is not tenant-prefixed", job.Payload["payload_ref"]) + } + if _, err := objects.Get(ctx, payloadKey); err != nil { + t.Fatalf("stored payload missing: %v", err) + } +} + func TestExceptionApprovalControlsReadinessAndTenantScope(t *testing.T) { ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) ctx := context.Background() diff --git a/internal/app/vex.go b/internal/app/vex.go index 18bde22..f1fcf6f 100644 --- a/internal/app/vex.go +++ b/internal/app/vex.go @@ -146,7 +146,15 @@ func (l *Ledger) UploadVEX(ctx context.Context, actor domain.Actor, releaseID, a SchemaVersion: domain.VEXDocumentSchemaVersion, CreatedAt: l.now(), } - l.vexDocuments[vex.ID] = vex + persistedVEX := vex + chainAction := "vex.parsed" + if l.workerOwnedParsers { + persistedVEX.Author = "" + persistedVEX.StatementCount = 0 + persistedVEX.StatusSummary = nil + chainAction = "vex.accepted" + } + l.vexDocuments[vex.ID] = persistedVEX createdDecisions := 0 for _, statement := range doc.Statements { for _, matched := range l.findMatchingFindingsLocked(actor.TenantID, releaseID, statement) { @@ -161,7 +169,7 @@ func (l *Ledger) UploadVEX(ctx context.Context, actor domain.Actor, releaseID, a createdDecisions++ } } - _, _ = l.appendChainLocked(actor.TenantID, "vex.parsed", "vex_document", vex.ID, "api_key", actor.KeyID, payloadHash, "") + _, _ = l.appendChainLocked(actor.TenantID, chainAction, "vex_document", vex.ID, "api_key", actor.KeyID, payloadHash, "") if err := l.enqueue(ctx, actor.TenantID, "parse_vex", "vex_document", vex.ID, map[string]any{"payload_ref": payloadRef, "payload_hash": payloadHash, "parser_version": ParserVersionOpenVEXJSON, "decisions_created": createdDecisions}); err != nil { return domain.VEXDocument{}, err } From ede1fefe8b19f47861906a33ebbadd33ae9327be Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 22:14:45 +0300 Subject: [PATCH 115/287] feat: create vex decisions in workers --- .api.env.example | 4 +- README.md | 2 +- cmd/evydence-worker/main.go | 153 ++++++++++++++++++++++++- cmd/evydence-worker/main_test.go | 55 +++++++++ docs/architecture.md | 4 +- docs/reference/configuration.md | 2 +- docs/reference/production-readiness.md | 20 ++-- docs/reference/worker-outbox.md | 7 +- internal/app/ledger_test.go | 6 +- internal/app/ports.go | 47 ++++++++ internal/app/vex.go | 35 +++--- 11 files changed, 298 insertions(+), 37 deletions(-) diff --git a/.api.env.example b/.api.env.example index d773472..39c024b 100644 --- a/.api.env.example +++ b/.api.env.example @@ -7,8 +7,8 @@ EVYDENCE_OBJECT_STORE=filesystem EVYDENCE_OBJECT_DIR=./tmp/objects EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE=0 # Optional hardening mode for parser-backed uploads. When true, the API stores -# accepted records and the outbox worker writes parser-derived fields. OpenVEX -# vulnerability decisions are still created in the request path. +# accepted records and the outbox worker writes parser-derived fields and +# OpenVEX-derived vulnerability decisions. EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=false EVYDENCE_SIGNING_KEY_MODE=external # Optional external signing gateway. Use HTTPS outside localhost. diff --git a/README.md b/README.md index 05b2b10..e0ac1cf 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ This repository contains a Go implementation under module `github.com/aatuh/evyd - PostgreSQL-backed durable ledger state, tenant-scoped relational projections, migrations, and persisted outbox jobs when `EVYDENCE_DATABASE_URL` is set. - Filesystem or S3/MinIO-compatible object storage for raw upload payload bytes under tenant-prefixed paths. - Polling `cmd/evydence-worker` process that claims persisted outbox jobs with PostgreSQL row locking and records retry or terminal status. -- Optional worker-owned parser document side effects through `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; OpenVEX-derived vulnerability decisions still run in the request path so readiness decisions stay deterministic before workers finish. +- Optional worker-owned parser side effects through `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, including OpenVEX-derived vulnerability decisions created idempotently by the `parse_vex` worker. ### Tooling, Deployment, And Examples diff --git a/cmd/evydence-worker/main.go b/cmd/evydence-worker/main.go index 655fa3f..a0bcbec 100644 --- a/cmd/evydence-worker/main.go +++ b/cmd/evydence-worker/main.go @@ -242,6 +242,15 @@ func processJobInternal(ctx context.Context, state jobStateLoader, objects jobOb snapshot.VEXDocuments[job.SubjectID] = updated stateChanged = true } + if payloadBool(job, "worker_create_decisions") { + created, err := applyReplayedVEXDecisions(&snapshot, job, vex, parsed, replayed.Digest) + if err != nil { + return err + } + if created > 0 { + stateChanged = true + } + } } if err := requirePayloadHash(job, ""); err != nil { return err @@ -375,6 +384,14 @@ func payloadString(job postgres.ClaimedJob, key string) string { return strings.TrimSpace(value) } +func payloadBool(job postgres.ClaimedJob, key string) bool { + if job.Payload == nil { + return false + } + value, _ := job.Payload[key].(bool) + return value +} + func payloadObjectKey(job postgres.ClaimedJob) string { ref := payloadString(job, "payload_ref") return strings.TrimPrefix(ref, "object://") @@ -595,6 +612,16 @@ type replayedVEX struct { Author string StatementCount int StatusSummary map[string]int + Statements []replayedVEXStatement +} + +type replayedVEXStatement struct { + Vulnerability string + Products map[string]struct{} + Status string + Justification string + ImpactStatement string + ActionStatement string } func verifyReplayedVEX(parsed replayedVEX, vex domain.VEXDocument) error { @@ -651,6 +678,7 @@ func parseReplayedVEX(raw []byte) (replayedVEX, error) { return replayedVEX{}, errors.New("replayed vex payload is invalid") } summary := map[string]int{} + statements := make([]replayedVEXStatement, 0, len(doc.Statements)) for _, statement := range doc.Statements { status := strings.TrimSpace(statement.Status) if strings.TrimSpace(statement.Vulnerability.Name) == "" || status == "" || len(statement.Products) == 0 { @@ -662,8 +690,131 @@ func parseReplayedVEX(raw []byte) (replayedVEX, error) { return replayedVEX{}, errors.New("replayed vex payload is invalid") } summary[status]++ + statements = append(statements, replayedVEXStatement{ + Vulnerability: strings.TrimSpace(statement.Vulnerability.Name), + Products: replayedVEXProductIDs(statement.Products), + Status: status, + Justification: strings.TrimSpace(statement.Justification), + ImpactStatement: strings.TrimSpace(statement.ImpactStatement), + ActionStatement: strings.TrimSpace(statement.ActionStatement), + }) + } + return replayedVEX{Author: strings.TrimSpace(doc.Author), StatementCount: len(doc.Statements), StatusSummary: summary, Statements: statements}, nil +} + +func replayedVEXProductIDs(products []map[string]any) map[string]struct{} { + out := map[string]struct{}{} + var walk func([]map[string]any) + walk = func(items []map[string]any) { + for _, item := range items { + if id, ok := item["@id"].(string); ok { + if id = strings.TrimSpace(id); id != "" { + out[id] = struct{}{} + } + } + if children, ok := item["subcomponents"].([]any); ok { + mapped := make([]map[string]any, 0, len(children)) + for _, child := range children { + if childMap, ok := child.(map[string]any); ok { + mapped = append(mapped, childMap) + } + } + walk(mapped) + } + } + } + walk(products) + return out +} + +func applyReplayedVEXDecisions(state *app.PersistedState, job postgres.ClaimedJob, vex domain.VEXDocument, parsed replayedVEX, payloadHash string) (int, error) { + if state.Decisions == nil { + state.Decisions = map[string]domain.VulnerabilityDecision{} + } + actorType := nonEmptyWorker(payloadString(job, "actor_type"), "worker") + actorID := nonEmptyWorker(payloadString(job, "actor_id"), job.ID) + evidenceID := payloadString(job, "evidence_id") + now := time.Now().UTC() + created := 0 + scanIDs := make([]string, 0, len(state.Scans)) + for id, scan := range state.Scans { + if scan.TenantID == job.TenantID && scan.ReleaseID == vex.ReleaseID { + scanIDs = append(scanIDs, id) + } + } + sort.Strings(scanIDs) + for _, statement := range parsed.Statements { + for _, scanID := range scanIDs { + scan := state.Scans[scanID] + for _, finding := range scan.Findings { + if finding.Vulnerability != statement.Vulnerability { + continue + } + if len(statement.Products) > 0 && finding.Component != "" { + if _, ok := statement.Products[finding.Component]; !ok { + continue + } + } + if replayedVEXDecisionExists(state.Decisions, job.TenantID, vex.ID, finding.ID) { + continue + } + decisionID := replayedVEXDecisionID(vex.ID, finding.ID, statement.Status) + if _, exists := state.Decisions[decisionID]; exists { + continue + } + supersedes := "" + for id, existing := range state.Decisions { + if existing.TenantID == job.TenantID && existing.FindingID == finding.ID && existing.SupersededBy == "" { + supersedes = existing.ID + existing.SupersededBy = decisionID + state.Decisions[id] = existing + } + } + state.Decisions[decisionID] = domain.VulnerabilityDecision{ + ID: decisionID, + TenantID: job.TenantID, + FindingID: finding.ID, + ScanID: scan.ID, + ReleaseID: scan.ReleaseID, + Vulnerability: finding.Vulnerability, + Component: finding.Component, + Status: statement.Status, + Justification: statement.Justification, + ImpactStatement: statement.ImpactStatement, + ActionStatement: statement.ActionStatement, + Source: "vex", + EvidenceID: evidenceID, + VEXDocumentID: vex.ID, + Supersedes: supersedes, + ApprovedBy: actorID, + SchemaVersion: domain.VulnerabilityDecisionVersion, + CreatedAt: now, + } + if _, err := app.AppendPersistedChainEntry(state, now, job.TenantID, "vulnerability_decision.created", "vulnerability_finding", finding.ID, actorType, actorID, payloadHash, ""); err != nil { + return created, errors.New("append replayed vex decision audit entry") + } + created++ + } + } + } + return created, nil +} + +func replayedVEXDecisionExists(decisions map[string]domain.VulnerabilityDecision, tenantID, vexID, findingID string) bool { + for _, decision := range decisions { + if decision.TenantID == tenantID && decision.VEXDocumentID == vexID && decision.FindingID == findingID { + return true + } + } + return false +} + +func replayedVEXDecisionID(vexID, findingID, status string) string { + sum := strings.TrimPrefix(digestBytes([]byte(vexID+"\n"+findingID+"\n"+status)), "sha256:") + if len(sum) > 32 { + sum = sum[:32] } - return replayedVEX{Author: strings.TrimSpace(doc.Author), StatementCount: len(doc.Statements), StatusSummary: summary}, nil + return "vd_" + sum } func verifyReplayedAttestation(raw []byte, parsed replayedAttestation, attestation domain.BuildAttestation) error { diff --git a/cmd/evydence-worker/main_test.go b/cmd/evydence-worker/main_test.go index 9667d0a..acb0454 100644 --- a/cmd/evydence-worker/main_test.go +++ b/cmd/evydence-worker/main_test.go @@ -225,6 +225,61 @@ func TestProcessJobWithObjectsParsesPayloadAndChecksDurableState(t *testing.T) { } } +func TestProcessJobWithObjectsCreatesVEXDecisionsIdempotently(t *testing.T) { + body := []byte(`{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex","author":"security@example.test","timestamp":"2026-05-28T12:00:00Z","version":1,"statements":[{"vulnerability":{"name":"CVE-1"},"products":[{"@id":"pkg:oci/api"}],"status":"fixed","justification":"fixed","impact_statement":"patched","action_statement":"ship"}]}`) + hash := digestBytes(body) + job := postgres.ClaimedJob{ + ID: "job_vex", + TenantID: "ten_test", + Kind: "parse_vex", + SubjectID: "vex_test", + Payload: map[string]any{ + "payload_ref": "object://tenants/ten_test/payloads/vex.json", + "payload_hash": hash, + "parser_version": app.ParserVersionOpenVEXJSON, + "worker_create_decisions": true, + "actor_type": "api_key", + "actor_id": "key_test", + "evidence_id": "ev_vex", + }, + } + store := &fakeStateStore{ok: true, state: app.PersistedState{ + VEXDocuments: map[string]domain.VEXDocument{ + "vex_test": {ID: "vex_test", TenantID: "ten_test", ReleaseID: "rel_test", EvidenceID: "ev_vex", Format: "openvex"}, + }, + Scans: map[string]domain.VulnerabilityScan{ + "scan_test": {ID: "scan_test", TenantID: "ten_test", ReleaseID: "rel_test", Findings: []domain.VulnerabilityFinding{{ID: "finding_1", Vulnerability: "CVE-1", Component: "pkg:oci/api", Severity: "critical", State: "open"}}}, + }, + Decisions: map[string]domain.VulnerabilityDecision{}, + Chain: map[string][]domain.AuditChainEntry{}, + }} + object := app.Object{Key: "tenants/ten_test/payloads/vex.json", TenantID: "ten_test", Digest: hash, Bytes: body} + if err := processJobWithObjects(context.Background(), store, fakeObjectGetter{object: object}, job); err != nil { + t.Fatalf("process vex job: %v", err) + } + if len(store.saved.Decisions) != 1 { + t.Fatalf("decisions = %#v, want one", store.saved.Decisions) + } + for _, decision := range store.saved.Decisions { + if decision.FindingID != "finding_1" || decision.Status != "fixed" || decision.VEXDocumentID != "vex_test" || decision.ApprovedBy != "key_test" { + t.Fatalf("decision = %#v", decision) + } + } + if got := len(store.saved.Chain["ten_test"]); got != 1 { + t.Fatalf("chain entries = %d, want 1", got) + } + + previous := store.saved + store.state = previous + store.saved = app.PersistedState{} + if err := processJobWithObjects(context.Background(), store, fakeObjectGetter{object: object}, job); err != nil { + t.Fatalf("reprocess vex job: %v", err) + } + if len(store.saved.Decisions) != 0 || len(previous.Decisions) != 1 || len(previous.Chain["ten_test"]) != 1 { + t.Fatalf("replay duplicated side effects: saved=%#v previous=%#v", store.saved.Decisions, previous.Decisions) + } +} + func TestProcessJobWithObjectsFailsSafelyForParserMismatches(t *testing.T) { body := []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","components":[{"name":"api"},{"name":"worker"}]}`) hash := digestBytes(body) diff --git a/docs/architecture.md b/docs/architecture.md index 57df17f..a218837 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -26,7 +26,7 @@ When `EVYDENCE_DATABASE_URL` is set, mutations are saved to PostgreSQL before su Evidence, evidence lifecycle events, incidents, remediation tasks, security scans, manual security documents, SBOM diffs, VEX documents, vulnerability decisions/workflow records, organizations, users, role bindings, SSO providers, SSO sessions, legal holds, retention overrides, customer portal access records, questionnaire packages and drafts, evidence summaries, evidence graph snapshots, commercial and marketplace collector definitions, waivers, approvals, customer packages, report templates, evidence bundles, exceptions, build runs, build attestations, release candidates, artifact signatures, source-control records, deployment events, contract diffs, custom policy evaluations, provider verifications, signing operations, control evidence links, public transparency log entries, and release bundle records are append-only in behavior. Changes are represented by supersession, lifecycle events, approval transitions, session revocation, package access records, links, verification receipts, rollback-as-new-event records, or new audit-chain entries. -Outbox jobs are persisted in PostgreSQL and claimed by workers with `FOR UPDATE SKIP LOCKED`. Parser jobs re-read tenant-prefixed object-store payloads, verify size and digest, validate durable state, persist missing parser-derived normalized fields, and fail closed on mismatches. With `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, parser-backed uploads store accepted records and workers populate normalized document fields from replayed payloads. OpenVEX-derived vulnerability decision creation still runs in the request path, so moving every parser-owned side effect fully out of the API request path remains production hardening work. +Outbox jobs are persisted in PostgreSQL and claimed by workers with `FOR UPDATE SKIP LOCKED`. Parser jobs re-read tenant-prefixed object-store payloads, verify size and digest, validate durable state, persist missing parser-derived normalized fields, and fail closed on mismatches. With `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, parser-backed uploads store accepted records and workers populate normalized document fields from replayed payloads. OpenVEX-derived vulnerability decisions are created idempotently by the `parse_vex` worker in that mode. ## Verification And Trust @@ -52,6 +52,6 @@ Air-gapped import-bundle workflows preserve the same tenant-scoped import path a ## Limitations -The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, OIDC discovery refresh, SSO credential exchange with session-scoped OIDC group-role mapping, public-transparency proof fetching, and optional worker-owned parser document side effects are implemented, but direct cloud KMS/HSM SDK adapters, live Sigstore verification, live provider API validation, external group synchronization, and worker-owned OpenVEX decision creation remain deployment hardening work. Hand-tuned per-resource repository implementations and moving all remaining parser side effects fully out of request paths remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. +The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, OIDC discovery refresh, SSO credential exchange with session-scoped OIDC group-role mapping, public-transparency proof fetching, and optional worker-owned parser side effects are implemented, but direct cloud KMS/HSM SDK adapters, live Sigstore verification, live provider API validation, and external group synchronization remain deployment hardening work. Hand-tuned per-resource repository implementations remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. Evydence does not prove provider truth, scanner authority, runtime security, legal compliance, or release security by itself. diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 413b3aa..4c90bef 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -37,7 +37,7 @@ The example secrets are placeholders. Replace them before using shared or produc | `EVYDENCE_S3_REGION` | No | empty | Optional S3 region. | | `EVYDENCE_S3_USE_SSL` | No | `false` locally, `true` in chart values | Use TLS for remote object storage. | | `EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE` | No | `0` disabled | Optional in-process per-client request limit using the TCP remote address. Use reverse-proxy or ingress rate limiting for production edge controls. | -| `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS` | No | `false` | Optional hardening mode for parser-backed uploads. When set to `true`, the API stores accepted records and the outbox worker populates parser-derived fields from tenant-prefixed raw payloads after digest verification. OpenVEX vulnerability decisions are still created in the request path. | +| `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS` | No | `false` | Optional hardening mode for parser-backed uploads. When set to `true`, the API stores accepted records and the outbox worker populates parser-derived fields from tenant-prefixed raw payloads after digest verification, including OpenVEX-derived vulnerability decisions. | | `EVYDENCE_SKIP_MIGRATIONS` | No | unset | Set to `true` only when migrations are applied by a separate release process. API and worker startup still verify that no committed migrations are pending and fail closed if the database is behind. | | `EVYDENCE_MIGRATIONS_DIR` | No | `migrations` | Migration directory for API startup and `cmd/evydence-migrate`. | | `EVYDENCE_BOOTSTRAP_TENANT` | No | `Local Tenant` | Tenant name used when bootstrapping an empty store. | diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 541019e..253499f 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -39,11 +39,11 @@ Known hardening work remains: - worker parser jobs re-read raw object-store payloads for key formats, verify digests, validate durable state, and persist missing parser-derived normalized fields. CycloneDX SBOM, generic vulnerability-scan, and OpenAPI - contract, DSSE build-attestation, and OpenVEX document uploads can run with - worker-owned document side effects by setting + contract, DSSE build-attestation, and OpenVEX uploads can run with + worker-owned parser side effects by setting `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; OpenVEX-derived - vulnerability decisions still run in the request path, so fully worker-owned - decision creation remains hardening work; + vulnerability decisions are created idempotently by the `parse_vex` worker in + that mode; - OpenAPI precision is enforced across the registered public API. The generated matrix remains the source of truth for operation ids, scopes, idempotency, parameters, and request/response schemas; @@ -145,12 +145,12 @@ implemented capabilities: - Split the large application ledger aggregate into focused services or repositories once relational writes are in place, preserving tenant isolation and append-only behavior throughout. -- Continue moving OpenVEX-derived vulnerability decision creation into an - idempotent worker processor. CycloneDX SBOM, generic vulnerability scan, - OpenAPI contract, DSSE build-attestation, and OpenVEX document metadata can - be worker-owned behind `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; - workers also persist missing parser-derived fields for replay-compatible - records. +- Keep worker-owned parser side effects covered as parser formats evolve. + CycloneDX SBOM, generic vulnerability scan, OpenAPI contract, DSSE + build-attestation, OpenVEX document metadata, and OpenVEX-derived + vulnerability decisions can be worker-owned behind + `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; workers also persist + missing parser-derived fields for replay-compatible records. - Keep OpenAPI precision at zero broad operations as routes are added or changed, and expand generated SDK coverage from the committed contract. - Add direct cloud KMS/HSM SDK adapters where required. The current HTTPS diff --git a/docs/reference/worker-outbox.md b/docs/reference/worker-outbox.md index 1981519..04361cb 100644 --- a/docs/reference/worker-outbox.md +++ b/docs/reference/worker-outbox.md @@ -12,7 +12,7 @@ Configured job kinds: - `verify_subject` - `verify_attestation` -Current behavior is intentionally conservative. The API still records normalized signing and verification results before enqueueing jobs for the implemented paths. Parser jobs independently replay tenant-prefixed payload objects when `payload_ref` is present, verify object metadata and byte digests when `payload_hash` is present, parse SBOM, vulnerability-scan, OpenAPI, OpenVEX, and DSSE attestation payloads, and check that replayed payload summaries match the expected durable state. When `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, parser-backed uploads store accepted records first and workers write parser-derived document fields after replay. OpenVEX-derived vulnerability decisions are still created in the request path so release-readiness decisions stay deterministic before the `parse_vex` worker runs. Missing objects, wrong tenant prefixes, tenant mismatches, oversized payload objects, malformed replay payloads, durable-state mismatches, incomplete verification, missing signatures, hash mismatch, uninitialized storage, and unsupported job kinds fail the job safely. +Current behavior is intentionally conservative. The API still records normalized signing and verification results before enqueueing jobs for the implemented paths. Parser jobs independently replay tenant-prefixed payload objects when `payload_ref` is present, verify object metadata and byte digests when `payload_hash` is present, parse SBOM, vulnerability-scan, OpenAPI, OpenVEX, and DSSE attestation payloads, and check that replayed payload summaries match the expected durable state. When `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, parser-backed uploads store accepted records first and workers write parser-derived document fields after replay. The `parse_vex` worker also creates OpenVEX-derived vulnerability decisions idempotently in that mode. Missing objects, wrong tenant prefixes, tenant mismatches, oversized payload objects, malformed replay payloads, durable-state mismatches, incomplete verification, missing signatures, hash mismatch, uninitialized storage, and unsupported job kinds fail the job safely. Parser and attestation jobs include a deterministic `parser_version` payload field for new uploads. Workers reject unsupported parser versions and accept @@ -21,9 +21,8 @@ older jobs with no parser version for upgrade compatibility. Parser replay is worker-owned for CycloneDX SBOM, generic vulnerability-scan, OpenAPI contract, DSSE build-attestation, and OpenVEX document metadata when `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`. OpenVEX-derived -vulnerability decision creation still runs in the request path. Moving that -decision side effect into an idempotent worker processor remains production -hardening work. +vulnerability decision creation is also worker-owned in that mode and uses +deterministic decision IDs to avoid duplicate side effects on retry. Workers use the same object-store environment variables as the API. The default worker payload replay limit is 20 MiB and can be adjusted with `EVYDENCE_WORKER_MAX_PAYLOAD_BYTES`. diff --git a/internal/app/ledger_test.go b/internal/app/ledger_test.go index 2e982ab..7e6a1c2 100644 --- a/internal/app/ledger_test.go +++ b/internal/app/ledger_test.go @@ -776,14 +776,14 @@ func TestUploadVEXCanDeferDocumentParserSideEffectsToWorker(t *testing.T) { decisionFound = true } } - if !decisionFound { - t.Fatal("request path should still create OpenVEX-derived vulnerability decisions") + if decisionFound { + t.Fatal("worker-owned parser mode should leave OpenVEX-derived vulnerability decisions to the worker") } if len(outbox.jobs) != 1 { t.Fatalf("outbox jobs = %d, want 1", len(outbox.jobs)) } job := outbox.jobs[0] - if job.Kind != "parse_vex" || job.Payload["payload_ref"] == "" || job.Payload["payload_hash"] == "" || job.Payload["parser_version"] != ParserVersionOpenVEXJSON { + if job.Kind != "parse_vex" || job.Payload["payload_ref"] == "" || job.Payload["payload_hash"] == "" || job.Payload["parser_version"] != ParserVersionOpenVEXJSON || job.Payload["worker_create_decisions"] != true { t.Fatalf("outbox job missing replay metadata: %#v", job) } payloadRef, ok := job.Payload["payload_ref"].(string) diff --git a/internal/app/ports.go b/internal/app/ports.go index 4fc0e19..9caedf2 100644 --- a/internal/app/ports.go +++ b/internal/app/ports.go @@ -198,6 +198,53 @@ type PersistedState struct { Idempotency map[string]IdempotencyRecord `json:"idempotency"` } +func AppendPersistedChainEntry(state *PersistedState, now time.Time, tenantID, entryType, subjectType, subjectID, actorType, actorID, payloadHash, signatureRef string) (domain.AuditChainEntry, error) { + if state.Chain == nil { + state.Chain = map[string][]domain.AuditChainEntry{} + } + entries := state.Chain[tenantID] + previous := "" + if len(entries) > 0 { + previous = entries[len(entries)-1].EntryHash + } + entry := domain.AuditChainEntry{ + ID: newID("ace"), + TenantID: tenantID, + Sequence: int64(len(entries) + 1), + EntryType: entryType, + SubjectType: subjectType, + SubjectID: subjectID, + ActorType: actorType, + ActorID: actorID, + OccurredAt: now.UTC(), + PayloadHash: payloadHash, + PreviousEntryHash: previous, + SignatureRef: signatureRef, + SchemaVersion: domain.AuditChainEntrySchemaVersion, + } + canonical, err := canonicalAnyHash(map[string]any{ + "tenant_id": entry.TenantID, + "sequence": entry.Sequence, + "entry_type": entry.EntryType, + "subject_type": entry.SubjectType, + "subject_id": entry.SubjectID, + "actor_type": entry.ActorType, + "actor_id": entry.ActorID, + "occurred_at": entry.OccurredAt.UTC().Format(time.RFC3339Nano), + "payload_hash": entry.PayloadHash, + "previous_entry_hash": entry.PreviousEntryHash, + "signature_ref": entry.SignatureRef, + "schema_version": entry.SchemaVersion, + }) + if err != nil { + return domain.AuditChainEntry{}, err + } + entry.CanonicalEntryHash = canonical + entry.EntryHash = hashBytes([]byte(previous + "\n" + canonical)) + state.Chain[tenantID] = append(entries, entry) + return entry, nil +} + type IdempotencyRecord struct { RequestHash string `json:"request_hash"` Status int `json:"status"` diff --git a/internal/app/vex.go b/internal/app/vex.go index f1fcf6f..d3da82b 100644 --- a/internal/app/vex.go +++ b/internal/app/vex.go @@ -156,21 +156,30 @@ func (l *Ledger) UploadVEX(ctx context.Context, actor domain.Actor, releaseID, a } l.vexDocuments[vex.ID] = persistedVEX createdDecisions := 0 - for _, statement := range doc.Statements { - for _, matched := range l.findMatchingFindingsLocked(actor.TenantID, releaseID, statement) { - decision := l.createDecisionLocked(actor.TenantID, matched.scan, matched.finding, CreateVulnerabilityDecisionInput{ - Status: statement.Status, - Justification: statement.Justification, - ImpactStatement: statement.ImpactStatement, - ActionStatement: statement.ActionStatement, - }, "vex", actor.KeyID, item.ID, vex.ID) - l.decisions[decision.ID] = decision - _, _ = l.appendChainLocked(actor.TenantID, "vulnerability_decision.created", "vulnerability_finding", matched.finding.ID, "api_key", actor.KeyID, payloadHash, "") - createdDecisions++ + if !l.workerOwnedParsers { + for _, statement := range doc.Statements { + for _, matched := range l.findMatchingFindingsLocked(actor.TenantID, releaseID, statement) { + decision := l.createDecisionLocked(actor.TenantID, matched.scan, matched.finding, CreateVulnerabilityDecisionInput{ + Status: statement.Status, + Justification: statement.Justification, + ImpactStatement: statement.ImpactStatement, + ActionStatement: statement.ActionStatement, + }, "vex", actorID(actor), item.ID, vex.ID) + l.decisions[decision.ID] = decision + _, _ = l.appendChainLocked(actor.TenantID, "vulnerability_decision.created", "vulnerability_finding", matched.finding.ID, actorType(actor), actorID(actor), payloadHash, "") + createdDecisions++ + } } } - _, _ = l.appendChainLocked(actor.TenantID, chainAction, "vex_document", vex.ID, "api_key", actor.KeyID, payloadHash, "") - if err := l.enqueue(ctx, actor.TenantID, "parse_vex", "vex_document", vex.ID, map[string]any{"payload_ref": payloadRef, "payload_hash": payloadHash, "parser_version": ParserVersionOpenVEXJSON, "decisions_created": createdDecisions}); err != nil { + _, _ = l.appendChainLocked(actor.TenantID, chainAction, "vex_document", vex.ID, actorType(actor), actorID(actor), payloadHash, "") + jobPayload := map[string]any{"payload_ref": payloadRef, "payload_hash": payloadHash, "parser_version": ParserVersionOpenVEXJSON, "decisions_created": createdDecisions} + if l.workerOwnedParsers { + jobPayload["worker_create_decisions"] = true + jobPayload["actor_type"] = actorType(actor) + jobPayload["actor_id"] = actorID(actor) + jobPayload["evidence_id"] = item.ID + } + if err := l.enqueue(ctx, actor.TenantID, "parse_vex", "vex_document", vex.ID, jobPayload); err != nil { return domain.VEXDocument{}, err } if err := l.persistLocked(ctx); err != nil { From d371646b01a67d0b38c0c2942b185b0ffb0bdf91 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Thu, 28 May 2026 22:15:11 +0300 Subject: [PATCH 116/287] docs: clarify worker parser readiness status --- docs/reference/production-readiness.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 253499f..4047356 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -38,7 +38,7 @@ Known hardening work remains: signing operation, and future-extension state from relational rows; - worker parser jobs re-read raw object-store payloads for key formats, verify digests, validate durable state, and persist missing parser-derived - normalized fields. CycloneDX SBOM, generic vulnerability-scan, and OpenAPI + normalized fields. CycloneDX SBOM, generic vulnerability-scan, OpenAPI contract, DSSE build-attestation, and OpenVEX uploads can run with worker-owned parser side effects by setting `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; OpenVEX-derived From 74f6e606289cc9efd64233fd50d224b33ba7aedf Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Fri, 29 May 2026 17:11:33 +0300 Subject: [PATCH 117/287] docs: define release candidate hardening profile --- CHANGELOG.md | 18 +++++--- README.md | 5 ++- RELEASE_EVIDENCE.md | 7 +++ SECURITY.md | 30 ++++++++----- docs/README.md | 1 + docs/reference/production-readiness.md | 29 ++++++++++-- docs/reference/release-candidate.md | 62 ++++++++++++++++++++++++++ docs/reference/release-validation.md | 19 ++++++++ scripts/release_acceptance.sh | 8 ++++ 9 files changed, 155 insertions(+), 24 deletions(-) create mode 100644 docs/reference/release-candidate.md diff --git a/CHANGELOG.md b/CHANGELOG.md index f0cbcb5..7aabf55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,16 +9,20 @@ results, no secure-release guarantee, and no regulator or auditor acceptance. ## Unreleased -Release status: self-hosted production hardening. Current builds are suitable -for evaluation, pilots, and controlled internal production after operator -review. Broad self-hosted production readiness requires the production gate and -exit criteria in `docs/reference/production-readiness.md`. +Release status: controlled self-hosted production candidate hardening. Current +builds are suitable for evaluation, pilots, and controlled internal production +after operator review. Broad self-hosted production readiness, regulated +production, and hosted SaaS production remain out of scope for this status. +Release-candidate tagging requires the production gate and checklist in +`docs/reference/release-candidate.md`. ### Added - Root legal, governance, security, support, trademark, commercial licensing, release-evidence, and changelog metadata. - Production-readiness profile, production gate, and coverage-threshold gate. +- Release-candidate checklist requiring production-check evidence, checksums, + signed artifact manifests, release notes, and documented limitations. ### Known Limits @@ -26,6 +30,6 @@ exit criteria in `docs/reference/production-readiness.md`. - Operators remain responsible for production PostgreSQL, object storage, network policy, TLS, backups, monitoring, external signing, and incident response. -- Canonical persistence, async parser replay, API schema precision, CI release - enforcement, and coverage remain production-hardening work until the - production gate passes. +- Focused relational write paths, HA/multi-writer operation, direct KMS/HSM SDK + adapters, live provider validation, broader object-lock proof, and final exit + review remain production-hardening work after the release-candidate gate. diff --git a/README.md b/README.md index e0ac1cf..4b6728b 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ It does not make legal compliance conclusions, grant certification, prove SBOM c ## Current Implementation -This repository contains a Go implementation under module `github.com/aatuh/evydence`. The current status is self-hosted production hardening: useful for evaluation, pilots, and controlled internal production after operator review, with a stricter production gate tracking the remaining work. +This repository contains a Go implementation under module `github.com/aatuh/evydence`. The current status is controlled self-hosted production candidate hardening: useful for evaluation, pilots, and controlled internal production after operator review, with a stricter production gate and release-candidate checklist tracking the remaining work before any broader production claim. ### API And Contracts @@ -88,6 +88,7 @@ For a runnable first evidence flow, use [Getting started](docs/tutorials/getting The canonical release validation reference is [docs/reference/release-validation.md](docs/reference/release-validation.md). The self-hosted production-readiness profile is [docs/reference/production-readiness.md](docs/reference/production-readiness.md). +The release-candidate checklist is [docs/reference/release-candidate.md](docs/reference/release-candidate.md). Common local checks: @@ -108,4 +109,4 @@ make postgres-integration-test `make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. -`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required production-readiness evidence, but it does not by itself close the remaining repository-split, remaining worker side-effect, direct KMS/HSM SDK, provider API/group validation, object-lock enforcement, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. +`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required release-candidate evidence, but it does not by itself close the remaining focused repository-write, direct KMS/HSM SDK, provider API/group validation, object-lock enforcement, HA, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. Current self-hosted production guidance uses a single API writer replica and allows worker replicas to scale through PostgreSQL outbox row locking. diff --git a/RELEASE_EVIDENCE.md b/RELEASE_EVIDENCE.md index 4dc4dd6..aa6b54f 100644 --- a/RELEASE_EVIDENCE.md +++ b/RELEASE_EVIDENCE.md @@ -28,6 +28,13 @@ requires live PostgreSQL through `EVYDENCE_TEST_DATABASE_URL`, enforces the coverage threshold, and runs a local release artifact signing smoke test. A failure means the build has not yet met the self-hosted production profile. +Release-candidate tagging is documented in +[`docs/reference/release-candidate.md`](docs/reference/release-candidate.md). +The required evidence set is a passing production-check summary, coverage +summary, OpenAPI checksum, migration checksum, signed artifact manifest, +checksums for published artifacts, and release notes with assumptions, +limitations, and unresolved hardening work. + Commercial release evidence packages may include signed release manifests, image digests, SBOMs, vulnerability scan outputs, OpenAPI checksums, migration checks, acceptance evidence, support notes, deployment hardening notes, and diff --git a/SECURITY.md b/SECURITY.md index 5b44133..538bfc1 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -8,11 +8,14 @@ object storage, reports, exports, and release evidence. ## Reporting A Vulnerability -If you believe you found a vulnerability, contact Aatu Harju through LinkedIn: +If you believe you found a vulnerability, use the private security intake +channel listed for the current release when available. Until a dedicated +security mailbox or advisory portal is published, contact Aatu Harju through +LinkedIn to request a private reporting channel: -Use the initial message to request a private reporting channel. Do not include +Use the initial message only to request a private reporting channel. Do not include API keys, collector secrets, bearer tokens, session tokens, portal tokens, private keys, provider credentials, database URLs, raw evidence payloads, customer data, exploit payloads against third-party systems, or other sensitive @@ -32,11 +35,22 @@ Once a private channel is established, include: CI collectors are involved, - suggested fix if known. -## Supported Scope +## Supported Versions And Scope Security support focuses on the current `master` branch and current release -tags. Older releases are best effort unless a commercial support agreement says -otherwise. +candidate or release tags. Older releases are best effort unless a commercial +support agreement says otherwise. Reports should identify the affected commit, +tag, image digest, Helm chart version, or deployment profile so triage can +reproduce the issue without production data. + +## Advisory And Disclosure Expectations + +Evydence handles tenant-scoped evidence, credentials, signing metadata, object +payload references, and customer-package boundaries. Security fixes should be +coordinated privately until maintainers have a reasonable opportunity to +triage, patch, publish release evidence, and document upgrade guidance. Public +advisories should avoid raw exploit payloads, customer evidence, secrets, or +instructions that increase exposure before users can update. Out of scope: @@ -49,12 +63,6 @@ Out of scope: - requests for legal compliance, certification, complete SBOM, scanner authority, secure-release, regulator-acceptance, or auditor-acceptance claims. -## Disclosure - -Please allow time for triage and remediation before public disclosure. Public -fixes should avoid exposing exploit details before affected users have a -reasonable update path. - Do not post secrets, raw evidence payloads, private keys, provider credentials, session tokens, bearer tokens, database URLs, customer data, or unredacted customer package contents in public issues, pull requests, screenshots, logs, diff --git a/docs/README.md b/docs/README.md index 9809b07..bd3987d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -24,6 +24,7 @@ This documentation is organized by reader task. Implementation claims should be - [OpenAPI contract](reference/openapi.md): generation, drift checks, and review tips for `openapi.yaml`. - [Observability](reference/observability.md): readiness, admin metrics, Prometheus rules, and dashboard starter assets. - [Production readiness](reference/production-readiness.md): self-hosted production profiles, production gates, and exit criteria. +- [Release candidate checklist](reference/release-candidate.md): required evidence before tagging a controlled self-hosted release candidate. - [Worker outbox contract](reference/worker-outbox.md): durable job kinds, idempotency, and safe logging rules. - [Release validation](reference/release-validation.md): canonical `make release-check` behavior and summary evidence. - [SDK workflow](sdk/README.md): current Go, TypeScript, and Python wrapper usage and limitations. diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 4047356..76f489a 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -7,10 +7,12 @@ release security. ## Current Status -Evydence is in self-hosted production hardening. It is suitable for evaluation, -pilots, and controlled internal production after operator review. Broad -self-hosted production use requires the production gate in this file to pass -with live PostgreSQL and release evidence enabled. +Evydence is in controlled self-hosted production candidate hardening. It is +suitable for evaluation, pilots, and controlled internal production after +operator review. Broad production for most uses, regulated production, and +hosted SaaS production remain out of scope until the production gate, +release-candidate checklist, and exit review pass with the required deployment +controls. Known hardening work remains: @@ -68,6 +70,19 @@ Known hardening work remains: | Air-gapped production | Requires transfer controls | All small-production controls plus signed offline artifacts, import/export verification, local registry or package mirror, offline docs, and explicit backup/restore procedure. | | Hosted SaaS production | Out of scope for this profile | Requires separate hosted tenancy, SLO, abuse, billing, privacy, support, and cloud operations controls before any SaaS production claim. | +## HA And Concurrency Contract + +The current self-hosted production profile supports one API writer replica. +This is intentional while the application still uses a large in-process ledger +aggregate plus `LoadState` / `SaveState` persistence boundaries. Do not scale +API writer replicas above one for production use until focused relational +repository writes or another reviewed concurrency-control design is implemented +and documented. + +Worker replicas may be scaled because persisted outbox jobs are claimed with +PostgreSQL row locking. Scaling workers increases parser/signing/report +throughput; it does not make API writes multi-writer safe. + ## Machine Gate Run the production gate from the repository root: @@ -89,6 +104,11 @@ The gate requires: - release artifact signing smoke test passing with local temporary keys; - generated release evidence summary available under `tmp/`. +Release-candidate tagging additionally requires the evidence set in +[Release candidate checklist](release-candidate.md), including OpenAPI and +migration checksums, signed artifact manifests, artifact checksums, and release +notes with limitations. + The default coverage threshold is 80 percent: ```sh @@ -112,6 +132,7 @@ Do not describe an Evydence build as broadly self-hosted production-ready until: - the built-in local restore rehearsal passes and backup/restore have been tested for the target deployment profile; - OpenAPI, OpenAPI precision, route-contract, and SDK drift checks pass; +- the HA story for the target profile is documented and reviewed; - production hardening review is current; - unresolved limitations are documented in release notes. diff --git a/docs/reference/release-candidate.md b/docs/reference/release-candidate.md new file mode 100644 index 0000000..ccf37cb --- /dev/null +++ b/docs/reference/release-candidate.md @@ -0,0 +1,62 @@ +# Release Candidate Checklist + +This reference defines the minimum evidence for a controlled self-hosted +Evydence release candidate such as `v0.1.0-rc.1` or `v0.9.0-rc.1`. + +Release-candidate evidence supports reproducible engineering and operator +review. It is not a certification, legal compliance conclusion, complete SBOM +claim, authoritative vulnerability result, secure-release guarantee, regulator +acceptance, or auditor acceptance. + +## Required Evidence + +Before creating a release-candidate tag, collect: + +- passing `make production-check` output with live PostgreSQL configured; +- `tmp/release-check-summary.txt` from the same run; +- `coverage.out` and the total coverage summary; +- `openapi.yaml` plus an OpenAPI checksum; +- migration checksum output for the directory or per-file migration checksums; +- signed release artifact manifest and manifest signature; +- checksums for every published binary, container image digest, chart package, + and release archive; +- release notes with supported profile, upgrade notes, assumptions, + limitations, and unresolved hardening work. + +## Required Commands + +Run from a clean checkout with a disposable PostgreSQL database: + +```sh +make production-check +sha256sum openapi.yaml > tmp/openapi.sha256 +find migrations -type f -print0 | sort -z | xargs -0 sha256sum > tmp/migrations.sha256 +``` + +Build release artifacts through the release-artifacts workflow or an equivalent +local process that records the same manifest, checksums, and signature files. +Do not tag from a run where live PostgreSQL checks, migration compatibility, +coverage threshold enforcement, OpenAPI checks, docs checks, deployment checks, +SDK checks, lint, gosec, govulncheck, or race tests were skipped. + +## Supported Profile Statement + +Release notes must use this status unless the production exit review has +explicitly changed it: + +> Controlled self-hosted production candidate for evaluation, pilots, and +> controlled internal production after operator review. + +The notes must also state that broad production for most uses, regulated +production, and hosted SaaS production require additional review and controls. + +## Deployment Constraints + +- Use one API writer replica for the current production profile. +- Worker replicas may be scaled when PostgreSQL outbox locking is enabled. +- Use external PostgreSQL, external object storage, TLS ingress, non-default + API-key pepper, externalized secrets, backup and restore rehearsal, + monitoring, and documented incident response. +- Keep focused relational repository writes, HA/multi-writer operation, direct + KMS/HSM SDK adapters, live provider validation, and broader object-lock proof + listed as unresolved hardening work until they are implemented and verified. diff --git a/docs/reference/release-validation.md b/docs/reference/release-validation.md index a131d03..ea3e687 100644 --- a/docs/reference/release-validation.md +++ b/docs/reference/release-validation.md @@ -43,6 +43,25 @@ upgrade to the current schema in a temporary PostgreSQL schema, and runs a release artifact signing smoke test. See [Production readiness](production-readiness.md) for the supported profiles and exit criteria. +## Release Candidate Checklist + +Before tagging `v0.1.0-rc.1`, `v0.9.0-rc.1`, or another controlled +self-hosted release candidate, follow +[Release candidate checklist](release-candidate.md). The minimum evidence set +is: + +- passing `make production-check` with live PostgreSQL; +- `tmp/release-check-summary.txt` from the same run; +- coverage output and threshold result; +- OpenAPI checksum and migration checksums; +- signed release artifact manifest, manifest signature, and artifact checksums; +- release notes that state supported profile, assumptions, limitations, + upgrade notes, and unresolved hardening work. + +Do not use release-candidate evidence as legal compliance proof, certification, +complete vulnerability coverage, complete SBOM proof, secure-release proof, or +auditor/regulator acceptance. + ## Configured Live PostgreSQL Profile For the scripted local profile, run: diff --git a/scripts/release_acceptance.sh b/scripts/release_acceptance.sh index 3132304..29f010c 100755 --- a/scripts/release_acceptance.sh +++ b/scripts/release_acceptance.sh @@ -45,6 +45,7 @@ for file in \ .dockerignore \ README.md \ docs/README.md \ + docs/reference/release-candidate.md \ docs/reference/release-validation.md; do require_file "$file" done @@ -59,12 +60,19 @@ require_text CONTRIBUTING.md "contributor license agreement" require_text CONTRIBUTING.md "EVYDENCE_TEST_DATABASE_URL" require_text SECURITY.md "raw evidence payloads" require_text SECURITY.md "tenant isolation" +require_text SECURITY.md "private security intake" +require_text SECURITY.md "Supported Versions And Scope" require_text SUPPORT.md "sanitized logs" require_text SUPPORT.md "release evidence artifacts" require_text TRADEMARKS.md "Evydence fork" require_text RELEASE_EVIDENCE.md "Release evidence is not a certification" require_text RELEASE_EVIDENCE.md "make release-check" +require_text RELEASE_EVIDENCE.md "release-candidate" require_text CHANGELOG.md "Unreleased" +require_text docs/reference/release-candidate.md "Controlled self-hosted production candidate" +require_text docs/reference/release-candidate.md "Use one API writer replica" +require_text docs/reference/release-candidate.md "OpenAPI checksum" +require_text docs/reference/release-candidate.md "migration checksum" for pattern in \ ".refs" \ From 5192f692ee3ab27dafc50e006bbb9223885ba814 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Fri, 29 May 2026 17:36:18 +0300 Subject: [PATCH 118/287] chore: harden helm release candidate defaults --- Makefile | 15 +++++++ cmd/evydence-worker/main.go | 14 ++++++- cmd/evydence-worker/main_test.go | 9 ++++ .../evydence/templates/deployment-api.yaml | 9 +++- .../evydence/templates/deployment-worker.yaml | 19 ++++++++- .../evydence/templates/networkpolicy.yaml | 17 ++++++++ deploy/helm/evydence/values.yaml | 42 ++++++++++++++++++- docs/kubernetes.md | 14 +++++-- 8 files changed, 128 insertions(+), 11 deletions(-) create mode 100644 deploy/helm/evydence/templates/networkpolicy.yaml diff --git a/Makefile b/Makefile index 2064edc..01dcb91 100644 --- a/Makefile +++ b/Makefile @@ -96,6 +96,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @test -f docs/reference/openapi.md @test -f docs/reference/observability.md @test -f docs/reference/production-readiness.md + @test -f docs/reference/release-candidate.md @test -f docs/reference/worker-outbox.md @test -f docs/reference/release-validation.md @test -f docs/explanation/trust-model.md @@ -121,6 +122,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod "reference/openapi.md" \ "reference/observability.md" \ "reference/production-readiness.md" \ + "reference/release-candidate.md" \ "reference/worker-outbox.md" \ "reference/release-validation.md" \ "collectors/source-snapshots.md" \ @@ -156,6 +158,9 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'EVYDENCE_RELEASE_SIGNING_PRIVATE_KEY_B64' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'evydence-release-manifest.sig.json' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'gh release create' .github/workflows/release-artifacts.yml >/dev/null + @grep -F 'Controlled self-hosted production candidate' docs/reference/release-candidate.md >/dev/null + @grep -F 'Use one API writer replica' docs/reference/release-candidate.md >/dev/null + @grep -F 'private security intake' SECURITY.md >/dev/null @! grep -R -i "automatically compliant\|certified secure\|legally sufficient\|SBOM is complete\|all vulnerabilities detected\|scanner findings are authoritative\|regulator-ready without review" README.md docs deploy-check: ## Validate deployment and air-gap skeletons exist @@ -163,9 +168,19 @@ deploy-check: ## Validate deployment and air-gap skeletons exist @test -f deploy/helm/evydence/values.yaml @test -f deploy/helm/evydence/templates/deployment-api.yaml @test -f deploy/helm/evydence/templates/deployment-worker.yaml + @test -f deploy/helm/evydence/templates/networkpolicy.yaml @test -f deploy/airgap/manifest.yaml @test -f deploy/observability/prometheus-rules.yaml @test -f deploy/observability/grafana-dashboard.json + @grep -F 'tag: ""' deploy/helm/evydence/values.yaml >/dev/null + @grep -F 'replicas: 1' deploy/helm/evydence/values.yaml >/dev/null + @grep -F 'runAsNonRoot: true' deploy/helm/evydence/values.yaml >/dev/null + @grep -F 'allowPrivilegeEscalation: false' deploy/helm/evydence/values.yaml >/dev/null + @grep -F 'required "image.tag is required' deploy/helm/evydence/templates/deployment-api.yaml >/dev/null + @grep -F 'required "image.tag is required' deploy/helm/evydence/templates/deployment-worker.yaml >/dev/null + @grep -F 'evydence-worker' deploy/helm/evydence/templates/deployment-worker.yaml >/dev/null + @grep -F 'healthcheck' deploy/helm/evydence/values.yaml >/dev/null + @grep -F 'single API writer replica' docs/kubernetes.md >/dev/null sdk-check: ## Validate SDK helper and generated route-catalog coverage against OpenAPI @test -f sdk/go/evydence/client.go diff --git a/cmd/evydence-worker/main.go b/cmd/evydence-worker/main.go index a0bcbec..401e0ae 100644 --- a/cmd/evydence-worker/main.go +++ b/cmd/evydence-worker/main.go @@ -38,12 +38,24 @@ var expectedParserVersions = map[string]string{ } func main() { - if err := run(); err != nil { + if err := runWithArgs(os.Args[1:]); err != nil { log.Fatal(err) } } func run() error { + return runWithArgs(nil) +} + +func runWithArgs(args []string) error { + if len(args) > 0 { + switch args[0] { + case "healthcheck", "--healthcheck": + return nil + default: + return fmt.Errorf("unsupported worker command %q", args[0]) + } + } production := strings.EqualFold(os.Getenv("ENV"), "production") databaseURL := strings.TrimSpace(os.Getenv("EVYDENCE_DATABASE_URL")) if databaseURL == "" { diff --git a/cmd/evydence-worker/main_test.go b/cmd/evydence-worker/main_test.go index acb0454..8cad288 100644 --- a/cmd/evydence-worker/main_test.go +++ b/cmd/evydence-worker/main_test.go @@ -602,6 +602,15 @@ func TestReplayMergeHelpersCoverParserSideEffects(t *testing.T) { } func TestRunRequiresDatabaseURLAndWrapsOpenFailure(t *testing.T) { + if err := runWithArgs([]string{"healthcheck"}); err != nil { + t.Fatalf("healthcheck: %v", err) + } + if err := runWithArgs([]string{"--healthcheck"}); err != nil { + t.Fatalf("--healthcheck: %v", err) + } + if err := runWithArgs([]string{"unexpected"}); err == nil || !strings.Contains(err.Error(), "unsupported worker command") { + t.Fatalf("unexpected command err=%v", err) + } t.Setenv("EVYDENCE_DATABASE_URL", "") err := run() if err == nil || !strings.Contains(err.Error(), "EVYDENCE_DATABASE_URL") { diff --git a/deploy/helm/evydence/templates/deployment-api.yaml b/deploy/helm/evydence/templates/deployment-api.yaml index ec08f13..1d30924 100644 --- a/deploy/helm/evydence/templates/deployment-api.yaml +++ b/deploy/helm/evydence/templates/deployment-api.yaml @@ -1,3 +1,4 @@ +{{- $imageTag := required "image.tag is required for Evydence release installs" .Values.image.tag -}} apiVersion: apps/v1 kind: Deployment metadata: @@ -14,10 +15,14 @@ spec: app.kubernetes.io/name: {{ include "evydence.name" . }} app.kubernetes.io/component: api spec: + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} containers: - name: api - image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + image: "{{ .Values.image.repository }}:{{ $imageTag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} + securityContext: + {{- toYaml .Values.containerSecurityContext | nindent 12 }} command: ["evydence-api"] ports: - name: http @@ -45,4 +50,4 @@ spec: path: /v1/health port: http resources: - {{- toYaml .Values.resources | nindent 12 }} + {{- toYaml .Values.api.resources | nindent 12 }} diff --git a/deploy/helm/evydence/templates/deployment-worker.yaml b/deploy/helm/evydence/templates/deployment-worker.yaml index 4627a1a..0b49a8f 100644 --- a/deploy/helm/evydence/templates/deployment-worker.yaml +++ b/deploy/helm/evydence/templates/deployment-worker.yaml @@ -1,3 +1,4 @@ +{{- $imageTag := required "image.tag is required for Evydence release installs" .Values.image.tag -}} apiVersion: apps/v1 kind: Deployment metadata: @@ -14,10 +15,14 @@ spec: app.kubernetes.io/name: {{ include "evydence.name" . }} app.kubernetes.io/component: worker spec: + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} containers: - name: worker - image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + image: "{{ .Values.image.repository }}:{{ $imageTag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} + securityContext: + {{- toYaml .Values.containerSecurityContext | nindent 12 }} command: ["evydence-worker"] envFrom: - configMapRef: @@ -33,5 +38,15 @@ spec: secretKeyRef: name: {{ .Values.existingSecret }} key: {{ .Values.env.apiKeyPepperSecretKey }} + {{- if .Values.worker.probes.enabled }} + readinessProbe: + exec: + command: + {{- toYaml .Values.worker.probes.readinessCommand | nindent 16 }} + livenessProbe: + exec: + command: + {{- toYaml .Values.worker.probes.livenessCommand | nindent 16 }} + {{- end }} resources: - {{- toYaml .Values.resources | nindent 12 }} + {{- toYaml .Values.worker.resources | nindent 12 }} diff --git a/deploy/helm/evydence/templates/networkpolicy.yaml b/deploy/helm/evydence/templates/networkpolicy.yaml new file mode 100644 index 0000000..e9c12ac --- /dev/null +++ b/deploy/helm/evydence/templates/networkpolicy.yaml @@ -0,0 +1,17 @@ +{{- if .Values.networkPolicy.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "evydence.fullname" . }} +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: {{ include "evydence.name" . }} + app.kubernetes.io/component: api + policyTypes: + - Ingress + ingress: + - ports: + - protocol: TCP + port: 8080 +{{- end }} diff --git a/deploy/helm/evydence/values.yaml b/deploy/helm/evydence/values.yaml index caca018..27f6d7f 100644 --- a/deploy/helm/evydence/values.yaml +++ b/deploy/helm/evydence/values.yaml @@ -1,15 +1,40 @@ image: repository: ghcr.io/aatuh/evydence - tag: dev + # Release installs must set an explicit immutable tag or digest-style tag. + # Local demos may override this with a local development tag. + tag: "" pullPolicy: IfNotPresent api: + # Keep API replicas at 1 for the current production profile. API writes are + # single-writer until focused relational write paths or optimistic + # concurrency controls are implemented and documented. replicas: 1 addr: ":8080" + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + memory: 512Mi worker: replicas: 1 pollInterval: 1s + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + memory: 512Mi + probes: + enabled: true + readinessCommand: + - evydence-worker + - healthcheck + livenessCommand: + - evydence-worker + - healthcheck env: production: true @@ -34,4 +59,17 @@ ingress: host: evydence.example.com tlsSecretName: "" -resources: {} +podSecurityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + +containerSecurityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: false + +networkPolicy: + enabled: false diff --git a/docs/kubernetes.md b/docs/kubernetes.md index 641eb82..97a5e68 100644 --- a/docs/kubernetes.md +++ b/docs/kubernetes.md @@ -1,12 +1,12 @@ # Kubernetes Deployment -This is a how-to guide for self-hosted Kubernetes deployments. +This is a how-to guide for controlled self-hosted Kubernetes deployments. The Helm chart lives at `deploy/helm/evydence`. It deploys the API, worker, service, optional ingress, readiness and liveness probes, and configuration for external PostgreSQL, S3/MinIO object storage, and external signing mode. ## Prerequisites -- A published Evydence image. +- A published Evydence image with an explicit immutable tag or digest. - External PostgreSQL and S3/MinIO-compatible object storage. - A pre-created object-store bucket. - A Kubernetes secret containing at least `EVYDENCE_DATABASE_URL` and `EVYDENCE_API_KEY_PEPPER`. @@ -29,7 +29,7 @@ Store real values in your secret manager or sealed-secret process. Do not commit ```sh helm upgrade --install evydence ./deploy/helm/evydence \ --set image.repository=registry.example.com/evydence \ - --set image.tag=v0.1.0 \ + --set image.tag=v0.1.0-rc.1 \ --set env.s3Endpoint=s3.example.com \ --set env.s3Bucket=evydence ``` @@ -39,6 +39,12 @@ Relevant chart values are defined in `deploy/helm/evydence/values.yaml`: | Value | Purpose | |-------|---------| | `image.repository`, `image.tag` | API and worker image. | +| `api.replicas` | API writer replicas. Keep `1` for the current production profile. | +| `worker.replicas` | Worker replicas. May be scaled with PostgreSQL outbox locking. | +| `api.resources`, `worker.resources` | Resource requests and limits. | +| `podSecurityContext`, `containerSecurityContext` | Non-root and least-privilege pod/container defaults. | +| `worker.probes.*` | Worker exec probes using `evydence-worker healthcheck`. | +| `networkPolicy.enabled` | Optional starter NetworkPolicy for API ingress. | | `existingSecret` | Secret containing runtime sensitive variables. | | `env.databaseURLSecretKey` | Secret key for `EVYDENCE_DATABASE_URL`. | | `env.apiKeyPepperSecretKey` | Secret key for `EVYDENCE_API_KEY_PEPPER`. | @@ -77,4 +83,4 @@ Rollback does not roll back PostgreSQL data or object-store payloads. Keep datab ## Production Notes -Production deployments should use external PostgreSQL, S3/MinIO-compatible object storage, TLS ingress, backup automation, network access controls, and external signing. See [Production hardening review](production-hardening.md) and [Configuration](reference/configuration.md). +Production deployments should use external PostgreSQL, S3/MinIO-compatible object storage, TLS ingress, backup automation, network access controls, and external signing. Current production guidance uses a single API writer replica; worker replicas can scale independently through PostgreSQL outbox row locking. See [Production hardening review](production-hardening.md), [Production readiness](reference/production-readiness.md), and [Configuration](reference/configuration.md). From 0c2de5cd3e11cd432e7ac3065f176f75a8588031 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Fri, 29 May 2026 18:42:05 +0300 Subject: [PATCH 119/287] feat: add focused critical mutation port --- internal/app/critical_mutation_test.go | 202 +++++++++++++++++++++++++ internal/app/enterprise.go | 14 +- internal/app/ledger.go | 32 ++-- internal/app/ports.go | 25 +++ internal/app/state.go | 92 ++++++++++- internal/app/vex.go | 2 +- 6 files changed, 344 insertions(+), 23 deletions(-) create mode 100644 internal/app/critical_mutation_test.go diff --git a/internal/app/critical_mutation_test.go b/internal/app/critical_mutation_test.go new file mode 100644 index 0000000..8c22270 --- /dev/null +++ b/internal/app/critical_mutation_test.go @@ -0,0 +1,202 @@ +package app + +import ( + "context" + "testing" + "time" + + "github.com/aatuh/evydence/internal/domain" +) + +type focusedStoreSpy struct { + saveCalls int + criticalCalls int + mutations []CriticalMutation +} + +func (s *focusedStoreSpy) LoadState(context.Context) (PersistedState, bool, error) { + return PersistedState{}, false, nil +} + +func (s *focusedStoreSpy) SaveState(context.Context, PersistedState) error { + s.saveCalls++ + return nil +} + +func (s *focusedStoreSpy) ApplyCriticalMutation(_ context.Context, mutation CriticalMutation) error { + s.criticalCalls++ + s.mutations = append(s.mutations, mutation) + return nil +} + +func (s *focusedStoreSpy) reset() { + s.saveCalls = 0 + s.criticalCalls = 0 + s.mutations = nil +} + +func TestCriticalMutationStoreAvoidsAggregateSaveForMigratedFlows(t *testing.T) { + ctx := context.Background() + store := &focusedStoreSpy{} + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow, Store: store}) + + _, key, secret, err := ledger.BootstrapTenant(ctx, "Tenant", "admin", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap: %v", err) + } + if store.saveCalls != 0 || store.criticalCalls != 1 { + t.Fatalf("bootstrap save=%d critical=%d", store.saveCalls, store.criticalCalls) + } + first := store.mutations[0] + if len(first.APIKeys) != 1 || first.APIKeys[0].Hash != "" || first.APIKeyHashes[key.ID] == "" { + t.Fatalf("api key mutation leaked or missed hash: %#v hashes=%#v", first.APIKeys, first.APIKeyHashes) + } + + actor, err := ledger.Authenticate(ctx, secret) + if err != nil { + t.Fatalf("authenticate: %v", err) + } + if store.saveCalls != 0 || store.criticalCalls != 2 { + t.Fatalf("authenticate save=%d critical=%d", store.saveCalls, store.criticalCalls) + } + + store.reset() + if _, _, err := ledger.CreateAPIKey(ctx, actor, "reader", []string{ScopeProductRead}, nil); err != nil { + t.Fatalf("create api key: %v", err) + } + if store.saveCalls != 0 || store.criticalCalls != 1 { + t.Fatalf("create api key save=%d critical=%d", store.saveCalls, store.criticalCalls) + } + + store.reset() + status, response, err := ledger.WithIdempotency(ctx, actor, "POST", "/v1/products", "idem-key", []byte(`{"name":"x"}`), func() (int, any, error) { + return 201, map[string]any{"ok": true}, nil + }) + if err != nil || status != 201 || response == nil { + t.Fatalf("idempotency status=%d response=%#v err=%v", status, response, err) + } + if store.saveCalls != 0 || store.criticalCalls != 1 || len(store.mutations[0].Idempotency) != 1 { + t.Fatalf("idempotency save=%d critical=%d mutation=%#v", store.saveCalls, store.criticalCalls, store.mutations) + } +} + +func TestCriticalMutationStoreCoversBundleVerificationAndDecision(t *testing.T) { + ctx := context.Background() + store := &focusedStoreSpy{} + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow, Store: store}) + actor, release, artifact := setupReleaseRiskFixture(t, ledger) + _ = artifact + + store.reset() + bundle, err := ledger.CreateReleaseBundle(ctx, actor, release.ID) + if err != nil { + t.Fatalf("bundle: %v", err) + } + if store.saveCalls != 0 || store.criticalCalls != 1 { + t.Fatalf("bundle save=%d critical=%d", store.saveCalls, store.criticalCalls) + } + bundleMutation := store.mutations[0] + if len(bundleMutation.ReleaseBundles) == 0 || len(bundleMutation.Signatures) == 0 || len(bundleMutation.AuditChainEntries) == 0 || len(bundleMutation.OutboxJobs) != 1 { + t.Fatalf("bundle mutation incomplete: %#v", bundleMutation) + } + + store.reset() + if _, err := ledger.VerifySubject(ctx, actor, "release_bundle", bundle.ID); err != nil { + t.Fatalf("verify bundle: %v", err) + } + if store.saveCalls != 0 || store.criticalCalls != 1 || len(store.mutations[0].VerificationResults) == 0 || len(store.mutations[0].OutboxJobs) != 1 { + t.Fatalf("verify mutation incomplete save=%d critical=%d mutation=%#v", store.saveCalls, store.criticalCalls, store.mutations) + } + + scan := domain.VulnerabilityScan{ID: "scan_test", TenantID: actor.TenantID, ReleaseID: release.ID, Findings: []domain.VulnerabilityFinding{{ID: "finding_test", Vulnerability: "CVE-0000-0001", Severity: "critical", Component: "lib"}}} + ledger.scans[scan.ID] = scan + store.reset() + if _, err := ledger.CreateVulnerabilityDecision(ctx, actor, "finding_test", CreateVulnerabilityDecisionInput{Status: decisionStatusNotAffected, Justification: "component is not present"}); err != nil { + t.Fatalf("decision: %v", err) + } + if store.saveCalls != 0 || store.criticalCalls != 1 || len(store.mutations[0].VulnerabilityDecisions) == 0 { + t.Fatalf("decision mutation incomplete save=%d critical=%d mutation=%#v", store.saveCalls, store.criticalCalls, store.mutations) + } +} + +func TestCriticalMutationStoreCoversSSOAndPortalSecrets(t *testing.T) { + ctx := context.Background() + store := &focusedStoreSpy{} + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow, Store: store}) + actor := domain.Actor{TenantID: "ten_test", KeyID: "key_test", Scopes: []string{"*"}} + ledger.tenants[actor.TenantID] = domain.Tenant{ID: actor.TenantID, Name: "Tenant", CreatedAt: fixedNow()} + ledger.users["user_test"] = domain.HumanUser{ + ID: "user_test", TenantID: actor.TenantID, OrganizationID: "org_test", + Email: "user@example.test", Status: "active", SchemaVersion: domain.HumanUserSchemaVersion, + CreatedAt: fixedNow(), + } + ledger.ssoProviders["sso_test"] = domain.SSOProvider{ + ID: "sso_test", TenantID: actor.TenantID, Name: "OIDC", Type: "oidc", + Issuer: "https://idp.example.test", ClientID: "client", Status: "active", + SchemaVersion: domain.SSOProviderSchemaVersion, CreatedAt: fixedNow(), + } + ledger.customerPackages["pkg_test"] = domain.CustomerSecurityPackage{ + ID: "pkg_test", TenantID: actor.TenantID, Title: "Customer package", + ManifestHash: "sha256:test", SchemaVersion: domain.CustomerPackageSchemaVersion, + CreatedAt: fixedNow(), + } + + store.reset() + session, secret, err := ledger.CreateSSOSession(ctx, actor, CreateSSOSessionInput{ + UserID: "user_test", ProviderID: "sso_test", ExpiresAt: fixedNow().Add(time.Hour), + }) + if err != nil { + t.Fatalf("create sso session: %v", err) + } + if secret == "" || session.Hash != "" { + t.Fatalf("sso session leaked hash or missed secret: session=%#v secret=%q", session, secret) + } + if store.saveCalls != 0 || store.criticalCalls != 1 || len(store.mutations[0].SSOSessions) == 0 || store.mutations[0].SSOSessionHashes[session.ID] == "" { + t.Fatalf("sso mutation incomplete save=%d critical=%d mutation=%#v", store.saveCalls, store.criticalCalls, store.mutations) + } + if store.mutations[0].SSOSessions[0].Hash != "" { + t.Fatalf("sso mutation exposed hash on resource: %#v", store.mutations[0].SSOSessions[0]) + } + + store.reset() + access, portalSecret, err := ledger.CreateCustomerPortalAccess(ctx, actor, CreateCustomerPortalAccessInput{ + PackageID: "pkg_test", CustomerName: "Customer", ExpiresAt: fixedNow().Add(time.Hour), + }) + if err != nil { + t.Fatalf("create portal access: %v", err) + } + if portalSecret == "" || access.Hash != "" { + t.Fatalf("portal access leaked hash or missed secret: access=%#v secret=%q", access, portalSecret) + } + if store.saveCalls != 0 || store.criticalCalls != 1 || len(store.mutations[0].CustomerPortalAccess) == 0 || store.mutations[0].CustomerPortalHashes[access.ID] == "" { + t.Fatalf("portal mutation incomplete save=%d critical=%d mutation=%#v", store.saveCalls, store.criticalCalls, store.mutations) + } + if store.mutations[0].CustomerPortalAccess[0].Hash != "" { + t.Fatalf("portal mutation exposed hash on resource: %#v", store.mutations[0].CustomerPortalAccess[0]) + } +} + +func TestCriticalMutationFallsBackToAggregateSave(t *testing.T) { + ctx := context.Background() + store := &focusedFallbackStore{} + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow, Store: store}) + if _, _, _, err := ledger.BootstrapTenant(ctx, "Tenant", "admin", []string{"*"}); err != nil { + t.Fatalf("bootstrap: %v", err) + } + if store.saveCalls != 1 { + t.Fatalf("fallback save calls = %d", store.saveCalls) + } +} + +type focusedFallbackStore struct { + saveCalls int +} + +func (s *focusedFallbackStore) LoadState(context.Context) (PersistedState, bool, error) { + return PersistedState{}, false, nil +} + +func (s *focusedFallbackStore) SaveState(context.Context, PersistedState) error { + s.saveCalls++ + return nil +} diff --git a/internal/app/enterprise.go b/internal/app/enterprise.go index f117d64..bdcdbca 100644 --- a/internal/app/enterprise.go +++ b/internal/app/enterprise.go @@ -475,7 +475,7 @@ func (l *Ledger) CreateSSOSession(ctx context.Context, actor domain.Actor, in Cr session := domain.SSOSession{ID: newID("sess"), TenantID: actor.TenantID, UserID: user.ID, ProviderID: provider.ID, Prefix: secretPrefix(secret), ExpiresAt: in.ExpiresAt.UTC(), SchemaVersion: domain.SSOSessionSchemaVersion, CreatedAt: l.now(), Hash: l.hashSecret(secret)} l.ssoSessions[session.ID] = session _, _ = l.appendChainLocked(actor.TenantID, "sso_session.created", "human_user", user.ID, actorType(actor), actorID(actor), "", "") - if err := l.persistLocked(ctx); err != nil { + if err := l.persistCriticalLocked(ctx, l.criticalMutationLocked()); err != nil { return domain.SSOSession{}, "", err } session.Hash = "" @@ -593,7 +593,7 @@ func (l *Ledger) ExchangeSSOCredential(ctx context.Context, in ExchangeSSOCreden session := domain.SSOSession{ID: newID("sess"), TenantID: provider.TenantID, UserID: user.ID, ProviderID: provider.ID, Prefix: secretPrefix(secret), Groups: groups, ExpiresAt: expiresAt, SchemaVersion: domain.SSOSessionSchemaVersion, CreatedAt: now, Hash: l.hashSecret(secret)} l.ssoSessions[session.ID] = session _, _ = l.appendChainLocked(provider.TenantID, "sso_session.created", "human_user", user.ID, "sso_provider", provider.ID, "", "") - if err := l.persistLocked(ctx); err != nil { + if err := l.persistCriticalLocked(ctx, l.criticalMutationLocked()); err != nil { return domain.ProviderVerification{}, domain.SSOSession{}, "", err } session.Hash = "" @@ -620,7 +620,7 @@ func (l *Ledger) RevokeSSOSession(ctx context.Context, actor domain.Actor, id st session.RevokedAt = &now l.ssoSessions[session.ID] = session _, _ = l.appendChainLocked(actor.TenantID, "sso_session.revoked", "sso_session", session.ID, actorType(actor), actorID(actor), "", "") - if err := l.persistLocked(ctx); err != nil { + if err := l.persistCriticalLocked(ctx, l.criticalMutationLocked()); err != nil { return domain.SSOSession{}, err } session.Hash = "" @@ -647,7 +647,7 @@ func (l *Ledger) RevokeCurrentSSOSession(ctx context.Context, actor domain.Actor session.RevokedAt = &now l.ssoSessions[session.ID] = session _, _ = l.appendChainLocked(actor.TenantID, "sso_session.revoked", "sso_session", session.ID, actorType(actor), actorID(actor), "", "") - if err := l.persistLocked(ctx); err != nil { + if err := l.persistCriticalLocked(ctx, l.criticalMutationLocked()); err != nil { return domain.SSOSession{}, err } session.Hash = "" @@ -761,7 +761,7 @@ func (l *Ledger) CreateCustomerPortalAccess(ctx context.Context, actor domain.Ac access := domain.CustomerPortalAccess{ID: newID("cpa"), TenantID: actor.TenantID, PackageID: pkg.ID, CustomerName: in.CustomerName, Prefix: secretPrefix(secret), ExpiresAt: in.ExpiresAt.UTC(), SchemaVersion: domain.CustomerPortalAccessVersion, CreatedAt: l.now(), Hash: l.hashSecret(secret)} l.portalAccess[access.ID] = access _, _ = l.appendChainLocked(actor.TenantID, "customer_portal_access.created", "customer_security_package", pkg.ID, actorType(actor), actorID(actor), "", "") - if err := l.persistLocked(ctx); err != nil { + if err := l.persistCriticalLocked(ctx, l.criticalMutationLocked()); err != nil { return domain.CustomerPortalAccess{}, "", err } access.Hash = "" @@ -794,7 +794,7 @@ func (l *Ledger) AccessCustomerPortalPackage(ctx context.Context, token string) if access.RevokedAt != nil && access.FailedAccessCount == customerPortalFailedAccessLimit { _, _ = l.appendChainLocked(access.TenantID, "customer_portal_access.revoked_after_failed_access", "customer_portal_access", access.ID, "customer_portal", "unverified", "", "") } - _ = l.persistLocked(ctx) + _ = l.persistCriticalLocked(ctx, l.criticalMutationLocked()) } continue } @@ -807,7 +807,7 @@ func (l *Ledger) AccessCustomerPortalPackage(ctx context.Context, token string) access.LastAccessedAt = &now l.portalAccess[id] = access _, _ = l.appendChainLocked(access.TenantID, "customer_portal_package.accessed", "customer_security_package", pkg.ID, "customer_portal", access.ID, pkg.ManifestHash, "") - if err := l.persistLocked(ctx); err != nil { + if err := l.persistCriticalLocked(ctx, l.criticalMutationLocked()); err != nil { return domain.CustomerSecurityPackage{}, err } return pkg, nil diff --git a/internal/app/ledger.go b/internal/app/ledger.go index 0428d7d..dd0cd85 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -351,7 +351,7 @@ func (l *Ledger) BootstrapTenant(ctx context.Context, name, keyName string, scop return domain.Tenant{}, domain.APIKey{}, "", err } _, _ = l.appendChainLocked(tenant.ID, "tenant.created", "tenant", tenant.ID, "system", "bootstrap", "", "") - if err := l.persistLocked(ctx); err != nil { + if err := l.persistCriticalLocked(ctx, l.criticalMutationLocked()); err != nil { return domain.Tenant{}, domain.APIKey{}, "", err } return tenant, key, secret, nil @@ -388,7 +388,7 @@ func (l *Ledger) Authenticate(ctx context.Context, secret string) (domain.Actor, break } } - _ = l.persistLocked(ctx) + _ = l.persistCriticalLocked(ctx, l.criticalMutationLocked()) return domain.Actor{TenantID: key.TenantID, KeyID: key.ID, Name: key.Name, Scopes: append([]string(nil), key.Scopes...), CollectorID: collectorID}, nil } for id, session := range l.ssoSessions { @@ -405,7 +405,7 @@ func (l *Ledger) Authenticate(ctx context.Context, secret string) (domain.Actor, return domain.Actor{}, ErrForbidden } l.ssoSessions[id] = session - _ = l.persistLocked(ctx) + _ = l.persistCriticalLocked(ctx, l.criticalMutationLocked()) return domain.Actor{TenantID: user.TenantID, UserID: user.ID, SessionID: session.ID, Name: user.Email, Scopes: scopes, ResourceGrants: grants}, nil } return domain.Actor{}, ErrUnauthorized @@ -431,7 +431,7 @@ func (l *Ledger) CreateAPIKey(ctx context.Context, actor domain.Actor, name stri return domain.APIKey{}, "", err } _, _ = l.appendChainLocked(actor.TenantID, "api_key.created", "api_key", key.ID, "api_key", actor.KeyID, "", "") - if err := l.persistLocked(ctx); err != nil { + if err := l.persistCriticalLocked(ctx, l.criticalMutationLocked()); err != nil { return domain.APIKey{}, "", err } return key, secret, nil @@ -1359,10 +1359,15 @@ func (l *Ledger) CreateReleaseBundle(ctx context.Context, actor domain.Actor, re bundle := domain.ReleaseBundle{ID: bundleID, TenantID: actor.TenantID, ReleaseID: release.ID, State: "generated", Manifest: manifest, ManifestHash: manifestHash, SignatureRefs: []string{sig.ID}, CreatedAt: l.now()} l.bundles[bundle.ID] = bundle _, _ = l.appendChainLocked(actor.TenantID, "bundle.generated", "release_bundle", bundle.ID, "api_key", actor.KeyID, manifestHash, sig.ID) - if err := l.enqueue(ctx, actor.TenantID, "sign_bundle", "release_bundle", bundle.ID, map[string]any{"manifest_hash": manifestHash}); err != nil { - return domain.ReleaseBundle{}, err + job := l.newOutboxJob(actor.TenantID, "sign_bundle", "release_bundle", bundle.ID, map[string]any{"manifest_hash": manifestHash}) + mutation := l.criticalMutationLocked() + mutation.OutboxJobs = append(mutation.OutboxJobs, job) + if _, ok := l.store.(CriticalMutationStore); !ok { + if err := l.enqueueJob(ctx, job); err != nil { + return domain.ReleaseBundle{}, err + } } - if err := l.persistLocked(ctx); err != nil { + if err := l.persistCriticalLocked(ctx, mutation); err != nil { return domain.ReleaseBundle{}, err } return bundle, nil @@ -1613,10 +1618,15 @@ func (l *Ledger) VerifySubject(ctx context.Context, actor domain.Actor, subjectT } vr := domain.VerificationResult{ID: newID("vr"), TenantID: actor.TenantID, SubjectType: subjectType, SubjectID: subjectID, Result: result, Checks: checks, VerifiedAt: l.now()} l.verifications[vr.ID] = vr - if err := l.enqueue(ctx, actor.TenantID, "verify_subject", subjectType, subjectID, map[string]any{"result_id": vr.ID}); err != nil { - return domain.VerificationResult{}, err + job := l.newOutboxJob(actor.TenantID, "verify_subject", subjectType, subjectID, map[string]any{"result_id": vr.ID}) + mutation := l.criticalMutationLocked() + mutation.OutboxJobs = append(mutation.OutboxJobs, job) + if _, ok := l.store.(CriticalMutationStore); !ok { + if err := l.enqueueJob(ctx, job); err != nil { + return domain.VerificationResult{}, err + } } - if err := l.persistLocked(ctx); err != nil { + if err := l.persistCriticalLocked(ctx, mutation); err != nil { return domain.VerificationResult{}, err } if result != "passed" { @@ -1711,7 +1721,7 @@ func (l *Ledger) WithIdempotency(ctx context.Context, actor domain.Actor, method } l.mu.Lock() l.idempotency[storeKey] = IdempotencyRecord{RequestHash: requestHash, Status: status, Response: response, CreatedAt: l.now()} - if err := l.persistLocked(ctx); err != nil { + if err := l.persistCriticalLocked(ctx, l.criticalMutationLocked()); err != nil { l.mu.Unlock() return 0, nil, err } diff --git a/internal/app/ports.go b/internal/app/ports.go index 9caedf2..2655d34 100644 --- a/internal/app/ports.go +++ b/internal/app/ports.go @@ -12,6 +12,10 @@ type Store interface { SaveState(context.Context, PersistedState) error } +type CriticalMutationStore interface { + ApplyCriticalMutation(context.Context, CriticalMutation) error +} + type ObjectStore interface { Put(context.Context, Object) error Get(context.Context, string) (Object, error) @@ -279,6 +283,27 @@ type OutboxJob struct { CreatedAt time.Time `json:"created_at"` } +type CriticalMutation struct { + Tenants []domain.Tenant + APIKeys []domain.APIKey + APIKeyHashes map[string]string + Collectors []domain.Collector + SSOSessions []domain.SSOSession + SSOSessionHashes map[string]string + CustomerPortalAccess []domain.CustomerPortalAccess + CustomerPortalHashes map[string]string + Idempotency map[string]IdempotencyRecord + SigningKeys []domain.SigningKey + SigningKeyPrivate map[string][]byte + Signatures []domain.Signature + ReleaseBundles []domain.ReleaseBundle + VerificationResults []domain.VerificationResult + ProviderVerifications []domain.ProviderVerification + VulnerabilityDecisions []domain.VulnerabilityDecision + AuditChainEntries []domain.AuditChainEntry + OutboxJobs []OutboxJob +} + type nopOutbox struct{} func (nopOutbox) Enqueue(context.Context, OutboxJob) error { return nil } diff --git a/internal/app/state.go b/internal/app/state.go index 9f4ef1f..e315ba5 100644 --- a/internal/app/state.go +++ b/internal/app/state.go @@ -283,6 +283,83 @@ func (l *Ledger) persistLocked(ctx context.Context) error { return l.store.SaveState(ctx, l.snapshotLocked()) } +func (l *Ledger) persistCriticalLocked(ctx context.Context, mutation CriticalMutation) error { + if l.store == nil { + return nil + } + focused, ok := l.store.(CriticalMutationStore) + if !ok { + return l.persistLocked(ctx) + } + return focused.ApplyCriticalMutation(ctx, mutation) +} + +func (l *Ledger) criticalMutationLocked() CriticalMutation { + return criticalMutationFromState(l.snapshotLocked()) +} + +func criticalMutationFromState(state PersistedState) CriticalMutation { + mutation := CriticalMutation{ + APIKeyHashes: map[string]string{}, + SSOSessionHashes: map[string]string{}, + CustomerPortalHashes: map[string]string{}, + Idempotency: map[string]IdempotencyRecord{}, + SigningKeyPrivate: map[string][]byte{}, + } + for _, tenant := range state.Tenants { + mutation.Tenants = append(mutation.Tenants, tenant) + } + for id, key := range state.APIKeys { + mutation.APIKeys = append(mutation.APIKeys, key) + if hash := state.APIKeyHashes[id]; hash != "" { + mutation.APIKeyHashes[id] = hash + } + } + for _, collector := range state.Collectors { + mutation.Collectors = append(mutation.Collectors, collector) + } + for id, session := range state.SSOSessions { + mutation.SSOSessions = append(mutation.SSOSessions, session) + if hash := state.SSOSessionHashes[id]; hash != "" { + mutation.SSOSessionHashes[id] = hash + } + } + for id, access := range state.CustomerPortalAccess { + mutation.CustomerPortalAccess = append(mutation.CustomerPortalAccess, access) + if hash := state.CustomerPortalHashes[id]; hash != "" { + mutation.CustomerPortalHashes[id] = hash + } + } + for key, record := range state.Idempotency { + mutation.Idempotency[key] = record + } + for id, key := range state.SigningKeys { + mutation.SigningKeys = append(mutation.SigningKeys, key) + if private := state.SigningKeyPrivate[id]; len(private) > 0 { + mutation.SigningKeyPrivate[id] = append([]byte(nil), private...) + } + } + for _, signature := range state.Signatures { + mutation.Signatures = append(mutation.Signatures, signature) + } + for _, bundle := range state.Bundles { + mutation.ReleaseBundles = append(mutation.ReleaseBundles, bundle) + } + for _, verification := range state.Verifications { + mutation.VerificationResults = append(mutation.VerificationResults, verification) + } + for _, verification := range state.ProviderVerifications { + mutation.ProviderVerifications = append(mutation.ProviderVerifications, verification) + } + for _, decision := range state.Decisions { + mutation.VulnerabilityDecisions = append(mutation.VulnerabilityDecisions, decision) + } + for _, entries := range state.Chain { + mutation.AuditChainEntries = append(mutation.AuditChainEntries, entries...) + } + return mutation +} + func (l *Ledger) storePayload(ctx context.Context, tenantID, kind, mediaType, digest string, raw []byte) (string, error) { if l.objects == nil { return "", nil @@ -307,10 +384,11 @@ func (l *Ledger) storePayload(ctx context.Context, tenantID, kind, mediaType, di } func (l *Ledger) enqueue(ctx context.Context, tenantID, kind, subjectType, subjectID string, payload map[string]any) error { - if l.outbox == nil { - return nil - } - job := OutboxJob{ + return l.enqueueJob(ctx, l.newOutboxJob(tenantID, kind, subjectType, subjectID, payload)) +} + +func (l *Ledger) newOutboxJob(tenantID, kind, subjectType, subjectID string, payload map[string]any) OutboxJob { + return OutboxJob{ ID: newID("job"), TenantID: tenantID, Kind: kind, @@ -319,6 +397,12 @@ func (l *Ledger) enqueue(ctx context.Context, tenantID, kind, subjectType, subje Payload: cloneMap(payload), CreatedAt: l.now(), } +} + +func (l *Ledger) enqueueJob(ctx context.Context, job OutboxJob) error { + if l.outbox == nil { + return nil + } return l.outbox.Enqueue(ctx, job) } diff --git a/internal/app/vex.go b/internal/app/vex.go index d3da82b..f2c3b0a 100644 --- a/internal/app/vex.go +++ b/internal/app/vex.go @@ -229,7 +229,7 @@ func (l *Ledger) CreateVulnerabilityDecision(ctx context.Context, actor domain.A decision := l.createDecisionLocked(actor.TenantID, scan, finding, in, "api", actor.KeyID, "", "") l.decisions[decision.ID] = decision _, _ = l.appendChainLocked(actor.TenantID, "vulnerability_decision.created", "vulnerability_finding", finding.ID, "api_key", actor.KeyID, "", "") - if err := l.persistLocked(ctx); err != nil { + if err := l.persistCriticalLocked(ctx, l.criticalMutationLocked()); err != nil { return domain.VulnerabilityDecision{}, err } return decision, nil From 2e269abb2da93223b9be048938672ae3851e860d Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Fri, 29 May 2026 19:48:57 +0300 Subject: [PATCH 120/287] feat: persist critical mutations in postgres --- internal/adapters/postgres/store.go | 259 ++++++++++++++++++++++- internal/adapters/postgres/store_test.go | 225 ++++++++++++++++++++ 2 files changed, 483 insertions(+), 1 deletion(-) diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index f11d3ee..ba7df50 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -10,6 +10,7 @@ import ( "time" "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" "github.com/jackc/pgx/v5/pgxpool" "github.com/aatuh/evydence/internal/app" @@ -2530,6 +2531,95 @@ func (s *Store) SaveState(ctx context.Context, state app.PersistedState) error { return nil } +func (s *Store) ApplyCriticalMutation(ctx context.Context, mutation app.CriticalMutation) error { + tx, err := s.pool.BeginTx(ctx, pgx.TxOptions{}) + if err != nil { + return fmt.Errorf("begin critical mutation transaction: %w", err) + } + defer func() { _ = tx.Rollback(ctx) }() + state := criticalMutationState(mutation) + if err := syncCriticalIdentityAndIdempotency(ctx, tx, mutation); err != nil { + return err + } + if err := syncRiskBuildControlRows(ctx, tx, state); err != nil { + return err + } + if err := syncReleaseLedgerCore(ctx, tx, state); err != nil { + return err + } + if err := syncPackageReportRetentionRows(ctx, tx, state); err != nil { + return err + } + for _, job := range mutation.OutboxJobs { + if err := insertOutboxJobTx(ctx, tx, job); err != nil { + return err + } + } + if err := syncCriticalResourceIndex(ctx, tx, state); err != nil { + return err + } + if err := tx.Commit(ctx); err != nil { + return fmt.Errorf("commit critical mutation transaction: %w", err) + } + return nil +} + +func criticalMutationState(mutation app.CriticalMutation) app.PersistedState { + state := relationalEmptyState() + for _, tenant := range mutation.Tenants { + state.Tenants[tenant.ID] = tenant + } + for _, key := range mutation.APIKeys { + state.APIKeys[key.ID] = key + } + for id, hash := range mutation.APIKeyHashes { + state.APIKeyHashes[id] = hash + } + for _, collector := range mutation.Collectors { + state.Collectors[collector.ID] = collector + } + for _, session := range mutation.SSOSessions { + state.SSOSessions[session.ID] = session + } + for id, hash := range mutation.SSOSessionHashes { + state.SSOSessionHashes[id] = hash + } + for _, access := range mutation.CustomerPortalAccess { + state.CustomerPortalAccess[access.ID] = access + } + for id, hash := range mutation.CustomerPortalHashes { + state.CustomerPortalHashes[id] = hash + } + for key, record := range mutation.Idempotency { + state.Idempotency[key] = record + } + for _, key := range mutation.SigningKeys { + state.SigningKeys[key.ID] = key + } + for id, private := range mutation.SigningKeyPrivate { + state.SigningKeyPrivate[id] = append([]byte(nil), private...) + } + for _, signature := range mutation.Signatures { + state.Signatures[signature.ID] = signature + } + for _, bundle := range mutation.ReleaseBundles { + state.Bundles[bundle.ID] = bundle + } + for _, verification := range mutation.VerificationResults { + state.Verifications[verification.ID] = verification + } + for _, verification := range mutation.ProviderVerifications { + state.ProviderVerifications[verification.ID] = verification + } + for _, decision := range mutation.VulnerabilityDecisions { + state.Decisions[decision.ID] = decision + } + for _, entry := range mutation.AuditChainEntries { + state.Chain[entry.TenantID] = append(state.Chain[entry.TenantID], entry) + } + return state +} + func syncReleaseLedgerCore(ctx context.Context, tx pgx.Tx, state app.PersistedState) error { for _, product := range state.Products { if product.ID == "" || product.TenantID == "" { @@ -4456,6 +4546,134 @@ func syncIdentityAndIdempotency(ctx context.Context, tx pgx.Tx, state app.Persis return nil } +func syncCriticalIdentityAndIdempotency(ctx context.Context, tx pgx.Tx, mutation app.CriticalMutation) error { + for _, tenant := range mutation.Tenants { + if tenant.ID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO tenants (id, name, created_at) + VALUES ($1, $2, $3) + ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name + `, tenant.ID, tenant.Name, nonZeroTime(tenant.CreatedAt)); err != nil { + return fmt.Errorf("upsert critical tenant row: %w", err) + } + } + for _, key := range mutation.APIKeys { + if key.ID == "" || key.TenantID == "" { + continue + } + hash := mutation.APIKeyHashes[key.ID] + if hash == "" { + hash = key.Hash + } + scopes, err := json.Marshal(key.Scopes) + if err != nil { + return fmt.Errorf("encode critical api key scopes: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO api_keys ( + id, tenant_id, name, prefix, hash, scopes, expires_at, + revoked_at, last_used_at, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) + ON CONFLICT (id) DO UPDATE SET + name = EXCLUDED.name, + prefix = EXCLUDED.prefix, + hash = EXCLUDED.hash, + scopes = EXCLUDED.scopes, + expires_at = EXCLUDED.expires_at, + revoked_at = EXCLUDED.revoked_at, + last_used_at = EXCLUDED.last_used_at + `, key.ID, key.TenantID, key.Name, key.Prefix, hash, scopes, nullableTime(key.ExpiresAt), nullableTime(key.RevokedAt), nullableTime(key.LastUsedAt), nonZeroTime(key.CreatedAt)); err != nil { + return fmt.Errorf("upsert critical api key row: %w", err) + } + } + for _, session := range mutation.SSOSessions { + if session.ID == "" || session.TenantID == "" { + continue + } + hash := mutation.SSOSessionHashes[session.ID] + if hash == "" { + hash = session.Hash + } + groups, err := json.Marshal(session.Groups) + if err != nil { + return fmt.Errorf("encode critical sso session groups: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO sso_sessions ( + id, tenant_id, user_id, provider_id, prefix, hash, groups, expires_at, + revoked_at, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7::jsonb, $8, $9, $10, $11) + ON CONFLICT (id) DO UPDATE SET + prefix = EXCLUDED.prefix, + hash = EXCLUDED.hash, + groups = EXCLUDED.groups, + expires_at = EXCLUDED.expires_at, + revoked_at = EXCLUDED.revoked_at, + schema_version = EXCLUDED.schema_version + `, session.ID, session.TenantID, session.UserID, session.ProviderID, session.Prefix, hash, string(groups), session.ExpiresAt, nullableTime(session.RevokedAt), session.SchemaVersion, nonZeroTime(session.CreatedAt)); err != nil { + return fmt.Errorf("upsert critical sso session row: %w", err) + } + } + for _, access := range mutation.CustomerPortalAccess { + if access.ID == "" || access.TenantID == "" { + continue + } + hash := mutation.CustomerPortalHashes[access.ID] + if hash == "" { + hash = access.Hash + } + if _, err := tx.Exec(ctx, ` + INSERT INTO customer_portal_access ( + id, tenant_id, package_id, customer_name, prefix, hash, + expires_at, revoked_at, access_count, failed_access_count, + last_accessed_at, last_failed_at, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) + ON CONFLICT (id) DO UPDATE SET + customer_name = EXCLUDED.customer_name, + prefix = EXCLUDED.prefix, + hash = EXCLUDED.hash, + expires_at = EXCLUDED.expires_at, + revoked_at = EXCLUDED.revoked_at, + access_count = EXCLUDED.access_count, + failed_access_count = EXCLUDED.failed_access_count, + last_accessed_at = EXCLUDED.last_accessed_at, + last_failed_at = EXCLUDED.last_failed_at, + schema_version = EXCLUDED.schema_version + `, access.ID, access.TenantID, access.PackageID, access.CustomerName, access.Prefix, hash, access.ExpiresAt, nullableTime(access.RevokedAt), access.AccessCount, access.FailedAccessCount, nullableTime(access.LastAccessedAt), nullableTime(access.LastFailedAt), access.SchemaVersion, nonZeroTime(access.CreatedAt)); err != nil { + return fmt.Errorf("upsert critical customer portal access row: %w", err) + } + } + for key, record := range mutation.Idempotency { + parts, ok := app.ParseIdempotencyRecordKey(key) + if !ok { + continue + } + response, err := json.Marshal(record.Response) + if err != nil { + return fmt.Errorf("encode critical idempotency response: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO idempotency_records ( + tenant_id, actor_key_id, method, path, idempotency_key, + request_hash, status, response, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + ON CONFLICT (tenant_id, actor_key_id, method, path, idempotency_key) + DO UPDATE SET request_hash = EXCLUDED.request_hash, + status = EXCLUDED.status, + response = EXCLUDED.response + `, parts.TenantID, parts.ActorID, parts.Method, parts.Path, parts.IdempotencyKey, record.RequestHash, record.Status, response, nonZeroTime(record.CreatedAt)); err != nil { + return fmt.Errorf("upsert critical idempotency record row: %w", err) + } + } + return nil +} + type resourceProjection struct { TenantID string ResourceType string @@ -4497,6 +4715,33 @@ func syncResourceIndex(ctx context.Context, tx pgx.Tx, state app.PersistedState) return nil } +func syncCriticalResourceIndex(ctx context.Context, tx pgx.Tx, state app.PersistedState) error { + for _, projection := range resourceProjections(state) { + if projection.TenantID == "" || projection.ResourceID == "" || projection.ResourceType == "" { + continue + } + if projection.CreatedAt.IsZero() { + projection.CreatedAt = time.Now().UTC() + } + if _, err := tx.Exec(ctx, ` + INSERT INTO resource_index ( + tenant_id, resource_type, resource_id, product_id, project_id, + release_id, created_at, updated_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, now()) + ON CONFLICT (tenant_id, resource_type, resource_id) + DO UPDATE SET product_id = EXCLUDED.product_id, + project_id = EXCLUDED.project_id, + release_id = EXCLUDED.release_id, + created_at = EXCLUDED.created_at, + updated_at = EXCLUDED.updated_at + `, projection.TenantID, projection.ResourceType, projection.ResourceID, nullableString(projection.ProductID), nullableString(projection.ProjectID), nullableString(projection.ReleaseID), projection.CreatedAt); err != nil { + return fmt.Errorf("upsert critical resource index: %w", err) + } + } + return nil +} + func resourceProjections(state app.PersistedState) []resourceProjection { out := []resourceProjection{} for _, v := range state.Tenants { @@ -4802,11 +5047,19 @@ func nonZeroTime(value time.Time) time.Time { } func (s *Store) Enqueue(ctx context.Context, job app.OutboxJob) error { + return insertOutboxJob(ctx, s.pool, job) +} + +type outboxExecutor interface { + Exec(context.Context, string, ...any) (pgconn.CommandTag, error) +} + +func insertOutboxJob(ctx context.Context, exec outboxExecutor, job app.OutboxJob) error { payload, err := json.Marshal(job.Payload) if err != nil { return fmt.Errorf("encode outbox payload: %w", err) } - _, err = s.pool.Exec(ctx, ` + _, err = exec.Exec(ctx, ` INSERT INTO outbox_jobs ( id, tenant_id, kind, subject_type, subject_id, payload, status, attempts, max_attempts, run_after, created_at, updated_at @@ -4820,6 +5073,10 @@ func (s *Store) Enqueue(ctx context.Context, job app.OutboxJob) error { return nil } +func insertOutboxJobTx(ctx context.Context, tx pgx.Tx, job app.OutboxJob) error { + return insertOutboxJob(ctx, tx, job) +} + func (s *Store) ClaimJobs(ctx context.Context, limit int) ([]ClaimedJob, error) { if limit <= 0 { limit = 10 diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index f02cc64..683d4e3 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -757,6 +757,231 @@ func ptrTime(t time.Time) *time.Time { return &t } +func TestApplyCriticalMutationWithPostgres(t *testing.T) { + databaseURL := os.Getenv("EVYDENCE_TEST_DATABASE_URL") + if databaseURL == "" { + t.Skip("EVYDENCE_TEST_DATABASE_URL is not set") + } + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + admin, err := Open(ctx, databaseURL) + if err != nil { + t.Fatal(err) + } + defer admin.Close() + schema := "evydence_critical_mutation_" + strings.ReplaceAll(time.Now().Format("150405.000000000"), ".", "_") + quotedSchema := pgx.Identifier{schema}.Sanitize() + if _, err := admin.pool.Exec(ctx, "CREATE SCHEMA "+quotedSchema); err != nil { + t.Fatal(err) + } + defer func(cleanupCtx context.Context) { + _, _ = admin.pool.Exec(cleanupCtx, "DROP SCHEMA "+quotedSchema+" CASCADE") + }(context.WithoutCancel(ctx)) + + store, err := OpenWithOptions(ctx, databaseURLWithSearchPath(t, databaseURL, schema), StoreOptions{LoadMode: LoadModeRelationalOnly, DisableSnapshotWrites: true}) + if err != nil { + t.Fatal(err) + } + defer store.Close() + if _, err := store.ApplyMigrations(ctx, "../../../migrations"); err != nil { + t.Fatal(err) + } + + now := time.Now().UTC() + mutation := app.CriticalMutation{ + Tenants: []domain.Tenant{{ID: "ten_focus", Name: "Focused", CreatedAt: now}}, + APIKeys: []domain.APIKey{{ + ID: "key_focus", TenantID: "ten_focus", Name: "api", Prefix: "evy_focus", + Scopes: []string{"*"}, LastUsedAt: ptrTime(now), CreatedAt: now, + }}, + APIKeyHashes: map[string]string{"key_focus": "api-key-hmac-hash"}, + SSOSessions: []domain.SSOSession{{ + ID: "sess_focus", TenantID: "ten_focus", UserID: "user_focus", ProviderID: "sso_focus", + Prefix: "sess_focus", Groups: []string{"security"}, ExpiresAt: now.Add(time.Hour), + SchemaVersion: domain.SSOSessionSchemaVersion, CreatedAt: now, + }}, + SSOSessionHashes: map[string]string{"sess_focus": "sso-session-hash"}, + CustomerPortalAccess: []domain.CustomerPortalAccess{{ + ID: "cpa_focus", TenantID: "ten_focus", PackageID: "pkg_focus", CustomerName: "Customer", + Prefix: "evycp_focus", ExpiresAt: now.Add(time.Hour), AccessCount: 2, FailedAccessCount: 1, + LastAccessedAt: ptrTime(now), LastFailedAt: ptrTime(now), SchemaVersion: domain.CustomerPortalAccessVersion, + CreatedAt: now, + }}, + CustomerPortalHashes: map[string]string{"cpa_focus": "portal-token-hash"}, + Idempotency: map[string]app.IdempotencyRecord{ + app.NewIdempotencyRecordKey("ten_focus", "key_focus", "POST", "/v1/release-bundles", "idem-a"): { + RequestHash: "sha256:request-a", Status: 201, Response: map[string]any{"id": "bundle_focus"}, CreatedAt: now, + }, + }, + SigningKeys: []domain.SigningKey{{ + ID: "sigkey_focus", TenantID: "ten_focus", KID: "kid-focus", Algorithm: "Ed25519", + Status: "active", PublicKey: "public-key", CreatedAt: now, + }}, + SigningKeyPrivate: map[string][]byte{"sigkey_focus": []byte("encrypted-dev-key")}, + Signatures: []domain.Signature{{ + ID: "sig_focus", TenantID: "ten_focus", SubjectType: "release_bundle", SubjectID: "bundle_focus", + KeyID: "sigkey_focus", Algorithm: "Ed25519", Value: "signature", CreatedAt: now, + }}, + ReleaseBundles: []domain.ReleaseBundle{{ + ID: "bundle_focus", TenantID: "ten_focus", ReleaseID: "rel_focus", State: "generated", + Manifest: map[string]any{"release_id": "rel_focus"}, ManifestHash: "sha256:" + strings.Repeat("a", 64), + SignatureRefs: []string{"sig_focus"}, CreatedAt: now, + }}, + VerificationResults: []domain.VerificationResult{{ + ID: "verify_focus", TenantID: "ten_focus", SubjectType: "release_bundle", SubjectID: "bundle_focus", + Result: "passed", Checks: []domain.VerifyCheck{{Name: "signature", Result: "passed"}}, VerifiedAt: now, + }}, + VulnerabilityDecisions: []domain.VulnerabilityDecision{{ + ID: "decision_focus", TenantID: "ten_focus", FindingID: "finding_focus", ScanID: "scan_focus", + ReleaseID: "rel_focus", Vulnerability: "CVE-2099-0001", Component: "pkg:generic/api", + Status: "not_affected", Justification: "component_not_present", Source: "manual", + SchemaVersion: domain.VulnerabilityDecisionVersion, CreatedAt: now, + }}, + AuditChainEntries: []domain.AuditChainEntry{{ + ID: "chain_focus", TenantID: "ten_focus", Sequence: 1, EntryType: "release_bundle.created", + SubjectType: "release_bundle", SubjectID: "bundle_focus", ActorType: "api_key", ActorID: "key_focus", + OccurredAt: now, CanonicalEntryHash: "sha256:" + strings.Repeat("b", 64), + PreviousEntryHash: "", EntryHash: "sha256:" + strings.Repeat("c", 64), + Metadata: map[string]any{"focused": true}, SchemaVersion: domain.AuditChainEntrySchemaVersion, + }}, + OutboxJobs: []app.OutboxJob{{ + ID: "job_focus", TenantID: "ten_focus", Kind: "sign_bundle", + SubjectType: "release_bundle", SubjectID: "bundle_focus", Payload: map[string]any{"bundle_id": "bundle_focus"}, + CreatedAt: now, + }}, + } + if err := store.ApplyCriticalMutation(ctx, mutation); err != nil { + t.Fatal(err) + } + if err := store.ApplyCriticalMutation(ctx, mutation); err != nil { + t.Fatalf("retry focused mutation: %v", err) + } + if err := store.ApplyCriticalMutation(ctx, app.CriticalMutation{ + Idempotency: map[string]app.IdempotencyRecord{ + app.NewIdempotencyRecordKey("ten_focus", "key_focus", "POST", "/v1/release-bundles", "idem-b"): { + RequestHash: "sha256:request-b", Status: 201, Response: map[string]any{"id": "bundle_other"}, CreatedAt: now, + }, + }, + }); err != nil { + t.Fatalf("second idempotency mutation: %v", err) + } + + var snapshotRows int + if err := store.pool.QueryRow(ctx, `SELECT count(*) FROM ledger_state`).Scan(&snapshotRows); err != nil { + t.Fatal(err) + } + if snapshotRows != 0 { + t.Fatalf("ledger_state rows = %d, want 0", snapshotRows) + } + checks := []struct { + name string + query string + }{ + {name: "tenant", query: `SELECT count(*) FROM tenants WHERE id = 'ten_focus'`}, + {name: "api key hash", query: `SELECT count(*) FROM api_keys WHERE id = 'key_focus' AND hash = 'api-key-hmac-hash' AND last_used_at IS NOT NULL`}, + {name: "sso session hash", query: `SELECT count(*) FROM sso_sessions WHERE id = 'sess_focus' AND hash = 'sso-session-hash' AND groups = '["security"]'::jsonb`}, + {name: "portal hash", query: `SELECT count(*) FROM customer_portal_access WHERE id = 'cpa_focus' AND hash = 'portal-token-hash' AND failed_access_count = 1`}, + {name: "audit chain", query: `SELECT count(*) FROM audit_chain_entries WHERE tenant_id = 'ten_focus' AND sequence = 1`}, + {name: "signing key private", query: `SELECT count(*) FROM signing_keys WHERE id = 'sigkey_focus' AND encrypted_private_key IS NOT NULL`}, + {name: "signature", query: `SELECT count(*) FROM signatures WHERE id = 'sig_focus' AND key_id = 'sigkey_focus'`}, + {name: "bundle", query: `SELECT count(*) FROM release_bundles WHERE id = 'bundle_focus' AND signature_refs = '["sig_focus"]'::jsonb`}, + {name: "verification", query: `SELECT count(*) FROM verification_results WHERE id = 'verify_focus' AND result = 'passed'`}, + {name: "decision", query: `SELECT count(*) FROM vulnerability_decisions WHERE id = 'decision_focus' AND status = 'not_affected'`}, + {name: "outbox", query: `SELECT count(*) FROM outbox_jobs WHERE id = 'job_focus' AND status = 'queued'`}, + {name: "resource index", query: `SELECT count(*) FROM resource_index WHERE tenant_id = 'ten_focus' AND resource_type = 'release_bundle' AND resource_id = 'bundle_focus'`}, + } + for _, check := range checks { + var rows int + if err := store.pool.QueryRow(ctx, check.query).Scan(&rows); err != nil { + t.Fatalf("%s query: %v", check.name, err) + } + if rows != 1 { + t.Fatalf("%s rows = %d, want 1", check.name, rows) + } + } + var idempotencyRows int + if err := store.pool.QueryRow(ctx, `SELECT count(*) FROM idempotency_records WHERE tenant_id = 'ten_focus'`).Scan(&idempotencyRows); err != nil { + t.Fatal(err) + } + if idempotencyRows != 2 { + t.Fatalf("idempotency rows = %d, want 2", idempotencyRows) + } + var outboxRows int + if err := store.pool.QueryRow(ctx, `SELECT count(*) FROM outbox_jobs WHERE id = 'job_focus'`).Scan(&outboxRows); err != nil { + t.Fatal(err) + } + if outboxRows != 1 { + t.Fatalf("outbox retry rows = %d, want 1", outboxRows) + } + + loaded, ok, err := store.LoadState(ctx) + if err != nil || !ok { + t.Fatalf("relational load ok=%v err=%v", ok, err) + } + if loaded.APIKeyHashes["key_focus"] != "api-key-hmac-hash" || loaded.APIKeys["key_focus"].Hash != "" { + t.Fatalf("loaded api key hash=%q exposed=%q", loaded.APIKeyHashes["key_focus"], loaded.APIKeys["key_focus"].Hash) + } + if loaded.SSOSessionHashes["sess_focus"] != "sso-session-hash" || loaded.SSOSessions["sess_focus"].Hash != "" { + t.Fatalf("loaded sso session hash=%q exposed=%q", loaded.SSOSessionHashes["sess_focus"], loaded.SSOSessions["sess_focus"].Hash) + } + if loaded.CustomerPortalHashes["cpa_focus"] != "portal-token-hash" || loaded.CustomerPortalAccess["cpa_focus"].Hash != "" { + t.Fatalf("loaded portal hash=%q exposed=%q", loaded.CustomerPortalHashes["cpa_focus"], loaded.CustomerPortalAccess["cpa_focus"].Hash) + } + if loaded.Bundles["bundle_focus"].ManifestHash == "" || loaded.Decisions["decision_focus"].Status != "not_affected" || len(loaded.Chain["ten_focus"]) != 1 { + t.Fatalf("loaded critical resources missing: bundle=%#v decision=%#v chain=%#v", loaded.Bundles["bundle_focus"], loaded.Decisions["decision_focus"], loaded.Chain["ten_focus"]) + } +} + +func TestApplyCriticalMutationRollsBackTransaction(t *testing.T) { + databaseURL := os.Getenv("EVYDENCE_TEST_DATABASE_URL") + if databaseURL == "" { + t.Skip("EVYDENCE_TEST_DATABASE_URL is not set") + } + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + admin, err := Open(ctx, databaseURL) + if err != nil { + t.Fatal(err) + } + defer admin.Close() + schema := "evydence_critical_rollback_" + strings.ReplaceAll(time.Now().Format("150405.000000000"), ".", "_") + quotedSchema := pgx.Identifier{schema}.Sanitize() + if _, err := admin.pool.Exec(ctx, "CREATE SCHEMA "+quotedSchema); err != nil { + t.Fatal(err) + } + defer func(cleanupCtx context.Context) { + _, _ = admin.pool.Exec(cleanupCtx, "DROP SCHEMA "+quotedSchema+" CASCADE") + }(context.WithoutCancel(ctx)) + + store, err := OpenWithOptions(ctx, databaseURLWithSearchPath(t, databaseURL, schema), StoreOptions{LoadMode: LoadModeRelationalOnly, DisableSnapshotWrites: true}) + if err != nil { + t.Fatal(err) + } + defer store.Close() + if _, err := store.ApplyMigrations(ctx, "../../../migrations"); err != nil { + t.Fatal(err) + } + now := time.Now().UTC() + err = store.ApplyCriticalMutation(ctx, app.CriticalMutation{ + Tenants: []domain.Tenant{{ID: "ten_rollback", Name: "Rollback", CreatedAt: now}}, + Signatures: []domain.Signature{{ + ID: "sig_rollback", TenantID: "ten_rollback", SubjectType: "release_bundle", + SubjectID: "bundle_rollback", KeyID: "missing_key", Algorithm: "Ed25519", + Value: "signature", CreatedAt: now, + }}, + }) + if err == nil { + t.Fatal("expected missing signing key to fail critical mutation") + } + var tenantRows int + if queryErr := store.pool.QueryRow(ctx, `SELECT count(*) FROM tenants WHERE id = 'ten_rollback'`).Scan(&tenantRows); queryErr != nil { + t.Fatal(queryErr) + } + if tenantRows != 0 { + t.Fatalf("rollback tenant rows = %d, want 0", tenantRows) + } +} + func TestPendingMigrationVersionsWithPostgres(t *testing.T) { databaseURL := os.Getenv("EVYDENCE_TEST_DATABASE_URL") if databaseURL == "" { From 74f2356de1753e7b56b58a29fe4a57344454c0ad Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Fri, 29 May 2026 20:44:21 +0300 Subject: [PATCH 121/287] docs: document focused critical writes --- CHANGELOG.md | 6 +++++- README.md | 2 +- docs/architecture.md | 2 +- docs/reference/configuration.md | 8 ++++++++ docs/reference/production-readiness.md | 27 +++++++++++++++++++------- docs/reference/release-candidate.md | 6 +++--- 6 files changed, 38 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7aabf55..300cf90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,10 @@ Release-candidate tagging requires the production gate and checklist in - Production-readiness profile, production gate, and coverage-threshold gate. - Release-candidate checklist requiring production-check evidence, checksums, signed artifact manifests, release notes, and documented limitations. +- Focused PostgreSQL critical mutations for tenants, credential hashes, + idempotency records, audit-chain entries, release bundles, signatures, + verification results, provider verification receipts, vulnerability + decisions, and outbox jobs. ### Known Limits @@ -30,6 +34,6 @@ Release-candidate tagging requires the production gate and checklist in - Operators remain responsible for production PostgreSQL, object storage, network policy, TLS, backups, monitoring, external signing, and incident response. -- Focused relational write paths, HA/multi-writer operation, direct KMS/HSM SDK +- Full repository decomposition, HA/multi-writer operation, direct KMS/HSM SDK adapters, live provider validation, broader object-lock proof, and final exit review remain production-hardening work after the release-candidate gate. diff --git a/README.md b/README.md index 4b6728b..94050c8 100644 --- a/README.md +++ b/README.md @@ -109,4 +109,4 @@ make postgres-integration-test `make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. -`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required release-candidate evidence, but it does not by itself close the remaining focused repository-write, direct KMS/HSM SDK, provider API/group validation, object-lock enforcement, HA, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. Current self-hosted production guidance uses a single API writer replica and allows worker replicas to scale through PostgreSQL outbox row locking. +`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required release-candidate evidence, but it does not by itself close the remaining repository decomposition, direct KMS/HSM SDK, provider API/group validation, object-lock enforcement, HA, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. Critical runtime mutations for tenants, credential hashes, idempotency, audit-chain entries, release bundles, signatures, verification results, vulnerability decisions, and outbox jobs use focused PostgreSQL write paths when available. Current self-hosted production guidance still uses a single API writer replica and allows worker replicas to scale through PostgreSQL outbox row locking. diff --git a/docs/architecture.md b/docs/architecture.md index a218837..9274dcd 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -10,7 +10,7 @@ Evydence follows a ports-and-adapters shape: - `internal/adapters/objectstore/s3` stores the same tenant-prefixed object keys in S3/MinIO-compatible buckets. - `cmd/*` contains process entry points. -Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity, idempotency, and customer portal token records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. Collector/build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension records are synchronized into their migration-backed relational tables. Production API and worker startup defaults to relational-only reconstruction and disables compatibility snapshot writes; local development defaults to snapshot-preferred compatibility. If the snapshot row is absent, the Postgres store can rebuild identity, SSO session, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. +Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity, idempotency, and customer portal token records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. Collector/build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension records are synchronized into their migration-backed relational tables. Production API and worker startup defaults to relational-only reconstruction and disables compatibility snapshot writes; local development defaults to snapshot-preferred compatibility. When the PostgreSQL store is configured, critical runtime mutations for tenants, API-key hashes, SSO-session hashes, customer-portal token hashes, idempotency records, audit-chain entries, signing keys, signatures, release bundles, verification results, provider verification receipts, vulnerability decisions, and outbox jobs are written through focused transaction-backed mutations instead of relying only on aggregate `SaveState`. Non-migrated resource families still use the broader aggregate persistence path. If the snapshot row is absent, the Postgres store can rebuild identity, SSO session, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. ## Tenant And Auth Boundaries diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 4c90bef..8a0a6d7 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -73,6 +73,14 @@ preserve existing workflows. Use `relational_preferred` only for controlled non-production migration or recovery checks that intentionally fall back to the snapshot. +When PostgreSQL is configured, critical runtime mutations use focused +transaction-backed writes for tenants, API-key hashes, SSO-session hashes, +customer-portal token hashes, idempotency records, audit-chain entries, +signing keys, signatures, release bundles, verification results, provider +verification receipts, vulnerability decisions, and outbox jobs. Remaining +resource families still depend on the broader ledger persistence path until +later repository decomposition work. + ## S3/MinIO Object-Retention Verification When `EVYDENCE_OBJECT_STORE=s3` or `minio`, object-retention policy verification diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 76f489a..4296ceb 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -17,7 +17,7 @@ controls. Known hardening work remains: - canonical production persistence still needs hand-tuned relational repository - paths for all high-risk resource families. PostgreSQL now maintains + paths for all resource families. PostgreSQL now maintains relational identity, idempotency, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE @@ -30,7 +30,13 @@ Known hardening work remains: worker startup load from relational reconstruction only. Production refuses snapshot fallback modes and disables compatibility snapshot writes; local development still defaults to snapshot-preferred loading and snapshot writes. - If the snapshot row is absent, the store can rebuild identity, SSO session, + Critical runtime mutations for tenants, API-key hashes, SSO-session hashes, + customer-portal token hashes, idempotency records, audit-chain entries, + signing keys, signatures, release bundles, verification results, provider + verification receipts, vulnerability decisions, and outbox jobs now use + focused PostgreSQL transactions when that store is configured. Non-migrated + resource families still use broader aggregate persistence. If the snapshot + row is absent, the store can rebuild identity, SSO session, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE @@ -74,10 +80,12 @@ Known hardening work remains: The current self-hosted production profile supports one API writer replica. This is intentional while the application still uses a large in-process ledger -aggregate plus `LoadState` / `SaveState` persistence boundaries. Do not scale -API writer replicas above one for production use until focused relational -repository writes or another reviewed concurrency-control design is implemented -and documented. +aggregate and some resource families still use aggregate persistence. Focused +critical mutations reduce the riskiest `SaveState` dependence, but they are +not a full multi-writer concurrency design. Do not scale API writer replicas +above one for production use until focused relational repository writes cover +all write families or another reviewed concurrency-control design is +implemented and documented. Worker replicas may be scaled because persisted outbox jobs are claimed with PostgreSQL row locking. Scaling workers increases parser/signing/report @@ -144,7 +152,12 @@ implemented capabilities: - Continue replacing aggregate `SaveState` synchronization with dependency-ordered relational repositories for focused resource families. - Identity, idempotency, customer portal token, release-ledger core, build provenance, + Focused transaction-backed writes now cover tenants, API-key hashes, + SSO-session hashes, customer-portal token hashes, idempotency records, + audit-chain entries, signing keys, signatures, release bundles, verification + results, provider verification receipts, vulnerability decisions, and outbox + jobs. Relational row synchronization also covers identity, idempotency, + customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, diff --git a/docs/reference/release-candidate.md b/docs/reference/release-candidate.md index ccf37cb..1075891 100644 --- a/docs/reference/release-candidate.md +++ b/docs/reference/release-candidate.md @@ -57,6 +57,6 @@ production, and hosted SaaS production require additional review and controls. - Use external PostgreSQL, external object storage, TLS ingress, non-default API-key pepper, externalized secrets, backup and restore rehearsal, monitoring, and documented incident response. -- Keep focused relational repository writes, HA/multi-writer operation, direct - KMS/HSM SDK adapters, live provider validation, and broader object-lock proof - listed as unresolved hardening work until they are implemented and verified. +- Keep full repository decomposition, HA/multi-writer operation, direct KMS/HSM + SDK adapters, live provider validation, and broader object-lock proof listed + as unresolved hardening work until they are implemented and verified. From 3f3ee887e79c3d947e63a06b9321b931448f540c Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sat, 30 May 2026 08:10:52 +0300 Subject: [PATCH 122/287] feat: add release candidate packaging gate --- Makefile | 14 +- docs/README.md | 1 + docs/reference/release-notes-v0.1.0-rc.1.md | 52 ++++++++ scripts/release_candidate_package.sh | 138 ++++++++++++++++++++ scripts/release_candidate_validate.sh | 72 ++++++++++ 5 files changed, 276 insertions(+), 1 deletion(-) create mode 100644 docs/reference/release-notes-v0.1.0-rc.1.md create mode 100755 scripts/release_candidate_package.sh create mode 100755 scripts/release_candidate_validate.sh diff --git a/Makefile b/Makefile index 01dcb91..5043a33 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,9 @@ GOLANGCI_LINT_VERSION ?= v2.11.4 GOSEC_VERSION ?= v2.25.0 GOVULNCHECK_VERSION ?= v1.2.0 -.PHONY: help tools fmt lint vuln gosec test test-race coverage coverage-check openapi-check openapi-precision-check meta-check docs-check deploy-check sdk-check fast-check finalize release-acceptance release-check production-check migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean +TAG ?= v0.1.0-rc.1 + +.PHONY: help tools fmt lint vuln gosec test test-race coverage coverage-check openapi-check openapi-precision-check meta-check docs-check deploy-check sdk-check fast-check finalize release-acceptance release-check production-check release-candidate-check migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean help: ## Show help @awk 'BEGIN {FS=":.*## "}; /^[a-zA-Z0-9_.-]+:.*## / { printf " %-18s %s\n", $$1, $$2 }' $(MAKEFILE_LIST) @@ -65,6 +67,8 @@ meta-check: ## Validate root legal, governance, support, and release-evidence me @test -f CHANGELOG.md @test -f .dockerignore @test -x scripts/release_acceptance.sh + @test -x scripts/release_candidate_package.sh + @test -x scripts/release_candidate_validate.sh @grep -F 'GNU AFFERO GENERAL PUBLIC LICENSE' LICENSE >/dev/null @grep -F 'AGPL-3.0-only' COMMERCIAL.md >/dev/null @grep -F 'Commercial license exceptions' COMMERCIAL.md >/dev/null @@ -97,6 +101,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @test -f docs/reference/observability.md @test -f docs/reference/production-readiness.md @test -f docs/reference/release-candidate.md + @test -f docs/reference/release-notes-v0.1.0-rc.1.md @test -f docs/reference/worker-outbox.md @test -f docs/reference/release-validation.md @test -f docs/explanation/trust-model.md @@ -123,6 +128,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod "reference/observability.md" \ "reference/production-readiness.md" \ "reference/release-candidate.md" \ + "reference/release-notes-v0.1.0-rc.1.md" \ "reference/worker-outbox.md" \ "reference/release-validation.md" \ "collectors/source-snapshots.md" \ @@ -156,9 +162,12 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'make production-check' .github/workflows/ci.yml >/dev/null @grep -F 'make production-check' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'EVYDENCE_RELEASE_SIGNING_PRIVATE_KEY_B64' .github/workflows/release-artifacts.yml >/dev/null + @grep -F 'scripts/release_candidate_package.sh' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'evydence-release-manifest.sig.json' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'gh release create' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'Controlled self-hosted production candidate' docs/reference/release-candidate.md >/dev/null + @grep -F 'Controlled self-hosted production candidate' docs/reference/release-notes-v0.1.0-rc.1.md >/dev/null + @grep -F 'not legal compliance proof' docs/reference/release-notes-v0.1.0-rc.1.md >/dev/null @grep -F 'Use one API writer replica' docs/reference/release-candidate.md >/dev/null @grep -F 'private security intake' SECURITY.md >/dev/null @! grep -R -i "automatically compliant\|certified secure\|legally sufficient\|SBOM is complete\|all vulnerabilities detected\|scanner findings are authoritative\|regulator-ready without review" README.md docs @@ -239,6 +248,9 @@ release-check: ## Release validation with security, race, and configured live in production-check: ## Strict self-hosted production readiness gate; requires live PostgreSQL and coverage threshold @scripts/production_check.sh +release-candidate-check: ## Build and validate a signed release-candidate package with TAG=v0.1.0-rc.1 by default + @scripts/release_candidate_package.sh "$(TAG)" + migration-compatibility-check: ## Verify every committed migration prefix upgrades to current schema @$(GO) test ./internal/adapters/postgres -run TestMigrationCompatibilityFromEveryCommittedState -count=1 diff --git a/docs/README.md b/docs/README.md index bd3987d..d17d750 100644 --- a/docs/README.md +++ b/docs/README.md @@ -25,6 +25,7 @@ This documentation is organized by reader task. Implementation claims should be - [Observability](reference/observability.md): readiness, admin metrics, Prometheus rules, and dashboard starter assets. - [Production readiness](reference/production-readiness.md): self-hosted production profiles, production gates, and exit criteria. - [Release candidate checklist](reference/release-candidate.md): required evidence before tagging a controlled self-hosted release candidate. +- [Release notes v0.1.0-rc.1](reference/release-notes-v0.1.0-rc.1.md): checked release-note wording for the first controlled self-hosted release candidate. - [Worker outbox contract](reference/worker-outbox.md): durable job kinds, idempotency, and safe logging rules. - [Release validation](reference/release-validation.md): canonical `make release-check` behavior and summary evidence. - [SDK workflow](sdk/README.md): current Go, TypeScript, and Python wrapper usage and limitations. diff --git a/docs/reference/release-notes-v0.1.0-rc.1.md b/docs/reference/release-notes-v0.1.0-rc.1.md new file mode 100644 index 0000000..9a69db2 --- /dev/null +++ b/docs/reference/release-notes-v0.1.0-rc.1.md @@ -0,0 +1,52 @@ +# Evydence v0.1.0-rc.1 Release Notes + +Status: Controlled self-hosted production candidate. + +This release candidate is intended for evaluation, pilots, and controlled +internal production after operator review. It is not legal compliance proof, +not a certification, not a secure-release guarantee, not complete SBOM proof, +not authoritative vulnerability coverage, and not auditor or regulator +acceptance. + +## Supported Profile + +- Self-hosted API, worker, PostgreSQL, and object storage deployment. +- One API writer replica for the current production profile. +- Worker replicas may scale through PostgreSQL outbox row locking. +- External TLS, secret management, backup automation, monitoring, and incident + response remain operator responsibilities. + +## Evidence In This Release Package + +- Passing `make production-check` evidence with live PostgreSQL. +- `release-check-summary.txt` from the same run. +- `coverage.out` and threshold evidence. +- `openapi.yaml` and `openapi.sha256`. +- `migrations.sha256`. +- `SHA256SUMS` for release archives and evidence files. +- Signed release artifact manifest and manifest signature. + +## Install And Upgrade Notes + +- Use PostgreSQL for durable runtime state. +- Use S3/MinIO-compatible object storage or the documented filesystem mode for + local evaluation only. +- Set `ENV=production`, a non-default `EVYDENCE_API_KEY_PEPPER`, and + `EVYDENCE_SIGNING_KEY_MODE=external` for production-profile startup. +- Apply all committed migrations before starting API or worker processes. +- For Kubernetes, set an explicit image tag or digest and keep API replicas at + `1` until HA/multi-writer support is reviewed. + +## Known Limitations + +- Full repository decomposition remains hardening work; focused critical + PostgreSQL writes cover the highest-risk runtime mutations, but not every + resource family. +- HA/multi-writer API operation is not supported in this profile. +- Direct cloud KMS/HSM SDK adapters are not included. +- Live GitHub/GitLab provider API validation and external group + synchronization remain deployment-dependent. +- Broader WORM/object-lock proof beyond configured S3/MinIO checks remains + deployment-dependent. +- Operators must run backup and restore rehearsals for their target + infrastructure before relying on this in production. diff --git a/scripts/release_candidate_package.sh b/scripts/release_candidate_package.sh new file mode 100755 index 0000000..fe4a813 --- /dev/null +++ b/scripts/release_candidate_package.sh @@ -0,0 +1,138 @@ +#!/usr/bin/env bash +set -euo pipefail + +repo_root="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)" +cd "$repo_root" + +tag="${1:-}" +if [[ -z "$tag" ]]; then + echo "usage: scripts/release_candidate_package.sh " >&2 + exit 2 +fi +if [[ ! "$tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$ ]]; then + echo "release candidate tag must look like v0.1.0-rc.1" >&2 + exit 2 +fi +if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then + echo "release candidate packaging must run inside a git checkout" >&2 + exit 2 +fi +if [[ -n "$(git status --porcelain --untracked-files=all)" ]]; then + echo "release candidate packaging requires a clean worktree" >&2 + exit 2 +fi +if git rev-parse -q --verify "refs/tags/${tag}" >/dev/null; then + if [[ "${EVYDENCE_RELEASE_ALLOW_EXISTING_TAG:-}" != "1" ]]; then + echo "release candidate tag already exists locally: ${tag}" >&2 + exit 2 + fi +fi +if [[ -z "${EVYDENCE_TEST_DATABASE_URL:-}" ]]; then + echo "EVYDENCE_TEST_DATABASE_URL is required for release candidate packaging" >&2 + exit 2 +fi + +signing_key_b64="${EVYDENCE_RELEASE_SIGNING_PRIVATE_KEY_B64:-${RELEASE_SIGNING_PRIVATE_KEY_B64:-}}" +if [[ -z "$signing_key_b64" ]]; then + echo "EVYDENCE_RELEASE_SIGNING_PRIVATE_KEY_B64 or RELEASE_SIGNING_PRIVATE_KEY_B64 is required" >&2 + exit 2 +fi +RELEASE_CANDIDATE_SIGNING_KEY_B64="$signing_key_b64" python3 - <<'PY' +import base64 +import os +import sys + +raw = os.environ.get("RELEASE_CANDIDATE_SIGNING_KEY_B64", "").strip() +try: + decoded = base64.b64decode(raw, validate=True) +except Exception: + print("release signing key must be base64", file=sys.stderr) + sys.exit(2) +if len(decoded) != 64: + print("release signing key must decode to a 64-byte Ed25519 private key", file=sys.stderr) + sys.exit(2) +PY + +echo "Packaging Evydence release candidate ${tag}" +make production-check + +distdir="dist/${tag}" +workdir="tmp/release-candidate/${tag}" +rm -rf "$distdir" "$workdir" +install -m 755 -d "$distdir" "$workdir" + +commands=(evydence evydence-api evydence-worker evydence-migrate) +targets=(linux/amd64 linux/arm64 darwin/amd64 darwin/arm64 windows/amd64) + +for target in "${targets[@]}"; do + goos="${target%/*}" + goarch="${target#*/}" + outdir="${workdir}/evydence_${tag}_${goos}_${goarch}" + mkdir -p "$outdir" + for command in "${commands[@]}"; do + suffix="" + if [[ "$goos" == "windows" ]]; then + suffix=".exe" + fi + GOOS="$goos" GOARCH="$goarch" CGO_ENABLED=0 \ + go build -trimpath -ldflags "-s -w" \ + -o "${outdir}/${command}${suffix}" "./cmd/${command}" + done + cp LICENSE README.md CHANGELOG.md "$outdir/" + if [[ "$goos" == "windows" ]]; then + (cd "$workdir" && zip -qr "${repo_root}/${distdir}/evydence_${tag}_${goos}_${goarch}.zip" "evydence_${tag}_${goos}_${goarch}") + else + tar -C "$workdir" -czf "${distdir}/evydence_${tag}_${goos}_${goarch}.tar.gz" "evydence_${tag}_${goos}_${goarch}" + fi +done + +cp openapi.yaml "$distdir/openapi.yaml" +cp coverage.out "$distdir/coverage.out" +cp tmp/release-check-summary.txt "$distdir/release-check-summary.txt" +cp docs/reference/release-notes-v0.1.0-rc.1.md "$distdir/release-notes.md" +sed -i.bak "s/v0.1.0-rc.1/${tag}/g" "$distdir/release-notes.md" +rm -f "$distdir/release-notes.md.bak" + +(cd "$distdir" && sha256sum openapi.yaml > openapi.sha256) +(cd "$repo_root" && find migrations -type f -print | LC_ALL=C sort | xargs sha256sum > "$distdir/migrations.sha256") + +(cd "$distdir" && sha256sum \ + evydence_${tag}_*.tar.gz \ + evydence_${tag}_*.zip \ + openapi.yaml \ + openapi.sha256 \ + coverage.out \ + release-check-summary.txt \ + migrations.sha256 \ + release-notes.md > SHA256SUMS) + +signing_dir="${workdir}/signing" +install -m 700 -d "$signing_dir" +signing_key="${signing_dir}/private.key" +umask 077 +printf '%s' "$signing_key_b64" > "$signing_key" + +tar -xzf "${distdir}/evydence_${tag}_linux_amd64.tar.gz" -C "$signing_dir" +cli="${signing_dir}/evydence_${tag}_linux_amd64/evydence" +"$cli" release manifest \ + --out "$distdir/evydence-release-manifest.json" \ + "$distdir"/evydence_${tag}_*.tar.gz \ + "$distdir"/evydence_${tag}_*.zip \ + "$distdir/openapi.yaml" \ + "$distdir/openapi.sha256" \ + "$distdir/coverage.out" \ + "$distdir/release-check-summary.txt" \ + "$distdir/migrations.sha256" \ + "$distdir/release-notes.md" \ + "$distdir/SHA256SUMS" +"$cli" release sign \ + --manifest "$distdir/evydence-release-manifest.json" \ + --private-key "$signing_key" \ + --out "$distdir/evydence-release-manifest.sig.json" +rm -f "$signing_key" +"$cli" release verify \ + --manifest "$distdir/evydence-release-manifest.json" \ + --signature "$distdir/evydence-release-manifest.sig.json" + +scripts/release_candidate_validate.sh "$tag" +echo "release candidate package written: ${distdir}" diff --git a/scripts/release_candidate_validate.sh b/scripts/release_candidate_validate.sh new file mode 100755 index 0000000..714f20e --- /dev/null +++ b/scripts/release_candidate_validate.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +set -euo pipefail + +repo_root="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)" +cd "$repo_root" + +tag="${1:-}" +if [[ -z "$tag" ]]; then + echo "usage: scripts/release_candidate_validate.sh " >&2 + exit 2 +fi +if [[ ! "$tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$ ]]; then + echo "release candidate tag must look like v0.1.0-rc.1" >&2 + exit 2 +fi + +distdir="dist/${tag}" +if [[ ! -d "$distdir" ]]; then + echo "release candidate dist directory missing: $distdir" >&2 + exit 2 +fi + +required=( + "SHA256SUMS" + "openapi.yaml" + "openapi.sha256" + "migrations.sha256" + "coverage.out" + "release-check-summary.txt" + "release-notes.md" + "evydence-release-manifest.json" + "evydence-release-manifest.sig.json" + "evydence_${tag}_linux_amd64.tar.gz" + "evydence_${tag}_linux_arm64.tar.gz" + "evydence_${tag}_darwin_amd64.tar.gz" + "evydence_${tag}_darwin_arm64.tar.gz" + "evydence_${tag}_windows_amd64.zip" +) +for file in "${required[@]}"; do + if [[ ! -f "$distdir/$file" ]]; then + echo "release candidate artifact missing: $distdir/$file" >&2 + exit 2 + fi +done + +(cd "$distdir" && sha256sum -c SHA256SUMS >/dev/null) +(cd "$distdir" && sha256sum -c openapi.sha256 >/dev/null) +sha256sum -c "$distdir/migrations.sha256" >/dev/null + +go run ./cmd/evydence release verify \ + --manifest "$distdir/evydence-release-manifest.json" \ + --signature "$distdir/evydence-release-manifest.sig.json" >/dev/null + +grep -F "Controlled self-hosted production candidate" "$distdir/release-notes.md" >/dev/null +grep -F "not legal compliance proof" "$distdir/release-notes.md" >/dev/null +grep -F "not a certification" "$distdir/release-notes.md" >/dev/null +grep -F "not a secure-release guarantee" "$distdir/release-notes.md" >/dev/null +grep -F "complete SBOM proof" "$distdir/release-notes.md" >/dev/null +grep -F "authoritative vulnerability coverage" "$distdir/release-notes.md" >/dev/null +grep -F "single API writer replica" "$distdir/release-notes.md" >/dev/null +grep -F "full repository decomposition" "$distdir/release-notes.md" >/dev/null + +if grep -R -i "automatically compliant\|certified secure\|legally sufficient\|SBOM is complete\|all vulnerabilities detected\|scanner findings are authoritative\|regulator-ready without review" "$distdir/release-notes.md" >/dev/null; then + echo "release notes contain a prohibited product claim" >&2 + exit 2 +fi +if find "$distdir" -type f \( -name "*.key" -o -name "*.pem" -o -name "*.p12" -o -name "*.pfx" \) | grep . >/dev/null; then + echo "release candidate artifact directory contains private key material" >&2 + exit 2 +fi + +echo "release candidate evidence validated: $tag" From e34396089d96240304dfad85a473f77ec06d1ae4 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sat, 30 May 2026 08:10:57 +0300 Subject: [PATCH 123/287] docs: align release candidate evidence workflow --- .github/workflows/release-artifacts.yml | 87 +++---------------------- CHANGELOG.md | 3 + RELEASE_EVIDENCE.md | 6 ++ docs/reference/release-candidate.md | 19 ++++-- docs/reference/release-validation.md | 35 +++++++--- 5 files changed, 58 insertions(+), 92 deletions(-) diff --git a/.github/workflows/release-artifacts.yml b/.github/workflows/release-artifacts.yml index 01164bd..d8fd631 100644 --- a/.github/workflows/release-artifacts.yml +++ b/.github/workflows/release-artifacts.yml @@ -40,7 +40,8 @@ jobs: env: EVYDENCE_API_KEY_PEPPER: ci-test-pepper EVYDENCE_TEST_DATABASE_URL: postgres://evydence:change-me@localhost:5432/evydence?sslmode=disable - RELEASE_SIGNING_PRIVATE_KEY_B64: ${{ secrets.EVYDENCE_RELEASE_SIGNING_PRIVATE_KEY_B64 }} + EVYDENCE_RELEASE_SIGNING_PRIVATE_KEY_B64: ${{ secrets.EVYDENCE_RELEASE_SIGNING_PRIVATE_KEY_B64 }} + EVYDENCE_RELEASE_ALLOW_EXISTING_TAG: ${{ github.ref_type == 'tag' && '1' || '0' }} steps: - name: Check out repository uses: actions/checkout@v5 @@ -72,96 +73,28 @@ jobs: - name: Install QA tools run: make tools - - name: Run production gate - run: make production-check - - name: Require release signing secret shell: bash run: | set -euo pipefail - if [[ -z "${RELEASE_SIGNING_PRIVATE_KEY_B64}" ]]; then + if [[ -z "${EVYDENCE_RELEASE_SIGNING_PRIVATE_KEY_B64}" ]]; then echo "EVYDENCE_RELEASE_SIGNING_PRIVATE_KEY_B64 secret is required to sign release artifacts" >&2 exit 2 fi - - name: Build release archives - shell: bash - run: | - set -euo pipefail - version="${{ steps.release.outputs.tag }}" - mkdir -p dist tmp/release - commands=(evydence evydence-api evydence-worker evydence-migrate) - targets=(linux/amd64 linux/arm64 darwin/amd64 darwin/arm64 windows/amd64) - for target in "${targets[@]}"; do - goos="${target%/*}" - goarch="${target#*/}" - outdir="tmp/release/evydence_${version}_${goos}_${goarch}" - mkdir -p "${outdir}" - for command in "${commands[@]}"; do - suffix="" - if [[ "${goos}" == "windows" ]]; then - suffix=".exe" - fi - GOOS="${goos}" GOARCH="${goarch}" CGO_ENABLED=0 \ - go build -trimpath -ldflags "-s -w" \ - -o "${outdir}/${command}${suffix}" "./cmd/${command}" - done - cp LICENSE README.md "${outdir}/" - if [[ "${goos}" == "windows" ]]; then - (cd tmp/release && zip -qr "../../dist/evydence_${version}_${goos}_${goarch}.zip" "evydence_${version}_${goos}_${goarch}") - else - tar -C tmp/release -czf "dist/evydence_${version}_${goos}_${goarch}.tar.gz" "evydence_${version}_${goos}_${goarch}" - fi - done - cp openapi.yaml dist/openapi.yaml - cp coverage.out dist/coverage.out - cp tmp/release-check-summary.txt dist/release-check-summary.txt - find migrations -type f -print | LC_ALL=C sort | xargs sha256sum > dist/migrations.sha256 - (cd dist && sha256sum evydence_${version}_*.tar.gz evydence_${version}_*.zip openapi.yaml coverage.out release-check-summary.txt migrations.sha256 > SHA256SUMS) - - - name: Create and sign release manifest + - name: Package signed release candidate shell: bash run: | set -euo pipefail - install -m 700 -d tmp/release-signing - signing_key="tmp/release-signing/private.key" - umask 077 - printf '%s' "${RELEASE_SIGNING_PRIVATE_KEY_B64}" > "${signing_key}" - tar -xzf "dist/evydence_${{ steps.release.outputs.tag }}_linux_amd64.tar.gz" -C tmp/release-signing - cli="tmp/release-signing/evydence_${{ steps.release.outputs.tag }}_linux_amd64/evydence" - "${cli}" release manifest \ - --out dist/evydence-release-manifest.json \ - dist/evydence_${{ steps.release.outputs.tag }}_*.tar.gz \ - dist/evydence_${{ steps.release.outputs.tag }}_*.zip \ - dist/openapi.yaml \ - dist/coverage.out \ - dist/release-check-summary.txt \ - dist/migrations.sha256 \ - dist/SHA256SUMS - "${cli}" release sign \ - --manifest dist/evydence-release-manifest.json \ - --private-key "${signing_key}" \ - --out dist/evydence-release-manifest.sig.json - rm -f "${signing_key}" - "${cli}" release verify \ - --manifest dist/evydence-release-manifest.json \ - --signature dist/evydence-release-manifest.sig.json - - - name: Write release notes - shell: bash - run: | - set -euo pipefail - cat > dist/release-notes.md <<'NOTES' - Evydence release artifacts include binaries, checksums, the OpenAPI contract, migration checksums, coverage output, a release-check summary, a signed release artifact manifest, and verification metadata. - - This release evidence supports engineering review of technical evidence handling. It is not legal compliance proof, certification, a secure-release guarantee, complete SBOM proof, or authoritative vulnerability coverage. - NOTES + # scripts/release_candidate_package.sh runs make production-check before artifact packaging. + # The generated dist// evidence set includes evydence-release-manifest.sig.json. + scripts/release_candidate_package.sh "${{ steps.release.outputs.tag }}" - name: Upload packaged release evidence uses: actions/upload-artifact@v7 with: name: evydence-release-artifacts-${{ steps.release.outputs.tag }} - path: dist/ + path: dist/${{ steps.release.outputs.tag }}/ if-no-files-found: error - name: Create or update draft GitHub release @@ -173,7 +106,7 @@ jobs: set -euo pipefail tag="${{ steps.release.outputs.tag }}" if gh release view "${tag}" >/dev/null 2>&1; then - gh release upload "${tag}" dist/* --clobber + gh release upload "${tag}" dist/${tag}/* --clobber else - gh release create "${tag}" dist/* --draft --title "Evydence ${tag}" --notes-file dist/release-notes.md + gh release create "${tag}" dist/${tag}/* --draft --title "Evydence ${tag}" --notes-file "dist/${tag}/release-notes.md" fi diff --git a/CHANGELOG.md b/CHANGELOG.md index 300cf90..5bd5318 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,9 @@ Release-candidate tagging requires the production gate and checklist in - Production-readiness profile, production gate, and coverage-threshold gate. - Release-candidate checklist requiring production-check evidence, checksums, signed artifact manifests, release notes, and documented limitations. +- Release-candidate package gate for `v0.1.0-rc.1` artifacts, checksums, + OpenAPI and migration checksums, checked release notes, signed release + manifest, and manifest signature. - Focused PostgreSQL critical mutations for tenants, credential hashes, idempotency records, audit-chain entries, release bundles, signatures, verification results, provider verification receipts, vulnerability diff --git a/RELEASE_EVIDENCE.md b/RELEASE_EVIDENCE.md index aa6b54f..99fca26 100644 --- a/RELEASE_EVIDENCE.md +++ b/RELEASE_EVIDENCE.md @@ -28,6 +28,12 @@ requires live PostgreSQL through `EVYDENCE_TEST_DATABASE_URL`, enforces the coverage threshold, and runs a local release artifact signing smoke test. A failure means the build has not yet met the self-hosted production profile. +`make release-candidate-check TAG=v0.1.0-rc.1` is the controlled release +candidate packaging gate. It requires a clean worktree, live PostgreSQL, and +release signing material, then writes release archives, checksums, OpenAPI and +migration checksums, coverage output, release-check summary, checked release +notes, a signed release manifest, and a manifest signature under `dist//`. + Release-candidate tagging is documented in [`docs/reference/release-candidate.md`](docs/reference/release-candidate.md). The required evidence set is a passing production-check summary, coverage diff --git a/docs/reference/release-candidate.md b/docs/reference/release-candidate.md index 1075891..7bb9dce 100644 --- a/docs/reference/release-candidate.md +++ b/docs/reference/release-candidate.md @@ -28,16 +28,23 @@ Before creating a release-candidate tag, collect: Run from a clean checkout with a disposable PostgreSQL database: ```sh -make production-check -sha256sum openapi.yaml > tmp/openapi.sha256 -find migrations -type f -print0 | sort -z | xargs -0 sha256sum > tmp/migrations.sha256 +set -a; . ./.test.env; set +a +export EVYDENCE_RELEASE_SIGNING_PRIVATE_KEY_B64="$(cat evydence-release-private.key)" +make release-candidate-check TAG=v0.1.0-rc.1 ``` -Build release artifacts through the release-artifacts workflow or an equivalent -local process that records the same manifest, checksums, and signature files. +The target runs `scripts/release_candidate_package.sh`, which requires a clean +worktree, a release-candidate tag such as `v0.1.0-rc.1`, no existing local tag +unless the CI tag workflow explicitly allows it, live PostgreSQL through +`EVYDENCE_TEST_DATABASE_URL`, and release signing material. It runs +`make production-check`, builds the release archive matrix, writes checksums, +signs the release manifest, verifies the manifest signature, and validates the +release-note language. + Do not tag from a run where live PostgreSQL checks, migration compatibility, coverage threshold enforcement, OpenAPI checks, docs checks, deployment checks, -SDK checks, lint, gosec, govulncheck, or race tests were skipped. +SDK checks, lint, gosec, govulncheck, race tests, artifact checksums, or +manifest signature verification were skipped. ## Supported Profile Statement diff --git a/docs/reference/release-validation.md b/docs/reference/release-validation.md index ea3e687..0a741ad 100644 --- a/docs/reference/release-validation.md +++ b/docs/reference/release-validation.md @@ -62,6 +62,22 @@ Do not use release-candidate evidence as legal compliance proof, certification, complete vulnerability coverage, complete SBOM proof, secure-release proof, or auditor/regulator acceptance. +The local packaging gate is: + +```sh +set -a; . ./.test.env; set +a +export EVYDENCE_RELEASE_SIGNING_PRIVATE_KEY_B64="$(cat evydence-release-private.key)" +make release-candidate-check TAG=v0.1.0-rc.1 +``` + +`scripts/release_candidate_package.sh` creates `dist/v0.1.0-rc.1/` with the +release archives, `SHA256SUMS`, `openapi.sha256`, `migrations.sha256`, +`coverage.out`, `release-check-summary.txt`, checked release notes, signed +release manifest, and manifest signature. It refuses dirty worktrees, invalid +release-candidate tags, missing live PostgreSQL configuration, missing signing +material, and existing local tags unless a CI tag build explicitly sets +`EVYDENCE_RELEASE_ALLOW_EXISTING_TAG=1`. + ## Configured Live PostgreSQL Profile For the scripted local profile, run: @@ -110,10 +126,11 @@ signing-key material, or other real secrets. ## Signed Release Artifact Workflow -The checked-in `.github/workflows/release-artifacts.yml` workflow packages -self-contained release archives for the CLI, API, worker, and migration -commands on Linux, macOS, and Windows targets. It runs `make production-check` -against disposable PostgreSQL before building artifacts. +The checked-in `.github/workflows/release-artifacts.yml` workflow calls the +same release-candidate package script used locally. It packages self-contained +release archives for the CLI, API, worker, and migration commands on Linux, +macOS, and Windows targets. The script runs `make production-check` against +disposable PostgreSQL before building artifacts. The workflow requires this repository secret: @@ -132,11 +149,11 @@ The value must be the base64 Ed25519 private key generated by: The private key is written only to a temporary file with restrictive permissions inside the workflow, used to produce `evydence-release-manifest.sig.json`, and then removed. The uploaded artifact -set includes binaries, checksums, `openapi.yaml`, migration checksums, -`coverage.out`, `tmp/release-check-summary.txt`, the release manifest, and the -manifest signature. Tag pushes create or update a draft GitHub release; manual -runs can upload only the workflow artifact unless `upload_draft_release` is -enabled. +set includes binaries, checksums, `openapi.yaml`, `openapi.sha256`, migration +checksums, `coverage.out`, `release-check-summary.txt`, checked release notes, +the release manifest, and the manifest signature. Tag pushes create or update a +draft GitHub release; manual runs can upload only the workflow artifact unless +`upload_draft_release` is enabled. These artifacts support reproducible engineering review. They are not legal compliance proof, certification, a secure-release guarantee, complete SBOM From d06ae81861b072bb420857ec199a6d83360ec6fe Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sat, 30 May 2026 08:14:41 +0300 Subject: [PATCH 124/287] docs: clarify release candidate API writer limit --- docs/reference/release-notes-v0.1.0-rc.1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/release-notes-v0.1.0-rc.1.md b/docs/reference/release-notes-v0.1.0-rc.1.md index 9a69db2..222afeb 100644 --- a/docs/reference/release-notes-v0.1.0-rc.1.md +++ b/docs/reference/release-notes-v0.1.0-rc.1.md @@ -11,7 +11,7 @@ acceptance. ## Supported Profile - Self-hosted API, worker, PostgreSQL, and object storage deployment. -- One API writer replica for the current production profile. +- Use a single API writer replica for the current production profile. - Worker replicas may scale through PostgreSQL outbox row locking. - External TLS, secret management, backup automation, monitoring, and incident response remain operator responsibilities. From dfca3cf3cedd572fa7d5abb7cd7bd387d35bd340 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sat, 30 May 2026 08:27:11 +0300 Subject: [PATCH 125/287] fix: make release note validation case insensitive --- scripts/release_candidate_validate.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/scripts/release_candidate_validate.sh b/scripts/release_candidate_validate.sh index 714f20e..7ebdc6b 100755 --- a/scripts/release_candidate_validate.sh +++ b/scripts/release_candidate_validate.sh @@ -51,14 +51,14 @@ go run ./cmd/evydence release verify \ --manifest "$distdir/evydence-release-manifest.json" \ --signature "$distdir/evydence-release-manifest.sig.json" >/dev/null -grep -F "Controlled self-hosted production candidate" "$distdir/release-notes.md" >/dev/null -grep -F "not legal compliance proof" "$distdir/release-notes.md" >/dev/null -grep -F "not a certification" "$distdir/release-notes.md" >/dev/null -grep -F "not a secure-release guarantee" "$distdir/release-notes.md" >/dev/null -grep -F "complete SBOM proof" "$distdir/release-notes.md" >/dev/null -grep -F "authoritative vulnerability coverage" "$distdir/release-notes.md" >/dev/null -grep -F "single API writer replica" "$distdir/release-notes.md" >/dev/null -grep -F "full repository decomposition" "$distdir/release-notes.md" >/dev/null +grep -Fi "Controlled self-hosted production candidate" "$distdir/release-notes.md" >/dev/null +grep -Fi "not legal compliance proof" "$distdir/release-notes.md" >/dev/null +grep -Fi "not a certification" "$distdir/release-notes.md" >/dev/null +grep -Fi "not a secure-release guarantee" "$distdir/release-notes.md" >/dev/null +grep -Fi "complete SBOM proof" "$distdir/release-notes.md" >/dev/null +grep -Fi "authoritative vulnerability coverage" "$distdir/release-notes.md" >/dev/null +grep -Fi "single API writer replica" "$distdir/release-notes.md" >/dev/null +grep -Fi "full repository decomposition" "$distdir/release-notes.md" >/dev/null if grep -R -i "automatically compliant\|certified secure\|legally sufficient\|SBOM is complete\|all vulnerabilities detected\|scanner findings are authoritative\|regulator-ready without review" "$distdir/release-notes.md" >/dev/null; then echo "release notes contain a prohibited product claim" >&2 From d27bf6dc4cd54dc9ca8fd857ca9b5229012b1c7f Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 09:36:24 +0300 Subject: [PATCH 126/287] feat: add focused release ledger mutations --- cmd/evydence-worker/main.go | 20 ++ cmd/evydence-worker/main_test.go | 50 +++++ internal/adapters/postgres/store.go | 71 +++++++ internal/adapters/postgres/store_test.go | 235 ++++++++++++++++++++++ internal/app/critical_mutation_test.go | 191 ++++++++++++++++++ internal/app/implementation_increments.go | 2 +- internal/app/ledger.go | 36 ++-- internal/app/ports.go | 20 ++ internal/app/risk_workflows.go | 4 +- internal/app/state.go | 71 +++++++ internal/app/vex.go | 6 +- 11 files changed, 678 insertions(+), 28 deletions(-) diff --git a/cmd/evydence-worker/main.go b/cmd/evydence-worker/main.go index 401e0ae..ae791dd 100644 --- a/cmd/evydence-worker/main.go +++ b/cmd/evydence-worker/main.go @@ -134,6 +134,11 @@ type jobStateStore interface { SaveState(context.Context, app.PersistedState) error } +type jobReleaseLedgerMutationStore interface { + jobStateLoader + ApplyReleaseLedgerMutation(context.Context, app.ReleaseLedgerMutation) error +} + type jobObjectGetter interface { Get(context.Context, string) (app.Object, error) } @@ -317,6 +322,12 @@ func processJobInternal(ctx context.Context, state jobStateLoader, objects jobOb return errors.New("unsupported outbox job kind") } if stateChanged { + if focused, ok := state.(jobReleaseLedgerMutationStore); ok && releaseLedgerParserJob(job.Kind) { + if err := focused.ApplyReleaseLedgerMutation(ctx, app.ReleaseLedgerMutationFromState(snapshot)); err != nil { + return errors.New("persist durable parser side effects") + } + return nil + } stateStore, ok := state.(jobStateStore) if !ok { return errors.New("durable parser side effects require writable state") @@ -328,6 +339,15 @@ func processJobInternal(ctx context.Context, state jobStateLoader, objects jobOb return nil } +func releaseLedgerParserJob(kind string) bool { + switch kind { + case "parse_sbom", "parse_vulnerability_scan", "parse_openapi_contract", "parse_vex": + return true + default: + return false + } +} + func requireParserVersion(job postgres.ClaimedJob) error { expected, ok := expectedParserVersions[job.Kind] if !ok { diff --git a/cmd/evydence-worker/main_test.go b/cmd/evydence-worker/main_test.go index 8cad288..36d04f2 100644 --- a/cmd/evydence-worker/main_test.go +++ b/cmd/evydence-worker/main_test.go @@ -44,6 +44,28 @@ func (f *fakeStateStore) SaveState(_ context.Context, state app.PersistedState) return nil } +type fakeReleaseLedgerMutationStore struct { + state app.PersistedState + mutation app.ReleaseLedgerMutation + saveCalls int + ok bool + err error +} + +func (f *fakeReleaseLedgerMutationStore) LoadState(context.Context) (app.PersistedState, bool, error) { + return f.state, f.ok, f.err +} + +func (f *fakeReleaseLedgerMutationStore) ApplyReleaseLedgerMutation(_ context.Context, mutation app.ReleaseLedgerMutation) error { + f.mutation = mutation + return nil +} + +func (f *fakeReleaseLedgerMutationStore) SaveState(context.Context, app.PersistedState) error { + f.saveCalls++ + return nil +} + type fakeObjectGetter struct { object app.Object err error @@ -102,6 +124,34 @@ func TestProcessJobWithObjectsPersistsParserDerivedFields(t *testing.T) { } } +func TestProcessJobWithObjectsUsesFocusedReleaseLedgerMutationForParserSideEffects(t *testing.T) { + body := []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","components":[{"name":"api","version":"1.0.0"}]}`) + hash := digestBytes(body) + job := postgres.ClaimedJob{ + TenantID: "ten_test", + Kind: "parse_sbom", + SubjectID: "sbom_test", + Payload: map[string]any{"payload_ref": "object://tenants/ten_test/payloads/sbom.json", "payload_hash": hash}, + } + store := &fakeReleaseLedgerMutationStore{ + ok: true, + state: app.PersistedState{SBOMs: map[string]domain.SBOM{ + "sbom_test": {ID: "sbom_test", TenantID: "ten_test"}, + }}, + } + object := app.Object{Key: "tenants/ten_test/payloads/sbom.json", TenantID: "ten_test", Digest: hash, Bytes: body} + if err := processJobWithObjects(context.Background(), store, fakeObjectGetter{object: object}, job); err != nil { + t.Fatalf("process object-backed job: %v", err) + } + if store.saveCalls != 0 || len(store.mutation.SBOMs) != 1 { + t.Fatalf("focused parser persistence save=%d mutation=%#v", store.saveCalls, store.mutation) + } + updated := store.mutation.SBOMs[0] + if updated.SpecVersion != "1.6" || updated.ComponentCount != 1 || len(updated.Components) != 1 { + t.Fatalf("focused sbom mutation = %#v", updated) + } +} + func TestProcessJobWithObjectsRequiresWritableStateForParserSideEffects(t *testing.T) { body := []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","components":[{"name":"api"}]}`) hash := digestBytes(body) diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index ba7df50..ad5a619 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -2564,6 +2564,36 @@ func (s *Store) ApplyCriticalMutation(ctx context.Context, mutation app.Critical return nil } +func (s *Store) ApplyReleaseLedgerMutation(ctx context.Context, mutation app.ReleaseLedgerMutation) error { + tx, err := s.pool.BeginTx(ctx, pgx.TxOptions{}) + if err != nil { + return fmt.Errorf("begin release ledger mutation transaction: %w", err) + } + defer func() { _ = tx.Rollback(ctx) }() + state := releaseLedgerMutationState(mutation) + if err := syncReleaseLedgerCore(ctx, tx, state); err != nil { + return err + } + if err := syncRiskBuildControlRows(ctx, tx, state); err != nil { + return err + } + if err := syncSourceDeploymentLifecycleRows(ctx, tx, state); err != nil { + return err + } + for _, job := range mutation.OutboxJobs { + if err := insertOutboxJobTx(ctx, tx, job); err != nil { + return err + } + } + if err := syncCriticalResourceIndex(ctx, tx, state); err != nil { + return err + } + if err := tx.Commit(ctx); err != nil { + return fmt.Errorf("commit release ledger mutation transaction: %w", err) + } + return nil +} + func criticalMutationState(mutation app.CriticalMutation) app.PersistedState { state := relationalEmptyState() for _, tenant := range mutation.Tenants { @@ -2620,6 +2650,47 @@ func criticalMutationState(mutation app.CriticalMutation) app.PersistedState { return state } +func releaseLedgerMutationState(mutation app.ReleaseLedgerMutation) app.PersistedState { + state := relationalEmptyState() + for _, product := range mutation.Products { + state.Products[product.ID] = product + } + for _, project := range mutation.Projects { + state.Projects[project.ID] = project + } + for _, release := range mutation.Releases { + state.Releases[release.ID] = release + } + for _, artifact := range mutation.Artifacts { + state.Artifacts[artifact.ID] = artifact + } + for _, evidence := range mutation.Evidence { + state.Evidence[evidence.ID] = evidence + } + for _, event := range mutation.EvidenceLifecycle { + state.EvidenceLifecycle[event.ID] = event + } + for _, sbom := range mutation.SBOMs { + state.SBOMs[sbom.ID] = sbom + } + for _, scan := range mutation.Scans { + state.Scans[scan.ID] = scan + } + for _, contract := range mutation.Contracts { + state.Contracts[contract.ID] = contract + } + for _, vex := range mutation.VEXDocuments { + state.VEXDocuments[vex.ID] = vex + } + for _, decision := range mutation.VulnerabilityDecisions { + state.Decisions[decision.ID] = decision + } + for _, entry := range mutation.AuditChainEntries { + state.Chain[entry.TenantID] = append(state.Chain[entry.TenantID], entry) + } + return state +} + func syncReleaseLedgerCore(ctx context.Context, tx pgx.Tx, state app.PersistedState) error { for _, product := range state.Products { if product.ID == "" || product.TenantID == "" { diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index 683d4e3..414a48f 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -932,6 +932,241 @@ func TestApplyCriticalMutationWithPostgres(t *testing.T) { } } +func TestApplyReleaseLedgerMutationWithPostgres(t *testing.T) { + databaseURL := os.Getenv("EVYDENCE_TEST_DATABASE_URL") + if databaseURL == "" { + t.Skip("EVYDENCE_TEST_DATABASE_URL is not set") + } + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + admin, err := Open(ctx, databaseURL) + if err != nil { + t.Fatal(err) + } + defer admin.Close() + schema := "evydence_release_mutation_" + strings.ReplaceAll(time.Now().Format("150405.000000000"), ".", "_") + quotedSchema := pgx.Identifier{schema}.Sanitize() + if _, err := admin.pool.Exec(ctx, "CREATE SCHEMA "+quotedSchema); err != nil { + t.Fatal(err) + } + defer func(cleanupCtx context.Context) { + _, _ = admin.pool.Exec(cleanupCtx, "DROP SCHEMA "+quotedSchema+" CASCADE") + }(context.WithoutCancel(ctx)) + + store, err := OpenWithOptions(ctx, databaseURLWithSearchPath(t, databaseURL, schema), StoreOptions{LoadMode: LoadModeRelationalOnly, DisableSnapshotWrites: true}) + if err != nil { + t.Fatal(err) + } + defer store.Close() + if _, err := store.ApplyMigrations(ctx, "../../../migrations"); err != nil { + t.Fatal(err) + } + + now := time.Now().UTC() + if err := store.ApplyCriticalMutation(ctx, app.CriticalMutation{ + Tenants: []domain.Tenant{{ID: "ten_release_focus", Name: "Release Focus", CreatedAt: now}}, + }); err != nil { + t.Fatalf("seed tenant: %v", err) + } + hash := "sha256:" + strings.Repeat("a", 64) + chainHash := "sha256:" + strings.Repeat("b", 64) + mutation := app.ReleaseLedgerMutation{ + Products: []domain.Product{{ + ID: "prod_focus", TenantID: "ten_release_focus", Name: "Payments", Slug: "payments", CreatedAt: now, + }}, + Projects: []domain.Project{{ + ID: "proj_focus", TenantID: "ten_release_focus", ProductID: "prod_focus", Name: "API", CreatedAt: now, + }}, + Releases: []domain.Release{{ + ID: "rel_focus", TenantID: "ten_release_focus", ProductID: "prod_focus", Version: "1.0.0", State: "approved", + FrozenAt: ptrTime(now), ApprovedAt: ptrTime(now), CreatedAt: now, + }}, + Artifacts: []domain.Artifact{{ + ID: "art_focus", TenantID: "ten_release_focus", Name: "api.tar.gz", MediaType: "application/gzip", Size: 42, + Digest: hash, CreatedAt: now, + }}, + Evidence: []domain.EvidenceItem{{ + ID: "ev_focus", TenantID: "ten_release_focus", ProductID: "prod_focus", ProjectID: "proj_focus", ReleaseID: "rel_focus", + Type: "sbom", Subtype: "cyclonedx", Title: "SBOM", SourceSystem: "api", ObservedAt: now, + EvidenceVersion: 1, SchemaVersion: domain.EvidenceItemSchemaVersion, PayloadHash: hash, CanonicalHash: hash, + Canonicalization: domain.CanonicalizationProfileVersion, TrustLevel: "L2", VerificationStatus: "pending", + SubjectRefs: []domain.SubjectRef{{Type: "artifact", ID: "art_focus"}}, CreatedAt: now, + }}, + EvidenceLifecycle: []domain.EvidenceLifecycleEvent{{ + ID: "elc_focus", TenantID: "ten_release_focus", EvidenceID: "ev_focus", Action: "amendment", + Reason: "correct metadata", ActorID: "key_focus", SchemaVersion: domain.EvidenceLifecycleSchemaVersion, CreatedAt: now, + }}, + SBOMs: []domain.SBOM{{ + ID: "sbom_focus", TenantID: "ten_release_focus", EvidenceID: "ev_focus", ReleaseID: "rel_focus", ArtifactID: "art_focus", + Format: "cyclonedx", SpecVersion: "1.5", ComponentCount: 1, + Components: []domain.SBOMComponent{{Name: "lib", Version: "1.0.0"}}, CreatedAt: now, + }}, + Scans: []domain.VulnerabilityScan{{ + ID: "scan_focus", TenantID: "ten_release_focus", EvidenceID: "ev_focus", ReleaseID: "rel_focus", + Scanner: "generic", TargetRef: "api", Summary: map[string]int{"critical": 1}, + Findings: []domain.VulnerabilityFinding{{ID: "finding_focus", Vulnerability: "CVE-2099-0001", Component: "lib", Severity: "critical", State: "open"}}, + CreatedAt: now, + }}, + Contracts: []domain.OpenAPIContract{{ + ID: "oas_focus", TenantID: "ten_release_focus", ProductID: "prod_focus", ReleaseID: "rel_focus", + Version: "1.0.0", Hash: hash, PathCount: 1, Operations: []domain.OpenAPIOperation{{Method: "GET", Path: "/health", OperationID: "health"}}, + EvidenceID: "ev_focus", CreatedAt: now, + }}, + VEXDocuments: []domain.VEXDocument{{ + ID: "vex_focus", TenantID: "ten_release_focus", EvidenceID: "ev_focus", ReleaseID: "rel_focus", ArtifactID: "art_focus", + Format: "openvex", Author: "security", Version: "1", StatementCount: 1, + StatusSummary: map[string]int{"not_affected": 1}, SchemaVersion: domain.VEXDocumentSchemaVersion, CreatedAt: now, + }}, + VulnerabilityDecisions: []domain.VulnerabilityDecision{{ + ID: "decision_release_focus", TenantID: "ten_release_focus", FindingID: "finding_focus", ScanID: "scan_focus", + ReleaseID: "rel_focus", Vulnerability: "CVE-2099-0001", Component: "lib", Status: "not_affected", + Justification: "component_not_present", Source: "vex", EvidenceID: "ev_focus", VEXDocumentID: "vex_focus", + SchemaVersion: domain.VulnerabilityDecisionVersion, CreatedAt: now, + }}, + AuditChainEntries: []domain.AuditChainEntry{{ + ID: "chain_release_focus", TenantID: "ten_release_focus", Sequence: 1, EntryType: "evidence.created", + SubjectType: "evidence_item", SubjectID: "ev_focus", ActorType: "api_key", ActorID: "key_focus", + OccurredAt: now, PayloadHash: hash, CanonicalEntryHash: chainHash, EntryHash: chainHash, + SchemaVersion: domain.AuditChainEntrySchemaVersion, + }}, + OutboxJobs: []app.OutboxJob{{ + ID: "job_release_focus", TenantID: "ten_release_focus", Kind: "parse_sbom", + SubjectType: "sbom", SubjectID: "sbom_focus", Payload: map[string]any{"payload_hash": hash}, CreatedAt: now, + }}, + } + if err := store.ApplyReleaseLedgerMutation(ctx, mutation); err != nil { + t.Fatal(err) + } + if err := store.ApplyReleaseLedgerMutation(ctx, mutation); err != nil { + t.Fatalf("retry release ledger mutation: %v", err) + } + + var snapshotRows int + if err := store.pool.QueryRow(ctx, `SELECT count(*) FROM ledger_state`).Scan(&snapshotRows); err != nil { + t.Fatal(err) + } + if snapshotRows != 0 { + t.Fatalf("ledger_state rows = %d, want 0", snapshotRows) + } + checks := []struct { + name string + query string + }{ + {name: "product", query: `SELECT count(*) FROM products WHERE id = 'prod_focus' AND slug = 'payments'`}, + {name: "project", query: `SELECT count(*) FROM projects WHERE id = 'proj_focus' AND product_id = 'prod_focus'`}, + {name: "release", query: `SELECT count(*) FROM releases WHERE id = 'rel_focus' AND state = 'approved'`}, + {name: "artifact", query: `SELECT count(*) FROM artifacts WHERE id = 'art_focus' AND digest = '` + hash + `'`}, + {name: "evidence", query: `SELECT count(*) FROM evidence_items WHERE id = 'ev_focus' AND product_id = 'prod_focus'`}, + {name: "lifecycle", query: `SELECT count(*) FROM evidence_lifecycle_events WHERE id = 'elc_focus' AND action = 'amendment'`}, + {name: "sbom", query: `SELECT count(*) FROM sboms WHERE id = 'sbom_focus' AND component_count = 1`}, + {name: "scan", query: `SELECT count(*) FROM vulnerability_scans WHERE id = 'scan_focus' AND release_id = 'rel_focus'`}, + {name: "contract", query: `SELECT count(*) FROM openapi_contracts WHERE id = 'oas_focus' AND path_count = 1`}, + {name: "vex", query: `SELECT count(*) FROM vex_documents WHERE id = 'vex_focus' AND statement_count = 1`}, + {name: "decision", query: `SELECT count(*) FROM vulnerability_decisions WHERE id = 'decision_release_focus' AND status = 'not_affected'`}, + {name: "audit chain", query: `SELECT count(*) FROM audit_chain_entries WHERE id = 'chain_release_focus'`}, + {name: "outbox", query: `SELECT count(*) FROM outbox_jobs WHERE id = 'job_release_focus' AND status = 'queued'`}, + {name: "resource index", query: `SELECT count(*) FROM resource_index WHERE tenant_id = 'ten_release_focus' AND resource_type = 'evidence_item' AND resource_id = 'ev_focus'`}, + } + for _, check := range checks { + var rows int + if err := store.pool.QueryRow(ctx, check.query).Scan(&rows); err != nil { + t.Fatalf("%s query: %v", check.name, err) + } + if rows != 1 { + t.Fatalf("%s rows = %d, want 1", check.name, rows) + } + } + var outboxRows int + if err := store.pool.QueryRow(ctx, `SELECT count(*) FROM outbox_jobs WHERE id = 'job_release_focus'`).Scan(&outboxRows); err != nil { + t.Fatal(err) + } + if outboxRows != 1 { + t.Fatalf("outbox retry rows = %d, want 1", outboxRows) + } + loaded, ok, err := store.LoadState(ctx) + if err != nil || !ok { + t.Fatalf("relational load ok=%v err=%v", ok, err) + } + if loaded.Products["prod_focus"].Slug != "payments" || loaded.Evidence["ev_focus"].CanonicalHash == "" || len(loaded.EvidenceLifecycle) != 1 { + t.Fatalf("loaded release ledger core missing: product=%#v evidence=%#v lifecycle=%#v", loaded.Products["prod_focus"], loaded.Evidence["ev_focus"], loaded.EvidenceLifecycle) + } + if loaded.SBOMs["sbom_focus"].ComponentCount != 1 || loaded.Scans["scan_focus"].ReleaseID != "rel_focus" || loaded.Contracts["oas_focus"].PathCount != 1 || loaded.VEXDocuments["vex_focus"].StatementCount != 1 { + t.Fatalf("loaded parser metadata missing: sbom=%#v scan=%#v contract=%#v vex=%#v", loaded.SBOMs["sbom_focus"], loaded.Scans["scan_focus"], loaded.Contracts["oas_focus"], loaded.VEXDocuments["vex_focus"]) + } + if loaded.Decisions["decision_release_focus"].Status != "not_affected" || len(loaded.Chain["ten_release_focus"]) != 1 { + t.Fatalf("loaded decision/chain missing: decision=%#v chain=%#v", loaded.Decisions["decision_release_focus"], loaded.Chain["ten_release_focus"]) + } +} + +func TestApplyReleaseLedgerMutationRollsBackTransaction(t *testing.T) { + databaseURL := os.Getenv("EVYDENCE_TEST_DATABASE_URL") + if databaseURL == "" { + t.Skip("EVYDENCE_TEST_DATABASE_URL is not set") + } + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + admin, err := Open(ctx, databaseURL) + if err != nil { + t.Fatal(err) + } + defer admin.Close() + schema := "evydence_release_rollback_" + strings.ReplaceAll(time.Now().Format("150405.000000000"), ".", "_") + quotedSchema := pgx.Identifier{schema}.Sanitize() + if _, err := admin.pool.Exec(ctx, "CREATE SCHEMA "+quotedSchema); err != nil { + t.Fatal(err) + } + defer func(cleanupCtx context.Context) { + _, _ = admin.pool.Exec(cleanupCtx, "DROP SCHEMA "+quotedSchema+" CASCADE") + }(context.WithoutCancel(ctx)) + + store, err := OpenWithOptions(ctx, databaseURLWithSearchPath(t, databaseURL, schema), StoreOptions{LoadMode: LoadModeRelationalOnly, DisableSnapshotWrites: true}) + if err != nil { + t.Fatal(err) + } + defer store.Close() + if _, err := store.ApplyMigrations(ctx, "../../../migrations"); err != nil { + t.Fatal(err) + } + now := time.Now().UTC() + if err := store.ApplyCriticalMutation(ctx, app.CriticalMutation{ + Tenants: []domain.Tenant{{ID: "ten_release_rollback", Name: "Rollback", CreatedAt: now}}, + }); err != nil { + t.Fatalf("seed tenant: %v", err) + } + err = store.ApplyReleaseLedgerMutation(ctx, app.ReleaseLedgerMutation{ + Products: []domain.Product{{ + ID: "prod_release_rollback", TenantID: "ten_release_rollback", Name: "Rollback", Slug: "rollback", CreatedAt: now, + }}, + Projects: []domain.Project{{ + ID: "proj_release_rollback", TenantID: "ten_release_rollback", ProductID: "missing_product", Name: "Broken", CreatedAt: now, + }}, + OutboxJobs: []app.OutboxJob{{ + ID: "job_release_rollback", TenantID: "ten_release_rollback", Kind: "parse_sbom", + SubjectType: "sbom", SubjectID: "sbom_missing", CreatedAt: now, + }}, + }) + if err == nil { + t.Fatal("expected missing product to fail release ledger mutation") + } + checks := []struct { + name string + query string + }{ + {name: "product", query: `SELECT count(*) FROM products WHERE id = 'prod_release_rollback'`}, + {name: "project", query: `SELECT count(*) FROM projects WHERE id = 'proj_release_rollback'`}, + {name: "outbox", query: `SELECT count(*) FROM outbox_jobs WHERE id = 'job_release_rollback'`}, + } + for _, check := range checks { + var rows int + if queryErr := store.pool.QueryRow(ctx, check.query).Scan(&rows); queryErr != nil { + t.Fatalf("%s query: %v", check.name, queryErr) + } + if rows != 0 { + t.Fatalf("%s rows after rollback = %d, want 0", check.name, rows) + } + } +} + func TestApplyCriticalMutationRollsBackTransaction(t *testing.T) { databaseURL := os.Getenv("EVYDENCE_TEST_DATABASE_URL") if databaseURL == "" { diff --git a/internal/app/critical_mutation_test.go b/internal/app/critical_mutation_test.go index 8c22270..b44b84f 100644 --- a/internal/app/critical_mutation_test.go +++ b/internal/app/critical_mutation_test.go @@ -11,7 +11,9 @@ import ( type focusedStoreSpy struct { saveCalls int criticalCalls int + releaseCalls int mutations []CriticalMutation + releases []ReleaseLedgerMutation } func (s *focusedStoreSpy) LoadState(context.Context) (PersistedState, bool, error) { @@ -29,10 +31,18 @@ func (s *focusedStoreSpy) ApplyCriticalMutation(_ context.Context, mutation Crit return nil } +func (s *focusedStoreSpy) ApplyReleaseLedgerMutation(_ context.Context, mutation ReleaseLedgerMutation) error { + s.releaseCalls++ + s.releases = append(s.releases, mutation) + return nil +} + func (s *focusedStoreSpy) reset() { s.saveCalls = 0 s.criticalCalls = 0 + s.releaseCalls = 0 s.mutations = nil + s.releases = nil } func TestCriticalMutationStoreAvoidsAggregateSaveForMigratedFlows(t *testing.T) { @@ -176,6 +186,121 @@ func TestCriticalMutationStoreCoversSSOAndPortalSecrets(t *testing.T) { } } +func TestReleaseLedgerMutationStoreAvoidsAggregateSaveForCoreFlows(t *testing.T) { + ctx := context.Background() + store := &focusedStoreSpy{} + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow, Store: store}) + _, _, secret, err := ledger.BootstrapTenant(ctx, "Tenant", "admin", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap: %v", err) + } + actor, err := ledger.Authenticate(ctx, secret) + if err != nil { + t.Fatalf("authenticate: %v", err) + } + + store.reset() + product, err := ledger.CreateProduct(ctx, actor, "Payments API", "payments-core") + if err != nil { + t.Fatalf("create product: %v", err) + } + if store.saveCalls != 0 || store.releaseCalls != 1 || len(store.releases[0].Products) == 0 || len(store.releases[0].AuditChainEntries) == 0 { + t.Fatalf("product mutation save=%d release=%d mutation=%#v", store.saveCalls, store.releaseCalls, store.releases) + } + + store.reset() + project, err := ledger.CreateProject(ctx, actor, product.ID, "API") + if err != nil { + t.Fatalf("create project: %v", err) + } + release, err := ledger.CreateRelease(ctx, actor, product.ID, "1.0.0") + if err != nil { + t.Fatalf("create release: %v", err) + } + if _, err := ledger.FreezeRelease(ctx, actor, release.ID); err != nil { + t.Fatalf("freeze release: %v", err) + } + if _, err := ledger.ApproveRelease(ctx, actor, release.ID); err != nil { + t.Fatalf("approve release: %v", err) + } + if store.saveCalls != 0 || store.releaseCalls != 4 { + t.Fatalf("project/release save=%d release=%d mutations=%#v", store.saveCalls, store.releaseCalls, store.releases) + } + lastReleaseMutation := store.releases[len(store.releases)-1] + if len(lastReleaseMutation.Releases) == 0 || len(lastReleaseMutation.AuditChainEntries) == 0 { + t.Fatalf("release mutation incomplete: %#v", lastReleaseMutation) + } + + store.reset() + artifact, err := ledger.RegisterArtifact(ctx, actor, "api.tar.gz", "application/gzip", sampleDigest("artifact"), 42) + if err != nil { + t.Fatalf("register artifact: %v", err) + } + item, err := ledger.CreateEvidence(ctx, actor, CreateEvidenceInput{ + ProductID: product.ID, + ProjectID: project.ID, + ReleaseID: release.ID, + Type: "build", + Title: "Build evidence", + PayloadHash: sampleDigest("build"), + SubjectRefs: []domain.SubjectRef{{Type: "artifact", ID: artifact.ID}}, + }) + if err != nil { + t.Fatalf("create evidence: %v", err) + } + if _, err := ledger.RecordEvidenceLifecycleEvent(ctx, actor, item.ID, RecordEvidenceLifecycleInput{Action: lifecycleAmendment, Reason: "corrected metadata"}); err != nil { + t.Fatalf("record lifecycle: %v", err) + } + if store.saveCalls != 0 || store.releaseCalls != 3 { + t.Fatalf("artifact/evidence save=%d release=%d mutations=%#v", store.saveCalls, store.releaseCalls, store.releases) + } + last := store.releases[len(store.releases)-1] + if len(last.Evidence) == 0 || len(last.EvidenceLifecycle) == 0 || len(last.AuditChainEntries) == 0 { + t.Fatalf("evidence lifecycle mutation incomplete: %#v", last) + } +} + +func TestReleaseLedgerMutationStoreCoversParserMetadataAndOutbox(t *testing.T) { + ctx := context.Background() + store := &focusedStoreSpy{} + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow, Store: store, WorkerOwnedParserSideEffects: true}) + actor, release, artifact := setupReleaseRiskFixture(t, ledger) + + store.reset() + if _, err := ledger.UploadSBOM(ctx, actor, release.ID, artifact.ID, []byte(`{"bomFormat":"CycloneDX","specVersion":"1.5","components":[{"name":"lib","version":"1.0.0"}]}`)); err != nil { + t.Fatalf("upload sbom: %v", err) + } + if store.saveCalls != 0 || store.releaseCalls == 0 || !releaseMutationsContainSBOMAndOutbox(store.releases, "parse_sbom") { + t.Fatalf("sbom release mutations save=%d release=%d mutations=%#v", store.saveCalls, store.releaseCalls, store.releases) + } + + store.reset() + if _, err := ledger.UploadVulnerabilityScan(ctx, actor, []byte(`{"scanner":"generic","target_ref":"api","release_id":"`+release.ID+`","findings":[{"vulnerability":"CVE-0000-0001","component":"lib","severity":"critical"}]}`)); err != nil { + t.Fatalf("upload scan: %v", err) + } + if store.saveCalls != 0 || store.releaseCalls == 0 || !releaseMutationsContainScanAndOutbox(store.releases, "parse_vulnerability_scan") { + t.Fatalf("scan release mutations save=%d release=%d mutations=%#v", store.saveCalls, store.releaseCalls, store.releases) + } + + store.reset() + rawOpenAPI := []byte(`{"openapi":"3.1.0","info":{"title":"API","version":"1.0.0"},"paths":{"/health":{"get":{"responses":{"200":{"description":"ok"}}}}}}`) + if _, err := ledger.UploadOpenAPIContract(ctx, actor, release.ProductID, release.ID, "1.0.0", rawOpenAPI); err != nil { + t.Fatalf("upload openapi: %v", err) + } + if store.saveCalls != 0 || store.releaseCalls == 0 || !releaseMutationsContainContractAndOutbox(store.releases, "parse_openapi_contract") { + t.Fatalf("openapi release mutations save=%d release=%d mutations=%#v", store.saveCalls, store.releaseCalls, store.releases) + } + + store.reset() + rawVEX := []byte(`{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex","author":"security","timestamp":"2026-01-01T00:00:00Z","statements":[{"vulnerability":{"name":"CVE-0000-0001"},"products":[{"@id":"lib"}],"status":"not_affected","justification":"component_not_present","impact_statement":"not shipped"}]}`) + if _, err := ledger.UploadVEX(ctx, actor, release.ID, artifact.ID, rawVEX); err != nil { + t.Fatalf("upload vex: %v", err) + } + if store.saveCalls != 0 || store.releaseCalls == 0 || !releaseMutationsContainVEXAndOutbox(store.releases, "parse_vex") { + t.Fatalf("vex release mutations save=%d release=%d mutations=%#v", store.saveCalls, store.releaseCalls, store.releases) + } +} + func TestCriticalMutationFallsBackToAggregateSave(t *testing.T) { ctx := context.Background() store := &focusedFallbackStore{} @@ -188,6 +313,72 @@ func TestCriticalMutationFallsBackToAggregateSave(t *testing.T) { } } +func TestReleaseLedgerMutationFallsBackToAggregateSave(t *testing.T) { + ctx := context.Background() + store := &focusedFallbackStore{} + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow, Store: store}) + _, _, secret, err := ledger.BootstrapTenant(ctx, "Tenant", "admin", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap: %v", err) + } + actor, err := ledger.Authenticate(ctx, secret) + if err != nil { + t.Fatalf("authenticate: %v", err) + } + store.saveCalls = 0 + if _, err := ledger.CreateProduct(ctx, actor, "Payments API", "payments-fallback"); err != nil { + t.Fatalf("create product: %v", err) + } + if store.saveCalls != 1 { + t.Fatalf("release fallback save calls = %d", store.saveCalls) + } +} + +func releaseMutationsContainSBOMAndOutbox(mutations []ReleaseLedgerMutation, kind string) bool { + for _, mutation := range mutations { + if len(mutation.SBOMs) > 0 && releaseMutationHasOutbox(mutation, kind) { + return true + } + } + return false +} + +func releaseMutationsContainScanAndOutbox(mutations []ReleaseLedgerMutation, kind string) bool { + for _, mutation := range mutations { + if len(mutation.Scans) > 0 && releaseMutationHasOutbox(mutation, kind) { + return true + } + } + return false +} + +func releaseMutationsContainContractAndOutbox(mutations []ReleaseLedgerMutation, kind string) bool { + for _, mutation := range mutations { + if len(mutation.Contracts) > 0 && releaseMutationHasOutbox(mutation, kind) { + return true + } + } + return false +} + +func releaseMutationsContainVEXAndOutbox(mutations []ReleaseLedgerMutation, kind string) bool { + for _, mutation := range mutations { + if len(mutation.VEXDocuments) > 0 && releaseMutationHasOutbox(mutation, kind) { + return true + } + } + return false +} + +func releaseMutationHasOutbox(mutation ReleaseLedgerMutation, kind string) bool { + for _, job := range mutation.OutboxJobs { + if job.Kind == kind { + return true + } + } + return false +} + type focusedFallbackStore struct { saveCalls int } diff --git a/internal/app/implementation_increments.go b/internal/app/implementation_increments.go index 2d12953..19a0f69 100644 --- a/internal/app/implementation_increments.go +++ b/internal/app/implementation_increments.go @@ -213,7 +213,7 @@ func (l *Ledger) RecordEvidenceLifecycleEvent(ctx context.Context, actor domain. } l.lifecycle[event.ID] = event _, _ = l.appendChainLocked(actor.TenantID, "evidence."+event.Action, "evidence_item", item.ID, actorType(actor), actorID(actor), item.PayloadHash, "") - if err := l.persistLocked(ctx); err != nil { + if err := l.persistReleaseLedgerLocked(ctx, l.releaseLedgerMutationLocked()); err != nil { return domain.EvidenceLifecycleEvent{}, err } return event, nil diff --git a/internal/app/ledger.go b/internal/app/ledger.go index dd0cd85..98a043c 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -481,7 +481,7 @@ func (l *Ledger) CreateProduct(ctx context.Context, actor domain.Actor, name, sl product := domain.Product{ID: newID("prod"), TenantID: actor.TenantID, Name: name, Slug: slug, CreatedAt: l.now()} l.products[product.ID] = product _, _ = l.appendChainLocked(actor.TenantID, "product.created", "product", product.ID, "api_key", actor.KeyID, "", "") - if err := l.persistLocked(ctx); err != nil { + if err := l.persistReleaseLedgerLocked(ctx, l.releaseLedgerMutationLocked()); err != nil { return domain.Product{}, err } return product, nil @@ -529,7 +529,7 @@ func (l *Ledger) CreateProject(ctx context.Context, actor domain.Actor, productI project := domain.Project{ID: newID("proj"), TenantID: actor.TenantID, ProductID: productID, Name: name, CreatedAt: l.now()} l.projects[project.ID] = project _, _ = l.appendChainLocked(actor.TenantID, "project.created", "project", project.ID, "api_key", actor.KeyID, "", "") - if err := l.persistLocked(ctx); err != nil { + if err := l.persistReleaseLedgerLocked(ctx, l.releaseLedgerMutationLocked()); err != nil { return domain.Project{}, err } return project, nil @@ -563,7 +563,7 @@ func (l *Ledger) CreateRelease(ctx context.Context, actor domain.Actor, productI release := domain.Release{ID: newID("rel"), TenantID: actor.TenantID, ProductID: productID, Version: version, State: "draft", CreatedAt: l.now()} l.releases[release.ID] = release _, _ = l.appendChainLocked(actor.TenantID, "release.created", "release", release.ID, "api_key", actor.KeyID, "", "") - if err := l.persistLocked(ctx); err != nil { + if err := l.persistReleaseLedgerLocked(ctx, l.releaseLedgerMutationLocked()); err != nil { return domain.Release{}, err } return release, nil @@ -612,7 +612,7 @@ func (l *Ledger) FreezeRelease(ctx context.Context, actor domain.Actor, releaseI release.FrozenAt = &now l.releases[release.ID] = release _, _ = l.appendChainLocked(actor.TenantID, "release.frozen", "release", release.ID, "api_key", actor.KeyID, "", "") - if err := l.persistLocked(ctx); err != nil { + if err := l.persistReleaseLedgerLocked(ctx, l.releaseLedgerMutationLocked()); err != nil { return domain.Release{}, err } return release, nil @@ -642,7 +642,7 @@ func (l *Ledger) ApproveRelease(ctx context.Context, actor domain.Actor, release release.ApprovedAt = &now l.releases[release.ID] = release _, _ = l.appendChainLocked(actor.TenantID, "release.approved", "release", release.ID, "api_key", actor.KeyID, "", "") - if err := l.persistLocked(ctx); err != nil { + if err := l.persistReleaseLedgerLocked(ctx, l.releaseLedgerMutationLocked()); err != nil { return domain.Release{}, err } return release, nil @@ -669,7 +669,7 @@ func (l *Ledger) RegisterArtifact(ctx context.Context, actor domain.Actor, name, artifact := domain.Artifact{ID: newID("art"), TenantID: actor.TenantID, Name: name, MediaType: mediaType, Size: size, Digest: digest, CreatedAt: l.now()} l.artifacts[artifact.ID] = artifact _, _ = l.appendChainLocked(actor.TenantID, "artifact.created", "artifact", artifact.ID, "api_key", actor.KeyID, digest, "") - if err := l.persistLocked(ctx); err != nil { + if err := l.persistReleaseLedgerLocked(ctx, l.releaseLedgerMutationLocked()); err != nil { return domain.Artifact{}, err } return artifact, nil @@ -769,7 +769,7 @@ func (l *Ledger) CreateEvidence(ctx context.Context, actor domain.Actor, in Crea } item.ChainEntryID = entry.ID l.evidence[item.ID] = item - if err := l.persistLocked(ctx); err != nil { + if err := l.persistReleaseLedgerLocked(ctx, l.releaseLedgerMutationLocked()); err != nil { return domain.EvidenceItem{}, err } return item, nil @@ -854,7 +854,7 @@ func (l *Ledger) SupersedeEvidence(ctx context.Context, actor domain.Actor, id, l.evidence[item.ID] = item l.evidence[replacement.ID] = replacement _, _ = l.appendChainLocked(actor.TenantID, "evidence.superseded", "evidence_item", item.ID, "api_key", actor.KeyID, item.PayloadHash, "") - if err := l.persistLocked(ctx); err != nil { + if err := l.persistReleaseLedgerLocked(ctx, l.releaseLedgerMutationLocked()); err != nil { return domain.EvidenceItem{}, err } return item, nil @@ -905,7 +905,7 @@ func (l *Ledger) LinkEvidence(ctx context.Context, actor domain.Actor, id, targe item.RelatedEvidenceRefs = append(item.RelatedEvidenceRefs, domain.EvidenceRef{Type: targetType, ID: targetID, Relationship: "linked_to"}) l.evidence[item.ID] = item _, _ = l.appendChainLocked(actor.TenantID, "evidence.linked", "evidence_item", item.ID, "api_key", actor.KeyID, item.PayloadHash, "") - if err := l.persistLocked(ctx); err != nil { + if err := l.persistReleaseLedgerLocked(ctx, l.releaseLedgerMutationLocked()); err != nil { return domain.EvidenceItem{}, err } return item, nil @@ -991,10 +991,8 @@ func (l *Ledger) UploadSBOM(ctx context.Context, actor domain.Actor, releaseID, } l.sboms[sbom.ID] = persistedSBOM _, _ = l.appendChainLocked(actor.TenantID, chainAction, "sbom", sbom.ID, "api_key", actor.KeyID, payloadHash, "") - if err := l.enqueue(ctx, actor.TenantID, "parse_sbom", "sbom", sbom.ID, map[string]any{"payload_ref": payloadRef, "payload_hash": payloadHash, "parser_version": ParserVersionCycloneDXJSON}); err != nil { - return domain.SBOM{}, err - } - if err := l.persistLocked(ctx); err != nil { + job := l.newOutboxJob(actor.TenantID, "parse_sbom", "sbom", sbom.ID, map[string]any{"payload_ref": payloadRef, "payload_hash": payloadHash, "parser_version": ParserVersionCycloneDXJSON}) + if err := l.persistReleaseLedgerWithOutboxLocked(ctx, job); err != nil { return domain.SBOM{}, err } return sbom, nil @@ -1087,10 +1085,8 @@ func (l *Ledger) UploadVulnerabilityScan(ctx context.Context, actor domain.Actor } l.scans[scan.ID] = persistedScan _, _ = l.appendChainLocked(actor.TenantID, chainAction, "vulnerability_scan", scan.ID, "api_key", actor.KeyID, payloadHash, "") - if err := l.enqueue(ctx, actor.TenantID, "parse_vulnerability_scan", "vulnerability_scan", scan.ID, map[string]any{"payload_ref": payloadRef, "payload_hash": payloadHash, "parser_version": ParserVersionGenericVulnerabilityJSON}); err != nil { - return domain.VulnerabilityScan{}, err - } - if err := l.persistLocked(ctx); err != nil { + job := l.newOutboxJob(actor.TenantID, "parse_vulnerability_scan", "vulnerability_scan", scan.ID, map[string]any{"payload_ref": payloadRef, "payload_hash": payloadHash, "parser_version": ParserVersionGenericVulnerabilityJSON}) + if err := l.persistReleaseLedgerWithOutboxLocked(ctx, job); err != nil { return domain.VulnerabilityScan{}, err } return scan, nil @@ -1156,10 +1152,8 @@ func (l *Ledger) UploadOpenAPIContract(ctx context.Context, actor domain.Actor, } l.contracts[contract.ID] = persistedContract _, _ = l.appendChainLocked(actor.TenantID, chainAction, "openapi_contract", contract.ID, "api_key", actor.KeyID, contract.Hash, "") - if err := l.enqueue(ctx, actor.TenantID, "parse_openapi_contract", "openapi_contract", contract.ID, map[string]any{"payload_ref": payloadRef, "payload_hash": payloadHash, "parser_version": ParserVersionOpenAPIJSON}); err != nil { - return domain.OpenAPIContract{}, err - } - if err := l.persistLocked(ctx); err != nil { + job := l.newOutboxJob(actor.TenantID, "parse_openapi_contract", "openapi_contract", contract.ID, map[string]any{"payload_ref": payloadRef, "payload_hash": payloadHash, "parser_version": ParserVersionOpenAPIJSON}) + if err := l.persistReleaseLedgerWithOutboxLocked(ctx, job); err != nil { return domain.OpenAPIContract{}, err } return contract, nil diff --git a/internal/app/ports.go b/internal/app/ports.go index 2655d34..0cd23d6 100644 --- a/internal/app/ports.go +++ b/internal/app/ports.go @@ -16,6 +16,10 @@ type CriticalMutationStore interface { ApplyCriticalMutation(context.Context, CriticalMutation) error } +type ReleaseLedgerMutationStore interface { + ApplyReleaseLedgerMutation(context.Context, ReleaseLedgerMutation) error +} + type ObjectStore interface { Put(context.Context, Object) error Get(context.Context, string) (Object, error) @@ -304,6 +308,22 @@ type CriticalMutation struct { OutboxJobs []OutboxJob } +type ReleaseLedgerMutation struct { + Products []domain.Product + Projects []domain.Project + Releases []domain.Release + Artifacts []domain.Artifact + Evidence []domain.EvidenceItem + EvidenceLifecycle []domain.EvidenceLifecycleEvent + SBOMs []domain.SBOM + Scans []domain.VulnerabilityScan + Contracts []domain.OpenAPIContract + VEXDocuments []domain.VEXDocument + VulnerabilityDecisions []domain.VulnerabilityDecision + AuditChainEntries []domain.AuditChainEntry + OutboxJobs []OutboxJob +} + type nopOutbox struct{} func (nopOutbox) Enqueue(context.Context, OutboxJob) error { return nil } diff --git a/internal/app/risk_workflows.go b/internal/app/risk_workflows.go index 5296830..e42abc3 100644 --- a/internal/app/risk_workflows.go +++ b/internal/app/risk_workflows.go @@ -752,7 +752,7 @@ func (l *Ledger) UploadSPDXSBOM(ctx context.Context, actor domain.Actor, release sbom := domain.SBOM{ID: newID("sbom"), TenantID: actor.TenantID, EvidenceID: item.ID, ReleaseID: releaseID, ArtifactID: artifactID, Format: "spdx", SpecVersion: doc.SPDXVersion, ComponentCount: len(components), Components: components, CreatedAt: l.now()} l.sboms[sbom.ID] = sbom _, _ = l.appendChainLocked(actor.TenantID, "sbom.parsed", "sbom", sbom.ID, "api_key", actor.KeyID, payloadHash, "") - if err := l.persistLocked(ctx); err != nil { + if err := l.persistReleaseLedgerLocked(ctx, l.releaseLedgerMutationLocked()); err != nil { return domain.SBOM{}, err } return sbom, nil @@ -883,7 +883,7 @@ func (l *Ledger) UploadCycloneDXVEX(ctx context.Context, actor domain.Actor, rel } l.vexDocuments[vex.ID] = vex _, _ = l.appendChainLocked(actor.TenantID, "vex.parsed", "vex_document", vex.ID, "api_key", actor.KeyID, payloadHash, "") - if err := l.persistLocked(ctx); err != nil { + if err := l.persistReleaseLedgerLocked(ctx, l.releaseLedgerMutationLocked()); err != nil { return domain.VEXDocument{}, err } return vex, nil diff --git a/internal/app/state.go b/internal/app/state.go index e315ba5..84e80a9 100644 --- a/internal/app/state.go +++ b/internal/app/state.go @@ -294,10 +294,81 @@ func (l *Ledger) persistCriticalLocked(ctx context.Context, mutation CriticalMut return focused.ApplyCriticalMutation(ctx, mutation) } +func (l *Ledger) persistReleaseLedgerLocked(ctx context.Context, mutation ReleaseLedgerMutation) error { + if l.store == nil { + return nil + } + focused, ok := l.store.(ReleaseLedgerMutationStore) + if !ok { + return l.persistLocked(ctx) + } + return focused.ApplyReleaseLedgerMutation(ctx, mutation) +} + func (l *Ledger) criticalMutationLocked() CriticalMutation { return criticalMutationFromState(l.snapshotLocked()) } +func (l *Ledger) releaseLedgerMutationLocked() ReleaseLedgerMutation { + return releaseLedgerMutationFromState(l.snapshotLocked()) +} + +func ReleaseLedgerMutationFromState(state PersistedState) ReleaseLedgerMutation { + return releaseLedgerMutationFromState(state) +} + +func (l *Ledger) persistReleaseLedgerWithOutboxLocked(ctx context.Context, job OutboxJob) error { + mutation := l.releaseLedgerMutationLocked() + mutation.OutboxJobs = append(mutation.OutboxJobs, job) + if _, ok := l.store.(ReleaseLedgerMutationStore); !ok { + if err := l.enqueueJob(ctx, job); err != nil { + return err + } + } + return l.persistReleaseLedgerLocked(ctx, mutation) +} + +func releaseLedgerMutationFromState(state PersistedState) ReleaseLedgerMutation { + mutation := ReleaseLedgerMutation{} + for _, product := range state.Products { + mutation.Products = append(mutation.Products, product) + } + for _, project := range state.Projects { + mutation.Projects = append(mutation.Projects, project) + } + for _, release := range state.Releases { + mutation.Releases = append(mutation.Releases, release) + } + for _, artifact := range state.Artifacts { + mutation.Artifacts = append(mutation.Artifacts, artifact) + } + for _, evidence := range state.Evidence { + mutation.Evidence = append(mutation.Evidence, evidence) + } + for _, event := range state.EvidenceLifecycle { + mutation.EvidenceLifecycle = append(mutation.EvidenceLifecycle, event) + } + for _, sbom := range state.SBOMs { + mutation.SBOMs = append(mutation.SBOMs, sbom) + } + for _, scan := range state.Scans { + mutation.Scans = append(mutation.Scans, scan) + } + for _, contract := range state.Contracts { + mutation.Contracts = append(mutation.Contracts, contract) + } + for _, vex := range state.VEXDocuments { + mutation.VEXDocuments = append(mutation.VEXDocuments, vex) + } + for _, decision := range state.Decisions { + mutation.VulnerabilityDecisions = append(mutation.VulnerabilityDecisions, decision) + } + for _, tenantChain := range state.Chain { + mutation.AuditChainEntries = append(mutation.AuditChainEntries, tenantChain...) + } + return mutation +} + func criticalMutationFromState(state PersistedState) CriticalMutation { mutation := CriticalMutation{ APIKeyHashes: map[string]string{}, diff --git a/internal/app/vex.go b/internal/app/vex.go index f2c3b0a..b18391f 100644 --- a/internal/app/vex.go +++ b/internal/app/vex.go @@ -179,10 +179,8 @@ func (l *Ledger) UploadVEX(ctx context.Context, actor domain.Actor, releaseID, a jobPayload["actor_id"] = actorID(actor) jobPayload["evidence_id"] = item.ID } - if err := l.enqueue(ctx, actor.TenantID, "parse_vex", "vex_document", vex.ID, jobPayload); err != nil { - return domain.VEXDocument{}, err - } - if err := l.persistLocked(ctx); err != nil { + job := l.newOutboxJob(actor.TenantID, "parse_vex", "vex_document", vex.ID, jobPayload) + if err := l.persistReleaseLedgerWithOutboxLocked(ctx, job); err != nil { return domain.VEXDocument{}, err } return vex, nil From f79705cd84e0f24c6e6758ae940bf34ff7493d77 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 09:37:46 +0300 Subject: [PATCH 127/287] docs: document focused release ledger writes --- CHANGELOG.md | 4 ++++ README.md | 2 +- docs/reference/production-readiness.md | 22 +++++++++++++++------- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5bd5318..518e5ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,10 @@ Release-candidate tagging requires the production gate and checklist in idempotency records, audit-chain entries, release bundles, signatures, verification results, provider verification receipts, vulnerability decisions, and outbox jobs. +- Focused PostgreSQL release-ledger mutations for products, projects, releases, + artifacts, evidence items, evidence lifecycle events, SBOMs, vulnerability + scans, OpenAPI contracts, VEX documents, audit-chain entries, and parser + outbox jobs. ### Known Limits diff --git a/README.md b/README.md index 94050c8..f3612a6 100644 --- a/README.md +++ b/README.md @@ -109,4 +109,4 @@ make postgres-integration-test `make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. -`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required release-candidate evidence, but it does not by itself close the remaining repository decomposition, direct KMS/HSM SDK, provider API/group validation, object-lock enforcement, HA, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. Critical runtime mutations for tenants, credential hashes, idempotency, audit-chain entries, release bundles, signatures, verification results, vulnerability decisions, and outbox jobs use focused PostgreSQL write paths when available. Current self-hosted production guidance still uses a single API writer replica and allows worker replicas to scale through PostgreSQL outbox row locking. +`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required release-candidate evidence, but it does not by itself close the remaining repository decomposition, direct KMS/HSM SDK, provider API/group validation, object-lock enforcement, HA, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. Critical runtime mutations for tenants, credential hashes, idempotency, audit-chain entries, release bundles, signatures, verification results, vulnerability decisions, and outbox jobs use focused PostgreSQL write paths when available. Release-ledger and evidence-core mutations for products, projects, releases, artifacts, evidence items, evidence lifecycle events, SBOMs, vulnerability scans, OpenAPI contracts, VEX documents, audit-chain entries, and parser outbox jobs also use focused PostgreSQL write paths when available. Current self-hosted production guidance still uses a single API writer replica and allows worker replicas to scale through PostgreSQL outbox row locking. diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 4296ceb..321bb74 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -34,9 +34,13 @@ Known hardening work remains: customer-portal token hashes, idempotency records, audit-chain entries, signing keys, signatures, release bundles, verification results, provider verification receipts, vulnerability decisions, and outbox jobs now use - focused PostgreSQL transactions when that store is configured. Non-migrated - resource families still use broader aggregate persistence. If the snapshot - row is absent, the store can rebuild identity, SSO session, + focused PostgreSQL transactions when that store is configured. Release-ledger + and evidence-core mutations for products, projects, releases, artifacts, + evidence items, evidence lifecycle events, SBOMs, vulnerability scans, + OpenAPI contracts, VEX documents, audit-chain entries, and parser outbox jobs + also use focused PostgreSQL transactions when that store is configured. + Non-migrated resource families still use broader aggregate persistence. If + the snapshot row is absent, the store can rebuild identity, SSO session, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE @@ -156,8 +160,11 @@ implemented capabilities: SSO-session hashes, customer-portal token hashes, idempotency records, audit-chain entries, signing keys, signatures, release bundles, verification results, provider verification receipts, vulnerability decisions, and outbox - jobs. Relational row synchronization also covers identity, idempotency, - customer portal token, release-ledger core, build provenance, + jobs, plus release-ledger and evidence-core writes for products, projects, + releases, artifacts, evidence items, evidence lifecycle events, SBOMs, + vulnerability scans, OpenAPI contracts, VEX documents, audit-chain entries, + and parser outbox jobs. Relational row synchronization also covers identity, + idempotency, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, @@ -183,8 +190,9 @@ implemented capabilities: CycloneDX SBOM, generic vulnerability scan, OpenAPI contract, DSSE build-attestation, OpenVEX document metadata, and OpenVEX-derived vulnerability decisions can be worker-owned behind - `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; workers also persist - missing parser-derived fields for replay-compatible records. + `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; SBOM, scan, OpenAPI, and + OpenVEX replay side effects use focused release-ledger mutations when the + PostgreSQL store supports them. - Keep OpenAPI precision at zero broad operations as routes are added or changed, and expand generated SDK coverage from the committed contract. - Add direct cloud KMS/HSM SDK adapters where required. The current HTTPS From 77fc897fa25f64466d1024d90d38a06eb0ced195 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 09:51:01 +0300 Subject: [PATCH 128/287] feat: route remaining state through relational persistence --- CHANGELOG.md | 4 +- README.md | 2 +- docs/architecture.md | 2 +- docs/reference/production-readiness.md | 16 +++-- internal/adapters/postgres/store.go | 10 ++- internal/adapters/postgres/store_test.go | 61 +++++++++++++++++ internal/app/critical_mutation_test.go | 87 ++++++++++++++++++++++++ internal/app/ports.go | 4 ++ internal/app/state.go | 6 +- 9 files changed, 180 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 518e5ef..0cb8128 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,8 @@ Release-candidate tagging requires the production gate and checklist in artifacts, evidence items, evidence lifecycle events, SBOMs, vulnerability scans, OpenAPI contracts, VEX documents, audit-chain entries, and parser outbox jobs. +- Relational PostgreSQL state synchronization for remaining aggregate + persistence calls without writing the compatibility `ledger_state` snapshot. ### Known Limits @@ -41,6 +43,6 @@ Release-candidate tagging requires the production gate and checklist in - Operators remain responsible for production PostgreSQL, object storage, network policy, TLS, backups, monitoring, external signing, and incident response. -- Full repository decomposition, HA/multi-writer operation, direct KMS/HSM SDK +- Service decomposition, HA/multi-writer operation, direct KMS/HSM SDK adapters, live provider validation, broader object-lock proof, and final exit review remain production-hardening work after the release-candidate gate. diff --git a/README.md b/README.md index f3612a6..a53b6a1 100644 --- a/README.md +++ b/README.md @@ -109,4 +109,4 @@ make postgres-integration-test `make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. -`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required release-candidate evidence, but it does not by itself close the remaining repository decomposition, direct KMS/HSM SDK, provider API/group validation, object-lock enforcement, HA, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. Critical runtime mutations for tenants, credential hashes, idempotency, audit-chain entries, release bundles, signatures, verification results, vulnerability decisions, and outbox jobs use focused PostgreSQL write paths when available. Release-ledger and evidence-core mutations for products, projects, releases, artifacts, evidence items, evidence lifecycle events, SBOMs, vulnerability scans, OpenAPI contracts, VEX documents, audit-chain entries, and parser outbox jobs also use focused PostgreSQL write paths when available. Current self-hosted production guidance still uses a single API writer replica and allows worker replicas to scale through PostgreSQL outbox row locking. +`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required release-candidate evidence, but it does not by itself close the remaining service decomposition, direct KMS/HSM SDK, provider API/group validation, object-lock enforcement, HA, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. Critical runtime mutations for tenants, credential hashes, idempotency, audit-chain entries, release bundles, signatures, verification results, vulnerability decisions, and outbox jobs use focused PostgreSQL write paths when available. Release-ledger and evidence-core mutations for products, projects, releases, artifacts, evidence items, evidence lifecycle events, SBOMs, vulnerability scans, OpenAPI contracts, VEX documents, audit-chain entries, and parser outbox jobs also use focused PostgreSQL write paths when available. Remaining aggregate persistence calls use PostgreSQL relational synchronization without writing the compatibility snapshot when that store is configured. Current self-hosted production guidance still uses a single API writer replica and allows worker replicas to scale through PostgreSQL outbox row locking. diff --git a/docs/architecture.md b/docs/architecture.md index 9274dcd..1004a94 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -10,7 +10,7 @@ Evydence follows a ports-and-adapters shape: - `internal/adapters/objectstore/s3` stores the same tenant-prefixed object keys in S3/MinIO-compatible buckets. - `cmd/*` contains process entry points. -Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity, idempotency, and customer portal token records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. Collector/build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension records are synchronized into their migration-backed relational tables. Production API and worker startup defaults to relational-only reconstruction and disables compatibility snapshot writes; local development defaults to snapshot-preferred compatibility. When the PostgreSQL store is configured, critical runtime mutations for tenants, API-key hashes, SSO-session hashes, customer-portal token hashes, idempotency records, audit-chain entries, signing keys, signatures, release bundles, verification results, provider verification receipts, vulnerability decisions, and outbox jobs are written through focused transaction-backed mutations instead of relying only on aggregate `SaveState`. Non-migrated resource families still use the broader aggregate persistence path. If the snapshot row is absent, the Postgres store can rebuild identity, SSO session, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. +Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity, idempotency, and customer portal token records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. Collector/build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension records are synchronized into their migration-backed relational tables. Production API and worker startup defaults to relational-only reconstruction and disables compatibility snapshot writes; local development defaults to snapshot-preferred compatibility. When the PostgreSQL store is configured, critical runtime mutations for tenants, API-key hashes, SSO-session hashes, customer-portal token hashes, idempotency records, audit-chain entries, signing keys, signatures, release bundles, verification results, provider verification receipts, vulnerability decisions, and outbox jobs are written through focused transaction-backed mutations instead of relying only on aggregate `SaveState`. Release-ledger and evidence-core mutations use focused transaction-backed mutations, and remaining aggregate persistence calls synchronize relational rows without writing the compatibility snapshot. If the snapshot row is absent, the Postgres store can rebuild identity, SSO session, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. ## Tenant And Auth Boundaries diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 321bb74..d79c443 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -39,8 +39,10 @@ Known hardening work remains: evidence items, evidence lifecycle events, SBOMs, vulnerability scans, OpenAPI contracts, VEX documents, audit-chain entries, and parser outbox jobs also use focused PostgreSQL transactions when that store is configured. - Non-migrated resource families still use broader aggregate persistence. If - the snapshot row is absent, the store can rebuild identity, SSO session, + Remaining aggregate persistence calls now use PostgreSQL relational + synchronization without writing the compatibility snapshot when that store is + configured. If the snapshot row is absent, the store can rebuild identity, + SSO session, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE @@ -154,8 +156,8 @@ These items are tracked separately from the feature-completeness checklist in `.implementation_increments.md` because they are hardening work on already implemented capabilities: -- Continue replacing aggregate `SaveState` synchronization with - dependency-ordered relational repositories for focused resource families. +- Continue splitting the large application ledger into focused services while + preserving the dependency-ordered relational persistence paths now in place. Focused transaction-backed writes now cover tenants, API-key hashes, SSO-session hashes, customer-portal token hashes, idempotency records, audit-chain entries, signing keys, signatures, release bundles, verification @@ -183,9 +185,9 @@ implemented capabilities: provider verification, signing operation, and future-extension families from relational rows. Snapshots remain for local compatibility, export/import, and non-production migration checks. -- Split the large application ledger aggregate into focused services or - repositories once relational writes are in place, preserving tenant isolation - and append-only behavior throughout. +- Split the large application ledger aggregate into focused services once the + next service-boundary review is complete, preserving tenant isolation and + append-only behavior throughout. - Keep worker-owned parser side effects covered as parser formats evolve. CycloneDX SBOM, generic vulnerability scan, OpenAPI contract, DSSE build-attestation, OpenVEX document metadata, and OpenVEX-derived diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index ad5a619..963c2d8 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -2479,12 +2479,20 @@ func (s *Store) loadRelationalIdempotency(ctx context.Context, state *app.Persis } func (s *Store) SaveState(ctx context.Context, state app.PersistedState) error { + return s.saveState(ctx, state, !s.disableSnapshotWrites) +} + +func (s *Store) SaveRelationalState(ctx context.Context, state app.PersistedState) error { + return s.saveState(ctx, state, false) +} + +func (s *Store) saveState(ctx context.Context, state app.PersistedState, writeSnapshot bool) error { tx, err := s.pool.BeginTx(ctx, pgx.TxOptions{}) if err != nil { return fmt.Errorf("begin save ledger state transaction: %w", err) } defer func() { _ = tx.Rollback(ctx) }() - if !s.disableSnapshotWrites { + if writeSnapshot { body, err := json.Marshal(state) if err != nil { return fmt.Errorf("encode ledger state: %w", err) diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index 414a48f..18c5335 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -116,6 +116,67 @@ func TestStoreCanDisableSnapshotWritesAndLoadRelationalState(t *testing.T) { } } +func TestStoreSaveRelationalStateSkipsLedgerSnapshot(t *testing.T) { + databaseURL := os.Getenv("EVYDENCE_TEST_DATABASE_URL") + if databaseURL == "" { + t.Skip("EVYDENCE_TEST_DATABASE_URL is not set") + } + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + admin, err := Open(ctx, databaseURL) + if err != nil { + t.Fatal(err) + } + defer admin.Close() + schema := "evydence_relational_state_" + strings.ReplaceAll(strings.ToLower(time.Now().Format("20060102150405.000000000")), ".", "_") + quotedSchema := pgx.Identifier{schema}.Sanitize() + if _, err := admin.pool.Exec(ctx, "CREATE SCHEMA "+quotedSchema); err != nil { + t.Fatal(err) + } + defer func(cleanupCtx context.Context) { + _, _ = admin.pool.Exec(cleanupCtx, "DROP SCHEMA "+quotedSchema+" CASCADE") + }(context.WithoutCancel(ctx)) + + store, err := OpenWithOptions(ctx, databaseURLWithSearchPath(t, databaseURL, schema), StoreOptions{LoadMode: LoadModeRelationalPreferred}) + if err != nil { + t.Fatal(err) + } + defer store.Close() + if _, err := store.ApplyMigrations(ctx, "../../../migrations"); err != nil { + t.Fatal(err) + } + now := time.Now().UTC() + state := app.PersistedState{ + Tenants: map[string]domain.Tenant{ + "ten_relational_state": {ID: "ten_relational_state", Name: "Relational State", CreatedAt: now}, + }, + ControlFrameworks: map[string]domain.ControlFramework{ + "fw_relational_state": { + ID: "fw_relational_state", TenantID: "ten_relational_state", Name: "Framework", + Slug: "framework", Version: "1.0.0", Status: "active", + SchemaVersion: domain.ControlFrameworkSchemaVersion, CreatedAt: now, + }, + }, + } + if err := store.SaveRelationalState(ctx, state); err != nil { + t.Fatal(err) + } + var snapshotRows int + if err := store.pool.QueryRow(ctx, `SELECT count(*) FROM ledger_state`).Scan(&snapshotRows); err != nil { + t.Fatal(err) + } + if snapshotRows != 0 { + t.Fatalf("ledger_state rows = %d, want 0", snapshotRows) + } + loaded, ok, err := store.LoadState(ctx) + if err != nil || !ok { + t.Fatalf("load relational state ok=%v err=%v", ok, err) + } + if loaded.ControlFrameworks["fw_relational_state"].Slug != "framework" { + t.Fatalf("loaded frameworks = %#v", loaded.ControlFrameworks) + } +} + func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { databaseURL := os.Getenv("EVYDENCE_TEST_DATABASE_URL") if databaseURL == "" { diff --git a/internal/app/critical_mutation_test.go b/internal/app/critical_mutation_test.go index b44b84f..62f5cbe 100644 --- a/internal/app/critical_mutation_test.go +++ b/internal/app/critical_mutation_test.go @@ -391,3 +391,90 @@ func (s *focusedFallbackStore) SaveState(context.Context, PersistedState) error s.saveCalls++ return nil } + +type fullRelationalStoreSpy struct { + saveCalls int + relationalCalls int + criticalCalls int + releaseCalls int + states []PersistedState +} + +func (s *fullRelationalStoreSpy) LoadState(context.Context) (PersistedState, bool, error) { + return PersistedState{}, false, nil +} + +func (s *fullRelationalStoreSpy) SaveState(context.Context, PersistedState) error { + s.saveCalls++ + return nil +} + +func (s *fullRelationalStoreSpy) SaveRelationalState(_ context.Context, state PersistedState) error { + s.relationalCalls++ + s.states = append(s.states, state) + return nil +} + +func (s *fullRelationalStoreSpy) ApplyCriticalMutation(context.Context, CriticalMutation) error { + s.criticalCalls++ + return nil +} + +func (s *fullRelationalStoreSpy) ApplyReleaseLedgerMutation(context.Context, ReleaseLedgerMutation) error { + s.releaseCalls++ + return nil +} + +func (s *fullRelationalStoreSpy) reset() { + s.saveCalls = 0 + s.relationalCalls = 0 + s.criticalCalls = 0 + s.releaseCalls = 0 + s.states = nil +} + +func TestRelationalStateStoreAvoidsAggregateSaveForRemainingFamilies(t *testing.T) { + ctx := context.Background() + store := &fullRelationalStoreSpy{} + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow, Store: store}) + _, _, secret, err := ledger.BootstrapTenant(ctx, "Tenant", "admin", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap: %v", err) + } + actor, err := ledger.Authenticate(ctx, secret) + if err != nil { + t.Fatalf("authenticate: %v", err) + } + + store.reset() + framework, err := ledger.CreateControlFramework(ctx, actor, CreateControlFrameworkInput{Name: "CRA Readiness", Slug: "cra-readiness", Version: "1.0.0"}) + if err != nil { + t.Fatalf("create control framework: %v", err) + } + if store.saveCalls != 0 || store.relationalCalls != 1 || store.criticalCalls != 0 || store.releaseCalls != 0 { + t.Fatalf("framework persistence save=%d relational=%d critical=%d release=%d", store.saveCalls, store.relationalCalls, store.criticalCalls, store.releaseCalls) + } + if got := store.states[0].ControlFrameworks[framework.ID]; got.ID != framework.ID || got.TenantID != actor.TenantID { + t.Fatalf("relational state missed framework: %#v", got) + } + + product, err := ledger.CreateProduct(ctx, actor, "Payments", "payments-relational-state") + if err != nil { + t.Fatalf("create product: %v", err) + } + release, err := ledger.CreateRelease(ctx, actor, product.ID, "1.0.0") + if err != nil { + t.Fatalf("create release: %v", err) + } + store.reset() + incident, err := ledger.CreateIncident(ctx, actor, CreateIncidentInput{ProductID: product.ID, ReleaseID: release.ID, Title: "Incident", Severity: "high"}) + if err != nil { + t.Fatalf("create incident: %v", err) + } + if store.saveCalls != 0 || store.relationalCalls != 1 { + t.Fatalf("incident persistence save=%d relational=%d", store.saveCalls, store.relationalCalls) + } + if got := store.states[0].Incidents[incident.ID]; got.ID != incident.ID || got.TenantID != actor.TenantID { + t.Fatalf("relational state missed incident: %#v", got) + } +} diff --git a/internal/app/ports.go b/internal/app/ports.go index 0cd23d6..f0697ac 100644 --- a/internal/app/ports.go +++ b/internal/app/ports.go @@ -20,6 +20,10 @@ type ReleaseLedgerMutationStore interface { ApplyReleaseLedgerMutation(context.Context, ReleaseLedgerMutation) error } +type RelationalStateStore interface { + SaveRelationalState(context.Context, PersistedState) error +} + type ObjectStore interface { Put(context.Context, Object) error Get(context.Context, string) (Object, error) diff --git a/internal/app/state.go b/internal/app/state.go index 84e80a9..d9007df 100644 --- a/internal/app/state.go +++ b/internal/app/state.go @@ -280,7 +280,11 @@ func (l *Ledger) persistLocked(ctx context.Context) error { if l.store == nil { return nil } - return l.store.SaveState(ctx, l.snapshotLocked()) + state := l.snapshotLocked() + if relational, ok := l.store.(RelationalStateStore); ok { + return relational.SaveRelationalState(ctx, state) + } + return l.store.SaveState(ctx, state) } func (l *Ledger) persistCriticalLocked(ctx context.Context, mutation CriticalMutation) error { From 395333812ba5305e153003499677be8ca7e25c56 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 09:58:41 +0300 Subject: [PATCH 129/287] feat: add aws kms signing executor --- .api.env.example | 5 + CHANGELOG.md | 4 +- README.md | 4 +- cmd/evydence-api/main.go | 24 ++- cmd/evydence-api/main_test.go | 14 ++ docs/architecture.md | 4 +- docs/production-hardening.md | 3 +- docs/reference/configuration.md | 18 ++- docs/reference/production-readiness.md | 28 ++-- docs/reference/release-candidate.md | 6 +- docs/reference/release-notes-v0.1.0-rc.1.md | 6 +- go.mod | 15 ++ go.sum | 30 ++++ internal/adapters/signing/awskms/awskms.go | 151 ++++++++++++++++++ .../adapters/signing/awskms/awskms_test.go | 118 ++++++++++++++ 15 files changed, 401 insertions(+), 29 deletions(-) create mode 100644 internal/adapters/signing/awskms/awskms.go create mode 100644 internal/adapters/signing/awskms/awskms_test.go diff --git a/.api.env.example b/.api.env.example index 39c024b..7baa6ba 100644 --- a/.api.env.example +++ b/.api.env.example @@ -15,6 +15,11 @@ EVYDENCE_SIGNING_KEY_MODE=external # EVYDENCE_SIGNING_EXECUTOR_URL=https://signer.example.test/sign # EVYDENCE_SIGNING_EXECUTOR_TOKEN=replace-with-signing-gateway-token # EVYDENCE_SIGNING_EXECUTOR_TIMEOUT_SECONDS=10 +# Optional AWS KMS signing executor. Set EVYDENCE_SIGNING_KEY_MODE=aws-kms. +# EVYDENCE_AWS_REGION=eu-north-1 +# EVYDENCE_AWS_KMS_KEY_ID=alias/evydence-release +# EVYDENCE_AWS_KMS_SIGNING_ALGORITHM=ECDSA_SHA_256 +# EVYDENCE_AWS_KMS_TIMEOUT_SECONDS=10 # Optional OIDC discovery refresh tuning. HTTP is allowed only for localhost when explicitly enabled. # EVYDENCE_OIDC_DISCOVERY_TIMEOUT_SECONDS=10 # EVYDENCE_OIDC_DISCOVERY_ALLOW_INSECURE_LOCALHOST=false diff --git a/CHANGELOG.md b/CHANGELOG.md index 0cb8128..138e037 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,8 @@ Release-candidate tagging requires the production gate and checklist in outbox jobs. - Relational PostgreSQL state synchronization for remaining aggregate persistence calls without writing the compatibility `ledger_state` snapshot. +- AWS KMS signing executor for signing provider operations over stored + SHA-256 payload hashes without sending raw evidence payload bytes. ### Known Limits @@ -43,6 +45,6 @@ Release-candidate tagging requires the production gate and checklist in - Operators remain responsible for production PostgreSQL, object storage, network policy, TLS, backups, monitoring, external signing, and incident response. -- Service decomposition, HA/multi-writer operation, direct KMS/HSM SDK +- Service decomposition, HA/multi-writer operation, non-AWS KMS/HSM SDK adapters, live provider validation, broader object-lock proof, and final exit review remain production-hardening work after the release-candidate gate. diff --git a/README.md b/README.md index a53b6a1..8ccc778 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ This repository contains a Go implementation under module `github.com/aatuh/evyd - AGPL license, commercial licensing, governance, contribution, security, support, trademark, release-evidence, and changelog metadata. -Implemented-but-partial areas are documented explicitly: signing-provider operation receipts do not replace direct production KMS/HSM SDK adapters, SSO credential exchange uses configured local OIDC/SAML trust material and session-scoped OIDC group-role mappings but does not replace live provider API validation or external group synchronization, and public transparency records can verify operator-supplied or fetched inclusion proof material without replacing provider-specific trust review. +Implemented-but-partial areas are documented explicitly: signing-provider operation receipts can use an HTTPS signing gateway or the built-in AWS KMS executor, but additional cloud KMS/HSM providers and deployment-specific custody review remain operator work; SSO credential exchange uses configured local OIDC/SAML trust material and session-scoped OIDC group-role mappings but does not replace live provider API validation or external group synchronization; and public transparency records can verify operator-supplied or fetched inclusion proof material without replacing provider-specific trust review. ## License, Security, Support, And Governance @@ -109,4 +109,4 @@ make postgres-integration-test `make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. -`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required release-candidate evidence, but it does not by itself close the remaining service decomposition, direct KMS/HSM SDK, provider API/group validation, object-lock enforcement, HA, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. Critical runtime mutations for tenants, credential hashes, idempotency, audit-chain entries, release bundles, signatures, verification results, vulnerability decisions, and outbox jobs use focused PostgreSQL write paths when available. Release-ledger and evidence-core mutations for products, projects, releases, artifacts, evidence items, evidence lifecycle events, SBOMs, vulnerability scans, OpenAPI contracts, VEX documents, audit-chain entries, and parser outbox jobs also use focused PostgreSQL write paths when available. Remaining aggregate persistence calls use PostgreSQL relational synchronization without writing the compatibility snapshot when that store is configured. Current self-hosted production guidance still uses a single API writer replica and allows worker replicas to scale through PostgreSQL outbox row locking. +`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required release-candidate evidence, but it does not by itself close the remaining service decomposition, non-AWS KMS/HSM SDK providers, provider API/group validation, object-lock enforcement, HA, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. Critical runtime mutations for tenants, credential hashes, idempotency, audit-chain entries, release bundles, signatures, verification results, vulnerability decisions, and outbox jobs use focused PostgreSQL write paths when available. Release-ledger and evidence-core mutations for products, projects, releases, artifacts, evidence items, evidence lifecycle events, SBOMs, vulnerability scans, OpenAPI contracts, VEX documents, audit-chain entries, and parser outbox jobs also use focused PostgreSQL write paths when available. Remaining aggregate persistence calls use PostgreSQL relational synchronization without writing the compatibility snapshot when that store is configured. Current self-hosted production guidance still uses a single API writer replica and allows worker replicas to scale through PostgreSQL outbox row locking. diff --git a/cmd/evydence-api/main.go b/cmd/evydence-api/main.go index 11395da..520c088 100644 --- a/cmd/evydence-api/main.go +++ b/cmd/evydence-api/main.go @@ -18,6 +18,7 @@ import ( "github.com/aatuh/evydence/internal/adapters/objectstore/filesystem" s3store "github.com/aatuh/evydence/internal/adapters/objectstore/s3" "github.com/aatuh/evydence/internal/adapters/postgres" + "github.com/aatuh/evydence/internal/adapters/signing/awskms" "github.com/aatuh/evydence/internal/adapters/signing/httpgateway" "github.com/aatuh/evydence/internal/adapters/transparency/httpfetcher" "github.com/aatuh/evydence/internal/app" @@ -128,6 +129,24 @@ func run() error { } func openSigningExecutor() (app.SigningExecutor, error) { + mode := strings.ToLower(strings.TrimSpace(os.Getenv("EVYDENCE_SIGNING_KEY_MODE"))) + if mode == "aws_kms" || mode == "aws-kms" { + region := strings.TrimSpace(os.Getenv("EVYDENCE_AWS_REGION")) + if region == "" { + region = strings.TrimSpace(os.Getenv("AWS_REGION")) + } + executor, err := awskms.New(context.Background(), awskms.Config{ + Region: region, + KeyID: os.Getenv("EVYDENCE_AWS_KMS_KEY_ID"), + Endpoint: os.Getenv("EVYDENCE_AWS_KMS_ENDPOINT"), + SigningAlgorithm: os.Getenv("EVYDENCE_AWS_KMS_SIGNING_ALGORITHM"), + Timeout: time.Duration(intEnv("EVYDENCE_AWS_KMS_TIMEOUT_SECONDS", 10)) * time.Second, + }) + if err != nil { + return nil, fmt.Errorf("configure AWS KMS signing executor: %w", err) + } + return executor, nil + } endpoint := strings.TrimSpace(os.Getenv("EVYDENCE_SIGNING_EXECUTOR_URL")) if endpoint == "" { return nil, nil @@ -154,8 +173,9 @@ func validateRuntimeConfig(production bool, databaseURL, pepper, signingKeyMode if strings.TrimSpace(pepper) == "" || strings.TrimSpace(pepper) == "local-dev-pepper-change-me" { return errors.New("production requires a non-default EVYDENCE_API_KEY_PEPPER") } - if strings.TrimSpace(signingKeyMode) != "external" { - return errors.New("production requires EVYDENCE_SIGNING_KEY_MODE=external; plaintext local signing keys are dev-only") + normalizedMode := strings.ToLower(strings.TrimSpace(signingKeyMode)) + if normalizedMode != "external" && normalizedMode != "aws-kms" && normalizedMode != "aws_kms" { + return errors.New("production requires EVYDENCE_SIGNING_KEY_MODE=external or aws-kms; plaintext local signing keys are dev-only") } if printBootstrapSecret { return errors.New("production refuses EVYDENCE_PRINT_BOOTSTRAP_SECRET=true") diff --git a/cmd/evydence-api/main_test.go b/cmd/evydence-api/main_test.go index 3407c2a..a5acacf 100644 --- a/cmd/evydence-api/main_test.go +++ b/cmd/evydence-api/main_test.go @@ -46,6 +46,12 @@ func TestValidateRuntimeConfigRejectsProductionDefaults(t *testing.T) { } } +func TestValidateRuntimeConfigAllowsProductionAWSKMSMode(t *testing.T) { + if err := validateRuntimeConfig(true, "postgres://example", "not-default", "aws-kms", false); err != nil { + t.Fatalf("aws-kms production mode should be accepted: %v", err) + } +} + func TestPostgresLoadModeDefaultsToRelationalOnlyInProduction(t *testing.T) { mode, err := postgres.ResolveLoadMode("", true) if err != nil { @@ -138,3 +144,11 @@ func TestOpenSigningExecutorRequiresHTTPSUnlessLocalOverride(t *testing.T) { t.Fatal("expected signer") } } + +func TestOpenSigningExecutorRejectsIncompleteAWSKMSConfig(t *testing.T) { + t.Setenv("EVYDENCE_SIGNING_KEY_MODE", "aws-kms") + t.Setenv("EVYDENCE_AWS_REGION", "eu-north-1") + if _, err := openSigningExecutor(); err == nil { + t.Fatal("expected missing AWS KMS key id to be rejected") + } +} diff --git a/docs/architecture.md b/docs/architecture.md index 1004a94..8147f76 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -34,7 +34,7 @@ Release readiness is deterministic and evidence-scoped. Open critical vulnerabil DSSE attestation signatures can be verified against configured Ed25519 trust roots when raw attestation bytes are available. Cosign-style artifact verification records digest binding, signature presence, and optional Rekor metadata without overstating full Sigstore trust-chain validation. Signing keys support revocation and valid-at-signing semantics for historical signatures. -Merkle batches, signed checkpoints, optional transparency checkpoint/public transparency records with operator-supplied or fetched inclusion proof verification, backup manifests, object-retention policy records with verification hashes, legal holds, retention overrides, readiness, metrics, instance admin diagnostics, external signing gateway receipts, and admin audit queries provide operational integrity and review surfaces. +Merkle batches, signed checkpoints, optional transparency checkpoint/public transparency records with operator-supplied or fetched inclusion proof verification, backup manifests, object-retention policy records with verification hashes, legal holds, retention overrides, readiness, metrics, instance admin diagnostics, external signing gateway/AWS KMS signing receipts, and admin audit queries provide operational integrity and review surfaces. ## Reports And Customer-Facing Packages @@ -52,6 +52,6 @@ Air-gapped import-bundle workflows preserve the same tenant-scoped import path a ## Limitations -The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, OIDC discovery refresh, SSO credential exchange with session-scoped OIDC group-role mapping, public-transparency proof fetching, and optional worker-owned parser side effects are implemented, but direct cloud KMS/HSM SDK adapters, live Sigstore verification, live provider API validation, and external group synchronization remain deployment hardening work. Hand-tuned per-resource repository implementations remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. +The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, an AWS KMS signing executor, OIDC discovery refresh, SSO credential exchange with session-scoped OIDC group-role mapping, public-transparency proof fetching, and optional worker-owned parser side effects are implemented, but non-AWS cloud KMS/HSM SDK adapters, live Sigstore verification, live provider API validation, and external group synchronization remain deployment hardening work. Hand-tuned per-resource repository implementations remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. Evydence does not prove provider truth, scanner authority, runtime security, legal compliance, or release security by itself. diff --git a/docs/production-hardening.md b/docs/production-hardening.md index 6d69fb2..57bfa18 100644 --- a/docs/production-hardening.md +++ b/docs/production-hardening.md @@ -9,7 +9,7 @@ Before labeling a deployment production, verify: - `ENV=production` is set. - `EVYDENCE_DATABASE_URL` points to external PostgreSQL. - `EVYDENCE_API_KEY_PEPPER` is a non-default random value. -- `EVYDENCE_SIGNING_KEY_MODE=external` is set. +- `EVYDENCE_SIGNING_KEY_MODE=external` or `EVYDENCE_SIGNING_KEY_MODE=aws-kms` is set. - `EVYDENCE_PRINT_BOOTSTRAP_SECRET` is unset or false. These checks are enforced by API startup. See [Configuration](reference/configuration.md). @@ -26,6 +26,7 @@ These checks are enforced by API startup. See [Configuration](reference/configur - Customer portal access tokens are short-lived, scoped to one package, and handled as bearer secrets. - Generated customer packages use explicit redaction profiles and expiry. - Collector releases are pinned and have signature, SBOM, and vulnerability scan evidence when available. +- Signing operations use either a tenant-controlled HTTPS signing gateway or the AWS KMS executor; raw evidence payload bytes are not sent to either executor by Evydence. ## Backup And Restore Checklist diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 8a0a6d7..df3331d 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -46,11 +46,16 @@ The example secrets are placeholders. Replace them before using shared or produc | `EVYDENCE_WORKER_POLL_INTERVAL` | No | `1s` | Worker outbox polling interval. | | `EVYDENCE_WORKER_BATCH_SIZE` | No | `10` | Maximum outbox jobs claimed per polling cycle. | | `EVYDENCE_WORKER_MAX_PAYLOAD_BYTES` | No | `20971520` | Maximum raw object payload size replayed by a worker job. | -| `EVYDENCE_SIGNING_KEY_MODE` | Production yes | `external` for production | Production rejects local plaintext signing-key mode. | +| `EVYDENCE_SIGNING_KEY_MODE` | Production yes | `external` or `aws-kms` for production | Production rejects local plaintext signing-key mode. `external` uses the optional HTTPS signing gateway; `aws-kms` uses the built-in AWS KMS executor. | | `EVYDENCE_SIGNING_EXECUTOR_URL` | No | unset | Optional HTTPS signing gateway used by `POST /v1/signing-operations` when `external_signature` is omitted. The API sends subject metadata and `payload_hash`, not raw payload bytes. | | `EVYDENCE_SIGNING_EXECUTOR_TOKEN` | Signing gateway | unset | Optional bearer token for the signing gateway. Store outside source control and logs. | | `EVYDENCE_SIGNING_EXECUTOR_TIMEOUT_SECONDS` | No | `10` | Timeout for signing gateway requests. | | `EVYDENCE_SIGNING_EXECUTOR_ALLOW_INSECURE_LOCALHOST` | Local only | `false` | Allows `http://localhost` or loopback signing gateway endpoints for local development and tests. Do not use for production. | +| `EVYDENCE_AWS_KMS_KEY_ID` | AWS KMS mode | unset | AWS KMS asymmetric signing key id, alias, or ARN. Store IAM credentials outside Evydence config and logs. | +| `EVYDENCE_AWS_REGION` / `AWS_REGION` | AWS KMS mode | unset | Region used by the AWS KMS executor. `EVYDENCE_AWS_REGION` takes precedence. | +| `EVYDENCE_AWS_KMS_ENDPOINT` | No | unset | Optional AWS KMS-compatible endpoint for tests or controlled private endpoints. | +| `EVYDENCE_AWS_KMS_SIGNING_ALGORITHM` | No | `ECDSA_SHA_256` | Supported values are `ECDSA_SHA_256`, `RSASSA_PSS_SHA_256`, and `RSASSA_PKCS1_V1_5_SHA_256` because Evydence signs stored SHA-256 payload hashes. | +| `EVYDENCE_AWS_KMS_TIMEOUT_SECONDS` | No | `10` | Timeout for AWS KMS signing requests. | | `EVYDENCE_TEST_DATABASE_URL` | Live tests | `.test.env.example` value | Used by `make live-postgres-check`, `make postgres-integration-test`, and `make release-check`. | ## Production Rejection Checks @@ -59,7 +64,7 @@ When `ENV=production`, the API refuses to start unless: - `EVYDENCE_DATABASE_URL` is set. - `EVYDENCE_API_KEY_PEPPER` is non-empty and not the local default. -- `EVYDENCE_SIGNING_KEY_MODE=external`. +- `EVYDENCE_SIGNING_KEY_MODE=external` or `EVYDENCE_SIGNING_KEY_MODE=aws-kms`. - `EVYDENCE_PRINT_BOOTSTRAP_SECRET` is not `true`. - `EVYDENCE_POSTGRES_LOAD_MODE`, when set, is `relational_only`. @@ -90,7 +95,7 @@ and limitations. The check is bucket-level: operators still need to review bucket creation mode, IAM policy, lifecycle rules, backups, and any deployment-specific WORM requirements. -## External Signing Gateway +## Signing Executors When `EVYDENCE_SIGNING_EXECUTOR_URL` is set, signing operations can omit `external_signature`. Evydence sends a JSON request containing tenant id, @@ -99,6 +104,13 @@ gateway returns a signature, optional provider key id, and optional algorithm. Evydence records the signature receipt and verification checks; it does not store production private key material or send raw evidence payload bytes. +When `EVYDENCE_SIGNING_KEY_MODE=aws-kms`, Evydence uses the AWS KMS `Sign` +operation against `EVYDENCE_AWS_KMS_KEY_ID`. The executor signs the decoded +SHA-256 digest with KMS `MessageType=DIGEST`; it does not send raw evidence +payload bytes to AWS KMS. Operators remain responsible for AWS IAM policy, +key lifecycle, CloudTrail review, regional availability, and external review +of whether the selected key custody profile satisfies their deployment needs. + ## Related Commands - Local operation: [Install and operate](../how-to/install-and-operate.md) diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index d79c443..73c9601 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -61,16 +61,16 @@ Known hardening work remains: - OpenAPI precision is enforced across the registered public API. The generated matrix remains the source of truth for operation ids, scopes, idempotency, parameters, and request/response schemas; -- production signing can use the HTTPS signing gateway executor, but direct - cloud KMS/HSM SDK adapters, live provider API validation/group sync, and - broad object-lock enforcement proof remain provider- and deployment-dependent - hardening areas. SSO credential exchange can issue bearer sessions and - HttpOnly cookies after local OIDC/SAML verification against configured trust - material, OIDC group claim values can map to session-scoped roles without - creating permanent role bindings, and public transparency proof material can - be fetched from a configured endpoint and verified locally, but - provider-specific trust semantics and availability remain deployment - responsibilities; +- production signing can use the HTTPS signing gateway executor or the built-in + AWS KMS signing executor, but non-AWS cloud KMS/HSM SDK adapters, live + provider API validation/group sync, and broad object-lock enforcement proof + remain provider- and deployment-dependent hardening areas. SSO credential + exchange can issue bearer sessions and HttpOnly cookies after local OIDC/SAML + verification against configured trust material, OIDC group claim values can + map to session-scoped roles without creating permanent role bindings, and + public transparency proof material can be fetched from a configured endpoint + and verified locally, but provider-specific trust semantics and availability + remain deployment responsibilities; - the broader production exit review remains incomplete. ## Production Profiles @@ -197,9 +197,11 @@ implemented capabilities: PostgreSQL store supports them. - Keep OpenAPI precision at zero broad operations as routes are added or changed, and expand generated SDK coverage from the committed contract. -- Add direct cloud KMS/HSM SDK adapters where required. The current HTTPS - signing gateway executor covers deployments that put KMS/HSM custody behind a - tenant-controlled signing service and do not send raw payload bytes. +- Add direct cloud KMS/HSM SDK adapters where required beyond AWS KMS. The + current HTTPS signing gateway executor covers deployments that put KMS/HSM + custody behind a tenant-controlled signing service and do not send raw + payload bytes; the AWS KMS executor signs stored SHA-256 payload hashes with + KMS `MessageType=DIGEST`. - Complete live provider API validation and optional group mapping where those profiles are enabled. OIDC discovery/JWKS refresh is implemented for public trust-material updates, manual JWKS and SAML signing-certificate rotation is diff --git a/docs/reference/release-candidate.md b/docs/reference/release-candidate.md index 7bb9dce..7f71b5e 100644 --- a/docs/reference/release-candidate.md +++ b/docs/reference/release-candidate.md @@ -64,6 +64,6 @@ production, and hosted SaaS production require additional review and controls. - Use external PostgreSQL, external object storage, TLS ingress, non-default API-key pepper, externalized secrets, backup and restore rehearsal, monitoring, and documented incident response. -- Keep full repository decomposition, HA/multi-writer operation, direct KMS/HSM - SDK adapters, live provider validation, and broader object-lock proof listed - as unresolved hardening work until they are implemented and verified. +- Keep service decomposition, HA/multi-writer operation, non-AWS KMS/HSM SDK + adapters, live provider validation, and broader object-lock proof listed as + unresolved hardening work until they are implemented and verified. diff --git a/docs/reference/release-notes-v0.1.0-rc.1.md b/docs/reference/release-notes-v0.1.0-rc.1.md index 222afeb..3f14a2f 100644 --- a/docs/reference/release-notes-v0.1.0-rc.1.md +++ b/docs/reference/release-notes-v0.1.0-rc.1.md @@ -32,7 +32,8 @@ acceptance. - Use S3/MinIO-compatible object storage or the documented filesystem mode for local evaluation only. - Set `ENV=production`, a non-default `EVYDENCE_API_KEY_PEPPER`, and - `EVYDENCE_SIGNING_KEY_MODE=external` for production-profile startup. + `EVYDENCE_SIGNING_KEY_MODE=external` or `EVYDENCE_SIGNING_KEY_MODE=aws-kms` + for production-profile startup. - Apply all committed migrations before starting API or worker processes. - For Kubernetes, set an explicit image tag or digest and keep API replicas at `1` until HA/multi-writer support is reviewed. @@ -43,7 +44,8 @@ acceptance. PostgreSQL writes cover the highest-risk runtime mutations, but not every resource family. - HA/multi-writer API operation is not supported in this profile. -- Direct cloud KMS/HSM SDK adapters are not included. +- The AWS KMS signing executor is included; non-AWS cloud KMS/HSM SDK adapters + are not included. - Live GitHub/GitLab provider API validation and external group synchronization remain deployment-dependent. - Broader WORM/object-lock proof beyond configured S3/MinIO checks remains diff --git a/go.mod b/go.mod index 01534a1..418b322 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,21 @@ require ( ) require ( + github.com/aws/aws-sdk-go-v2 v1.41.9 // indirect + github.com/aws/aws-sdk-go-v2/config v1.32.20 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.19.19 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.25 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.25 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.25 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.26 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.10 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.25 // indirect + github.com/aws/aws-sdk-go-v2/service/kms v1.52.2 // indirect + github.com/aws/aws-sdk-go-v2/service/signin v1.1.1 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.30.19 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.36.2 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.42.3 // indirect + github.com/aws/smithy-go v1.26.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect diff --git a/go.sum b/go.sum index 73ff4b8..64bf869 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,35 @@ github.com/aatuh/api-toolkit/v3 v3.1.2 h1:QT/gH6L/rP9G2Defl1Zj71cQYQ0AJ0kp+NjoBvRs6gs= github.com/aatuh/api-toolkit/v3 v3.1.2/go.mod h1:aZrzzBRyglFi5KaHpAomD+R9I7qp3rL8vmBi7xlloMw= +github.com/aws/aws-sdk-go-v2 v1.41.9 h1:/rYeyO2+HrMztAmxAq9++XJtFMqSIpSsNA0yDGALYq4= +github.com/aws/aws-sdk-go-v2 v1.41.9/go.mod h1:+HsoOEX80qAVUitj1A2DhCNTjmb3edVyuDypb6LNEeo= +github.com/aws/aws-sdk-go-v2/config v1.32.20 h1:8VMDnWc/kEzxsI/1ngGM9mG81a8IGmIHD8KLcYGwagc= +github.com/aws/aws-sdk-go-v2/config v1.32.20/go.mod h1:PuwEpciweIXGULWeOeSTXtSbH4CW9mWdWrhdCKQI1sM= +github.com/aws/aws-sdk-go-v2/credentials v1.19.19 h1:yuFzSV1U0aRNYCQGVaTY2zW2M/L93pYHnXnrJUphYhU= +github.com/aws/aws-sdk-go-v2/credentials v1.19.19/go.mod h1:7y63L1kGzeoDlJaQ3Z578KrnmfBut96JjvJUzGwR+YE= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.25 h1:0w6dCiO8iez+YKwRhRBlL1CH/E3GTfdkuzrwj1by8vo= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.25/go.mod h1:9FDWUothyr5RCRAHc45XOiVCzUR8n/IhCYX+uVqw6vk= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.25 h1:Uii3frf9ztec/ABM2/FSH9/z7PLzxfpG8h4RpkUFflQ= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.25/go.mod h1:G6kntsA2GorAxDPbap6xgB2F+amSLUF8GJTi7PUoX44= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.25 h1:r1+/l6m+WaUJF9HISEsNOLHSNj5EXYQxK8VX6Cz9NlA= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.25/go.mod h1:cKf+D+NMDK1LndD7BowHbBZPgR9V0/5HubH0PFWvA+c= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.26 h1:A1PmWU2zfkIm9EyFlJncFXL4W4phML+h8KjltUsCvNQ= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.26/go.mod h1:dY4MRzXEizrD4hqtpKvWVGPX7QleSGGVY+EBolo1RmM= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.10 h1:d5/908OJ4bXg8lyjeMPvXetEKqoDoLi5Owy1zNue3yg= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.10/go.mod h1:a57l7Hwh+FWI+we50g5NPJHYUKeJKfXbc4w8SyXu8Ig= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.25 h1:dD3dhHNglpd98gs72my22Ndqi1hqQGllFFg1F+twfxg= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.25/go.mod h1:0yAbjPfd64gG7mj85RW+fMEYdfBgCRZw8g/oWcL1pjc= +github.com/aws/aws-sdk-go-v2/service/kms v1.52.2 h1:J0TorhKhXYPjIgLWd/J+q2bJVGywwyFApA+6Iqf2808= +github.com/aws/aws-sdk-go-v2/service/kms v1.52.2/go.mod h1:oqZYP0JN0ih1JTsoiT10Un/Ivg8LeVOMTK+UDNBq3sU= +github.com/aws/aws-sdk-go-v2/service/signin v1.1.1 h1:1VwbP3qMNfxUDEXWki4rCE5iA+44VA1lokTz9HasGzw= +github.com/aws/aws-sdk-go-v2/service/signin v1.1.1/go.mod h1:vUtyoSj0OPji3kjIVSc/GlKuWEiL33f/WFxl6dmpy/A= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.19 h1:N6pIsdFOW1Kd9S4KyFKXdGRBojPPxkP32+uHFWLv4Hc= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.19/go.mod h1:3gt5WJArFooNmyLONS+h/R4J+o86II8du38IgCwj9dE= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.36.2 h1:hc+lBYiiTr8Zk4MTzIsQ92MeDWCIDvWGmzKUWOaBcOg= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.36.2/go.mod h1:hU6fqB3OJA6/ePheD47LQnxvjYk6br6PtQxs+Q9ojvk= +github.com/aws/aws-sdk-go-v2/service/sts v1.42.3 h1:ErklX/7uhSbkAAeyQD/Y1OoQ9hO3SJXQNEgksORW3Js= +github.com/aws/aws-sdk-go-v2/service/sts v1.42.3/go.mod h1:ULe4HCzfKPiR6R3HEurE3b1upEkuk8AkMrOKtaOxKO8= +github.com/aws/smithy-go v1.26.0 h1:9ouqbi+NyKP7fV3Te7UElCwdAb6Y8uk7LGwPE5tVe/s= +github.com/aws/smithy-go v1.26.0/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/internal/adapters/signing/awskms/awskms.go b/internal/adapters/signing/awskms/awskms.go new file mode 100644 index 0000000..cf0b942 --- /dev/null +++ b/internal/adapters/signing/awskms/awskms.go @@ -0,0 +1,151 @@ +package awskms + +import ( + "context" + "encoding/base64" + "encoding/hex" + "errors" + "strings" + "time" + + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/service/kms" + "github.com/aws/aws-sdk-go-v2/service/kms/types" + + "github.com/aatuh/evydence/internal/app" + "github.com/aatuh/evydence/internal/domain" +) + +const defaultTimeout = 10 * time.Second + +type Config struct { + Region string + KeyID string + Endpoint string + SigningAlgorithm string + Timeout time.Duration +} + +type kmsSigner interface { + Sign(context.Context, *kms.SignInput, ...func(*kms.Options)) (*kms.SignOutput, error) +} + +type Executor struct { + client kmsSigner + keyID string + algorithm types.SigningAlgorithmSpec + timeout time.Duration +} + +func New(ctx context.Context, cfg Config) (*Executor, error) { + if strings.TrimSpace(cfg.Region) == "" { + return nil, app.ErrValidation + } + awsCfg, err := config.LoadDefaultConfig(ctx, config.WithRegion(strings.TrimSpace(cfg.Region))) + if err != nil { + return nil, errors.New("load AWS KMS signing configuration") + } + options := []func(*kms.Options){} + if endpoint := strings.TrimSpace(cfg.Endpoint); endpoint != "" { + options = append(options, func(o *kms.Options) { + o.BaseEndpoint = &endpoint + }) + } + return NewWithClient(kms.NewFromConfig(awsCfg, options...), cfg) +} + +func NewWithClient(client kmsSigner, cfg Config) (*Executor, error) { + keyID := strings.TrimSpace(cfg.KeyID) + if client == nil || keyID == "" { + return nil, app.ErrValidation + } + algorithm, err := parseSigningAlgorithm(cfg.SigningAlgorithm) + if err != nil { + return nil, err + } + timeout := cfg.Timeout + if timeout <= 0 { + timeout = defaultTimeout + } + return &Executor{client: client, keyID: keyID, algorithm: algorithm, timeout: timeout}, nil +} + +func (e *Executor) Sign(ctx context.Context, request app.SigningRequest) (app.SigningResult, error) { + if e == nil || e.client == nil || e.keyID == "" { + return app.SigningResult{}, app.ErrValidation + } + if strings.TrimSpace(request.TenantID) == "" || strings.TrimSpace(request.SubjectType) == "" || strings.TrimSpace(request.SubjectID) == "" { + return app.SigningResult{}, app.ErrValidation + } + digest, err := parseSHA256Digest(request.PayloadHash) + if err != nil { + return app.SigningResult{}, err + } + callCtx := ctx + var cancel context.CancelFunc + if e.timeout > 0 { + callCtx, cancel = context.WithTimeout(ctx, e.timeout) + defer cancel() + } + output, err := e.client.Sign(callCtx, &kms.SignInput{ + KeyId: &e.keyID, + Message: digest, + MessageType: types.MessageTypeDigest, + SigningAlgorithm: e.algorithm, + }) + if err != nil { + return app.SigningResult{}, errors.New("execute AWS KMS signing request") + } + if len(output.Signature) == 0 || len(output.Signature) > 32768 { + return app.SigningResult{}, app.ErrValidation + } + keyID := e.keyID + if output.KeyId != nil && strings.TrimSpace(*output.KeyId) != "" { + keyID = strings.TrimSpace(*output.KeyId) + } + algorithm := output.SigningAlgorithm + if algorithm == "" { + algorithm = e.algorithm + } + return app.SigningResult{ + Signature: base64.StdEncoding.EncodeToString(output.Signature), + KeyID: keyID, + Algorithm: "aws-kms:" + string(algorithm), + Checks: []domain.VerifyCheck{ + {Name: "aws_kms_signature_returned", Result: "passed", Detail: "AWS KMS returned a signature over the submitted SHA-256 digest."}, + }, + }, nil +} + +func parseSHA256Digest(value string) ([]byte, error) { + const prefix = "sha256:" + trimmed := strings.TrimSpace(value) + if !strings.HasPrefix(trimmed, prefix) { + return nil, app.ErrValidation + } + encoded := strings.TrimPrefix(trimmed, prefix) + if len(encoded) != 64 { + return nil, app.ErrValidation + } + digest, err := hex.DecodeString(encoded) + if err != nil || len(digest) != 32 { + return nil, app.ErrValidation + } + return digest, nil +} + +func parseSigningAlgorithm(value string) (types.SigningAlgorithmSpec, error) { + trimmed := strings.TrimSpace(value) + if trimmed == "" { + return types.SigningAlgorithmSpecEcdsaSha256, nil + } + algorithm := types.SigningAlgorithmSpec(trimmed) + switch algorithm { + case types.SigningAlgorithmSpecEcdsaSha256, + types.SigningAlgorithmSpecRsassaPssSha256, + types.SigningAlgorithmSpecRsassaPkcs1V15Sha256: + return algorithm, nil + default: + return "", errors.New("unsupported AWS KMS signing algorithm") + } +} diff --git a/internal/adapters/signing/awskms/awskms_test.go b/internal/adapters/signing/awskms/awskms_test.go new file mode 100644 index 0000000..122ed5e --- /dev/null +++ b/internal/adapters/signing/awskms/awskms_test.go @@ -0,0 +1,118 @@ +package awskms + +import ( + "context" + "encoding/base64" + "errors" + "strings" + "testing" + + "github.com/aws/aws-sdk-go-v2/service/kms" + "github.com/aws/aws-sdk-go-v2/service/kms/types" + + "github.com/aatuh/evydence/internal/app" +) + +type fakeKMSSigner struct { + input *kms.SignInput + err error +} + +func (f *fakeKMSSigner) Sign(_ context.Context, input *kms.SignInput, _ ...func(*kms.Options)) (*kms.SignOutput, error) { + f.input = input + if f.err != nil { + return nil, f.err + } + keyID := "arn:aws:kms:eu-north-1:111122223333:key/test" + return &kms.SignOutput{ + KeyId: &keyID, + Signature: []byte("der-signature"), + SigningAlgorithm: input.SigningAlgorithm, + }, nil +} + +func TestNewWithClientRequiresClientAndKeyID(t *testing.T) { + if _, err := NewWithClient(nil, Config{KeyID: "key"}); err == nil { + t.Fatal("expected nil client to be rejected") + } + if _, err := NewWithClient(&fakeKMSSigner{}, Config{}); err == nil { + t.Fatal("expected missing key id to be rejected") + } +} + +func TestNewWithClientRejectsNonSHA256Algorithms(t *testing.T) { + if _, err := NewWithClient(&fakeKMSSigner{}, Config{KeyID: "key", SigningAlgorithm: string(types.SigningAlgorithmSpecEcdsaSha384)}); err == nil { + t.Fatal("expected SHA-384 algorithm to be rejected for sha256 payload hashes") + } +} + +func TestSignSendsDigestOnlyAndReturnsBase64Signature(t *testing.T) { + fake := &fakeKMSSigner{} + executor, err := NewWithClient(fake, Config{KeyID: "alias/evydence-release", SigningAlgorithm: string(types.SigningAlgorithmSpecRsassaPssSha256)}) + if err != nil { + t.Fatal(err) + } + result, err := executor.Sign(t.Context(), app.SigningRequest{ + TenantID: "ten_1", + SubjectType: "release", + SubjectID: "rel_1", + PayloadHash: "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", + }) + if err != nil { + t.Fatal(err) + } + if fake.input == nil { + t.Fatal("expected KMS request") + } + if fake.input.KeyId == nil || *fake.input.KeyId != "alias/evydence-release" { + t.Fatalf("key id = %v", fake.input.KeyId) + } + if fake.input.MessageType != types.MessageTypeDigest { + t.Fatalf("message type = %q, want DIGEST", fake.input.MessageType) + } + if got := len(fake.input.Message); got != 32 { + t.Fatalf("message length = %d, want SHA-256 digest length", got) + } + if fake.input.SigningAlgorithm != types.SigningAlgorithmSpecRsassaPssSha256 { + t.Fatalf("algorithm = %q", fake.input.SigningAlgorithm) + } + if result.Signature != base64.StdEncoding.EncodeToString([]byte("der-signature")) { + t.Fatalf("signature = %q", result.Signature) + } + if result.Algorithm != "aws-kms:RSASSA_PSS_SHA_256" { + t.Fatalf("algorithm = %q", result.Algorithm) + } + if result.KeyID == "" || len(result.Checks) != 1 || result.Checks[0].Name != "aws_kms_signature_returned" { + t.Fatalf("result = %#v", result) + } +} + +func TestSignRejectsMalformedDigest(t *testing.T) { + executor, err := NewWithClient(&fakeKMSSigner{}, Config{KeyID: "alias/evydence-release"}) + if err != nil { + t.Fatal(err) + } + if _, err := executor.Sign(t.Context(), app.SigningRequest{TenantID: "ten_1", SubjectType: "release", SubjectID: "rel_1", PayloadHash: "sha256:not-hex"}); !errors.Is(err, app.ErrValidation) { + t.Fatalf("err=%v, want validation", err) + } +} + +func TestSignHidesProviderErrorDetails(t *testing.T) { + fake := &fakeKMSSigner{err: errors.New("provider included payload sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")} + executor, err := NewWithClient(fake, Config{KeyID: "alias/evydence-release"}) + if err != nil { + t.Fatal(err) + } + _, err = executor.Sign(context.Background(), app.SigningRequest{ + TenantID: "ten_1", + SubjectType: "release", + SubjectID: "rel_1", + PayloadHash: "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", + }) + if err == nil { + t.Fatal("expected provider error") + } + if strings.Contains(err.Error(), "0123456789abcdef") || strings.Contains(err.Error(), "payload") { + t.Fatalf("error leaked provider details: %v", err) + } +} From b6b76a10791df4c780cf128e3a42f9988574c56f Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 10:06:09 +0300 Subject: [PATCH 130/287] feat: add oidc userinfo provider validation --- .api.env.example | 3 + CHANGELOG.md | 8 +- README.md | 4 +- cmd/evydence-api/main.go | 5 + docs/api.md | 2 +- docs/architecture.md | 2 +- docs/production-hardening.md | 3 + docs/reference/configuration.md | 2 + docs/reference/production-readiness.md | 35 ++-- docs/reference/release-candidate.md | 5 +- docs/reference/release-notes-v0.1.0-rc.1.md | 3 +- docs/sdk/README.md | 2 +- internal/adapters/httpapi/future_handlers.go | 3 +- internal/adapters/httpapi/openapi.go | 1 + .../identity/oidcuserinfo/oidcuserinfo.go | 184 ++++++++++++++++++ .../oidcuserinfo/oidcuserinfo_test.go | 92 +++++++++ internal/app/future_extensions.go | 100 +++++++--- internal/app/future_extensions_test.go | 60 ++++++ internal/app/ledger.go | 3 + internal/app/ports.go | 20 ++ openapi.yaml | 2 +- sdk/go/evydence/client.go | 1 + sdk/typescript/client.ts | 1 + 23 files changed, 486 insertions(+), 55 deletions(-) create mode 100644 internal/adapters/identity/oidcuserinfo/oidcuserinfo.go create mode 100644 internal/adapters/identity/oidcuserinfo/oidcuserinfo_test.go diff --git a/.api.env.example b/.api.env.example index 7baa6ba..8ccbf34 100644 --- a/.api.env.example +++ b/.api.env.example @@ -23,6 +23,9 @@ EVYDENCE_SIGNING_KEY_MODE=external # Optional OIDC discovery refresh tuning. HTTP is allowed only for localhost when explicitly enabled. # EVYDENCE_OIDC_DISCOVERY_TIMEOUT_SECONDS=10 # EVYDENCE_OIDC_DISCOVERY_ALLOW_INSECURE_LOCALHOST=false +# Optional OIDC UserInfo live validation tuning. HTTP is allowed only for localhost when explicitly enabled. +# EVYDENCE_OIDC_USERINFO_TIMEOUT_SECONDS=10 +# EVYDENCE_OIDC_USERINFO_ALLOW_INSECURE_LOCALHOST=false # Optional public transparency proof fetch tuning. HTTP is allowed only for localhost when explicitly enabled. # EVYDENCE_TRANSPARENCY_FETCH_TIMEOUT_SECONDS=10 # EVYDENCE_TRANSPARENCY_FETCH_ALLOW_INSECURE_LOCALHOST=false diff --git a/CHANGELOG.md b/CHANGELOG.md index 138e037..6afb796 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,9 @@ Release-candidate tagging requires the production gate and checklist in persistence calls without writing the compatibility `ledger_state` snapshot. - AWS KMS signing executor for signing provider operations over stored SHA-256 payload hashes without sending raw evidence payload bytes. +- Optional OIDC UserInfo live provider validation for + `POST /v1/provider-verifications` using a supplied access token that is not + persisted. ### Known Limits @@ -46,5 +49,6 @@ Release-candidate tagging requires the production gate and checklist in network policy, TLS, backups, monitoring, external signing, and incident response. - Service decomposition, HA/multi-writer operation, non-AWS KMS/HSM SDK - adapters, live provider validation, broader object-lock proof, and final exit - review remain production-hardening work after the release-candidate gate. + adapters, provider-specific management API/group synchronization, broader + object-lock proof, and final exit review remain production-hardening work + after the release-candidate gate. diff --git a/README.md b/README.md index 8ccc778..470de99 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ This repository contains a Go implementation under module `github.com/aatuh/evyd - AGPL license, commercial licensing, governance, contribution, security, support, trademark, release-evidence, and changelog metadata. -Implemented-but-partial areas are documented explicitly: signing-provider operation receipts can use an HTTPS signing gateway or the built-in AWS KMS executor, but additional cloud KMS/HSM providers and deployment-specific custody review remain operator work; SSO credential exchange uses configured local OIDC/SAML trust material and session-scoped OIDC group-role mappings but does not replace live provider API validation or external group synchronization; and public transparency records can verify operator-supplied or fetched inclusion proof material without replacing provider-specific trust review. +Implemented-but-partial areas are documented explicitly: signing-provider operation receipts can use an HTTPS signing gateway or the built-in AWS KMS executor, but additional cloud KMS/HSM providers and deployment-specific custody review remain operator work; SSO credential exchange uses configured local OIDC/SAML trust material and session-scoped OIDC group-role mappings, and provider verification can optionally call OIDC UserInfo with a supplied access token, but this does not replace provider-specific management API validation or external group synchronization; and public transparency records can verify operator-supplied or fetched inclusion proof material without replacing provider-specific trust review. ## License, Security, Support, And Governance @@ -109,4 +109,4 @@ make postgres-integration-test `make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. -`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required release-candidate evidence, but it does not by itself close the remaining service decomposition, non-AWS KMS/HSM SDK providers, provider API/group validation, object-lock enforcement, HA, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. Critical runtime mutations for tenants, credential hashes, idempotency, audit-chain entries, release bundles, signatures, verification results, vulnerability decisions, and outbox jobs use focused PostgreSQL write paths when available. Release-ledger and evidence-core mutations for products, projects, releases, artifacts, evidence items, evidence lifecycle events, SBOMs, vulnerability scans, OpenAPI contracts, VEX documents, audit-chain entries, and parser outbox jobs also use focused PostgreSQL write paths when available. Remaining aggregate persistence calls use PostgreSQL relational synchronization without writing the compatibility snapshot when that store is configured. Current self-hosted production guidance still uses a single API writer replica and allows worker replicas to scale through PostgreSQL outbox row locking. +`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required release-candidate evidence, but it does not by itself close the remaining service decomposition, non-AWS KMS/HSM SDK providers, provider-specific management API/group synchronization, object-lock enforcement, HA, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. Critical runtime mutations for tenants, credential hashes, idempotency, audit-chain entries, release bundles, signatures, verification results, vulnerability decisions, and outbox jobs use focused PostgreSQL write paths when available. Release-ledger and evidence-core mutations for products, projects, releases, artifacts, evidence items, evidence lifecycle events, SBOMs, vulnerability scans, OpenAPI contracts, VEX documents, audit-chain entries, and parser outbox jobs also use focused PostgreSQL write paths when available. Remaining aggregate persistence calls use PostgreSQL relational synchronization without writing the compatibility snapshot when that store is configured. Current self-hosted production guidance still uses a single API writer replica and allows worker replicas to scale through PostgreSQL outbox row locking. diff --git a/cmd/evydence-api/main.go b/cmd/evydence-api/main.go index 520c088..97664ed 100644 --- a/cmd/evydence-api/main.go +++ b/cmd/evydence-api/main.go @@ -15,6 +15,7 @@ import ( "github.com/aatuh/evydence/internal/adapters/httpapi" "github.com/aatuh/evydence/internal/adapters/identity/oidcdiscovery" + "github.com/aatuh/evydence/internal/adapters/identity/oidcuserinfo" "github.com/aatuh/evydence/internal/adapters/objectstore/filesystem" s3store "github.com/aatuh/evydence/internal/adapters/objectstore/s3" "github.com/aatuh/evydence/internal/adapters/postgres" @@ -43,6 +44,10 @@ func run() error { AllowInsecureForLocalhost: strings.EqualFold(os.Getenv("EVYDENCE_OIDC_DISCOVERY_ALLOW_INSECURE_LOCALHOST"), "true"), Timeout: time.Duration(intEnv("EVYDENCE_OIDC_DISCOVERY_TIMEOUT_SECONDS", 10)) * time.Second, }) + cfg.ProviderAPI = oidcuserinfo.New(oidcuserinfo.Config{ + AllowInsecureForLocalhost: strings.EqualFold(os.Getenv("EVYDENCE_OIDC_USERINFO_ALLOW_INSECURE_LOCALHOST"), "true"), + Timeout: time.Duration(intEnv("EVYDENCE_OIDC_USERINFO_TIMEOUT_SECONDS", 10)) * time.Second, + }) cfg.Transparency = httpfetcher.New(httpfetcher.Config{ AllowInsecureForLocalhost: strings.EqualFold(os.Getenv("EVYDENCE_TRANSPARENCY_FETCH_ALLOW_INSECURE_LOCALHOST"), "true"), Timeout: time.Duration(intEnv("EVYDENCE_TRANSPARENCY_FETCH_TIMEOUT_SECONDS", 10)) * time.Second, diff --git a/docs/api.md b/docs/api.md index fcf8001..e23c63f 100644 --- a/docs/api.md +++ b/docs/api.md @@ -251,7 +251,7 @@ Important scope boundaries: | `POST` | `/v1/api-keys` | Create one-time API key secret. | | `GET` | `/v1/api-keys` | List keys without secret hashes. | -Current SSO endpoints model admin-managed provider, identity-link, trust-material, and session records plus API-first session logout. OIDC provider records can include public JWKS material, and SAML provider records can include PEM-encoded assertion signing certificates; both can be rotated through `POST /v1/sso/providers/{id}/trust-material`. OIDC public JWKS can also be refreshed from the configured issuer with `POST /v1/sso/providers/{id}/discover-oidc`. `POST /v1/provider-verifications` can verify a supplied OIDC ID token or SAML assertion locally for issuer, audience, subject, time bounds, and signature. `POST /v1/sso/session-exchanges` uses the same local verification and a verified identity link to issue a one-time SSO bearer secret and an HttpOnly cookie for browser clients. OIDC group claim values can map to session-scoped roles through the provider `groups_claim` and `role_mapping`; no permanent role binding is created from token claims. Live provider API validation and external group synchronization are not implemented in this slice. +Current SSO endpoints model admin-managed provider, identity-link, trust-material, and session records plus API-first session logout. OIDC provider records can include public JWKS material, and SAML provider records can include PEM-encoded assertion signing certificates; both can be rotated through `POST /v1/sso/providers/{id}/trust-material`. OIDC public JWKS can also be refreshed from the configured issuer with `POST /v1/sso/providers/{id}/discover-oidc`. `POST /v1/provider-verifications` can verify a supplied OIDC ID token or SAML assertion locally for issuer, audience, subject, time bounds, and signature. When an OIDC `access_token` is supplied, the same endpoint can call the provider's discovered UserInfo endpoint, verify the returned `sub`, and record any configured group-claim mapping checks without storing the access token. `POST /v1/sso/session-exchanges` uses local token/assertion verification and a verified identity link to issue a one-time SSO bearer secret and an HttpOnly cookie for browser clients. OIDC group claim values can map to session-scoped roles through the provider `groups_claim` and `role_mapping`; no permanent role binding is created from token claims. External group synchronization into permanent role bindings is not implemented in this slice. ### Products, Releases, Evidence, And Risk diff --git a/docs/architecture.md b/docs/architecture.md index 8147f76..8dc9e5e 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -52,6 +52,6 @@ Air-gapped import-bundle workflows preserve the same tenant-scoped import path a ## Limitations -The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, an AWS KMS signing executor, OIDC discovery refresh, SSO credential exchange with session-scoped OIDC group-role mapping, public-transparency proof fetching, and optional worker-owned parser side effects are implemented, but non-AWS cloud KMS/HSM SDK adapters, live Sigstore verification, live provider API validation, and external group synchronization remain deployment hardening work. Hand-tuned per-resource repository implementations remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. +The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, an AWS KMS signing executor, OIDC discovery refresh, optional live OIDC UserInfo validation, SSO credential exchange with session-scoped OIDC group-role mapping, public-transparency proof fetching, and optional worker-owned parser side effects are implemented, but non-AWS cloud KMS/HSM SDK adapters, live Sigstore verification, provider-specific management API validation, and external group synchronization remain deployment hardening work. Hand-tuned per-resource repository implementations remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. Evydence does not prove provider truth, scanner authority, runtime security, legal compliance, or release security by itself. diff --git a/docs/production-hardening.md b/docs/production-hardening.md index 57bfa18..3a61467 100644 --- a/docs/production-hardening.md +++ b/docs/production-hardening.md @@ -23,6 +23,9 @@ These checks are enforced by API startup. See [Configuration](reference/configur - Edge rate limiting is configured at the reverse proxy or ingress. The optional `EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE` in-process limiter is a local safety net and keys by TCP remote address only. - `/v1/metrics`, `/v1/audit-log`, and `/v1/admin/instance` are protected by server-side scopes and are not public. - API keys and collector keys are scoped, rotated, and stored outside source control. +- OIDC UserInfo validation, when used, sends only the supplied access token to + the configured provider endpoint and stores verification checks, not bearer + token values. - Customer portal access tokens are short-lived, scoped to one package, and handled as bearer secrets. - Generated customer packages use explicit redaction profiles and expiry. - Collector releases are pinned and have signature, SBOM, and vulnerability scan evidence when available. diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index df3331d..c5dcd7a 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -46,6 +46,8 @@ The example secrets are placeholders. Replace them before using shared or produc | `EVYDENCE_WORKER_POLL_INTERVAL` | No | `1s` | Worker outbox polling interval. | | `EVYDENCE_WORKER_BATCH_SIZE` | No | `10` | Maximum outbox jobs claimed per polling cycle. | | `EVYDENCE_WORKER_MAX_PAYLOAD_BYTES` | No | `20971520` | Maximum raw object payload size replayed by a worker job. | +| `EVYDENCE_OIDC_USERINFO_TIMEOUT_SECONDS` | No | `10` | Timeout for optional live OIDC UserInfo validation when `POST /v1/provider-verifications` includes `access_token`. | +| `EVYDENCE_OIDC_USERINFO_ALLOW_INSECURE_LOCALHOST` | Local only | `false` | Allows HTTP OIDC issuer/UserInfo endpoints only for localhost tests. Do not use for production. | | `EVYDENCE_SIGNING_KEY_MODE` | Production yes | `external` or `aws-kms` for production | Production rejects local plaintext signing-key mode. `external` uses the optional HTTPS signing gateway; `aws-kms` uses the built-in AWS KMS executor. | | `EVYDENCE_SIGNING_EXECUTOR_URL` | No | unset | Optional HTTPS signing gateway used by `POST /v1/signing-operations` when `external_signature` is omitted. The API sends subject metadata and `payload_hash`, not raw payload bytes. | | `EVYDENCE_SIGNING_EXECUTOR_TOKEN` | Signing gateway | unset | Optional bearer token for the signing gateway. Store outside source control and logs. | diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 73c9601..ee8caef 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -62,14 +62,16 @@ Known hardening work remains: matrix remains the source of truth for operation ids, scopes, idempotency, parameters, and request/response schemas; - production signing can use the HTTPS signing gateway executor or the built-in - AWS KMS signing executor, but non-AWS cloud KMS/HSM SDK adapters, live - provider API validation/group sync, and broad object-lock enforcement proof - remain provider- and deployment-dependent hardening areas. SSO credential - exchange can issue bearer sessions and HttpOnly cookies after local OIDC/SAML - verification against configured trust material, OIDC group claim values can - map to session-scoped roles without creating permanent role bindings, and - public transparency proof material can be fetched from a configured endpoint - and verified locally, but provider-specific trust semantics and availability + AWS KMS signing executor, but non-AWS cloud KMS/HSM SDK adapters, + provider-specific management API validation/group synchronization, and broad + object-lock enforcement proof remain provider- and deployment-dependent + hardening areas. SSO credential exchange can issue bearer sessions and + HttpOnly cookies after local OIDC/SAML verification against configured trust + material, OIDC group claim values can map to session-scoped roles without + creating permanent role bindings, provider verification can optionally call a + discovered OIDC UserInfo endpoint with a supplied access token, and public + transparency proof material can be fetched from a configured endpoint and + verified locally, but provider-specific trust semantics and availability remain deployment responsibilities; - the broader production exit review remains incomplete. @@ -202,13 +204,16 @@ implemented capabilities: custody behind a tenant-controlled signing service and do not send raw payload bytes; the AWS KMS executor signs stored SHA-256 payload hashes with KMS `MessageType=DIGEST`. -- Complete live provider API validation and optional group mapping where those - profiles are enabled. OIDC discovery/JWKS refresh is implemented for public - trust-material updates, manual JWKS and SAML signing-certificate rotation is - implemented through the SSO provider trust-material endpoint, SSO credential - exchange can issue bearer sessions plus HttpOnly cookies after local token or - assertion verification, OIDC group claim values can map to session-scoped - roles, and API-first session logout can revoke the current SSO bearer session. +- Complete provider-specific management API validation and external group + synchronization where those profiles are enabled. OIDC discovery/JWKS refresh + is implemented for public trust-material updates, manual JWKS and SAML + signing-certificate rotation is implemented through the SSO provider + trust-material endpoint, provider verification can optionally call OIDC + UserInfo with a supplied access token and record group-claim checks without + storing the token, SSO credential exchange can issue bearer sessions plus + HttpOnly cookies after local token or assertion verification, OIDC group + claim values can map to session-scoped roles, and API-first session logout + can revoke the current SSO bearer session. - Extend object-lock/WORM verification beyond the current S3/MinIO bucket-level checks plus optional sample-object retention checks where deployments require broader object-level legal hold proofs or provider policy evidence. diff --git a/docs/reference/release-candidate.md b/docs/reference/release-candidate.md index 7f71b5e..7221db6 100644 --- a/docs/reference/release-candidate.md +++ b/docs/reference/release-candidate.md @@ -65,5 +65,6 @@ production, and hosted SaaS production require additional review and controls. API-key pepper, externalized secrets, backup and restore rehearsal, monitoring, and documented incident response. - Keep service decomposition, HA/multi-writer operation, non-AWS KMS/HSM SDK - adapters, live provider validation, and broader object-lock proof listed as - unresolved hardening work until they are implemented and verified. + adapters, provider-specific management API/group synchronization, and broader + object-lock proof listed as unresolved hardening work until they are + implemented and verified. diff --git a/docs/reference/release-notes-v0.1.0-rc.1.md b/docs/reference/release-notes-v0.1.0-rc.1.md index 3f14a2f..1522bba 100644 --- a/docs/reference/release-notes-v0.1.0-rc.1.md +++ b/docs/reference/release-notes-v0.1.0-rc.1.md @@ -46,7 +46,8 @@ acceptance. - HA/multi-writer API operation is not supported in this profile. - The AWS KMS signing executor is included; non-AWS cloud KMS/HSM SDK adapters are not included. -- Live GitHub/GitLab provider API validation and external group +- OIDC UserInfo validation is available when a caller supplies an access token; + provider-specific management API validation and external group synchronization remain deployment-dependent. - Broader WORM/object-lock proof beyond configured S3/MinIO checks remains deployment-dependent. diff --git a/docs/sdk/README.md b/docs/sdk/README.md index efc0d52..8f3d66d 100644 --- a/docs/sdk/README.md +++ b/docs/sdk/README.md @@ -52,7 +52,7 @@ func createProduct() error { The helper rejects paths that do not start with `/v1/` and blank idempotency keys. Non-2xx responses return an error containing the HTTP status code; callers that need Problem Details bodies should use a generated or custom client. -The Go wrapper also exposes typed helpers for `CreateRelease`, `RegisterArtifact`, `CreateBuild`, `Readiness`, `ReleaseReadiness`, `CreateSSOProvider`, and `VerifyProviderIdentity`. `VerifyProviderIdentity` can carry an OIDC `id_token` or SAML `saml_assertion`; SDK errors intentionally include only the HTTP status code and not the response body. +The Go wrapper also exposes typed helpers for `CreateRelease`, `RegisterArtifact`, `CreateBuild`, `Readiness`, `ReleaseReadiness`, `CreateSSOProvider`, and `VerifyProviderIdentity`. `VerifyProviderIdentity` can carry an OIDC `id_token`, OIDC `access_token` for live UserInfo validation, or SAML `saml_assertion`; SDK errors intentionally include only the HTTP status code and not the response body. ## TypeScript diff --git a/internal/adapters/httpapi/future_handlers.go b/internal/adapters/httpapi/future_handlers.go index d8c229a..20d4b12 100644 --- a/internal/adapters/httpapi/future_handlers.go +++ b/internal/adapters/httpapi/future_handlers.go @@ -227,12 +227,13 @@ func (s *Server) verifyProviderIdentity(w http.ResponseWriter, r *http.Request) Subject string `json:"subject"` IDToken string `json:"id_token"` SAMLAssertion string `json:"saml_assertion"` + AccessToken string `json:"access_token"` } s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - record, err := s.ledger.VerifyProviderIdentity(ctx, actor, app.VerifyProviderIdentityInput{ProviderType: req.ProviderType, ProviderID: req.ProviderID, Subject: req.Subject, IDToken: req.IDToken, SAMLAssertion: req.SAMLAssertion}) + record, err := s.ledger.VerifyProviderIdentity(ctx, actor, app.VerifyProviderIdentityInput{ProviderType: req.ProviderType, ProviderID: req.ProviderID, Subject: req.Subject, IDToken: req.IDToken, SAMLAssertion: req.SAMLAssertion, AccessToken: req.AccessToken}) return http.StatusCreated, record, err }) } diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index d57a1e6..902050f 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -102,6 +102,7 @@ func registerCriticalSchemas(registry *specs.Registry) { "subject": map[string]any{"type": "string"}, "id_token": map[string]any{"type": "string", "description": "Optional OIDC ID token verified locally against the provider's configured static JWKS."}, "saml_assertion": map[string]any{"type": "string", "description": "Optional SAML assertion verified locally against configured SAML signing certificates."}, + "access_token": map[string]any{"type": "string", "description": "Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers."}, }, "provider_type", "provider_id", "subject")) registry.RegisterSchema("VerifyCheck", objectSchema(map[string]any{ "name": map[string]any{"type": "string"}, diff --git a/internal/adapters/identity/oidcuserinfo/oidcuserinfo.go b/internal/adapters/identity/oidcuserinfo/oidcuserinfo.go new file mode 100644 index 0000000..dfb6242 --- /dev/null +++ b/internal/adapters/identity/oidcuserinfo/oidcuserinfo.go @@ -0,0 +1,184 @@ +package oidcuserinfo + +import ( + "context" + "encoding/json" + "errors" + "io" + "net" + "net/http" + "net/url" + "strings" + "time" + + "github.com/aatuh/evydence/internal/app" + "github.com/aatuh/evydence/internal/domain" +) + +const defaultTimeout = 10 * time.Second + +type Config struct { + Timeout time.Duration + AllowInsecureForLocalhost bool + Client *http.Client +} + +type Validator struct { + client *http.Client + allowInsecureForLocalhost bool +} + +type discoveryDocument struct { + UserInfoEndpoint string `json:"userinfo_endpoint"` +} + +type userInfoDocument map[string]any + +func New(cfg Config) *Validator { + timeout := cfg.Timeout + if timeout <= 0 { + timeout = defaultTimeout + } + client := cfg.Client + if client == nil { + client = &http.Client{Timeout: timeout} + } + return &Validator{client: client, allowInsecureForLocalhost: cfg.AllowInsecureForLocalhost} +} + +func (v *Validator) ValidateProviderIdentity(ctx context.Context, req app.ProviderIdentityValidationRequest) (app.ProviderIdentityValidationResult, error) { + if v == nil || v.client == nil { + return app.ProviderIdentityValidationResult{}, app.ErrValidation + } + if strings.TrimSpace(req.ProviderType) != "oidc" || strings.TrimSpace(req.Subject) == "" || strings.TrimSpace(req.AccessToken) == "" || len(strings.TrimSpace(req.AccessToken)) > 16*1024 { + return app.ProviderIdentityValidationResult{}, app.ErrValidation + } + issuer, err := validateURL(req.Issuer, v.allowInsecureForLocalhost) + if err != nil { + return failed("oidc_issuer_url"), app.ErrValidation + } + discoveryURL := issuer.JoinPath(".well-known", "openid-configuration").String() + var discovery discoveryDocument + if err := v.getJSON(ctx, discoveryURL, "", &discovery); err != nil { + return failed("oidc_discovery_fetch"), app.ErrVerificationFailed + } + userInfoURL, err := validateURL(discovery.UserInfoEndpoint, v.allowInsecureForLocalhost) + if err != nil { + return failed("oidc_userinfo_endpoint"), app.ErrVerificationFailed + } + var info userInfoDocument + if err := v.getJSON(ctx, userInfoURL.String(), req.AccessToken, &info); err != nil { + return failed("oidc_userinfo_fetch"), app.ErrVerificationFailed + } + subject, _ := info["sub"].(string) + if strings.TrimSpace(subject) == "" || subject != strings.TrimSpace(req.Subject) { + return app.ProviderIdentityValidationResult{Checks: []domain.VerifyCheck{ + {Name: "oidc_discovery_fetch", Result: "passed"}, + {Name: "oidc_userinfo_fetch", Result: "passed"}, + {Name: "oidc_userinfo_subject", Result: "failed"}, + }, Limitations: limitations()}, app.ErrVerificationFailed + } + groups := groupsFromUserInfo(info, req.GroupsClaim) + checks := []domain.VerifyCheck{ + {Name: "oidc_discovery_fetch", Result: "passed"}, + {Name: "oidc_userinfo_fetch", Result: "passed"}, + {Name: "oidc_userinfo_subject", Result: "passed"}, + } + if strings.TrimSpace(req.GroupsClaim) != "" { + if len(groups) == 0 { + checks = append(checks, domain.VerifyCheck{Name: "oidc_userinfo_groups", Result: "warning", Detail: "Configured groups claim was absent or empty in UserInfo."}) + } else { + checks = append(checks, domain.VerifyCheck{Name: "oidc_userinfo_groups", Result: "passed"}) + } + } + return app.ProviderIdentityValidationResult{Checks: checks, Groups: groups, Limitations: limitations()}, nil +} + +func (v *Validator) getJSON(ctx context.Context, endpoint, bearerToken string, target any) error { + httpReq, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil) + if err != nil { + return err + } + httpReq.Header.Set("Accept", "application/json") + if bearerToken != "" { + httpReq.Header.Set("Authorization", "Bearer "+bearerToken) + } + resp, err := v.client.Do(httpReq) + if err != nil { + return errors.New("provider request failed") + } + defer resp.Body.Close() + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + _, _ = io.Copy(io.Discard, io.LimitReader(resp.Body, 4096)) + return errors.New("provider request failed") + } + decoder := json.NewDecoder(io.LimitReader(resp.Body, 1<<20)) + if err := decoder.Decode(target); err != nil { + return errors.New("provider response decode failed") + } + return nil +} + +func validateURL(value string, allowInsecureLocalhost bool) (*url.URL, error) { + parsed, err := url.Parse(strings.TrimSpace(value)) + if err != nil || parsed.Scheme == "" || parsed.Host == "" { + return nil, errors.New("invalid provider url") + } + if parsed.Scheme == "https" { + return parsed, nil + } + if parsed.Scheme == "http" && allowInsecureLocalhost && localhostHost(parsed.Hostname()) { + return parsed, nil + } + return nil, errors.New("provider url must use https") +} + +func localhostHost(host string) bool { + if host == "localhost" { + return true + } + ip := net.ParseIP(host) + return ip != nil && ip.IsLoopback() +} + +func groupsFromUserInfo(info userInfoDocument, claim string) []string { + claim = strings.TrimSpace(claim) + if claim == "" { + return nil + } + raw, ok := info[claim] + if !ok { + return nil + } + groups := []string{} + switch typed := raw.(type) { + case []any: + for _, item := range typed { + if value, ok := item.(string); ok && strings.TrimSpace(value) != "" { + groups = append(groups, strings.TrimSpace(value)) + } + } + case []string: + for _, item := range typed { + if strings.TrimSpace(item) != "" { + groups = append(groups, strings.TrimSpace(item)) + } + } + case string: + if strings.TrimSpace(typed) != "" { + groups = append(groups, strings.TrimSpace(typed)) + } + } + return groups +} + +func failed(name string) app.ProviderIdentityValidationResult { + return app.ProviderIdentityValidationResult{ + Checks: []domain.VerifyCheck{{Name: name, Result: "failed"}}, + Limitations: limitations(), + } +} + +func limitations() []string { + return []string{"Live OIDC UserInfo validation used a supplied bearer access token; Evydence does not store the token and does not synchronize provider groups permanently."} +} diff --git a/internal/adapters/identity/oidcuserinfo/oidcuserinfo_test.go b/internal/adapters/identity/oidcuserinfo/oidcuserinfo_test.go new file mode 100644 index 0000000..ea5b8c9 --- /dev/null +++ b/internal/adapters/identity/oidcuserinfo/oidcuserinfo_test.go @@ -0,0 +1,92 @@ +package oidcuserinfo + +import ( + "encoding/json" + "net/http" + "net/http/httptest" + "strings" + "testing" + + "github.com/aatuh/evydence/internal/app" +) + +func TestValidateProviderIdentityFetchesUserInfoAndGroups(t *testing.T) { + var gotAuth string + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case "/.well-known/openid-configuration": + _ = json.NewEncoder(w).Encode(map[string]any{"userinfo_endpoint": "http://" + r.Host + "/userinfo"}) + case "/userinfo": + gotAuth = r.Header.Get("Authorization") + _ = json.NewEncoder(w).Encode(map[string]any{"sub": "sub-1", "groups": []string{"security", "engineering"}}) + default: + http.NotFound(w, r) + } + })) + defer server.Close() + + validator := New(Config{AllowInsecureForLocalhost: true}) + result, err := validator.ValidateProviderIdentity(t.Context(), app.ProviderIdentityValidationRequest{ + ProviderType: "oidc", + Issuer: server.URL, + Subject: "sub-1", + GroupsClaim: "groups", + AccessToken: "secret-token", + }) + if err != nil { + t.Fatal(err) + } + if gotAuth != "Bearer secret-token" { + t.Fatalf("authorization header = %q", gotAuth) + } + if len(result.Groups) != 2 || result.Groups[0] != "security" { + t.Fatalf("groups = %#v", result.Groups) + } + if len(result.Checks) < 4 || result.Checks[2].Name != "oidc_userinfo_subject" || result.Checks[2].Result != "passed" { + t.Fatalf("checks = %#v", result.Checks) + } +} + +func TestValidateProviderIdentityRejectsSubjectMismatch(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case "/.well-known/openid-configuration": + _ = json.NewEncoder(w).Encode(map[string]any{"userinfo_endpoint": "http://" + r.Host + "/userinfo"}) + case "/userinfo": + _ = json.NewEncoder(w).Encode(map[string]any{"sub": "other"}) + } + })) + defer server.Close() + + validator := New(Config{AllowInsecureForLocalhost: true}) + result, err := validator.ValidateProviderIdentity(t.Context(), app.ProviderIdentityValidationRequest{ProviderType: "oidc", Issuer: server.URL, Subject: "sub-1", AccessToken: "secret-token"}) + if err == nil { + t.Fatal("expected verification failure") + } + if len(result.Checks) != 3 || result.Checks[2].Result != "failed" { + t.Fatalf("checks = %#v", result.Checks) + } +} + +func TestValidateProviderIdentityRequiresHTTPSExceptLocalhostOverride(t *testing.T) { + validator := New(Config{}) + if _, err := validator.ValidateProviderIdentity(t.Context(), app.ProviderIdentityValidationRequest{ProviderType: "oidc", Issuer: "http://example.com", Subject: "sub-1", AccessToken: "secret-token"}); err == nil { + t.Fatal("expected insecure remote issuer to be rejected") + } +} + +func TestValidateProviderIdentityHidesBearerTokenFromErrors(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.Error(w, "token secret-token rejected", http.StatusUnauthorized) + })) + defer server.Close() + + validator := New(Config{AllowInsecureForLocalhost: true}) + _, err := validator.ValidateProviderIdentity(t.Context(), app.ProviderIdentityValidationRequest{ProviderType: "oidc", Issuer: server.URL, Subject: "sub-1", AccessToken: "secret-token"}) + if err == nil { + t.Fatal("expected verification failure") + } + if strings.Contains(err.Error(), "secret-token") { + t.Fatalf("error leaked token: %v", err) + } +} diff --git a/internal/app/future_extensions.go b/internal/app/future_extensions.go index b936a6e..7be16bd 100644 --- a/internal/app/future_extensions.go +++ b/internal/app/future_extensions.go @@ -14,6 +14,7 @@ import ( "encoding/pem" "encoding/xml" "errors" + "fmt" "math/big" "strings" "time" @@ -103,6 +104,7 @@ type VerifyProviderIdentityInput struct { Subject string IDToken string SAMLAssertion string + AccessToken string } func (l *Ledger) CreateEvidenceSummary(ctx context.Context, actor domain.Actor, in CreateEvidenceSummaryInput) (domain.EvidenceSummary, error) { @@ -1233,57 +1235,99 @@ func (l *Ledger) VerifyProviderIdentity(ctx context.Context, actor domain.Actor, providerType, providerID, subject := strings.TrimSpace(in.ProviderType), strings.TrimSpace(in.ProviderID), strings.TrimSpace(in.Subject) idToken := strings.TrimSpace(in.IDToken) samlAssertion := strings.TrimSpace(in.SAMLAssertion) + accessToken := strings.TrimSpace(in.AccessToken) if providerType == "" || providerID == "" || subject == "" { return domain.ProviderVerification{}, ErrValidation } - if (providerType == "oidc" && samlAssertion != "") || (providerType == "saml" && idToken != "") { + if len(accessToken) > 16*1024 { + return domain.ProviderVerification{}, ErrValidation + } + if (providerType == "oidc" && samlAssertion != "") || (providerType == "saml" && (idToken != "" || accessToken != "")) { return domain.ProviderVerification{}, ErrValidation } l.mu.Lock() - defer l.mu.Unlock() - checks := []domain.VerifyCheck{} - result := "passed" + var provider domain.SSOProvider + var providerFound bool + var verifiedLinkFound bool switch providerType { case "oidc", "saml": - provider, ok := l.ssoProviders[providerID] - if !ok || provider.TenantID != actor.TenantID || provider.Type != providerType { + provider, providerFound = l.ssoProviders[providerID] + if !providerFound || provider.TenantID != actor.TenantID || provider.Type != providerType { + l.mu.Unlock() return domain.ProviderVerification{}, ErrNotFound } - if idToken != "" { - tokenChecks, err := verifyOIDCIDToken(provider, subject, idToken, l.now()) - checks = append(checks, tokenChecks...) - if err != nil { - result = "failed" - } - } - if samlAssertion != "" { - assertionChecks, err := verifySAMLAssertion(provider, subject, samlAssertion, l.now()) - checks = append(checks, assertionChecks...) - if err != nil { - result = "failed" - } - } - found := false for _, link := range l.identityLinks { if link.TenantID == actor.TenantID && link.ProviderID == provider.ID && link.Subject == subject && link.Verified { - found = true + verifiedLinkFound = true break } } - if found { - checks = append(checks, domain.VerifyCheck{Name: "verified_identity_link", Result: "passed"}) - } else { - result = "failed" - checks = append(checks, domain.VerifyCheck{Name: "verified_identity_link", Result: "failed"}) - } default: + l.mu.Unlock() return domain.ProviderVerification{}, ErrValidation } + l.mu.Unlock() + + checks := []domain.VerifyCheck{} + result := "passed" + now := l.now() + if idToken != "" { + tokenChecks, err := verifyOIDCIDToken(provider, subject, idToken, now) + checks = append(checks, tokenChecks...) + if err != nil { + result = "failed" + } + } + if samlAssertion != "" { + assertionChecks, err := verifySAMLAssertion(provider, subject, samlAssertion, now) + checks = append(checks, assertionChecks...) + if err != nil { + result = "failed" + } + } limitations := []string{"Verification uses stored provider metadata and configured local token/assertion trust roots; no live provider API or discovery call is made."} if idToken == "" && samlAssertion == "" { limitations = []string{"Verification is limited to stored provider/link metadata because no provider token was supplied."} } + if accessToken != "" { + if l.providerAPI == nil { + result = "failed" + checks = append(checks, domain.VerifyCheck{Name: "live_provider_api_configured", Result: "failed"}) + limitations = []string{"A provider access token was supplied, but no live provider API validator is configured."} + } else { + validation, err := l.providerAPI.ValidateProviderIdentity(ctx, ProviderIdentityValidationRequest{ + TenantID: actor.TenantID, + ProviderID: provider.ID, + ProviderType: provider.Type, + Issuer: provider.Issuer, + Subject: subject, + GroupsClaim: provider.GroupsClaim, + AccessToken: accessToken, + }) + checks = append(checks, validation.Checks...) + if len(validation.Groups) > 0 && len(resourceGrantsForProviderGroups(provider, validation.Groups)) > 0 { + checks = append(checks, domain.VerifyCheck{Name: "mapped_provider_api_groups", Result: "passed", Detail: fmt.Sprintf("%d provider API group role mapping(s) can be applied to sessions", len(resourceGrantsForProviderGroups(provider, validation.Groups)))}) + } + if len(validation.Limitations) > 0 { + limitations = validation.Limitations + } else { + limitations = []string{"Live provider API validation used a supplied OIDC access token; no access token is stored in Evydence records."} + } + if err != nil { + result = "failed" + } + } + } + if verifiedLinkFound { + checks = append(checks, domain.VerifyCheck{Name: "verified_identity_link", Result: "passed"}) + } else { + result = "failed" + checks = append(checks, domain.VerifyCheck{Name: "verified_identity_link", Result: "failed"}) + } + record := domain.ProviderVerification{ID: newID("pvr"), TenantID: actor.TenantID, ProviderType: providerType, ProviderID: providerID, Subject: subject, Result: result, Checks: checks, Limitations: limitations, SchemaVersion: domain.ProviderVerificationVersion, CreatedAt: l.now()} + l.mu.Lock() + defer l.mu.Unlock() l.providerVerifications[record.ID] = record _, _ = l.appendChainLocked(actor.TenantID, "provider_identity.verified", "provider_identity", record.ID, actorType(actor), actorID(actor), "", "") if err := l.persistLocked(ctx); err != nil { diff --git a/internal/app/future_extensions_test.go b/internal/app/future_extensions_test.go index 46bbcf9..9025f3d 100644 --- a/internal/app/future_extensions_test.go +++ b/internal/app/future_extensions_test.go @@ -3,6 +3,7 @@ package app import ( "context" "encoding/hex" + "encoding/json" "errors" "strings" "testing" @@ -297,6 +298,20 @@ func (f *fakeSigningExecutor) Sign(_ context.Context, request SigningRequest) (S }, nil } +type fakeProviderIdentityValidator struct { + request ProviderIdentityValidationRequest + result ProviderIdentityValidationResult + err error +} + +func (f *fakeProviderIdentityValidator) ValidateProviderIdentity(_ context.Context, request ProviderIdentityValidationRequest) (ProviderIdentityValidationResult, error) { + f.request = request + if f.err != nil { + return f.result, f.err + } + return f.result, nil +} + type fakeTransparencyProofFetcher struct { request TransparencyProofRequest result TransparencyProofResult @@ -335,6 +350,51 @@ func TestSigningOperationCanExecuteConfiguredSignerWithoutPrivateKey(t *testing. } } +func TestProviderVerificationCanUseLiveOIDCUserInfoWithoutPersistingToken(t *testing.T) { + validator := &fakeProviderIdentityValidator{result: ProviderIdentityValidationResult{ + Checks: []domain.VerifyCheck{{Name: "oidc_userinfo_subject", Result: "passed"}}, + Groups: []string{"security"}, + Limitations: []string{"live provider API validation was used"}, + }} + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow, ProviderAPI: validator}) + ctx := context.Background() + actor, _, _ := setupReleaseRiskFixture(t, ledger) + provider, err := ledger.CreateSSOProvider(ctx, actor, CreateSSOProviderInput{Name: "OIDC", Type: "oidc", Issuer: "https://idp.example.test", ClientID: "client", GroupsClaim: "groups", RoleMapping: map[string]string{"security": "security_engineer"}}) + if err != nil { + t.Fatalf("provider: %v", err) + } + user, err := ledger.CreateUser(ctx, actor, CreateUserInput{Email: "user@example.test", DisplayName: "User"}) + if err != nil { + t.Fatalf("user: %v", err) + } + if _, err := ledger.LinkSSOIdentity(ctx, actor, LinkSSOIdentityInput{UserID: user.ID, ProviderID: provider.ID, Subject: "sub-1", Email: user.Email, Verified: true}); err != nil { + t.Fatalf("identity link: %v", err) + } + verification, err := ledger.VerifyProviderIdentity(ctx, actor, VerifyProviderIdentityInput{ProviderType: "oidc", ProviderID: provider.ID, Subject: "sub-1", AccessToken: "access-token-secret"}) + if err != nil { + t.Fatalf("provider verification: %v", err) + } + if validator.request.AccessToken != "access-token-secret" || validator.request.Subject != "sub-1" { + t.Fatalf("validator request = %#v", validator.request) + } + if verification.Result != "passed" || len(verification.Checks) < 3 { + t.Fatalf("verification = %#v", verification) + } + for _, check := range verification.Checks { + if strings.Contains(check.Detail, "access-token-secret") { + t.Fatalf("check leaked access token: %#v", check) + } + } + ledger.mu.Lock() + state := ledger.snapshotLocked() + ledger.mu.Unlock() + stored := state.ProviderVerifications[verification.ID] + encoded, _ := json.Marshal(stored) + if strings.Contains(string(encoded), "access-token-secret") { + t.Fatalf("stored provider verification leaked access token: %s", encoded) + } +} + func TestSigningOperationRequiresSignatureWhenNoExecutorConfigured(t *testing.T) { ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) ctx := context.Background() diff --git a/internal/app/ledger.go b/internal/app/ledger.go index 98a043c..ff47f48 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -69,6 +69,7 @@ type Config struct { Retention ObjectRetentionVerifier Signer SigningExecutor OIDC OIDCDiscoveryClient + ProviderAPI ProviderIdentityValidator Transparency TransparencyProofFetcher Outbox Outbox // WorkerOwnedParserSideEffects stores accepted parser records first and @@ -86,6 +87,7 @@ type Ledger struct { retention ObjectRetentionVerifier signer SigningExecutor oidc OIDCDiscoveryClient + providerAPI ProviderIdentityValidator transparencyProofs TransparencyProofFetcher outbox Outbox workerOwnedParsers bool @@ -212,6 +214,7 @@ func NewLedgerWithError(cfg Config) (*Ledger, error) { retention: retention, signer: cfg.Signer, oidc: cfg.OIDC, + providerAPI: cfg.ProviderAPI, transparencyProofs: cfg.Transparency, outbox: cfg.Outbox, workerOwnedParsers: cfg.WorkerOwnedParserSideEffects, diff --git a/internal/app/ports.go b/internal/app/ports.go index f0697ac..b8f72a2 100644 --- a/internal/app/ports.go +++ b/internal/app/ports.go @@ -41,6 +41,10 @@ type OIDCDiscoveryClient interface { FetchOIDCTrustMaterial(context.Context, OIDCDiscoveryRequest) (OIDCDiscoveryResult, error) } +type ProviderIdentityValidator interface { + ValidateProviderIdentity(context.Context, ProviderIdentityValidationRequest) (ProviderIdentityValidationResult, error) +} + type TransparencyProofFetcher interface { FetchTransparencyProof(context.Context, TransparencyProofRequest) (TransparencyProofResult, error) } @@ -79,6 +83,22 @@ type OIDCDiscoveryResult struct { Limitations []string } +type ProviderIdentityValidationRequest struct { + TenantID string + ProviderID string + ProviderType string + Issuer string + Subject string + GroupsClaim string + AccessToken string +} + +type ProviderIdentityValidationResult struct { + Checks []domain.VerifyCheck + Groups []string + Limitations []string +} + type TransparencyProofRequest struct { TenantID string LogID string diff --git a/openapi.yaml b/openapi.yaml index 36241c8..7a4d2bf 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/sdk/go/evydence/client.go b/sdk/go/evydence/client.go index 03dd214..6204292 100644 --- a/sdk/go/evydence/client.go +++ b/sdk/go/evydence/client.go @@ -70,6 +70,7 @@ type VerifyProviderIdentityRequest struct { Subject string `json:"subject"` IDToken string `json:"id_token,omitempty"` SAMLAssertion string `json:"saml_assertion,omitempty"` + AccessToken string `json:"access_token,omitempty"` } func (c Client) Post(ctx context.Context, path, idempotencyKey string, payload any, out any) error { diff --git a/sdk/typescript/client.ts b/sdk/typescript/client.ts index 08563b5..603ca5c 100644 --- a/sdk/typescript/client.ts +++ b/sdk/typescript/client.ts @@ -57,6 +57,7 @@ export type VerifyProviderIdentityRequest = { subject: string; id_token?: string; saml_assertion?: string; + access_token?: string; }; export class EvydenceClient { From 632af590f45bf4483bda35bb21b7658ca3749e30 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 10:11:41 +0300 Subject: [PATCH 131/287] feat: verify sample object legal hold --- CHANGELOG.md | 7 +- README.md | 2 +- docs/api.md | 2 +- docs/architecture.md | 2 +- docs/operations.md | 2 +- docs/production-hardening.md | 2 +- docs/reference/configuration.md | 7 +- docs/reference/production-readiness.md | 7 +- docs/reference/release-candidate.md | 4 +- docs/reference/release-notes-v0.1.0-rc.1.md | 4 +- internal/adapters/httpapi/openapi.go | 32 ++++---- internal/adapters/httpapi/router.go | 13 ++-- internal/adapters/objectstore/s3/s3.go | 20 ++++- internal/adapters/objectstore/s3/s3_test.go | 42 ++++++++++- internal/adapters/postgres/store.go | 11 +-- internal/adapters/postgres/store_test.go | 6 +- internal/app/integrity_runtime.go | 73 ++++++++++--------- internal/app/integrity_runtime_test.go | 34 +++++++++ internal/app/ports.go | 11 +-- internal/domain/domain.go | 1 + ...00100_object_retention_legal_hold.down.sql | 4 + ...1000100_object_retention_legal_hold.up.sql | 6 ++ openapi.yaml | 2 +- 23 files changed, 204 insertions(+), 90 deletions(-) create mode 100644 migrations/20260531000100_object_retention_legal_hold.down.sql create mode 100644 migrations/20260531000100_object_retention_legal_hold.up.sql diff --git a/CHANGELOG.md b/CHANGELOG.md index 6afb796..d4070b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,8 @@ Release-candidate tagging requires the production gate and checklist in - Optional OIDC UserInfo live provider validation for `POST /v1/provider-verifications` using a supplied access token that is not persisted. +- Object-retention policies can require sample-object legal hold verification + with S3/MinIO providers that expose object legal-hold status. ### Known Limits @@ -50,5 +52,6 @@ Release-candidate tagging requires the production gate and checklist in response. - Service decomposition, HA/multi-writer operation, non-AWS KMS/HSM SDK adapters, provider-specific management API/group synchronization, broader - object-lock proof, and final exit review remain production-hardening work - after the release-candidate gate. + object-lock proof beyond configured bucket/sample-object checks, and final + exit review remain production-hardening work after the release-candidate + gate. diff --git a/README.md b/README.md index 470de99..13490f9 100644 --- a/README.md +++ b/README.md @@ -109,4 +109,4 @@ make postgres-integration-test `make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. -`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required release-candidate evidence, but it does not by itself close the remaining service decomposition, non-AWS KMS/HSM SDK providers, provider-specific management API/group synchronization, object-lock enforcement, HA, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. Critical runtime mutations for tenants, credential hashes, idempotency, audit-chain entries, release bundles, signatures, verification results, vulnerability decisions, and outbox jobs use focused PostgreSQL write paths when available. Release-ledger and evidence-core mutations for products, projects, releases, artifacts, evidence items, evidence lifecycle events, SBOMs, vulnerability scans, OpenAPI contracts, VEX documents, audit-chain entries, and parser outbox jobs also use focused PostgreSQL write paths when available. Remaining aggregate persistence calls use PostgreSQL relational synchronization without writing the compatibility snapshot when that store is configured. Current self-hosted production guidance still uses a single API writer replica and allows worker replicas to scale through PostgreSQL outbox row locking. +`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required release-candidate evidence, but it does not by itself close the remaining service decomposition, non-AWS KMS/HSM SDK providers, provider-specific management API/group synchronization, broader object-lock enforcement beyond configured bucket/sample-object checks, HA, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. Critical runtime mutations for tenants, credential hashes, idempotency, audit-chain entries, release bundles, signatures, verification results, vulnerability decisions, and outbox jobs use focused PostgreSQL write paths when available. Release-ledger and evidence-core mutations for products, projects, releases, artifacts, evidence items, evidence lifecycle events, SBOMs, vulnerability scans, OpenAPI contracts, VEX documents, audit-chain entries, and parser outbox jobs also use focused PostgreSQL write paths when available. Remaining aggregate persistence calls use PostgreSQL relational synchronization without writing the compatibility snapshot when that store is configured. Current self-hosted production guidance still uses a single API writer replica and allows worker replicas to scale through PostgreSQL outbox row locking. diff --git a/docs/api.md b/docs/api.md index e23c63f..1440392 100644 --- a/docs/api.md +++ b/docs/api.md @@ -400,7 +400,7 @@ Source snapshots capture submitted provider metadata. They do not call provider | `POST` | `/v1/public-transparency-log-entries` | Record published public transparency log entry metadata. | | `POST` | `/v1/public-transparency-log-entries/{id}/verify` | Verify operator-supplied RFC6962-style public transparency inclusion proof material. | | `POST` | `/v1/public-transparency-log-entries/{id}/fetch-proof` | Fetch proof material from the configured transparency endpoint and verify it locally. | -| `POST` | `/v1/object-retention-policies` | Record retention policy intent with optional tenant-prefixed sample object key. | +| `POST` | `/v1/object-retention-policies` | Record retention policy intent with optional tenant-prefixed sample object key and legal-hold proof requirement. | | `POST` | `/v1/object-retention-policies/{id}/verify` | Record provider verification transition. | | `POST` | `/v1/legal-holds` | Record legal hold. | | `POST` | `/v1/retention-overrides` | Record retention override. | diff --git a/docs/architecture.md b/docs/architecture.md index 8dc9e5e..7fa23f4 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -48,7 +48,7 @@ Evidence summaries, questionnaire drafts, graph snapshots, PDF packages, and ano GitHub OIDC subject metadata can be captured, and stored OIDC/SAML identity links can be verified against tenant metadata. OIDC provider records can include public JWKS material for local EdDSA or RS256 ID-token signature and claim verification, and SAML provider records can include PEM signing certificates for local assertion signature and claim verification. Trust material can be rotated without recreating the provider. Live provider API verification, discovery, browser login callbacks, and group synchronization remain trust boundaries outside those records. Collector supply-chain records track pinned collector versions with signature, SBOM, and scan evidence where available; commercial and marketplace collector definitions add extension metadata without granting provider trust. -Air-gapped import-bundle workflows preserve the same tenant-scoped import path after controlled transfer. Object-retention policy APIs record tenant-scoped retention intent and, when the S3/MinIO object-store adapter is configured, verify bucket versioning plus default object-lock mode and duration. Policies can also name a tenant-prefixed sample object key for object-level retention checks where the provider supports them. Those checks are evidence for the configured bucket and sample object only; WORM/object-lock enforcement, IAM policy, lifecycle rules, and deployment-specific retention review remain operator responsibilities. +Air-gapped import-bundle workflows preserve the same tenant-scoped import path after controlled transfer. Object-retention policy APIs record tenant-scoped retention intent and, when the S3/MinIO object-store adapter is configured, verify bucket versioning plus default object-lock mode and duration. Policies can also name a tenant-prefixed sample object key for object-level retention and optional legal-hold checks where the provider supports them. Those checks are evidence for the configured bucket and sample object only; WORM/object-lock enforcement, IAM policy, lifecycle rules, and deployment-specific retention review remain operator responsibilities. ## Limitations diff --git a/docs/operations.md b/docs/operations.md index 9f2417f..5a7698c 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -31,6 +31,6 @@ This operator index points to the canonical references for running Evydence. Kee - API keys, collector keys, SSO session tokens, and customer portal access tokens are bearer secrets. Do not place them in logs, documentation, long-lived build output, or customer packages. - Customer portal access tokens are returned once by `POST /v1/customer-portal/access`, expire, and are stored as hashes. Deployments should still use reverse-proxy or API-gateway throttling for the unauthenticated portal endpoint. - Human SSO session records are admin-managed, authenticated SSO sessions can revoke themselves through API-first logout, and SSO credential exchange can set an HttpOnly session cookie after locally verifying an OIDC ID token or SAML assertion against tenant-configured trust material. OIDC group claim values can be captured on the session and mapped to configured roles without creating permanent role bindings from token claims. Current endpoints can refresh OIDC public JWKS from discovery metadata, but they do not implement live provider API validation or external group synchronization. -- Object-retention APIs record and verify retention intent for tenant-prefixed object paths. Enforcing WORM or object-lock settings remains the responsibility of the configured object store and deployment policy. +- Object-retention APIs record and verify retention intent for tenant-prefixed object paths. S3/MinIO verification can check bucket defaults plus sample-object retention and legal hold where configured. Enforcing WORM or object-lock settings remains the responsibility of the configured object store and deployment policy. Evydence operations support evidence organization, review, and tamper-evident records. Operational checks do not replace external audit review, secret management, backup testing, or provider verification. diff --git a/docs/production-hardening.md b/docs/production-hardening.md index 3a61467..0216803 100644 --- a/docs/production-hardening.md +++ b/docs/production-hardening.md @@ -18,7 +18,7 @@ These checks are enforced by API startup. See [Configuration](reference/configur - PostgreSQL is external, backed up, monitored, and restored in a test environment. - Object storage is external S3/MinIO-compatible storage with tenant-prefixed paths, encryption, lifecycle policy, and retention/object-lock policy where required. -- S3/MinIO object-retention policy verification has been run for required tenant prefixes, and records show bucket versioning plus default object-lock mode/duration checks with documented limitations. +- S3/MinIO object-retention policy verification has been run for required tenant prefixes, and records show bucket versioning, default object-lock mode/duration, sample object retention, and sample object legal-hold checks where those controls are required, with documented limitations. - Ingress terminates TLS and does not expose internal diagnostics. - Edge rate limiting is configured at the reverse proxy or ingress. The optional `EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE` in-process limiter is a local safety net and keys by TCP remote address only. - `/v1/metrics`, `/v1/audit-log`, and `/v1/admin/instance` are protected by server-side scopes and are not public. diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index c5dcd7a..c0689c0 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -92,8 +92,11 @@ later repository decomposition work. When `EVYDENCE_OBJECT_STORE=s3` or `minio`, object-retention policy verification uses the same S3/MinIO client to check bucket versioning and default -object-lock settings. The resulting policy record includes verification checks -and limitations. The check is bucket-level: operators still need to review +object-lock settings. When the policy names a tenant-prefixed sample object, +the verifier also checks object-level retention; when `require_legal_hold` is +true, it checks that legal hold is enabled for that sample object. The resulting +policy record includes verification checks and limitations. These checks cover +the configured bucket and sample object only: operators still need to review bucket creation mode, IAM policy, lifecycle rules, backups, and any deployment-specific WORM requirements. diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index ee8caef..21181e5 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -64,7 +64,8 @@ Known hardening work remains: - production signing can use the HTTPS signing gateway executor or the built-in AWS KMS signing executor, but non-AWS cloud KMS/HSM SDK adapters, provider-specific management API validation/group synchronization, and broad - object-lock enforcement proof remain provider- and deployment-dependent + object-lock enforcement proof beyond bucket plus sample-object retention/legal-hold + checks remain provider- and deployment-dependent hardening areas. SSO credential exchange can issue bearer sessions and HttpOnly cookies after local OIDC/SAML verification against configured trust material, OIDC group claim values can map to session-scoped roles without @@ -215,8 +216,8 @@ implemented capabilities: claim values can map to session-scoped roles, and API-first session logout can revoke the current SSO bearer session. - Extend object-lock/WORM verification beyond the current S3/MinIO bucket-level - checks plus optional sample-object retention checks where deployments require - broader object-level legal hold proofs or provider policy evidence. + checks plus optional sample-object retention and legal-hold checks where + deployments require broader provider policy evidence. - Run final product, codebase, security, documentation, and test audits before changing release status beyond controlled self-hosted production candidate. diff --git a/docs/reference/release-candidate.md b/docs/reference/release-candidate.md index 7221db6..00e20ae 100644 --- a/docs/reference/release-candidate.md +++ b/docs/reference/release-candidate.md @@ -66,5 +66,5 @@ production, and hosted SaaS production require additional review and controls. monitoring, and documented incident response. - Keep service decomposition, HA/multi-writer operation, non-AWS KMS/HSM SDK adapters, provider-specific management API/group synchronization, and broader - object-lock proof listed as unresolved hardening work until they are - implemented and verified. + object-lock proof beyond configured bucket/sample-object checks listed as + unresolved hardening work until they are implemented and verified. diff --git a/docs/reference/release-notes-v0.1.0-rc.1.md b/docs/reference/release-notes-v0.1.0-rc.1.md index 1522bba..379d458 100644 --- a/docs/reference/release-notes-v0.1.0-rc.1.md +++ b/docs/reference/release-notes-v0.1.0-rc.1.md @@ -49,7 +49,7 @@ acceptance. - OIDC UserInfo validation is available when a caller supplies an access token; provider-specific management API validation and external group synchronization remain deployment-dependent. -- Broader WORM/object-lock proof beyond configured S3/MinIO checks remains - deployment-dependent. +- Broader WORM/object-lock proof beyond configured S3/MinIO bucket and + sample-object retention/legal-hold checks remains deployment-dependent. - Operators must run backup and restore rehearsals for their target infrastructure before relying on this in production. diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 902050f..23f5acc 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -196,23 +196,25 @@ func registerCriticalSchemas(registry *specs.Registry) { }, "id", "tenant_id", "batch_id", "provider", "timestamp_hash", "state", "schema_version", "created_at")) registry.RegisterSchema("TransparencyCheckpointEnvelope", dataEnvelopeSchema("#/components/schemas/TransparencyCheckpoint")) registry.RegisterSchema("CreateObjectRetentionPolicyRequest", objectSchema(map[string]any{ - "name": map[string]any{"type": "string"}, - "object_prefix": map[string]any{"type": "string"}, - "object_key": map[string]any{"type": "string", "description": "Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store."}, - "mode": map[string]any{"type": "string", "enum": []string{"governance", "compliance"}}, - "retention_days": map[string]any{"type": "integer", "minimum": 1}, + "name": map[string]any{"type": "string"}, + "object_prefix": map[string]any{"type": "string"}, + "object_key": map[string]any{"type": "string", "description": "Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store."}, + "require_legal_hold": map[string]any{"type": "boolean", "description": "When true, the sample object key must have provider-reported legal hold enabled."}, + "mode": map[string]any{"type": "string", "enum": []string{"governance", "compliance"}}, + "retention_days": map[string]any{"type": "integer", "minimum": 1}, }, "name", "mode", "retention_days")) registry.RegisterSchema("ObjectRetentionPolicy", objectSchema(map[string]any{ - "id": map[string]any{"type": "string"}, - "tenant_id": map[string]any{"type": "string"}, - "name": map[string]any{"type": "string"}, - "object_prefix": map[string]any{"type": "string"}, - "object_key": map[string]any{"type": "string"}, - "mode": map[string]any{"type": "string"}, - "retention_days": map[string]any{"type": "integer"}, - "status": map[string]any{"type": "string"}, - "verified_at": map[string]any{"type": "string", "format": "date-time"}, - "verification_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "object_prefix": map[string]any{"type": "string"}, + "object_key": map[string]any{"type": "string"}, + "require_legal_hold": map[string]any{"type": "boolean"}, + "mode": map[string]any{"type": "string"}, + "retention_days": map[string]any{"type": "integer"}, + "status": map[string]any{"type": "string"}, + "verified_at": map[string]any{"type": "string", "format": "date-time"}, + "verification_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, "verification_checks": map[string]any{ "type": "array", "items": map[string]any{"$ref": "#/components/schemas/VerifyCheck"}, diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index 97c5781..1bcdca3 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -1851,17 +1851,18 @@ func (s *Server) createTransparencyCheckpoint(w http.ResponseWriter, r *http.Req func (s *Server) createObjectRetentionPolicy(w http.ResponseWriter, r *http.Request) { var req struct { - Name string `json:"name"` - ObjectPrefix string `json:"object_prefix"` - ObjectKey string `json:"object_key"` - Mode string `json:"mode"` - RetentionDays int `json:"retention_days"` + Name string `json:"name"` + ObjectPrefix string `json:"object_prefix"` + ObjectKey string `json:"object_key"` + RequireLegalHold bool `json:"require_legal_hold"` + Mode string `json:"mode"` + RetentionDays int `json:"retention_days"` } s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - policy, err := s.ledger.CreateObjectRetentionPolicy(ctx, actor, app.CreateObjectRetentionPolicyInput{Name: req.Name, ObjectPrefix: req.ObjectPrefix, ObjectKey: req.ObjectKey, Mode: req.Mode, RetentionDays: req.RetentionDays}) + policy, err := s.ledger.CreateObjectRetentionPolicy(ctx, actor, app.CreateObjectRetentionPolicyInput{Name: req.Name, ObjectPrefix: req.ObjectPrefix, ObjectKey: req.ObjectKey, RequireLegalHold: req.RequireLegalHold, Mode: req.Mode, RetentionDays: req.RetentionDays}) return http.StatusCreated, policy, err }) } diff --git a/internal/adapters/objectstore/s3/s3.go b/internal/adapters/objectstore/s3/s3.go index ecb6580..fe6b62a 100644 --- a/internal/adapters/objectstore/s3/s3.go +++ b/internal/adapters/objectstore/s3/s3.go @@ -124,13 +124,20 @@ func (s *Store) VerifyObjectRetention(ctx context.Context, req app.ObjectRetenti } var objectMode *minio.RetentionMode var retainUntil *time.Time + var legalHold *minio.LegalHoldStatus if objectKey != "" { objectMode, retainUntil, err = s.client.GetObjectRetention(ctx, s.bucket, objectKey, "") if err != nil && !objectLockConfigMissing(err) { return app.ObjectRetentionResult{}, fmt.Errorf("check s3 object retention: %w", err) } + if req.RequireLegalHold { + legalHold, err = s.client.GetObjectLegalHold(ctx, s.bucket, objectKey, minio.GetObjectLegalHoldOptions{}) + if err != nil && !objectLockConfigMissing(err) { + return app.ObjectRetentionResult{}, fmt.Errorf("check s3 object legal hold: %w", err) + } + } } - return evaluateObjectRetention(req, versioning.Enabled(), mode, validity, unit, objectMode, retainUntil, time.Now().UTC()), nil + return evaluateObjectRetention(req, versioning.Enabled(), mode, validity, unit, objectMode, retainUntil, legalHold, time.Now().UTC()), nil } func metadataValue(metadata map[string]string, keys ...string) string { @@ -147,7 +154,7 @@ func objectLockConfigMissing(err error) bool { return resp.Code == "NoSuchObjectLockConfiguration" || resp.Code == "ObjectLockConfigurationNotFoundError" } -func evaluateObjectRetention(req app.ObjectRetentionRequest, versioningEnabled bool, mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, objectMode *minio.RetentionMode, retainUntil *time.Time, now time.Time) app.ObjectRetentionResult { +func evaluateObjectRetention(req app.ObjectRetentionRequest, versioningEnabled bool, mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, objectMode *minio.RetentionMode, retainUntil *time.Time, legalHold *minio.LegalHoldStatus, now time.Time) app.ObjectRetentionResult { expectedPrefix := "tenants/" + strings.TrimSpace(req.TenantID) + "/" prefixOK := strings.HasPrefix(strings.TrimSpace(req.ObjectPrefix), expectedPrefix) objectKey := strings.TrimSpace(req.ObjectKey) @@ -166,6 +173,7 @@ func evaluateObjectRetention(req app.ObjectRetentionRequest, versioningEnabled b retentionOK := req.RetentionDays > 0 && retentionDays >= uint(req.RetentionDays) objectModeOK := objectKey == "" || (expectedMode != "" && actualObjectMode == expectedMode) objectRetainUntilOK := objectKey == "" || (retainUntil != nil && retainUntil.UTC().After(now.Add(time.Duration(req.RetentionDays)*24*time.Hour-time.Second))) + legalHoldOK := !req.RequireLegalHold || (objectKey != "" && legalHold != nil && *legalHold == minio.LegalHoldEnabled) checks := []domain.VerifyCheck{ {Name: "s3_bucket_versioning", Result: checkResult(versioningEnabled), Detail: "Bucket versioning must be enabled for object-lock retention."}, {Name: "s3_object_lock_mode", Result: checkResult(modeOK), Detail: "Bucket default object-lock mode must match the policy mode."}, @@ -179,7 +187,10 @@ func evaluateObjectRetention(req app.ObjectRetentionRequest, versioningEnabled b domain.VerifyCheck{Name: "s3_object_retention_until", Result: checkResult(objectRetainUntilOK), Detail: "Sample object retain-until timestamp must meet or exceed the policy duration."}, ) } - enforced := versioningEnabled && modeOK && retentionOK && prefixOK && objectKeyOK && objectModeOK && objectRetainUntilOK + if req.RequireLegalHold { + checks = append(checks, domain.VerifyCheck{Name: "s3_object_legal_hold", Result: checkResult(legalHoldOK), Detail: "Sample object legal hold must be enabled when the policy requires legal hold proof."}) + } + enforced := versioningEnabled && modeOK && retentionOK && prefixOK && objectKeyOK && objectModeOK && objectRetainUntilOK && legalHoldOK limitations := []string{ "S3/MinIO checks validate bucket-level versioning and default object-lock settings.", "Operators remain responsible for bucket creation mode, IAM policy, lifecycle rules, backups, and deployment-specific retention review.", @@ -189,6 +200,9 @@ func evaluateObjectRetention(req app.ObjectRetentionRequest, versioningEnabled b } else { limitations = append(limitations, "Object-level retention was checked for the configured sample object key only.") } + if req.RequireLegalHold { + limitations = append(limitations, "Object-level legal hold was checked for the configured sample object key only.") + } return app.ObjectRetentionResult{ Provider: "s3", Enforced: enforced, diff --git a/internal/adapters/objectstore/s3/s3_test.go b/internal/adapters/objectstore/s3/s3_test.go index b73769c..0819d20 100644 --- a/internal/adapters/objectstore/s3/s3_test.go +++ b/internal/adapters/objectstore/s3/s3_test.go @@ -62,7 +62,7 @@ func TestEvaluateObjectRetentionRequiresVersioningLockAndTenantPrefix(t *testing ObjectPrefix: "tenants/ten_1/raw/", Mode: "compliance", RetentionDays: 30, - }, true, &mode, &validity, &unit, nil, nil, time.Date(2026, 5, 29, 0, 0, 0, 0, time.UTC)) + }, true, &mode, &validity, &unit, nil, nil, nil, time.Date(2026, 5, 29, 0, 0, 0, 0, time.UTC)) if !result.Enforced { t.Fatalf("expected enforced retention: %#v", result) } @@ -83,7 +83,7 @@ func TestEvaluateObjectRetentionReportsMissingProviderControls(t *testing.T) { ObjectPrefix: "tenants/other/raw/", Mode: "compliance", RetentionDays: 30, - }, false, &mode, &validity, &unit, nil, nil, time.Date(2026, 5, 29, 0, 0, 0, 0, time.UTC)) + }, false, &mode, &validity, &unit, nil, nil, nil, time.Date(2026, 5, 29, 0, 0, 0, 0, time.UTC)) if result.Enforced { t.Fatalf("unexpected enforced retention: %#v", result) } @@ -110,7 +110,7 @@ func TestEvaluateObjectRetentionChecksSampleObjectRetention(t *testing.T) { ObjectKey: "tenants/ten_1/raw/sample.json", Mode: "compliance", RetentionDays: 30, - }, true, &mode, &validity, &unit, &mode, &retainUntil, now) + }, true, &mode, &validity, &unit, &mode, &retainUntil, nil, now) if !result.Enforced { t.Fatalf("expected object-level enforced retention: %#v", result) } @@ -119,6 +119,42 @@ func TestEvaluateObjectRetentionChecksSampleObjectRetention(t *testing.T) { } } +func TestEvaluateObjectRetentionChecksRequiredLegalHold(t *testing.T) { + mode := minio.Compliance + validity := uint(90) + unit := minio.Days + now := time.Date(2026, 5, 29, 0, 0, 0, 0, time.UTC) + retainUntil := now.Add(45 * 24 * time.Hour) + legalHold := minio.LegalHoldEnabled + result := evaluateObjectRetention(app.ObjectRetentionRequest{ + TenantID: "ten_1", + ObjectPrefix: "tenants/ten_1/raw/", + ObjectKey: "tenants/ten_1/raw/sample.json", + Mode: "compliance", + RetentionDays: 30, + RequireLegalHold: true, + }, true, &mode, &validity, &unit, &mode, &retainUntil, &legalHold, now) + if !result.Enforced { + t.Fatalf("expected legal-hold enforced retention: %#v", result) + } + if got := result.Checks[len(result.Checks)-1]; got.Name != "s3_object_legal_hold" || got.Result != "passed" { + t.Fatalf("legal hold check = %#v", got) + } + + legalHold = minio.LegalHoldDisabled + result = evaluateObjectRetention(app.ObjectRetentionRequest{ + TenantID: "ten_1", + ObjectPrefix: "tenants/ten_1/raw/", + ObjectKey: "tenants/ten_1/raw/sample.json", + Mode: "compliance", + RetentionDays: 30, + RequireLegalHold: true, + }, true, &mode, &validity, &unit, &mode, &retainUntil, &legalHold, now) + if result.Enforced { + t.Fatalf("disabled legal hold should not be enforced: %#v", result) + } +} + func TestRetentionDaysConvertsYears(t *testing.T) { validity := uint(2) unit := minio.Years diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index 963c2d8..b0e5336 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -2111,7 +2111,7 @@ func (s *Store) loadRelationalReports(ctx context.Context, state *app.PersistedS } func (s *Store) loadRelationalRetention(ctx context.Context, state *app.PersistedState, loaded *bool) error { - policyRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, name, object_prefix, COALESCE(object_key, ''), mode, retention_days, status, verified_at, verification_hash, verification_checks, verification_limitations, schema_version, created_at FROM object_retention_policies`) + policyRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, name, object_prefix, COALESCE(object_key, ''), COALESCE(require_legal_hold, false), mode, retention_days, status, verified_at, verification_hash, verification_checks, verification_limitations, schema_version, created_at FROM object_retention_policies`) if err != nil { return fmt.Errorf("load relational object retention policies: %w", err) } @@ -2121,7 +2121,7 @@ func (s *Store) loadRelationalRetention(ctx context.Context, state *app.Persiste var verifiedAt sql.NullTime var verificationHash sql.NullString var checks []byte - if err := policyRows.Scan(&policy.ID, &policy.TenantID, &policy.Name, &policy.ObjectPrefix, &policy.ObjectKey, &policy.Mode, &policy.RetentionDays, &policy.Status, &verifiedAt, &verificationHash, &checks, &policy.VerificationLimitations, &policy.SchemaVersion, &policy.CreatedAt); err != nil { + if err := policyRows.Scan(&policy.ID, &policy.TenantID, &policy.Name, &policy.ObjectPrefix, &policy.ObjectKey, &policy.RequireLegalHold, &policy.Mode, &policy.RetentionDays, &policy.Status, &verifiedAt, &verificationHash, &checks, &policy.VerificationLimitations, &policy.SchemaVersion, &policy.CreatedAt); err != nil { return fmt.Errorf("scan relational object retention policy: %w", err) } policy.VerifiedAt = nullableSQLTime(verifiedAt) @@ -4013,20 +4013,21 @@ func syncPackageReportRetentionRows(ctx context.Context, tx pgx.Tx, state app.Pe } if _, err := tx.Exec(ctx, ` INSERT INTO object_retention_policies ( - id, tenant_id, name, object_prefix, object_key, mode, retention_days, status, + id, tenant_id, name, object_prefix, object_key, require_legal_hold, mode, retention_days, status, verified_at, verification_hash, verification_checks, verification_limitations, schema_version, created_at ) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15) ON CONFLICT (id) DO UPDATE SET object_key = EXCLUDED.object_key, + require_legal_hold = EXCLUDED.require_legal_hold, status = EXCLUDED.status, verified_at = EXCLUDED.verified_at, verification_hash = EXCLUDED.verification_hash, verification_checks = EXCLUDED.verification_checks, verification_limitations = EXCLUDED.verification_limitations, schema_version = EXCLUDED.schema_version - `, policy.ID, policy.TenantID, policy.Name, policy.ObjectPrefix, policy.ObjectKey, policy.Mode, policy.RetentionDays, policy.Status, nullableTime(policy.VerifiedAt), nullableString(policy.VerificationHash), checks, policy.VerificationLimitations, policy.SchemaVersion, nonZeroTime(policy.CreatedAt)); err != nil { + `, policy.ID, policy.TenantID, policy.Name, policy.ObjectPrefix, policy.ObjectKey, policy.RequireLegalHold, policy.Mode, policy.RetentionDays, policy.Status, nullableTime(policy.VerifiedAt), nullableString(policy.VerificationHash), checks, policy.VerificationLimitations, policy.SchemaVersion, nonZeroTime(policy.CreatedAt)); err != nil { return fmt.Errorf("upsert object retention policy row: %w", err) } } diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index 18c5335..e434e1b 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -421,7 +421,7 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { "ebi_test": {ID: "ebi_test", TenantID: "ten_test", BundleHash: "sha256:" + strings.Repeat("5", 64), Result: "imported", ImportedCount: 1, SchemaVersion: domain.EvidenceBundleImportVersion, CreatedAt: time.Now().UTC()}, }, ObjectRetentionPolicies: map[string]domain.ObjectRetentionPolicy{ - "orp_test": {ID: "orp_test", TenantID: "ten_test", Name: "retain", ObjectPrefix: "tenants/ten_test/", Mode: "governance", RetentionDays: 30, Status: "verified", VerifiedAt: ptrTime(time.Now().UTC()), VerificationHash: "sha256:" + strings.Repeat("6", 64), VerificationChecks: []domain.VerifyCheck{{Name: "versioning", Result: "passed"}}, VerificationLimitations: []string{"test"}, SchemaVersion: domain.ObjectRetentionPolicyVersion, CreatedAt: time.Now().UTC()}, + "orp_test": {ID: "orp_test", TenantID: "ten_test", Name: "retain", ObjectPrefix: "tenants/ten_test/", ObjectKey: "tenants/ten_test/raw/sample.json", RequireLegalHold: true, Mode: "governance", RetentionDays: 30, Status: "verified", VerifiedAt: ptrTime(time.Now().UTC()), VerificationHash: "sha256:" + strings.Repeat("6", 64), VerificationChecks: []domain.VerifyCheck{{Name: "versioning", Result: "passed"}}, VerificationLimitations: []string{"test"}, SchemaVersion: domain.ObjectRetentionPolicyVersion, CreatedAt: time.Now().UTC()}, }, BackupManifests: map[string]domain.BackupManifest{ "bak_test": {ID: "bak_test", TenantID: "ten_test", StateHash: "sha256:" + strings.Repeat("7", 64), ResourceCounts: map[string]int{"evidence": 1}, ConsistencyChecks: []domain.VerifyCheck{{Name: "chain", Result: "passed"}}, Limitations: []string{"objects separately backed up"}, SchemaVersion: domain.BackupManifestSchemaVersion, CreatedAt: time.Now().UTC()}, @@ -614,7 +614,7 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { {name: "rendered report", query: `SELECT count(*) FROM rendered_reports WHERE tenant_id = 'ten_test' AND id = 'render_test'`}, {name: "evidence bundle", query: `SELECT count(*) FROM evidence_bundles WHERE tenant_id = 'ten_test' AND id = 'eb_test'`}, {name: "evidence bundle import", query: `SELECT count(*) FROM evidence_bundle_imports WHERE tenant_id = 'ten_test' AND id = 'ebi_test'`}, - {name: "object retention", query: `SELECT count(*) FROM object_retention_policies WHERE tenant_id = 'ten_test' AND id = 'orp_test' AND verification_checks <> '[]'::jsonb`}, + {name: "object retention", query: `SELECT count(*) FROM object_retention_policies WHERE tenant_id = 'ten_test' AND id = 'orp_test' AND require_legal_hold = true AND verification_checks <> '[]'::jsonb`}, {name: "backup manifest", query: `SELECT count(*) FROM backup_manifests WHERE tenant_id = 'ten_test' AND id = 'bak_test'`}, {name: "legal hold", query: `SELECT count(*) FROM legal_holds WHERE tenant_id = 'ten_test' AND id = 'hold_test' AND released_at IS NOT NULL`}, {name: "retention override", query: `SELECT count(*) FROM retention_overrides WHERE tenant_id = 'ten_test' AND id = 'ret_test'`}, @@ -745,7 +745,7 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { if relational.EvidenceBundles["eb_test"].ManifestHash == "" || relational.BundleImports["ebi_test"].ImportedCount != 1 { t.Fatalf("relational evidence bundle rows missing: bundle=%#v import=%#v", relational.EvidenceBundles["eb_test"], relational.BundleImports["ebi_test"]) } - if relational.ObjectRetentionPolicies["orp_test"].Status != "verified" || len(relational.ObjectRetentionPolicies["orp_test"].VerificationChecks) != 1 { + if relational.ObjectRetentionPolicies["orp_test"].Status != "verified" || !relational.ObjectRetentionPolicies["orp_test"].RequireLegalHold || len(relational.ObjectRetentionPolicies["orp_test"].VerificationChecks) != 1 { t.Fatalf("relational object retention policy = %#v", relational.ObjectRetentionPolicies["orp_test"]) } if relational.BackupManifests["bak_test"].ResourceCounts["evidence"] != 1 || relational.LegalHolds["hold_test"].ReleasedAt == nil || relational.RetentionOverrides["ret_test"].Owner != "security" { diff --git a/internal/app/integrity_runtime.go b/internal/app/integrity_runtime.go index b2eb3d3..54a6999 100644 --- a/internal/app/integrity_runtime.go +++ b/internal/app/integrity_runtime.go @@ -36,11 +36,12 @@ type CreateTransparencyCheckpointInput struct { } type CreateObjectRetentionPolicyInput struct { - Name string - ObjectPrefix string - ObjectKey string - Mode string - RetentionDays int + Name string + ObjectPrefix string + ObjectKey string + Mode string + RetentionDays int + RequireLegalHold bool } type AuditLogFilter struct { @@ -308,9 +309,12 @@ func (l *Ledger) CreateObjectRetentionPolicy(ctx context.Context, actor domain.A if in.ObjectKey != "" && (!strings.HasPrefix(in.ObjectKey, expectedPrefix) || !strings.HasPrefix(in.ObjectKey, in.ObjectPrefix)) { return domain.ObjectRetentionPolicy{}, ErrValidation } + if in.RequireLegalHold && in.ObjectKey == "" { + return domain.ObjectRetentionPolicy{}, ErrValidation + } l.mu.Lock() defer l.mu.Unlock() - policy := domain.ObjectRetentionPolicy{ID: newID("orp"), TenantID: actor.TenantID, Name: in.Name, ObjectPrefix: in.ObjectPrefix, ObjectKey: in.ObjectKey, Mode: in.Mode, RetentionDays: in.RetentionDays, Status: "configured", SchemaVersion: domain.ObjectRetentionPolicyVersion, CreatedAt: l.now()} + policy := domain.ObjectRetentionPolicy{ID: newID("orp"), TenantID: actor.TenantID, Name: in.Name, ObjectPrefix: in.ObjectPrefix, ObjectKey: in.ObjectKey, RequireLegalHold: in.RequireLegalHold, Mode: in.Mode, RetentionDays: in.RetentionDays, Status: "configured", SchemaVersion: domain.ObjectRetentionPolicyVersion, CreatedAt: l.now()} l.retentionPolicies[policy.ID] = policy _, _ = l.appendChainLocked(actor.TenantID, "object_retention_policy.created", "object_retention_policy", policy.ID, actorType(actor), actorID(actor), "", "") if err := l.persistLocked(ctx); err != nil { @@ -348,11 +352,12 @@ func (l *Ledger) VerifyObjectRetentionPolicy(ctx context.Context, actor domain.A status := "verified" if verifier != nil { result, err := verifier.VerifyObjectRetention(ctx, ObjectRetentionRequest{ - TenantID: policy.TenantID, - ObjectPrefix: policy.ObjectPrefix, - ObjectKey: policy.ObjectKey, - Mode: policy.Mode, - RetentionDays: policy.RetentionDays, + TenantID: policy.TenantID, + ObjectPrefix: policy.ObjectPrefix, + ObjectKey: policy.ObjectKey, + Mode: policy.Mode, + RetentionDays: policy.RetentionDays, + RequireLegalHold: policy.RequireLegalHold, }) if err != nil { return domain.ObjectRetentionPolicy{}, ErrVerificationFailed @@ -369,29 +374,31 @@ func (l *Ledger) VerifyObjectRetentionPolicy(ctx context.Context, actor domain.A policy.VerificationChecks = append([]domain.VerifyCheck(nil), retentionResult.Checks...) policy.VerificationLimitations = append([]string(nil), retentionResult.Limitations...) verificationHash, err := canonicalAnyHash(struct { - ID string `json:"id"` - TenantID string `json:"tenant_id"` - ObjectPrefix string `json:"object_prefix"` - ObjectKey string `json:"object_key,omitempty"` - Mode string `json:"mode"` - Provider string `json:"provider"` - RetentionDays int `json:"retention_days"` - Status string `json:"status"` - VerifiedAt string `json:"verified_at"` - Checks []domain.VerifyCheck `json:"checks"` - Limitations []string `json:"limitations"` + ID string `json:"id"` + TenantID string `json:"tenant_id"` + ObjectPrefix string `json:"object_prefix"` + ObjectKey string `json:"object_key,omitempty"` + RequireLegalHold bool `json:"require_legal_hold"` + Mode string `json:"mode"` + Provider string `json:"provider"` + RetentionDays int `json:"retention_days"` + Status string `json:"status"` + VerifiedAt string `json:"verified_at"` + Checks []domain.VerifyCheck `json:"checks"` + Limitations []string `json:"limitations"` }{ - ID: policy.ID, - TenantID: policy.TenantID, - ObjectPrefix: policy.ObjectPrefix, - ObjectKey: policy.ObjectKey, - Mode: policy.Mode, - Provider: retentionResult.Provider, - RetentionDays: policy.RetentionDays, - Status: policy.Status, - VerifiedAt: now.Format(time.RFC3339Nano), - Checks: policy.VerificationChecks, - Limitations: policy.VerificationLimitations, + ID: policy.ID, + TenantID: policy.TenantID, + ObjectPrefix: policy.ObjectPrefix, + ObjectKey: policy.ObjectKey, + RequireLegalHold: policy.RequireLegalHold, + Mode: policy.Mode, + Provider: retentionResult.Provider, + RetentionDays: policy.RetentionDays, + Status: policy.Status, + VerifiedAt: now.Format(time.RFC3339Nano), + Checks: policy.VerificationChecks, + Limitations: policy.VerificationLimitations, }) if err != nil { return domain.ObjectRetentionPolicy{}, err diff --git a/internal/app/integrity_runtime_test.go b/internal/app/integrity_runtime_test.go index e7bfe0c..08a076e 100644 --- a/internal/app/integrity_runtime_test.go +++ b/internal/app/integrity_runtime_test.go @@ -83,6 +83,9 @@ func TestRuntimeRetentionBackupReadinessMetricsAndAudit(t *testing.T) { if _, err := ledger.CreateObjectRetentionPolicy(ctx, actor, CreateObjectRetentionPolicyInput{Name: "bad key", ObjectKey: "tenants/other/raw/sample.json", Mode: "governance", RetentionDays: 30}); !errors.Is(err, ErrValidation) { t.Fatalf("foreign object key err=%v, want validation", err) } + if _, err := ledger.CreateObjectRetentionPolicy(ctx, actor, CreateObjectRetentionPolicyInput{Name: "legal hold without object", RequireLegalHold: true, Mode: "governance", RetentionDays: 30}); !errors.Is(err, ErrValidation) { + t.Fatalf("legal hold without object err=%v, want validation", err) + } verifiedPolicy, err := ledger.VerifyObjectRetentionPolicy(ctx, actor, policy.ID) if err != nil { t.Fatalf("verify retention: %v", err) @@ -170,6 +173,37 @@ func TestObjectRetentionVerifierRecordsProviderChecks(t *testing.T) { } } +func TestObjectRetentionVerifierReceivesLegalHoldRequirement(t *testing.T) { + verifier := &fakeObjectRetentionVerifier{result: ObjectRetentionResult{ + Provider: "s3", + Enforced: true, + Checks: []domain.VerifyCheck{{Name: "s3_object_legal_hold", Result: "passed"}}, + Limitations: []string{"Sample object legal hold checked only."}, + }} + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow, Retention: verifier}) + ctx := context.Background() + _, _, secret, err := ledger.BootstrapTenant(ctx, "Tenant", "admin", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap: %v", err) + } + actor, err := ledger.Authenticate(ctx, secret) + if err != nil { + t.Fatalf("auth: %v", err) + } + objectKey := "tenants/" + actor.TenantID + "/raw/sample.json" + policy, err := ledger.CreateObjectRetentionPolicy(ctx, actor, CreateObjectRetentionPolicyInput{Name: "objects", ObjectPrefix: "tenants/" + actor.TenantID + "/raw/", ObjectKey: objectKey, RequireLegalHold: true, Mode: "compliance", RetentionDays: 90}) + if err != nil { + t.Fatalf("create policy: %v", err) + } + verified, err := ledger.VerifyObjectRetentionPolicy(ctx, actor, policy.ID) + if err != nil { + t.Fatalf("verify policy: %v", err) + } + if !verified.RequireLegalHold || len(verifier.requests) != 1 || !verifier.requests[0].RequireLegalHold || verifier.requests[0].ObjectKey != objectKey { + t.Fatalf("verified=%#v requests=%#v", verified, verifier.requests) + } +} + func TestObjectRetentionVerifierMarksProviderFailure(t *testing.T) { ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow, Retention: &fakeObjectRetentionVerifier{result: ObjectRetentionResult{ Provider: "s3", diff --git a/internal/app/ports.go b/internal/app/ports.go index b8f72a2..470d980 100644 --- a/internal/app/ports.go +++ b/internal/app/ports.go @@ -120,11 +120,12 @@ type TransparencyProofResult struct { } type ObjectRetentionRequest struct { - TenantID string - ObjectPrefix string - ObjectKey string - Mode string - RetentionDays int + TenantID string + ObjectPrefix string + ObjectKey string + Mode string + RetentionDays int + RequireLegalHold bool } type ObjectRetentionResult struct { diff --git a/internal/domain/domain.go b/internal/domain/domain.go index 957f8f5..c7743eb 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -698,6 +698,7 @@ type ObjectRetentionPolicy struct { Name string `json:"name"` ObjectPrefix string `json:"object_prefix"` ObjectKey string `json:"object_key,omitempty"` + RequireLegalHold bool `json:"require_legal_hold,omitempty"` Mode string `json:"mode"` RetentionDays int `json:"retention_days"` Status string `json:"status"` diff --git a/migrations/20260531000100_object_retention_legal_hold.down.sql b/migrations/20260531000100_object_retention_legal_hold.down.sql new file mode 100644 index 0000000..d1e9f36 --- /dev/null +++ b/migrations/20260531000100_object_retention_legal_hold.down.sql @@ -0,0 +1,4 @@ +DROP INDEX IF EXISTS object_retention_policies_tenant_legal_hold_idx; + +ALTER TABLE object_retention_policies + DROP COLUMN IF EXISTS require_legal_hold; diff --git a/migrations/20260531000100_object_retention_legal_hold.up.sql b/migrations/20260531000100_object_retention_legal_hold.up.sql new file mode 100644 index 0000000..1acf941 --- /dev/null +++ b/migrations/20260531000100_object_retention_legal_hold.up.sql @@ -0,0 +1,6 @@ +ALTER TABLE object_retention_policies + ADD COLUMN IF NOT EXISTS require_legal_hold boolean NOT NULL DEFAULT false; + +CREATE INDEX IF NOT EXISTS object_retention_policies_tenant_legal_hold_idx + ON object_retention_policies (tenant_id, require_legal_hold) + WHERE require_legal_hold = true; diff --git a/openapi.yaml b/openapi.yaml index 7a4d2bf..5a87038 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From 979f800d7ca6754b10c909b0c0b594d408e0abca Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 10:17:17 +0300 Subject: [PATCH 132/287] feat: enforce api writer lease --- CHANGELOG.md | 2 ++ README.md | 2 +- cmd/evydence-api/main.go | 11 ++++++++ deploy/helm/evydence/values.yaml | 7 ++--- docs/architecture.md | 2 +- docs/kubernetes.md | 2 +- docs/production-hardening.md | 2 ++ docs/reference/configuration.md | 4 +++ docs/reference/production-readiness.md | 10 ++++--- internal/adapters/postgres/store.go | 30 +++++++++++++++++++++ internal/adapters/postgres/store_test.go | 33 ++++++++++++++++++++++++ 11 files changed, 95 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4070b0..796a3bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,8 @@ Release-candidate tagging requires the production gate and checklist in persisted. - Object-retention policies can require sample-object legal hold verification with S3/MinIO providers that expose object legal-hold status. +- Production API startup takes a PostgreSQL advisory writer lease so accidental + second API writers fail closed under the supported single-writer profile. ### Known Limits diff --git a/README.md b/README.md index 13490f9..42f4388 100644 --- a/README.md +++ b/README.md @@ -109,4 +109,4 @@ make postgres-integration-test `make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. -`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required release-candidate evidence, but it does not by itself close the remaining service decomposition, non-AWS KMS/HSM SDK providers, provider-specific management API/group synchronization, broader object-lock enforcement beyond configured bucket/sample-object checks, HA, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. Critical runtime mutations for tenants, credential hashes, idempotency, audit-chain entries, release bundles, signatures, verification results, vulnerability decisions, and outbox jobs use focused PostgreSQL write paths when available. Release-ledger and evidence-core mutations for products, projects, releases, artifacts, evidence items, evidence lifecycle events, SBOMs, vulnerability scans, OpenAPI contracts, VEX documents, audit-chain entries, and parser outbox jobs also use focused PostgreSQL write paths when available. Remaining aggregate persistence calls use PostgreSQL relational synchronization without writing the compatibility snapshot when that store is configured. Current self-hosted production guidance still uses a single API writer replica and allows worker replicas to scale through PostgreSQL outbox row locking. +`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required release-candidate evidence, but it does not by itself close the remaining service decomposition, non-AWS KMS/HSM SDK providers, provider-specific management API/group synchronization, broader object-lock enforcement beyond configured bucket/sample-object checks, HA, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. Critical runtime mutations for tenants, credential hashes, idempotency, audit-chain entries, release bundles, signatures, verification results, vulnerability decisions, and outbox jobs use focused PostgreSQL write paths when available. Release-ledger and evidence-core mutations for products, projects, releases, artifacts, evidence items, evidence lifecycle events, SBOMs, vulnerability scans, OpenAPI contracts, VEX documents, audit-chain entries, and parser outbox jobs also use focused PostgreSQL write paths when available. Remaining aggregate persistence calls use PostgreSQL relational synchronization without writing the compatibility snapshot when that store is configured. Current self-hosted production guidance still uses a single API writer replica; production API startup enforces that stance with a PostgreSQL advisory writer lease, and worker replicas may scale through PostgreSQL outbox row locking. diff --git a/cmd/evydence-api/main.go b/cmd/evydence-api/main.go index 97664ed..ed1b287 100644 --- a/cmd/evydence-api/main.go +++ b/cmd/evydence-api/main.go @@ -58,6 +58,7 @@ func run() error { cfg.Signer = signer } var closeStore func() + var releaseWriterLease func() if databaseURL != "" { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() @@ -75,6 +76,13 @@ func run() error { return err } closeStore = pgStore.Close + if production { + releaseWriterLease, err = pgStore.AcquireAPIWriterLease(ctx) + if err != nil { + closeStore() + return fmt.Errorf("acquire api writer lease: %w", err) + } + } migrationsDir := envDefault("EVYDENCE_MIGRATIONS_DIR", "migrations") if !strings.EqualFold(os.Getenv("EVYDENCE_SKIP_MIGRATIONS"), "true") { if _, err := pgStore.ApplyMigrations(ctx, migrationsDir); err != nil { @@ -98,6 +106,9 @@ func run() error { if closeStore != nil { defer closeStore() } + if releaseWriterLease != nil { + defer releaseWriterLease() + } ledger, err := app.NewLedgerWithError(cfg) if err != nil { return fmt.Errorf("create ledger: %w", err) diff --git a/deploy/helm/evydence/values.yaml b/deploy/helm/evydence/values.yaml index 27f6d7f..1fcf8fa 100644 --- a/deploy/helm/evydence/values.yaml +++ b/deploy/helm/evydence/values.yaml @@ -6,9 +6,10 @@ image: pullPolicy: IfNotPresent api: - # Keep API replicas at 1 for the current production profile. API writes are - # single-writer until focused relational write paths or optimistic - # concurrency controls are implemented and documented. + # Keep API replicas at 1 for the current production profile. Production API + # startup also takes a PostgreSQL advisory writer lease and a second writer + # fails closed until multi-writer concurrency controls are implemented and + # documented. replicas: 1 addr: ":8080" resources: diff --git a/docs/architecture.md b/docs/architecture.md index 7fa23f4..b405ea5 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -10,7 +10,7 @@ Evydence follows a ports-and-adapters shape: - `internal/adapters/objectstore/s3` stores the same tenant-prefixed object keys in S3/MinIO-compatible buckets. - `cmd/*` contains process entry points. -Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity, idempotency, and customer portal token records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. Collector/build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension records are synchronized into their migration-backed relational tables. Production API and worker startup defaults to relational-only reconstruction and disables compatibility snapshot writes; local development defaults to snapshot-preferred compatibility. When the PostgreSQL store is configured, critical runtime mutations for tenants, API-key hashes, SSO-session hashes, customer-portal token hashes, idempotency records, audit-chain entries, signing keys, signatures, release bundles, verification results, provider verification receipts, vulnerability decisions, and outbox jobs are written through focused transaction-backed mutations instead of relying only on aggregate `SaveState`. Release-ledger and evidence-core mutations use focused transaction-backed mutations, and remaining aggregate persistence calls synchronize relational rows without writing the compatibility snapshot. If the snapshot row is absent, the Postgres store can rebuild identity, SSO session, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. +Core logic does not depend on HTTP routers, SQL drivers, object storage SDKs, queues, KMS providers, provider clients, or UI frameworks. PostgreSQL persistence currently stores a versioned ledger snapshot and rebuilds tenant-scoped relational projection rows plus forward-compatible per-resource tables for implemented release, evidence, source, deployment, and control resources. Identity, idempotency, and customer portal token records are synchronized into relational rows with non-secret hashes and tenant-scoped constraints. Release-ledger core rows are also synchronized for products, projects, releases, artifacts, evidence, audit-chain entries, signing keys, signatures, SBOMs, vulnerability scans, OpenAPI contracts, policy evaluations, release bundles, and verification receipts. Collector/build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension records are synchronized into their migration-backed relational tables. Production API and worker startup defaults to relational-only reconstruction and disables compatibility snapshot writes; local development defaults to snapshot-preferred compatibility. In production, API startup also takes a PostgreSQL advisory writer lease so an accidental second API writer fails closed while the supported profile remains single-writer. When the PostgreSQL store is configured, critical runtime mutations for tenants, API-key hashes, SSO-session hashes, customer-portal token hashes, idempotency records, audit-chain entries, signing keys, signatures, release bundles, verification results, provider verification receipts, vulnerability decisions, and outbox jobs are written through focused transaction-backed mutations instead of relying only on aggregate `SaveState`. Release-ledger and evidence-core mutations use focused transaction-backed mutations, and remaining aggregate persistence calls synchronize relational rows without writing the compatibility snapshot. If the snapshot row is absent, the Postgres store can rebuild identity, SSO session, customer portal token, release-ledger core, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension families from relational rows. Moving all canonical production writes to dependency-ordered relational repositories is tracked as production hardening, not as a completed production maturity claim. ## Tenant And Auth Boundaries diff --git a/docs/kubernetes.md b/docs/kubernetes.md index 97a5e68..d89af7d 100644 --- a/docs/kubernetes.md +++ b/docs/kubernetes.md @@ -83,4 +83,4 @@ Rollback does not roll back PostgreSQL data or object-store payloads. Keep datab ## Production Notes -Production deployments should use external PostgreSQL, S3/MinIO-compatible object storage, TLS ingress, backup automation, network access controls, and external signing. Current production guidance uses a single API writer replica; worker replicas can scale independently through PostgreSQL outbox row locking. See [Production hardening review](production-hardening.md), [Production readiness](reference/production-readiness.md), and [Configuration](reference/configuration.md). +Production deployments should use external PostgreSQL, S3/MinIO-compatible object storage, TLS ingress, backup automation, network access controls, and external signing. Current production guidance uses a single API writer replica; production API startup enforces that stance with a PostgreSQL advisory writer lease, and worker replicas can scale independently through PostgreSQL outbox row locking. See [Production hardening review](production-hardening.md), [Production readiness](reference/production-readiness.md), and [Configuration](reference/configuration.md). diff --git a/docs/production-hardening.md b/docs/production-hardening.md index 0216803..786cda3 100644 --- a/docs/production-hardening.md +++ b/docs/production-hardening.md @@ -11,6 +11,8 @@ Before labeling a deployment production, verify: - `EVYDENCE_API_KEY_PEPPER` is a non-default random value. - `EVYDENCE_SIGNING_KEY_MODE=external` or `EVYDENCE_SIGNING_KEY_MODE=aws-kms` is set. - `EVYDENCE_PRINT_BOOTSTRAP_SECRET` is unset or false. +- Only one API writer replica is deployed; production API startup also enforces + this with a PostgreSQL advisory writer lease. These checks are enforced by API startup. See [Configuration](reference/configuration.md). diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index c0689c0..cc4997a 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -80,6 +80,10 @@ preserve existing workflows. Use `relational_preferred` only for controlled non-production migration or recovery checks that intentionally fall back to the snapshot. +In production, API startup takes a PostgreSQL advisory writer lease and fails +if another API writer already holds it. Worker replicas are not constrained by +that lease because outbox jobs use row locking. + When PostgreSQL is configured, critical runtime mutations use focused transaction-backed writes for tenants, API-key hashes, SSO-session hashes, customer-portal token hashes, idempotency records, audit-chain entries, diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 21181e5..01f05f0 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -91,10 +91,12 @@ The current self-hosted production profile supports one API writer replica. This is intentional while the application still uses a large in-process ledger aggregate and some resource families still use aggregate persistence. Focused critical mutations reduce the riskiest `SaveState` dependence, but they are -not a full multi-writer concurrency design. Do not scale API writer replicas -above one for production use until focused relational repository writes cover -all write families or another reviewed concurrency-control design is -implemented and documented. +not a full multi-writer concurrency design. When `ENV=production` and +PostgreSQL is configured, API startup takes a PostgreSQL advisory writer lease +and fails if another API writer already holds it. Do not scale API writer +replicas above one for production use until focused relational repository +writes cover all write families or another reviewed concurrency-control design +is implemented and documented. Worker replicas may be scaled because persisted outbox jobs are claimed with PostgreSQL row locking. Scaling workers increases parser/signing/report diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index b0e5336..9cd10c0 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -36,6 +36,8 @@ type StoreOptions struct { DisableSnapshotWrites bool } +const apiWriterLeaseKey int64 = 0x65767964656e6365 + type ClaimedJob struct { ID string TenantID string @@ -105,6 +107,34 @@ func ValidateProductionLoadMode(mode LoadMode) error { return nil } +func (s *Store) AcquireAPIWriterLease(ctx context.Context) (func(), error) { + if s == nil || s.pool == nil { + return nil, app.ErrValidation + } + conn, err := s.pool.Acquire(ctx) + if err != nil { + return nil, fmt.Errorf("acquire api writer lease connection: %w", err) + } + releaseConn := true + defer func() { + if releaseConn { + conn.Release() + } + }() + var acquired bool + if err := conn.QueryRow(ctx, `SELECT pg_try_advisory_lock($1)`, apiWriterLeaseKey).Scan(&acquired); err != nil { + return nil, fmt.Errorf("acquire api writer lease: %w", err) + } + if !acquired { + return nil, errors.New("another Evydence API writer is already active") + } + releaseConn = false + return func() { + _, _ = conn.Exec(context.Background(), `SELECT pg_advisory_unlock($1)`, apiWriterLeaseKey) + conn.Release() + }, nil +} + func normalizeLoadMode(mode LoadMode) (LoadMode, error) { switch strings.ToLower(strings.TrimSpace(string(mode))) { case "", "snapshot", "snapshot_preferred", "snapshot-preferred": diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index e434e1b..0ff6ce0 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -60,6 +60,39 @@ func TestValidateProductionLoadModeRequiresRelationalOnly(t *testing.T) { } } +func TestStoreAPIWriterLeaseIsExclusive(t *testing.T) { + databaseURL := os.Getenv("EVYDENCE_TEST_DATABASE_URL") + if databaseURL == "" { + t.Skip("EVYDENCE_TEST_DATABASE_URL is not set") + } + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + first, err := Open(ctx, databaseURL) + if err != nil { + t.Fatal(err) + } + defer first.Close() + second, err := Open(ctx, databaseURL) + if err != nil { + t.Fatal(err) + } + defer second.Close() + releaseFirst, err := first.AcquireAPIWriterLease(ctx) + if err != nil { + t.Fatalf("first lease: %v", err) + } + if _, err := second.AcquireAPIWriterLease(ctx); err == nil || !strings.Contains(err.Error(), "already active") { + releaseFirst() + t.Fatalf("second lease err=%v, want active writer rejection", err) + } + releaseFirst() + releaseSecond, err := second.AcquireAPIWriterLease(ctx) + if err != nil { + t.Fatalf("second lease after release: %v", err) + } + releaseSecond() +} + func TestStoreCanDisableSnapshotWritesAndLoadRelationalState(t *testing.T) { databaseURL := os.Getenv("EVYDENCE_TEST_DATABASE_URL") if databaseURL == "" { From 95aa9985074624b3d7d21d06d57e43785cbe0d16 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 10:21:27 +0300 Subject: [PATCH 133/287] docs: add release evidence scanner workflow --- docs/README.md | 1 + docs/explanation/trust-model.md | 2 +- .../release-evidence-workflow.yml | 51 ++++++ docs/how-to/integrate-ci.md | 10 ++ scripts/github_release_evidence_manifest.py | 169 ++++++++++++++++++ 5 files changed, 232 insertions(+), 1 deletion(-) create mode 100755 scripts/github_release_evidence_manifest.py diff --git a/docs/README.md b/docs/README.md index d17d750..5771d51 100644 --- a/docs/README.md +++ b/docs/README.md @@ -48,6 +48,7 @@ This documentation is organized by reader task. Implementation claims should be - [GitHub Actions release evidence workflow](github-actions/release-evidence-workflow.yml) - [GitHub Actions upload-build composite action](github-actions/upload-build/action.yml) +- [GitHub release evidence manifest generator](../scripts/github_release_evidence_manifest.py) - [GitLab release evidence CI template](gitlab/evydence-release-evidence.gitlab-ci.yml) These examples require tenant-scoped API or collector secrets created through the API. They capture CI metadata as submitted evidence; provider-side truth still depends on the CI provider, workflow controls, and any verification receipts recorded separately. diff --git a/docs/explanation/trust-model.md b/docs/explanation/trust-model.md index 077137f..1fa1e76 100644 --- a/docs/explanation/trust-model.md +++ b/docs/explanation/trust-model.md @@ -4,6 +4,6 @@ Evydence records technical evidence, hashes payloads, links evidence to products Evydence trusts tenant-scoped API keys and SSO session tokens after server-side hash verification. Instance-wide diagnostics require the explicit `instance:admin` scope; tenant `admin` and wildcard tenant keys remain tenant-scoped unless that scope is also present. Collector identity is derived from the collector API key binding. Customer portal access uses expiring package tokens and exposes scoped package manifests, not raw tenant evidence. Repeated failed portal attempts revoke the access record without storing the supplied token. -Provider metadata such as GitHub Actions, GitLab, DSSE, VEX, SBOM, OpenAPI, scanner payloads, and SSO provider records is treated as uploaded evidence unless a configured trust root or verification path proves more. Current SSO support records provider metadata, identity links, expiring sessions, local OIDC token verification, and local SAML assertion verification against tenant-configured trust material. It does not perform live provider discovery/API validation, browser login callbacks, or group synchronization. Structural parsing is not the same as provider truth or cryptographic trust. +Provider metadata such as GitHub Actions, GitLab, DSSE, VEX, SBOM, OpenAPI, scanner payloads, and SSO provider records is treated as uploaded evidence unless a configured trust root or verification path proves more. Current SSO support records provider metadata, identity links, expiring sessions, local OIDC token verification, local SAML assertion verification against tenant-configured trust material, OIDC discovery/JWKS refresh, and optional OIDC UserInfo validation when a caller supplies an access token. It does not perform provider-specific management API validation, browser login callbacks, or external group synchronization. Structural parsing is not the same as provider truth or cryptographic trust. Reports are readiness and evidence-organization outputs. They do not state legal compliance, certification, complete SBOM coverage, authoritative vulnerability results, or secure releases. diff --git a/docs/github-actions/release-evidence-workflow.yml b/docs/github-actions/release-evidence-workflow.yml index e6e92fb..91a1bcd 100644 --- a/docs/github-actions/release-evidence-workflow.yml +++ b/docs/github-actions/release-evidence-workflow.yml @@ -35,3 +35,54 @@ jobs: --release-id "$EVYDENCE_RELEASE_ID" \ --artifact-id "$EVYDENCE_ARTIFACT_ID" \ --artifact-digest "$EVYDENCE_ARTIFACT_DIGEST" + - name: Generate SBOM and scanner evidence + run: | + set -euo pipefail + # Install or provide reviewed, pinned scanner versions in your runner image. + # These commands produce files consumed by scripts/github_release_evidence_manifest.py. + syft dir:. -o cyclonedx-json=sbom.cdx.json + grype dir:. -o json > grype.json + trivy fs --format json --output trivy.json . + - name: Build Evydence upload manifest + env: + EVYDENCE_RELEASE_ID: ${{ vars.EVYDENCE_RELEASE_ID }} + EVYDENCE_ARTIFACT_ID: ${{ vars.EVYDENCE_ARTIFACT_ID }} + EVYDENCE_PRODUCT_ID: ${{ vars.EVYDENCE_PRODUCT_ID }} + EVYDENCE_REDACTION_PROFILE_ID: ${{ vars.EVYDENCE_REDACTION_PROFILE_ID }} + run: | + set -euo pipefail + python3 scripts/github_release_evidence_manifest.py \ + --out .evydence/upload-manifest.json \ + --release-id "$EVYDENCE_RELEASE_ID" \ + --artifact-id "$EVYDENCE_ARTIFACT_ID" \ + --target-ref "pkg:github/${GITHUB_REPOSITORY}@${GITHUB_SHA}" \ + --idempotency-prefix "gha-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" \ + --cyclonedx-sbom sbom.cdx.json \ + --grype-json grype.json \ + --trivy-json trivy.json \ + --include-release-bundle + if [ -n "${EVYDENCE_PRODUCT_ID:-}" ] && [ -n "${EVYDENCE_REDACTION_PROFILE_ID:-}" ]; then + python3 scripts/github_release_evidence_manifest.py \ + --out .evydence/upload-manifest.json \ + --release-id "$EVYDENCE_RELEASE_ID" \ + --artifact-id "$EVYDENCE_ARTIFACT_ID" \ + --target-ref "pkg:github/${GITHUB_REPOSITORY}@${GITHUB_SHA}" \ + --idempotency-prefix "gha-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" \ + --cyclonedx-sbom sbom.cdx.json \ + --grype-json grype.json \ + --trivy-json trivy.json \ + --include-release-bundle \ + --customer-package-product-id "$EVYDENCE_PRODUCT_ID" \ + --customer-package-redaction-profile-id "$EVYDENCE_REDACTION_PROFILE_ID" \ + --customer-package-title "Release evidence ${GITHUB_SHA}" \ + --customer-package-expires-at "$(date -u -d '+30 days' +%Y-%m-%dT%H:%M:%SZ)" + fi + - name: Upload SBOM, scanner, bundle, and package evidence + env: + EVYDENCE_API_URL: ${{ secrets.EVYDENCE_API_URL }} + EVYDENCE_API_KEY: ${{ secrets.EVYDENCE_API_KEY }} + run: | + dist/evydence upload manifest \ + --url "$EVYDENCE_API_URL" \ + --api-key "$EVYDENCE_API_KEY" \ + --manifest .evydence/upload-manifest.json diff --git a/docs/how-to/integrate-ci.md b/docs/how-to/integrate-ci.md index d1cce2d..332e270 100644 --- a/docs/how-to/integrate-ci.md +++ b/docs/how-to/integrate-ci.md @@ -42,6 +42,16 @@ The CLI command used by the workflow reads GitHub-provided environment variables `EVYDENCE_GITHUB_OIDC_SUBJECT` or `--oidc-subject` can record an OIDC subject string when the workflow already has one. This implementation records the value as evidence metadata; it does not request or verify a GitHub OIDC token. +The full workflow also shows a scanner handoff path: + +- produce CycloneDX JSON with `syft`; +- produce Grype and Trivy JSON scanner outputs; +- run `scripts/github_release_evidence_manifest.py` to normalize those files into Evydence upload payloads; +- upload the manifest with `evydence upload manifest`; +- optionally create a customer package when `EVYDENCE_PRODUCT_ID` and `EVYDENCE_REDACTION_PROFILE_ID` are configured. + +Pin scanner versions in your runner image or workflow before using the example for production evidence. Scanner output is evidence for review; it is not treated as complete or authoritative vulnerability coverage. + ## GitLab CI The GitLab template is [docs/gitlab/evydence-release-evidence.gitlab-ci.yml](../gitlab/evydence-release-evidence.gitlab-ci.yml). diff --git a/scripts/github_release_evidence_manifest.py b/scripts/github_release_evidence_manifest.py new file mode 100755 index 0000000..b1774e6 --- /dev/null +++ b/scripts/github_release_evidence_manifest.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python3 +from __future__ import annotations + +import argparse +import json +from datetime import datetime, timezone +from pathlib import Path +from typing import Any + + +def load_json(path: str) -> Any: + try: + return json.loads(Path(path).read_text(encoding="utf-8")) + except json.JSONDecodeError as exc: + raise SystemExit(f"{path}: not valid JSON: {exc}") from exc + + +def write_json(path: Path, value: Any) -> None: + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(json.dumps(value, indent=2, sort_keys=True) + "\n", encoding="utf-8") + + +def severity(value: Any) -> str: + text = str(value or "unknown").strip().lower() + return text if text else "unknown" + + +def grype_findings(doc: dict[str, Any]) -> list[dict[str, str]]: + findings: list[dict[str, str]] = [] + for match in doc.get("matches", []): + vulnerability = match.get("vulnerability", {}) if isinstance(match, dict) else {} + artifact = match.get("artifact", {}) if isinstance(match, dict) else {} + vuln_id = str(vulnerability.get("id", "")).strip() + if not vuln_id: + continue + component = str(artifact.get("purl") or artifact.get("name") or "").strip() + findings.append( + { + "vulnerability": vuln_id, + "component": component, + "severity": severity(vulnerability.get("severity")), + "state": "open", + } + ) + return findings + + +def trivy_findings(doc: dict[str, Any]) -> list[dict[str, str]]: + findings: list[dict[str, str]] = [] + for result in doc.get("Results", []): + if not isinstance(result, dict): + continue + for vuln in result.get("Vulnerabilities", []) or []: + vuln_id = str(vuln.get("VulnerabilityID", "")).strip() + if not vuln_id: + continue + component = str(vuln.get("PkgIdentifier", {}).get("PURL") or vuln.get("PkgName") or "").strip() + findings.append( + { + "vulnerability": vuln_id, + "component": component, + "severity": severity(vuln.get("Severity")), + "state": "open", + } + ) + return findings + + +def request(path: str, idempotency_key: str, payload_file: str) -> dict[str, str]: + return {"path": path, "idempotency_key": idempotency_key, "payload_file": payload_file} + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description="Build an Evydence GitHub release evidence upload manifest.") + parser.add_argument("--out", default=".evydence/upload-manifest.json") + parser.add_argument("--release-id", required=True) + parser.add_argument("--artifact-id", default="") + parser.add_argument("--target-ref", required=True) + parser.add_argument("--idempotency-prefix", required=True) + parser.add_argument("--cyclonedx-sbom") + parser.add_argument("--grype-json") + parser.add_argument("--trivy-json") + parser.add_argument("--openvex-json") + parser.add_argument("--include-release-bundle", action="store_true") + parser.add_argument("--customer-package-product-id", default="") + parser.add_argument("--customer-package-redaction-profile-id", default="") + parser.add_argument("--customer-package-title", default="") + parser.add_argument("--customer-package-expires-at", default="") + return parser.parse_args() + + +def main() -> None: + args = parse_args() + out = Path(args.out) + base = out.parent + requests: list[dict[str, str]] = [] + + if args.cyclonedx_sbom: + payload = {"release_id": args.release_id, "artifact_id": args.artifact_id, "payload": load_json(args.cyclonedx_sbom)} + payload_path = base / "sbom-cyclonedx-upload.json" + write_json(payload_path, payload) + requests.append(request("/v1/sboms", f"{args.idempotency_prefix}-sbom-cyclonedx", payload_path.name)) + + if args.grype_json: + payload = { + "scanner": "grype", + "target_ref": args.target_ref, + "release_id": args.release_id, + "findings": grype_findings(load_json(args.grype_json)), + } + payload_path = base / "scan-grype-upload.json" + write_json(payload_path, payload) + requests.append(request("/v1/vulnerability-scans", f"{args.idempotency_prefix}-scan-grype", payload_path.name)) + + if args.trivy_json: + payload = { + "scanner": "trivy", + "target_ref": args.target_ref, + "release_id": args.release_id, + "findings": trivy_findings(load_json(args.trivy_json)), + } + payload_path = base / "scan-trivy-upload.json" + write_json(payload_path, payload) + requests.append(request("/v1/vulnerability-scans", f"{args.idempotency_prefix}-scan-trivy", payload_path.name)) + + if args.openvex_json: + payload = {"release_id": args.release_id, "artifact_id": args.artifact_id, "payload": load_json(args.openvex_json)} + payload_path = base / "vex-openvex-upload.json" + write_json(payload_path, payload) + requests.append(request("/v1/vex", f"{args.idempotency_prefix}-vex-openvex", payload_path.name)) + + if args.include_release_bundle: + payload_path = base / "release-bundle-upload.json" + write_json(payload_path, {"release_id": args.release_id}) + requests.append(request("/v1/release-bundles", f"{args.idempotency_prefix}-release-bundle", payload_path.name)) + + package_fields = [ + args.customer_package_product_id, + args.customer_package_redaction_profile_id, + args.customer_package_title, + args.customer_package_expires_at, + ] + if any(package_fields): + if not all(package_fields): + raise SystemExit("customer package fields must be supplied together") + try: + datetime.fromisoformat(args.customer_package_expires_at.replace("Z", "+00:00")).astimezone(timezone.utc) + except ValueError as exc: + raise SystemExit("customer package expires_at must be an RFC3339 timestamp") from exc + payload_path = base / "customer-package-upload.json" + write_json( + payload_path, + { + "product_id": args.customer_package_product_id, + "release_id": args.release_id, + "redaction_profile_id": args.customer_package_redaction_profile_id, + "title": args.customer_package_title, + "expires_at": args.customer_package_expires_at, + }, + ) + requests.append(request("/v1/customer-packages", f"{args.idempotency_prefix}-customer-package", payload_path.name)) + + if not requests: + raise SystemExit("no evidence inputs were supplied") + write_json(out, {"requests": requests}) + + +if __name__ == "__main__": + main() From fe4c4f29314140e0bb10c750fc02828cf1ee0187 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 10:27:31 +0300 Subject: [PATCH 134/287] fix: release api writer lease with caller context --- internal/adapters/postgres/store.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index 9cd10c0..afe19c3 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -129,8 +129,9 @@ func (s *Store) AcquireAPIWriterLease(ctx context.Context) (func(), error) { return nil, errors.New("another Evydence API writer is already active") } releaseConn = false + releaseCtx := context.WithoutCancel(ctx) return func() { - _, _ = conn.Exec(context.Background(), `SELECT pg_advisory_unlock($1)`, apiWriterLeaseKey) + _, _ = conn.Exec(releaseCtx, `SELECT pg_advisory_unlock($1)`, apiWriterLeaseKey) conn.Release() }, nil } From 11deac533de1cb452ebb4ec24c22f6ea30443b5e Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 10:36:43 +0300 Subject: [PATCH 135/287] docs: align release candidate evidence status --- CHANGELOG.md | 20 ++++++--- Makefile | 8 +++- README.md | 2 +- RELEASE_EVIDENCE.md | 2 +- docs/README.md | 1 + docs/reference/release-candidate.md | 2 +- docs/reference/release-notes-template.md | 55 ++++++++++++++++++++++++ docs/reference/release-validation.md | 4 +- scripts/release_candidate_package.sh | 8 +++- 9 files changed, 86 insertions(+), 16 deletions(-) create mode 100644 docs/reference/release-notes-template.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 796a3bf..28a54c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,12 +9,16 @@ results, no secure-release guarantee, and no regulator or auditor acceptance. ## Unreleased -Release status: controlled self-hosted production candidate hardening. Current -builds are suitable for evaluation, pilots, and controlled internal production -after operator review. Broad self-hosted production readiness, regulated -production, and hosted SaaS production remain out of scope for this status. -Release-candidate tagging requires the production gate and checklist in -`docs/reference/release-candidate.md`. +No public release notes have been added after `v0.1.0-rc.2`. + +## v0.1.0-rc.2 - 2026-05-31 + +Release status: controlled self-hosted production candidate. This build is +suitable for evaluation, pilots, and controlled internal production after +operator review. Broad self-hosted production readiness, regulated production, +and hosted SaaS production remain out of scope for this status. The local +release-candidate package for this tag was generated with +`make release-candidate-check TAG=v0.1.0-rc.2`. ### Added @@ -23,9 +27,11 @@ Release-candidate tagging requires the production gate and checklist in - Production-readiness profile, production gate, and coverage-threshold gate. - Release-candidate checklist requiring production-check evidence, checksums, signed artifact manifests, release notes, and documented limitations. -- Release-candidate package gate for `v0.1.0-rc.1` artifacts, checksums, +- Release-candidate package gate for controlled release-candidate artifacts, checksums, OpenAPI and migration checksums, checked release notes, signed release manifest, and manifest signature. +- Local `v0.1.0-rc.2` annotated release-candidate tag and signed evidence + package generated under ignored `dist/v0.1.0-rc.2/`. - Focused PostgreSQL critical mutations for tenants, credential hashes, idempotency records, audit-chain entries, release bundles, signatures, verification results, provider verification receipts, vulnerability diff --git a/Makefile b/Makefile index 5043a33..73005de 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ GOLANGCI_LINT_VERSION ?= v2.11.4 GOSEC_VERSION ?= v2.25.0 GOVULNCHECK_VERSION ?= v1.2.0 -TAG ?= v0.1.0-rc.1 +TAG ?= .PHONY: help tools fmt lint vuln gosec test test-race coverage coverage-check openapi-check openapi-precision-check meta-check docs-check deploy-check sdk-check fast-check finalize release-acceptance release-check production-check release-candidate-check migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean @@ -101,6 +101,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @test -f docs/reference/observability.md @test -f docs/reference/production-readiness.md @test -f docs/reference/release-candidate.md + @test -f docs/reference/release-notes-template.md @test -f docs/reference/release-notes-v0.1.0-rc.1.md @test -f docs/reference/worker-outbox.md @test -f docs/reference/release-validation.md @@ -128,6 +129,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod "reference/observability.md" \ "reference/production-readiness.md" \ "reference/release-candidate.md" \ + "reference/release-notes-template.md" \ "reference/release-notes-v0.1.0-rc.1.md" \ "reference/worker-outbox.md" \ "reference/release-validation.md" \ @@ -166,6 +168,8 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'evydence-release-manifest.sig.json' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'gh release create' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'Controlled self-hosted production candidate' docs/reference/release-candidate.md >/dev/null + @grep -F 'Controlled self-hosted production candidate' docs/reference/release-notes-template.md >/dev/null + @grep -F 'not legal compliance proof' docs/reference/release-notes-template.md >/dev/null @grep -F 'Controlled self-hosted production candidate' docs/reference/release-notes-v0.1.0-rc.1.md >/dev/null @grep -F 'not legal compliance proof' docs/reference/release-notes-v0.1.0-rc.1.md >/dev/null @grep -F 'Use one API writer replica' docs/reference/release-candidate.md >/dev/null @@ -248,7 +252,7 @@ release-check: ## Release validation with security, race, and configured live in production-check: ## Strict self-hosted production readiness gate; requires live PostgreSQL and coverage threshold @scripts/production_check.sh -release-candidate-check: ## Build and validate a signed release-candidate package with TAG=v0.1.0-rc.1 by default +release-candidate-check: ## Build and validate a signed release-candidate package with explicit TAG=vX.Y.Z-rc.N @scripts/release_candidate_package.sh "$(TAG)" migration-compatibility-check: ## Verify every committed migration prefix upgrades to current schema diff --git a/README.md b/README.md index 42f4388..4b78066 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ It does not make legal compliance conclusions, grant certification, prove SBOM c ## Current Implementation -This repository contains a Go implementation under module `github.com/aatuh/evydence`. The current status is controlled self-hosted production candidate hardening: useful for evaluation, pilots, and controlled internal production after operator review, with a stricter production gate and release-candidate checklist tracking the remaining work before any broader production claim. +This repository contains a Go implementation under module `github.com/aatuh/evydence`. The current status is controlled self-hosted production candidate: useful for evaluation, pilots, and controlled internal production after operator review, with a stricter production gate and release-candidate checklist tracking the remaining work before any broader production claim. A local signed `v0.1.0-rc.2` evidence package has been generated from this checkout; public release publication remains a separate operator action. ### API And Contracts diff --git a/RELEASE_EVIDENCE.md b/RELEASE_EVIDENCE.md index 99fca26..55e05ce 100644 --- a/RELEASE_EVIDENCE.md +++ b/RELEASE_EVIDENCE.md @@ -28,7 +28,7 @@ requires live PostgreSQL through `EVYDENCE_TEST_DATABASE_URL`, enforces the coverage threshold, and runs a local release artifact signing smoke test. A failure means the build has not yet met the self-hosted production profile. -`make release-candidate-check TAG=v0.1.0-rc.1` is the controlled release +`make release-candidate-check TAG=` is the controlled release candidate packaging gate. It requires a clean worktree, live PostgreSQL, and release signing material, then writes release archives, checksums, OpenAPI and migration checksums, coverage output, release-check summary, checked release diff --git a/docs/README.md b/docs/README.md index 5771d51..9ed8879 100644 --- a/docs/README.md +++ b/docs/README.md @@ -25,6 +25,7 @@ This documentation is organized by reader task. Implementation claims should be - [Observability](reference/observability.md): readiness, admin metrics, Prometheus rules, and dashboard starter assets. - [Production readiness](reference/production-readiness.md): self-hosted production profiles, production gates, and exit criteria. - [Release candidate checklist](reference/release-candidate.md): required evidence before tagging a controlled self-hosted release candidate. +- [Release notes template](reference/release-notes-template.md): checked wording used by release-candidate packaging when a tag-specific note file is absent. - [Release notes v0.1.0-rc.1](reference/release-notes-v0.1.0-rc.1.md): checked release-note wording for the first controlled self-hosted release candidate. - [Worker outbox contract](reference/worker-outbox.md): durable job kinds, idempotency, and safe logging rules. - [Release validation](reference/release-validation.md): canonical `make release-check` behavior and summary evidence. diff --git a/docs/reference/release-candidate.md b/docs/reference/release-candidate.md index 00e20ae..192743c 100644 --- a/docs/reference/release-candidate.md +++ b/docs/reference/release-candidate.md @@ -30,7 +30,7 @@ Run from a clean checkout with a disposable PostgreSQL database: ```sh set -a; . ./.test.env; set +a export EVYDENCE_RELEASE_SIGNING_PRIVATE_KEY_B64="$(cat evydence-release-private.key)" -make release-candidate-check TAG=v0.1.0-rc.1 +make release-candidate-check TAG= ``` The target runs `scripts/release_candidate_package.sh`, which requires a clean diff --git a/docs/reference/release-notes-template.md b/docs/reference/release-notes-template.md new file mode 100644 index 0000000..f9a7339 --- /dev/null +++ b/docs/reference/release-notes-template.md @@ -0,0 +1,55 @@ +# Evydence {{TAG}} Release Notes + +Status: Controlled self-hosted production candidate. + +This release candidate is intended for evaluation, pilots, and controlled +internal production after operator review. It is not legal compliance proof, +not a certification, not a secure-release guarantee, not complete SBOM proof, +not authoritative vulnerability coverage, and not auditor or regulator +acceptance. + +## Supported Profile + +- Self-hosted API, worker, PostgreSQL, and object storage deployment. +- Use a single API writer replica for the current production profile. +- Worker replicas may scale through PostgreSQL outbox row locking. +- External TLS, secret management, backup automation, monitoring, and incident + response remain operator responsibilities. + +## Evidence In This Release Package + +- Passing `make production-check` evidence with live PostgreSQL. +- `release-check-summary.txt` from the same run. +- `coverage.out` and threshold evidence. +- `openapi.yaml` and `openapi.sha256`. +- `migrations.sha256`. +- `SHA256SUMS` for release archives and evidence files. +- Signed release artifact manifest and manifest signature. + +## Install And Upgrade Notes + +- Use PostgreSQL for durable runtime state. +- Use S3/MinIO-compatible object storage or the documented filesystem mode for + local evaluation only. +- Set `ENV=production`, a non-default `EVYDENCE_API_KEY_PEPPER`, and + `EVYDENCE_SIGNING_KEY_MODE=external` or `EVYDENCE_SIGNING_KEY_MODE=aws-kms` + for production-profile startup. +- Apply all committed migrations before starting API or worker processes. +- For Kubernetes, set an explicit image tag or digest and keep API replicas at + `1` until HA/multi-writer support is reviewed. + +## Known Limitations + +- Full repository decomposition remains hardening work; focused critical + PostgreSQL writes cover the highest-risk runtime mutations, but not every + resource family. +- HA/multi-writer API operation is not supported in this profile. +- The AWS KMS signing executor is included; non-AWS cloud KMS/HSM SDK adapters + are not included. +- OIDC UserInfo validation is available when a caller supplies an access token; + provider-specific management API validation and external group + synchronization remain deployment-dependent. +- Broader WORM/object-lock proof beyond configured S3/MinIO bucket and + sample-object retention/legal-hold checks remains deployment-dependent. +- Operators must run backup and restore rehearsals for their target + infrastructure before relying on this in production. diff --git a/docs/reference/release-validation.md b/docs/reference/release-validation.md index 0a741ad..ccbae9f 100644 --- a/docs/reference/release-validation.md +++ b/docs/reference/release-validation.md @@ -67,10 +67,10 @@ The local packaging gate is: ```sh set -a; . ./.test.env; set +a export EVYDENCE_RELEASE_SIGNING_PRIVATE_KEY_B64="$(cat evydence-release-private.key)" -make release-candidate-check TAG=v0.1.0-rc.1 +make release-candidate-check TAG= ``` -`scripts/release_candidate_package.sh` creates `dist/v0.1.0-rc.1/` with the +`scripts/release_candidate_package.sh` creates `dist//` with the release archives, `SHA256SUMS`, `openapi.sha256`, `migrations.sha256`, `coverage.out`, `release-check-summary.txt`, checked release notes, signed release manifest, and manifest signature. It refuses dirty worktrees, invalid diff --git a/scripts/release_candidate_package.sh b/scripts/release_candidate_package.sh index fe4a813..1ac0e03 100755 --- a/scripts/release_candidate_package.sh +++ b/scripts/release_candidate_package.sh @@ -89,8 +89,12 @@ done cp openapi.yaml "$distdir/openapi.yaml" cp coverage.out "$distdir/coverage.out" cp tmp/release-check-summary.txt "$distdir/release-check-summary.txt" -cp docs/reference/release-notes-v0.1.0-rc.1.md "$distdir/release-notes.md" -sed -i.bak "s/v0.1.0-rc.1/${tag}/g" "$distdir/release-notes.md" +notes_source="docs/reference/release-notes-${tag}.md" +if [[ ! -f "$notes_source" ]]; then + notes_source="docs/reference/release-notes-template.md" +fi +cp "$notes_source" "$distdir/release-notes.md" +sed -i.bak "s/{{TAG}}/${tag}/g; s/v0.1.0-rc.1/${tag}/g" "$distdir/release-notes.md" rm -f "$distdir/release-notes.md.bak" (cd "$distdir" && sha256sum openapi.yaml > openapi.sha256) From 74206f7318c7dae6d0aeed874b04438796594a69 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 10:44:43 +0300 Subject: [PATCH 136/287] docs: record maturity v2 implementation status --- .implementation_increments.md | 2 +- .maturity_next_steps_v2_status.md | 91 +++++++++++++++++++++++++++++++ docs/api.md | 5 +- docs/architecture.md | 2 +- 4 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 .maturity_next_steps_v2_status.md diff --git a/.implementation_increments.md b/.implementation_increments.md index 609c705..c7eef84 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -203,7 +203,7 @@ Status legend: Added role bindings for users and collectors, role-to-scope enforcement for human sessions, admin/customer/collector roles, tenant isolation checks, API routes, and tests. 59. `[x]` Enterprise SSO/SAML/OIDC - Added OIDC/SAML provider records, verified identity links, one-time hashed SSO session tokens, session revocation, role mapping metadata, static JWKS-backed local OIDC ID-token verification, OIDC discovery/JWKS refresh, local SAML assertion verification against configured signing certificates, audit entries, API routes, and tests. Live provider API validation, browser login callbacks, browser cookie/session handling, and group synchronization remain external/provider work. + Added OIDC/SAML provider records, verified identity links, one-time hashed SSO session tokens, session revocation, role mapping metadata, static JWKS-backed local OIDC ID-token verification, OIDC discovery/JWKS refresh, local SAML assertion verification against configured signing certificates, API-first session exchange with HttpOnly session-cookie output, audit entries, API routes, and tests. Live provider management API validation, browser redirect/callback orchestration, and external group synchronization remain external/provider work. 60. `[x]` Multi-Tenant Admin Console API Added low-detail instance admin snapshot API with tenant/resource counts and no raw evidence, token, or secret exposure. diff --git a/.maturity_next_steps_v2_status.md b/.maturity_next_steps_v2_status.md new file mode 100644 index 0000000..c5a32b2 --- /dev/null +++ b/.maturity_next_steps_v2_status.md @@ -0,0 +1,91 @@ +# Maturity V2 Implementation Status + +Source report: `.maturity_next_steps_v2.md` + +Last updated: 2026-05-31 + +This file records repository evidence after the v2 maturity report. It is a +status companion, not a replacement for the report. Evydence remains a +controlled self-hosted production candidate; this status does not claim broad +production readiness, regulated production readiness, hosted SaaS readiness, +legal compliance, certification, complete SBOM proof, authoritative scanner +coverage, or a secure-release guarantee. + +## Closed Repo-Local Findings + +- Tagged release-candidate evidence: local annotated tag `v0.1.0-rc.2` points + at the current release-candidate commit, and `dist/v0.1.0-rc.2/` was generated + by `make release-candidate-check TAG=v0.1.0-rc.2` with live PostgreSQL, + coverage threshold, migration compatibility, signed manifest, checksums, + OpenAPI checksum, migration checksums, release notes, and manifest + verification. +- Production claim clarity: README, changelog, release evidence, release + validation, release-candidate, Kubernetes, production-readiness, and + hardening docs use controlled self-hosted production candidate language and + preserve non-claims. +- Critical relational writes: critical runtime state and release/evidence-core + mutations have focused PostgreSQL transaction paths, production startup + defaults to relational-only load, and production writes skip compatibility + snapshot persistence when PostgreSQL relational support is configured. +- Single-writer HA stance: production API startup enforces a PostgreSQL + advisory writer lease, Helm defaults keep API replicas at one, and docs state + worker replicas may scale through PostgreSQL outbox locking while API + multi-writer mode remains unsupported. +- Helm hardening: chart values require explicit image tags for release installs + and include security contexts, resource/probe configuration, network policy, + and single-writer guidance validated by `make deploy-check`. +- Security intake: root security/support/governance metadata documents private + security intake, supported scope, sensitive-data handling, disclosure + expectations, and non-goals without asking reporters to disclose secrets or + raw evidence publicly. +- Trust automation hardening: signing operations can use the HTTPS signing + gateway or built-in AWS KMS executor; OIDC provider verification can call + discovered UserInfo endpoints with a supplied access token without persisting + that token; S3/MinIO object-retention verification can check bucket defaults + plus sample-object retention and legal-hold status. +- Integration proof: the checked GitHub Actions example now covers build + provenance, artifact digest, SBOM upload, Grype/Trivy vulnerability-scan + normalization, optional OpenVEX and release-bundle evidence, and manifest + upload through the CLI. + +## Still Not A Broad Production Claim + +These items remain outside the current controlled candidate, or require +deployment/provider evidence that cannot be completed by repository code alone: + +- High-scale multi-writer API HA remains unsupported until the large application + ledger is split into focused services or another reviewed concurrency-control + design replaces the current single-writer stance. +- Non-AWS cloud KMS/HSM custody remains deployment-specific. The HTTPS signing + gateway covers tenant-controlled KMS/HSM services without sending raw payload + bytes, and AWS KMS has a direct executor, but other providers require + operator selection, credentials, IAM review, and provider-specific tests. +- Provider management API validation and external group synchronization remain + provider-specific. Evydence can verify configured OIDC/SAML trust material and + optional OIDC UserInfo checks, but GitHub, GitLab, IdP, or directory group + authority still depends on the configured provider and operator review. +- WORM/object-lock enforcement beyond configured bucket and sample-object + checks depends on object-store creation mode, IAM policy, lifecycle rules, + backups, retention settings, and provider audit evidence. +- Public transparency provider semantics and availability remain external. + Evydence can verify operator-supplied or fetched inclusion proof material, but + provider trust and timestamp semantics require deployment review. +- Hosted SaaS production, regulated production, and customer-specific legal or + audit conclusions require separate controls, support, privacy, operational, + and external review work. + +## Current Gates + +Recent local evidence: + +- `make docs-check`: passed after release-status and docs-consistency updates. +- `make release-acceptance`: passed after release-note template wiring. +- `make finalize`: passed after release-note template wiring. +- `make release-candidate-check TAG=v0.1.0-rc.2`: passed after the template + change and regenerated the signed local release-candidate package. +- `make production-check`: passed inside the release-candidate packaging run + with live PostgreSQL and total coverage at `80.1%`. + +Release publication, cloud-provider validation, production object-lock proof, +and deployment-specific backup/restore rehearsals must be run in the target +operator environment before relying on those controls. diff --git a/docs/api.md b/docs/api.md index 1440392..9a69dc2 100644 --- a/docs/api.md +++ b/docs/api.md @@ -428,7 +428,10 @@ Source snapshots capture submitted provider metadata. They do not call provider ## Current Contract Limitations - `openapi.yaml` is generated as compact JSON-style YAML and is optimized for drift checks and tooling, not prose review. -- A subset of high-value operations has precise named schemas and response envelopes. Some broad resource families still use generic data envelopes until generated clients require fully named response schemas for every route. +- The current OpenAPI precision gate reports every registered public operation + as precise. New or changed routes should add endpoint-specific request, + response, parameter, auth-scope, idempotency, and error metadata before they + are merged. - Operation-level examples are maintained here and in tests until the generator emits richer examples. - OpenAPI diffing classifies operation removal/addition, required request-body and request-field changes, response status changes, and broad path-count fallback for older stored contracts. diff --git a/docs/architecture.md b/docs/architecture.md index b405ea5..acc69df 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -46,7 +46,7 @@ Evidence summaries, questionnaire drafts, graph snapshots, PDF packages, and ano ## Provider And Deployment Boundaries -GitHub OIDC subject metadata can be captured, and stored OIDC/SAML identity links can be verified against tenant metadata. OIDC provider records can include public JWKS material for local EdDSA or RS256 ID-token signature and claim verification, and SAML provider records can include PEM signing certificates for local assertion signature and claim verification. Trust material can be rotated without recreating the provider. Live provider API verification, discovery, browser login callbacks, and group synchronization remain trust boundaries outside those records. Collector supply-chain records track pinned collector versions with signature, SBOM, and scan evidence where available; commercial and marketplace collector definitions add extension metadata without granting provider trust. +GitHub OIDC subject metadata can be captured, and stored OIDC/SAML identity links can be verified against tenant metadata. OIDC provider records can include public JWKS material for local EdDSA or RS256 ID-token signature and claim verification, and SAML provider records can include PEM signing certificates for local assertion signature and claim verification. Trust material can be rotated without recreating the provider, and OIDC public JWKS can be refreshed from discovery metadata. SSO credential exchange can issue bearer session secrets plus HttpOnly cookies for browser clients after local OIDC/SAML verification. Live provider management API verification, browser redirect/callback orchestration, and external group synchronization remain trust boundaries outside those records. Collector supply-chain records track pinned collector versions with signature, SBOM, and scan evidence where available; commercial and marketplace collector definitions add extension metadata without granting provider trust. Air-gapped import-bundle workflows preserve the same tenant-scoped import path after controlled transfer. Object-retention policy APIs record tenant-scoped retention intent and, when the S3/MinIO object-store adapter is configured, verify bucket versioning plus default object-lock mode and duration. Policies can also name a tenant-prefixed sample object key for object-level retention and optional legal-hold checks where the provider supports them. Those checks are evidence for the configured bucket and sample object only; WORM/object-lock enforcement, IAM policy, lifecycle rules, and deployment-specific retention review remain operator responsibilities. From eac67853c4595abe7ed33a988d28ceb12f9e5297 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 10:49:05 +0300 Subject: [PATCH 137/287] docs: clarify remaining provider trust boundaries --- .implementation_increments.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.implementation_increments.md b/.implementation_increments.md index c7eef84..8785700 100644 --- a/.implementation_increments.md +++ b/.implementation_increments.md @@ -253,7 +253,7 @@ Status legend: - `[x]` Object-retention verification receipts now record a reproducible verification hash with bucket-level and optional sample-object checks, while broad WORM/object-lock enforcement remains a deployment and object-store control. - `[x]` External signing-provider operation receipts now record payload hashes, checks, and signature references, while production KMS/HSM adapter execution remains deployment hardening work. -- `[x]` Stored OIDC/SAML identity-link verification records provider-verification receipts, and OIDC ID tokens plus SAML assertions can be verified locally against configured tenant trust material. Public OIDC JWKS can be refreshed from discovery metadata, and public JWKS plus SAML signing certificates can be rotated without recreating the provider. Live provider API calls, browser login callbacks, browser cookie/session handling, and group synchronization remain external/provider work. +- `[x]` Stored OIDC/SAML identity-link verification records provider-verification receipts, and OIDC ID tokens plus SAML assertions can be verified locally against configured tenant trust material. Public OIDC JWKS can be refreshed from discovery metadata, public JWKS plus SAML signing certificates can be rotated without recreating the provider, and SSO credential exchange can issue bearer session secrets plus HttpOnly cookies. Live provider management API calls, browser redirect/callback orchestration, and external group synchronization remain external/provider work. - `[x]` Public transparency log records now link local Merkle checkpoints to external entry metadata and can verify operator-supplied or fetched inclusion proof material locally. Provider-specific trust semantics and availability remain deployment responsibilities. - `[x]` Marketplace collector records now capture package metadata and evidence references, and expose package health reports for signature, SBOM, and vulnerability scan evidence gaps. Marketplace distribution remains external operational hardening. - `[x]` Docker/Helm runtime packaging now includes the worker binary and migrations and uses commands that match the image PATH. From 9a489e55d806f0033cdf38eee4d22114ea1da3eb Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 11:02:36 +0300 Subject: [PATCH 138/287] fix: enforce single api writer mode --- Makefile | 3 ++ README.md | 2 +- cmd/evydence-api/main.go | 30 ++++++++++++++ cmd/evydence-api/main_test.go | 40 +++++++++++++++++++ deploy/helm/evydence/templates/configmap.yaml | 2 + deploy/helm/evydence/values.yaml | 1 + docs/kubernetes.md | 3 +- docs/reference/configuration.md | 11 +++-- docs/reference/production-readiness.md | 14 ++++--- 9 files changed, 95 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 73005de..8bbd7ab 100644 --- a/Makefile +++ b/Makefile @@ -187,6 +187,9 @@ deploy-check: ## Validate deployment and air-gap skeletons exist @test -f deploy/observability/grafana-dashboard.json @grep -F 'tag: ""' deploy/helm/evydence/values.yaml >/dev/null @grep -F 'replicas: 1' deploy/helm/evydence/values.yaml >/dev/null + @grep -F 'writerMode: single' deploy/helm/evydence/values.yaml >/dev/null + @grep -F 'EVYDENCE_API_WRITER_MODE' deploy/helm/evydence/templates/configmap.yaml >/dev/null + @grep -F 'EVYDENCE_API_WRITER_REPLICAS' deploy/helm/evydence/templates/configmap.yaml >/dev/null @grep -F 'runAsNonRoot: true' deploy/helm/evydence/values.yaml >/dev/null @grep -F 'allowPrivilegeEscalation: false' deploy/helm/evydence/values.yaml >/dev/null @grep -F 'required "image.tag is required' deploy/helm/evydence/templates/deployment-api.yaml >/dev/null diff --git a/README.md b/README.md index 4b78066..36cb182 100644 --- a/README.md +++ b/README.md @@ -109,4 +109,4 @@ make postgres-integration-test `make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. -`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required release-candidate evidence, but it does not by itself close the remaining service decomposition, non-AWS KMS/HSM SDK providers, provider-specific management API/group synchronization, broader object-lock enforcement beyond configured bucket/sample-object checks, HA, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. Critical runtime mutations for tenants, credential hashes, idempotency, audit-chain entries, release bundles, signatures, verification results, vulnerability decisions, and outbox jobs use focused PostgreSQL write paths when available. Release-ledger and evidence-core mutations for products, projects, releases, artifacts, evidence items, evidence lifecycle events, SBOMs, vulnerability scans, OpenAPI contracts, VEX documents, audit-chain entries, and parser outbox jobs also use focused PostgreSQL write paths when available. Remaining aggregate persistence calls use PostgreSQL relational synchronization without writing the compatibility snapshot when that store is configured. Current self-hosted production guidance still uses a single API writer replica; production API startup enforces that stance with a PostgreSQL advisory writer lease, and worker replicas may scale through PostgreSQL outbox row locking. +`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required release-candidate evidence, but it does not by itself close the remaining service decomposition, non-AWS KMS/HSM SDK providers, provider-specific management API/group synchronization, broader object-lock enforcement beyond configured bucket/sample-object checks, HA, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. Critical runtime mutations for tenants, credential hashes, idempotency, audit-chain entries, release bundles, signatures, verification results, vulnerability decisions, and outbox jobs use focused PostgreSQL write paths when available. Release-ledger and evidence-core mutations for products, projects, releases, artifacts, evidence items, evidence lifecycle events, SBOMs, vulnerability scans, OpenAPI contracts, VEX documents, audit-chain entries, and parser outbox jobs also use focused PostgreSQL write paths when available. Remaining aggregate persistence calls use PostgreSQL relational synchronization without writing the compatibility snapshot when that store is configured. Current self-hosted production guidance still uses a single API writer replica; production API startup rejects unsupported writer modes and declared replica counts above one, then enforces that stance with a PostgreSQL advisory writer lease. Worker replicas may scale through PostgreSQL outbox row locking. diff --git a/cmd/evydence-api/main.go b/cmd/evydence-api/main.go index ed1b287..a8db24e 100644 --- a/cmd/evydence-api/main.go +++ b/cmd/evydence-api/main.go @@ -38,6 +38,9 @@ func run() error { if err := validateRuntimeConfig(production, databaseURL, pepper, strings.TrimSpace(os.Getenv("EVYDENCE_SIGNING_KEY_MODE")), strings.EqualFold(os.Getenv("EVYDENCE_PRINT_BOOTSTRAP_SECRET"), "true")); err != nil { return err } + if err := validateAPIWriterMode(production, os.Getenv("EVYDENCE_API_WRITER_MODE"), os.Getenv("EVYDENCE_API_WRITER_REPLICAS")); err != nil { + return err + } cfg := app.Config{APIKeyPepper: pepper} cfg.WorkerOwnedParserSideEffects = boolEnv("EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS") cfg.OIDC = oidcdiscovery.New(oidcdiscovery.Config{ @@ -199,6 +202,33 @@ func validateRuntimeConfig(production bool, databaseURL, pepper, signingKeyMode return nil } +func validateAPIWriterMode(production bool, mode, replicas string) error { + normalizedMode := strings.ToLower(strings.TrimSpace(mode)) + if normalizedMode == "" { + normalizedMode = "single" + } + switch normalizedMode { + case "single", "single-writer": + default: + if production { + return fmt.Errorf("production supports only EVYDENCE_API_WRITER_MODE=single until multi-writer concurrency controls are implemented") + } + } + + replicaValue := strings.TrimSpace(replicas) + if replicaValue == "" { + return nil + } + replicaCount, err := strconv.Atoi(replicaValue) + if err != nil || replicaCount < 1 { + return fmt.Errorf("EVYDENCE_API_WRITER_REPLICAS must be a positive integer") + } + if production && replicaCount != 1 { + return fmt.Errorf("production supports only one API writer replica until multi-writer concurrency controls are implemented") + } + return nil +} + func envDefault(name, fallback string) string { if value := strings.TrimSpace(os.Getenv(name)); value != "" { return value diff --git a/cmd/evydence-api/main_test.go b/cmd/evydence-api/main_test.go index a5acacf..3849c58 100644 --- a/cmd/evydence-api/main_test.go +++ b/cmd/evydence-api/main_test.go @@ -52,6 +52,46 @@ func TestValidateRuntimeConfigAllowsProductionAWSKMSMode(t *testing.T) { } } +func TestValidateAPIWriterModeAllowsProductionSingleWriter(t *testing.T) { + if err := validateAPIWriterMode(true, "single", "1"); err != nil { + t.Fatalf("single writer production mode should be accepted: %v", err) + } + if err := validateAPIWriterMode(true, "", ""); err != nil { + t.Fatalf("default writer mode should be accepted: %v", err) + } +} + +func TestValidateAPIWriterModeRejectsProductionMultiWriter(t *testing.T) { + err := validateAPIWriterMode(true, "multi", "1") + if err == nil || !strings.Contains(err.Error(), "EVYDENCE_API_WRITER_MODE") { + t.Fatalf("multi-writer production mode err=%v", err) + } +} + +func TestValidateAPIWriterModeRejectsProductionReplicaCountAboveOne(t *testing.T) { + err := validateAPIWriterMode(true, "single", "2") + if err == nil || !strings.Contains(err.Error(), "one API writer replica") { + t.Fatalf("production replica count err=%v", err) + } +} + +func TestValidateAPIWriterModeRejectsInvalidReplicaCount(t *testing.T) { + for _, value := range []string{"0", "-1", "not-a-number"} { + t.Run(value, func(t *testing.T) { + err := validateAPIWriterMode(false, "multi", value) + if err == nil || !strings.Contains(err.Error(), "EVYDENCE_API_WRITER_REPLICAS") { + t.Fatalf("invalid replica count err=%v", err) + } + }) + } +} + +func TestValidateAPIWriterModeAllowsLocalExperimentalMode(t *testing.T) { + if err := validateAPIWriterMode(false, "multi", "3"); err != nil { + t.Fatalf("local experimental writer mode should not be production-blocked: %v", err) + } +} + func TestPostgresLoadModeDefaultsToRelationalOnlyInProduction(t *testing.T) { mode, err := postgres.ResolveLoadMode("", true) if err != nil { diff --git a/deploy/helm/evydence/templates/configmap.yaml b/deploy/helm/evydence/templates/configmap.yaml index 4cf1711..29ea311 100644 --- a/deploy/helm/evydence/templates/configmap.yaml +++ b/deploy/helm/evydence/templates/configmap.yaml @@ -5,6 +5,8 @@ metadata: data: ENV: {{ ternary "production" "development" .Values.env.production | quote }} EVYDENCE_ADDR: {{ .Values.api.addr | quote }} + EVYDENCE_API_WRITER_MODE: {{ .Values.api.writerMode | quote }} + EVYDENCE_API_WRITER_REPLICAS: {{ .Values.api.replicas | quote }} EVYDENCE_OBJECT_STORE: {{ .Values.env.objectStore | quote }} EVYDENCE_S3_ENDPOINT: {{ .Values.env.s3Endpoint | quote }} EVYDENCE_S3_BUCKET: {{ .Values.env.s3Bucket | quote }} diff --git a/deploy/helm/evydence/values.yaml b/deploy/helm/evydence/values.yaml index 1fcf8fa..6c2bca6 100644 --- a/deploy/helm/evydence/values.yaml +++ b/deploy/helm/evydence/values.yaml @@ -11,6 +11,7 @@ api: # fails closed until multi-writer concurrency controls are implemented and # documented. replicas: 1 + writerMode: single addr: ":8080" resources: requests: diff --git a/docs/kubernetes.md b/docs/kubernetes.md index d89af7d..28da940 100644 --- a/docs/kubernetes.md +++ b/docs/kubernetes.md @@ -40,6 +40,7 @@ Relevant chart values are defined in `deploy/helm/evydence/values.yaml`: |-------|---------| | `image.repository`, `image.tag` | API and worker image. | | `api.replicas` | API writer replicas. Keep `1` for the current production profile. | +| `api.writerMode` | Runtime writer mode passed as `EVYDENCE_API_WRITER_MODE`. Keep `single` for production. | | `worker.replicas` | Worker replicas. May be scaled with PostgreSQL outbox locking. | | `api.resources`, `worker.resources` | Resource requests and limits. | | `podSecurityContext`, `containerSecurityContext` | Non-root and least-privilege pod/container defaults. | @@ -83,4 +84,4 @@ Rollback does not roll back PostgreSQL data or object-store payloads. Keep datab ## Production Notes -Production deployments should use external PostgreSQL, S3/MinIO-compatible object storage, TLS ingress, backup automation, network access controls, and external signing. Current production guidance uses a single API writer replica; production API startup enforces that stance with a PostgreSQL advisory writer lease, and worker replicas can scale independently through PostgreSQL outbox row locking. See [Production hardening review](production-hardening.md), [Production readiness](reference/production-readiness.md), and [Configuration](reference/configuration.md). +Production deployments should use external PostgreSQL, S3/MinIO-compatible object storage, TLS ingress, backup automation, network access controls, and external signing. Current production guidance uses a single API writer replica; the chart passes `EVYDENCE_API_WRITER_MODE=single` and `EVYDENCE_API_WRITER_REPLICAS=1`, production API startup rejects unsupported writer modes or replica counts above one, then enforces the stance with a PostgreSQL advisory writer lease. Worker replicas can scale independently through PostgreSQL outbox row locking. See [Production hardening review](production-hardening.md), [Production readiness](reference/production-readiness.md), and [Configuration](reference/configuration.md). diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index cc4997a..0fdd740 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -28,6 +28,8 @@ The example secrets are placeholders. Replace them before using shared or produc | `EVYDENCE_API_KEY_PEPPER` | Production yes | `change-me-long-random-pepper` | HMAC pepper for API key, session, and portal-token hashes. Use a long random value. | | `EVYDENCE_DATABASE_URL` | Production yes | `postgres://evydence:change-me@localhost:5432/evydence?sslmode=disable` | Enables PostgreSQL durable state, projections, migrations, and persisted outbox jobs. If unset, the API uses in-process state. | | `EVYDENCE_POSTGRES_LOAD_MODE` | No | `snapshot_preferred` locally, `relational_only` when `ENV=production` | PostgreSQL state load mode. Supported values are `snapshot_preferred`, `relational_preferred`, and `relational_only`. Production defaults to relational-only startup reads, refuses snapshot fallback modes, and disables compatibility snapshot writes; snapshots remain available for local compatibility and non-production migration checks. | +| `EVYDENCE_API_WRITER_MODE` | No | `single` | API writer concurrency mode. Production supports only `single` or `single-writer` until multi-writer concurrency controls are implemented. | +| `EVYDENCE_API_WRITER_REPLICAS` | No | unset, chart sets `1` | Optional self-declared API writer replica count used by startup safety checks. Production rejects values other than `1`. | | `EVYDENCE_OBJECT_STORE` | No | `filesystem` | Supported values are `filesystem`, `s3`, and `minio`. | | `EVYDENCE_OBJECT_DIR` | Filesystem object store | `./tmp/objects` | Local raw payload storage root. | | `EVYDENCE_S3_ENDPOINT` | S3/MinIO object store | `localhost:9000` | Endpoint for S3-compatible object storage. | @@ -69,6 +71,8 @@ When `ENV=production`, the API refuses to start unless: - `EVYDENCE_SIGNING_KEY_MODE=external` or `EVYDENCE_SIGNING_KEY_MODE=aws-kms`. - `EVYDENCE_PRINT_BOOTSTRAP_SECRET` is not `true`. - `EVYDENCE_POSTGRES_LOAD_MODE`, when set, is `relational_only`. +- `EVYDENCE_API_WRITER_MODE`, when set, is `single` or `single-writer`. +- `EVYDENCE_API_WRITER_REPLICAS`, when set, is `1`. These checks reduce unsafe runtime defaults. They do not replace secret management, network controls, backup validation, or external signing operations. @@ -80,9 +84,10 @@ preserve existing workflows. Use `relational_preferred` only for controlled non-production migration or recovery checks that intentionally fall back to the snapshot. -In production, API startup takes a PostgreSQL advisory writer lease and fails -if another API writer already holds it. Worker replicas are not constrained by -that lease because outbox jobs use row locking. +In production, API startup rejects non-single writer mode, rejects a declared +API writer replica count above one, takes a PostgreSQL advisory writer lease, +and fails if another API writer already holds it. Worker replicas are not +constrained by that lease because outbox jobs use row locking. When PostgreSQL is configured, critical runtime mutations use focused transaction-backed writes for tenants, API-key hashes, SSO-session hashes, diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 01f05f0..889ad20 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -91,12 +91,14 @@ The current self-hosted production profile supports one API writer replica. This is intentional while the application still uses a large in-process ledger aggregate and some resource families still use aggregate persistence. Focused critical mutations reduce the riskiest `SaveState` dependence, but they are -not a full multi-writer concurrency design. When `ENV=production` and -PostgreSQL is configured, API startup takes a PostgreSQL advisory writer lease -and fails if another API writer already holds it. Do not scale API writer -replicas above one for production use until focused relational repository -writes cover all write families or another reviewed concurrency-control design -is implemented and documented. +not a full multi-writer concurrency design. When `ENV=production`, API startup +rejects unsupported `EVYDENCE_API_WRITER_MODE` values and rejects +`EVYDENCE_API_WRITER_REPLICAS` values above `1`. When PostgreSQL is configured, +startup also takes a PostgreSQL advisory writer lease and fails if another API +writer already holds it. Do not scale API writer replicas above one for +production use until focused relational repository writes cover all write +families or another reviewed concurrency-control design is implemented and +documented. Worker replicas may be scaled because persisted outbox jobs are claimed with PostgreSQL row locking. Scaling workers increases parser/signing/report From 32aa5c7fcc7a7c184fb45312a9ffab1360e1797a Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 11:06:27 +0300 Subject: [PATCH 139/287] feat: clarify gateway signing provider modes --- README.md | 4 +- cmd/evydence-api/main.go | 51 ++++++++++++++++++--- cmd/evydence-api/main_test.go | 49 ++++++++++++++++++-- docs/architecture.md | 2 +- docs/kubernetes.md | 6 ++- docs/production-hardening.md | 5 +- docs/reference/configuration.md | 12 ++++- docs/reference/production-readiness.md | 14 +++--- docs/reference/release-notes-template.md | 11 +++-- docs/reference/release-notes-v0.1.0-rc.1.md | 11 +++-- 10 files changed, 129 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 36cb182..2ae2159 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ This repository contains a Go implementation under module `github.com/aatuh/evyd - AGPL license, commercial licensing, governance, contribution, security, support, trademark, release-evidence, and changelog metadata. -Implemented-but-partial areas are documented explicitly: signing-provider operation receipts can use an HTTPS signing gateway or the built-in AWS KMS executor, but additional cloud KMS/HSM providers and deployment-specific custody review remain operator work; SSO credential exchange uses configured local OIDC/SAML trust material and session-scoped OIDC group-role mappings, and provider verification can optionally call OIDC UserInfo with a supplied access token, but this does not replace provider-specific management API validation or external group synchronization; and public transparency records can verify operator-supplied or fetched inclusion proof material without replacing provider-specific trust review. +Implemented-but-partial areas are documented explicitly: signing-provider operation receipts can use an HTTPS signing gateway, explicit gateway-backed `gcp-kms`, `azure-key-vault`, and `pkcs11-hsm` modes, or the built-in AWS KMS executor, but direct non-AWS cloud KMS/HSM SDK adapters and deployment-specific custody review remain operator work; SSO credential exchange uses configured local OIDC/SAML trust material and session-scoped OIDC group-role mappings, and provider verification can optionally call OIDC UserInfo with a supplied access token, but this does not replace provider-specific management API validation or external group synchronization; and public transparency records can verify operator-supplied or fetched inclusion proof material without replacing provider-specific trust review. ## License, Security, Support, And Governance @@ -109,4 +109,4 @@ make postgres-integration-test `make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. -`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required release-candidate evidence, but it does not by itself close the remaining service decomposition, non-AWS KMS/HSM SDK providers, provider-specific management API/group synchronization, broader object-lock enforcement beyond configured bucket/sample-object checks, HA, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. Critical runtime mutations for tenants, credential hashes, idempotency, audit-chain entries, release bundles, signatures, verification results, vulnerability decisions, and outbox jobs use focused PostgreSQL write paths when available. Release-ledger and evidence-core mutations for products, projects, releases, artifacts, evidence items, evidence lifecycle events, SBOMs, vulnerability scans, OpenAPI contracts, VEX documents, audit-chain entries, and parser outbox jobs also use focused PostgreSQL write paths when available. Remaining aggregate persistence calls use PostgreSQL relational synchronization without writing the compatibility snapshot when that store is configured. Current self-hosted production guidance still uses a single API writer replica; production API startup rejects unsupported writer modes and declared replica counts above one, then enforces that stance with a PostgreSQL advisory writer lease. Worker replicas may scale through PostgreSQL outbox row locking. +`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required release-candidate evidence, but it does not by itself close the remaining service decomposition, direct non-AWS KMS/HSM SDK providers, provider-specific management API/group synchronization, broader object-lock enforcement beyond configured bucket/sample-object checks, HA, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. Critical runtime mutations for tenants, credential hashes, idempotency, audit-chain entries, release bundles, signatures, verification results, vulnerability decisions, and outbox jobs use focused PostgreSQL write paths when available. Release-ledger and evidence-core mutations for products, projects, releases, artifacts, evidence items, evidence lifecycle events, SBOMs, vulnerability scans, OpenAPI contracts, VEX documents, audit-chain entries, and parser outbox jobs also use focused PostgreSQL write paths when available. Remaining aggregate persistence calls use PostgreSQL relational synchronization without writing the compatibility snapshot when that store is configured. Current self-hosted production guidance still uses a single API writer replica; production API startup rejects unsupported writer modes and declared replica counts above one, then enforces that stance with a PostgreSQL advisory writer lease. Worker replicas may scale through PostgreSQL outbox row locking. diff --git a/cmd/evydence-api/main.go b/cmd/evydence-api/main.go index a8db24e..ebbe4e2 100644 --- a/cmd/evydence-api/main.go +++ b/cmd/evydence-api/main.go @@ -35,7 +35,14 @@ func run() error { production := strings.EqualFold(os.Getenv("ENV"), "production") databaseURL := strings.TrimSpace(os.Getenv("EVYDENCE_DATABASE_URL")) pepper := strings.TrimSpace(os.Getenv("EVYDENCE_API_KEY_PEPPER")) - if err := validateRuntimeConfig(production, databaseURL, pepper, strings.TrimSpace(os.Getenv("EVYDENCE_SIGNING_KEY_MODE")), strings.EqualFold(os.Getenv("EVYDENCE_PRINT_BOOTSTRAP_SECRET"), "true")); err != nil { + if err := validateRuntimeConfig( + production, + databaseURL, + pepper, + strings.TrimSpace(os.Getenv("EVYDENCE_SIGNING_KEY_MODE")), + strings.TrimSpace(os.Getenv("EVYDENCE_SIGNING_EXECUTOR_URL")), + strings.EqualFold(os.Getenv("EVYDENCE_PRINT_BOOTSTRAP_SECRET"), "true"), + ); err != nil { return err } if err := validateAPIWriterMode(production, os.Getenv("EVYDENCE_API_WRITER_MODE"), os.Getenv("EVYDENCE_API_WRITER_REPLICAS")); err != nil { @@ -148,8 +155,8 @@ func run() error { } func openSigningExecutor() (app.SigningExecutor, error) { - mode := strings.ToLower(strings.TrimSpace(os.Getenv("EVYDENCE_SIGNING_KEY_MODE"))) - if mode == "aws_kms" || mode == "aws-kms" { + mode := normalizeSigningKeyMode(os.Getenv("EVYDENCE_SIGNING_KEY_MODE")) + if mode == "aws_kms" { region := strings.TrimSpace(os.Getenv("EVYDENCE_AWS_REGION")) if region == "" { region = strings.TrimSpace(os.Getenv("AWS_REGION")) @@ -167,6 +174,9 @@ func openSigningExecutor() (app.SigningExecutor, error) { return executor, nil } endpoint := strings.TrimSpace(os.Getenv("EVYDENCE_SIGNING_EXECUTOR_URL")) + if endpoint == "" && signingModeRequiresGateway(mode) { + return nil, fmt.Errorf("EVYDENCE_SIGNING_KEY_MODE=%s requires EVYDENCE_SIGNING_EXECUTOR_URL because no direct SDK executor is configured", mode) + } if endpoint == "" { return nil, nil } @@ -182,7 +192,7 @@ func openSigningExecutor() (app.SigningExecutor, error) { return executor, nil } -func validateRuntimeConfig(production bool, databaseURL, pepper, signingKeyMode string, printBootstrapSecret bool) error { +func validateRuntimeConfig(production bool, databaseURL, pepper, signingKeyMode, signingExecutorURL string, printBootstrapSecret bool) error { if !production { return nil } @@ -192,9 +202,12 @@ func validateRuntimeConfig(production bool, databaseURL, pepper, signingKeyMode if strings.TrimSpace(pepper) == "" || strings.TrimSpace(pepper) == "local-dev-pepper-change-me" { return errors.New("production requires a non-default EVYDENCE_API_KEY_PEPPER") } - normalizedMode := strings.ToLower(strings.TrimSpace(signingKeyMode)) - if normalizedMode != "external" && normalizedMode != "aws-kms" && normalizedMode != "aws_kms" { - return errors.New("production requires EVYDENCE_SIGNING_KEY_MODE=external or aws-kms; plaintext local signing keys are dev-only") + normalizedMode := normalizeSigningKeyMode(signingKeyMode) + if !productionSigningKeyMode(normalizedMode) { + return errors.New("production requires EVYDENCE_SIGNING_KEY_MODE=external, aws-kms, gcp-kms, azure-key-vault, or pkcs11-hsm; plaintext local signing keys are dev-only") + } + if signingModeRequiresGateway(normalizedMode) && strings.TrimSpace(signingExecutorURL) == "" { + return fmt.Errorf("production EVYDENCE_SIGNING_KEY_MODE=%s requires EVYDENCE_SIGNING_EXECUTOR_URL", normalizedMode) } if printBootstrapSecret { return errors.New("production refuses EVYDENCE_PRINT_BOOTSTRAP_SECRET=true") @@ -202,6 +215,30 @@ func validateRuntimeConfig(production bool, databaseURL, pepper, signingKeyMode return nil } +func normalizeSigningKeyMode(value string) string { + normalized := strings.ToLower(strings.TrimSpace(value)) + normalized = strings.ReplaceAll(normalized, "-", "_") + return normalized +} + +func productionSigningKeyMode(normalizedMode string) bool { + switch normalizedMode { + case "external", "aws_kms", "gcp_kms", "azure_key_vault", "pkcs11_hsm": + return true + default: + return false + } +} + +func signingModeRequiresGateway(normalizedMode string) bool { + switch normalizedMode { + case "gcp_kms", "azure_key_vault", "pkcs11_hsm": + return true + default: + return false + } +} + func validateAPIWriterMode(production bool, mode, replicas string) error { normalizedMode := strings.ToLower(strings.TrimSpace(mode)) if normalizedMode == "" { diff --git a/cmd/evydence-api/main_test.go b/cmd/evydence-api/main_test.go index 3849c58..da99431 100644 --- a/cmd/evydence-api/main_test.go +++ b/cmd/evydence-api/main_test.go @@ -8,7 +8,7 @@ import ( ) func TestValidateRuntimeConfigRejectsProductionBootstrapSecretPrinting(t *testing.T) { - err := validateRuntimeConfig(true, "postgres://example", "not-default", "external", true) + err := validateRuntimeConfig(true, "postgres://example", "not-default", "external", "", true) if err == nil { t.Fatal("expected production bootstrap secret printing to be rejected") } @@ -18,7 +18,7 @@ func TestValidateRuntimeConfigRejectsProductionBootstrapSecretPrinting(t *testin } func TestValidateRuntimeConfigAllowsLocalBootstrapSecretPrinting(t *testing.T) { - if err := validateRuntimeConfig(false, "", "", "", true); err != nil { + if err := validateRuntimeConfig(false, "", "", "", "", true); err != nil { t.Fatalf("local config should allow explicit bootstrap secret printing: %v", err) } } @@ -38,7 +38,7 @@ func TestValidateRuntimeConfigRejectsProductionDefaults(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - err := validateRuntimeConfig(true, tt.database, tt.pepper, tt.signing, false) + err := validateRuntimeConfig(true, tt.database, tt.pepper, tt.signing, "", false) if err == nil || !strings.Contains(err.Error(), tt.wantSubstr) { t.Fatalf("err=%v, want %q", err, tt.wantSubstr) } @@ -47,11 +47,32 @@ func TestValidateRuntimeConfigRejectsProductionDefaults(t *testing.T) { } func TestValidateRuntimeConfigAllowsProductionAWSKMSMode(t *testing.T) { - if err := validateRuntimeConfig(true, "postgres://example", "not-default", "aws-kms", false); err != nil { + if err := validateRuntimeConfig(true, "postgres://example", "not-default", "aws-kms", "", false); err != nil { t.Fatalf("aws-kms production mode should be accepted: %v", err) } } +func TestValidateRuntimeConfigAllowsGatewayBackedKMSModesWithExecutor(t *testing.T) { + for _, mode := range []string{"gcp-kms", "azure-key-vault", "pkcs11-hsm"} { + t.Run(mode, func(t *testing.T) { + if err := validateRuntimeConfig(true, "postgres://example", "not-default", mode, "https://signer.example.test/sign", false); err != nil { + t.Fatalf("%s production gateway mode should be accepted: %v", mode, err) + } + }) + } +} + +func TestValidateRuntimeConfigRejectsGatewayBackedKMSModesWithoutExecutor(t *testing.T) { + for _, mode := range []string{"gcp-kms", "azure-key-vault", "pkcs11-hsm"} { + t.Run(mode, func(t *testing.T) { + err := validateRuntimeConfig(true, "postgres://example", "not-default", mode, "", false) + if err == nil || !strings.Contains(err.Error(), "EVYDENCE_SIGNING_EXECUTOR_URL") { + t.Fatalf("%s missing gateway err=%v", mode, err) + } + }) + } +} + func TestValidateAPIWriterModeAllowsProductionSingleWriter(t *testing.T) { if err := validateAPIWriterMode(true, "single", "1"); err != nil { t.Fatalf("single writer production mode should be accepted: %v", err) @@ -185,6 +206,26 @@ func TestOpenSigningExecutorRequiresHTTPSUnlessLocalOverride(t *testing.T) { } } +func TestOpenSigningExecutorUsesGatewayForNonAWSKMSModes(t *testing.T) { + t.Setenv("EVYDENCE_SIGNING_KEY_MODE", "gcp-kms") + t.Setenv("EVYDENCE_SIGNING_EXECUTOR_URL", "http://127.0.0.1/sign") + t.Setenv("EVYDENCE_SIGNING_EXECUTOR_ALLOW_INSECURE_LOCALHOST", "true") + signer, err := openSigningExecutor() + if err != nil { + t.Fatalf("gcp-kms gateway signer should be accepted: %v", err) + } + if signer == nil { + t.Fatal("expected signer") + } +} + +func TestOpenSigningExecutorRequiresGatewayForNonAWSKMSModes(t *testing.T) { + t.Setenv("EVYDENCE_SIGNING_KEY_MODE", "azure-key-vault") + if _, err := openSigningExecutor(); err == nil || !strings.Contains(err.Error(), "EVYDENCE_SIGNING_EXECUTOR_URL") { + t.Fatalf("missing gateway err=%v", err) + } +} + func TestOpenSigningExecutorRejectsIncompleteAWSKMSConfig(t *testing.T) { t.Setenv("EVYDENCE_SIGNING_KEY_MODE", "aws-kms") t.Setenv("EVYDENCE_AWS_REGION", "eu-north-1") diff --git a/docs/architecture.md b/docs/architecture.md index acc69df..4c558a1 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -52,6 +52,6 @@ Air-gapped import-bundle workflows preserve the same tenant-scoped import path a ## Limitations -The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, an AWS KMS signing executor, OIDC discovery refresh, optional live OIDC UserInfo validation, SSO credential exchange with session-scoped OIDC group-role mapping, public-transparency proof fetching, and optional worker-owned parser side effects are implemented, but non-AWS cloud KMS/HSM SDK adapters, live Sigstore verification, provider-specific management API validation, and external group synchronization remain deployment hardening work. Hand-tuned per-resource repository implementations remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, local plaintext signing-key mode, and bootstrap secret printing. +The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, explicit gateway-backed `gcp-kms`, `azure-key-vault`, and `pkcs11-hsm` signing modes, an AWS KMS signing executor, OIDC discovery refresh, optional live OIDC UserInfo validation, SSO credential exchange with session-scoped OIDC group-role mapping, public-transparency proof fetching, and optional worker-owned parser side effects are implemented, but direct non-AWS cloud KMS/HSM SDK adapters, live Sigstore verification, provider-specific management API validation, and external group synchronization remain deployment hardening work. Hand-tuned per-resource repository implementations remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, unsupported API writer modes or replica counts above one, local plaintext signing-key mode, and bootstrap secret printing. Evydence does not prove provider truth, scanner authority, runtime security, legal compliance, or release security by itself. diff --git a/docs/kubernetes.md b/docs/kubernetes.md index 28da940..6f463a3 100644 --- a/docs/kubernetes.md +++ b/docs/kubernetes.md @@ -10,7 +10,9 @@ The Helm chart lives at `deploy/helm/evydence`. It deploys the API, worker, serv - External PostgreSQL and S3/MinIO-compatible object storage. - A pre-created object-store bucket. - A Kubernetes secret containing at least `EVYDENCE_DATABASE_URL` and `EVYDENCE_API_KEY_PEPPER`. -- A signing setup compatible with `EVYDENCE_SIGNING_KEY_MODE=external`. +- A signing setup compatible with `EVYDENCE_SIGNING_KEY_MODE=external`, + `aws-kms`, or one of the gateway-backed provider profiles documented in the + configuration reference. The chart does not create databases, buckets, KMS keys, or secrets. @@ -51,7 +53,7 @@ Relevant chart values are defined in `deploy/helm/evydence/values.yaml`: | `env.apiKeyPepperSecretKey` | Secret key for `EVYDENCE_API_KEY_PEPPER`. | | `env.objectStore` | `s3` or `minio` for cluster deployments. | | `env.s3Endpoint`, `env.s3Bucket`, `env.s3Region`, `env.s3UseSSL` | Object-store configuration. | -| `env.signingKeyMode` | Should be `external` for production. | +| `env.signingKeyMode` | Production signing mode. Use `external`, `aws-kms`, or a gateway-backed provider profile. | | `ingress.*` | Optional ingress host and TLS secret. | ## Verify diff --git a/docs/production-hardening.md b/docs/production-hardening.md index 786cda3..4d2a400 100644 --- a/docs/production-hardening.md +++ b/docs/production-hardening.md @@ -9,7 +9,8 @@ Before labeling a deployment production, verify: - `ENV=production` is set. - `EVYDENCE_DATABASE_URL` points to external PostgreSQL. - `EVYDENCE_API_KEY_PEPPER` is a non-default random value. -- `EVYDENCE_SIGNING_KEY_MODE=external` or `EVYDENCE_SIGNING_KEY_MODE=aws-kms` is set. +- `EVYDENCE_SIGNING_KEY_MODE=external`, `aws-kms`, or a gateway-backed + provider profile such as `gcp-kms`, `azure-key-vault`, or `pkcs11-hsm` is set. - `EVYDENCE_PRINT_BOOTSTRAP_SECRET` is unset or false. - Only one API writer replica is deployed; production API startup also enforces this with a PostgreSQL advisory writer lease. @@ -31,7 +32,7 @@ These checks are enforced by API startup. See [Configuration](reference/configur - Customer portal access tokens are short-lived, scoped to one package, and handled as bearer secrets. - Generated customer packages use explicit redaction profiles and expiry. - Collector releases are pinned and have signature, SBOM, and vulnerability scan evidence when available. -- Signing operations use either a tenant-controlled HTTPS signing gateway or the AWS KMS executor; raw evidence payload bytes are not sent to either executor by Evydence. +- Signing operations use either a tenant-controlled HTTPS signing gateway, an explicit gateway-backed provider profile, or the AWS KMS executor; raw evidence payload bytes are not sent to any signing executor by Evydence. ## Backup And Restore Checklist diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 0fdd740..e36a540 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -50,7 +50,7 @@ The example secrets are placeholders. Replace them before using shared or produc | `EVYDENCE_WORKER_MAX_PAYLOAD_BYTES` | No | `20971520` | Maximum raw object payload size replayed by a worker job. | | `EVYDENCE_OIDC_USERINFO_TIMEOUT_SECONDS` | No | `10` | Timeout for optional live OIDC UserInfo validation when `POST /v1/provider-verifications` includes `access_token`. | | `EVYDENCE_OIDC_USERINFO_ALLOW_INSECURE_LOCALHOST` | Local only | `false` | Allows HTTP OIDC issuer/UserInfo endpoints only for localhost tests. Do not use for production. | -| `EVYDENCE_SIGNING_KEY_MODE` | Production yes | `external` or `aws-kms` for production | Production rejects local plaintext signing-key mode. `external` uses the optional HTTPS signing gateway; `aws-kms` uses the built-in AWS KMS executor. | +| `EVYDENCE_SIGNING_KEY_MODE` | Production yes | `external`, `aws-kms`, `gcp-kms`, `azure-key-vault`, or `pkcs11-hsm` for production | Production rejects local plaintext signing-key mode. `aws-kms` uses the built-in AWS KMS executor. `gcp-kms`, `azure-key-vault`, and `pkcs11-hsm` are explicit HTTPS signing-gateway profiles and require `EVYDENCE_SIGNING_EXECUTOR_URL`. | | `EVYDENCE_SIGNING_EXECUTOR_URL` | No | unset | Optional HTTPS signing gateway used by `POST /v1/signing-operations` when `external_signature` is omitted. The API sends subject metadata and `payload_hash`, not raw payload bytes. | | `EVYDENCE_SIGNING_EXECUTOR_TOKEN` | Signing gateway | unset | Optional bearer token for the signing gateway. Store outside source control and logs. | | `EVYDENCE_SIGNING_EXECUTOR_TIMEOUT_SECONDS` | No | `10` | Timeout for signing gateway requests. | @@ -68,7 +68,9 @@ When `ENV=production`, the API refuses to start unless: - `EVYDENCE_DATABASE_URL` is set. - `EVYDENCE_API_KEY_PEPPER` is non-empty and not the local default. -- `EVYDENCE_SIGNING_KEY_MODE=external` or `EVYDENCE_SIGNING_KEY_MODE=aws-kms`. +- `EVYDENCE_SIGNING_KEY_MODE` is `external`, `aws-kms`, `gcp-kms`, + `azure-key-vault`, or `pkcs11-hsm`. The non-AWS provider modes require + `EVYDENCE_SIGNING_EXECUTOR_URL`. - `EVYDENCE_PRINT_BOOTSTRAP_SECRET` is not `true`. - `EVYDENCE_POSTGRES_LOAD_MODE`, when set, is `relational_only`. - `EVYDENCE_API_WRITER_MODE`, when set, is `single` or `single-writer`. @@ -118,6 +120,12 @@ gateway returns a signature, optional provider key id, and optional algorithm. Evydence records the signature receipt and verification checks; it does not store production private key material or send raw evidence payload bytes. +`EVYDENCE_SIGNING_KEY_MODE=gcp-kms`, `azure-key-vault`, or `pkcs11-hsm` makes +that gateway requirement explicit for deployments that keep non-AWS KMS/HSM +custody behind a tenant-controlled signing service. These modes are not direct +cloud-provider SDK adapters; operators remain responsible for provider +credentials, IAM, key lifecycle, gateway operation, and custody review. + When `EVYDENCE_SIGNING_KEY_MODE=aws-kms`, Evydence uses the AWS KMS `Sign` operation against `EVYDENCE_AWS_KMS_KEY_ID`. The executor signs the decoded SHA-256 digest with KMS `MessageType=DIGEST`; it does not send raw evidence diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 889ad20..9211e81 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -61,8 +61,9 @@ Known hardening work remains: - OpenAPI precision is enforced across the registered public API. The generated matrix remains the source of truth for operation ids, scopes, idempotency, parameters, and request/response schemas; -- production signing can use the HTTPS signing gateway executor or the built-in - AWS KMS signing executor, but non-AWS cloud KMS/HSM SDK adapters, +- production signing can use the HTTPS signing gateway executor, explicit + gateway-backed `gcp-kms`, `azure-key-vault`, and `pkcs11-hsm` modes, or the + built-in AWS KMS signing executor, but direct non-AWS cloud KMS/HSM SDK adapters, provider-specific management API validation/group synchronization, and broad object-lock enforcement proof beyond bucket plus sample-object retention/legal-hold checks remain provider- and deployment-dependent @@ -205,10 +206,11 @@ implemented capabilities: - Keep OpenAPI precision at zero broad operations as routes are added or changed, and expand generated SDK coverage from the committed contract. - Add direct cloud KMS/HSM SDK adapters where required beyond AWS KMS. The - current HTTPS signing gateway executor covers deployments that put KMS/HSM - custody behind a tenant-controlled signing service and do not send raw - payload bytes; the AWS KMS executor signs stored SHA-256 payload hashes with - KMS `MessageType=DIGEST`. + current HTTPS signing gateway executor and explicit `gcp-kms`, + `azure-key-vault`, and `pkcs11-hsm` gateway-backed modes cover deployments + that put KMS/HSM custody behind a tenant-controlled signing service and do + not send raw payload bytes; the AWS KMS executor signs stored SHA-256 payload + hashes with KMS `MessageType=DIGEST`. - Complete provider-specific management API validation and external group synchronization where those profiles are enabled. OIDC discovery/JWKS refresh is implemented for public trust-material updates, manual JWKS and SAML diff --git a/docs/reference/release-notes-template.md b/docs/reference/release-notes-template.md index f9a7339..2e9ab60 100644 --- a/docs/reference/release-notes-template.md +++ b/docs/reference/release-notes-template.md @@ -31,9 +31,9 @@ acceptance. - Use PostgreSQL for durable runtime state. - Use S3/MinIO-compatible object storage or the documented filesystem mode for local evaluation only. -- Set `ENV=production`, a non-default `EVYDENCE_API_KEY_PEPPER`, and - `EVYDENCE_SIGNING_KEY_MODE=external` or `EVYDENCE_SIGNING_KEY_MODE=aws-kms` - for production-profile startup. +- Set `ENV=production`, a non-default `EVYDENCE_API_KEY_PEPPER`, and a + production signing mode such as `external`, `aws-kms`, or an explicit + gateway-backed provider profile for production-profile startup. - Apply all committed migrations before starting API or worker processes. - For Kubernetes, set an explicit image tag or digest and keep API replicas at `1` until HA/multi-writer support is reviewed. @@ -44,8 +44,9 @@ acceptance. PostgreSQL writes cover the highest-risk runtime mutations, but not every resource family. - HA/multi-writer API operation is not supported in this profile. -- The AWS KMS signing executor is included; non-AWS cloud KMS/HSM SDK adapters - are not included. +- The AWS KMS signing executor and explicit gateway-backed non-AWS KMS/HSM + profiles are included; direct non-AWS cloud KMS/HSM SDK adapters are not + included. - OIDC UserInfo validation is available when a caller supplies an access token; provider-specific management API validation and external group synchronization remain deployment-dependent. diff --git a/docs/reference/release-notes-v0.1.0-rc.1.md b/docs/reference/release-notes-v0.1.0-rc.1.md index 379d458..5c0d12e 100644 --- a/docs/reference/release-notes-v0.1.0-rc.1.md +++ b/docs/reference/release-notes-v0.1.0-rc.1.md @@ -31,9 +31,9 @@ acceptance. - Use PostgreSQL for durable runtime state. - Use S3/MinIO-compatible object storage or the documented filesystem mode for local evaluation only. -- Set `ENV=production`, a non-default `EVYDENCE_API_KEY_PEPPER`, and - `EVYDENCE_SIGNING_KEY_MODE=external` or `EVYDENCE_SIGNING_KEY_MODE=aws-kms` - for production-profile startup. +- Set `ENV=production`, a non-default `EVYDENCE_API_KEY_PEPPER`, and a + production signing mode such as `external`, `aws-kms`, or an explicit + gateway-backed provider profile for production-profile startup. - Apply all committed migrations before starting API or worker processes. - For Kubernetes, set an explicit image tag or digest and keep API replicas at `1` until HA/multi-writer support is reviewed. @@ -44,8 +44,9 @@ acceptance. PostgreSQL writes cover the highest-risk runtime mutations, but not every resource family. - HA/multi-writer API operation is not supported in this profile. -- The AWS KMS signing executor is included; non-AWS cloud KMS/HSM SDK adapters - are not included. +- The AWS KMS signing executor and explicit gateway-backed non-AWS KMS/HSM + profiles are included; direct non-AWS cloud KMS/HSM SDK adapters are not + included. - OIDC UserInfo validation is available when a caller supplies an access token; provider-specific management API validation and external group synchronization remain deployment-dependent. From c68aa38f20f6c6aebc655b8952f3bc5e44fdea21 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 11:11:21 +0300 Subject: [PATCH 140/287] feat: add provider validation gateway --- README.md | 4 +- cmd/evydence-api/main.go | 30 ++- cmd/evydence-api/main_test.go | 19 ++ docs/api.md | 2 +- docs/architecture.md | 2 +- docs/explanation/trust-model.md | 2 +- docs/operations.md | 2 +- docs/reference/configuration.md | 19 ++ docs/reference/production-readiness.md | 28 +-- .../identity/httpvalidator/httpvalidator.go | 216 ++++++++++++++++++ .../httpvalidator/httpvalidator_test.go | 126 ++++++++++ 11 files changed, 427 insertions(+), 23 deletions(-) create mode 100644 internal/adapters/identity/httpvalidator/httpvalidator.go create mode 100644 internal/adapters/identity/httpvalidator/httpvalidator_test.go diff --git a/README.md b/README.md index 2ae2159..24996f3 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ This repository contains a Go implementation under module `github.com/aatuh/evyd - AGPL license, commercial licensing, governance, contribution, security, support, trademark, release-evidence, and changelog metadata. -Implemented-but-partial areas are documented explicitly: signing-provider operation receipts can use an HTTPS signing gateway, explicit gateway-backed `gcp-kms`, `azure-key-vault`, and `pkcs11-hsm` modes, or the built-in AWS KMS executor, but direct non-AWS cloud KMS/HSM SDK adapters and deployment-specific custody review remain operator work; SSO credential exchange uses configured local OIDC/SAML trust material and session-scoped OIDC group-role mappings, and provider verification can optionally call OIDC UserInfo with a supplied access token, but this does not replace provider-specific management API validation or external group synchronization; and public transparency records can verify operator-supplied or fetched inclusion proof material without replacing provider-specific trust review. +Implemented-but-partial areas are documented explicitly: signing-provider operation receipts can use an HTTPS signing gateway, explicit gateway-backed `gcp-kms`, `azure-key-vault`, and `pkcs11-hsm` modes, or the built-in AWS KMS executor, but direct non-AWS cloud KMS/HSM SDK adapters and deployment-specific custody review remain operator work; SSO credential exchange uses configured local OIDC/SAML trust material and session-scoped OIDC group-role mappings, and provider verification can optionally call OIDC UserInfo or an operator-controlled provider validation gateway with a supplied access token, but this does not replace direct provider-specific management API clients or external group synchronization; and public transparency records can verify operator-supplied or fetched inclusion proof material without replacing provider-specific trust review. ## License, Security, Support, And Governance @@ -109,4 +109,4 @@ make postgres-integration-test `make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. -`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required release-candidate evidence, but it does not by itself close the remaining service decomposition, direct non-AWS KMS/HSM SDK providers, provider-specific management API/group synchronization, broader object-lock enforcement beyond configured bucket/sample-object checks, HA, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. Critical runtime mutations for tenants, credential hashes, idempotency, audit-chain entries, release bundles, signatures, verification results, vulnerability decisions, and outbox jobs use focused PostgreSQL write paths when available. Release-ledger and evidence-core mutations for products, projects, releases, artifacts, evidence items, evidence lifecycle events, SBOMs, vulnerability scans, OpenAPI contracts, VEX documents, audit-chain entries, and parser outbox jobs also use focused PostgreSQL write paths when available. Remaining aggregate persistence calls use PostgreSQL relational synchronization without writing the compatibility snapshot when that store is configured. Current self-hosted production guidance still uses a single API writer replica; production API startup rejects unsupported writer modes and declared replica counts above one, then enforces that stance with a PostgreSQL advisory writer lease. Worker replicas may scale through PostgreSQL outbox row locking. +`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required release-candidate evidence, but it does not by itself close the remaining service decomposition, direct non-AWS KMS/HSM SDK providers, direct provider-specific management API/group synchronization, broader object-lock enforcement beyond configured bucket/sample-object checks, HA, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. Critical runtime mutations for tenants, credential hashes, idempotency, audit-chain entries, release bundles, signatures, verification results, vulnerability decisions, and outbox jobs use focused PostgreSQL write paths when available. Release-ledger and evidence-core mutations for products, projects, releases, artifacts, evidence items, evidence lifecycle events, SBOMs, vulnerability scans, OpenAPI contracts, VEX documents, audit-chain entries, and parser outbox jobs also use focused PostgreSQL write paths when available. Remaining aggregate persistence calls use PostgreSQL relational synchronization without writing the compatibility snapshot when that store is configured. Current self-hosted production guidance still uses a single API writer replica; production API startup rejects unsupported writer modes and declared replica counts above one, then enforces that stance with a PostgreSQL advisory writer lease. Worker replicas may scale through PostgreSQL outbox row locking. diff --git a/cmd/evydence-api/main.go b/cmd/evydence-api/main.go index ebbe4e2..fa26664 100644 --- a/cmd/evydence-api/main.go +++ b/cmd/evydence-api/main.go @@ -14,6 +14,7 @@ import ( "time" "github.com/aatuh/evydence/internal/adapters/httpapi" + "github.com/aatuh/evydence/internal/adapters/identity/httpvalidator" "github.com/aatuh/evydence/internal/adapters/identity/oidcdiscovery" "github.com/aatuh/evydence/internal/adapters/identity/oidcuserinfo" "github.com/aatuh/evydence/internal/adapters/objectstore/filesystem" @@ -54,10 +55,11 @@ func run() error { AllowInsecureForLocalhost: strings.EqualFold(os.Getenv("EVYDENCE_OIDC_DISCOVERY_ALLOW_INSECURE_LOCALHOST"), "true"), Timeout: time.Duration(intEnv("EVYDENCE_OIDC_DISCOVERY_TIMEOUT_SECONDS", 10)) * time.Second, }) - cfg.ProviderAPI = oidcuserinfo.New(oidcuserinfo.Config{ - AllowInsecureForLocalhost: strings.EqualFold(os.Getenv("EVYDENCE_OIDC_USERINFO_ALLOW_INSECURE_LOCALHOST"), "true"), - Timeout: time.Duration(intEnv("EVYDENCE_OIDC_USERINFO_TIMEOUT_SECONDS", 10)) * time.Second, - }) + providerValidator, err := openProviderIdentityValidator() + if err != nil { + return err + } + cfg.ProviderAPI = providerValidator cfg.Transparency = httpfetcher.New(httpfetcher.Config{ AllowInsecureForLocalhost: strings.EqualFold(os.Getenv("EVYDENCE_TRANSPARENCY_FETCH_ALLOW_INSECURE_LOCALHOST"), "true"), Timeout: time.Duration(intEnv("EVYDENCE_TRANSPARENCY_FETCH_TIMEOUT_SECONDS", 10)) * time.Second, @@ -192,6 +194,26 @@ func openSigningExecutor() (app.SigningExecutor, error) { return executor, nil } +func openProviderIdentityValidator() (app.ProviderIdentityValidator, error) { + endpoint := strings.TrimSpace(os.Getenv("EVYDENCE_PROVIDER_VALIDATION_GATEWAY_URL")) + if endpoint != "" { + validator, err := httpvalidator.New(httpvalidator.Config{ + Endpoint: endpoint, + BearerToken: os.Getenv("EVYDENCE_PROVIDER_VALIDATION_GATEWAY_TOKEN"), + AllowInsecureForLocalhost: strings.EqualFold(os.Getenv("EVYDENCE_PROVIDER_VALIDATION_GATEWAY_ALLOW_INSECURE_LOCALHOST"), "true"), + Timeout: time.Duration(intEnv("EVYDENCE_PROVIDER_VALIDATION_GATEWAY_TIMEOUT_SECONDS", 10)) * time.Second, + }) + if err != nil { + return nil, fmt.Errorf("configure provider validation gateway: %w", err) + } + return validator, nil + } + return oidcuserinfo.New(oidcuserinfo.Config{ + AllowInsecureForLocalhost: strings.EqualFold(os.Getenv("EVYDENCE_OIDC_USERINFO_ALLOW_INSECURE_LOCALHOST"), "true"), + Timeout: time.Duration(intEnv("EVYDENCE_OIDC_USERINFO_TIMEOUT_SECONDS", 10)) * time.Second, + }), nil +} + func validateRuntimeConfig(production bool, databaseURL, pepper, signingKeyMode, signingExecutorURL string, printBootstrapSecret bool) error { if !production { return nil diff --git a/cmd/evydence-api/main_test.go b/cmd/evydence-api/main_test.go index da99431..ca06c32 100644 --- a/cmd/evydence-api/main_test.go +++ b/cmd/evydence-api/main_test.go @@ -233,3 +233,22 @@ func TestOpenSigningExecutorRejectsIncompleteAWSKMSConfig(t *testing.T) { t.Fatal("expected missing AWS KMS key id to be rejected") } } + +func TestOpenProviderIdentityValidatorUsesGatewayWhenConfigured(t *testing.T) { + t.Setenv("EVYDENCE_PROVIDER_VALIDATION_GATEWAY_URL", "http://127.0.0.1/provider") + t.Setenv("EVYDENCE_PROVIDER_VALIDATION_GATEWAY_ALLOW_INSECURE_LOCALHOST", "true") + validator, err := openProviderIdentityValidator() + if err != nil { + t.Fatalf("provider validation gateway should be accepted: %v", err) + } + if validator == nil { + t.Fatal("expected provider validator") + } +} + +func TestOpenProviderIdentityValidatorRequiresHTTPSForRemoteGateway(t *testing.T) { + t.Setenv("EVYDENCE_PROVIDER_VALIDATION_GATEWAY_URL", "http://provider.example.test/validate") + if _, err := openProviderIdentityValidator(); err == nil || !strings.Contains(err.Error(), "https") { + t.Fatalf("remote http provider validator err=%v, want https rejection", err) + } +} diff --git a/docs/api.md b/docs/api.md index 9a69dc2..6fc219f 100644 --- a/docs/api.md +++ b/docs/api.md @@ -251,7 +251,7 @@ Important scope boundaries: | `POST` | `/v1/api-keys` | Create one-time API key secret. | | `GET` | `/v1/api-keys` | List keys without secret hashes. | -Current SSO endpoints model admin-managed provider, identity-link, trust-material, and session records plus API-first session logout. OIDC provider records can include public JWKS material, and SAML provider records can include PEM-encoded assertion signing certificates; both can be rotated through `POST /v1/sso/providers/{id}/trust-material`. OIDC public JWKS can also be refreshed from the configured issuer with `POST /v1/sso/providers/{id}/discover-oidc`. `POST /v1/provider-verifications` can verify a supplied OIDC ID token or SAML assertion locally for issuer, audience, subject, time bounds, and signature. When an OIDC `access_token` is supplied, the same endpoint can call the provider's discovered UserInfo endpoint, verify the returned `sub`, and record any configured group-claim mapping checks without storing the access token. `POST /v1/sso/session-exchanges` uses local token/assertion verification and a verified identity link to issue a one-time SSO bearer secret and an HttpOnly cookie for browser clients. OIDC group claim values can map to session-scoped roles through the provider `groups_claim` and `role_mapping`; no permanent role binding is created from token claims. External group synchronization into permanent role bindings is not implemented in this slice. +Current SSO endpoints model admin-managed provider, identity-link, trust-material, and session records plus API-first session logout. OIDC provider records can include public JWKS material, and SAML provider records can include PEM-encoded assertion signing certificates; both can be rotated through `POST /v1/sso/providers/{id}/trust-material`. OIDC public JWKS can also be refreshed from the configured issuer with `POST /v1/sso/providers/{id}/discover-oidc`. `POST /v1/provider-verifications` can verify a supplied OIDC ID token or SAML assertion locally for issuer, audience, subject, time bounds, and signature. When an OIDC `access_token` is supplied, the same endpoint can call either the provider's discovered UserInfo endpoint or a configured operator-controlled provider validation gateway, verify the returned subject, and record any configured group-claim mapping checks without storing the access token. `POST /v1/sso/session-exchanges` uses local token/assertion verification and a verified identity link to issue a one-time SSO bearer secret and an HttpOnly cookie for browser clients. OIDC group claim values can map to session-scoped roles through the provider `groups_claim` and `role_mapping`; no permanent role binding is created from token claims. External group synchronization into permanent role bindings is not implemented in this slice. ### Products, Releases, Evidence, And Risk diff --git a/docs/architecture.md b/docs/architecture.md index 4c558a1..a13c7a9 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -52,6 +52,6 @@ Air-gapped import-bundle workflows preserve the same tenant-scoped import path a ## Limitations -The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, explicit gateway-backed `gcp-kms`, `azure-key-vault`, and `pkcs11-hsm` signing modes, an AWS KMS signing executor, OIDC discovery refresh, optional live OIDC UserInfo validation, SSO credential exchange with session-scoped OIDC group-role mapping, public-transparency proof fetching, and optional worker-owned parser side effects are implemented, but direct non-AWS cloud KMS/HSM SDK adapters, live Sigstore verification, provider-specific management API validation, and external group synchronization remain deployment hardening work. Hand-tuned per-resource repository implementations remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, unsupported API writer modes or replica counts above one, local plaintext signing-key mode, and bootstrap secret printing. +The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, explicit gateway-backed `gcp-kms`, `azure-key-vault`, and `pkcs11-hsm` signing modes, an AWS KMS signing executor, OIDC discovery refresh, optional live OIDC UserInfo validation, an optional provider validation gateway, SSO credential exchange with session-scoped OIDC group-role mapping, public-transparency proof fetching, and optional worker-owned parser side effects are implemented, but direct non-AWS cloud KMS/HSM SDK adapters, direct provider-specific management API clients, and external group synchronization remain deployment hardening work. Hand-tuned per-resource repository implementations remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, unsupported API writer modes or replica counts above one, local plaintext signing-key mode, and bootstrap secret printing. Evydence does not prove provider truth, scanner authority, runtime security, legal compliance, or release security by itself. diff --git a/docs/explanation/trust-model.md b/docs/explanation/trust-model.md index 1fa1e76..044d32b 100644 --- a/docs/explanation/trust-model.md +++ b/docs/explanation/trust-model.md @@ -4,6 +4,6 @@ Evydence records technical evidence, hashes payloads, links evidence to products Evydence trusts tenant-scoped API keys and SSO session tokens after server-side hash verification. Instance-wide diagnostics require the explicit `instance:admin` scope; tenant `admin` and wildcard tenant keys remain tenant-scoped unless that scope is also present. Collector identity is derived from the collector API key binding. Customer portal access uses expiring package tokens and exposes scoped package manifests, not raw tenant evidence. Repeated failed portal attempts revoke the access record without storing the supplied token. -Provider metadata such as GitHub Actions, GitLab, DSSE, VEX, SBOM, OpenAPI, scanner payloads, and SSO provider records is treated as uploaded evidence unless a configured trust root or verification path proves more. Current SSO support records provider metadata, identity links, expiring sessions, local OIDC token verification, local SAML assertion verification against tenant-configured trust material, OIDC discovery/JWKS refresh, and optional OIDC UserInfo validation when a caller supplies an access token. It does not perform provider-specific management API validation, browser login callbacks, or external group synchronization. Structural parsing is not the same as provider truth or cryptographic trust. +Provider metadata such as GitHub Actions, GitLab, DSSE, VEX, SBOM, OpenAPI, scanner payloads, and SSO provider records is treated as uploaded evidence unless a configured trust root or verification path proves more. Current SSO support records provider metadata, identity links, expiring sessions, local OIDC token verification, local SAML assertion verification against tenant-configured trust material, OIDC discovery/JWKS refresh, optional OIDC UserInfo validation when a caller supplies an access token, and an optional operator-controlled provider validation gateway. It does not include direct provider-specific management API clients, browser login callbacks, or external group synchronization. Structural parsing is not the same as provider truth or cryptographic trust. Reports are readiness and evidence-organization outputs. They do not state legal compliance, certification, complete SBOM coverage, authoritative vulnerability results, or secure releases. diff --git a/docs/operations.md b/docs/operations.md index 5a7698c..56df3cd 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -30,7 +30,7 @@ This operator index points to the canonical references for running Evydence. Kee - API keys, collector keys, SSO session tokens, and customer portal access tokens are bearer secrets. Do not place them in logs, documentation, long-lived build output, or customer packages. - Customer portal access tokens are returned once by `POST /v1/customer-portal/access`, expire, and are stored as hashes. Deployments should still use reverse-proxy or API-gateway throttling for the unauthenticated portal endpoint. -- Human SSO session records are admin-managed, authenticated SSO sessions can revoke themselves through API-first logout, and SSO credential exchange can set an HttpOnly session cookie after locally verifying an OIDC ID token or SAML assertion against tenant-configured trust material. OIDC group claim values can be captured on the session and mapped to configured roles without creating permanent role bindings from token claims. Current endpoints can refresh OIDC public JWKS from discovery metadata, but they do not implement live provider API validation or external group synchronization. +- Human SSO session records are admin-managed, authenticated SSO sessions can revoke themselves through API-first logout, and SSO credential exchange can set an HttpOnly session cookie after locally verifying an OIDC ID token or SAML assertion against tenant-configured trust material. OIDC group claim values can be captured on the session and mapped to configured roles without creating permanent role bindings from token claims. Current endpoints can refresh OIDC public JWKS from discovery metadata and can call a configured OIDC UserInfo endpoint or provider validation gateway for verification checks, but they do not implement direct provider-specific management API clients or external group synchronization. - Object-retention APIs record and verify retention intent for tenant-prefixed object paths. S3/MinIO verification can check bucket defaults plus sample-object retention and legal hold where configured. Enforcing WORM or object-lock settings remains the responsibility of the configured object store and deployment policy. Evydence operations support evidence organization, review, and tamper-evident records. Operational checks do not replace external audit review, secret management, backup testing, or provider verification. diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index e36a540..1352b54 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -50,6 +50,10 @@ The example secrets are placeholders. Replace them before using shared or produc | `EVYDENCE_WORKER_MAX_PAYLOAD_BYTES` | No | `20971520` | Maximum raw object payload size replayed by a worker job. | | `EVYDENCE_OIDC_USERINFO_TIMEOUT_SECONDS` | No | `10` | Timeout for optional live OIDC UserInfo validation when `POST /v1/provider-verifications` includes `access_token`. | | `EVYDENCE_OIDC_USERINFO_ALLOW_INSECURE_LOCALHOST` | Local only | `false` | Allows HTTP OIDC issuer/UserInfo endpoints only for localhost tests. Do not use for production. | +| `EVYDENCE_PROVIDER_VALIDATION_GATEWAY_URL` | No | unset | Optional HTTPS operator-controlled provider validation gateway. When set, provider verification uses this gateway instead of direct OIDC UserInfo calls. | +| `EVYDENCE_PROVIDER_VALIDATION_GATEWAY_TOKEN` | Gateway | unset | Optional bearer token for the provider validation gateway. Store outside source control and logs. | +| `EVYDENCE_PROVIDER_VALIDATION_GATEWAY_TIMEOUT_SECONDS` | No | `10` | Timeout for provider validation gateway requests. | +| `EVYDENCE_PROVIDER_VALIDATION_GATEWAY_ALLOW_INSECURE_LOCALHOST` | Local only | `false` | Allows an HTTP localhost gateway for tests. Do not use for production. | | `EVYDENCE_SIGNING_KEY_MODE` | Production yes | `external`, `aws-kms`, `gcp-kms`, `azure-key-vault`, or `pkcs11-hsm` for production | Production rejects local plaintext signing-key mode. `aws-kms` uses the built-in AWS KMS executor. `gcp-kms`, `azure-key-vault`, and `pkcs11-hsm` are explicit HTTPS signing-gateway profiles and require `EVYDENCE_SIGNING_EXECUTOR_URL`. | | `EVYDENCE_SIGNING_EXECUTOR_URL` | No | unset | Optional HTTPS signing gateway used by `POST /v1/signing-operations` when `external_signature` is omitted. The API sends subject metadata and `payload_hash`, not raw payload bytes. | | `EVYDENCE_SIGNING_EXECUTOR_TOKEN` | Signing gateway | unset | Optional bearer token for the signing gateway. Store outside source control and logs. | @@ -133,6 +137,21 @@ payload bytes to AWS KMS. Operators remain responsible for AWS IAM policy, key lifecycle, CloudTrail review, regional availability, and external review of whether the selected key custody profile satisfies their deployment needs. +## Provider Validation Gateway + +When `EVYDENCE_PROVIDER_VALIDATION_GATEWAY_URL` is set, provider identity +verification can call an operator-controlled HTTPS gateway with tenant id, +provider id/type, issuer, subject, group-claim name, and a supplied access +token when the request includes one. The gateway returns non-secret checks, +groups, and limitations. Evydence stores the checks and normalized groups, not +the supplied token or raw provider response. + +This gateway is an integration point for GitHub, GitLab, IdP, directory, or +other provider-specific validation logic that depends on deployment-owned +credentials and policies. It does not make external group synchronization +automatic, does not create permanent role bindings, and does not prove provider +truth beyond the gateway response and recorded limitations. + ## Related Commands - Local operation: [Install and operate](../how-to/install-and-operate.md) diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 9211e81..320e1b4 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -64,17 +64,18 @@ Known hardening work remains: - production signing can use the HTTPS signing gateway executor, explicit gateway-backed `gcp-kms`, `azure-key-vault`, and `pkcs11-hsm` modes, or the built-in AWS KMS signing executor, but direct non-AWS cloud KMS/HSM SDK adapters, - provider-specific management API validation/group synchronization, and broad - object-lock enforcement proof beyond bucket plus sample-object retention/legal-hold - checks remain provider- and deployment-dependent + direct provider-specific management API clients/group synchronization, and + broad object-lock enforcement proof beyond bucket plus sample-object + retention/legal-hold checks remain provider- and deployment-dependent hardening areas. SSO credential exchange can issue bearer sessions and HttpOnly cookies after local OIDC/SAML verification against configured trust material, OIDC group claim values can map to session-scoped roles without creating permanent role bindings, provider verification can optionally call a - discovered OIDC UserInfo endpoint with a supplied access token, and public - transparency proof material can be fetched from a configured endpoint and - verified locally, but provider-specific trust semantics and availability - remain deployment responsibilities; + discovered OIDC UserInfo endpoint or an operator-controlled provider + validation gateway with a supplied access token, and public transparency + proof material can be fetched from a configured endpoint and verified + locally, but provider-specific trust semantics and availability remain + deployment responsibilities; - the broader production exit review remains incomplete. ## Production Profiles @@ -211,16 +212,17 @@ implemented capabilities: that put KMS/HSM custody behind a tenant-controlled signing service and do not send raw payload bytes; the AWS KMS executor signs stored SHA-256 payload hashes with KMS `MessageType=DIGEST`. -- Complete provider-specific management API validation and external group +- Complete direct provider-specific management API clients and external group synchronization where those profiles are enabled. OIDC discovery/JWKS refresh is implemented for public trust-material updates, manual JWKS and SAML signing-certificate rotation is implemented through the SSO provider trust-material endpoint, provider verification can optionally call OIDC - UserInfo with a supplied access token and record group-claim checks without - storing the token, SSO credential exchange can issue bearer sessions plus - HttpOnly cookies after local token or assertion verification, OIDC group - claim values can map to session-scoped roles, and API-first session logout - can revoke the current SSO bearer session. + UserInfo or an operator-controlled provider validation gateway with a + supplied access token and record group-claim checks without storing the token, + SSO credential exchange can issue bearer sessions plus HttpOnly cookies after + local token or assertion verification, OIDC group claim values can map to + session-scoped roles, and API-first session logout can revoke the current SSO + bearer session. - Extend object-lock/WORM verification beyond the current S3/MinIO bucket-level checks plus optional sample-object retention and legal-hold checks where deployments require broader provider policy evidence. diff --git a/internal/adapters/identity/httpvalidator/httpvalidator.go b/internal/adapters/identity/httpvalidator/httpvalidator.go new file mode 100644 index 0000000..003cbef --- /dev/null +++ b/internal/adapters/identity/httpvalidator/httpvalidator.go @@ -0,0 +1,216 @@ +package httpvalidator + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "io" + "net" + "net/http" + "net/url" + "strings" + "time" + + "github.com/aatuh/evydence/internal/app" + "github.com/aatuh/evydence/internal/domain" +) + +const ( + defaultTimeout = 10 * time.Second + maxBodyBytes = 1 << 20 +) + +type Config struct { + Endpoint string + BearerToken string + Timeout time.Duration + AllowInsecureForLocalhost bool + Client *http.Client +} + +type Validator struct { + endpoint string + bearerToken string + client *http.Client +} + +type validationRequest struct { + TenantID string `json:"tenant_id"` + ProviderID string `json:"provider_id"` + ProviderType string `json:"provider_type"` + Issuer string `json:"issuer,omitempty"` + Subject string `json:"subject"` + GroupsClaim string `json:"groups_claim,omitempty"` + AccessToken string `json:"access_token,omitempty"` + AccessTokenPresent bool `json:"access_token_present"` +} + +type validationResponse struct { + Subject string `json:"subject,omitempty"` + Groups []string `json:"groups,omitempty"` + Checks []domain.VerifyCheck `json:"checks,omitempty"` + Limitations []string `json:"limitations,omitempty"` +} + +func New(cfg Config) (*Validator, error) { + endpoint := strings.TrimSpace(cfg.Endpoint) + if endpoint == "" { + return nil, app.ErrValidation + } + parsed, err := url.Parse(endpoint) + if err != nil || parsed.Scheme == "" || parsed.Host == "" || parsed.User != nil { + return nil, app.ErrValidation + } + if parsed.Scheme != "https" && (!cfg.AllowInsecureForLocalhost || parsed.Scheme != "http" || !localhostHost(parsed.Hostname())) { + return nil, errors.New("provider validation gateway endpoint must use https") + } + timeout := cfg.Timeout + if timeout <= 0 { + timeout = defaultTimeout + } + client := cfg.Client + if client == nil { + client = &http.Client{Timeout: timeout} + } + return &Validator{endpoint: endpoint, bearerToken: strings.TrimSpace(cfg.BearerToken), client: client}, nil +} + +func (v *Validator) ValidateProviderIdentity(ctx context.Context, req app.ProviderIdentityValidationRequest) (app.ProviderIdentityValidationResult, error) { + if v == nil || v.client == nil { + return app.ProviderIdentityValidationResult{}, app.ErrValidation + } + subject := strings.TrimSpace(req.Subject) + if subject == "" { + return app.ProviderIdentityValidationResult{}, app.ErrValidation + } + accessToken := strings.TrimSpace(req.AccessToken) + if len(accessToken) > 16*1024 { + return app.ProviderIdentityValidationResult{}, app.ErrValidation + } + body, err := json.Marshal(validationRequest{ + TenantID: strings.TrimSpace(req.TenantID), + ProviderID: strings.TrimSpace(req.ProviderID), + ProviderType: strings.TrimSpace(req.ProviderType), + Issuer: strings.TrimSpace(req.Issuer), + Subject: subject, + GroupsClaim: strings.TrimSpace(req.GroupsClaim), + AccessToken: accessToken, + AccessTokenPresent: accessToken != "", + }) + if err != nil { + return app.ProviderIdentityValidationResult{}, app.ErrValidation + } + httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, v.endpoint, bytes.NewReader(body)) + if err != nil { + return app.ProviderIdentityValidationResult{}, app.ErrValidation + } + httpReq.Header.Set("Accept", "application/json") + httpReq.Header.Set("Content-Type", "application/json") + if v.bearerToken != "" { + httpReq.Header.Set("Authorization", "Bearer "+v.bearerToken) + } + resp, err := v.client.Do(httpReq) + if err != nil { + return app.ProviderIdentityValidationResult{}, errors.New("provider validation gateway request failed") + } + defer resp.Body.Close() + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + _, _ = io.Copy(io.Discard, io.LimitReader(resp.Body, 4096)) + return failed("provider_validation_gateway_status"), app.ErrVerificationFailed + } + var decoded validationResponse + decoder := json.NewDecoder(io.LimitReader(resp.Body, maxBodyBytes+1)) + decoder.DisallowUnknownFields() + if err := decoder.Decode(&decoded); err != nil { + return failed("provider_validation_gateway_response"), app.ErrVerificationFailed + } + if decoder.InputOffset() > maxBodyBytes { + return failed("provider_validation_gateway_response_size"), app.ErrVerificationFailed + } + decoded.Subject = strings.TrimSpace(decoded.Subject) + if decoded.Subject != "" && decoded.Subject != subject { + return app.ProviderIdentityValidationResult{ + Checks: append(safeChecks(decoded.Checks), domain.VerifyCheck{Name: "provider_validation_gateway_subject", Result: "failed"}), + Groups: safeGroups(decoded.Groups), + Limitations: safeLimitations(decoded.Limitations), + }, app.ErrVerificationFailed + } + checks := safeChecks(decoded.Checks) + checks = append([]domain.VerifyCheck{{Name: "provider_validation_gateway", Result: "passed"}}, checks...) + if decoded.Subject != "" { + checks = append(checks, domain.VerifyCheck{Name: "provider_validation_gateway_subject", Result: "passed"}) + } + limitations := safeLimitations(decoded.Limitations) + if len(limitations) == 0 { + limitations = []string{"Provider validation gateway returned non-secret identity checks; Evydence does not store supplied access tokens or synchronize provider groups permanently."} + } + return app.ProviderIdentityValidationResult{Checks: checks, Groups: safeGroups(decoded.Groups), Limitations: limitations}, nil +} + +func failed(check string) app.ProviderIdentityValidationResult { + return app.ProviderIdentityValidationResult{ + Checks: []domain.VerifyCheck{{Name: check, Result: "failed"}}, + Limitations: []string{"Provider validation gateway failed without storing supplied access tokens or raw provider responses."}, + } +} + +func safeChecks(in []domain.VerifyCheck) []domain.VerifyCheck { + out := make([]domain.VerifyCheck, 0, len(in)) + for _, check := range in { + name := strings.TrimSpace(check.Name) + result := strings.TrimSpace(check.Result) + detail := strings.TrimSpace(check.Detail) + if name == "" || result == "" || len(name) > 128 || len(result) > 32 || len(detail) > 1024 { + continue + } + out = append(out, domain.VerifyCheck{Name: name, Result: result, Detail: detail}) + if len(out) >= 32 { + break + } + } + return out +} + +func safeGroups(in []string) []string { + out := make([]string, 0, len(in)) + seen := map[string]struct{}{} + for _, group := range in { + group = strings.TrimSpace(group) + if group == "" || len(group) > 256 { + continue + } + if _, ok := seen[group]; ok { + continue + } + seen[group] = struct{}{} + out = append(out, group) + if len(out) >= 128 { + break + } + } + return out +} + +func safeLimitations(in []string) []string { + out := make([]string, 0, len(in)) + for _, limitation := range in { + limitation = strings.TrimSpace(limitation) + if limitation == "" || len(limitation) > 1024 { + continue + } + out = append(out, limitation) + if len(out) >= 16 { + break + } + } + return out +} + +func localhostHost(host string) bool { + if strings.EqualFold(host, "localhost") { + return true + } + ip := net.ParseIP(host) + return ip != nil && ip.IsLoopback() +} diff --git a/internal/adapters/identity/httpvalidator/httpvalidator_test.go b/internal/adapters/identity/httpvalidator/httpvalidator_test.go new file mode 100644 index 0000000..ca49a3e --- /dev/null +++ b/internal/adapters/identity/httpvalidator/httpvalidator_test.go @@ -0,0 +1,126 @@ +package httpvalidator + +import ( + "encoding/json" + "net/http" + "net/http/httptest" + "strings" + "testing" + + "github.com/aatuh/evydence/internal/app" + "github.com/aatuh/evydence/internal/domain" +) + +func TestValidateProviderIdentityPostsSafeRequestAndReturnsChecks(t *testing.T) { + var gotAuth string + var gotRequest validationRequest + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + t.Fatalf("method = %s", r.Method) + } + gotAuth = r.Header.Get("Authorization") + if err := json.NewDecoder(r.Body).Decode(&gotRequest); err != nil { + t.Fatal(err) + } + _ = json.NewEncoder(w).Encode(validationResponse{ + Subject: "sub-1", + Groups: []string{"security", "security", "engineering"}, + Checks: []domain.VerifyCheck{{Name: "github_team_membership", Result: "passed"}}, + Limitations: []string{ + "Gateway checked provider membership with operator-managed credentials.", + }, + }) + })) + defer server.Close() + + validator, err := New(Config{Endpoint: server.URL, BearerToken: "gateway-token", AllowInsecureForLocalhost: true}) + if err != nil { + t.Fatal(err) + } + result, err := validator.ValidateProviderIdentity(t.Context(), app.ProviderIdentityValidationRequest{ + TenantID: "ten_1", + ProviderID: "sso_1", + ProviderType: "oidc", + Issuer: "https://idp.example.test", + Subject: "sub-1", + GroupsClaim: "groups", + AccessToken: "access-token-secret", + }) + if err != nil { + t.Fatal(err) + } + if gotAuth != "Bearer gateway-token" { + t.Fatalf("auth header = %q", gotAuth) + } + if gotRequest.AccessToken != "access-token-secret" || !gotRequest.AccessTokenPresent || gotRequest.Subject != "sub-1" { + t.Fatalf("request = %#v", gotRequest) + } + if len(result.Groups) != 2 || result.Groups[0] != "security" || result.Groups[1] != "engineering" { + t.Fatalf("groups = %#v", result.Groups) + } + if len(result.Checks) < 3 || result.Checks[0].Name != "provider_validation_gateway" || result.Checks[0].Result != "passed" { + t.Fatalf("checks = %#v", result.Checks) + } +} + +func TestValidateProviderIdentityRejectsSubjectMismatch(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + _ = json.NewEncoder(w).Encode(validationResponse{Subject: "other"}) + })) + defer server.Close() + + validator, err := New(Config{Endpoint: server.URL, AllowInsecureForLocalhost: true}) + if err != nil { + t.Fatal(err) + } + result, err := validator.ValidateProviderIdentity(t.Context(), app.ProviderIdentityValidationRequest{Subject: "sub-1"}) + if err == nil { + t.Fatal("expected subject mismatch to fail") + } + if len(result.Checks) != 1 || result.Checks[0].Name != "provider_validation_gateway_subject" || result.Checks[0].Result != "failed" { + t.Fatalf("checks = %#v", result.Checks) + } +} + +func TestValidateProviderIdentityRejectsUnknownResponseFields(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + _, _ = w.Write([]byte(`{"subject":"sub-1","unexpected":"nope"}`)) + })) + defer server.Close() + + validator, err := New(Config{Endpoint: server.URL, AllowInsecureForLocalhost: true}) + if err != nil { + t.Fatal(err) + } + if _, err := validator.ValidateProviderIdentity(t.Context(), app.ProviderIdentityValidationRequest{Subject: "sub-1"}); err == nil { + t.Fatal("expected strict response decoding to reject unknown fields") + } +} + +func TestValidateProviderIdentityHidesGatewayBodyAndTokensFromErrors(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + http.Error(w, "access-token-secret rejected", http.StatusUnauthorized) + })) + defer server.Close() + + validator, err := New(Config{Endpoint: server.URL, AllowInsecureForLocalhost: true}) + if err != nil { + t.Fatal(err) + } + _, err = validator.ValidateProviderIdentity(t.Context(), app.ProviderIdentityValidationRequest{Subject: "sub-1", AccessToken: "access-token-secret"}) + if err == nil { + t.Fatal("expected provider validation failure") + } + if strings.Contains(err.Error(), "access-token-secret") { + t.Fatalf("error leaked access token: %v", err) + } +} + +func TestNewRequiresHTTPSEndpointExceptLocalhostOverride(t *testing.T) { + if _, err := New(Config{Endpoint: "http://example.com/provider"}); err == nil { + t.Fatal("expected remote HTTP endpoint to be rejected") + } + if _, err := New(Config{Endpoint: "http://127.0.0.1/provider", AllowInsecureForLocalhost: true}); err != nil { + t.Fatalf("localhost override should be accepted: %v", err) + } +} From ac2426114fb7777b003defd91f5949d0af08cd5f Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 11:14:53 +0300 Subject: [PATCH 141/287] feat: add transparency proof gateway --- README.md | 2 +- cmd/evydence-api/main.go | 34 ++- cmd/evydence-api/main_test.go | 19 ++ docs/api.md | 2 +- docs/architecture.md | 2 +- docs/reference/configuration.md | 18 ++ docs/reference/production-readiness.md | 7 +- .../adapters/httpapi/openapi_operations.go | 2 +- .../transparency/httpgateway/httpgateway.go | 208 ++++++++++++++++++ .../httpgateway/httpgateway_test.go | 107 +++++++++ openapi.yaml | 2 +- 11 files changed, 389 insertions(+), 14 deletions(-) create mode 100644 internal/adapters/transparency/httpgateway/httpgateway.go create mode 100644 internal/adapters/transparency/httpgateway/httpgateway_test.go diff --git a/README.md b/README.md index 24996f3..7f42287 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ This repository contains a Go implementation under module `github.com/aatuh/evyd - AGPL license, commercial licensing, governance, contribution, security, support, trademark, release-evidence, and changelog metadata. -Implemented-but-partial areas are documented explicitly: signing-provider operation receipts can use an HTTPS signing gateway, explicit gateway-backed `gcp-kms`, `azure-key-vault`, and `pkcs11-hsm` modes, or the built-in AWS KMS executor, but direct non-AWS cloud KMS/HSM SDK adapters and deployment-specific custody review remain operator work; SSO credential exchange uses configured local OIDC/SAML trust material and session-scoped OIDC group-role mappings, and provider verification can optionally call OIDC UserInfo or an operator-controlled provider validation gateway with a supplied access token, but this does not replace direct provider-specific management API clients or external group synchronization; and public transparency records can verify operator-supplied or fetched inclusion proof material without replacing provider-specific trust review. +Implemented-but-partial areas are documented explicitly: signing-provider operation receipts can use an HTTPS signing gateway, explicit gateway-backed `gcp-kms`, `azure-key-vault`, and `pkcs11-hsm` modes, or the built-in AWS KMS executor, but direct non-AWS cloud KMS/HSM SDK adapters and deployment-specific custody review remain operator work; SSO credential exchange uses configured local OIDC/SAML trust material and session-scoped OIDC group-role mappings, and provider verification can optionally call OIDC UserInfo or an operator-controlled provider validation gateway with a supplied access token, but this does not replace direct provider-specific management API clients or external group synchronization; and public transparency records can verify operator-supplied proof material, fetch from configured endpoints, or use an operator-controlled transparency proof gateway without replacing provider-specific trust review. ## License, Security, Support, And Governance diff --git a/cmd/evydence-api/main.go b/cmd/evydence-api/main.go index fa26664..5b743fb 100644 --- a/cmd/evydence-api/main.go +++ b/cmd/evydence-api/main.go @@ -21,8 +21,9 @@ import ( s3store "github.com/aatuh/evydence/internal/adapters/objectstore/s3" "github.com/aatuh/evydence/internal/adapters/postgres" "github.com/aatuh/evydence/internal/adapters/signing/awskms" - "github.com/aatuh/evydence/internal/adapters/signing/httpgateway" + signinggateway "github.com/aatuh/evydence/internal/adapters/signing/httpgateway" "github.com/aatuh/evydence/internal/adapters/transparency/httpfetcher" + transparencygateway "github.com/aatuh/evydence/internal/adapters/transparency/httpgateway" "github.com/aatuh/evydence/internal/app" ) @@ -60,10 +61,11 @@ func run() error { return err } cfg.ProviderAPI = providerValidator - cfg.Transparency = httpfetcher.New(httpfetcher.Config{ - AllowInsecureForLocalhost: strings.EqualFold(os.Getenv("EVYDENCE_TRANSPARENCY_FETCH_ALLOW_INSECURE_LOCALHOST"), "true"), - Timeout: time.Duration(intEnv("EVYDENCE_TRANSPARENCY_FETCH_TIMEOUT_SECONDS", 10)) * time.Second, - }) + transparencyFetcher, err := openTransparencyProofFetcher() + if err != nil { + return err + } + cfg.Transparency = transparencyFetcher if signer, err := openSigningExecutor(); err != nil { return err } else { @@ -182,7 +184,7 @@ func openSigningExecutor() (app.SigningExecutor, error) { if endpoint == "" { return nil, nil } - executor, err := httpgateway.New(httpgateway.Config{ + executor, err := signinggateway.New(signinggateway.Config{ Endpoint: endpoint, BearerToken: os.Getenv("EVYDENCE_SIGNING_EXECUTOR_TOKEN"), AllowInsecureForLocalhost: strings.EqualFold(os.Getenv("EVYDENCE_SIGNING_EXECUTOR_ALLOW_INSECURE_LOCALHOST"), "true"), @@ -194,6 +196,26 @@ func openSigningExecutor() (app.SigningExecutor, error) { return executor, nil } +func openTransparencyProofFetcher() (app.TransparencyProofFetcher, error) { + endpoint := strings.TrimSpace(os.Getenv("EVYDENCE_TRANSPARENCY_PROOF_GATEWAY_URL")) + if endpoint != "" { + fetcher, err := transparencygateway.New(transparencygateway.Config{ + Endpoint: endpoint, + BearerToken: os.Getenv("EVYDENCE_TRANSPARENCY_PROOF_GATEWAY_TOKEN"), + AllowInsecureForLocalhost: strings.EqualFold(os.Getenv("EVYDENCE_TRANSPARENCY_PROOF_GATEWAY_ALLOW_INSECURE_LOCALHOST"), "true"), + Timeout: time.Duration(intEnv("EVYDENCE_TRANSPARENCY_PROOF_GATEWAY_TIMEOUT_SECONDS", 10)) * time.Second, + }) + if err != nil { + return nil, fmt.Errorf("configure transparency proof gateway: %w", err) + } + return fetcher, nil + } + return httpfetcher.New(httpfetcher.Config{ + AllowInsecureForLocalhost: strings.EqualFold(os.Getenv("EVYDENCE_TRANSPARENCY_FETCH_ALLOW_INSECURE_LOCALHOST"), "true"), + Timeout: time.Duration(intEnv("EVYDENCE_TRANSPARENCY_FETCH_TIMEOUT_SECONDS", 10)) * time.Second, + }), nil +} + func openProviderIdentityValidator() (app.ProviderIdentityValidator, error) { endpoint := strings.TrimSpace(os.Getenv("EVYDENCE_PROVIDER_VALIDATION_GATEWAY_URL")) if endpoint != "" { diff --git a/cmd/evydence-api/main_test.go b/cmd/evydence-api/main_test.go index ca06c32..7d66aab 100644 --- a/cmd/evydence-api/main_test.go +++ b/cmd/evydence-api/main_test.go @@ -252,3 +252,22 @@ func TestOpenProviderIdentityValidatorRequiresHTTPSForRemoteGateway(t *testing.T t.Fatalf("remote http provider validator err=%v, want https rejection", err) } } + +func TestOpenTransparencyProofFetcherUsesGatewayWhenConfigured(t *testing.T) { + t.Setenv("EVYDENCE_TRANSPARENCY_PROOF_GATEWAY_URL", "http://127.0.0.1/proof") + t.Setenv("EVYDENCE_TRANSPARENCY_PROOF_GATEWAY_ALLOW_INSECURE_LOCALHOST", "true") + fetcher, err := openTransparencyProofFetcher() + if err != nil { + t.Fatalf("transparency proof gateway should be accepted: %v", err) + } + if fetcher == nil { + t.Fatal("expected transparency proof fetcher") + } +} + +func TestOpenTransparencyProofFetcherRequiresHTTPSForRemoteGateway(t *testing.T) { + t.Setenv("EVYDENCE_TRANSPARENCY_PROOF_GATEWAY_URL", "http://transparency.example.test/proof") + if _, err := openTransparencyProofFetcher(); err == nil || !strings.Contains(err.Error(), "https") { + t.Fatalf("remote http transparency gateway err=%v, want https rejection", err) + } +} diff --git a/docs/api.md b/docs/api.md index 6fc219f..84d1798 100644 --- a/docs/api.md +++ b/docs/api.md @@ -399,7 +399,7 @@ Source snapshots capture submitted provider metadata. They do not call provider | `POST` | `/v1/public-transparency-logs` | Record optional public transparency log configuration. | | `POST` | `/v1/public-transparency-log-entries` | Record published public transparency log entry metadata. | | `POST` | `/v1/public-transparency-log-entries/{id}/verify` | Verify operator-supplied RFC6962-style public transparency inclusion proof material. | -| `POST` | `/v1/public-transparency-log-entries/{id}/fetch-proof` | Fetch proof material from the configured transparency endpoint and verify it locally. | +| `POST` | `/v1/public-transparency-log-entries/{id}/fetch-proof` | Fetch proof material from the configured transparency endpoint or proof gateway and verify it locally. | | `POST` | `/v1/object-retention-policies` | Record retention policy intent with optional tenant-prefixed sample object key and legal-hold proof requirement. | | `POST` | `/v1/object-retention-policies/{id}/verify` | Record provider verification transition. | | `POST` | `/v1/legal-holds` | Record legal hold. | diff --git a/docs/architecture.md b/docs/architecture.md index a13c7a9..48735bf 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -52,6 +52,6 @@ Air-gapped import-bundle workflows preserve the same tenant-scoped import path a ## Limitations -The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, explicit gateway-backed `gcp-kms`, `azure-key-vault`, and `pkcs11-hsm` signing modes, an AWS KMS signing executor, OIDC discovery refresh, optional live OIDC UserInfo validation, an optional provider validation gateway, SSO credential exchange with session-scoped OIDC group-role mapping, public-transparency proof fetching, and optional worker-owned parser side effects are implemented, but direct non-AWS cloud KMS/HSM SDK adapters, direct provider-specific management API clients, and external group synchronization remain deployment hardening work. Hand-tuned per-resource repository implementations remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, unsupported API writer modes or replica counts above one, local plaintext signing-key mode, and bootstrap secret printing. +The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, explicit gateway-backed `gcp-kms`, `azure-key-vault`, and `pkcs11-hsm` signing modes, an AWS KMS signing executor, OIDC discovery refresh, optional live OIDC UserInfo validation, an optional provider validation gateway, SSO credential exchange with session-scoped OIDC group-role mapping, public-transparency proof fetching, an optional transparency proof gateway, and optional worker-owned parser side effects are implemented, but direct non-AWS cloud KMS/HSM SDK adapters, direct provider-specific management API clients, and external group synchronization remain deployment hardening work. Hand-tuned per-resource repository implementations remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, unsupported API writer modes or replica counts above one, local plaintext signing-key mode, and bootstrap secret printing. Evydence does not prove provider truth, scanner authority, runtime security, legal compliance, or release security by itself. diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 1352b54..47f985a 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -64,6 +64,10 @@ The example secrets are placeholders. Replace them before using shared or produc | `EVYDENCE_AWS_KMS_ENDPOINT` | No | unset | Optional AWS KMS-compatible endpoint for tests or controlled private endpoints. | | `EVYDENCE_AWS_KMS_SIGNING_ALGORITHM` | No | `ECDSA_SHA_256` | Supported values are `ECDSA_SHA_256`, `RSASSA_PSS_SHA_256`, and `RSASSA_PKCS1_V1_5_SHA_256` because Evydence signs stored SHA-256 payload hashes. | | `EVYDENCE_AWS_KMS_TIMEOUT_SECONDS` | No | `10` | Timeout for AWS KMS signing requests. | +| `EVYDENCE_TRANSPARENCY_PROOF_GATEWAY_URL` | No | unset | Optional HTTPS operator-controlled gateway for transparency inclusion proof fetch/verification material. When unset, Evydence fetches from the configured public log endpoint. | +| `EVYDENCE_TRANSPARENCY_PROOF_GATEWAY_TOKEN` | Gateway | unset | Optional bearer token for the transparency proof gateway. Store outside source control and logs. | +| `EVYDENCE_TRANSPARENCY_PROOF_GATEWAY_TIMEOUT_SECONDS` | No | `10` | Timeout for transparency proof gateway requests. | +| `EVYDENCE_TRANSPARENCY_PROOF_GATEWAY_ALLOW_INSECURE_LOCALHOST` | Local only | `false` | Allows an HTTP localhost transparency proof gateway for tests. Do not use for production. | | `EVYDENCE_TEST_DATABASE_URL` | Live tests | `.test.env.example` value | Used by `make live-postgres-check`, `make postgres-integration-test`, and `make release-check`. | ## Production Rejection Checks @@ -152,6 +156,20 @@ credentials and policies. It does not make external group synchronization automatic, does not create permanent role bindings, and does not prove provider truth beyond the gateway response and recorded limitations. +## Transparency Proof Gateway + +When `EVYDENCE_TRANSPARENCY_PROOF_GATEWAY_URL` is set, public transparency +proof fetches call an operator-controlled HTTPS gateway instead of constructing +`/entries/{external_id}/inclusion-proof` requests directly against the log +endpoint. Evydence sends tenant id, log id, entry id, configured endpoint, +external entry id, and the expected Evydence entry hash. The gateway returns +RFC6962-style proof material plus optional non-secret checks and limitations. + +Evydence still verifies the returned proof material locally against the +published entry hash. The gateway records provider-specific proof retrieval or +timestamp semantics as evidence only; operators remain responsible for public +log trust, gateway operation, and provider availability. + ## Related Commands - Local operation: [Install and operate](../how-to/install-and-operate.md) diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 320e1b4..dac9434 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -73,9 +73,10 @@ Known hardening work remains: creating permanent role bindings, provider verification can optionally call a discovered OIDC UserInfo endpoint or an operator-controlled provider validation gateway with a supplied access token, and public transparency - proof material can be fetched from a configured endpoint and verified - locally, but provider-specific trust semantics and availability remain - deployment responsibilities; + proof material can be fetched from a configured endpoint or an + operator-controlled transparency proof gateway and verified locally, but + provider-specific trust semantics and availability remain deployment + responsibilities; - the broader production exit review remains incomplete. ## Production Profiles diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 1062056..a927d74 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -620,7 +620,7 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.RequestBody = jsonRequest("Public transparency log inclusion proof verification request.", "#/components/schemas/VerifyPublicTransparencyLogEntryRequest") operation.Responses[http.StatusOK] = jsonResponse("Verified public transparency log entry envelope.", "#/components/schemas/PublicTransparencyLogEntryEnvelope") case "fetchPublicTransparencyLogEntryProof": - operation.Description = "Fetches public transparency inclusion proof material from the configured log endpoint and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities." + operation.Description = "Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities." operation.Parameters = append(operation.Parameters, pathParam("id", "Public transparency log entry id.")) operation.RequestBody = jsonRequest("Empty JSON object.", "#/components/schemas/EmptyObject") operation.Responses[http.StatusOK] = jsonResponse("Fetched and verified public transparency log entry envelope.", "#/components/schemas/PublicTransparencyLogEntryEnvelope") diff --git a/internal/adapters/transparency/httpgateway/httpgateway.go b/internal/adapters/transparency/httpgateway/httpgateway.go new file mode 100644 index 0000000..c3b1e1b --- /dev/null +++ b/internal/adapters/transparency/httpgateway/httpgateway.go @@ -0,0 +1,208 @@ +package httpgateway + +import ( + "bytes" + "context" + "encoding/hex" + "encoding/json" + "errors" + "io" + "net" + "net/http" + "net/url" + "strings" + "time" + + "github.com/aatuh/evydence/internal/app" + "github.com/aatuh/evydence/internal/domain" +) + +const ( + defaultTimeout = 10 * time.Second + maxBodyBytes = 128 * 1024 +) + +type Config struct { + Endpoint string + BearerToken string + Timeout time.Duration + AllowInsecureForLocalhost bool + Client *http.Client +} + +type Fetcher struct { + endpoint string + bearerToken string + client *http.Client +} + +type proofRequest struct { + TenantID string `json:"tenant_id"` + LogID string `json:"log_id"` + EntryID string `json:"entry_id"` + Endpoint string `json:"endpoint"` + ExternalID string `json:"external_id"` + EntryHash string `json:"entry_hash"` +} + +type proofResponse struct { + ExternalID string `json:"external_id"` + LeafHash string `json:"leaf_hash"` + RootHash string `json:"root_hash"` + LeafIndex int `json:"leaf_index"` + TreeSize int `json:"tree_size"` + InclusionProof []string `json:"inclusion_proof"` + Checks []domain.VerifyCheck `json:"checks,omitempty"` + Limitations []string `json:"limitations,omitempty"` +} + +func New(cfg Config) (*Fetcher, error) { + endpoint := strings.TrimSpace(cfg.Endpoint) + if endpoint == "" { + return nil, app.ErrValidation + } + parsed, err := url.Parse(endpoint) + if err != nil || parsed.Scheme == "" || parsed.Host == "" || parsed.User != nil { + return nil, app.ErrValidation + } + if parsed.Scheme != "https" && (!cfg.AllowInsecureForLocalhost || parsed.Scheme != "http" || !localhostHost(parsed.Hostname())) { + return nil, errors.New("transparency proof gateway endpoint must use https") + } + timeout := cfg.Timeout + if timeout <= 0 { + timeout = defaultTimeout + } + client := cfg.Client + if client == nil { + client = &http.Client{Timeout: timeout} + } + return &Fetcher{endpoint: endpoint, bearerToken: strings.TrimSpace(cfg.BearerToken), client: client}, nil +} + +func (f *Fetcher) FetchTransparencyProof(ctx context.Context, req app.TransparencyProofRequest) (app.TransparencyProofResult, error) { + if f == nil || f.client == nil { + return app.TransparencyProofResult{}, app.ErrValidation + } + externalID := strings.TrimSpace(req.ExternalID) + if externalID == "" { + return app.TransparencyProofResult{}, app.ErrValidation + } + body, err := json.Marshal(proofRequest{ + TenantID: strings.TrimSpace(req.TenantID), + LogID: strings.TrimSpace(req.LogID), + EntryID: strings.TrimSpace(req.EntryID), + Endpoint: strings.TrimSpace(req.Endpoint), + ExternalID: externalID, + EntryHash: strings.TrimSpace(req.EntryHash), + }) + if err != nil { + return app.TransparencyProofResult{}, app.ErrValidation + } + httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, f.endpoint, bytes.NewReader(body)) + if err != nil { + return app.TransparencyProofResult{}, app.ErrValidation + } + httpReq.Header.Set("Accept", "application/json") + httpReq.Header.Set("Content-Type", "application/json") + if f.bearerToken != "" { + httpReq.Header.Set("Authorization", "Bearer "+f.bearerToken) + } + resp, err := f.client.Do(httpReq) + if err != nil { + return app.TransparencyProofResult{}, errors.New("transparency proof gateway request failed") + } + defer resp.Body.Close() + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + _, _ = io.Copy(io.Discard, io.LimitReader(resp.Body, 4096)) + return app.TransparencyProofResult{}, app.ErrVerificationFailed + } + var decoded proofResponse + decoder := json.NewDecoder(io.LimitReader(resp.Body, maxBodyBytes+1)) + decoder.DisallowUnknownFields() + if err := decoder.Decode(&decoded); err != nil { + return app.TransparencyProofResult{}, app.ErrVerificationFailed + } + if decoder.InputOffset() > maxBodyBytes { + return app.TransparencyProofResult{}, app.ErrVerificationFailed + } + decoded.ExternalID = strings.TrimSpace(decoded.ExternalID) + decoded.LeafHash = strings.TrimSpace(decoded.LeafHash) + decoded.RootHash = strings.TrimSpace(decoded.RootHash) + if decoded.ExternalID != "" && decoded.ExternalID != externalID { + return app.TransparencyProofResult{}, app.ErrVerificationFailed + } + if !validSHA256Digest(decoded.RootHash) || (decoded.LeafHash != "" && !validSHA256Digest(decoded.LeafHash)) || decoded.TreeSize <= 0 || decoded.LeafIndex < 0 || decoded.LeafIndex >= decoded.TreeSize || len(decoded.InclusionProof) > 64 { + return app.TransparencyProofResult{}, app.ErrVerificationFailed + } + proof := make([]string, 0, len(decoded.InclusionProof)) + for _, hash := range decoded.InclusionProof { + hash = strings.TrimSpace(hash) + if !validSHA256Digest(hash) { + return app.TransparencyProofResult{}, app.ErrVerificationFailed + } + proof = append(proof, hash) + } + checks := append([]domain.VerifyCheck{{Name: "transparency_proof_gateway", Result: "passed"}}, safeChecks(decoded.Checks)...) + limitations := safeLimitations(decoded.Limitations) + if len(limitations) == 0 { + limitations = []string{"Transparency proof gateway returned proof material for local verification; provider trust and timestamp semantics remain deployment responsibilities."} + } + return app.TransparencyProofResult{ + ExternalID: decoded.ExternalID, + LeafHash: decoded.LeafHash, + RootHash: decoded.RootHash, + LeafIndex: decoded.LeafIndex, + TreeSize: decoded.TreeSize, + InclusionProof: proof, + Checks: checks, + Limitations: limitations, + }, nil +} + +func validSHA256Digest(value string) bool { + if !strings.HasPrefix(value, "sha256:") || len(value) != len("sha256:")+64 { + return false + } + raw, err := hex.DecodeString(strings.TrimPrefix(value, "sha256:")) + return err == nil && len(raw) == 32 +} + +func safeChecks(in []domain.VerifyCheck) []domain.VerifyCheck { + out := make([]domain.VerifyCheck, 0, len(in)) + for _, check := range in { + name := strings.TrimSpace(check.Name) + result := strings.TrimSpace(check.Result) + detail := strings.TrimSpace(check.Detail) + if name == "" || result == "" || len(name) > 128 || len(result) > 32 || len(detail) > 1024 { + continue + } + out = append(out, domain.VerifyCheck{Name: name, Result: result, Detail: detail}) + if len(out) >= 32 { + break + } + } + return out +} + +func safeLimitations(in []string) []string { + out := make([]string, 0, len(in)) + for _, limitation := range in { + limitation = strings.TrimSpace(limitation) + if limitation == "" || len(limitation) > 1024 { + continue + } + out = append(out, limitation) + if len(out) >= 16 { + break + } + } + return out +} + +func localhostHost(host string) bool { + if strings.EqualFold(host, "localhost") { + return true + } + ip := net.ParseIP(host) + return ip != nil && ip.IsLoopback() +} diff --git a/internal/adapters/transparency/httpgateway/httpgateway_test.go b/internal/adapters/transparency/httpgateway/httpgateway_test.go new file mode 100644 index 0000000..d71576a --- /dev/null +++ b/internal/adapters/transparency/httpgateway/httpgateway_test.go @@ -0,0 +1,107 @@ +package httpgateway + +import ( + "encoding/json" + "net/http" + "net/http/httptest" + "strings" + "testing" + + "github.com/aatuh/evydence/internal/app" + "github.com/aatuh/evydence/internal/domain" +) + +const testDigest = "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + +func TestFetchTransparencyProofPostsSafeRequestAndReturnsProof(t *testing.T) { + var gotAuth string + var gotRequest proofRequest + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + t.Fatalf("method = %s", r.Method) + } + gotAuth = r.Header.Get("Authorization") + if err := json.NewDecoder(r.Body).Decode(&gotRequest); err != nil { + t.Fatal(err) + } + _ = json.NewEncoder(w).Encode(proofResponse{ + ExternalID: "entry-1", + LeafHash: testDigest, + RootHash: testDigest, + LeafIndex: 0, + TreeSize: 1, + InclusionProof: []string{}, + Checks: []domain.VerifyCheck{{Name: "provider_timestamp", Result: "passed"}}, + Limitations: []string{"Gateway checked provider proof material."}, + }) + })) + defer server.Close() + + fetcher, err := New(Config{Endpoint: server.URL, BearerToken: "gateway-token", AllowInsecureForLocalhost: true}) + if err != nil { + t.Fatal(err) + } + result, err := fetcher.FetchTransparencyProof(t.Context(), app.TransparencyProofRequest{ + TenantID: "ten_1", + LogID: "log_1", + EntryID: "pte_1", + Endpoint: "https://log.example.test", + ExternalID: "entry-1", + EntryHash: testDigest, + }) + if err != nil { + t.Fatal(err) + } + if gotAuth != "Bearer gateway-token" { + t.Fatalf("auth header = %q", gotAuth) + } + if gotRequest.ExternalID != "entry-1" || gotRequest.EntryHash != testDigest || gotRequest.Endpoint != "https://log.example.test" { + t.Fatalf("request = %#v", gotRequest) + } + if result.RootHash != testDigest || len(result.Checks) < 2 || result.Checks[0].Name != "transparency_proof_gateway" { + t.Fatalf("result = %#v", result) + } +} + +func TestFetchTransparencyProofRejectsExternalIDMismatch(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + _ = json.NewEncoder(w).Encode(proofResponse{ExternalID: "other", RootHash: testDigest, LeafIndex: 0, TreeSize: 1, InclusionProof: []string{}}) + })) + defer server.Close() + + fetcher, err := New(Config{Endpoint: server.URL, AllowInsecureForLocalhost: true}) + if err != nil { + t.Fatal(err) + } + if _, err := fetcher.FetchTransparencyProof(t.Context(), app.TransparencyProofRequest{ExternalID: "entry-1"}); err == nil { + t.Fatal("expected external id mismatch to fail") + } +} + +func TestFetchTransparencyProofRejectsUnknownFieldsAndHidesBody(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + _, _ = w.Write([]byte(`{"external_id":"entry-1","root_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","leaf_index":0,"tree_size":1,"inclusion_proof":[],"secret":"provider-secret"}`)) + })) + defer server.Close() + + fetcher, err := New(Config{Endpoint: server.URL, AllowInsecureForLocalhost: true}) + if err != nil { + t.Fatal(err) + } + _, err = fetcher.FetchTransparencyProof(t.Context(), app.TransparencyProofRequest{ExternalID: "entry-1"}) + if err == nil { + t.Fatal("expected strict response decoding failure") + } + if strings.Contains(err.Error(), "provider-secret") { + t.Fatalf("error leaked body: %v", err) + } +} + +func TestNewRequiresHTTPSEndpointExceptLocalhostOverride(t *testing.T) { + if _, err := New(Config{Endpoint: "http://example.com/proof"}); err == nil { + t.Fatal("expected remote HTTP endpoint to be rejected") + } + if _, err := New(Config{Endpoint: "http://127.0.0.1/proof", AllowInsecureForLocalhost: true}); err != nil { + t.Fatalf("localhost override should be accepted: %v", err) + } +} diff --git a/openapi.yaml b/openapi.yaml index 5a87038..246ef48 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From 3fb40bbec352092671d9087622417765738e1bd3 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 11:17:53 +0300 Subject: [PATCH 142/287] fix: avoid forwarding provider access tokens --- README.md | 2 +- docs/api.md | 2 +- docs/reference/configuration.md | 9 +++++---- docs/reference/production-readiness.md | 10 ++++++---- .../identity/httpvalidator/httpvalidator.go | 2 -- .../identity/httpvalidator/httpvalidator_test.go | 14 ++++++++++++-- 6 files changed, 25 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 7f42287..9b96d38 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ This repository contains a Go implementation under module `github.com/aatuh/evyd - AGPL license, commercial licensing, governance, contribution, security, support, trademark, release-evidence, and changelog metadata. -Implemented-but-partial areas are documented explicitly: signing-provider operation receipts can use an HTTPS signing gateway, explicit gateway-backed `gcp-kms`, `azure-key-vault`, and `pkcs11-hsm` modes, or the built-in AWS KMS executor, but direct non-AWS cloud KMS/HSM SDK adapters and deployment-specific custody review remain operator work; SSO credential exchange uses configured local OIDC/SAML trust material and session-scoped OIDC group-role mappings, and provider verification can optionally call OIDC UserInfo or an operator-controlled provider validation gateway with a supplied access token, but this does not replace direct provider-specific management API clients or external group synchronization; and public transparency records can verify operator-supplied proof material, fetch from configured endpoints, or use an operator-controlled transparency proof gateway without replacing provider-specific trust review. +Implemented-but-partial areas are documented explicitly: signing-provider operation receipts can use an HTTPS signing gateway, explicit gateway-backed `gcp-kms`, `azure-key-vault`, and `pkcs11-hsm` modes, or the built-in AWS KMS executor, but direct non-AWS cloud KMS/HSM SDK adapters and deployment-specific custody review remain operator work; SSO credential exchange uses configured local OIDC/SAML trust material and session-scoped OIDC group-role mappings, and provider verification can optionally call OIDC UserInfo or an operator-controlled provider validation gateway when a caller supplies an access token, but the gateway receives only non-secret metadata and this does not replace direct provider-specific management API clients or external group synchronization; and public transparency records can verify operator-supplied proof material, fetch from configured endpoints, or use an operator-controlled transparency proof gateway without replacing provider-specific trust review. ## License, Security, Support, And Governance diff --git a/docs/api.md b/docs/api.md index 84d1798..4feac20 100644 --- a/docs/api.md +++ b/docs/api.md @@ -251,7 +251,7 @@ Important scope boundaries: | `POST` | `/v1/api-keys` | Create one-time API key secret. | | `GET` | `/v1/api-keys` | List keys without secret hashes. | -Current SSO endpoints model admin-managed provider, identity-link, trust-material, and session records plus API-first session logout. OIDC provider records can include public JWKS material, and SAML provider records can include PEM-encoded assertion signing certificates; both can be rotated through `POST /v1/sso/providers/{id}/trust-material`. OIDC public JWKS can also be refreshed from the configured issuer with `POST /v1/sso/providers/{id}/discover-oidc`. `POST /v1/provider-verifications` can verify a supplied OIDC ID token or SAML assertion locally for issuer, audience, subject, time bounds, and signature. When an OIDC `access_token` is supplied, the same endpoint can call either the provider's discovered UserInfo endpoint or a configured operator-controlled provider validation gateway, verify the returned subject, and record any configured group-claim mapping checks without storing the access token. `POST /v1/sso/session-exchanges` uses local token/assertion verification and a verified identity link to issue a one-time SSO bearer secret and an HttpOnly cookie for browser clients. OIDC group claim values can map to session-scoped roles through the provider `groups_claim` and `role_mapping`; no permanent role binding is created from token claims. External group synchronization into permanent role bindings is not implemented in this slice. +Current SSO endpoints model admin-managed provider, identity-link, trust-material, and session records plus API-first session logout. OIDC provider records can include public JWKS material, and SAML provider records can include PEM-encoded assertion signing certificates; both can be rotated through `POST /v1/sso/providers/{id}/trust-material`. OIDC public JWKS can also be refreshed from the configured issuer with `POST /v1/sso/providers/{id}/discover-oidc`. `POST /v1/provider-verifications` can verify a supplied OIDC ID token or SAML assertion locally for issuer, audience, subject, time bounds, and signature. When an OIDC `access_token` is supplied, the same endpoint can call either the provider's discovered UserInfo endpoint or a configured operator-controlled provider validation gateway, verify the returned subject, and record any configured group-claim mapping checks without storing the access token. The provider validation gateway receives only non-secret request metadata and an `access_token_present` flag, not the supplied token. `POST /v1/sso/session-exchanges` uses local token/assertion verification and a verified identity link to issue a one-time SSO bearer secret and an HttpOnly cookie for browser clients. OIDC group claim values can map to session-scoped roles through the provider `groups_claim` and `role_mapping`; no permanent role binding is created from token claims. External group synchronization into permanent role bindings is not implemented in this slice. ### Products, Releases, Evidence, And Risk diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 47f985a..ed03a4f 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -145,10 +145,11 @@ of whether the selected key custody profile satisfies their deployment needs. When `EVYDENCE_PROVIDER_VALIDATION_GATEWAY_URL` is set, provider identity verification can call an operator-controlled HTTPS gateway with tenant id, -provider id/type, issuer, subject, group-claim name, and a supplied access -token when the request includes one. The gateway returns non-secret checks, -groups, and limitations. Evydence stores the checks and normalized groups, not -the supplied token or raw provider response. +provider id/type, issuer, subject, group-claim name, and whether the caller +supplied an access token. Evydence does not forward that access token to the +gateway. The gateway returns non-secret checks, groups, and limitations. +Evydence stores the checks and normalized groups, not the supplied token or raw +provider response. This gateway is an integration point for GitHub, GitLab, IdP, directory, or other provider-specific validation logic that depends on deployment-owned diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index dac9434..4a7922b 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -72,8 +72,9 @@ Known hardening work remains: material, OIDC group claim values can map to session-scoped roles without creating permanent role bindings, provider verification can optionally call a discovered OIDC UserInfo endpoint or an operator-controlled provider - validation gateway with a supplied access token, and public transparency - proof material can be fetched from a configured endpoint or an + validation gateway when a caller supplies an access token. The gateway + receives only non-secret metadata and an access-token-present flag. Public + transparency proof material can be fetched from a configured endpoint or an operator-controlled transparency proof gateway and verified locally, but provider-specific trust semantics and availability remain deployment responsibilities; @@ -218,8 +219,9 @@ implemented capabilities: is implemented for public trust-material updates, manual JWKS and SAML signing-certificate rotation is implemented through the SSO provider trust-material endpoint, provider verification can optionally call OIDC - UserInfo or an operator-controlled provider validation gateway with a - supplied access token and record group-claim checks without storing the token, + UserInfo or an operator-controlled provider validation gateway when a caller + supplies an access token and record group-claim checks without storing or + forwarding that token to the gateway, SSO credential exchange can issue bearer sessions plus HttpOnly cookies after local token or assertion verification, OIDC group claim values can map to session-scoped roles, and API-first session logout can revoke the current SSO diff --git a/internal/adapters/identity/httpvalidator/httpvalidator.go b/internal/adapters/identity/httpvalidator/httpvalidator.go index 003cbef..7395845 100644 --- a/internal/adapters/identity/httpvalidator/httpvalidator.go +++ b/internal/adapters/identity/httpvalidator/httpvalidator.go @@ -42,7 +42,6 @@ type validationRequest struct { Issuer string `json:"issuer,omitempty"` Subject string `json:"subject"` GroupsClaim string `json:"groups_claim,omitempty"` - AccessToken string `json:"access_token,omitempty"` AccessTokenPresent bool `json:"access_token_present"` } @@ -95,7 +94,6 @@ func (v *Validator) ValidateProviderIdentity(ctx context.Context, req app.Provid Issuer: strings.TrimSpace(req.Issuer), Subject: subject, GroupsClaim: strings.TrimSpace(req.GroupsClaim), - AccessToken: accessToken, AccessTokenPresent: accessToken != "", }) if err != nil { diff --git a/internal/adapters/identity/httpvalidator/httpvalidator_test.go b/internal/adapters/identity/httpvalidator/httpvalidator_test.go index ca49a3e..bc0d3a2 100644 --- a/internal/adapters/identity/httpvalidator/httpvalidator_test.go +++ b/internal/adapters/identity/httpvalidator/httpvalidator_test.go @@ -2,6 +2,7 @@ package httpvalidator import ( "encoding/json" + "io" "net/http" "net/http/httptest" "strings" @@ -14,12 +15,18 @@ import ( func TestValidateProviderIdentityPostsSafeRequestAndReturnsChecks(t *testing.T) { var gotAuth string var gotRequest validationRequest + var gotBody []byte server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { t.Fatalf("method = %s", r.Method) } gotAuth = r.Header.Get("Authorization") - if err := json.NewDecoder(r.Body).Decode(&gotRequest); err != nil { + var err error + gotBody, err = io.ReadAll(r.Body) + if err != nil { + t.Fatal(err) + } + if err := json.Unmarshal(gotBody, &gotRequest); err != nil { t.Fatal(err) } _ = json.NewEncoder(w).Encode(validationResponse{ @@ -52,9 +59,12 @@ func TestValidateProviderIdentityPostsSafeRequestAndReturnsChecks(t *testing.T) if gotAuth != "Bearer gateway-token" { t.Fatalf("auth header = %q", gotAuth) } - if gotRequest.AccessToken != "access-token-secret" || !gotRequest.AccessTokenPresent || gotRequest.Subject != "sub-1" { + if !gotRequest.AccessTokenPresent || gotRequest.Subject != "sub-1" { t.Fatalf("request = %#v", gotRequest) } + if strings.Contains(string(gotBody), "access-token-secret") { + t.Fatalf("gateway request leaked supplied access token: %s", gotBody) + } if len(result.Groups) != 2 || result.Groups[0] != "security" || result.Groups[1] != "engineering" { t.Fatalf("groups = %#v", result.Groups) } From 104d8a30d35a22566f18ee0f5fe31afea3df2f40 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 11:25:37 +0300 Subject: [PATCH 143/287] docs: update maturity v2 status --- .maturity_next_steps_v2_status.md | 65 ++++++++++++++++++------------- 1 file changed, 38 insertions(+), 27 deletions(-) diff --git a/.maturity_next_steps_v2_status.md b/.maturity_next_steps_v2_status.md index c5a32b2..5903e27 100644 --- a/.maturity_next_steps_v2_status.md +++ b/.maturity_next_steps_v2_status.md @@ -13,9 +13,9 @@ coverage, or a secure-release guarantee. ## Closed Repo-Local Findings -- Tagged release-candidate evidence: local annotated tag `v0.1.0-rc.2` points - at the current release-candidate commit, and `dist/v0.1.0-rc.2/` was generated - by `make release-candidate-check TAG=v0.1.0-rc.2` with live PostgreSQL, +- Tagged release-candidate evidence: local annotated tag `v0.1.0-rc.3` points + at the current release-candidate commit, and `dist/v0.1.0-rc.3/` was generated + by `make release-candidate-check TAG=v0.1.0-rc.3` with live PostgreSQL, coverage threshold, migration compatibility, signed manifest, checksums, OpenAPI checksum, migration checksums, release notes, and manifest verification. @@ -27,10 +27,11 @@ coverage, or a secure-release guarantee. mutations have focused PostgreSQL transaction paths, production startup defaults to relational-only load, and production writes skip compatibility snapshot persistence when PostgreSQL relational support is configured. -- Single-writer HA stance: production API startup enforces a PostgreSQL - advisory writer lease, Helm defaults keep API replicas at one, and docs state - worker replicas may scale through PostgreSQL outbox locking while API - multi-writer mode remains unsupported. +- Single-writer HA stance: production API startup rejects unsupported writer + modes and declared replica counts above one, enforces a PostgreSQL advisory + writer lease, Helm defaults keep API replicas at one, and docs state worker + replicas may scale through PostgreSQL outbox locking while API multi-writer + mode remains unsupported. - Helm hardening: chart values require explicit image tags for release installs and include security contexts, resource/probe configuration, network policy, and single-writer guidance validated by `make deploy-check`. @@ -39,10 +40,15 @@ coverage, or a secure-release guarantee. expectations, and non-goals without asking reporters to disclose secrets or raw evidence publicly. - Trust automation hardening: signing operations can use the HTTPS signing - gateway or built-in AWS KMS executor; OIDC provider verification can call - discovered UserInfo endpoints with a supplied access token without persisting - that token; S3/MinIO object-retention verification can check bucket defaults - plus sample-object retention and legal-hold status. + gateway, explicit gateway-backed `gcp-kms`, `azure-key-vault`, and + `pkcs11-hsm` modes, or the built-in AWS KMS executor. OIDC provider + verification can call discovered UserInfo endpoints with a supplied access + token without persisting that token, or call an operator-controlled provider + validation gateway with only non-secret metadata and an + access-token-present flag. Public transparency proof fetches can use a + configured log endpoint or an operator-controlled transparency proof gateway + before local proof verification. S3/MinIO object-retention verification can + check bucket defaults plus sample-object retention and legal-hold status. - Integration proof: the checked GitHub Actions example now covers build provenance, artifact digest, SBOM upload, Grype/Trivy vulnerability-scan normalization, optional OpenVEX and release-bundle evidence, and manifest @@ -57,19 +63,22 @@ deployment/provider evidence that cannot be completed by repository code alone: ledger is split into focused services or another reviewed concurrency-control design replaces the current single-writer stance. - Non-AWS cloud KMS/HSM custody remains deployment-specific. The HTTPS signing - gateway covers tenant-controlled KMS/HSM services without sending raw payload - bytes, and AWS KMS has a direct executor, but other providers require - operator selection, credentials, IAM review, and provider-specific tests. -- Provider management API validation and external group synchronization remain - provider-specific. Evydence can verify configured OIDC/SAML trust material and - optional OIDC UserInfo checks, but GitHub, GitLab, IdP, or directory group - authority still depends on the configured provider and operator review. + gateway and explicit gateway-backed provider modes cover tenant-controlled + KMS/HSM services without sending raw payload bytes, and AWS KMS has a direct + executor, but direct non-AWS SDK custody still depends on operator provider + selection, credentials, IAM review, and provider-specific tests. +- Direct provider management API clients and external group synchronization + remain provider-specific. Evydence can verify configured OIDC/SAML trust + material, optional OIDC UserInfo checks, and an operator-controlled provider + validation gateway, but GitHub, GitLab, IdP, or directory group authority + still depends on the configured provider and operator review. - WORM/object-lock enforcement beyond configured bucket and sample-object checks depends on object-store creation mode, IAM policy, lifecycle rules, backups, retention settings, and provider audit evidence. - Public transparency provider semantics and availability remain external. - Evydence can verify operator-supplied or fetched inclusion proof material, but - provider trust and timestamp semantics require deployment review. + Evydence can verify operator-supplied, fetched, or gateway-returned inclusion + proof material locally, but provider trust and timestamp semantics require + deployment review. - Hosted SaaS production, regulated production, and customer-specific legal or audit conclusions require separate controls, support, privacy, operational, and external review work. @@ -78,13 +87,15 @@ deployment/provider evidence that cannot be completed by repository code alone: Recent local evidence: -- `make docs-check`: passed after release-status and docs-consistency updates. -- `make release-acceptance`: passed after release-note template wiring. -- `make finalize`: passed after release-note template wiring. -- `make release-candidate-check TAG=v0.1.0-rc.2`: passed after the template - change and regenerated the signed local release-candidate package. -- `make production-check`: passed inside the release-candidate packaging run - with live PostgreSQL and total coverage at `80.1%`. +- `make finalize`: passed after provider gateway and transparency gateway + hardening. +- `make release-acceptance`: passed after provider gateway and transparency + gateway hardening. +- `set -a; . ./.test.env.example; set +a; make production-check`: passed with + live PostgreSQL, gosec, govulncheck, race tests, migration compatibility, + release-signing smoke test, and total coverage at `80.1%`. +- `make release-candidate-check TAG=v0.1.0-rc.3`: passed and generated the + signed local release-candidate package at `dist/v0.1.0-rc.3/`. Release publication, cloud-provider validation, production object-lock proof, and deployment-specific backup/restore rehearsals must be run in the target From b3eee7cb9ef587994167c160dba06ba97ce3d934 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 11:36:23 +0300 Subject: [PATCH 144/287] feat: add direct cloud kms signers --- .maturity_next_steps_v2_status.md | 15 +- README.md | 4 +- cmd/evydence-api/main.go | 33 ++- cmd/evydence-api/main_test.go | 46 +++- docs/architecture.md | 2 +- docs/kubernetes.md | 6 +- docs/production-hardening.md | 6 +- docs/reference/configuration.md | 42 +++- docs/reference/production-readiness.md | 21 +- docs/reference/release-candidate.md | 4 +- docs/reference/release-notes-template.md | 10 +- docs/reference/release-notes-v0.1.0-rc.1.md | 10 +- .../signing/azurekeyvault/azurekeyvault.go | 213 ++++++++++++++++++ .../azurekeyvault/azurekeyvault_test.go | 100 ++++++++ internal/adapters/signing/gcpkms/gcpkms.go | 165 ++++++++++++++ .../adapters/signing/gcpkms/gcpkms_test.go | 79 +++++++ 16 files changed, 701 insertions(+), 55 deletions(-) create mode 100644 internal/adapters/signing/azurekeyvault/azurekeyvault.go create mode 100644 internal/adapters/signing/azurekeyvault/azurekeyvault_test.go create mode 100644 internal/adapters/signing/gcpkms/gcpkms.go create mode 100644 internal/adapters/signing/gcpkms/gcpkms_test.go diff --git a/.maturity_next_steps_v2_status.md b/.maturity_next_steps_v2_status.md index 5903e27..bb4b47d 100644 --- a/.maturity_next_steps_v2_status.md +++ b/.maturity_next_steps_v2_status.md @@ -40,8 +40,9 @@ coverage, or a secure-release guarantee. expectations, and non-goals without asking reporters to disclose secrets or raw evidence publicly. - Trust automation hardening: signing operations can use the HTTPS signing - gateway, explicit gateway-backed `gcp-kms`, `azure-key-vault`, and - `pkcs11-hsm` modes, or the built-in AWS KMS executor. OIDC provider + gateway, built-in AWS KMS, GCP Cloud KMS, and Azure Key Vault executors, with + `pkcs11-hsm` remaining gateway-backed because native HSM modules and slots + are deployment-specific. OIDC provider verification can call discovered UserInfo endpoints with a supplied access token without persisting that token, or call an operator-controlled provider validation gateway with only non-secret metadata and an @@ -62,11 +63,11 @@ deployment/provider evidence that cannot be completed by repository code alone: - High-scale multi-writer API HA remains unsupported until the large application ledger is split into focused services or another reviewed concurrency-control design replaces the current single-writer stance. -- Non-AWS cloud KMS/HSM custody remains deployment-specific. The HTTPS signing - gateway and explicit gateway-backed provider modes cover tenant-controlled - KMS/HSM services without sending raw payload bytes, and AWS KMS has a direct - executor, but direct non-AWS SDK custody still depends on operator provider - selection, credentials, IAM review, and provider-specific tests. +- KMS/HSM custody remains deployment-specific. AWS KMS, GCP Cloud KMS, and + Azure Key Vault have direct executors that send SHA-256 digests rather than + raw payload bytes. The HTTPS signing gateway covers tenant-controlled + PKCS#11/HSM services; native module/slot handling still depends on operator + hardware, credentials, IAM review, and provider-specific tests. - Direct provider management API clients and external group synchronization remain provider-specific. Evydence can verify configured OIDC/SAML trust material, optional OIDC UserInfo checks, and an operator-controlled provider diff --git a/README.md b/README.md index 9b96d38..24602ac 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ This repository contains a Go implementation under module `github.com/aatuh/evyd - AGPL license, commercial licensing, governance, contribution, security, support, trademark, release-evidence, and changelog metadata. -Implemented-but-partial areas are documented explicitly: signing-provider operation receipts can use an HTTPS signing gateway, explicit gateway-backed `gcp-kms`, `azure-key-vault`, and `pkcs11-hsm` modes, or the built-in AWS KMS executor, but direct non-AWS cloud KMS/HSM SDK adapters and deployment-specific custody review remain operator work; SSO credential exchange uses configured local OIDC/SAML trust material and session-scoped OIDC group-role mappings, and provider verification can optionally call OIDC UserInfo or an operator-controlled provider validation gateway when a caller supplies an access token, but the gateway receives only non-secret metadata and this does not replace direct provider-specific management API clients or external group synchronization; and public transparency records can verify operator-supplied proof material, fetch from configured endpoints, or use an operator-controlled transparency proof gateway without replacing provider-specific trust review. +Implemented-but-partial areas are documented explicitly: signing-provider operation receipts can use an HTTPS signing gateway, built-in AWS KMS, GCP Cloud KMS, or Azure Key Vault executors, and `pkcs11-hsm` remains gateway-backed because native HSM modules are deployment-specific; deployment-specific custody review remains operator work. SSO credential exchange uses configured local OIDC/SAML trust material and session-scoped OIDC group-role mappings, and provider verification can optionally call OIDC UserInfo or an operator-controlled provider validation gateway when a caller supplies an access token, but the gateway receives only non-secret metadata and this does not replace direct provider-specific management API clients or external group synchronization. Public transparency records can verify operator-supplied proof material, fetch from configured endpoints, or use an operator-controlled transparency proof gateway without replacing provider-specific trust review. ## License, Security, Support, And Governance @@ -109,4 +109,4 @@ make postgres-integration-test `make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. -`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required release-candidate evidence, but it does not by itself close the remaining service decomposition, direct non-AWS KMS/HSM SDK providers, direct provider-specific management API/group synchronization, broader object-lock enforcement beyond configured bucket/sample-object checks, HA, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. Critical runtime mutations for tenants, credential hashes, idempotency, audit-chain entries, release bundles, signatures, verification results, vulnerability decisions, and outbox jobs use focused PostgreSQL write paths when available. Release-ledger and evidence-core mutations for products, projects, releases, artifacts, evidence items, evidence lifecycle events, SBOMs, vulnerability scans, OpenAPI contracts, VEX documents, audit-chain entries, and parser outbox jobs also use focused PostgreSQL write paths when available. Remaining aggregate persistence calls use PostgreSQL relational synchronization without writing the compatibility snapshot when that store is configured. Current self-hosted production guidance still uses a single API writer replica; production API startup rejects unsupported writer modes and declared replica counts above one, then enforces that stance with a PostgreSQL advisory writer lease. Worker replicas may scale through PostgreSQL outbox row locking. +`make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required release-candidate evidence, but it does not by itself close the remaining service decomposition, PKCS#11/native HSM custody, direct provider-specific management API/group synchronization, broader object-lock enforcement beyond configured bucket/sample-object checks, HA, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. Critical runtime mutations for tenants, credential hashes, idempotency, audit-chain entries, release bundles, signatures, verification results, vulnerability decisions, and outbox jobs use focused PostgreSQL write paths when available. Release-ledger and evidence-core mutations for products, projects, releases, artifacts, evidence items, evidence lifecycle events, SBOMs, vulnerability scans, OpenAPI contracts, VEX documents, audit-chain entries, and parser outbox jobs also use focused PostgreSQL write paths when available. Remaining aggregate persistence calls use PostgreSQL relational synchronization without writing the compatibility snapshot when that store is configured. Current self-hosted production guidance still uses a single API writer replica; production API startup rejects unsupported writer modes and declared replica counts above one, then enforces that stance with a PostgreSQL advisory writer lease. Worker replicas may scale through PostgreSQL outbox row locking. diff --git a/cmd/evydence-api/main.go b/cmd/evydence-api/main.go index 5b743fb..9f4ecd2 100644 --- a/cmd/evydence-api/main.go +++ b/cmd/evydence-api/main.go @@ -21,6 +21,8 @@ import ( s3store "github.com/aatuh/evydence/internal/adapters/objectstore/s3" "github.com/aatuh/evydence/internal/adapters/postgres" "github.com/aatuh/evydence/internal/adapters/signing/awskms" + "github.com/aatuh/evydence/internal/adapters/signing/azurekeyvault" + "github.com/aatuh/evydence/internal/adapters/signing/gcpkms" signinggateway "github.com/aatuh/evydence/internal/adapters/signing/httpgateway" "github.com/aatuh/evydence/internal/adapters/transparency/httpfetcher" transparencygateway "github.com/aatuh/evydence/internal/adapters/transparency/httpgateway" @@ -177,9 +179,36 @@ func openSigningExecutor() (app.SigningExecutor, error) { } return executor, nil } + if mode == "gcp_kms" && strings.TrimSpace(os.Getenv("EVYDENCE_GCP_KMS_ACCESS_TOKEN")) != "" { + executor, err := gcpkms.New(gcpkms.Config{ + Endpoint: os.Getenv("EVYDENCE_GCP_KMS_ENDPOINT"), + AccessToken: os.Getenv("EVYDENCE_GCP_KMS_ACCESS_TOKEN"), + KeyName: os.Getenv("EVYDENCE_GCP_KMS_KEY_NAME"), + Timeout: time.Duration(intEnv("EVYDENCE_GCP_KMS_TIMEOUT_SECONDS", 10)) * time.Second, + }) + if err != nil { + return nil, fmt.Errorf("configure GCP KMS signing executor: %w", err) + } + return executor, nil + } + if mode == "azure_key_vault" && strings.TrimSpace(os.Getenv("EVYDENCE_AZURE_KEY_VAULT_ACCESS_TOKEN")) != "" { + executor, err := azurekeyvault.New(azurekeyvault.Config{ + VaultURL: os.Getenv("EVYDENCE_AZURE_KEY_VAULT_URL"), + AccessToken: os.Getenv("EVYDENCE_AZURE_KEY_VAULT_ACCESS_TOKEN"), + KeyName: os.Getenv("EVYDENCE_AZURE_KEY_VAULT_KEY_NAME"), + KeyVersion: os.Getenv("EVYDENCE_AZURE_KEY_VAULT_KEY_VERSION"), + Algorithm: os.Getenv("EVYDENCE_AZURE_KEY_VAULT_ALGORITHM"), + APIVersion: os.Getenv("EVYDENCE_AZURE_KEY_VAULT_API_VERSION"), + Timeout: time.Duration(intEnv("EVYDENCE_AZURE_KEY_VAULT_TIMEOUT_SECONDS", 10)) * time.Second, + }) + if err != nil { + return nil, fmt.Errorf("configure Azure Key Vault signing executor: %w", err) + } + return executor, nil + } endpoint := strings.TrimSpace(os.Getenv("EVYDENCE_SIGNING_EXECUTOR_URL")) if endpoint == "" && signingModeRequiresGateway(mode) { - return nil, fmt.Errorf("EVYDENCE_SIGNING_KEY_MODE=%s requires EVYDENCE_SIGNING_EXECUTOR_URL because no direct SDK executor is configured", mode) + return nil, fmt.Errorf("EVYDENCE_SIGNING_KEY_MODE=%s requires direct provider credentials or EVYDENCE_SIGNING_EXECUTOR_URL", mode) } if endpoint == "" { return nil, nil @@ -250,7 +279,7 @@ func validateRuntimeConfig(production bool, databaseURL, pepper, signingKeyMode, if !productionSigningKeyMode(normalizedMode) { return errors.New("production requires EVYDENCE_SIGNING_KEY_MODE=external, aws-kms, gcp-kms, azure-key-vault, or pkcs11-hsm; plaintext local signing keys are dev-only") } - if signingModeRequiresGateway(normalizedMode) && strings.TrimSpace(signingExecutorURL) == "" { + if normalizedMode == "pkcs11_hsm" && strings.TrimSpace(signingExecutorURL) == "" { return fmt.Errorf("production EVYDENCE_SIGNING_KEY_MODE=%s requires EVYDENCE_SIGNING_EXECUTOR_URL", normalizedMode) } if printBootstrapSecret { diff --git a/cmd/evydence-api/main_test.go b/cmd/evydence-api/main_test.go index 7d66aab..c570c3d 100644 --- a/cmd/evydence-api/main_test.go +++ b/cmd/evydence-api/main_test.go @@ -62,17 +62,23 @@ func TestValidateRuntimeConfigAllowsGatewayBackedKMSModesWithExecutor(t *testing } } -func TestValidateRuntimeConfigRejectsGatewayBackedKMSModesWithoutExecutor(t *testing.T) { - for _, mode := range []string{"gcp-kms", "azure-key-vault", "pkcs11-hsm"} { +func TestValidateRuntimeConfigAllowsDirectCloudKMSModesWithoutGateway(t *testing.T) { + for _, mode := range []string{"gcp-kms", "azure-key-vault"} { t.Run(mode, func(t *testing.T) { - err := validateRuntimeConfig(true, "postgres://example", "not-default", mode, "", false) - if err == nil || !strings.Contains(err.Error(), "EVYDENCE_SIGNING_EXECUTOR_URL") { - t.Fatalf("%s missing gateway err=%v", mode, err) + if err := validateRuntimeConfig(true, "postgres://example", "not-default", mode, "", false); err != nil { + t.Fatalf("%s direct mode should pass runtime config validation: %v", mode, err) } }) } } +func TestValidateRuntimeConfigRejectsPKCS11ModeWithoutGateway(t *testing.T) { + err := validateRuntimeConfig(true, "postgres://example", "not-default", "pkcs11-hsm", "", false) + if err == nil || !strings.Contains(err.Error(), "EVYDENCE_SIGNING_EXECUTOR_URL") { + t.Fatalf("pkcs11 missing gateway err=%v", err) + } +} + func TestValidateAPIWriterModeAllowsProductionSingleWriter(t *testing.T) { if err := validateAPIWriterMode(true, "single", "1"); err != nil { t.Fatalf("single writer production mode should be accepted: %v", err) @@ -220,12 +226,40 @@ func TestOpenSigningExecutorUsesGatewayForNonAWSKMSModes(t *testing.T) { } func TestOpenSigningExecutorRequiresGatewayForNonAWSKMSModes(t *testing.T) { - t.Setenv("EVYDENCE_SIGNING_KEY_MODE", "azure-key-vault") + t.Setenv("EVYDENCE_SIGNING_KEY_MODE", "pkcs11-hsm") if _, err := openSigningExecutor(); err == nil || !strings.Contains(err.Error(), "EVYDENCE_SIGNING_EXECUTOR_URL") { t.Fatalf("missing gateway err=%v", err) } } +func TestOpenSigningExecutorConfiguresDirectGCPKMS(t *testing.T) { + t.Setenv("EVYDENCE_SIGNING_KEY_MODE", "gcp-kms") + t.Setenv("EVYDENCE_GCP_KMS_ENDPOINT", "https://kms.example.test") + t.Setenv("EVYDENCE_GCP_KMS_ACCESS_TOKEN", "access-token") + signer, err := openSigningExecutor() + if err != nil { + t.Fatalf("gcp-kms direct signer should be accepted: %v", err) + } + if signer == nil { + t.Fatal("expected signer") + } +} + +func TestOpenSigningExecutorConfiguresDirectAzureKeyVault(t *testing.T) { + t.Setenv("EVYDENCE_SIGNING_KEY_MODE", "azure-key-vault") + t.Setenv("EVYDENCE_AZURE_KEY_VAULT_URL", "https://vault.example.test") + t.Setenv("EVYDENCE_AZURE_KEY_VAULT_ACCESS_TOKEN", "access-token") + t.Setenv("EVYDENCE_AZURE_KEY_VAULT_KEY_NAME", "evydence") + t.Setenv("EVYDENCE_AZURE_KEY_VAULT_KEY_VERSION", "v1") + signer, err := openSigningExecutor() + if err != nil { + t.Fatalf("azure-key-vault direct signer should be accepted: %v", err) + } + if signer == nil { + t.Fatal("expected signer") + } +} + func TestOpenSigningExecutorRejectsIncompleteAWSKMSConfig(t *testing.T) { t.Setenv("EVYDENCE_SIGNING_KEY_MODE", "aws-kms") t.Setenv("EVYDENCE_AWS_REGION", "eu-north-1") diff --git a/docs/architecture.md b/docs/architecture.md index 48735bf..ff08463 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -52,6 +52,6 @@ Air-gapped import-bundle workflows preserve the same tenant-scoped import path a ## Limitations -The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, explicit gateway-backed `gcp-kms`, `azure-key-vault`, and `pkcs11-hsm` signing modes, an AWS KMS signing executor, OIDC discovery refresh, optional live OIDC UserInfo validation, an optional provider validation gateway, SSO credential exchange with session-scoped OIDC group-role mapping, public-transparency proof fetching, an optional transparency proof gateway, and optional worker-owned parser side effects are implemented, but direct non-AWS cloud KMS/HSM SDK adapters, direct provider-specific management API clients, and external group synchronization remain deployment hardening work. Hand-tuned per-resource repository implementations remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, unsupported API writer modes or replica counts above one, local plaintext signing-key mode, and bootstrap secret printing. +The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, built-in AWS KMS, GCP Cloud KMS, and Azure Key Vault signing executors, gateway-backed `pkcs11-hsm` mode, OIDC discovery refresh, optional live OIDC UserInfo validation, an optional provider validation gateway, SSO credential exchange with session-scoped OIDC group-role mapping, public-transparency proof fetching, an optional transparency proof gateway, and optional worker-owned parser side effects are implemented, but native PKCS#11/HSM module handling, direct provider-specific management API clients, and external group synchronization remain deployment hardening work. Hand-tuned per-resource repository implementations remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, unsupported API writer modes or replica counts above one, local plaintext signing-key mode, and bootstrap secret printing. Evydence does not prove provider truth, scanner authority, runtime security, legal compliance, or release security by itself. diff --git a/docs/kubernetes.md b/docs/kubernetes.md index 6f463a3..adcd9eb 100644 --- a/docs/kubernetes.md +++ b/docs/kubernetes.md @@ -11,8 +11,8 @@ The Helm chart lives at `deploy/helm/evydence`. It deploys the API, worker, serv - A pre-created object-store bucket. - A Kubernetes secret containing at least `EVYDENCE_DATABASE_URL` and `EVYDENCE_API_KEY_PEPPER`. - A signing setup compatible with `EVYDENCE_SIGNING_KEY_MODE=external`, - `aws-kms`, or one of the gateway-backed provider profiles documented in the - configuration reference. + `aws-kms`, `gcp-kms`, `azure-key-vault`, or the gateway-backed `pkcs11-hsm` + profile documented in the configuration reference. The chart does not create databases, buckets, KMS keys, or secrets. @@ -53,7 +53,7 @@ Relevant chart values are defined in `deploy/helm/evydence/values.yaml`: | `env.apiKeyPepperSecretKey` | Secret key for `EVYDENCE_API_KEY_PEPPER`. | | `env.objectStore` | `s3` or `minio` for cluster deployments. | | `env.s3Endpoint`, `env.s3Bucket`, `env.s3Region`, `env.s3UseSSL` | Object-store configuration. | -| `env.signingKeyMode` | Production signing mode. Use `external`, `aws-kms`, or a gateway-backed provider profile. | +| `env.signingKeyMode` | Production signing mode. Use `external`, `aws-kms`, `gcp-kms`, `azure-key-vault`, or gateway-backed `pkcs11-hsm`. | | `ingress.*` | Optional ingress host and TLS secret. | ## Verify diff --git a/docs/production-hardening.md b/docs/production-hardening.md index 4d2a400..42fb202 100644 --- a/docs/production-hardening.md +++ b/docs/production-hardening.md @@ -9,8 +9,8 @@ Before labeling a deployment production, verify: - `ENV=production` is set. - `EVYDENCE_DATABASE_URL` points to external PostgreSQL. - `EVYDENCE_API_KEY_PEPPER` is a non-default random value. -- `EVYDENCE_SIGNING_KEY_MODE=external`, `aws-kms`, or a gateway-backed - provider profile such as `gcp-kms`, `azure-key-vault`, or `pkcs11-hsm` is set. +- `EVYDENCE_SIGNING_KEY_MODE=external`, `aws-kms`, `gcp-kms`, + `azure-key-vault`, or gateway-backed `pkcs11-hsm` is set. - `EVYDENCE_PRINT_BOOTSTRAP_SECRET` is unset or false. - Only one API writer replica is deployed; production API startup also enforces this with a PostgreSQL advisory writer lease. @@ -32,7 +32,7 @@ These checks are enforced by API startup. See [Configuration](reference/configur - Customer portal access tokens are short-lived, scoped to one package, and handled as bearer secrets. - Generated customer packages use explicit redaction profiles and expiry. - Collector releases are pinned and have signature, SBOM, and vulnerability scan evidence when available. -- Signing operations use either a tenant-controlled HTTPS signing gateway, an explicit gateway-backed provider profile, or the AWS KMS executor; raw evidence payload bytes are not sent to any signing executor by Evydence. +- Signing operations use either a tenant-controlled HTTPS signing gateway, AWS KMS, GCP Cloud KMS, Azure Key Vault, or gateway-backed PKCS#11/HSM profile; raw evidence payload bytes are not sent to any signing executor by Evydence. ## Backup And Restore Checklist diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index ed03a4f..c902cac 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -54,7 +54,7 @@ The example secrets are placeholders. Replace them before using shared or produc | `EVYDENCE_PROVIDER_VALIDATION_GATEWAY_TOKEN` | Gateway | unset | Optional bearer token for the provider validation gateway. Store outside source control and logs. | | `EVYDENCE_PROVIDER_VALIDATION_GATEWAY_TIMEOUT_SECONDS` | No | `10` | Timeout for provider validation gateway requests. | | `EVYDENCE_PROVIDER_VALIDATION_GATEWAY_ALLOW_INSECURE_LOCALHOST` | Local only | `false` | Allows an HTTP localhost gateway for tests. Do not use for production. | -| `EVYDENCE_SIGNING_KEY_MODE` | Production yes | `external`, `aws-kms`, `gcp-kms`, `azure-key-vault`, or `pkcs11-hsm` for production | Production rejects local plaintext signing-key mode. `aws-kms` uses the built-in AWS KMS executor. `gcp-kms`, `azure-key-vault`, and `pkcs11-hsm` are explicit HTTPS signing-gateway profiles and require `EVYDENCE_SIGNING_EXECUTOR_URL`. | +| `EVYDENCE_SIGNING_KEY_MODE` | Production yes | `external`, `aws-kms`, `gcp-kms`, `azure-key-vault`, or `pkcs11-hsm` for production | Production rejects local plaintext signing-key mode. `aws-kms`, `gcp-kms`, and `azure-key-vault` can use built-in provider executors. `pkcs11-hsm` remains an HTTPS signing-gateway profile. | | `EVYDENCE_SIGNING_EXECUTOR_URL` | No | unset | Optional HTTPS signing gateway used by `POST /v1/signing-operations` when `external_signature` is omitted. The API sends subject metadata and `payload_hash`, not raw payload bytes. | | `EVYDENCE_SIGNING_EXECUTOR_TOKEN` | Signing gateway | unset | Optional bearer token for the signing gateway. Store outside source control and logs. | | `EVYDENCE_SIGNING_EXECUTOR_TIMEOUT_SECONDS` | No | `10` | Timeout for signing gateway requests. | @@ -64,6 +64,17 @@ The example secrets are placeholders. Replace them before using shared or produc | `EVYDENCE_AWS_KMS_ENDPOINT` | No | unset | Optional AWS KMS-compatible endpoint for tests or controlled private endpoints. | | `EVYDENCE_AWS_KMS_SIGNING_ALGORITHM` | No | `ECDSA_SHA_256` | Supported values are `ECDSA_SHA_256`, `RSASSA_PSS_SHA_256`, and `RSASSA_PKCS1_V1_5_SHA_256` because Evydence signs stored SHA-256 payload hashes. | | `EVYDENCE_AWS_KMS_TIMEOUT_SECONDS` | No | `10` | Timeout for AWS KMS signing requests. | +| `EVYDENCE_GCP_KMS_ACCESS_TOKEN` | GCP KMS mode | unset | Bearer token used by the direct GCP Cloud KMS executor. Store outside source control and logs. If unset, `gcp-kms` requires `EVYDENCE_SIGNING_EXECUTOR_URL`. | +| `EVYDENCE_GCP_KMS_KEY_NAME` | GCP KMS mode | unset | Default GCP Cloud KMS key version resource name. A signing provider `key_ref` can override it. | +| `EVYDENCE_GCP_KMS_ENDPOINT` | No | `https://cloudkms.googleapis.com` | Optional GCP KMS endpoint for tests or controlled private endpoints. | +| `EVYDENCE_GCP_KMS_TIMEOUT_SECONDS` | No | `10` | Timeout for GCP KMS signing requests. | +| `EVYDENCE_AZURE_KEY_VAULT_URL` | Azure Key Vault mode | unset | HTTPS Key Vault URL used by the direct Azure Key Vault executor. | +| `EVYDENCE_AZURE_KEY_VAULT_ACCESS_TOKEN` | Azure Key Vault mode | unset | Bearer token used by the direct Azure Key Vault executor. Store outside source control and logs. If unset, `azure-key-vault` requires `EVYDENCE_SIGNING_EXECUTOR_URL`. | +| `EVYDENCE_AZURE_KEY_VAULT_KEY_NAME` | Azure Key Vault mode | unset | Default Key Vault key name. A signing provider `key_ref` URL can override it. | +| `EVYDENCE_AZURE_KEY_VAULT_KEY_VERSION` | Azure Key Vault mode | unset | Default Key Vault key version. A signing provider `key_ref` URL can override it. | +| `EVYDENCE_AZURE_KEY_VAULT_ALGORITHM` | No | `ES256` | Azure Key Vault signing algorithm used for the SHA-256 digest. | +| `EVYDENCE_AZURE_KEY_VAULT_API_VERSION` | No | `7.4` | Azure Key Vault API version. | +| `EVYDENCE_AZURE_KEY_VAULT_TIMEOUT_SECONDS` | No | `10` | Timeout for Azure Key Vault signing requests. | | `EVYDENCE_TRANSPARENCY_PROOF_GATEWAY_URL` | No | unset | Optional HTTPS operator-controlled gateway for transparency inclusion proof fetch/verification material. When unset, Evydence fetches from the configured public log endpoint. | | `EVYDENCE_TRANSPARENCY_PROOF_GATEWAY_TOKEN` | Gateway | unset | Optional bearer token for the transparency proof gateway. Store outside source control and logs. | | `EVYDENCE_TRANSPARENCY_PROOF_GATEWAY_TIMEOUT_SECONDS` | No | `10` | Timeout for transparency proof gateway requests. | @@ -77,8 +88,9 @@ When `ENV=production`, the API refuses to start unless: - `EVYDENCE_DATABASE_URL` is set. - `EVYDENCE_API_KEY_PEPPER` is non-empty and not the local default. - `EVYDENCE_SIGNING_KEY_MODE` is `external`, `aws-kms`, `gcp-kms`, - `azure-key-vault`, or `pkcs11-hsm`. The non-AWS provider modes require - `EVYDENCE_SIGNING_EXECUTOR_URL`. + `azure-key-vault`, or `pkcs11-hsm`. `pkcs11-hsm` requires + `EVYDENCE_SIGNING_EXECUTOR_URL`; `gcp-kms` and `azure-key-vault` require + either their direct provider credentials or `EVYDENCE_SIGNING_EXECUTOR_URL`. - `EVYDENCE_PRINT_BOOTSTRAP_SECRET` is not `true`. - `EVYDENCE_POSTGRES_LOAD_MODE`, when set, is `relational_only`. - `EVYDENCE_API_WRITER_MODE`, when set, is `single` or `single-writer`. @@ -128,11 +140,13 @@ gateway returns a signature, optional provider key id, and optional algorithm. Evydence records the signature receipt and verification checks; it does not store production private key material or send raw evidence payload bytes. -`EVYDENCE_SIGNING_KEY_MODE=gcp-kms`, `azure-key-vault`, or `pkcs11-hsm` makes -that gateway requirement explicit for deployments that keep non-AWS KMS/HSM -custody behind a tenant-controlled signing service. These modes are not direct -cloud-provider SDK adapters; operators remain responsible for provider -credentials, IAM, key lifecycle, gateway operation, and custody review. +`EVYDENCE_SIGNING_KEY_MODE=gcp-kms` and `azure-key-vault` can use direct +provider executors when their access-token and key configuration variables are +set. If direct credentials are absent, they fall back to requiring the HTTPS +signing gateway. `pkcs11-hsm` always uses the HTTPS signing gateway because +native HSM modules and slots are deployment-specific. Operators remain +responsible for provider credentials, IAM, key lifecycle, gateway operation +where used, and custody review. When `EVYDENCE_SIGNING_KEY_MODE=aws-kms`, Evydence uses the AWS KMS `Sign` operation against `EVYDENCE_AWS_KMS_KEY_ID`. The executor signs the decoded @@ -141,6 +155,18 @@ payload bytes to AWS KMS. Operators remain responsible for AWS IAM policy, key lifecycle, CloudTrail review, regional availability, and external review of whether the selected key custody profile satisfies their deployment needs. +When `EVYDENCE_SIGNING_KEY_MODE=gcp-kms`, Evydence can call GCP Cloud KMS +`asymmetricSign` with a configured bearer token and key-version resource name. +The executor sends a SHA-256 digest, not raw evidence payload bytes. Operators +remain responsible for GCP IAM, token issuance, audit logs, key lifecycle, and +regional availability. + +When `EVYDENCE_SIGNING_KEY_MODE=azure-key-vault`, Evydence can call Azure Key +Vault `sign` with a configured bearer token, key name, key version, and +algorithm. The executor sends a SHA-256 digest encoded for Key Vault, not raw +evidence payload bytes. Operators remain responsible for Azure identity, Key +Vault access policy/RBAC, audit logs, key lifecycle, and regional availability. + ## Provider Validation Gateway When `EVYDENCE_PROVIDER_VALIDATION_GATEWAY_URL` is set, provider identity diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 4a7922b..f296eda 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -61,11 +61,11 @@ Known hardening work remains: - OpenAPI precision is enforced across the registered public API. The generated matrix remains the source of truth for operation ids, scopes, idempotency, parameters, and request/response schemas; -- production signing can use the HTTPS signing gateway executor, explicit - gateway-backed `gcp-kms`, `azure-key-vault`, and `pkcs11-hsm` modes, or the - built-in AWS KMS signing executor, but direct non-AWS cloud KMS/HSM SDK adapters, - direct provider-specific management API clients/group synchronization, and - broad object-lock enforcement proof beyond bucket plus sample-object +- production signing can use the HTTPS signing gateway executor, built-in AWS + KMS, GCP Cloud KMS, Azure Key Vault signing executors, or gateway-backed + `pkcs11-hsm`, but native PKCS#11/HSM module custody, direct + provider-specific management API clients/group synchronization, and broad + object-lock enforcement proof beyond bucket plus sample-object retention/legal-hold checks remain provider- and deployment-dependent hardening areas. SSO credential exchange can issue bearer sessions and HttpOnly cookies after local OIDC/SAML verification against configured trust @@ -208,12 +208,11 @@ implemented capabilities: PostgreSQL store supports them. - Keep OpenAPI precision at zero broad operations as routes are added or changed, and expand generated SDK coverage from the committed contract. -- Add direct cloud KMS/HSM SDK adapters where required beyond AWS KMS. The - current HTTPS signing gateway executor and explicit `gcp-kms`, - `azure-key-vault`, and `pkcs11-hsm` gateway-backed modes cover deployments - that put KMS/HSM custody behind a tenant-controlled signing service and do - not send raw payload bytes; the AWS KMS executor signs stored SHA-256 payload - hashes with KMS `MessageType=DIGEST`. +- Add native PKCS#11/HSM module support where required by the deployment + profile. The current HTTPS signing gateway executor covers deployments that + put HSM custody behind a tenant-controlled signing service and do not send raw + payload bytes. AWS KMS, GCP Cloud KMS, and Azure Key Vault direct executors + sign stored SHA-256 payload hashes through their provider APIs. - Complete direct provider-specific management API clients and external group synchronization where those profiles are enabled. OIDC discovery/JWKS refresh is implemented for public trust-material updates, manual JWKS and SAML diff --git a/docs/reference/release-candidate.md b/docs/reference/release-candidate.md index 192743c..9e22a10 100644 --- a/docs/reference/release-candidate.md +++ b/docs/reference/release-candidate.md @@ -64,7 +64,7 @@ production, and hosted SaaS production require additional review and controls. - Use external PostgreSQL, external object storage, TLS ingress, non-default API-key pepper, externalized secrets, backup and restore rehearsal, monitoring, and documented incident response. -- Keep service decomposition, HA/multi-writer operation, non-AWS KMS/HSM SDK - adapters, provider-specific management API/group synchronization, and broader +- Keep service decomposition, HA/multi-writer operation, native PKCS#11/HSM + modules, provider-specific management API/group synchronization, and broader object-lock proof beyond configured bucket/sample-object checks listed as unresolved hardening work until they are implemented and verified. diff --git a/docs/reference/release-notes-template.md b/docs/reference/release-notes-template.md index 2e9ab60..6e2fee2 100644 --- a/docs/reference/release-notes-template.md +++ b/docs/reference/release-notes-template.md @@ -32,8 +32,9 @@ acceptance. - Use S3/MinIO-compatible object storage or the documented filesystem mode for local evaluation only. - Set `ENV=production`, a non-default `EVYDENCE_API_KEY_PEPPER`, and a - production signing mode such as `external`, `aws-kms`, or an explicit - gateway-backed provider profile for production-profile startup. + production signing mode such as `external`, `aws-kms`, `gcp-kms`, + `azure-key-vault`, or gateway-backed `pkcs11-hsm` for production-profile + startup. - Apply all committed migrations before starting API or worker processes. - For Kubernetes, set an explicit image tag or digest and keep API replicas at `1` until HA/multi-writer support is reviewed. @@ -44,9 +45,8 @@ acceptance. PostgreSQL writes cover the highest-risk runtime mutations, but not every resource family. - HA/multi-writer API operation is not supported in this profile. -- The AWS KMS signing executor and explicit gateway-backed non-AWS KMS/HSM - profiles are included; direct non-AWS cloud KMS/HSM SDK adapters are not - included. +- AWS KMS, GCP Cloud KMS, and Azure Key Vault signing executors are included; + native PKCS#11/HSM modules remain gateway-backed and deployment-specific. - OIDC UserInfo validation is available when a caller supplies an access token; provider-specific management API validation and external group synchronization remain deployment-dependent. diff --git a/docs/reference/release-notes-v0.1.0-rc.1.md b/docs/reference/release-notes-v0.1.0-rc.1.md index 5c0d12e..8cca69b 100644 --- a/docs/reference/release-notes-v0.1.0-rc.1.md +++ b/docs/reference/release-notes-v0.1.0-rc.1.md @@ -32,8 +32,9 @@ acceptance. - Use S3/MinIO-compatible object storage or the documented filesystem mode for local evaluation only. - Set `ENV=production`, a non-default `EVYDENCE_API_KEY_PEPPER`, and a - production signing mode such as `external`, `aws-kms`, or an explicit - gateway-backed provider profile for production-profile startup. + production signing mode such as `external`, `aws-kms`, `gcp-kms`, + `azure-key-vault`, or gateway-backed `pkcs11-hsm` for production-profile + startup. - Apply all committed migrations before starting API or worker processes. - For Kubernetes, set an explicit image tag or digest and keep API replicas at `1` until HA/multi-writer support is reviewed. @@ -44,9 +45,8 @@ acceptance. PostgreSQL writes cover the highest-risk runtime mutations, but not every resource family. - HA/multi-writer API operation is not supported in this profile. -- The AWS KMS signing executor and explicit gateway-backed non-AWS KMS/HSM - profiles are included; direct non-AWS cloud KMS/HSM SDK adapters are not - included. +- AWS KMS, GCP Cloud KMS, and Azure Key Vault signing executors are included; + native PKCS#11/HSM modules remain gateway-backed and deployment-specific. - OIDC UserInfo validation is available when a caller supplies an access token; provider-specific management API validation and external group synchronization remain deployment-dependent. diff --git a/internal/adapters/signing/azurekeyvault/azurekeyvault.go b/internal/adapters/signing/azurekeyvault/azurekeyvault.go new file mode 100644 index 0000000..22d5845 --- /dev/null +++ b/internal/adapters/signing/azurekeyvault/azurekeyvault.go @@ -0,0 +1,213 @@ +package azurekeyvault + +import ( + "bytes" + "context" + "encoding/base64" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "strings" + "time" + + "github.com/aatuh/evydence/internal/app" + "github.com/aatuh/evydence/internal/domain" +) + +const ( + defaultAPIVersion = "7.4" + defaultAlgorithm = "ES256" + defaultTimeout = 10 * time.Second +) + +type Config struct { + VaultURL string + AccessToken string + KeyName string + KeyVersion string + Algorithm string + APIVersion string + Timeout time.Duration + Client *http.Client +} + +type Executor struct { + vaultURL string + accessToken string + keyName string + keyVersion string + algorithm string + apiVersion string + client *http.Client +} + +type signRequest struct { + Algorithm string `json:"alg"` + Value string `json:"value"` +} + +type signResponse struct { + KeyID string `json:"kid,omitempty"` + Value string `json:"value"` +} + +func New(cfg Config) (*Executor, error) { + vaultURL := strings.TrimRight(strings.TrimSpace(cfg.VaultURL), "/") + if vaultURL == "" { + return nil, app.ErrValidation + } + parsed, err := url.Parse(vaultURL) + if err != nil || parsed.Scheme != "https" || parsed.Host == "" || parsed.User != nil { + return nil, app.ErrValidation + } + if strings.TrimSpace(cfg.AccessToken) == "" { + return nil, errors.New("configure Azure Key Vault access token") + } + algorithm := strings.TrimSpace(cfg.Algorithm) + if algorithm == "" { + algorithm = defaultAlgorithm + } + apiVersion := strings.TrimSpace(cfg.APIVersion) + if apiVersion == "" { + apiVersion = defaultAPIVersion + } + timeout := cfg.Timeout + if timeout <= 0 { + timeout = defaultTimeout + } + client := cfg.Client + if client == nil { + client = &http.Client{Timeout: timeout} + } + return &Executor{ + vaultURL: vaultURL, + accessToken: strings.TrimSpace(cfg.AccessToken), + keyName: strings.TrimSpace(cfg.KeyName), + keyVersion: strings.TrimSpace(cfg.KeyVersion), + algorithm: algorithm, + apiVersion: apiVersion, + client: client, + }, nil +} + +func (e *Executor) Sign(ctx context.Context, req app.SigningRequest) (app.SigningResult, error) { + if e == nil || e.client == nil { + return app.SigningResult{}, app.ErrValidation + } + if providerType := strings.TrimSpace(req.ProviderType); providerType != "" && providerType != "azure_key_vault" { + return app.SigningResult{}, app.ErrValidation + } + digest, err := decodePayloadHash(req.PayloadHash) + if err != nil { + return app.SigningResult{}, err + } + vaultURL, keyName, keyVersion, err := e.resolveKey(req.KeyRef) + if err != nil { + return app.SigningResult{}, err + } + body, err := json.Marshal(signRequest{Algorithm: e.algorithm, Value: base64.RawURLEncoding.EncodeToString(digest)}) + if err != nil { + return app.SigningResult{}, app.ErrValidation + } + signURL := fmt.Sprintf("%s/keys/%s/%s/sign?api-version=%s", vaultURL, url.PathEscape(keyName), url.PathEscape(keyVersion), url.QueryEscape(e.apiVersion)) + httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, signURL, bytes.NewReader(body)) + if err != nil { + return app.SigningResult{}, app.ErrValidation + } + httpReq.Header.Set("Accept", "application/json") + httpReq.Header.Set("Content-Type", "application/json") + httpReq.Header.Set("Authorization", "Bearer "+e.accessToken) + resp, err := e.client.Do(httpReq) + if err != nil { + return app.SigningResult{}, errors.New("execute Azure Key Vault signing request") + } + defer resp.Body.Close() + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + _, _ = io.Copy(io.Discard, io.LimitReader(resp.Body, 4096)) + return app.SigningResult{}, fmt.Errorf("azure Key Vault signing request returned status %d", resp.StatusCode) + } + var decoded signResponse + decoder := json.NewDecoder(io.LimitReader(resp.Body, 1<<20)) + decoder.DisallowUnknownFields() + if err := decoder.Decode(&decoded); err != nil { + return app.SigningResult{}, errors.New("decode Azure Key Vault signing response") + } + signature, err := normalizeBase64URLSignature(decoded.Value) + if err != nil || len(signature) > 32768 { + return app.SigningResult{}, app.ErrValidation + } + return app.SigningResult{ + Signature: signature, + KeyID: firstNonEmpty(strings.TrimSpace(decoded.KeyID), vaultURL+"/keys/"+keyName+"/"+keyVersion), + Algorithm: "azure-key-vault:" + e.algorithm, + Checks: []domain.VerifyCheck{ + {Name: "azure_key_vault_signature_returned", Result: "passed", Detail: "Azure Key Vault returned a signature over the submitted SHA-256 digest."}, + }, + }, nil +} + +func (e *Executor) resolveKey(keyRef string) (string, string, string, error) { + keyRef = strings.TrimSpace(keyRef) + if keyRef != "" && strings.HasPrefix(keyRef, "https://") { + parsed, err := url.Parse(keyRef) + if err != nil || parsed.Scheme != "https" || parsed.Host == "" || parsed.User != nil { + return "", "", "", app.ErrValidation + } + parts := strings.Split(strings.Trim(parsed.Path, "/"), "/") + if len(parts) < 3 || parts[0] != "keys" || !validSegment(parts[1]) || !validSegment(parts[2]) { + return "", "", "", app.ErrValidation + } + return parsed.Scheme + "://" + parsed.Host, parts[1], parts[2], nil + } + keyName := firstNonEmpty(keyRef, e.keyName) + keyVersion := e.keyVersion + if !validSegment(keyName) || !validSegment(keyVersion) { + return "", "", "", app.ErrValidation + } + return e.vaultURL, keyName, keyVersion, nil +} + +func decodePayloadHash(value string) ([]byte, error) { + value = strings.TrimSpace(value) + if !strings.HasPrefix(value, "sha256:") { + return nil, app.ErrValidation + } + raw, err := hex.DecodeString(strings.TrimPrefix(value, "sha256:")) + if err != nil || len(raw) != 32 { + return nil, app.ErrValidation + } + return raw, nil +} + +func normalizeBase64URLSignature(value string) (string, error) { + value = strings.TrimSpace(value) + if value == "" { + return "", app.ErrValidation + } + raw, err := base64.RawURLEncoding.DecodeString(value) + if err != nil { + raw, err = base64.URLEncoding.DecodeString(value) + } + if err != nil || len(raw) == 0 { + return "", app.ErrValidation + } + return base64.StdEncoding.EncodeToString(raw), nil +} + +func validSegment(value string) bool { + value = strings.TrimSpace(value) + return value != "" && !strings.ContainsAny(value, "/?#") && !strings.Contains(value, "..") +} + +func firstNonEmpty(values ...string) string { + for _, value := range values { + if strings.TrimSpace(value) != "" { + return strings.TrimSpace(value) + } + } + return "" +} diff --git a/internal/adapters/signing/azurekeyvault/azurekeyvault_test.go b/internal/adapters/signing/azurekeyvault/azurekeyvault_test.go new file mode 100644 index 0000000..bb503fe --- /dev/null +++ b/internal/adapters/signing/azurekeyvault/azurekeyvault_test.go @@ -0,0 +1,100 @@ +package azurekeyvault + +import ( + "encoding/base64" + "encoding/json" + "net/http" + "net/http/httptest" + "strings" + "testing" + + "github.com/aatuh/evydence/internal/app" +) + +func TestSignSendsDigestOnlyToAzureKeyVault(t *testing.T) { + var gotAuth string + var gotPath string + var gotQuery string + var gotRequest signRequest + server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + gotAuth = r.Header.Get("Authorization") + gotPath = r.URL.Path + gotQuery = r.URL.RawQuery + if err := json.NewDecoder(r.Body).Decode(&gotRequest); err != nil { + t.Fatal(err) + } + _ = json.NewEncoder(w).Encode(signResponse{KeyID: serverKeyID(r), Value: base64.RawURLEncoding.EncodeToString([]byte("sig"))}) + })) + defer server.Close() + + executor, err := New(Config{VaultURL: server.URL, AccessToken: "access-token", KeyName: "evydence", KeyVersion: "v1", Algorithm: "ES256", Client: server.Client()}) + if err != nil { + t.Fatal(err) + } + result, err := executor.Sign(t.Context(), app.SigningRequest{ProviderType: "azure_key_vault", PayloadHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}) + if err != nil { + t.Fatal(err) + } + if gotAuth != "Bearer access-token" { + t.Fatalf("authorization = %q", gotAuth) + } + if gotPath != "/keys/evydence/v1/sign" || gotQuery != "api-version=7.4" { + t.Fatalf("path/query = %q?%q", gotPath, gotQuery) + } + if gotRequest.Algorithm != "ES256" || gotRequest.Value != base64.RawURLEncoding.EncodeToString(bytesOf(0xaa, 32)) { + t.Fatalf("request = %#v", gotRequest) + } + if result.Signature != base64.StdEncoding.EncodeToString([]byte("sig")) || result.Algorithm != "azure-key-vault:ES256" || len(result.Checks) == 0 { + t.Fatalf("result = %#v", result) + } +} + +func TestSignCanUseKeyRefURL(t *testing.T) { + server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/keys/from-ref/v2/sign" { + t.Fatalf("path = %s", r.URL.Path) + } + _ = json.NewEncoder(w).Encode(signResponse{Value: base64.RawURLEncoding.EncodeToString([]byte("sig"))}) + })) + defer server.Close() + + executor, err := New(Config{VaultURL: "https://unused.example.test", AccessToken: "access-token", KeyName: "evydence", KeyVersion: "v1", Client: server.Client()}) + if err != nil { + t.Fatal(err) + } + _, err = executor.Sign(t.Context(), app.SigningRequest{ProviderType: "azure_key_vault", KeyRef: server.URL + "/keys/from-ref/v2", PayloadHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}) + if err != nil { + t.Fatal(err) + } +} + +func TestSignRejectsWrongProviderType(t *testing.T) { + executor, err := New(Config{VaultURL: "https://vault.example.test", AccessToken: "token", KeyName: "evydence", KeyVersion: "v1"}) + if err != nil { + t.Fatal(err) + } + if _, err := executor.Sign(t.Context(), app.SigningRequest{ProviderType: "gcp_kms", PayloadHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}); err == nil { + t.Fatal("expected wrong provider type to be rejected") + } +} + +func TestNewRequiresHTTPSAndAccessToken(t *testing.T) { + if _, err := New(Config{VaultURL: "http://vault.example.test", AccessToken: "token"}); err == nil { + t.Fatal("expected non-HTTPS vault URL to be rejected") + } + if _, err := New(Config{VaultURL: "https://vault.example.test"}); err == nil { + t.Fatal("expected missing access token to be rejected") + } +} + +func serverKeyID(r *http.Request) string { + return "https://" + r.Host + strings.TrimSuffix(r.URL.Path, "/sign") +} + +func bytesOf(value byte, count int) []byte { + out := make([]byte, count) + for i := range out { + out[i] = value + } + return out +} diff --git a/internal/adapters/signing/gcpkms/gcpkms.go b/internal/adapters/signing/gcpkms/gcpkms.go new file mode 100644 index 0000000..d8b77e0 --- /dev/null +++ b/internal/adapters/signing/gcpkms/gcpkms.go @@ -0,0 +1,165 @@ +package gcpkms + +import ( + "bytes" + "context" + "encoding/base64" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "strings" + "time" + + "github.com/aatuh/evydence/internal/app" + "github.com/aatuh/evydence/internal/domain" +) + +const ( + defaultEndpoint = "https://cloudkms.googleapis.com" + defaultTimeout = 10 * time.Second +) + +type Config struct { + Endpoint string + AccessToken string + KeyName string + Timeout time.Duration + Client *http.Client +} + +type Executor struct { + endpoint string + accessToken string + keyName string + client *http.Client +} + +type signRequest struct { + Digest digestValue `json:"digest"` +} + +type digestValue struct { + SHA256 string `json:"sha256"` +} + +type signResponse struct { + Signature string `json:"signature"` + Name string `json:"name,omitempty"` +} + +func New(cfg Config) (*Executor, error) { + endpoint := strings.TrimRight(strings.TrimSpace(cfg.Endpoint), "/") + if endpoint == "" { + endpoint = defaultEndpoint + } + parsed, err := url.Parse(endpoint) + if err != nil || parsed.Scheme != "https" || parsed.Host == "" || parsed.User != nil { + return nil, app.ErrValidation + } + if strings.TrimSpace(cfg.AccessToken) == "" { + return nil, errors.New("configure GCP KMS access token") + } + timeout := cfg.Timeout + if timeout <= 0 { + timeout = defaultTimeout + } + client := cfg.Client + if client == nil { + client = &http.Client{Timeout: timeout} + } + return &Executor{ + endpoint: endpoint, + accessToken: strings.TrimSpace(cfg.AccessToken), + keyName: strings.TrimSpace(cfg.KeyName), + client: client, + }, nil +} + +func (e *Executor) Sign(ctx context.Context, req app.SigningRequest) (app.SigningResult, error) { + if e == nil || e.client == nil { + return app.SigningResult{}, app.ErrValidation + } + if providerType := strings.TrimSpace(req.ProviderType); providerType != "" && providerType != "gcp_kms" { + return app.SigningResult{}, app.ErrValidation + } + digest, err := decodePayloadHash(req.PayloadHash) + if err != nil { + return app.SigningResult{}, err + } + keyName := strings.TrimSpace(req.KeyRef) + if keyName == "" { + keyName = e.keyName + } + if !validKeyName(keyName) { + return app.SigningResult{}, app.ErrValidation + } + body, err := json.Marshal(signRequest{Digest: digestValue{SHA256: base64.StdEncoding.EncodeToString(digest)}}) + if err != nil { + return app.SigningResult{}, app.ErrValidation + } + signURL := e.endpoint + "/v1/" + strings.TrimLeft(keyName, "/") + ":asymmetricSign" + httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, signURL, bytes.NewReader(body)) + if err != nil { + return app.SigningResult{}, app.ErrValidation + } + httpReq.Header.Set("Accept", "application/json") + httpReq.Header.Set("Content-Type", "application/json") + httpReq.Header.Set("Authorization", "Bearer "+e.accessToken) + resp, err := e.client.Do(httpReq) + if err != nil { + return app.SigningResult{}, errors.New("execute GCP KMS signing request") + } + defer resp.Body.Close() + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + _, _ = io.Copy(io.Discard, io.LimitReader(resp.Body, 4096)) + return app.SigningResult{}, fmt.Errorf("gcp KMS signing request returned status %d", resp.StatusCode) + } + var decoded signResponse + decoder := json.NewDecoder(io.LimitReader(resp.Body, 1<<20)) + decoder.DisallowUnknownFields() + if err := decoder.Decode(&decoded); err != nil { + return app.SigningResult{}, errors.New("decode GCP KMS signing response") + } + decoded.Signature = strings.TrimSpace(decoded.Signature) + if decoded.Signature == "" || len(decoded.Signature) > 32768 { + return app.SigningResult{}, app.ErrValidation + } + return app.SigningResult{ + Signature: decoded.Signature, + KeyID: firstNonEmpty(strings.TrimSpace(decoded.Name), keyName), + Algorithm: "gcp-kms:asymmetric-sign-sha256", + Checks: []domain.VerifyCheck{ + {Name: "gcp_kms_signature_returned", Result: "passed", Detail: "GCP Cloud KMS returned a signature over the submitted SHA-256 digest."}, + }, + }, nil +} + +func decodePayloadHash(value string) ([]byte, error) { + value = strings.TrimSpace(value) + if !strings.HasPrefix(value, "sha256:") { + return nil, app.ErrValidation + } + raw, err := hex.DecodeString(strings.TrimPrefix(value, "sha256:")) + if err != nil || len(raw) != 32 { + return nil, app.ErrValidation + } + return raw, nil +} + +func validKeyName(value string) bool { + value = strings.TrimSpace(value) + return value != "" && !strings.ContainsAny(value, "?#") && !strings.Contains(value, "..") +} + +func firstNonEmpty(values ...string) string { + for _, value := range values { + if strings.TrimSpace(value) != "" { + return strings.TrimSpace(value) + } + } + return "" +} diff --git a/internal/adapters/signing/gcpkms/gcpkms_test.go b/internal/adapters/signing/gcpkms/gcpkms_test.go new file mode 100644 index 0000000..077816f --- /dev/null +++ b/internal/adapters/signing/gcpkms/gcpkms_test.go @@ -0,0 +1,79 @@ +package gcpkms + +import ( + "encoding/base64" + "encoding/json" + "net/http" + "net/http/httptest" + "strings" + "testing" + + "github.com/aatuh/evydence/internal/app" +) + +func TestSignSendsDigestOnlyToGCPKMS(t *testing.T) { + var gotAuth string + var gotPath string + var gotRequest signRequest + server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + gotAuth = r.Header.Get("Authorization") + gotPath = r.URL.Path + if err := json.NewDecoder(r.Body).Decode(&gotRequest); err != nil { + t.Fatal(err) + } + _ = json.NewEncoder(w).Encode(signResponse{Signature: base64.StdEncoding.EncodeToString([]byte("sig")), Name: "projects/p/locations/l/keyRings/r/cryptoKeys/k/cryptoKeyVersions/1"}) + })) + defer server.Close() + + executor, err := New(Config{Endpoint: server.URL, AccessToken: "access-token", Client: server.Client()}) + if err != nil { + t.Fatal(err) + } + result, err := executor.Sign(t.Context(), app.SigningRequest{ + ProviderType: "gcp_kms", + KeyRef: "projects/p/locations/l/keyRings/r/cryptoKeys/k/cryptoKeyVersions/1", + PayloadHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + }) + if err != nil { + t.Fatal(err) + } + if gotAuth != "Bearer access-token" { + t.Fatalf("authorization = %q", gotAuth) + } + if !strings.HasSuffix(gotPath, ":asymmetricSign") || !strings.Contains(gotPath, "/v1/projects/p/") { + t.Fatalf("path = %q", gotPath) + } + if gotRequest.Digest.SHA256 != base64.StdEncoding.EncodeToString(bytesOf(0xaa, 32)) { + t.Fatalf("digest = %q", gotRequest.Digest.SHA256) + } + if result.Signature == "" || result.Algorithm != "gcp-kms:asymmetric-sign-sha256" || len(result.Checks) == 0 { + t.Fatalf("result = %#v", result) + } +} + +func TestSignRejectsWrongProviderType(t *testing.T) { + executor, err := New(Config{Endpoint: "https://kms.example.test", AccessToken: "token", KeyName: "projects/p/locations/l/keyRings/r/cryptoKeys/k/cryptoKeyVersions/1"}) + if err != nil { + t.Fatal(err) + } + if _, err := executor.Sign(t.Context(), app.SigningRequest{ProviderType: "aws_kms", PayloadHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}); err == nil { + t.Fatal("expected wrong provider type to be rejected") + } +} + +func TestNewRequiresHTTPSAndAccessToken(t *testing.T) { + if _, err := New(Config{Endpoint: "http://kms.example.test", AccessToken: "token"}); err == nil { + t.Fatal("expected non-HTTPS endpoint to be rejected") + } + if _, err := New(Config{Endpoint: "https://kms.example.test"}); err == nil { + t.Fatal("expected missing access token to be rejected") + } +} + +func bytesOf(value byte, count int) []byte { + out := make([]byte, count) + for i := range out { + out[i] = value + } + return out +} From 2d7d25e7e73022608af66efd65296c0a44a74172 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 16:07:52 +0300 Subject: [PATCH 145/287] docs: prepare controlled production candidate materials --- .github/ISSUE_TEMPLATE/bug_report.yml | 69 +++++++ .github/ISSUE_TEMPLATE/config.yml | 8 + .github/ISSUE_TEMPLATE/docs.yml | 30 +++ .github/ISSUE_TEMPLATE/feature_request.yml | 47 +++++ .github/ISSUE_TEMPLATE/production_support.yml | 41 ++++ .github/dependabot.yml | 26 +++ .github/workflows/scorecard.yml | 34 ++++ CHANGELOG.md | 43 ++++- CODE_OF_CONDUCT.md | 36 ++++ Dockerfile | 2 + Makefile | 16 ++ README.md | 73 ++++++- SECURITY.md | 24 ++- compose.production-like.yml | 118 ++++++++++++ docs/README.md | 12 ++ docs/explanation/architecture-diagram.md | 42 ++++ docs/how-to/install-and-operate.md | 26 +++ docs/how-to/view-packages.md | 22 +++ docs/operations.md | 8 + docs/reference/benchmark-results.md | 54 ++++++ docs/reference/capacity-and-failures.md | 58 ++++++ docs/reference/production-exit-review.md | 51 +++++ docs/reference/production-readiness.md | 3 + docs/reference/release-candidate.md | 5 +- docs/reference/release-notes-template.md | 4 + docs/reference/release-notes-v0.1.0-rc.1.md | 4 + docs/reference/release-validation.md | 10 +- docs/reference/source-of-truth.md | 37 ++++ docs/runbooks/backup-restore.md | 60 ++++++ docs/runbooks/incident-response.md | 51 +++++ docs/runbooks/upgrade.md | 44 +++++ docs/sdk/README.md | 9 + .../end-to-end-release-evidence/README.md | 61 ++++++ .../release-evidence-manifest.json | 54 ++++++ .../run-local-demo.sh | 66 +++++++ .../sample-audit-chain-verification.json | 19 ++ .../sample-customer-package-manifest.json | 23 +++ .../sample-readiness-report.json | 32 +++ examples/sdk/go/main.go | 131 +++++++++++++ examples/sdk/go/main_test.go | 130 +++++++++++++ examples/sdk/python/example.py | 77 ++++++++ examples/sdk/typescript/example.ts | 64 ++++++ scripts/release_candidate_package.sh | 5 + scripts/release_candidate_validate.sh | 4 + scripts/release_evidence_metadata.py | 144 ++++++++++++++ site/package-viewer/index.html | 182 ++++++++++++++++++ 46 files changed, 2038 insertions(+), 21 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/docs.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml create mode 100644 .github/ISSUE_TEMPLATE/production_support.yml create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/scorecard.yml create mode 100644 CODE_OF_CONDUCT.md create mode 100644 compose.production-like.yml create mode 100644 docs/explanation/architecture-diagram.md create mode 100644 docs/how-to/view-packages.md create mode 100644 docs/reference/benchmark-results.md create mode 100644 docs/reference/capacity-and-failures.md create mode 100644 docs/reference/production-exit-review.md create mode 100644 docs/reference/source-of-truth.md create mode 100644 docs/runbooks/backup-restore.md create mode 100644 docs/runbooks/incident-response.md create mode 100644 docs/runbooks/upgrade.md create mode 100644 examples/end-to-end-release-evidence/README.md create mode 100644 examples/end-to-end-release-evidence/release-evidence-manifest.json create mode 100755 examples/end-to-end-release-evidence/run-local-demo.sh create mode 100644 examples/end-to-end-release-evidence/sample-audit-chain-verification.json create mode 100644 examples/end-to-end-release-evidence/sample-customer-package-manifest.json create mode 100644 examples/end-to-end-release-evidence/sample-readiness-report.json create mode 100644 examples/sdk/go/main.go create mode 100644 examples/sdk/go/main_test.go create mode 100644 examples/sdk/python/example.py create mode 100644 examples/sdk/typescript/example.ts create mode 100755 scripts/release_evidence_metadata.py create mode 100644 site/package-viewer/index.html diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..1ba0b59 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,69 @@ +name: Bug report +description: Report a reproducible Evydence defect without sharing secrets or raw evidence. +title: "bug: " +labels: ["bug", "triage"] +body: + - type: markdown + attributes: + value: | + Do not include API keys, bearer tokens, session tokens, private keys, + provider credentials, database URLs, raw evidence payloads, customer + data, or unredacted customer package contents. Use the private security + intake in SECURITY.md for suspected vulnerabilities. + - type: input + id: version + attributes: + label: Version or commit + description: Commit SHA, tag, image digest, or chart version. + placeholder: 842fb053f303b2a78eb3118be6a4536715571215 + validations: + required: true + - type: dropdown + id: area + attributes: + label: Area + options: + - API + - CLI + - Worker/outbox + - PostgreSQL/migrations + - Object storage + - Signing/verification + - Reports/packages + - Deployment/Helm/Docker + - Documentation + - Other + validations: + required: true + - type: textarea + id: expected + attributes: + label: Expected behavior + validations: + required: true + - type: textarea + id: observed + attributes: + label: Observed behavior + description: Sanitize logs and redact sensitive values. + validations: + required: true + - type: textarea + id: reproduce + attributes: + label: Reproduction steps + description: Include exact commands, API paths, or configuration names when safe. + validations: + required: true + - type: textarea + id: validation + attributes: + label: Checks already run + placeholder: make test, make docs-check, make production-check + - type: checkboxes + id: safety + attributes: + label: Safety confirmation + options: + - label: I have not included secrets, raw evidence payloads, private keys, bearer tokens, provider credentials, database URLs, or customer data. + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..ae12cb9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: Security vulnerability + url: https://github.com/aatuh/evydence/security + about: Use the private security intake described in SECURITY.md. Do not post suspected vulnerabilities publicly. + - name: Support policy + url: https://github.com/aatuh/evydence/blob/master/SUPPORT.md + about: Read support boundaries and sanitized-report expectations before opening an issue. diff --git a/.github/ISSUE_TEMPLATE/docs.yml b/.github/ISSUE_TEMPLATE/docs.yml new file mode 100644 index 0000000..9267eae --- /dev/null +++ b/.github/ISSUE_TEMPLATE/docs.yml @@ -0,0 +1,30 @@ +name: Documentation issue +description: Report unclear, stale, missing, or misleading documentation. +title: "docs: " +labels: ["documentation", "triage"] +body: + - type: input + id: path + attributes: + label: Document path + placeholder: docs/tutorials/getting-started.md + validations: + required: true + - type: textarea + id: problem + attributes: + label: What is wrong or missing? + description: Include the exact command, section, or expectation that did not match reality. + validations: + required: true + - type: textarea + id: fix + attributes: + label: Suggested correction + - type: checkboxes + id: claims + attributes: + label: Claim safety + options: + - label: This issue does not ask Evydence to claim legal compliance, certification, complete SBOM coverage, authoritative scanner results, or secure releases. + required: true diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..aa0f103 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,47 @@ +name: Feature request +description: Propose a focused Evydence capability or integration. +title: "feat: " +labels: ["enhancement", "triage"] +body: + - type: textarea + id: problem + attributes: + label: Problem + description: What release-evidence, compliance-readiness, or operator workflow is blocked? + validations: + required: true + - type: textarea + id: proposal + attributes: + label: Proposed behavior + description: Describe the smallest useful capability. + validations: + required: true + - type: dropdown + id: boundary + attributes: + label: Trust boundary affected + options: + - API + - Tenant isolation/authz + - File upload/object storage + - Signing/verification + - Provider/collector integration + - Reports/packages/exports + - Deployment/operations + - Documentation only + - Other + validations: + required: true + - type: textarea + id: validation + attributes: + label: Acceptance test idea + description: What command, API flow, or report would prove the feature works? + - type: checkboxes + id: scope + attributes: + label: Scope confirmation + options: + - label: This request supports compliance readiness or technical evidence organization without asking for legal compliance, certification, or secure-release guarantees. + required: true diff --git a/.github/ISSUE_TEMPLATE/production_support.yml b/.github/ISSUE_TEMPLATE/production_support.yml new file mode 100644 index 0000000..bff1fa0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/production_support.yml @@ -0,0 +1,41 @@ +name: Production support question +description: Ask a non-sensitive self-hosting or operations question. +title: "ops: " +labels: ["operations", "triage"] +body: + - type: markdown + attributes: + value: | + Public issues are not a private support channel. Do not include secrets, + raw evidence payloads, customer data, private keys, bearer tokens, + database URLs, or provider credentials. + - type: dropdown + id: profile + attributes: + label: Deployment profile + options: + - Local evaluation + - Controlled internal self-hosted candidate + - Air-gapped self-hosted candidate + - Regulated self-hosted review + - Other + validations: + required: true + - type: textarea + id: question + attributes: + label: Question + validations: + required: true + - type: textarea + id: sanitized_config + attributes: + label: Sanitized configuration summary + description: Use variable names and redacted values only. + - type: checkboxes + id: safety + attributes: + label: Safety confirmation + options: + - label: I have redacted all secrets, raw payloads, customer data, bearer tokens, private keys, provider credentials, and database URLs. + required: true diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..dc046eb --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,26 @@ +version: 2 +updates: + - package-ecosystem: gomod + directory: / + schedule: + interval: weekly + open-pull-requests-limit: 5 + labels: + - dependencies + - go + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + open-pull-requests-limit: 5 + labels: + - dependencies + - github-actions + - package-ecosystem: docker + directory: / + schedule: + interval: weekly + open-pull-requests-limit: 5 + labels: + - dependencies + - docker diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml new file mode 100644 index 0000000..1ef2310 --- /dev/null +++ b/.github/workflows/scorecard.yml @@ -0,0 +1,34 @@ +name: OpenSSF Scorecard + +on: + branch_protection_rule: + schedule: + - cron: "37 3 * * 1" + workflow_dispatch: + +permissions: + contents: read + security-events: write + id-token: write + +jobs: + scorecard: + name: Scorecard + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@v5 + with: + persist-credentials: false + + - name: Run OpenSSF Scorecard + uses: ossf/scorecard-action@v2.4.0 + with: + results_file: scorecard-results.sarif + results_format: sarif + publish_results: true + + - name: Upload SARIF + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: scorecard-results.sarif diff --git a/CHANGELOG.md b/CHANGELOG.md index 28a54c1..ae2bce8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,48 @@ results, no secure-release guarantee, and no regulator or auditor acceptance. ## Unreleased -No public release notes have been added after `v0.1.0-rc.2`. +No public release notes have been added after local release-candidate evidence +for `v0.1.0-rc.3`. Public GitHub release publication remains an operator +action. + +## v0.1.0-rc.3 - 2026-05-31 + +Release status: controlled self-hosted production candidate. This build is +suitable for evaluation, pilots, and controlled internal production after +operator review. Broad self-hosted production readiness, regulated production, +and hosted SaaS production remain out of scope for this status. The local +release-candidate package for this tag was generated with +`make release-candidate-check TAG=v0.1.0-rc.3`. + +### Added + +- Direct GCP Cloud KMS and Azure Key Vault signing executors for signing stored + SHA-256 payload hashes without sending raw evidence payload bytes. +- Operator-controlled provider validation gateway that records non-secret + validation metadata without forwarding supplied access tokens. +- Operator-controlled transparency proof gateway before local proof + verification. +- Release-candidate SBOM metadata and release provenance metadata generation. +- OpenSSF Scorecard workflow, Dependabot configuration, issue templates, code + of conduct, and production-like Compose rehearsal. + +### Changed + +- README positioning now leads with the release-evidence user problem, current + limitations, fastest proof path, and differentiation from adjacent tools. +- Security reporting guidance no longer depends on LinkedIn as the first + recommended path and calls out external repository settings that operators + must verify. + +### Known Limits + +- Public GitHub release publication, branch protection, public CI status, + private vulnerability-reporting settings, and public adoption evidence remain + external repository/operator proof. +- High-scale multi-writer API HA, native PKCS#11/HSM module handling, direct + provider management API/group synchronization, broad WORM/object-lock proof, + and final production exit review remain hardening work or deployment-specific + review items. ## v0.1.0-rc.2 - 2026-05-31 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..bf9652b --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,36 @@ +# Code Of Conduct + +Evydence is a high-trust release-evidence project. Participation must preserve +the same standard expected from the software: clear, respectful, evidence-based, +and careful with security-sensitive information. + +## Expected Behavior + +- Be direct without being abusive. +- Critique claims, code, docs, tests, and designs with concrete evidence. +- Keep discussions focused on Evydence, its users, and its technical tradeoffs. +- Respect boundaries around tenant data, credentials, raw evidence payloads, + customer package contents, provider tokens, private keys, and vulnerability + reports. +- Use private security intake for suspected vulnerabilities instead of public + issues, pull requests, screenshots, logs, or examples. + +## Unacceptable Behavior + +- Harassment, threats, personal attacks, or discriminatory conduct. +- Publishing secrets, credentials, raw evidence payloads, customer data, private + vulnerability details, or exploit material in public project channels. +- Repeatedly pushing legal compliance, certification, secure-release, complete + SBOM, authoritative scanner, regulator-acceptance, or auditor-acceptance + claims that the project explicitly does not make. +- Misrepresenting modified builds as official Evydence releases. + +## Enforcement + +Maintainers may edit, hide, lock, or remove comments, issues, pull requests, or +other contributions that violate this policy. Serious or repeated violations may +lead to a block from project spaces. Security-sensitive material may be removed +without preserving public context. + +This code of conduct is a project participation policy, not a legal compliance +or certification statement. diff --git a/Dockerfile b/Dockerfile index 62fe63d..d20364d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,6 +4,7 @@ COPY go.mod go.sum ./ RUN go mod download COPY . . RUN go build -o /out/evydence-api ./cmd/evydence-api +RUN go build -o /out/evydence-migrate ./cmd/evydence-migrate RUN go build -o /out/evydence-worker ./cmd/evydence-worker RUN go build -o /out/evydence ./cmd/evydence @@ -12,6 +13,7 @@ RUN addgroup -S evydence && adduser -S -G evydence evydence USER evydence WORKDIR /app COPY --from=build /out/evydence-api /usr/local/bin/evydence-api +COPY --from=build /out/evydence-migrate /usr/local/bin/evydence-migrate COPY --from=build /out/evydence-worker /usr/local/bin/evydence-worker COPY --from=build /out/evydence /usr/local/bin/evydence COPY --from=build /src/migrations /app/migrations diff --git a/Makefile b/Makefile index 8bbd7ab..e652f84 100644 --- a/Makefile +++ b/Makefile @@ -63,18 +63,28 @@ meta-check: ## Validate root legal, governance, support, and release-evidence me @test -f SECURITY.md @test -f SUPPORT.md @test -f TRADEMARKS.md + @test -f CODE_OF_CONDUCT.md @test -f RELEASE_EVIDENCE.md @test -f CHANGELOG.md @test -f .dockerignore + @test -f .github/dependabot.yml + @test -f .github/workflows/scorecard.yml + @test -f .github/ISSUE_TEMPLATE/bug_report.yml + @test -f .github/ISSUE_TEMPLATE/feature_request.yml + @test -f .github/ISSUE_TEMPLATE/docs.yml + @test -f .github/ISSUE_TEMPLATE/production_support.yml @test -x scripts/release_acceptance.sh @test -x scripts/release_candidate_package.sh @test -x scripts/release_candidate_validate.sh + @test -x scripts/release_evidence_metadata.py @grep -F 'GNU AFFERO GENERAL PUBLIC LICENSE' LICENSE >/dev/null @grep -F 'AGPL-3.0-only' COMMERCIAL.md >/dev/null @grep -F 'Commercial license exceptions' COMMERCIAL.md >/dev/null @grep -F 'contributor license agreement' CONTRIBUTING.md >/dev/null @grep -F 'raw evidence payloads' SECURITY.md >/dev/null @grep -F 'release evidence artifacts' SUPPORT.md >/dev/null + @grep -F 'Security vulnerability' .github/ISSUE_TEMPLATE/config.yml >/dev/null + @grep -F 'OpenSSF Scorecard' .github/workflows/scorecard.yml >/dev/null @grep -F 'Evydence fork' TRADEMARKS.md >/dev/null @grep -F 'Release evidence is not a certification' RELEASE_EVIDENCE.md >/dev/null @grep -F '.refs' .dockerignore >/dev/null @@ -177,6 +187,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @! grep -R -i "automatically compliant\|certified secure\|legally sufficient\|SBOM is complete\|all vulnerabilities detected\|scanner findings are authoritative\|regulator-ready without review" README.md docs deploy-check: ## Validate deployment and air-gap skeletons exist + @test -f compose.production-like.yml @test -f deploy/helm/evydence/Chart.yaml @test -f deploy/helm/evydence/values.yaml @test -f deploy/helm/evydence/templates/deployment-api.yaml @@ -197,6 +208,11 @@ deploy-check: ## Validate deployment and air-gap skeletons exist @grep -F 'evydence-worker' deploy/helm/evydence/templates/deployment-worker.yaml >/dev/null @grep -F 'healthcheck' deploy/helm/evydence/values.yaml >/dev/null @grep -F 'single API writer replica' docs/kubernetes.md >/dev/null + @grep -F 'EVYDENCE_API_WRITER_MODE: single' compose.production-like.yml >/dev/null + @grep -F 'EVYDENCE_PRINT_BOOTSTRAP_SECRET: "false"' compose.production-like.yml >/dev/null + @grep -F 'evydence-migrate ./cmd/evydence-migrate' Dockerfile >/dev/null + @grep -F 'entrypoint: ["evydence-migrate"]' compose.production-like.yml >/dev/null + @grep -F 'entrypoint: ["evydence-worker"]' compose.production-like.yml >/dev/null sdk-check: ## Validate SDK helper and generated route-catalog coverage against OpenAPI @test -f sdk/go/evydence/client.go diff --git a/README.md b/README.md index 24602ac..3cce21e 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,75 @@ # Evydence -Evydence is a self-hosted, API-first evidence ledger for software release evidence. It supports compliance readiness by organizing and verifying technical evidence, producing tamper-evident records, and showing gaps, assumptions, exceptions, and limitations. +[![CI](https://github.com/aatuh/evydence/actions/workflows/ci.yml/badge.svg)](https://github.com/aatuh/evydence/actions/workflows/ci.yml) +[![OpenSSF Scorecard](https://github.com/aatuh/evydence/actions/workflows/scorecard.yml/badge.svg)](https://github.com/aatuh/evydence/actions/workflows/scorecard.yml) +[![License: AGPL-3.0-only](https://img.shields.io/badge/license-AGPL--3.0--only-blue.svg)](LICENSE) +![Go Version](https://img.shields.io/badge/go-1.25+-00ADD8.svg) +![OpenAPI](https://img.shields.io/badge/OpenAPI-166%20precise%20operations-brightgreen.svg) +![Coverage Gate](https://img.shields.io/badge/coverage%20gate-80%25+-brightgreen.svg) + +Evydence is a self-hosted release evidence ledger that helps software teams +collect, verify, and share tamper-evident technical evidence for each release. + +It is for security, platform, AppSec, and compliance-readiness teams at B2B +software companies that need customer-reviewable release evidence without +handing all release trust data to a SaaS GRC platform. + +Before shipping a release, Evydence can collect SBOMs, vulnerability scans, VEX +decisions, build/source/deployment evidence, controls, exceptions, release +bundles, and customer-safe packages, then show readiness gaps, assumptions, and +limitations. + +It does not make legal compliance conclusions, grant certification, prove SBOM +completeness, treat scanner findings as authoritative, or guarantee release +security. + +## Current Limitations -It does not make legal compliance conclusions, grant certification, prove SBOM completeness, treat scanner findings as authoritative, or guarantee release security. +- Current status is a controlled self-hosted production candidate for + evaluation, pilots, and controlled internal production after operator review. +- Production API deployments use one API writer replica; workers may scale + through PostgreSQL outbox locking. +- Public release publication, branch protection, private vulnerability + reporting settings, and public CI status are GitHub/operator controls, not + guarantees made by repository files alone. +- Native PKCS#11/HSM module handling, broad WORM/object-lock proof, direct + provider-specific management API clients, external group synchronization, + regulated production, and hosted SaaS production remain outside the current + supported profile unless a deployment review closes those gaps. ## Current Implementation -This repository contains a Go implementation under module `github.com/aatuh/evydence`. The current status is controlled self-hosted production candidate: useful for evaluation, pilots, and controlled internal production after operator review, with a stricter production gate and release-candidate checklist tracking the remaining work before any broader production claim. A local signed `v0.1.0-rc.2` evidence package has been generated from this checkout; public release publication remains a separate operator action. +This repository contains a Go implementation under module +`github.com/aatuh/evydence`. A local signed `v0.1.0-rc.3` evidence package has +been generated from this checkout; public release publication remains a +separate operator action. + +## Fastest Proof Path + +For a first local API flow, follow [Getting started](docs/tutorials/getting-started.md). +For durable local evaluation, run the production-like Compose rehearsal in +[Install and operate](docs/how-to/install-and-operate.md). + +The end-to-end evidence flow to evaluate first is: + +1. Create a product, release, and artifact. +2. Upload SBOM and vulnerability scan evidence. +3. Record a VEX decision or exception for an intentionally blocking finding. +4. Generate a release bundle and readiness report. +5. Export a customer-safe package or evidence bundle for review. + +## Why Evydence Instead Of Existing Tools? + +- Dependency-Track and vulnerability-management tools are strong for SBOM and + finding workflows; Evydence focuses on release-level evidence, decisions, + bundles, audit chains, controls, customer packages, and review limitations. +- Vanta, Drata, and similar SaaS GRC tools are broad compliance platforms; + Evydence is a self-hosted technical evidence ledger and does not claim legal + compliance or certification. +- Building this in-house with object storage, scripts, spreadsheets, and ad hoc + Postgres tables is possible; Evydence provides a versioned API, OpenAPI + contract, tenant scoping, idempotency, audit chains, release evidence, and + checked non-claim language from the start. ### API And Contracts @@ -38,13 +101,15 @@ This repository contains a Go implementation under module `github.com/aatuh/evyd - `cmd/evydence` helper for hashing, manifest verification, GitHub Actions build provenance upload, release artifact manifest signing/verification, bulk upload manifests, and air-gapped evidence bundle import. - Docker Compose dependencies for PostgreSQL and MinIO. +- Production-like Docker Compose rehearsal with API, worker, migrations, + PostgreSQL, and MinIO. - Kubernetes Helm chart under `deploy/helm/evydence`. - Air-gapped package manifest under `deploy/airgap/manifest.yaml`. - Lightweight Go, TypeScript, and Python SDK wrappers. - GitHub Actions and GitLab CI workflow examples. - Documentation portal under `docs/`. - AGPL license, commercial licensing, governance, contribution, security, - support, trademark, release-evidence, and changelog metadata. + support, code of conduct, trademark, release-evidence, and changelog metadata. Implemented-but-partial areas are documented explicitly: signing-provider operation receipts can use an HTTPS signing gateway, built-in AWS KMS, GCP Cloud KMS, or Azure Key Vault executors, and `pkcs11-hsm` remains gateway-backed because native HSM modules are deployment-specific; deployment-specific custody review remains operator work. SSO credential exchange uses configured local OIDC/SAML trust material and session-scoped OIDC group-role mappings, and provider verification can optionally call OIDC UserInfo or an operator-controlled provider validation gateway when a caller supplies an access token, but the gateway receives only non-secret metadata and this does not replace direct provider-specific management API clients or external group synchronization. Public transparency records can verify operator-supplied proof material, fetch from configured endpoints, or use an operator-controlled transparency proof gateway without replacing provider-specific trust review. diff --git a/SECURITY.md b/SECURITY.md index 538bfc1..b678442 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -8,18 +8,22 @@ object storage, reports, exports, and release evidence. ## Reporting A Vulnerability -If you believe you found a vulnerability, use the private security intake -channel listed for the current release when available. Until a dedicated -security mailbox or advisory portal is published, contact Aatu Harju through -LinkedIn to request a private reporting channel: +If you believe you found a vulnerability, use GitHub private vulnerability +reporting for this repository when the "Report a vulnerability" button is +available on GitHub. If the button is unavailable for your account or region, +use the private security intake channel listed for the current release notes or +request a private channel from the maintainer without including vulnerability +details in the first contact. - +The repository file cannot itself prove that GitHub private vulnerability +reporting or a dedicated mailbox is enabled; that is an operator setting that +must be verified on the public repository before relying on it. -Use the initial message only to request a private reporting channel. Do not include -API keys, collector secrets, bearer tokens, session tokens, portal tokens, -private keys, provider credentials, database URLs, raw evidence payloads, -customer data, exploit payloads against third-party systems, or other sensitive -material in the first message. +Do not include API keys, collector secrets, bearer tokens, session tokens, +portal tokens, private keys, provider credentials, database URLs, raw evidence +payloads, customer data, exploit payloads against third-party systems, or other +sensitive material in public issues, pull requests, screenshots, logs, or first +contact messages. ## What To Include diff --git a/compose.production-like.yml b/compose.production-like.yml new file mode 100644 index 0000000..bddf4e9 --- /dev/null +++ b/compose.production-like.yml @@ -0,0 +1,118 @@ +# Production-like local evaluation stack. +# +# This file is for local operator rehearsal, not a turnkey production +# deployment. Replace all secrets, use TLS at the edge, back up PostgreSQL and +# object storage together, and keep API replicas at one for the current +# supported writer profile. + +services: + postgres: + image: postgres:16-alpine + environment: + POSTGRES_DB: ${POSTGRES_DB:-evydence} + POSTGRES_USER: ${POSTGRES_USER:-evydence} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required} + ports: + - "${POSTGRES_PORT:-5432}:5432" + volumes: + - postgres-data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER:-evydence}"] + interval: 5s + timeout: 5s + retries: 20 + + minio: + image: minio/minio:latest + command: server /data --console-address ":9001" + environment: + MINIO_ROOT_USER: ${MINIO_ROOT_USER:-evydence} + MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:?MINIO_ROOT_PASSWORD is required} + ports: + - "${MINIO_PORT:-9000}:9000" + - "${MINIO_CONSOLE_PORT:-9001}:9001" + volumes: + - minio-data:/data + + minio-init: + image: minio/mc:latest + depends_on: + minio: + condition: service_started + environment: + MINIO_ROOT_USER: ${MINIO_ROOT_USER:-evydence} + MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:?MINIO_ROOT_PASSWORD is required} + EVYDENCE_S3_BUCKET: ${EVYDENCE_S3_BUCKET:-evydence} + entrypoint: + - /bin/sh + - -ec + - | + until mc alias set local http://minio:9000 "$${MINIO_ROOT_USER}" "$${MINIO_ROOT_PASSWORD}" >/dev/null 2>&1; do + sleep 2 + done + mc mb --ignore-existing "local/$${EVYDENCE_S3_BUCKET}" + + migrate: + build: . + image: ${EVYDENCE_IMAGE:-evydence:local} + depends_on: + postgres: + condition: service_healthy + environment: + EVYDENCE_DATABASE_URL: postgres://${POSTGRES_USER:-evydence}:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}@postgres:5432/${POSTGRES_DB:-evydence}?sslmode=disable + entrypoint: ["evydence-migrate"] + + api: + build: . + image: ${EVYDENCE_IMAGE:-evydence:local} + depends_on: + migrate: + condition: service_completed_successfully + minio-init: + condition: service_completed_successfully + environment: + ENV: production + EVYDENCE_ADDR: :8080 + EVYDENCE_API_KEY_PEPPER: ${EVYDENCE_API_KEY_PEPPER:?EVYDENCE_API_KEY_PEPPER is required} + EVYDENCE_DATABASE_URL: postgres://${POSTGRES_USER:-evydence}:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}@postgres:5432/${POSTGRES_DB:-evydence}?sslmode=disable + EVYDENCE_OBJECT_STORE: minio + EVYDENCE_S3_ENDPOINT: minio:9000 + EVYDENCE_S3_BUCKET: ${EVYDENCE_S3_BUCKET:-evydence} + EVYDENCE_S3_ACCESS_KEY_ID: ${MINIO_ROOT_USER:-evydence} + EVYDENCE_S3_SECRET_ACCESS_KEY: ${MINIO_ROOT_PASSWORD:?MINIO_ROOT_PASSWORD is required} + EVYDENCE_S3_USE_SSL: "false" + EVYDENCE_SIGNING_KEY_MODE: ${EVYDENCE_SIGNING_KEY_MODE:-external} + EVYDENCE_API_WRITER_MODE: single + EVYDENCE_API_WRITER_REPLICAS: "1" + EVYDENCE_PRINT_BOOTSTRAP_SECRET: "false" + ports: + - "${EVYDENCE_PORT:-8080}:8080" + healthcheck: + test: ["CMD", "wget", "-qO-", "http://127.0.0.1:8080/v1/ready"] + interval: 10s + timeout: 3s + retries: 12 + + worker: + image: ${EVYDENCE_IMAGE:-evydence:local} + depends_on: + migrate: + condition: service_completed_successfully + minio-init: + condition: service_completed_successfully + environment: + ENV: production + EVYDENCE_API_KEY_PEPPER: ${EVYDENCE_API_KEY_PEPPER:?EVYDENCE_API_KEY_PEPPER is required} + EVYDENCE_DATABASE_URL: postgres://${POSTGRES_USER:-evydence}:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}@postgres:5432/${POSTGRES_DB:-evydence}?sslmode=disable + EVYDENCE_OBJECT_STORE: minio + EVYDENCE_S3_ENDPOINT: minio:9000 + EVYDENCE_S3_BUCKET: ${EVYDENCE_S3_BUCKET:-evydence} + EVYDENCE_S3_ACCESS_KEY_ID: ${MINIO_ROOT_USER:-evydence} + EVYDENCE_S3_SECRET_ACCESS_KEY: ${MINIO_ROOT_PASSWORD:?MINIO_ROOT_PASSWORD is required} + EVYDENCE_S3_USE_SSL: "false" + EVYDENCE_SIGNING_KEY_MODE: ${EVYDENCE_SIGNING_KEY_MODE:-external} + entrypoint: ["evydence-worker"] + +volumes: + postgres-data: + minio-data: diff --git a/docs/README.md b/docs/README.md index 9ed8879..038ddd3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -15,15 +15,23 @@ This documentation is organized by reader task. Implementation claims should be - [Kubernetes deployment](kubernetes.md): install the Helm chart and verify a self-hosted cluster deployment. - [Air-gapped installation](air-gapped.md): build, sign, transfer, verify, and import an offline package. - [Release signing](release-signing.md): create and verify local release artifact manifests. +- [View packages locally](how-to/view-packages.md): inspect package, readiness, and evidence-bundle JSON without uploading it. - [Production hardening review](production-hardening.md): review production configuration, backups, ingress, diagnostics, and customer package controls. +- [Backup and restore runbook](runbooks/backup-restore.md): rehearse paired database/object-store restore and verification. +- [Upgrade runbook](runbooks/upgrade.md): verify release artifacts, migrations, and post-upgrade checks. +- [Incident response runbook](runbooks/incident-response.md): handle operator incidents without leaking secrets or raw evidence. ## Reference - [Configuration](reference/configuration.md): canonical environment variables and the roles of `.env.example`, `.api.env.example`, and `.test.env.example`. +- [Documentation source of truth](reference/source-of-truth.md): canonical source map to keep commands, status, and limitations from drifting. - [API contract matrix](reference/api-contract-matrix.md): generated route-by-route contract precision inventory for production hardening. - [OpenAPI contract](reference/openapi.md): generation, drift checks, and review tips for `openapi.yaml`. - [Observability](reference/observability.md): readiness, admin metrics, Prometheus rules, and dashboard starter assets. +- [Capacity and failure modes](reference/capacity-and-failures.md): supported concurrency profile, sizing inputs, and failure behavior. +- [Benchmark results](reference/benchmark-results.md): current local benchmark command and interpretation. - [Production readiness](reference/production-readiness.md): self-hosted production profiles, production gates, and exit criteria. +- [Production exit review](reference/production-exit-review.md): current release-positioning decision and unresolved blockers. - [Release candidate checklist](reference/release-candidate.md): required evidence before tagging a controlled self-hosted release candidate. - [Release notes template](reference/release-notes-template.md): checked wording used by release-candidate packaging when a tag-specific note file is absent. - [Release notes v0.1.0-rc.1](reference/release-notes-v0.1.0-rc.1.md): checked release-note wording for the first controlled self-hosted release candidate. @@ -41,6 +49,7 @@ This documentation is organized by reader task. Implementation claims should be - [Support](../SUPPORT.md): community support expectations, commercial support boundaries, and sanitized bug-report requirements. - [Governance](../GOVERNANCE.md): maintainer-led decision process, contribution acceptance, release evidence expectations, and conservative product-language policy. - [Contributing](../CONTRIBUTING.md): contribution workflow, CLA expectation, licensing compatibility, and implementation invariants. +- [Code of conduct](../CODE_OF_CONDUCT.md): participation expectations for public project spaces. - [Trademarks](../TRADEMARKS.md): conservative use of the Evydence name and modified-build naming rules. - [Release evidence](../RELEASE_EVIDENCE.md): release evidence routing, local acceptance checks, and limits of release validation. - [Changelog](../CHANGELOG.md): unreleased and future public-release notes. @@ -51,12 +60,15 @@ This documentation is organized by reader task. Implementation claims should be - [GitHub Actions upload-build composite action](github-actions/upload-build/action.yml) - [GitHub release evidence manifest generator](../scripts/github_release_evidence_manifest.py) - [GitLab release evidence CI template](gitlab/evydence-release-evidence.gitlab-ci.yml) +- [End-to-end release evidence example](../examples/end-to-end-release-evidence/README.md) +- [SDK examples](../examples/sdk) These examples require tenant-scoped API or collector secrets created through the API. They capture CI metadata as submitted evidence; provider-side truth still depends on the CI provider, workflow controls, and any verification receipts recorded separately. ## Explanation - [Architecture](architecture.md): ports/adapters boundaries, persistence, object storage, append-only behavior, and current limitations. +- [Architecture diagram](explanation/architecture-diagram.md): compact diagram of API, worker, storage, signing, and provider boundaries. - [Trust model](explanation/trust-model.md): what Evydence verifies, what it records as assumptions, and where external review remains required. Evydence supports compliance readiness and technical evidence organization. The documentation avoids claims that Evydence makes legal compliance conclusions, grants certification, proves SBOM completeness, treats scanner output as authoritative, or guarantees release security. diff --git a/docs/explanation/architecture-diagram.md b/docs/explanation/architecture-diagram.md new file mode 100644 index 0000000..2d93e35 --- /dev/null +++ b/docs/explanation/architecture-diagram.md @@ -0,0 +1,42 @@ +# Architecture Diagram + +This explanation is a compact map of the current controlled self-hosted +production candidate architecture. It omits many resource families but shows the +trust boundaries operators need to understand first. + +```mermaid +flowchart LR + ci[CI collectors and CLI uploaders] --> api[Evydence API /v1] + users[Operators and API clients] --> api + portal[Customer portal token holder] --> api + + api --> auth[Scoped API key / SSO / portal auth] + auth --> app[Application ledger and policy services] + app --> pg[(PostgreSQL relational state)] + app --> obj[(S3/MinIO or filesystem object store)] + app --> outbox[(PostgreSQL outbox)] + app --> signer[Signing executor or KMS/gateway] + app --> provider[Optional provider validation gateway] + app --> transparency[Optional transparency proof gateway] + + worker[Evydence worker replicas] --> outbox + worker --> pg + worker --> obj + worker --> signer + + pg --> reports[Readiness, control, package, audit and backup reports] + obj --> reports +``` + +## Boundaries + +- API clients and collectors are untrusted until authenticated and authorized. +- Tenant IDs are enforced at application and persistence boundaries. +- Raw payload bytes live in object storage under tenant-prefixed keys. +- PostgreSQL is the production source of truth for the controlled profile. +- Workers re-read object payloads and verify digests before parser side effects. +- Signing providers receive payload hashes or signing requests, not raw evidence + payload bytes from Evydence. +- Provider validation, public transparency, broad WORM/object-lock proof, and + native HSM custody remain deployment/provider responsibilities unless a + specific deployment closes those checks. diff --git a/docs/how-to/install-and-operate.md b/docs/how-to/install-and-operate.md index 96ae45d..71793a5 100644 --- a/docs/how-to/install-and-operate.md +++ b/docs/how-to/install-and-operate.md @@ -26,6 +26,32 @@ Stop them with: make compose-down ``` +## Run The Production-Like Local Stack + +For a fuller local rehearsal, use `compose.production-like.yml`. It starts +PostgreSQL, MinIO, bucket initialization, migrations, one API writer, and one +worker. It is still a local evaluation stack: replace every secret, use TLS at +the edge, back up PostgreSQL and object storage together, and keep production +API writer replicas at one for the current supported profile. + +```sh +export POSTGRES_PASSWORD='replace-with-long-random-password' +export MINIO_ROOT_PASSWORD='replace-with-long-random-password' +export EVYDENCE_API_KEY_PEPPER='replace-with-long-random-pepper' +docker compose -f compose.production-like.yml up --build +``` + +Expected result: + +- migrations complete before the API and worker start; +- MinIO bucket `evydence` is created when absent; +- the API listens on `http://localhost:8080`; +- `/v1/ready` returns `200` after startup. + +This stack intentionally sets `EVYDENCE_PRINT_BOOTSTRAP_SECRET=false`. Create +or rotate production credentials through controlled operator procedures rather +than printing bootstrap secrets in shared logs. + ## Run With PostgreSQL ```sh diff --git a/docs/how-to/view-packages.md b/docs/how-to/view-packages.md new file mode 100644 index 0000000..9bde13d --- /dev/null +++ b/docs/how-to/view-packages.md @@ -0,0 +1,22 @@ +# View Release And Customer Packages Locally + +Evydence is API-first, but the repository includes a minimal local package +viewer at `site/package-viewer/index.html` for customer-package and +release-evidence review. + +Open the file in a browser, then select a JSON package, readiness report, +evidence bundle, or package manifest from disk. The viewer runs entirely in the +browser and does not upload data. + +Use it for: + +- checking a release-readiness report before sending a customer package; +- inspecting package manifests and limitations; +- reading evidence-bundle metadata during an offline review; +- confirming that a shared package does not contain raw evidence payload bytes + or secrets. + +Do not use the viewer as authorization. Customer access still depends on +server-side package scopes, redaction profiles, expiry, and access auditing. +Viewer output is not legal compliance proof, certification, complete SBOM +proof, an authoritative vulnerability result, or a secure-release guarantee. diff --git a/docs/operations.md b/docs/operations.md index 56df3cd..090a36b 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -7,15 +7,23 @@ This operator index points to the canonical references for running Evydence. Kee | Task | Canonical Doc | Expected Outcome | |------|---------------|------------------| | Choose local or durable runtime mode | [Install and operate](how-to/install-and-operate.md) | API and worker run with either in-process state or PostgreSQL-backed state. | +| Rehearse production-like Compose | [Install and operate](how-to/install-and-operate.md) | API, worker, migrations, PostgreSQL, and MinIO start together with one API writer. | | Configure environment variables | [Configuration](reference/configuration.md) | Runtime variables are set from local untracked files or deployment secrets. | | Wire observability | [Observability](reference/observability.md) | Readiness, admin metrics, Prometheus rules, and dashboard starter assets are reviewed for the deployment. | | Run release validation | [Release validation](reference/release-validation.md) | `tmp/release-check-summary.txt` records pass and explicit skip lines. | | Check production readiness | [Production readiness](reference/production-readiness.md) | Live PostgreSQL, coverage, release validation, and signed release artifact smoke checks pass before production positioning. | | Operate outbox workers | [Worker outbox contract](reference/worker-outbox.md) | Workers claim persisted jobs and fail safely on missing state, hash mismatch, or unsupported jobs. | | Integrate CI evidence | [Integrate CI collectors](how-to/integrate-ci.md) | CI jobs upload build, attestation, source snapshot, or collector evidence with scoped secrets. | +| View packages locally | [View packages locally](how-to/view-packages.md) | Customer package and readiness JSON can be inspected without uploading data. | | Deploy on Kubernetes | [Kubernetes deployment](kubernetes.md) | API and worker deploy with external PostgreSQL, object storage, and external signing mode. | | Build an offline package | [Air-gapped installation](air-gapped.md) | Package manifests and signatures are verified before import. | | Review production hardening | [Production hardening review](production-hardening.md) | Unsafe defaults, backup gaps, diagnostics exposure, and customer package handling are reviewed. | +| Rehearse backup and restore | [Backup and restore runbook](runbooks/backup-restore.md) | Database/object-store pairing and post-restore verification are recorded. | +| Upgrade a deployment | [Upgrade runbook](runbooks/upgrade.md) | Release artifacts, migrations, and post-upgrade verification are checked. | +| Respond to incidents | [Incident response runbook](runbooks/incident-response.md) | Secrets, tenant data, signing, provider, and package boundaries are handled without public leakage. | +| Review capacity and failure modes | [Capacity and failure modes](reference/capacity-and-failures.md) | Single-writer API limits, worker scaling, object-store failures, and retry behavior are understood. | +| Review benchmark evidence | [Benchmark results](reference/benchmark-results.md) | Local evidence-ingestion benchmark scope and limitations are clear. | +| Review release status | [Production exit review](reference/production-exit-review.md) | The controlled self-hosted candidate status and unresolved blockers are explicit. | ## Integrity Operations diff --git a/docs/reference/benchmark-results.md b/docs/reference/benchmark-results.md new file mode 100644 index 0000000..1cb9eac --- /dev/null +++ b/docs/reference/benchmark-results.md @@ -0,0 +1,54 @@ +# Benchmark Results + +This reference records lightweight local benchmark evidence for the supported +single-writer profile. It is not a broad throughput claim and should not be used +as capacity planning without target-environment tests. + +## Benchmark Command + +```sh +go test ./internal/app -bench BenchmarkReleaseEvidenceIngestion -benchtime=100x -run '^$' +``` + +## Current Interpretation + +The benchmark exercises in-process release evidence creation through the app +service and audit-chain path. It does not include HTTP routing, PostgreSQL, +object storage, signing providers, or worker parser side effects. + +Use it to detect obvious local regressions in the core evidence path. For +production sizing, run API-level tests against the target PostgreSQL and object +store and record: + +- Evydence commit/tag; +- database and object-store versions; +- payload sizes; +- API writer count; +- worker count; +- request rate; +- outbox backlog age; +- failed verification or parser checks; +- assumptions and limitations. + +## Latest Local Result + +Last recorded local run: + +```text +goos: linux +goarch: amd64 +pkg: github.com/aatuh/evydence/internal/app +cpu: AMD Ryzen 7 3700X 8-Core Processor +BenchmarkReleaseEvidenceIngestion-16 100 1474947 ns/op 517162 B/op 2544 allocs/op +``` + +Interpretation: this is a narrow app-layer benchmark for regression tracking. +It does not prove HTTP throughput, PostgreSQL throughput, object-store +performance, signing-provider latency, parser throughput, or multi-writer API +safety. + +## Current Known Limit + +The supported production profile remains one API writer replica. Worker replicas +may scale through PostgreSQL outbox locking, but this benchmark does not prove +multi-writer API safety. diff --git a/docs/reference/capacity-and-failures.md b/docs/reference/capacity-and-failures.md new file mode 100644 index 0000000..b956251 --- /dev/null +++ b/docs/reference/capacity-and-failures.md @@ -0,0 +1,58 @@ +# Capacity And Failure Modes + +This reference gives starting guidance for the controlled self-hosted +production candidate profile. It is not a benchmark claim. + +## Supported Concurrency Profile + +- API writer replicas: `1`. +- Worker replicas: may scale horizontally when PostgreSQL outbox locking is + enabled. +- API multi-writer HA remains unsupported until a reviewed concurrency design + replaces the current single-writer stance. + +## Practical Sizing Inputs + +Operators should measure these values in their own environment: + +- average and maximum uploaded payload size; +- object-store latency and error rate; +- PostgreSQL connection pool usage; +- outbox backlog age and retry counts; +- release bundle generation time; +- report generation time; +- customer package export size; +- audit-chain verification time for the largest tenant. + +## Starting Configuration + +- Keep API writer replicas at one. +- Set worker replicas based on outbox backlog and parser/signing/report load. +- Use external PostgreSQL with backups and tested restore. +- Use S3/MinIO-compatible object storage for shared deployments. +- Keep reverse-proxy request body limits aligned with Evydence upload limits. +- Monitor `/v1/ready`, admin metrics, outbox backlog, failed jobs, database + connection errors, and object-store errors. + +## Failure Modes + +| Failure | Expected Behavior | Operator Action | +| --- | --- | --- | +| Second API writer starts | Production startup fails when writer mode or PostgreSQL advisory lease rejects it. | Keep one API writer replica and investigate deployment drift. | +| Worker crashes | Persisted outbox jobs remain claimable by another worker after retry/backoff. | Check worker logs and outbox metrics; restart worker after fixing configuration. | +| Object payload missing | Parser, verification, or package generation fails safely. | Restore object payload from backup and re-run verification. | +| Object digest mismatch | Payload is not trusted and verification fails. | Investigate database/object backup pairing before retrying. | +| PostgreSQL unavailable | API/worker startup or operations fail rather than silently using in-process state in production. | Restore database service and verify migrations/readiness. | +| Signing provider unavailable | Signing operation records failure without logging raw payload bytes or secrets. | Restore provider, rotate credentials if needed, and retry through an append-only operation. | +| Provider validation unavailable | Provider verification records failed/limited checks. | Retry after provider/gateway recovery; do not treat metadata capture as provider truth. | + +## Benchmark Policy + +Do not publish broad throughput or scale claims without recording: + +- Evydence commit/tag and release manifest; +- database and object-store versions; +- machine sizes and network shape; +- payload sizes and evidence mix; +- API and worker replica counts; +- pass/fail criteria and limitations. diff --git a/docs/reference/production-exit-review.md b/docs/reference/production-exit-review.md new file mode 100644 index 0000000..1c11cef --- /dev/null +++ b/docs/reference/production-exit-review.md @@ -0,0 +1,51 @@ +# Production Exit Review + +This review records the current release-positioning decision. It is a product +and operations review, not legal compliance proof, certification, complete SBOM +proof, an authoritative vulnerability result, or a secure-release guarantee. + +## Verdict + +Evydence remains a controlled self-hosted production candidate. Do not change +the public status to broad production-ready, regulated production-ready, hosted +SaaS-ready, legally compliant, certified, or secure-release-guaranteed. + +## Repo-Verified Strengths + +- API contract has 166 precise `/v1` operations and zero broad operations. +- `make production-check` is available and requires live PostgreSQL, coverage, + migration compatibility, release validation, race tests, security scans, and + release-signing smoke checks. +- Production API startup rejects in-process state, default pepper, unsupported + writer modes, writer replicas above one, local plaintext signing-key mode, + and bootstrap secret printing. +- Release-candidate packaging generates checksums, OpenAPI checksum, migration + checksum, release SBOM metadata, release provenance metadata, release notes, + signed manifest, and manifest signature. +- PostgreSQL relational-only production loading and focused critical plus + release-ledger write paths are implemented for the current candidate profile. +- Security, support, governance, contribution, code of conduct, issue + templates, Dependabot, and Scorecard workflow files exist. + +## Remaining Exit Blockers + +- Public release publication and branch protection require GitHub/operator + settings outside repository files. +- Native PKCS#11/HSM module custody requires operator hardware, drivers, and + provider-specific validation. +- Broad WORM/object-lock proof requires object-store policy, IAM, lifecycle, + backup, and provider audit evidence. +- Direct provider management APIs and external group synchronization remain + outside the current bring-your-own-evidence posture. +- Multi-writer API HA remains unsupported. The current reviewed stance is one + API writer replica. +- Target-environment backup/restore, incident-response, monitoring, and + capacity tests must be run by each operator. + +## Decision + +The current repository can support controlled self-hosted evaluation, pilots, +and internal production after operator review. It should not be marketed as +broad production-ready for most uses until the external controls above are +closed and a fresh product, codebase, security, documentation, and test audit +confirms the change. diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index f296eda..4cae5c3 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -156,9 +156,12 @@ Do not describe an Evydence build as broadly self-hosted production-ready until: prefix to the current schema; - the built-in local restore rehearsal passes and backup/restore have been tested for the target deployment profile; +- the backup/restore, upgrade, incident-response, and capacity runbooks have + been reviewed against the target deployment; - OpenAPI, OpenAPI precision, route-contract, and SDK drift checks pass; - the HA story for the target profile is documented and reviewed; - production hardening review is current; +- production exit review is current; - unresolved limitations are documented in release notes. ## Remaining Production Maturity Backlog diff --git a/docs/reference/release-candidate.md b/docs/reference/release-candidate.md index 9e22a10..82cd3be 100644 --- a/docs/reference/release-candidate.md +++ b/docs/reference/release-candidate.md @@ -17,6 +17,7 @@ Before creating a release-candidate tag, collect: - `coverage.out` and the total coverage summary; - `openapi.yaml` plus an OpenAPI checksum; - migration checksum output for the directory or per-file migration checksums; +- release SBOM metadata and release provenance metadata; - signed release artifact manifest and manifest signature; - checksums for every published binary, container image digest, chart package, and release archive; @@ -38,8 +39,8 @@ worktree, a release-candidate tag such as `v0.1.0-rc.1`, no existing local tag unless the CI tag workflow explicitly allows it, live PostgreSQL through `EVYDENCE_TEST_DATABASE_URL`, and release signing material. It runs `make production-check`, builds the release archive matrix, writes checksums, -signs the release manifest, verifies the manifest signature, and validates the -release-note language. +generates release SBOM and provenance metadata, signs the release manifest, +verifies the manifest signature, and validates the release-note language. Do not tag from a run where live PostgreSQL checks, migration compatibility, coverage threshold enforcement, OpenAPI checks, docs checks, deployment checks, diff --git a/docs/reference/release-notes-template.md b/docs/reference/release-notes-template.md index 6e2fee2..fd84209 100644 --- a/docs/reference/release-notes-template.md +++ b/docs/reference/release-notes-template.md @@ -23,6 +23,10 @@ acceptance. - `coverage.out` and threshold evidence. - `openapi.yaml` and `openapi.sha256`. - `migrations.sha256`. +- `evydence-release-sbom.cdx.json` generated from Go module metadata; this is + release evidence, not complete SBOM proof. +- `evydence-release-provenance.json` with release-candidate packaging inputs; + this is not a SLSA level claim. - `SHA256SUMS` for release archives and evidence files. - Signed release artifact manifest and manifest signature. diff --git a/docs/reference/release-notes-v0.1.0-rc.1.md b/docs/reference/release-notes-v0.1.0-rc.1.md index 8cca69b..327cabf 100644 --- a/docs/reference/release-notes-v0.1.0-rc.1.md +++ b/docs/reference/release-notes-v0.1.0-rc.1.md @@ -23,6 +23,10 @@ acceptance. - `coverage.out` and threshold evidence. - `openapi.yaml` and `openapi.sha256`. - `migrations.sha256`. +- `evydence-release-sbom.cdx.json` generated from Go module metadata; this is + release evidence, not complete SBOM proof. +- `evydence-release-provenance.json` with release-candidate packaging inputs; + this is not a SLSA level claim. - `SHA256SUMS` for release archives and evidence files. - Signed release artifact manifest and manifest signature. diff --git a/docs/reference/release-validation.md b/docs/reference/release-validation.md index ccbae9f..40093d0 100644 --- a/docs/reference/release-validation.md +++ b/docs/reference/release-validation.md @@ -54,6 +54,7 @@ is: - `tmp/release-check-summary.txt` from the same run; - coverage output and threshold result; - OpenAPI checksum and migration checksums; +- release SBOM metadata and release provenance metadata; - signed release artifact manifest, manifest signature, and artifact checksums; - release notes that state supported profile, assumptions, limitations, upgrade notes, and unresolved hardening work. @@ -72,10 +73,11 @@ make release-candidate-check TAG= `scripts/release_candidate_package.sh` creates `dist//` with the release archives, `SHA256SUMS`, `openapi.sha256`, `migrations.sha256`, -`coverage.out`, `release-check-summary.txt`, checked release notes, signed -release manifest, and manifest signature. It refuses dirty worktrees, invalid -release-candidate tags, missing live PostgreSQL configuration, missing signing -material, and existing local tags unless a CI tag build explicitly sets +release SBOM metadata, release provenance metadata, `coverage.out`, +`release-check-summary.txt`, checked release notes, signed release manifest, +and manifest signature. It refuses dirty worktrees, invalid release-candidate +tags, missing live PostgreSQL configuration, missing signing material, and +existing local tags unless a CI tag build explicitly sets `EVYDENCE_RELEASE_ALLOW_EXISTING_TAG=1`. ## Configured Live PostgreSQL Profile diff --git a/docs/reference/source-of-truth.md b/docs/reference/source-of-truth.md new file mode 100644 index 0000000..411f546 --- /dev/null +++ b/docs/reference/source-of-truth.md @@ -0,0 +1,37 @@ +# Documentation Source Of Truth + +Use this map to avoid duplicating long command lists, release criteria, or +product-boundary language across the docs. + +| Topic | Canonical Source | Notes | +| --- | --- | --- | +| Product positioning and current status | `README.md` and `docs/reference/production-readiness.md` | Other docs should link here instead of redefining release status. | +| Runtime configuration | `docs/reference/configuration.md` | How-to guides may show a short example, then link here for variables. | +| API routes, scopes, idempotency, schemas | `openapi.yaml`, `docs/api.md`, `docs/reference/api-contract-matrix.md` | `openapi.yaml` is generated; the matrix is generated from it. | +| Local startup | `docs/tutorials/getting-started.md` | Uses in-process state only. | +| Durable operation | `docs/how-to/install-and-operate.md` | Includes PostgreSQL/object storage and production-like Compose rehearsal. | +| Kubernetes | `docs/kubernetes.md` | Helm-specific operator interface. | +| Release validation | `docs/reference/release-validation.md` | Canonical release gate behavior. | +| Release-candidate evidence | `docs/reference/release-candidate.md` | Canonical release-candidate artifact checklist. | +| Production profiles and exit criteria | `docs/reference/production-readiness.md` and `docs/reference/production-exit-review.md` | Do not broaden status elsewhere without updating these. | +| Backup/restore | `docs/runbooks/backup-restore.md` | Operator rehearsal steps and evidence to keep. | +| Upgrade | `docs/runbooks/upgrade.md` | Migration and release artifact verification steps. | +| Incident response | `docs/runbooks/incident-response.md` | Secrets, tenant, object-store, signing, provider, and package boundaries. | +| Capacity and failure modes | `docs/reference/capacity-and-failures.md` and `docs/reference/benchmark-results.md` | Benchmark results are narrow and local. | +| Security reporting | `SECURITY.md` | Repository settings for private reporting must be verified on GitHub. | +| Support expectations | `SUPPORT.md` | Public support boundaries and sanitized-report rules. | + +## Repetition Policy + +Repeat non-claims briefly where a document can be read alone, but keep detailed +wording in the canonical source. Prefer links over copying full checklists. + +Allowed short boundary wording: + +> Evydence supports compliance readiness and technical evidence organization; +> it does not make legal compliance conclusions, grant certification, prove SBOM +> completeness, treat scanner output as authoritative, or guarantee release +> security. + +Do not create new variants of release status, production profiles, or supported +deployment modes outside the canonical sources above. diff --git a/docs/runbooks/backup-restore.md b/docs/runbooks/backup-restore.md new file mode 100644 index 0000000..61d8910 --- /dev/null +++ b/docs/runbooks/backup-restore.md @@ -0,0 +1,60 @@ +# Backup And Restore Runbook + +This runbook is for self-hosted operators. It describes the evidence needed to +trust a restore rehearsal; it is not legal compliance proof or a disaster +recovery guarantee. + +## Scope + +Back up PostgreSQL and object storage as one logical unit. Evydence backup +manifests record counts, hashes, and verification checks, but they are not +backups by themselves. + +## Backup Procedure + +1. Record the Evydence commit, release tag, image digest, `openapi.sha256`, and + `migrations.sha256` used by the deployment. +2. Pause API writes or run the backup under an operator-approved consistency + window. Worker replicas may continue only if the backup procedure captures a + consistent database and object-store point. +3. Back up PostgreSQL with the operator's standard tool, such as + `pg_dump`, base backups, or managed service snapshots. +4. Back up the object store bucket/prefix that contains tenant-prefixed raw + payloads and package exports. +5. Call `POST /v1/backup-manifests` after the backup completes and store the + returned manifest with the backup metadata. +6. Store the release artifact manifest and signature next to the backup record. + +## Restore Rehearsal + +1. Restore PostgreSQL into a clean database. +2. Restore object payloads into a clean bucket or prefix. +3. Apply committed migrations for the target release. +4. Start one API writer and the required worker replicas. +5. Verify `/v1/ready`. +6. Verify the latest backup manifest with `GET /v1/backup-manifests/{id}/verify`. +7. Verify a representative audit chain, release bundle, readiness report, and + customer package from the restored deployment. +8. Record restore start/end time, data cut timestamp, object-store source, + database backup source, failed checks, and limitations. + +## Failure Handling + +- Missing object payloads: treat affected evidence, package, or report + verification as failed until the object backup is restored. +- Migration failure: stop startup, preserve logs, and use the previous release + artifact/migration set for recovery review. +- Hash mismatch: do not regenerate evidence silently. Record a verification + failure and investigate database/object-store pairing. +- Secret loss: rotate affected API keys, collector keys, SSO sessions, customer + portal tokens, and signing provider credentials. Do not place replacement + secrets in backup manifests or public issues. + +## Evidence To Keep + +- PostgreSQL backup identifier. +- Object-store backup identifier. +- Evydence release artifact manifest and signature. +- OpenAPI and migration checksums. +- Backup manifest and verification output. +- Restore rehearsal notes with assumptions and limitations. diff --git a/docs/runbooks/incident-response.md b/docs/runbooks/incident-response.md new file mode 100644 index 0000000..cb6f4c8 --- /dev/null +++ b/docs/runbooks/incident-response.md @@ -0,0 +1,51 @@ +# Incident Response Runbook + +Use this runbook for self-hosted Evydence operational incidents. It does not +replace the operator's security incident process. + +## First 15 Minutes + +1. Preserve logs, metrics, release evidence, and relevant configuration names. +2. Do not paste secrets, raw evidence payloads, customer data, bearer tokens, + private keys, provider credentials, or database URLs into public channels. +3. Identify the affected boundary: + API, tenant isolation, collector identity, SSO/session, object storage, + signing provider, release package, customer portal, provider integration, or + deployment infrastructure. +4. If API write integrity is uncertain, stop additional API writer processes and + keep worker processing paused until object/database consistency is reviewed. +5. If a secret may be exposed, revoke or rotate the affected key/token before + collecting broader diagnostics. + +## Containment Checklist + +- API key or collector key exposure: revoke the key, create a new scoped key, + and review audit-chain entries for the affected actor. +- SSO/session exposure: revoke sessions, refresh trust material if needed, and + review provider verification receipts. +- Object-store exposure: rotate object-store credentials, review bucket policy, + and verify tenant-prefixed object access. +- Signing provider exposure: disable the provider, rotate/revoke keys according + to provider policy, and verify valid-at-signing behavior for historical + signatures. +- Customer package exposure: expire portal access, create a new redaction + profile if required, and review package access records. +- Release artifact concern: verify `SHA256SUMS`, manifest signature, OpenAPI + checksum, migration checksum, SBOM metadata, and provenance metadata. + +## Communication + +Use concise, factual updates. Do not claim legal compliance, certification, +complete SBOM coverage, scanner authority, or secure releases. State what is +known, what evidence was checked, what remains under review, and what operators +should do next. + +## Post-Incident Evidence + +- Incident timeline and remediation tasks in Evydence when the deployment is + trusted again. +- Audit-chain verification result. +- Backup/restore verification if data integrity was in scope. +- Secret rotation evidence. +- Release or customer package re-issue evidence when affected. +- Limitations and assumptions for any report shared externally. diff --git a/docs/runbooks/upgrade.md b/docs/runbooks/upgrade.md new file mode 100644 index 0000000..ada5d71 --- /dev/null +++ b/docs/runbooks/upgrade.md @@ -0,0 +1,44 @@ +# Upgrade Runbook + +Use this runbook when moving a self-hosted Evydence deployment to a new release +candidate or release. It is a technical upgrade guide, not an assurance or +certification statement. + +## Before Upgrade + +1. Read the release notes and known limitations for the target version. +2. Verify release artifacts: + `SHA256SUMS`, signed release manifest, OpenAPI checksum, migration checksum, + release SBOM metadata, and release provenance metadata. +3. Back up PostgreSQL and object storage together. +4. Generate and verify a backup manifest. +5. Confirm the target profile still uses one API writer replica unless a later + release explicitly documents a reviewed multi-writer design. +6. Check that production secrets are externalized and that local plaintext + signing-key mode is not used in production. + +## Upgrade + +1. Stop API writers. +2. Let workers finish or stop them after recording pending outbox counts. +3. Apply migrations with `make migrate` or `evydence-migrate` using the target + release artifacts. +4. Start one API writer. +5. Start worker replicas. +6. Verify `/v1/ready`, a release-readiness report, an audit-chain verification, + a release bundle verification, and a representative package/export. + +## Rollback Or Forward Fix + +Evydence migrations are treated as forward-moving release evidence. Prefer a +forward fix when a migration has written new state. If an operator must restore +an older version, restore the matching PostgreSQL and object-store backups +together and record the data cut timestamp. + +## Evidence To Keep + +- Previous and target release artifact manifests and signatures. +- Migration checksum file. +- Backup manifest before upgrade. +- Upgrade command transcript with secrets redacted. +- Post-upgrade verification outputs and known limitations. diff --git a/docs/sdk/README.md b/docs/sdk/README.md index 8f3d66d..808e493 100644 --- a/docs/sdk/README.md +++ b/docs/sdk/README.md @@ -54,6 +54,9 @@ The helper rejects paths that do not start with `/v1/` and blank idempotency key The Go wrapper also exposes typed helpers for `CreateRelease`, `RegisterArtifact`, `CreateBuild`, `Readiness`, `ReleaseReadiness`, `CreateSSOProvider`, and `VerifyProviderIdentity`. `VerifyProviderIdentity` can carry an OIDC `id_token`, OIDC `access_token` for live UserInfo validation, or SAML `saml_assertion`; SDK errors intentionally include only the HTTP status code and not the response body. +See [`examples/sdk/go/main.go`](../../examples/sdk/go/main.go) for a minimal +product-create example. + ## TypeScript Import the source wrapper directly from the checkout or from your application-owned package copy. The wrapper uses `fetch`; Node.js 18+ provides it globally, and older runtimes should pass `fetchImpl`. @@ -76,6 +79,9 @@ The helper validates `/v1/` paths and idempotency keys. Non-2xx responses throw The TypeScript wrapper also exposes `createRelease`, `registerArtifact`, `createBuild`, `readiness`, `releaseReadiness`, `createSSOProvider`, and `verifyProviderIdentity` helpers over the same routes. +See [`examples/sdk/typescript/example.ts`](../../examples/sdk/typescript/example.ts) +for a minimal product-create example. + ## Python Put `sdk/python` on `PYTHONPATH`, install the copied module in your application package, or run the example from that directory: @@ -100,6 +106,9 @@ The helper validates `/v1/` paths and idempotency keys. HTTP errors raise `Runti The Python wrapper also exposes `create_release`, `register_artifact`, `create_build`, `readiness`, `release_readiness`, `create_sso_provider`, and `verify_provider_identity` helpers over the same routes. +See [`examples/sdk/python/example.py`](../../examples/sdk/python/example.py) +for a minimal product-create example. + ## Idempotency Guidance Use stable, operation-specific idempotency keys for create and action requests: diff --git a/examples/end-to-end-release-evidence/README.md b/examples/end-to-end-release-evidence/README.md new file mode 100644 index 0000000..a2ff394 --- /dev/null +++ b/examples/end-to-end-release-evidence/README.md @@ -0,0 +1,61 @@ +# End-To-End Release Evidence Example + +This example shows the product path Evydence should make easy to evaluate: + +1. CI builds an artifact and computes a digest. +2. CI uploads build provenance, SBOM, and vulnerability scan evidence. +3. Security records a VEX decision or approved exception for a blocking + finding. +4. Evydence creates a release bundle and readiness report. +5. Evydence exports customer-safe review evidence. + +The files in this directory are non-sensitive fixtures. They are not legal +compliance proof, certification, complete SBOM proof, authoritative +vulnerability results, or a secure-release guarantee. + +## Files + +- `release-evidence-manifest.json`: example CLI bulk-upload manifest. +- `sample-readiness-report.json`: representative readiness output with gaps and + limitations. +- `sample-customer-package-manifest.json`: representative customer package + manifest without raw tenant payload bytes. +- `sample-audit-chain-verification.json`: representative audit-chain + verification result. + +## Run Against A Local API + +Start Evydence with the getting-started tutorial or the production-like Compose +stack, then set: + +```sh +export EVYDENCE_URL=http://localhost:8080 +export EVYDENCE_API_KEY='evy_replace_with_scoped_secret' +``` + +Upload the manifest with the local CLI: + +```sh +go run ./cmd/evydence upload manifest \ + --api-url "$EVYDENCE_URL" \ + --api-key "$EVYDENCE_API_KEY" \ + --manifest examples/end-to-end-release-evidence/release-evidence-manifest.json +``` + +The manifest uses placeholder IDs. Replace `prod_example`, `proj_example`, +`rel_example`, and `art_example` with IDs created in your local tenant before +running it. + +For a complete local API flow that creates the IDs for you and writes example +outputs under `tmp/end-to-end-release-evidence/`, run: + +```sh +EVYDENCE_URL=http://localhost:8080 \ +EVYDENCE_API_KEY='evy_replace_with_scoped_secret' \ +examples/end-to-end-release-evidence/run-local-demo.sh +``` + +The script creates a product, release, artifact, SBOM, vulnerability scan, +vulnerability decision, release bundle, redaction profile, customer package, +readiness report, and audit-chain verification output. It expects a local API +that already has a tenant and scoped API key. diff --git a/examples/end-to-end-release-evidence/release-evidence-manifest.json b/examples/end-to-end-release-evidence/release-evidence-manifest.json new file mode 100644 index 0000000..d52700c --- /dev/null +++ b/examples/end-to-end-release-evidence/release-evidence-manifest.json @@ -0,0 +1,54 @@ +{ + "requests": [ + { + "path": "/v1/evidence", + "idempotency_key": "example-build-log", + "payload": { + "product_id": "prod_example", + "project_id": "proj_example", + "release_id": "rel_example", + "type": "build", + "subtype": "ci-log", + "title": "Example CI build log", + "payload_hash": "sha256:ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", + "tags": ["example", "ci"], + "limitations": ["Example fixture; replace with real CI output."] + } + }, + { + "path": "/v1/sboms", + "idempotency_key": "example-sbom", + "payload": { + "release_id": "rel_example", + "artifact_id": "art_example", + "payload": { + "bomFormat": "CycloneDX", + "specVersion": "1.6", + "components": [ + { + "name": "openssl", + "purl": "pkg:apk/openssl@3.1.0" + } + ] + } + } + }, + { + "path": "/v1/vulnerability-scans", + "idempotency_key": "example-vulnerability-scan", + "payload": { + "release_id": "rel_example", + "scanner": "grype", + "target_ref": "pkg:oci/example-api", + "findings": [ + { + "vulnerability": "CVE-2026-0099", + "component": "pkg:apk/openssl@3.1.0", + "severity": "critical", + "state": "open" + } + ] + } + } + ] +} diff --git a/examples/end-to-end-release-evidence/run-local-demo.sh b/examples/end-to-end-release-evidence/run-local-demo.sh new file mode 100755 index 0000000..38ff629 --- /dev/null +++ b/examples/end-to-end-release-evidence/run-local-demo.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env sh +set -eu + +: "${EVYDENCE_URL:=http://localhost:8080}" +: "${EVYDENCE_API_KEY:?EVYDENCE_API_KEY is required}" + +outdir="${EVYDENCE_DEMO_OUTDIR:-tmp/end-to-end-release-evidence}" +mkdir -p "$outdir" + +api() { + method="$1" + path="$2" + idem="$3" + body="$4" + if [ "$method" = "GET" ]; then + curl -sS "${EVYDENCE_URL}${path}" \ + -H "Authorization: Bearer ${EVYDENCE_API_KEY}" + else + curl -sS -X "$method" "${EVYDENCE_URL}${path}" \ + -H "Authorization: Bearer ${EVYDENCE_API_KEY}" \ + -H "Idempotency-Key: ${idem}" \ + -H "Content-Type: application/json" \ + --data "$body" + fi +} + +product="$(api POST /v1/products demo-product '{"name":"Demo Payments API","slug":"demo-payments-api"}')" +printf '%s\n' "$product" > "$outdir/product.json" +product_id="$(printf '%s' "$product" | jq -r '.data.id')" + +release="$(api POST /v1/releases demo-release "{\"product_id\":\"$product_id\",\"version\":\"1.0.0\"}")" +printf '%s\n' "$release" > "$outdir/release.json" +release_id="$(printf '%s' "$release" | jq -r '.data.id')" + +artifact="$(api POST /v1/artifacts demo-artifact "{\"release_id\":\"$release_id\",\"name\":\"payments-api.tar.gz\",\"media_type\":\"application/gzip\",\"digest\":\"sha256:ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb\",\"size\":42}")" +printf '%s\n' "$artifact" > "$outdir/artifact.json" +artifact_id="$(printf '%s' "$artifact" | jq -r '.data.id')" + +sbom="$(api POST /v1/sboms demo-sbom "{\"release_id\":\"$release_id\",\"artifact_id\":\"$artifact_id\",\"payload\":{\"bomFormat\":\"CycloneDX\",\"specVersion\":\"1.6\",\"components\":[{\"name\":\"openssl\",\"purl\":\"pkg:apk/openssl@3.1.0\"}]}}")" +printf '%s\n' "$sbom" > "$outdir/sbom.json" + +scan="$(api POST /v1/vulnerability-scans demo-scan "{\"release_id\":\"$release_id\",\"scanner\":\"grype\",\"target_ref\":\"pkg:oci/payments-api\",\"findings\":[{\"vulnerability\":\"CVE-2026-0099\",\"component\":\"pkg:apk/openssl@3.1.0\",\"severity\":\"critical\",\"state\":\"open\"}]}")" +printf '%s\n' "$scan" > "$outdir/vulnerability-scan.json" +finding_id="$(printf '%s' "$scan" | jq -r '.data.findings[0].id')" + +decision="$(api POST "/v1/vulnerability-findings/${finding_id}/decisions" demo-decision '{"status":"not_affected","justification":"Demo decision; replace with release-specific technical analysis."}')" +printf '%s\n' "$decision" > "$outdir/vulnerability-decision.json" + +bundle="$(api POST /v1/release-bundles demo-release-bundle "{\"release_id\":\"$release_id\"}")" +printf '%s\n' "$bundle" > "$outdir/release-bundle.json" + +profile="$(api POST /v1/redaction-profiles demo-redaction-profile '{"name":"Demo customer redaction","allowed_types":["sbom","vulnerability_scan","release_bundle"],"excluded_fields":["raw_payload","secrets"]}')" +printf '%s\n' "$profile" > "$outdir/redaction-profile.json" +profile_id="$(printf '%s' "$profile" | jq -r '.data.id')" + +package="$(api POST /v1/customer-packages demo-customer-package "{\"product_id\":\"$product_id\",\"release_id\":\"$release_id\",\"redaction_profile_id\":\"$profile_id\",\"title\":\"Demo customer release evidence\",\"expires_at\":\"2026-06-30T00:00:00Z\"}")" +printf '%s\n' "$package" > "$outdir/customer-package.json" + +readiness="$(api GET "/v1/reports/release-readiness?release_id=${release_id}" "" "")" +printf '%s\n' "$readiness" > "$outdir/release-readiness.json" + +audit="$(api GET /v1/audit-chain/verify "" "")" +printf '%s\n' "$audit" > "$outdir/audit-chain-verification.json" + +printf 'wrote demo evidence outputs to %s\n' "$outdir" +printf 'release_id=%s\n' "$release_id" diff --git a/examples/end-to-end-release-evidence/sample-audit-chain-verification.json b/examples/end-to-end-release-evidence/sample-audit-chain-verification.json new file mode 100644 index 0000000..5250e56 --- /dev/null +++ b/examples/end-to-end-release-evidence/sample-audit-chain-verification.json @@ -0,0 +1,19 @@ +{ + "data": { + "id": "ver_example_audit_chain", + "subject_type": "audit_chain", + "subject_id": "tenant-example", + "result": "passed", + "checked_at": "2026-05-31T09:00:00Z", + "checks": [ + { + "name": "audit_chain_hash_continuity", + "result": "passed", + "detail": "Every entry links to the previous hash for the tenant range." + } + ], + "limitations": [ + "Example output for documentation; verify a real tenant chain in the target deployment." + ] + } +} diff --git a/examples/end-to-end-release-evidence/sample-customer-package-manifest.json b/examples/end-to-end-release-evidence/sample-customer-package-manifest.json new file mode 100644 index 0000000..66abaad --- /dev/null +++ b/examples/end-to-end-release-evidence/sample-customer-package-manifest.json @@ -0,0 +1,23 @@ +{ + "data": { + "id": "pkg_example", + "release_id": "rel_example", + "scope": "customer_review", + "expires_at": "2026-06-30T00:00:00Z", + "manifest_hash": "sha256:example", + "included_subjects": [ + "release_bundle", + "readiness_report", + "sbom_summary", + "vulnerability_decisions" + ], + "redactions": [ + "raw evidence payload bytes are excluded", + "secrets and private keys are excluded" + ], + "limitations": [ + "Customer package supports technical evidence review only.", + "It is not legal compliance proof, certification, or a secure-release guarantee." + ] + } +} diff --git a/examples/end-to-end-release-evidence/sample-readiness-report.json b/examples/end-to-end-release-evidence/sample-readiness-report.json new file mode 100644 index 0000000..b0b62c8 --- /dev/null +++ b/examples/end-to-end-release-evidence/sample-readiness-report.json @@ -0,0 +1,32 @@ +{ + "data": { + "release_id": "rel_example", + "result": "failed", + "checks": [ + { + "name": "sbom_present", + "result": "passed", + "detail": "At least one SBOM is linked to the release." + }, + { + "name": "critical_findings_handled", + "result": "failed", + "detail": "One critical finding remains open without a valid decision or approved unexpired exception." + } + ], + "blocking_findings": [ + { + "id": "finding_example", + "vulnerability": "CVE-2026-0099", + "severity": "critical", + "state": "open" + } + ], + "assumptions": [ + "Scanner output is treated as submitted evidence, not authoritative vulnerability truth." + ], + "limitations": [ + "Example report; run against real release evidence before relying on it." + ] + } +} diff --git a/examples/sdk/go/main.go b/examples/sdk/go/main.go new file mode 100644 index 0000000..b876df4 --- /dev/null +++ b/examples/sdk/go/main.go @@ -0,0 +1,131 @@ +package main + +import ( + "context" + "fmt" + "os" + + "github.com/aatuh/evydence/sdk/go/evydence" +) + +func main() { + client := evydence.Client{ + BaseURL: env("EVYDENCE_URL", "http://localhost:8080"), + APIKey: os.Getenv("EVYDENCE_API_KEY"), + } + + ctx := context.Background() + + var product map[string]any + if err := client.CreateProduct(context.Background(), "example-go-product", evydence.CreateProductRequest{ + Name: "Example API", + Slug: "example-api", + }, &product); err != nil { + panic(err) + } + productID := id(product) + + var release map[string]any + if err := client.CreateRelease(ctx, "example-go-release", evydence.CreateReleaseRequest{ + ProductID: productID, + Version: "1.0.0", + }, &release); err != nil { + panic(err) + } + releaseID := id(release) + + var artifact map[string]any + if err := client.RegisterArtifact(ctx, "example-go-artifact", evydence.RegisterArtifactRequest{ + ReleaseID: releaseID, + Name: "example-api.tar.gz", + MediaType: "application/gzip", + Digest: "sha256:ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", + Size: 42, + }, &artifact); err != nil { + panic(err) + } + artifactID := id(artifact) + + if err := client.Post(ctx, "/v1/sboms", "example-go-sbom", map[string]any{ + "release_id": releaseID, + "artifact_id": artifactID, + "payload": map[string]any{ + "bomFormat": "CycloneDX", + "specVersion": "1.6", + "components": []map[string]string{{ + "name": "openssl", + "purl": "pkg:apk/openssl@3.1.0", + }}, + }, + }, nil); err != nil { + panic(err) + } + + var scan map[string]any + if err := client.Post(ctx, "/v1/vulnerability-scans", "example-go-scan", map[string]any{ + "release_id": releaseID, + "scanner": "grype", + "target_ref": "pkg:oci/example-api", + "findings": []map[string]string{{ + "vulnerability": "CVE-2026-0099", + "component": "pkg:apk/openssl@3.1.0", + "severity": "critical", + "state": "open", + }}, + }, &scan); err != nil { + panic(err) + } + findingID := nestedID(scan, "findings") + + if err := client.Post(ctx, "/v1/vulnerability-findings/"+findingID+"/decisions", "example-go-decision", map[string]any{ + "status": "not_affected", + "justification": "Example decision; replace with real technical analysis.", + }, nil); err != nil { + panic(err) + } + + var readiness map[string]any + if err := client.ReleaseReadiness(ctx, releaseID, &readiness); err != nil { + panic(err) + } + fmt.Printf("release readiness: %#v\n", readiness["data"]) +} + +func env(key, fallback string) string { + if value := os.Getenv(key); value != "" { + return value + } + return fallback +} + +func id(envelope map[string]any) string { + data, ok := envelope["data"].(map[string]any) + if !ok { + panic("missing data envelope") + } + value, ok := data["id"].(string) + if !ok || value == "" { + panic("missing id") + } + return value +} + +func nestedID(envelope map[string]any, field string) string { + data, ok := envelope["data"].(map[string]any) + if !ok { + panic("missing data envelope") + } + items, ok := data[field].([]any) + if !ok || len(items) == 0 { + panic("missing nested items") + } + first, ok := items[0].(map[string]any) + if !ok { + panic("nested item has unexpected shape") + } + value, ok := first["id"].(string) + if !ok || value == "" { + panic("missing nested id") + } + return value +} diff --git a/examples/sdk/go/main_test.go b/examples/sdk/go/main_test.go new file mode 100644 index 0000000..940d9ac --- /dev/null +++ b/examples/sdk/go/main_test.go @@ -0,0 +1,130 @@ +package main + +import ( + "encoding/json" + "net/http" + "net/http/httptest" + "os" + "strings" + "testing" +) + +func TestMainRunsCoreEvidenceFlow(t *testing.T) { + type observedRequest struct { + method string + path string + idempotencyKey string + } + var observed []observedRequest + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if got := r.Header.Get("Authorization"); got != "Bearer example-secret" { + t.Fatalf("unexpected auth header %q", got) + } + observed = append(observed, observedRequest{method: r.Method, path: r.URL.RequestURI(), idempotencyKey: r.Header.Get("Idempotency-Key")}) + if r.Method == http.MethodPost && strings.TrimSpace(r.Header.Get("Idempotency-Key")) == "" { + t.Fatalf("missing idempotency key for %s", r.URL.Path) + } + + var body map[string]any + if r.Body != nil { + if err := json.NewDecoder(r.Body).Decode(&body); err != nil && r.Method != http.MethodGet { + t.Fatalf("decode request for %s: %v", r.URL.Path, err) + } + } + switch { + case r.Method == http.MethodPost && r.URL.Path == "/v1/products": + assertField(t, body, "slug", "example-api") + writeJSON(w, http.StatusCreated, map[string]any{"data": map[string]any{"id": "prod_1"}}) + case r.Method == http.MethodPost && r.URL.Path == "/v1/releases": + assertField(t, body, "product_id", "prod_1") + writeJSON(w, http.StatusCreated, map[string]any{"data": map[string]any{"id": "rel_1"}}) + case r.Method == http.MethodPost && r.URL.Path == "/v1/artifacts": + assertField(t, body, "release_id", "rel_1") + writeJSON(w, http.StatusCreated, map[string]any{"data": map[string]any{"id": "art_1"}}) + case r.Method == http.MethodPost && r.URL.Path == "/v1/sboms": + assertField(t, body, "artifact_id", "art_1") + writeJSON(w, http.StatusCreated, map[string]any{"data": map[string]any{"id": "sbom_1"}}) + case r.Method == http.MethodPost && r.URL.Path == "/v1/vulnerability-scans": + if _, ok := body["scanned_at"]; ok { + t.Fatal("example sent unsupported scanned_at field") + } + assertField(t, body, "release_id", "rel_1") + writeJSON(w, http.StatusCreated, map[string]any{"data": map[string]any{ + "id": "scan_1", + "findings": []map[string]any{{"id": "finding_1"}}, + }}) + case r.Method == http.MethodPost && r.URL.Path == "/v1/vulnerability-findings/finding_1/decisions": + assertField(t, body, "status", "not_affected") + writeJSON(w, http.StatusCreated, map[string]any{"data": map[string]any{"id": "decision_1"}}) + case r.Method == http.MethodGet && r.URL.Path == "/v1/reports/release-readiness": + if got := r.URL.Query().Get("release_id"); got != "rel_1" { + t.Fatalf("unexpected release_id query %q", got) + } + writeJSON(w, http.StatusOK, map[string]any{"data": map[string]any{"result": "failed"}}) + default: + t.Fatalf("unexpected request %s %s", r.Method, r.URL.RequestURI()) + } + })) + defer server.Close() + + t.Setenv("EVYDENCE_URL", server.URL) + t.Setenv("EVYDENCE_API_KEY", "example-secret") + + stdout := os.Stdout + devNull, err := os.Open(os.DevNull) + if err != nil { + t.Fatal(err) + } + defer devNull.Close() + os.Stdout = devNull + defer func() { os.Stdout = stdout }() + + main() + + wantPaths := []string{ + "/v1/products", + "/v1/releases", + "/v1/artifacts", + "/v1/sboms", + "/v1/vulnerability-scans", + "/v1/vulnerability-findings/finding_1/decisions", + "/v1/reports/release-readiness?release_id=rel_1", + } + if len(observed) != len(wantPaths) { + t.Fatalf("observed %d requests, want %d: %#v", len(observed), len(wantPaths), observed) + } + for i, want := range wantPaths { + if observed[i].path != want { + t.Fatalf("request %d path = %q, want %q", i, observed[i].path, want) + } + } +} + +func TestEnvelopeIDHelpersRejectUnexpectedShapes(t *testing.T) { + assertPanics(t, func() { _ = id(map[string]any{}) }) + assertPanics(t, func() { _ = nestedID(map[string]any{"data": map[string]any{"findings": []any{}}}, "findings") }) +} + +func assertField(t *testing.T, body map[string]any, field, want string) { + t.Helper() + got, _ := body[field].(string) + if got != want { + t.Fatalf("%s = %q, want %q", field, got, want) + } +} + +func writeJSON(w http.ResponseWriter, status int, payload map[string]any) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(status) + _ = json.NewEncoder(w).Encode(payload) +} + +func assertPanics(t *testing.T, fn func()) { + t.Helper() + defer func() { + if recover() == nil { + t.Fatal("expected panic") + } + }() + fn() +} diff --git a/examples/sdk/python/example.py b/examples/sdk/python/example.py new file mode 100644 index 0000000..98d455e --- /dev/null +++ b/examples/sdk/python/example.py @@ -0,0 +1,77 @@ +import os + +from evydence_client import EvydenceClient + + +client = EvydenceClient( + base_url=os.environ.get("EVYDENCE_URL", "http://localhost:8080"), + api_key=os.environ["EVYDENCE_API_KEY"], +) + +product = client.create_product( + "example-python-product", + {"name": "Example API", "slug": "example-api"}, +) +product_id = product["data"]["id"] + +release = client.create_release( + "example-python-release", + {"product_id": product_id, "version": "1.0.0"}, +) +release_id = release["data"]["id"] + +artifact = client.register_artifact( + "example-python-artifact", + { + "release_id": release_id, + "name": "example-api.tar.gz", + "media_type": "application/gzip", + "digest": "sha256:ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", + "size": 42, + }, +) +artifact_id = artifact["data"]["id"] + +client.post( + "/v1/sboms", + "example-python-sbom", + { + "release_id": release_id, + "artifact_id": artifact_id, + "payload": { + "bomFormat": "CycloneDX", + "specVersion": "1.6", + "components": [{"name": "openssl", "purl": "pkg:apk/openssl@3.1.0"}], + }, + }, +) + +scan = client.post( + "/v1/vulnerability-scans", + "example-python-scan", + { + "release_id": release_id, + "scanner": "grype", + "target_ref": "pkg:oci/example-api", + "findings": [ + { + "vulnerability": "CVE-2026-0099", + "component": "pkg:apk/openssl@3.1.0", + "severity": "critical", + "state": "open", + } + ], + }, +) +finding_id = scan["data"]["findings"][0]["id"] + +client.post( + f"/v1/vulnerability-findings/{finding_id}/decisions", + "example-python-decision", + { + "status": "not_affected", + "justification": "Example decision; replace with real technical analysis.", + }, +) + +print(client.release_readiness(release_id)["data"]) diff --git a/examples/sdk/typescript/example.ts b/examples/sdk/typescript/example.ts new file mode 100644 index 0000000..3cc228a --- /dev/null +++ b/examples/sdk/typescript/example.ts @@ -0,0 +1,64 @@ +import { EvydenceClient } from "../../sdk/typescript/client"; + +const client = new EvydenceClient({ + baseUrl: process.env.EVYDENCE_URL ?? "http://localhost:8080", + apiKey: process.env.EVYDENCE_API_KEY ?? "", +}); + +const product = await client.createProduct<{ data: { id: string } }>( + "example-typescript-product", + { name: "Example API", slug: "example-api" }, +); + +const release = await client.createRelease<{ data: { id: string } }>( + "example-typescript-release", + { product_id: product.data.id, version: "1.0.0" }, +); + +const artifact = await client.registerArtifact<{ data: { id: string } }>( + "example-typescript-artifact", + { + release_id: release.data.id, + name: "example-api.tar.gz", + media_type: "application/gzip", + digest: "sha256:ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", + size: 42, + }, +); + +await client.post("/v1/sboms", "example-typescript-sbom", { + release_id: release.data.id, + artifact_id: artifact.data.id, + payload: { + bomFormat: "CycloneDX", + specVersion: "1.6", + components: [{ name: "openssl", purl: "pkg:apk/openssl@3.1.0" }], + }, +}); + +const scan = await client.post<{ data: { findings: Array<{ id: string }> } }>( + "/v1/vulnerability-scans", + "example-typescript-scan", + { + release_id: release.data.id, + scanner: "grype", + target_ref: "pkg:oci/example-api", + findings: [{ + vulnerability: "CVE-2026-0099", + component: "pkg:apk/openssl@3.1.0", + severity: "critical", + state: "open", + }], + }, +); + +await client.post( + `/v1/vulnerability-findings/${scan.data.findings[0].id}/decisions`, + "example-typescript-decision", + { + status: "not_affected", + justification: "Example decision; replace with real technical analysis.", + }, +); + +console.log(await client.releaseReadiness(release.data.id)); diff --git a/scripts/release_candidate_package.sh b/scripts/release_candidate_package.sh index 1ac0e03..9661ea6 100755 --- a/scripts/release_candidate_package.sh +++ b/scripts/release_candidate_package.sh @@ -99,12 +99,15 @@ rm -f "$distdir/release-notes.md.bak" (cd "$distdir" && sha256sum openapi.yaml > openapi.sha256) (cd "$repo_root" && find migrations -type f -print | LC_ALL=C sort | xargs sha256sum > "$distdir/migrations.sha256") +python3 scripts/release_evidence_metadata.py "$tag" "$distdir" (cd "$distdir" && sha256sum \ evydence_${tag}_*.tar.gz \ evydence_${tag}_*.zip \ openapi.yaml \ openapi.sha256 \ + evydence-release-sbom.cdx.json \ + evydence-release-provenance.json \ coverage.out \ release-check-summary.txt \ migrations.sha256 \ @@ -124,6 +127,8 @@ cli="${signing_dir}/evydence_${tag}_linux_amd64/evydence" "$distdir"/evydence_${tag}_*.zip \ "$distdir/openapi.yaml" \ "$distdir/openapi.sha256" \ + "$distdir/evydence-release-sbom.cdx.json" \ + "$distdir/evydence-release-provenance.json" \ "$distdir/coverage.out" \ "$distdir/release-check-summary.txt" \ "$distdir/migrations.sha256" \ diff --git a/scripts/release_candidate_validate.sh b/scripts/release_candidate_validate.sh index 7ebdc6b..2245054 100755 --- a/scripts/release_candidate_validate.sh +++ b/scripts/release_candidate_validate.sh @@ -24,6 +24,8 @@ required=( "SHA256SUMS" "openapi.yaml" "openapi.sha256" + "evydence-release-sbom.cdx.json" + "evydence-release-provenance.json" "migrations.sha256" "coverage.out" "release-check-summary.txt" @@ -59,6 +61,8 @@ grep -Fi "complete SBOM proof" "$distdir/release-notes.md" >/dev/null grep -Fi "authoritative vulnerability coverage" "$distdir/release-notes.md" >/dev/null grep -Fi "single API writer replica" "$distdir/release-notes.md" >/dev/null grep -Fi "full repository decomposition" "$distdir/release-notes.md" >/dev/null +grep -Fi "complete SBOM proof" "$distdir/evydence-release-sbom.cdx.json" >/dev/null +grep -Fi "not a SLSA level claim" "$distdir/evydence-release-provenance.json" >/dev/null if grep -R -i "automatically compliant\|certified secure\|legally sufficient\|SBOM is complete\|all vulnerabilities detected\|scanner findings are authoritative\|regulator-ready without review" "$distdir/release-notes.md" >/dev/null; then echo "release notes contain a prohibited product claim" >&2 diff --git a/scripts/release_evidence_metadata.py b/scripts/release_evidence_metadata.py new file mode 100755 index 0000000..161b82f --- /dev/null +++ b/scripts/release_evidence_metadata.py @@ -0,0 +1,144 @@ +#!/usr/bin/env python3 +"""Generate deterministic release-candidate SBOM and provenance metadata.""" + +from __future__ import annotations + +import hashlib +import json +import os +from pathlib import Path +import subprocess +import sys +import uuid + + +def run(args: list[str]) -> str: + return subprocess.check_output(args, text=True).strip() + + +def sha256(path: Path) -> str: + h = hashlib.sha256() + with path.open("rb") as fh: + for chunk in iter(lambda: fh.read(1024 * 1024), b""): + h.update(chunk) + return h.hexdigest() + + +def go_modules() -> list[dict[str, str]]: + raw = subprocess.check_output(["go", "list", "-m", "-json", "all"], text=True) + decoder = json.JSONDecoder() + modules: list[dict[str, str]] = [] + idx = 0 + while idx < len(raw): + while idx < len(raw) and raw[idx].isspace(): + idx += 1 + if idx >= len(raw): + break + obj, idx = decoder.raw_decode(raw, idx) + path = str(obj.get("Path", "")).strip() + if not path: + continue + version = str(obj.get("Version", "")).strip() + replacement = obj.get("Replace") + if isinstance(replacement, dict): + version = str(replacement.get("Version") or replacement.get("Path") or version).strip() + modules.append({"path": path, "version": version}) + modules.sort(key=lambda item: (item["path"], item["version"])) + return modules + + +def write_json(path: Path, payload: dict) -> None: + path.write_text(json.dumps(payload, indent=2, sort_keys=True) + "\n", encoding="utf-8") + + +def main() -> int: + if len(sys.argv) != 3: + print("usage: scripts/release_evidence_metadata.py ", file=sys.stderr) + return 2 + tag = sys.argv[1].strip() + distdir = Path(sys.argv[2]).resolve() + repo = Path.cwd().resolve() + try: + distdir.relative_to(repo) + except ValueError: + print("distdir must be inside the repository", file=sys.stderr) + return 2 + if not distdir.is_dir(): + print(f"distdir missing: {distdir}", file=sys.stderr) + return 2 + + commit = run(["git", "rev-parse", "HEAD"]) + commit_date = run(["git", "show", "-s", "--format=%cI", "HEAD"]) + go_version = run(["go", "version"]) + modules = go_modules() + + sbom = { + "bomFormat": "CycloneDX", + "specVersion": "1.6", + "serialNumber": "urn:uuid:" + str(uuid.uuid5(uuid.NAMESPACE_URL, "github.com/aatuh/evydence:" + tag)), + "version": 1, + "metadata": { + "component": { + "type": "application", + "name": "evydence", + "version": tag, + "purl": "pkg:github/aatuh/evydence@" + tag, + }, + "properties": [ + {"name": "evydence:commit", "value": commit}, + {"name": "evydence:commit_date", "value": commit_date}, + {"name": "evydence:go_version", "value": go_version}, + {"name": "evydence:limitations", "value": "Release SBOM is generated from Go module metadata and release packaging inputs; it is not a complete SBOM proof."}, + ], + }, + "components": [ + { + "type": "library", + "name": module["path"], + "version": module["version"], + "purl": f"pkg:golang/{module['path']}@{module['version']}" if module["version"] else f"pkg:golang/{module['path']}", + } + for module in modules + if module["path"] != "github.com/aatuh/evydence" + ], + } + + artifact_names = sorted( + path.name + for pattern in ("evydence_*.tar.gz", "evydence_*.zip", "openapi.yaml", "migrations.sha256", "release-notes.md") + for path in distdir.glob(pattern) + ) + provenance = { + "schema": "evydence-release-provenance.v1", + "subject": {"name": "evydence", "version": tag, "commit": commit, "commit_date": commit_date}, + "builder": { + "type": "local-or-github-actions-release-candidate-packager", + "commands": ["make production-check", "scripts/release_candidate_package.sh"], + "go_version": go_version, + }, + "materials": [ + {"path": name, "sha256": sha256(distdir / name)} + for name in artifact_names + if (distdir / name).is_file() + ], + "limitations": [ + "This provenance records repository release-candidate packaging inputs and hashes.", + "It is not a SLSA level claim, legal compliance proof, certification, complete SBOM proof, authoritative vulnerability result, or secure-release guarantee.", + "Public release publication, registry image digest verification, branch protection, and provider account settings require operator verification outside repository files.", + ], + "environment": { + "github_repository": os.environ.get("GITHUB_REPOSITORY", ""), + "github_run_id": os.environ.get("GITHUB_RUN_ID", ""), + "github_ref": os.environ.get("GITHUB_REF", ""), + }, + } + + write_json(distdir / "evydence-release-sbom.cdx.json", sbom) + write_json(distdir / "evydence-release-provenance.json", provenance) + print(f"wrote {distdir / 'evydence-release-sbom.cdx.json'}") + print(f"wrote {distdir / 'evydence-release-provenance.json'}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/site/package-viewer/index.html b/site/package-viewer/index.html new file mode 100644 index 0000000..5fd9365 --- /dev/null +++ b/site/package-viewer/index.html @@ -0,0 +1,182 @@ + + + + + + Evydence Package Viewer + + + +
+

Evydence Package Viewer

+

+ Open a customer package, release-readiness report, evidence bundle, or + package manifest JSON file locally. This viewer never uploads data. +

+ +
+ + No file loaded. +
+ +
+

Boundary

+

+ Viewer output supports technical evidence review only. It is not legal + compliance proof, certification, complete SBOM proof, an authoritative + vulnerability result, or a secure-release guarantee. +

+
+ +
+
{}
+
+ + + + From 772fe22e2cfbee424a20af7cee96da6b5f2c986e Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 16:08:03 +0300 Subject: [PATCH 146/287] refactor: split ledger application services --- internal/app/authz_inventory_test.go | 19 +- internal/app/benchmark_test.go | 46 +++++ internal/app/controls.go | 6 +- internal/app/critical_mutation_test.go | 30 ++++ internal/app/enterprise.go | 54 ++++-- internal/app/future_extensions.go | 12 +- internal/app/governance_packages.go | 33 ++-- internal/app/identity_service.go | 220 +++++++++++++++++++++++ internal/app/ledger.go | 190 +++++--------------- internal/app/package_report_service.go | 107 +++++++++++ internal/app/release_evidence_service.go | 123 +++++++++++++ internal/app/risk_workflows.go | 6 +- internal/app/vex.go | 21 ++- 13 files changed, 677 insertions(+), 190 deletions(-) create mode 100644 internal/app/benchmark_test.go create mode 100644 internal/app/identity_service.go create mode 100644 internal/app/package_report_service.go create mode 100644 internal/app/release_evidence_service.go diff --git a/internal/app/authz_inventory_test.go b/internal/app/authz_inventory_test.go index af465be..97d7f40 100644 --- a/internal/app/authz_inventory_test.go +++ b/internal/app/authz_inventory_test.go @@ -64,9 +64,22 @@ func TestResourceScopedAuthorizationCoverageInventory(t *testing.T) { func functionBody(t *testing.T, fileBody, name string) string { t.Helper() - marker := "func (l *Ledger) " + name - start := strings.Index(fileBody, marker) - if start < 0 { + markers := []string{ + "func (l *Ledger) " + name, + "func (s identityService) " + name, + "func (s releaseEvidenceService) " + name, + "func (s packageReportService) " + name, + } + start := -1 + marker := "" + for _, candidate := range markers { + if idx := strings.Index(fileBody, candidate); idx >= 0 { + start = idx + marker = candidate + break + } + } + if marker == "" { t.Fatalf("missing function %s", name) } rest := fileBody[start+len(marker):] diff --git a/internal/app/benchmark_test.go b/internal/app/benchmark_test.go new file mode 100644 index 0000000..acd2c14 --- /dev/null +++ b/internal/app/benchmark_test.go @@ -0,0 +1,46 @@ +package app + +import ( + "context" + "strconv" + "testing" +) + +func BenchmarkReleaseEvidenceIngestion(b *testing.B) { + ctx := context.Background() + ledger := NewLedger(Config{APIKeyPepper: "benchmark-pepper"}) + _, _, secret, err := ledger.BootstrapTenant(ctx, "Benchmark Tenant", "admin", []string{"*"}) + if err != nil { + b.Fatal(err) + } + actor, err := ledger.Authenticate(ctx, secret) + if err != nil { + b.Fatal(err) + } + product, err := ledger.CreateProduct(ctx, actor, "Benchmark Product", "bench-product") + if err != nil { + b.Fatal(err) + } + release, err := ledger.CreateRelease(ctx, actor, product.ID, "1.0.0") + if err != nil { + b.Fatal(err) + } + + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, err := ledger.CreateEvidence(ctx, actor, CreateEvidenceInput{ + ProductID: product.ID, + ReleaseID: release.ID, + Type: "build", + Subtype: "benchmark", + Title: "Benchmark evidence " + strconv.Itoa(i), + PayloadHash: "sha256:ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", + Tags: []string{"benchmark"}, + Limitations: []string{"Local benchmark evidence only."}, + }) + if err != nil { + b.Fatal(err) + } + } +} diff --git a/internal/app/controls.go b/internal/app/controls.go index 0caa326..f936613 100644 --- a/internal/app/controls.go +++ b/internal/app/controls.go @@ -285,7 +285,8 @@ func (l *Ledger) ListControlEvidence(ctx context.Context, actor domain.Actor, co return out, nil } -func (l *Ledger) ControlCoverageReport(ctx context.Context, actor domain.Actor, in ControlCoverageReportInput) (domain.ControlCoverageReport, error) { +func (s packageReportService) ControlCoverageReport(ctx context.Context, actor domain.Actor, in ControlCoverageReportInput) (domain.ControlCoverageReport, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.ControlCoverageReport{}, err } @@ -304,7 +305,8 @@ func (l *Ledger) ControlCoverageReport(ctx context.Context, actor domain.Actor, return report, nil } -func (l *Ledger) CRAReadinessReport(ctx context.Context, actor domain.Actor, in CRAReadinessReportInput) (domain.CRAReadinessReport, error) { +func (s packageReportService) CRAReadinessReport(ctx context.Context, actor domain.Actor, in CRAReadinessReportInput) (domain.CRAReadinessReport, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.CRAReadinessReport{}, err } diff --git a/internal/app/critical_mutation_test.go b/internal/app/critical_mutation_test.go index 62f5cbe..1faeb11 100644 --- a/internal/app/critical_mutation_test.go +++ b/internal/app/critical_mutation_test.go @@ -477,4 +477,34 @@ func TestRelationalStateStoreAvoidsAggregateSaveForRemainingFamilies(t *testing. if got := store.states[0].Incidents[incident.ID]; got.ID != incident.ID || got.TenantID != actor.TenantID { t.Fatalf("relational state missed incident: %#v", got) } + + store.reset() + profile, err := ledger.CreateRedactionProfile(ctx, actor, CreateRedactionProfileInput{Name: "Customer Safe", AllowedTypes: []string{"sbom", "vulnerability_scan"}}) + if err != nil { + t.Fatalf("create redaction profile: %v", err) + } + if store.saveCalls != 0 || store.relationalCalls != 1 { + t.Fatalf("redaction persistence save=%d relational=%d", store.saveCalls, store.relationalCalls) + } + if got := store.states[0].RedactionProfiles[profile.ID]; got.ID != profile.ID || got.TenantID != actor.TenantID { + t.Fatalf("relational state missed redaction profile: %#v", got) + } + + store.reset() + pkg, err := ledger.CreateCustomerSecurityPackage(ctx, actor, CreateCustomerPackageInput{ + ProductID: product.ID, + ReleaseID: release.ID, + RedactionProfileID: profile.ID, + Title: "Customer package", + ExpiresAt: fixedNow().Add(time.Hour), + }) + if err != nil { + t.Fatalf("create customer package: %v", err) + } + if store.saveCalls != 0 || store.relationalCalls != 1 { + t.Fatalf("customer package persistence save=%d relational=%d", store.saveCalls, store.relationalCalls) + } + if got := store.states[0].CustomerPackages[pkg.ID]; got.ID != pkg.ID || got.TenantID != actor.TenantID { + t.Fatalf("relational state missed customer package: %#v", got) + } } diff --git a/internal/app/enterprise.go b/internal/app/enterprise.go index bdcdbca..4d3fa32 100644 --- a/internal/app/enterprise.go +++ b/internal/app/enterprise.go @@ -113,7 +113,8 @@ type CreateCommercialCollectorInput struct { AllowedScopes []string } -func (l *Ledger) CreateOrganization(ctx context.Context, actor domain.Actor, in CreateOrganizationInput) (domain.Organization, error) { +func (s identityService) CreateOrganization(ctx context.Context, actor domain.Actor, in CreateOrganizationInput) (domain.Organization, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.Organization{}, err } @@ -140,7 +141,8 @@ func (l *Ledger) CreateOrganization(ctx context.Context, actor domain.Actor, in return org, nil } -func (l *Ledger) CreateUser(ctx context.Context, actor domain.Actor, in CreateUserInput) (domain.HumanUser, error) { +func (s identityService) CreateUser(ctx context.Context, actor domain.Actor, in CreateUserInput) (domain.HumanUser, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.HumanUser{}, err } @@ -174,7 +176,8 @@ func (l *Ledger) CreateUser(ctx context.Context, actor domain.Actor, in CreateUs return user, nil } -func (l *Ledger) DeactivateUser(ctx context.Context, actor domain.Actor, id string) (domain.HumanUser, error) { +func (s identityService) DeactivateUser(ctx context.Context, actor domain.Actor, id string) (domain.HumanUser, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.HumanUser{}, err } @@ -201,7 +204,8 @@ func (l *Ledger) DeactivateUser(ctx context.Context, actor domain.Actor, id stri return user, nil } -func (l *Ledger) CreateRoleBinding(ctx context.Context, actor domain.Actor, in CreateRoleBindingInput) (domain.RoleBinding, error) { +func (s identityService) CreateRoleBinding(ctx context.Context, actor domain.Actor, in CreateRoleBindingInput) (domain.RoleBinding, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.RoleBinding{}, err } @@ -230,7 +234,8 @@ func (l *Ledger) CreateRoleBinding(ctx context.Context, actor domain.Actor, in C return binding, nil } -func (l *Ledger) ListRoleBindings(ctx context.Context, actor domain.Actor) ([]domain.RoleBinding, error) { +func (s identityService) ListRoleBindings(ctx context.Context, actor domain.Actor) ([]domain.RoleBinding, error) { + l := s.ledger if err := ctx.Err(); err != nil { return nil, err } @@ -248,7 +253,8 @@ func (l *Ledger) ListRoleBindings(ctx context.Context, actor domain.Actor) ([]do return out, nil } -func (l *Ledger) CreateSSOProvider(ctx context.Context, actor domain.Actor, in CreateSSOProviderInput) (domain.SSOProvider, error) { +func (s identityService) CreateSSOProvider(ctx context.Context, actor domain.Actor, in CreateSSOProviderInput) (domain.SSOProvider, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.SSOProvider{}, err } @@ -278,7 +284,8 @@ func (l *Ledger) CreateSSOProvider(ctx context.Context, actor domain.Actor, in C return provider, nil } -func (l *Ledger) UpdateSSOProviderTrustMaterial(ctx context.Context, actor domain.Actor, id string, in UpdateSSOProviderTrustMaterialInput) (domain.SSOProvider, error) { +func (s identityService) UpdateSSOProviderTrustMaterial(ctx context.Context, actor domain.Actor, id string, in UpdateSSOProviderTrustMaterialInput) (domain.SSOProvider, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.SSOProvider{}, err } @@ -343,7 +350,8 @@ func (l *Ledger) UpdateSSOProviderTrustMaterial(ctx context.Context, actor domai return provider, nil } -func (l *Ledger) RefreshSSOProviderOIDCTrustMaterial(ctx context.Context, actor domain.Actor, id string) (domain.SSOProvider, error) { +func (s identityService) RefreshSSOProviderOIDCTrustMaterial(ctx context.Context, actor domain.Actor, id string) (domain.SSOProvider, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.SSOProvider{}, err } @@ -420,7 +428,8 @@ func (l *Ledger) RefreshSSOProviderOIDCTrustMaterial(ctx context.Context, actor return current, nil } -func (l *Ledger) LinkSSOIdentity(ctx context.Context, actor domain.Actor, in LinkSSOIdentityInput) (domain.UserIdentityLink, error) { +func (s identityService) LinkSSOIdentity(ctx context.Context, actor domain.Actor, in LinkSSOIdentityInput) (domain.UserIdentityLink, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.UserIdentityLink{}, err } @@ -451,7 +460,8 @@ func (l *Ledger) LinkSSOIdentity(ctx context.Context, actor domain.Actor, in Lin return link, nil } -func (l *Ledger) CreateSSOSession(ctx context.Context, actor domain.Actor, in CreateSSOSessionInput) (domain.SSOSession, string, error) { +func (s identityService) CreateSSOSession(ctx context.Context, actor domain.Actor, in CreateSSOSessionInput) (domain.SSOSession, string, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.SSOSession{}, "", err } @@ -482,7 +492,8 @@ func (l *Ledger) CreateSSOSession(ctx context.Context, actor domain.Actor, in Cr return session, secret, nil } -func (l *Ledger) ExchangeSSOCredential(ctx context.Context, in ExchangeSSOCredentialInput) (domain.ProviderVerification, domain.SSOSession, string, error) { +func (s identityService) ExchangeSSOCredential(ctx context.Context, in ExchangeSSOCredentialInput) (domain.ProviderVerification, domain.SSOSession, string, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.ProviderVerification{}, domain.SSOSession{}, "", err } @@ -600,7 +611,8 @@ func (l *Ledger) ExchangeSSOCredential(ctx context.Context, in ExchangeSSOCreden return verification, session, secret, nil } -func (l *Ledger) RevokeSSOSession(ctx context.Context, actor domain.Actor, id string) (domain.SSOSession, error) { +func (s identityService) RevokeSSOSession(ctx context.Context, actor domain.Actor, id string) (domain.SSOSession, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.SSOSession{}, err } @@ -627,7 +639,8 @@ func (l *Ledger) RevokeSSOSession(ctx context.Context, actor domain.Actor, id st return session, nil } -func (l *Ledger) RevokeCurrentSSOSession(ctx context.Context, actor domain.Actor) (domain.SSOSession, error) { +func (s identityService) RevokeCurrentSSOSession(ctx context.Context, actor domain.Actor) (domain.SSOSession, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.SSOSession{}, err } @@ -716,7 +729,8 @@ func (l *Ledger) CreateRetentionOverride(ctx context.Context, actor domain.Actor return override, nil } -func (l *Ledger) RetentionReport(ctx context.Context, actor domain.Actor, scopeType, scopeID string) (domain.RetentionReport, error) { +func (s packageReportService) RetentionReport(ctx context.Context, actor domain.Actor, scopeType, scopeID string) (domain.RetentionReport, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.RetentionReport{}, err } @@ -740,7 +754,8 @@ func (l *Ledger) RetentionReport(ctx context.Context, actor domain.Actor, scopeT return domain.RetentionReport{ReportType: "retention", ScopeType: scopeType, ScopeID: scopeID, LegalHolds: holds, RetentionOverrides: overrides, Limitations: []string{"Retention reports describe Evydence records and do not replace external storage lifecycle verification."}, GeneratedAt: l.now()}, nil } -func (l *Ledger) CreateCustomerPortalAccess(ctx context.Context, actor domain.Actor, in CreateCustomerPortalAccessInput) (domain.CustomerPortalAccess, string, error) { +func (s identityService) CreateCustomerPortalAccess(ctx context.Context, actor domain.Actor, in CreateCustomerPortalAccessInput) (domain.CustomerPortalAccess, string, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.CustomerPortalAccess{}, "", err } @@ -768,7 +783,8 @@ func (l *Ledger) CreateCustomerPortalAccess(ctx context.Context, actor domain.Ac return access, secret, nil } -func (l *Ledger) AccessCustomerPortalPackage(ctx context.Context, token string) (domain.CustomerSecurityPackage, error) { +func (s identityService) AccessCustomerPortalPackage(ctx context.Context, token string) (domain.CustomerSecurityPackage, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.CustomerSecurityPackage{}, err } @@ -815,7 +831,8 @@ func (l *Ledger) AccessCustomerPortalPackage(ctx context.Context, token string) return domain.CustomerSecurityPackage{}, ErrUnauthorized } -func (l *Ledger) CreateQuestionnaireTemplate(ctx context.Context, actor domain.Actor, in CreateQuestionnaireTemplateInput) (domain.QuestionnaireTemplate, error) { +func (s packageReportService) CreateQuestionnaireTemplate(ctx context.Context, actor domain.Actor, in CreateQuestionnaireTemplateInput) (domain.QuestionnaireTemplate, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.QuestionnaireTemplate{}, err } @@ -847,7 +864,8 @@ func (l *Ledger) CreateQuestionnaireTemplate(ctx context.Context, actor domain.A return tpl, nil } -func (l *Ledger) CreateQuestionnairePackage(ctx context.Context, actor domain.Actor, in CreateQuestionnairePackageInput) (domain.QuestionnairePackage, error) { +func (s packageReportService) CreateQuestionnairePackage(ctx context.Context, actor domain.Actor, in CreateQuestionnairePackageInput) (domain.QuestionnairePackage, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.QuestionnairePackage{}, err } diff --git a/internal/app/future_extensions.go b/internal/app/future_extensions.go index 7be16bd..1ef6b85 100644 --- a/internal/app/future_extensions.go +++ b/internal/app/future_extensions.go @@ -107,7 +107,8 @@ type VerifyProviderIdentityInput struct { AccessToken string } -func (l *Ledger) CreateEvidenceSummary(ctx context.Context, actor domain.Actor, in CreateEvidenceSummaryInput) (domain.EvidenceSummary, error) { +func (s packageReportService) CreateEvidenceSummary(ctx context.Context, actor domain.Actor, in CreateEvidenceSummaryInput) (domain.EvidenceSummary, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.EvidenceSummary{}, err } @@ -169,7 +170,8 @@ func (l *Ledger) CreateEvidenceSummary(ctx context.Context, actor domain.Actor, return summary, nil } -func (l *Ledger) CreateQuestionnaireDraft(ctx context.Context, actor domain.Actor, in CreateQuestionnaireDraftInput) (domain.QuestionnaireDraft, error) { +func (s packageReportService) CreateQuestionnaireDraft(ctx context.Context, actor domain.Actor, in CreateQuestionnaireDraftInput) (domain.QuestionnaireDraft, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.QuestionnaireDraft{}, err } @@ -1050,7 +1052,8 @@ func verifySAMLAssertionSignature(certs []string, payload, signature []byte) err return errors.New("no configured saml signing certificate verified assertion") } -func (l *Ledger) CreatePDFReportPackage(ctx context.Context, actor domain.Actor, in CreatePDFReportPackageInput) (domain.PDFReportPackage, error) { +func (s packageReportService) CreatePDFReportPackage(ctx context.Context, actor domain.Actor, in CreatePDFReportPackageInput) (domain.PDFReportPackage, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.PDFReportPackage{}, err } @@ -1085,7 +1088,8 @@ func (l *Ledger) CreatePDFReportPackage(ctx context.Context, actor domain.Actor, return record, nil } -func (l *Ledger) GenerateAnomalyReport(ctx context.Context, actor domain.Actor, in AnomalyReportInput) (domain.AnomalyReport, error) { +func (s packageReportService) GenerateAnomalyReport(ctx context.Context, actor domain.Actor, in AnomalyReportInput) (domain.AnomalyReport, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.AnomalyReport{}, err } diff --git a/internal/app/governance_packages.go b/internal/app/governance_packages.go index 236dcd0..fff3766 100644 --- a/internal/app/governance_packages.go +++ b/internal/app/governance_packages.go @@ -203,7 +203,8 @@ func (l *Ledger) CreateApprovalRecord(ctx context.Context, actor domain.Actor, i return approval, nil } -func (l *Ledger) CreateRedactionProfile(ctx context.Context, actor domain.Actor, in CreateRedactionProfileInput) (domain.RedactionProfile, error) { +func (s packageReportService) CreateRedactionProfile(ctx context.Context, actor domain.Actor, in CreateRedactionProfileInput) (domain.RedactionProfile, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.RedactionProfile{}, err } @@ -230,7 +231,8 @@ func (l *Ledger) CreateRedactionProfile(ctx context.Context, actor domain.Actor, return profile, nil } -func (l *Ledger) CreateCustomerSecurityPackage(ctx context.Context, actor domain.Actor, in CreateCustomerPackageInput) (domain.CustomerSecurityPackage, error) { +func (s packageReportService) CreateCustomerSecurityPackage(ctx context.Context, actor domain.Actor, in CreateCustomerPackageInput) (domain.CustomerSecurityPackage, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.CustomerSecurityPackage{}, err } @@ -277,7 +279,8 @@ func (l *Ledger) CreateCustomerSecurityPackage(ctx context.Context, actor domain return pkg, nil } -func (l *Ledger) AccessCustomerSecurityPackage(ctx context.Context, actor domain.Actor, id string) (domain.CustomerSecurityPackage, error) { +func (s packageReportService) AccessCustomerSecurityPackage(ctx context.Context, actor domain.Actor, id string) (domain.CustomerSecurityPackage, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.CustomerSecurityPackage{}, err } @@ -305,7 +308,8 @@ func (l *Ledger) AccessCustomerSecurityPackage(ctx context.Context, actor domain return pkg, nil } -func (l *Ledger) ExportCustomerSecurityPackageArchive(ctx context.Context, actor domain.Actor, id string) (CustomerPackageArchive, error) { +func (s packageReportService) ExportCustomerSecurityPackageArchive(ctx context.Context, actor domain.Actor, id string) (CustomerPackageArchive, error) { + l := s.ledger pkg, err := l.AccessCustomerSecurityPackage(ctx, actor, id) if err != nil { return CustomerPackageArchive{}, err @@ -313,7 +317,8 @@ func (l *Ledger) ExportCustomerSecurityPackageArchive(ctx context.Context, actor return customerPackageArchive(pkg) } -func (l *Ledger) ExportCustomerPortalPackageArchive(ctx context.Context, token string) (CustomerPackageArchive, error) { +func (s packageReportService) ExportCustomerPortalPackageArchive(ctx context.Context, token string) (CustomerPackageArchive, error) { + l := s.ledger pkg, err := l.AccessCustomerPortalPackage(ctx, token) if err != nil { return CustomerPackageArchive{}, err @@ -321,7 +326,8 @@ func (l *Ledger) ExportCustomerPortalPackageArchive(ctx context.Context, token s return customerPackageArchive(pkg) } -func (l *Ledger) SecurityReviewPackageReport(ctx context.Context, actor domain.Actor, packageID string) (domain.SecurityReviewPackageReport, error) { +func (s packageReportService) SecurityReviewPackageReport(ctx context.Context, actor domain.Actor, packageID string) (domain.SecurityReviewPackageReport, error) { + l := s.ledger pkg, err := l.AccessCustomerSecurityPackage(ctx, actor, packageID) if err != nil { return domain.SecurityReviewPackageReport{}, err @@ -414,7 +420,8 @@ func addZIPFile(zw *zip.Writer, name string, body []byte) error { return err } -func (l *Ledger) CRAReadinessHTMLPackage(ctx context.Context, actor domain.Actor, productID, releaseID string) (domain.HTMLReportPackage, error) { +func (s packageReportService) CRAReadinessHTMLPackage(ctx context.Context, actor domain.Actor, productID, releaseID string) (domain.HTMLReportPackage, error) { + l := s.ledger report, err := l.CRAReadinessReport(ctx, actor, CRAReadinessReportInput{ProductID: productID, ReleaseID: releaseID}) if err != nil { return domain.HTMLReportPackage{}, err @@ -483,7 +490,8 @@ func (l *Ledger) InstallControlFrameworkTemplatePack(ctx context.Context, actor return framework, nil } -func (l *Ledger) CreateCustomReportTemplate(ctx context.Context, actor domain.Actor, in CreateReportTemplateInput) (domain.CustomReportTemplate, error) { +func (s packageReportService) CreateCustomReportTemplate(ctx context.Context, actor domain.Actor, in CreateReportTemplateInput) (domain.CustomReportTemplate, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.CustomReportTemplate{}, err } @@ -505,7 +513,8 @@ func (l *Ledger) CreateCustomReportTemplate(ctx context.Context, actor domain.Ac return tpl, nil } -func (l *Ledger) RenderCustomReport(ctx context.Context, actor domain.Actor, in RenderReportInput) (domain.RenderedCustomReport, error) { +func (s packageReportService) RenderCustomReport(ctx context.Context, actor domain.Actor, in RenderReportInput) (domain.RenderedCustomReport, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.RenderedCustomReport{}, err } @@ -538,7 +547,8 @@ func (l *Ledger) RenderCustomReport(ctx context.Context, actor domain.Actor, in return rendered, nil } -func (l *Ledger) ExportEvidenceBundle(ctx context.Context, actor domain.Actor, releaseID string, evidenceIDs []string) (domain.EvidenceBundle, error) { +func (s packageReportService) ExportEvidenceBundle(ctx context.Context, actor domain.Actor, releaseID string, evidenceIDs []string) (domain.EvidenceBundle, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.EvidenceBundle{}, err } @@ -600,7 +610,8 @@ func (l *Ledger) ExportEvidenceBundle(ctx context.Context, actor domain.Actor, r return bundle, nil } -func (l *Ledger) ImportEvidenceBundle(ctx context.Context, actor domain.Actor, bundle domain.EvidenceBundle) (domain.EvidenceBundleImport, error) { +func (s packageReportService) ImportEvidenceBundle(ctx context.Context, actor domain.Actor, bundle domain.EvidenceBundle) (domain.EvidenceBundleImport, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.EvidenceBundleImport{}, err } diff --git a/internal/app/identity_service.go b/internal/app/identity_service.go new file mode 100644 index 0000000..34791ac --- /dev/null +++ b/internal/app/identity_service.go @@ -0,0 +1,220 @@ +package app + +import ( + "context" + "sort" + "strings" + "time" + + "github.com/aatuh/evydence/internal/domain" +) + +type identityService struct { + ledger *Ledger +} + +func (l *Ledger) identityService() identityService { + return identityService{ledger: l} +} + +func (s identityService) HasTenants() bool { + l := s.ledger + l.mu.Lock() + defer l.mu.Unlock() + return len(l.tenants) > 0 +} + +func (s identityService) BootstrapTenant(ctx context.Context, name, keyName string, scopes []string) (domain.Tenant, domain.APIKey, string, error) { + l := s.ledger + if err := ctx.Err(); err != nil { + return domain.Tenant{}, domain.APIKey{}, "", err + } + name = strings.TrimSpace(name) + keyName = strings.TrimSpace(keyName) + if name == "" || keyName == "" { + return domain.Tenant{}, domain.APIKey{}, "", ErrValidation + } + if len(scopes) == 0 { + scopes = []string{"*"} + } + l.mu.Lock() + defer l.mu.Unlock() + now := l.now() + tenant := domain.Tenant{ID: newID("ten"), Name: name, CreatedAt: now} + l.tenants[tenant.ID] = tenant + key, secret, err := l.createAPIKeyLocked(tenant.ID, keyName, scopes, nil) + if err != nil { + return domain.Tenant{}, domain.APIKey{}, "", err + } + if _, err := l.rotateSigningKeyLocked(tenant.ID, "bootstrap"); err != nil { + return domain.Tenant{}, domain.APIKey{}, "", err + } + _, _ = l.appendChainLocked(tenant.ID, "tenant.created", "tenant", tenant.ID, "system", "bootstrap", "", "") + if err := l.persistCriticalLocked(ctx, l.criticalMutationLocked()); err != nil { + return domain.Tenant{}, domain.APIKey{}, "", err + } + return tenant, key, secret, nil +} + +func (s identityService) Authenticate(ctx context.Context, secret string) (domain.Actor, error) { + l := s.ledger + if err := ctx.Err(); err != nil { + return domain.Actor{}, err + } + secret = strings.TrimSpace(strings.TrimPrefix(secret, "Bearer ")) + if secret == "" { + return domain.Actor{}, ErrUnauthorized + } + prefix := secretPrefix(secret) + hash := l.hashSecret(secret) + l.mu.Lock() + defer l.mu.Unlock() + for id, key := range l.apiKeys { + if key.Prefix != prefix || !secretHashEqual(key.Hash, hash) || key.RevokedAt != nil { + continue + } + if key.ExpiresAt != nil && !key.ExpiresAt.After(l.now()) { + return domain.Actor{}, ErrUnauthorized + } + now := l.now() + key.LastUsedAt = &now + l.apiKeys[id] = key + collectorID := "" + for collectorMapID, collector := range l.collectors { + if collector.TenantID == key.TenantID && collector.APIKeyID == key.ID { + collectorID = collector.ID + collector.LastSeenAt = &now + l.collectors[collectorMapID] = collector + break + } + } + _ = l.persistCriticalLocked(ctx, l.criticalMutationLocked()) + return domain.Actor{TenantID: key.TenantID, KeyID: key.ID, Name: key.Name, Scopes: append([]string(nil), key.Scopes...), CollectorID: collectorID}, nil + } + for id, session := range l.ssoSessions { + if session.Prefix != prefix || !secretHashEqual(session.Hash, hash) || session.RevokedAt != nil || !session.ExpiresAt.After(l.now()) { + continue + } + user, ok := l.users[session.UserID] + if !ok || user.TenantID != session.TenantID || user.Status != "active" { + return domain.Actor{}, ErrUnauthorized + } + grants := append(l.resourceGrantsForUserLocked(user.ID), l.resourceGrantsForSSOSessionLocked(session)...) + scopes := scopesFromResourceGrants(grants) + if len(scopes) == 0 { + return domain.Actor{}, ErrForbidden + } + l.ssoSessions[id] = session + _ = l.persistCriticalLocked(ctx, l.criticalMutationLocked()) + return domain.Actor{TenantID: user.TenantID, UserID: user.ID, SessionID: session.ID, Name: user.Email, Scopes: scopes, ResourceGrants: grants}, nil + } + return domain.Actor{}, ErrUnauthorized +} + +func (s identityService) CreateAPIKey(ctx context.Context, actor domain.Actor, name string, scopes []string, expiresAt *time.Time) (domain.APIKey, string, error) { + l := s.ledger + if err := ctx.Err(); err != nil { + return domain.APIKey{}, "", err + } + if err := require(actor, ScopeAdmin); err != nil { + return domain.APIKey{}, "", err + } + if strings.TrimSpace(name) == "" || len(scopes) == 0 { + return domain.APIKey{}, "", ErrValidation + } + if err := requireGrantableScopes(actor, scopes); err != nil { + return domain.APIKey{}, "", err + } + l.mu.Lock() + defer l.mu.Unlock() + key, secret, err := l.createAPIKeyLocked(actor.TenantID, name, scopes, expiresAt) + if err != nil { + return domain.APIKey{}, "", err + } + _, _ = l.appendChainLocked(actor.TenantID, "api_key.created", "api_key", key.ID, "api_key", actor.KeyID, "", "") + if err := l.persistCriticalLocked(ctx, l.criticalMutationLocked()); err != nil { + return domain.APIKey{}, "", err + } + return key, secret, nil +} + +func (s identityService) ListAPIKeys(ctx context.Context, actor domain.Actor) ([]domain.APIKey, error) { + l := s.ledger + if err := ctx.Err(); err != nil { + return nil, err + } + if err := require(actor, ScopeAdmin); err != nil { + return nil, err + } + l.mu.Lock() + defer l.mu.Unlock() + out := []domain.APIKey{} + for _, key := range l.apiKeys { + if key.TenantID == actor.TenantID { + key.Hash = "" + out = append(out, key) + } + } + sort.Slice(out, func(i, j int) bool { return out[i].ID < out[j].ID }) + return out, nil +} + +func (l *Ledger) CreateOrganization(ctx context.Context, actor domain.Actor, in CreateOrganizationInput) (domain.Organization, error) { + return l.identityService().CreateOrganization(ctx, actor, in) +} + +func (l *Ledger) CreateUser(ctx context.Context, actor domain.Actor, in CreateUserInput) (domain.HumanUser, error) { + return l.identityService().CreateUser(ctx, actor, in) +} + +func (l *Ledger) DeactivateUser(ctx context.Context, actor domain.Actor, id string) (domain.HumanUser, error) { + return l.identityService().DeactivateUser(ctx, actor, id) +} + +func (l *Ledger) CreateRoleBinding(ctx context.Context, actor domain.Actor, in CreateRoleBindingInput) (domain.RoleBinding, error) { + return l.identityService().CreateRoleBinding(ctx, actor, in) +} + +func (l *Ledger) ListRoleBindings(ctx context.Context, actor domain.Actor) ([]domain.RoleBinding, error) { + return l.identityService().ListRoleBindings(ctx, actor) +} + +func (l *Ledger) CreateSSOProvider(ctx context.Context, actor domain.Actor, in CreateSSOProviderInput) (domain.SSOProvider, error) { + return l.identityService().CreateSSOProvider(ctx, actor, in) +} + +func (l *Ledger) UpdateSSOProviderTrustMaterial(ctx context.Context, actor domain.Actor, id string, in UpdateSSOProviderTrustMaterialInput) (domain.SSOProvider, error) { + return l.identityService().UpdateSSOProviderTrustMaterial(ctx, actor, id, in) +} + +func (l *Ledger) RefreshSSOProviderOIDCTrustMaterial(ctx context.Context, actor domain.Actor, id string) (domain.SSOProvider, error) { + return l.identityService().RefreshSSOProviderOIDCTrustMaterial(ctx, actor, id) +} + +func (l *Ledger) LinkSSOIdentity(ctx context.Context, actor domain.Actor, in LinkSSOIdentityInput) (domain.UserIdentityLink, error) { + return l.identityService().LinkSSOIdentity(ctx, actor, in) +} + +func (l *Ledger) CreateSSOSession(ctx context.Context, actor domain.Actor, in CreateSSOSessionInput) (domain.SSOSession, string, error) { + return l.identityService().CreateSSOSession(ctx, actor, in) +} + +func (l *Ledger) ExchangeSSOCredential(ctx context.Context, in ExchangeSSOCredentialInput) (domain.ProviderVerification, domain.SSOSession, string, error) { + return l.identityService().ExchangeSSOCredential(ctx, in) +} + +func (l *Ledger) RevokeSSOSession(ctx context.Context, actor domain.Actor, id string) (domain.SSOSession, error) { + return l.identityService().RevokeSSOSession(ctx, actor, id) +} + +func (l *Ledger) RevokeCurrentSSOSession(ctx context.Context, actor domain.Actor) (domain.SSOSession, error) { + return l.identityService().RevokeCurrentSSOSession(ctx, actor) +} + +func (l *Ledger) CreateCustomerPortalAccess(ctx context.Context, actor domain.Actor, in CreateCustomerPortalAccessInput) (domain.CustomerPortalAccess, string, error) { + return l.identityService().CreateCustomerPortalAccess(ctx, actor, in) +} + +func (l *Ledger) AccessCustomerPortalPackage(ctx context.Context, token string) (domain.CustomerSecurityPackage, error) { + return l.identityService().AccessCustomerPortalPackage(ctx, token) +} diff --git a/internal/app/ledger.go b/internal/app/ledger.go index ff47f48..f0d8553 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -324,143 +324,27 @@ func NewLedgerWithError(cfg Config) (*Ledger, error) { } func (l *Ledger) HasTenants() bool { - l.mu.Lock() - defer l.mu.Unlock() - return len(l.tenants) > 0 + return l.identityService().HasTenants() } func (l *Ledger) BootstrapTenant(ctx context.Context, name, keyName string, scopes []string) (domain.Tenant, domain.APIKey, string, error) { - if err := ctx.Err(); err != nil { - return domain.Tenant{}, domain.APIKey{}, "", err - } - name = strings.TrimSpace(name) - keyName = strings.TrimSpace(keyName) - if name == "" || keyName == "" { - return domain.Tenant{}, domain.APIKey{}, "", ErrValidation - } - if len(scopes) == 0 { - scopes = []string{"*"} - } - l.mu.Lock() - defer l.mu.Unlock() - now := l.now() - tenant := domain.Tenant{ID: newID("ten"), Name: name, CreatedAt: now} - l.tenants[tenant.ID] = tenant - key, secret, err := l.createAPIKeyLocked(tenant.ID, keyName, scopes, nil) - if err != nil { - return domain.Tenant{}, domain.APIKey{}, "", err - } - if _, err := l.rotateSigningKeyLocked(tenant.ID, "bootstrap"); err != nil { - return domain.Tenant{}, domain.APIKey{}, "", err - } - _, _ = l.appendChainLocked(tenant.ID, "tenant.created", "tenant", tenant.ID, "system", "bootstrap", "", "") - if err := l.persistCriticalLocked(ctx, l.criticalMutationLocked()); err != nil { - return domain.Tenant{}, domain.APIKey{}, "", err - } - return tenant, key, secret, nil + return l.identityService().BootstrapTenant(ctx, name, keyName, scopes) } func (l *Ledger) Authenticate(ctx context.Context, secret string) (domain.Actor, error) { - if err := ctx.Err(); err != nil { - return domain.Actor{}, err - } - secret = strings.TrimSpace(strings.TrimPrefix(secret, "Bearer ")) - if secret == "" { - return domain.Actor{}, ErrUnauthorized - } - prefix := secretPrefix(secret) - hash := l.hashSecret(secret) - l.mu.Lock() - defer l.mu.Unlock() - for id, key := range l.apiKeys { - if key.Prefix != prefix || !secretHashEqual(key.Hash, hash) || key.RevokedAt != nil { - continue - } - if key.ExpiresAt != nil && !key.ExpiresAt.After(l.now()) { - return domain.Actor{}, ErrUnauthorized - } - now := l.now() - key.LastUsedAt = &now - l.apiKeys[id] = key - collectorID := "" - for collectorMapID, collector := range l.collectors { - if collector.TenantID == key.TenantID && collector.APIKeyID == key.ID { - collectorID = collector.ID - collector.LastSeenAt = &now - l.collectors[collectorMapID] = collector - break - } - } - _ = l.persistCriticalLocked(ctx, l.criticalMutationLocked()) - return domain.Actor{TenantID: key.TenantID, KeyID: key.ID, Name: key.Name, Scopes: append([]string(nil), key.Scopes...), CollectorID: collectorID}, nil - } - for id, session := range l.ssoSessions { - if session.Prefix != prefix || !secretHashEqual(session.Hash, hash) || session.RevokedAt != nil || !session.ExpiresAt.After(l.now()) { - continue - } - user, ok := l.users[session.UserID] - if !ok || user.TenantID != session.TenantID || user.Status != "active" { - return domain.Actor{}, ErrUnauthorized - } - grants := append(l.resourceGrantsForUserLocked(user.ID), l.resourceGrantsForSSOSessionLocked(session)...) - scopes := scopesFromResourceGrants(grants) - if len(scopes) == 0 { - return domain.Actor{}, ErrForbidden - } - l.ssoSessions[id] = session - _ = l.persistCriticalLocked(ctx, l.criticalMutationLocked()) - return domain.Actor{TenantID: user.TenantID, UserID: user.ID, SessionID: session.ID, Name: user.Email, Scopes: scopes, ResourceGrants: grants}, nil - } - return domain.Actor{}, ErrUnauthorized + return l.identityService().Authenticate(ctx, secret) } func (l *Ledger) CreateAPIKey(ctx context.Context, actor domain.Actor, name string, scopes []string, expiresAt *time.Time) (domain.APIKey, string, error) { - if err := ctx.Err(); err != nil { - return domain.APIKey{}, "", err - } - if err := require(actor, ScopeAdmin); err != nil { - return domain.APIKey{}, "", err - } - if strings.TrimSpace(name) == "" || len(scopes) == 0 { - return domain.APIKey{}, "", ErrValidation - } - if err := requireGrantableScopes(actor, scopes); err != nil { - return domain.APIKey{}, "", err - } - l.mu.Lock() - defer l.mu.Unlock() - key, secret, err := l.createAPIKeyLocked(actor.TenantID, name, scopes, expiresAt) - if err != nil { - return domain.APIKey{}, "", err - } - _, _ = l.appendChainLocked(actor.TenantID, "api_key.created", "api_key", key.ID, "api_key", actor.KeyID, "", "") - if err := l.persistCriticalLocked(ctx, l.criticalMutationLocked()); err != nil { - return domain.APIKey{}, "", err - } - return key, secret, nil + return l.identityService().CreateAPIKey(ctx, actor, name, scopes, expiresAt) } func (l *Ledger) ListAPIKeys(ctx context.Context, actor domain.Actor) ([]domain.APIKey, error) { - if err := ctx.Err(); err != nil { - return nil, err - } - if err := require(actor, ScopeAdmin); err != nil { - return nil, err - } - l.mu.Lock() - defer l.mu.Unlock() - out := []domain.APIKey{} - for _, key := range l.apiKeys { - if key.TenantID == actor.TenantID { - key.Hash = "" - out = append(out, key) - } - } - sort.Slice(out, func(i, j int) bool { return out[i].ID < out[j].ID }) - return out, nil + return l.identityService().ListAPIKeys(ctx, actor) } -func (l *Ledger) CreateProduct(ctx context.Context, actor domain.Actor, name, slug string) (domain.Product, error) { +func (s releaseEvidenceService) CreateProduct(ctx context.Context, actor domain.Actor, name, slug string) (domain.Product, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.Product{}, err } @@ -490,7 +374,8 @@ func (l *Ledger) CreateProduct(ctx context.Context, actor domain.Actor, name, sl return product, nil } -func (l *Ledger) ListProducts(ctx context.Context, actor domain.Actor) ([]domain.Product, error) { +func (s releaseEvidenceService) ListProducts(ctx context.Context, actor domain.Actor) ([]domain.Product, error) { + l := s.ledger if err := ctx.Err(); err != nil { return nil, err } @@ -509,7 +394,8 @@ func (l *Ledger) ListProducts(ctx context.Context, actor domain.Actor) ([]domain return out, nil } -func (l *Ledger) CreateProject(ctx context.Context, actor domain.Actor, productID, name string) (domain.Project, error) { +func (s releaseEvidenceService) CreateProject(ctx context.Context, actor domain.Actor, productID, name string) (domain.Project, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.Project{}, err } @@ -538,7 +424,8 @@ func (l *Ledger) CreateProject(ctx context.Context, actor domain.Actor, productI return project, nil } -func (l *Ledger) CreateRelease(ctx context.Context, actor domain.Actor, productID, version string) (domain.Release, error) { +func (s releaseEvidenceService) CreateRelease(ctx context.Context, actor domain.Actor, productID, version string) (domain.Release, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.Release{}, err } @@ -572,7 +459,8 @@ func (l *Ledger) CreateRelease(ctx context.Context, actor domain.Actor, productI return release, nil } -func (l *Ledger) GetRelease(ctx context.Context, actor domain.Actor, releaseID string) (domain.Release, error) { +func (s releaseEvidenceService) GetRelease(ctx context.Context, actor domain.Actor, releaseID string) (domain.Release, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.Release{}, err } @@ -591,7 +479,8 @@ func (l *Ledger) GetRelease(ctx context.Context, actor domain.Actor, releaseID s return release, nil } -func (l *Ledger) FreezeRelease(ctx context.Context, actor domain.Actor, releaseID string) (domain.Release, error) { +func (s releaseEvidenceService) FreezeRelease(ctx context.Context, actor domain.Actor, releaseID string) (domain.Release, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.Release{}, err } @@ -621,7 +510,8 @@ func (l *Ledger) FreezeRelease(ctx context.Context, actor domain.Actor, releaseI return release, nil } -func (l *Ledger) ApproveRelease(ctx context.Context, actor domain.Actor, releaseID string) (domain.Release, error) { +func (s releaseEvidenceService) ApproveRelease(ctx context.Context, actor domain.Actor, releaseID string) (domain.Release, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.Release{}, err } @@ -651,7 +541,8 @@ func (l *Ledger) ApproveRelease(ctx context.Context, actor domain.Actor, release return release, nil } -func (l *Ledger) RegisterArtifact(ctx context.Context, actor domain.Actor, name, mediaType, digest string, size int64) (domain.Artifact, error) { +func (s releaseEvidenceService) RegisterArtifact(ctx context.Context, actor domain.Actor, name, mediaType, digest string, size int64) (domain.Artifact, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.Artifact{}, err } @@ -701,7 +592,8 @@ type CreateEvidenceInput struct { Limitations []string } -func (l *Ledger) CreateEvidence(ctx context.Context, actor domain.Actor, in CreateEvidenceInput) (domain.EvidenceItem, error) { +func (s releaseEvidenceService) CreateEvidence(ctx context.Context, actor domain.Actor, in CreateEvidenceInput) (domain.EvidenceItem, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.EvidenceItem{}, err } @@ -778,7 +670,8 @@ func (l *Ledger) CreateEvidence(ctx context.Context, actor domain.Actor, in Crea return item, nil } -func (l *Ledger) GetEvidence(ctx context.Context, actor domain.Actor, id string) (domain.EvidenceItem, error) { +func (s releaseEvidenceService) GetEvidence(ctx context.Context, actor domain.Actor, id string) (domain.EvidenceItem, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.EvidenceItem{}, err } @@ -797,7 +690,8 @@ func (l *Ledger) GetEvidence(ctx context.Context, actor domain.Actor, id string) return item, nil } -func (l *Ledger) ListEvidence(ctx context.Context, actor domain.Actor, releaseID, typ string) ([]domain.EvidenceItem, error) { +func (s releaseEvidenceService) ListEvidence(ctx context.Context, actor domain.Actor, releaseID, typ string) ([]domain.EvidenceItem, error) { + l := s.ledger if err := ctx.Err(); err != nil { return nil, err } @@ -826,7 +720,8 @@ func (l *Ledger) ListEvidence(ctx context.Context, actor domain.Actor, releaseID return out, nil } -func (l *Ledger) SupersedeEvidence(ctx context.Context, actor domain.Actor, id, replacementID, reason string) (domain.EvidenceItem, error) { +func (s releaseEvidenceService) SupersedeEvidence(ctx context.Context, actor domain.Actor, id, replacementID, reason string) (domain.EvidenceItem, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.EvidenceItem{}, err } @@ -863,7 +758,8 @@ func (l *Ledger) SupersedeEvidence(ctx context.Context, actor domain.Actor, id, return item, nil } -func (l *Ledger) LinkEvidence(ctx context.Context, actor domain.Actor, id, targetType, targetID string) (domain.EvidenceItem, error) { +func (s releaseEvidenceService) LinkEvidence(ctx context.Context, actor domain.Actor, id, targetType, targetID string) (domain.EvidenceItem, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.EvidenceItem{}, err } @@ -914,7 +810,8 @@ func (l *Ledger) LinkEvidence(ctx context.Context, actor domain.Actor, id, targe return item, nil } -func (l *Ledger) UploadSBOM(ctx context.Context, actor domain.Actor, releaseID, artifactID string, raw []byte) (domain.SBOM, error) { +func (s releaseEvidenceService) UploadSBOM(ctx context.Context, actor domain.Actor, releaseID, artifactID string, raw []byte) (domain.SBOM, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.SBOM{}, err } @@ -1001,7 +898,8 @@ func (l *Ledger) UploadSBOM(ctx context.Context, actor domain.Actor, releaseID, return sbom, nil } -func (l *Ledger) UploadVulnerabilityScan(ctx context.Context, actor domain.Actor, raw []byte) (domain.VulnerabilityScan, error) { +func (s releaseEvidenceService) UploadVulnerabilityScan(ctx context.Context, actor domain.Actor, raw []byte) (domain.VulnerabilityScan, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.VulnerabilityScan{}, err } @@ -1095,7 +993,8 @@ func (l *Ledger) UploadVulnerabilityScan(ctx context.Context, actor domain.Actor return scan, nil } -func (l *Ledger) UploadOpenAPIContract(ctx context.Context, actor domain.Actor, productID, releaseID, version string, raw []byte) (domain.OpenAPIContract, error) { +func (s releaseEvidenceService) UploadOpenAPIContract(ctx context.Context, actor domain.Actor, productID, releaseID, version string, raw []byte) (domain.OpenAPIContract, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.OpenAPIContract{}, err } @@ -1389,7 +1288,8 @@ func (l *Ledger) GetReleaseBundle(ctx context.Context, actor domain.Actor, id st return bundle, nil } -func (l *Ledger) GetSBOM(ctx context.Context, actor domain.Actor, id string) (domain.SBOM, error) { +func (s releaseEvidenceService) GetSBOM(ctx context.Context, actor domain.Actor, id string) (domain.SBOM, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.SBOM{}, err } @@ -1417,7 +1317,8 @@ type ListSBOMComponentsInput struct { Limit int } -func (l *Ledger) ListSBOMComponents(ctx context.Context, actor domain.Actor, in ListSBOMComponentsInput) ([]domain.SBOMComponentRecord, error) { +func (s releaseEvidenceService) ListSBOMComponents(ctx context.Context, actor domain.Actor, in ListSBOMComponentsInput) ([]domain.SBOMComponentRecord, error) { + l := s.ledger if err := ctx.Err(); err != nil { return nil, err } @@ -1490,7 +1391,8 @@ func sbomComponentMatches(component domain.SBOMComponent, query, purl string) bo return strings.Contains(haystack, query) } -func (l *Ledger) GetVulnerabilityScan(ctx context.Context, actor domain.Actor, id string) (domain.VulnerabilityScan, error) { +func (s releaseEvidenceService) GetVulnerabilityScan(ctx context.Context, actor domain.Actor, id string) (domain.VulnerabilityScan, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.VulnerabilityScan{}, err } @@ -1509,7 +1411,8 @@ func (l *Ledger) GetVulnerabilityScan(ctx context.Context, actor domain.Actor, i return scan, nil } -func (l *Ledger) GetOpenAPIContract(ctx context.Context, actor domain.Actor, id string) (domain.OpenAPIContract, error) { +func (s releaseEvidenceService) GetOpenAPIContract(ctx context.Context, actor domain.Actor, id string) (domain.OpenAPIContract, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.OpenAPIContract{}, err } @@ -1672,7 +1575,8 @@ func (l *Ledger) ListSigningKeys(ctx context.Context, actor domain.Actor) ([]dom return out, nil } -func (l *Ledger) MissingEvidenceReport(ctx context.Context, actor domain.Actor, releaseID string) (map[string]any, error) { +func (s packageReportService) MissingEvidenceReport(ctx context.Context, actor domain.Actor, releaseID string) (map[string]any, error) { + l := s.ledger eval, err := l.EvaluateRelease(ctx, actor, releaseID) if err != nil && !errors.Is(err, ErrVerificationFailed) { return nil, err diff --git a/internal/app/package_report_service.go b/internal/app/package_report_service.go new file mode 100644 index 0000000..185199f --- /dev/null +++ b/internal/app/package_report_service.go @@ -0,0 +1,107 @@ +package app + +import ( + "context" + + "github.com/aatuh/evydence/internal/domain" +) + +type packageReportService struct { + ledger *Ledger +} + +func (l *Ledger) packageReportService() packageReportService { + return packageReportService{ledger: l} +} + +func (l *Ledger) MissingEvidenceReport(ctx context.Context, actor domain.Actor, releaseID string) (map[string]any, error) { + return l.packageReportService().MissingEvidenceReport(ctx, actor, releaseID) +} + +func (l *Ledger) ControlCoverageReport(ctx context.Context, actor domain.Actor, in ControlCoverageReportInput) (domain.ControlCoverageReport, error) { + return l.packageReportService().ControlCoverageReport(ctx, actor, in) +} + +func (l *Ledger) CRAReadinessReport(ctx context.Context, actor domain.Actor, in CRAReadinessReportInput) (domain.CRAReadinessReport, error) { + return l.packageReportService().CRAReadinessReport(ctx, actor, in) +} + +func (l *Ledger) IncidentReport(ctx context.Context, actor domain.Actor, incidentID string) (domain.IncidentReport, error) { + return l.packageReportService().IncidentReport(ctx, actor, incidentID) +} + +func (l *Ledger) VulnerabilityPostureReport(ctx context.Context, actor domain.Actor, releaseID string) (domain.VulnerabilityPostureReport, error) { + return l.packageReportService().VulnerabilityPostureReport(ctx, actor, releaseID) +} + +func (l *Ledger) RetentionReport(ctx context.Context, actor domain.Actor, scopeType, scopeID string) (domain.RetentionReport, error) { + return l.packageReportService().RetentionReport(ctx, actor, scopeType, scopeID) +} + +func (l *Ledger) CreateQuestionnaireTemplate(ctx context.Context, actor domain.Actor, in CreateQuestionnaireTemplateInput) (domain.QuestionnaireTemplate, error) { + return l.packageReportService().CreateQuestionnaireTemplate(ctx, actor, in) +} + +func (l *Ledger) CreateQuestionnairePackage(ctx context.Context, actor domain.Actor, in CreateQuestionnairePackageInput) (domain.QuestionnairePackage, error) { + return l.packageReportService().CreateQuestionnairePackage(ctx, actor, in) +} + +func (l *Ledger) CreateRedactionProfile(ctx context.Context, actor domain.Actor, in CreateRedactionProfileInput) (domain.RedactionProfile, error) { + return l.packageReportService().CreateRedactionProfile(ctx, actor, in) +} + +func (l *Ledger) CreateCustomerSecurityPackage(ctx context.Context, actor domain.Actor, in CreateCustomerPackageInput) (domain.CustomerSecurityPackage, error) { + return l.packageReportService().CreateCustomerSecurityPackage(ctx, actor, in) +} + +func (l *Ledger) AccessCustomerSecurityPackage(ctx context.Context, actor domain.Actor, id string) (domain.CustomerSecurityPackage, error) { + return l.packageReportService().AccessCustomerSecurityPackage(ctx, actor, id) +} + +func (l *Ledger) ExportCustomerSecurityPackageArchive(ctx context.Context, actor domain.Actor, id string) (CustomerPackageArchive, error) { + return l.packageReportService().ExportCustomerSecurityPackageArchive(ctx, actor, id) +} + +func (l *Ledger) ExportCustomerPortalPackageArchive(ctx context.Context, token string) (CustomerPackageArchive, error) { + return l.packageReportService().ExportCustomerPortalPackageArchive(ctx, token) +} + +func (l *Ledger) SecurityReviewPackageReport(ctx context.Context, actor domain.Actor, packageID string) (domain.SecurityReviewPackageReport, error) { + return l.packageReportService().SecurityReviewPackageReport(ctx, actor, packageID) +} + +func (l *Ledger) CRAReadinessHTMLPackage(ctx context.Context, actor domain.Actor, productID, releaseID string) (domain.HTMLReportPackage, error) { + return l.packageReportService().CRAReadinessHTMLPackage(ctx, actor, productID, releaseID) +} + +func (l *Ledger) CreateCustomReportTemplate(ctx context.Context, actor domain.Actor, in CreateReportTemplateInput) (domain.CustomReportTemplate, error) { + return l.packageReportService().CreateCustomReportTemplate(ctx, actor, in) +} + +func (l *Ledger) RenderCustomReport(ctx context.Context, actor domain.Actor, in RenderReportInput) (domain.RenderedCustomReport, error) { + return l.packageReportService().RenderCustomReport(ctx, actor, in) +} + +func (l *Ledger) ExportEvidenceBundle(ctx context.Context, actor domain.Actor, releaseID string, evidenceIDs []string) (domain.EvidenceBundle, error) { + return l.packageReportService().ExportEvidenceBundle(ctx, actor, releaseID, evidenceIDs) +} + +func (l *Ledger) ImportEvidenceBundle(ctx context.Context, actor domain.Actor, bundle domain.EvidenceBundle) (domain.EvidenceBundleImport, error) { + return l.packageReportService().ImportEvidenceBundle(ctx, actor, bundle) +} + +func (l *Ledger) CreateEvidenceSummary(ctx context.Context, actor domain.Actor, in CreateEvidenceSummaryInput) (domain.EvidenceSummary, error) { + return l.packageReportService().CreateEvidenceSummary(ctx, actor, in) +} + +func (l *Ledger) CreateQuestionnaireDraft(ctx context.Context, actor domain.Actor, in CreateQuestionnaireDraftInput) (domain.QuestionnaireDraft, error) { + return l.packageReportService().CreateQuestionnaireDraft(ctx, actor, in) +} + +func (l *Ledger) CreatePDFReportPackage(ctx context.Context, actor domain.Actor, in CreatePDFReportPackageInput) (domain.PDFReportPackage, error) { + return l.packageReportService().CreatePDFReportPackage(ctx, actor, in) +} + +func (l *Ledger) GenerateAnomalyReport(ctx context.Context, actor domain.Actor, in AnomalyReportInput) (domain.AnomalyReport, error) { + return l.packageReportService().GenerateAnomalyReport(ctx, actor, in) +} diff --git a/internal/app/release_evidence_service.go b/internal/app/release_evidence_service.go new file mode 100644 index 0000000..6a0b16f --- /dev/null +++ b/internal/app/release_evidence_service.go @@ -0,0 +1,123 @@ +package app + +import ( + "context" + + "github.com/aatuh/evydence/internal/domain" +) + +type releaseEvidenceService struct { + ledger *Ledger +} + +func (l *Ledger) releaseEvidenceService() releaseEvidenceService { + return releaseEvidenceService{ledger: l} +} + +func (l *Ledger) CreateProduct(ctx context.Context, actor domain.Actor, name, slug string) (domain.Product, error) { + return l.releaseEvidenceService().CreateProduct(ctx, actor, name, slug) +} + +func (l *Ledger) ListProducts(ctx context.Context, actor domain.Actor) ([]domain.Product, error) { + return l.releaseEvidenceService().ListProducts(ctx, actor) +} + +func (l *Ledger) CreateProject(ctx context.Context, actor domain.Actor, productID, name string) (domain.Project, error) { + return l.releaseEvidenceService().CreateProject(ctx, actor, productID, name) +} + +func (l *Ledger) CreateRelease(ctx context.Context, actor domain.Actor, productID, version string) (domain.Release, error) { + return l.releaseEvidenceService().CreateRelease(ctx, actor, productID, version) +} + +func (l *Ledger) GetRelease(ctx context.Context, actor domain.Actor, releaseID string) (domain.Release, error) { + return l.releaseEvidenceService().GetRelease(ctx, actor, releaseID) +} + +func (l *Ledger) FreezeRelease(ctx context.Context, actor domain.Actor, releaseID string) (domain.Release, error) { + return l.releaseEvidenceService().FreezeRelease(ctx, actor, releaseID) +} + +func (l *Ledger) ApproveRelease(ctx context.Context, actor domain.Actor, releaseID string) (domain.Release, error) { + return l.releaseEvidenceService().ApproveRelease(ctx, actor, releaseID) +} + +func (l *Ledger) RegisterArtifact(ctx context.Context, actor domain.Actor, name, mediaType, digest string, size int64) (domain.Artifact, error) { + return l.releaseEvidenceService().RegisterArtifact(ctx, actor, name, mediaType, digest, size) +} + +func (l *Ledger) CreateEvidence(ctx context.Context, actor domain.Actor, in CreateEvidenceInput) (domain.EvidenceItem, error) { + return l.releaseEvidenceService().CreateEvidence(ctx, actor, in) +} + +func (l *Ledger) GetEvidence(ctx context.Context, actor domain.Actor, id string) (domain.EvidenceItem, error) { + return l.releaseEvidenceService().GetEvidence(ctx, actor, id) +} + +func (l *Ledger) ListEvidence(ctx context.Context, actor domain.Actor, releaseID, typ string) ([]domain.EvidenceItem, error) { + return l.releaseEvidenceService().ListEvidence(ctx, actor, releaseID, typ) +} + +func (l *Ledger) SupersedeEvidence(ctx context.Context, actor domain.Actor, id, replacementID, reason string) (domain.EvidenceItem, error) { + return l.releaseEvidenceService().SupersedeEvidence(ctx, actor, id, replacementID, reason) +} + +func (l *Ledger) LinkEvidence(ctx context.Context, actor domain.Actor, id, targetType, targetID string) (domain.EvidenceItem, error) { + return l.releaseEvidenceService().LinkEvidence(ctx, actor, id, targetType, targetID) +} + +func (l *Ledger) UploadSBOM(ctx context.Context, actor domain.Actor, releaseID, artifactID string, raw []byte) (domain.SBOM, error) { + return l.releaseEvidenceService().UploadSBOM(ctx, actor, releaseID, artifactID, raw) +} + +func (l *Ledger) UploadVulnerabilityScan(ctx context.Context, actor domain.Actor, raw []byte) (domain.VulnerabilityScan, error) { + return l.releaseEvidenceService().UploadVulnerabilityScan(ctx, actor, raw) +} + +func (l *Ledger) UploadOpenAPIContract(ctx context.Context, actor domain.Actor, productID, releaseID, version string, raw []byte) (domain.OpenAPIContract, error) { + return l.releaseEvidenceService().UploadOpenAPIContract(ctx, actor, productID, releaseID, version, raw) +} + +func (l *Ledger) GetSBOM(ctx context.Context, actor domain.Actor, id string) (domain.SBOM, error) { + return l.releaseEvidenceService().GetSBOM(ctx, actor, id) +} + +func (l *Ledger) ListSBOMComponents(ctx context.Context, actor domain.Actor, in ListSBOMComponentsInput) ([]domain.SBOMComponentRecord, error) { + return l.releaseEvidenceService().ListSBOMComponents(ctx, actor, in) +} + +func (l *Ledger) GetVulnerabilityScan(ctx context.Context, actor domain.Actor, id string) (domain.VulnerabilityScan, error) { + return l.releaseEvidenceService().GetVulnerabilityScan(ctx, actor, id) +} + +func (l *Ledger) GetOpenAPIContract(ctx context.Context, actor domain.Actor, id string) (domain.OpenAPIContract, error) { + return l.releaseEvidenceService().GetOpenAPIContract(ctx, actor, id) +} + +func (l *Ledger) UploadVEX(ctx context.Context, actor domain.Actor, releaseID, artifactID string, raw []byte) (domain.VEXDocument, error) { + return l.releaseEvidenceService().UploadVEX(ctx, actor, releaseID, artifactID, raw) +} + +func (l *Ledger) GetVEXDocument(ctx context.Context, actor domain.Actor, id string) (domain.VEXDocument, error) { + return l.releaseEvidenceService().GetVEXDocument(ctx, actor, id) +} + +func (l *Ledger) CreateVulnerabilityDecision(ctx context.Context, actor domain.Actor, findingID string, in CreateVulnerabilityDecisionInput) (domain.VulnerabilityDecision, error) { + return l.releaseEvidenceService().CreateVulnerabilityDecision(ctx, actor, findingID, in) +} + +func (l *Ledger) CreateException(ctx context.Context, actor domain.Actor, in CreateExceptionInput) (domain.Exception, error) { + return l.releaseEvidenceService().CreateException(ctx, actor, in) +} + +func (l *Ledger) ListExceptions(ctx context.Context, actor domain.Actor, releaseID string) ([]domain.Exception, error) { + return l.releaseEvidenceService().ListExceptions(ctx, actor, releaseID) +} + +func (l *Ledger) ApproveException(ctx context.Context, actor domain.Actor, id string) (domain.Exception, error) { + return l.releaseEvidenceService().ApproveException(ctx, actor, id) +} + +func (l *Ledger) ReleaseReadinessReport(ctx context.Context, actor domain.Actor, releaseID string) (domain.ReleaseReadinessReport, error) { + return l.releaseEvidenceService().ReleaseReadinessReport(ctx, actor, releaseID) +} diff --git a/internal/app/risk_workflows.go b/internal/app/risk_workflows.go index e42abc3..90e0a89 100644 --- a/internal/app/risk_workflows.go +++ b/internal/app/risk_workflows.go @@ -440,7 +440,8 @@ func (l *Ledger) CreateRemediationTask(ctx context.Context, actor domain.Actor, return task, nil } -func (l *Ledger) IncidentReport(ctx context.Context, actor domain.Actor, incidentID string) (domain.IncidentReport, error) { +func (s packageReportService) IncidentReport(ctx context.Context, actor domain.Actor, incidentID string) (domain.IncidentReport, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.IncidentReport{}, err } @@ -918,7 +919,8 @@ func (l *Ledger) RecordVulnerabilityWorkflow(ctx context.Context, actor domain.A return record, nil } -func (l *Ledger) VulnerabilityPostureReport(ctx context.Context, actor domain.Actor, releaseID string) (domain.VulnerabilityPostureReport, error) { +func (s packageReportService) VulnerabilityPostureReport(ctx context.Context, actor domain.Actor, releaseID string) (domain.VulnerabilityPostureReport, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.VulnerabilityPostureReport{}, err } diff --git a/internal/app/vex.go b/internal/app/vex.go index b18391f..a6d68c9 100644 --- a/internal/app/vex.go +++ b/internal/app/vex.go @@ -63,7 +63,8 @@ type openVEXProduct struct { Subcomponents []openVEXProduct `json:"subcomponents,omitempty"` } -func (l *Ledger) UploadVEX(ctx context.Context, actor domain.Actor, releaseID, artifactID string, raw []byte) (domain.VEXDocument, error) { +func (s releaseEvidenceService) UploadVEX(ctx context.Context, actor domain.Actor, releaseID, artifactID string, raw []byte) (domain.VEXDocument, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.VEXDocument{}, err } @@ -186,7 +187,8 @@ func (l *Ledger) UploadVEX(ctx context.Context, actor domain.Actor, releaseID, a return vex, nil } -func (l *Ledger) GetVEXDocument(ctx context.Context, actor domain.Actor, id string) (domain.VEXDocument, error) { +func (s releaseEvidenceService) GetVEXDocument(ctx context.Context, actor domain.Actor, id string) (domain.VEXDocument, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.VEXDocument{}, err } @@ -205,7 +207,8 @@ func (l *Ledger) GetVEXDocument(ctx context.Context, actor domain.Actor, id stri return vex, nil } -func (l *Ledger) CreateVulnerabilityDecision(ctx context.Context, actor domain.Actor, findingID string, in CreateVulnerabilityDecisionInput) (domain.VulnerabilityDecision, error) { +func (s releaseEvidenceService) CreateVulnerabilityDecision(ctx context.Context, actor domain.Actor, findingID string, in CreateVulnerabilityDecisionInput) (domain.VulnerabilityDecision, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.VulnerabilityDecision{}, err } @@ -233,7 +236,8 @@ func (l *Ledger) CreateVulnerabilityDecision(ctx context.Context, actor domain.A return decision, nil } -func (l *Ledger) CreateException(ctx context.Context, actor domain.Actor, in CreateExceptionInput) (domain.Exception, error) { +func (s releaseEvidenceService) CreateException(ctx context.Context, actor domain.Actor, in CreateExceptionInput) (domain.Exception, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.Exception{}, err } @@ -288,7 +292,8 @@ func (l *Ledger) CreateException(ctx context.Context, actor domain.Actor, in Cre return exception, nil } -func (l *Ledger) ListExceptions(ctx context.Context, actor domain.Actor, releaseID string) ([]domain.Exception, error) { +func (s releaseEvidenceService) ListExceptions(ctx context.Context, actor domain.Actor, releaseID string) ([]domain.Exception, error) { + l := s.ledger if err := ctx.Err(); err != nil { return nil, err } @@ -314,7 +319,8 @@ func (l *Ledger) ListExceptions(ctx context.Context, actor domain.Actor, release return out, nil } -func (l *Ledger) ApproveException(ctx context.Context, actor domain.Actor, id string) (domain.Exception, error) { +func (s releaseEvidenceService) ApproveException(ctx context.Context, actor domain.Actor, id string) (domain.Exception, error) { + l := s.ledger if err := ctx.Err(); err != nil { return domain.Exception{}, err } @@ -348,7 +354,8 @@ func (l *Ledger) ApproveException(ctx context.Context, actor domain.Actor, id st return exception, nil } -func (l *Ledger) ReleaseReadinessReport(ctx context.Context, actor domain.Actor, releaseID string) (domain.ReleaseReadinessReport, error) { +func (s releaseEvidenceService) ReleaseReadinessReport(ctx context.Context, actor domain.Actor, releaseID string) (domain.ReleaseReadinessReport, error) { + l := s.ledger eval, err := l.EvaluateRelease(ctx, actor, releaseID) if err != nil { return domain.ReleaseReadinessReport{}, err From bfea705383c6eb341b260ba5080437e59776c94b Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 16:08:14 +0300 Subject: [PATCH 147/287] docs: record production readiness audits --- .production_readiness.md | 734 ++++++++++++++++++++++++++++++++++++ .production_readiness_v2.md | 605 +++++++++++++++++++++++++++++ 2 files changed, 1339 insertions(+) create mode 100644 .production_readiness.md create mode 100644 .production_readiness_v2.md diff --git a/.production_readiness.md b/.production_readiness.md new file mode 100644 index 0000000..c256ec1 --- /dev/null +++ b/.production_readiness.md @@ -0,0 +1,734 @@ +# User + +Act as a brutally honest senior backend/API architect, open-source maintainer, production-readiness reviewer, security reviewer, and skeptical B2B buyer. + +Before judging quality, explicitly state the exact latest commit you inspected. If you cannot verify the latest commit, do not claim this is based on the latest state. + +Evaluate this GitHub project based on its latest publicly visible state: + +REPOSITORY: +github.com/aatuh/evydence + +GOAL: +Determine whether this project is: +1. mature and high-grade enough for real production use, +2. feature-complete enough to solve a real-world problem, +3. marketable/interesting enough to attract users, buyers, contributors, or commercial opportunities, +4. worth continuing, repositioning, hardening, or abandoning. + +Important: +Do not flatter me. +Do not infer quality from intent. +Do not judge only by GitHub stars. +Do not give a generic repository review. +Ground every major claim in repository evidence: files, README, docs, code structure, tests, CI workflows, releases, issues, examples, Docker/deployment files, security files, license, package metadata, commit history, and public project positioning. + +First, verify the latest visible state: +- repository name and URL +- default branch +- latest commit SHA and commit date you can see +- latest release/tag, if any +- primary language(s) +- license +- whether the repository appears public, active, maintained, archived, experimental, or production-oriented +- anything you could not inspect + +Evaluate using this rubric: + +## 1. What the project appears to be + +Explain in plain English: +- what problem it tries to solve +- who the likely users are +- what category it belongs to +- whether the README clearly communicates this within 30 seconds +- whether the project sounds like a library, CLI, server, API, framework, infrastructure tool, or product + +## 2. Production readiness + +Assess whether it is production-grade for serious users. + +Check: +- architecture and code organization +- API design and stability +- configuration model +- error handling +- persistence/data model, if relevant +- migrations, if relevant +- logging and observability +- authentication/authorization, if relevant +- security posture +- dependency management +- CI/CD +- automated tests +- integration/e2e tests +- release process +- versioning +- backward compatibility policy +- Docker/deployment story +- documentation quality +- operational runbook or troubleshooting docs +- examples and quickstart +- performance or scalability considerations +- failure handling and recovery +- upgrade path + +Give a score from 1–10 and explain the score brutally. + +## 3. Feature completeness + +Answer: +- What real-world production use cases does it already support? +- What important use cases are missing? +- What features are table stakes for this category? +- Which missing features are blockers? +- Which missing features are nice-to-have? +- Is the project currently a toy, prototype, useful library, production component, or productizable system? + +Give a score from 1–10. + +## 4. Security and open-source trust + +Evaluate trust signals using common open-source expectations, including: +- LICENSE +- SECURITY.md +- CONTRIBUTING.md +- CODE_OF_CONDUCT.md, if community-oriented +- dependency update automation +- vulnerability scanning +- secret scanning awareness +- branch protection / required checks, if visible +- signed releases or provenance, if relevant +- SBOM, if relevant +- OpenSSF Scorecard-style concerns +- OpenSSF Best Practices Badge-style concerns + +Do not require every item blindly. Explain which ones matter for this specific project. + +Give a score from 1–10. + +## 5. Marketability and positioning + +Evaluate from the perspective of a skeptical user or buyer: +- Is the problem painful? +- Is the target user obvious? +- Is the value proposition sharp? +- Is the category already crowded? +- Is there a clear reason to choose this over existing alternatives? +- Is the README written like a product page or only like internal notes? +- Are there compelling examples, screenshots, diagrams, demos, or benchmarks? +- Is there a plausible monetization path: support, consulting, dual licensing, hosted option, enterprise features, compliance package, templates, training, private forks, or paid integrations? +- Does the project name help or hurt? + +Give a score from 1–10. + +## 6. Differentiation + +Compare the project conceptually against likely alternatives. + +Identify: +- direct alternatives +- indirect alternatives +- “do nothing / build in-house” alternative +- what makes this project meaningfully different +- what is not yet differentiated enough + +Do not invent competitors. Search if needed. + +## 7. Repository quality checklist + +Create a table: + +| Area | Status | Evidence | Severity | Recommended fix | +|------|--------|----------|----------|-----------------| + +Include at least: +- README +- quickstart +- examples +- tests +- CI +- releases +- docs +- Docker/deployment +- security policy +- license +- contribution docs +- issue templates +- changelog +- API documentation +- configuration docs +- operational docs + +Use statuses: +- Strong +- Adequate +- Weak +- Missing +- Not applicable + +Severity: +- Blocker +- High +- Medium +- Low + +## 8. Final verdict + +Give a direct verdict using one of these: + +- Production-ready +- Production-usable with caveats +- Promising but not production-ready +- Prototype only +- Not worth continuing in current form + +Then answer directly: +- Is it mature and high-grade enough for production for most uses? +- Is it highly marketable and interesting? +- Is it useful in real-world production, meaning it has enough features? +- What should be done next? + +## 9. Highest-leverage next steps + +Give a brutally prioritized roadmap: + +### Next 1–2 days +Small fixes that immediately improve trust. + +### Next 1–2 weeks +Changes that materially improve production readiness and marketability. + +### Next 1–2 months +Changes that could make the project seriously productizable. + +For each item include: +- why it matters +- what exact files/docs/features should be added or changed +- how it improves production readiness, trust, or marketability + +## 10. README/product-page rewrite advice + +Briefly suggest how the README should be repositioned: +- sharper one-sentence pitch +- target user +- core use case +- best demo/example to show first +- proof points to add +- what to remove or de-emphasize + +Output style: +Be concise but thorough. +Use blunt language. +Separate evidence from opinion. +When uncertain, say exactly what is uncertain and what evidence would resolve it. + +# ChatGPT + +## Remediation Tracking + +Status legend: + +- `[ ]` applicable to this repository and not yet done +- `[x]` applicable to this repository and completed with repo evidence +- `[e]` external or deployment/provider/account dependent; cannot be fully completed by repository files alone + +### Current State Verification + +- [x] PR-001 Verify the latest local commit inspected, including commit date. + Evidence: local `HEAD` is `842fb053f303b2a78eb3118be6a4536715571215`, dated `2026-05-31T11:37:01+03:00`. +- [e] PR-002 Verify branch protection, required checks, private vulnerability reporting settings, public CI pass history, public stars/forks/watchers, and public release visibility. + These are GitHub account/repository settings or public platform state, not repository-file changes. + +### Highest-Leverage Trust And Release Items + +- [e] PR-003 Publish a real public GitHub release candidate with uploaded artifacts. + Repository scripts/workflows can prepare artifacts, but public publication requires GitHub release permissions, signing secret configuration, and operator action. +- [x] PR-004 Align README and changelog release-candidate wording with the current `v0.1.0-rc.3` repo evidence or make the wording version-neutral. +- [x] PR-005 Add README badges and visible proof pointers for CI, license, Go version, release status, coverage, OpenAPI precision, and production-check expectations. +- [x] PR-006 Add a blunt README "Current limitations" section near the top. +- [x] PR-007 Reposition README top section around user pain, target user, core demo, and narrow differentiation instead of leading with a long implementation inventory. +- [e] PR-008 Configure a real private security mailbox or enable GitHub private vulnerability reporting. + The repository can document the expected channel, but mailbox/advisory settings are external. +- [x] PR-009 Remove LinkedIn-first security-reporting dependence from `SECURITY.md` once an acceptable private intake path is documented or scoped as external. +- [x] PR-010 Add issue templates for bug reports, feature requests, docs problems, and non-sensitive production-support questions. +- [x] PR-011 Add a code of conduct if community contribution is desired. +- [x] PR-012 Add Dependabot or Renovate dependency automation for Go modules, GitHub Actions, Docker, and related package ecosystems. +- [x] PR-013 Add OpenSSF Scorecard workflow. +- [x] PR-014 Add project release SBOM and provenance generation to the release-candidate evidence set. +- [e] PR-015 Enforce branch protection and required checks. + This is a GitHub repository setting, though workflows/check names can be provided by repository files. + +### Product Adoption And Marketability + +- [x] PR-016 Add one complete end-to-end release-evidence demo under `examples/end-to-end-release-evidence/`. +- [x] PR-017 Add screenshots, terminal captures, diagrams, or a short demo asset that explains the product without maintainer narration. +- [x] PR-018 Add a "Why not Dependency-Track, Vanta/Drata, or build in-house?" positioning section. +- [x] PR-019 Add example generated readiness report, customer package, and audit-chain verification artifacts. +- [e] PR-020 Add customer stories, public adoption proof, or third-party case studies. + This depends on real users/customers and cannot be created honestly in repository code. +- [x] PR-021 Add API client examples for Go, TypeScript, and Python showing create release, upload SBOM, upload scan, record decision, and fetch readiness. +- [x] PR-040 Add executable test coverage for the Go SDK example path so the example is proven and does not drag the production coverage gate below threshold. +- [x] PR-041 Remove unsupported fields from SDK examples that would be rejected by strict API decoders. + +### Production Operations + +- [x] PR-022 Add a durable quickstart using PostgreSQL, object storage, API, worker, and migrations. +- [x] PR-023 Add a full production-like Docker Compose stack for API, worker, Postgres, MinIO, migrations, health checks, and env-file secrets. +- [x] PR-042 Fix the production-like Docker image and Compose command wiring so migration and worker services run their own binaries instead of passing arguments to the API entrypoint. +- [x] PR-043 Strengthen deployment checks to assert the production-like stack includes the migrate binary and explicit migrate/worker entrypoints. +- [x] PR-024 Add backup/restore runbook tied to backup manifests and object-store consistency checks. +- [x] PR-025 Add upgrade runbook with migration, rollback/forward-fix, release evidence, and compatibility guidance. +- [x] PR-026 Add incident-response runbook for operator incidents involving secrets, tenant isolation, object storage, signing, provider credentials, or evidence exports. +- [x] PR-027 Add capacity, performance, and failure-mode guidance for API writer limits, worker throughput, object sizes, DB pool settings, and outbox retries. +- [x] PR-028 Add operational diagrams for architecture and deployment. +- [x] PR-029 Reduce documentation repetition while keeping canonical references clear. + +### Architecture And Feature Maturity + +- [x] PR-030 Continue splitting the large in-process `Ledger` aggregate and massive `PersistedState` into focused services/repositories. + - [x] PR-030a Production relational-only load and focused critical/release-ledger mutation paths are already implemented. + - [x] PR-030b Split identity/session/API-key behavior behind a focused application service. + - [x] PR-030b.1 API-key authentication, bootstrap, create, and list behavior now delegate through a focused internal identity service while preserving the public `Ledger` API. + - [x] PR-030b.2 Move SSO provider/session exchange, human users, organizations, role bindings, and portal-token identity behavior through the same service boundary. + - [x] PR-030c Split release/evidence/SBOM/scan/VEX behavior behind a focused application service. + Evidence: product/project/release, artifact, evidence, SBOM, vulnerability-scan, OpenAPI-contract, VEX, vulnerability-decision, exception, and release-readiness behavior now delegates through `releaseEvidenceService` while preserving the public `Ledger` API. `go test ./internal/app ./internal/adapters/httpapi ./cmd/evydence-api ./cmd/evydence-worker` and `make fast-check` passed after the split. + - [x] PR-030d Split package/report/portal behavior behind a focused application service. + Evidence: redaction profiles, customer package access/export, portal package archive export, security-review and CRA HTML packages, evidence bundles, custom reports, questionnaire templates/packages/drafts, evidence summaries, control/CRA coverage reports, incident and vulnerability posture reports, retention reports, missing-evidence reports, PDF report packages, and anomaly reports now delegate through `packageReportService` while preserving public `Ledger` API methods. The authz inventory test now recognizes focused service receivers and still checks implementation bodies for resource-scoped authorization. `go test ./internal/app ./internal/adapters/httpapi ./cmd/evydence-api ./cmd/evydence-worker` and `make fast-check` passed after the split. + - [x] PR-030e Replace broad aggregate `SaveState` synchronization for remaining write families with canonical repository transactions. + Evidence: `persistLocked` dispatches production-style stores through `RelationalStateStore.SaveRelationalState` instead of `Store.SaveState`; the PostgreSQL adapter executes dependency-ordered relational sync functions in a transaction with compatibility snapshot writes disabled for that path. `TestRelationalStateStoreAvoidsAggregateSaveForRemainingFamilies` covers representative remaining control, incident, redaction, and customer-package write families and asserts `SaveState` is not called, while existing PostgreSQL tests verify relational load/recovery and zero `ledger_state` rows for relational-only/focused mutation paths. Memory/snapshot `SaveState` remains only for local/demo compatibility and migration/recovery compatibility. +- [x] PR-031 Define and implement a reviewed multi-writer API HA design, or permanently keep the product scoped to single-writer controlled self-hosted deployments. +- [x] PR-032 Add direct provider-specific management API clients or narrow the product promise to bring-your-own-evidence integration. +- [e] PR-033 Add native PKCS#11/HSM module and slot handling. + Native HSM validation depends on operator hardware, drivers, credentials, and provider-specific test environments. +- [e] PR-034 Prove broad WORM/object-lock enforcement beyond configured bucket and sample-object checks. + Full proof depends on object-store creation mode, IAM, lifecycle policy, backups, and provider audit evidence. +- [x] PR-035 Add a minimal read-only package viewer or trust-package UI for release evidence, customer packages, and readiness reports. +- [x] PR-036 Add benchmark or capacity evidence for the supported single-writer profile. +- [e] PR-037 Validate public transparency provider semantics and availability. + Provider trust, timestamp semantics, and availability are external review items. + +### Final Positioning + +- [x] PR-038 Finish the production exit review before changing status beyond controlled self-hosted production candidate. +- [x] PR-044 Restore the strict production coverage gate to at least 80 percent when live PostgreSQL tests are configured. +- [e] PR-039 Claim broad production readiness, regulated production readiness, hosted SaaS readiness, legal compliance, certification, secure release, complete SBOM coverage, or authoritative scanner results. + These are intentionally outside the current product boundary and require external controls/review even if repository hardening improves. + +## Latest visible state inspected + +I inspected commit **`842fb053f303b2a78eb3118be6a4536715571215`**, commit message **`feat: add direct cloud kms signers`**. That is the latest head I could verify for `master` through the GitHub connector in this session, and the searchable commit record corroborates the SHA and message. + +I **could not see the exact commit timestamp for that head commit** from the accessible outputs. The immediately previous visible commit I found was `d55b955fce82384108cae55365096f7f52bf5b2b`, created **2026-05-31 11:25:37 +03:00**, so I will not invent a timestamp for `842fb0...`. + +| Item | Verified state | +|-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Repository | `aatuh/evydence`, `https://github.com/aatuh/evydence` | +| Visibility | Public repository. ([GitHub][1]) | +| Default branch | `master`. ([GitHub][1]) | +| Latest inspected commit | `842fb053f303b2a78eb3118be6a4536715571215`, `feat: add direct cloud kms signers`. | +| Latest release | **No published GitHub releases visible.** ([GitHub][1]) | +| Tags | README/changelog mention a local `v0.1.0-rc.2` evidence package/tag, but public release publication is separate and I could not inspect the public tag list. | +| Primary languages | Mostly Go, with small Python, Makefile, Shell, TypeScript, Dockerfile portions. ([GitHub][1]) | +| License | AGPL-3.0-only. | +| Activity | Active, but extremely fresh. Recent commit history shows multiple production-hardening commits on 2026-05-31. | +| Project status | Public, active, maintainer-led, production-oriented, but explicitly **not broad production-ready**. | +| Could not inspect | Exact head commit date, public tags list, branch protection, required checks, GitHub private vulnerability settings, Dependabot/vulnerability-alert settings, actual CI pass/fail history for the head commit, and runtime behavior by executing tests. | + +--- + +# 1. What the project appears to be + +**Plain English:** Evydence is a self-hosted API service for collecting and organizing technical evidence around software releases: SBOMs, vulnerability scans, VEX, release bundles, build/source/deployment records, audit chains, control coverage, readiness reports, customer-facing security packages, and related compliance-readiness artifacts. + +The README communicates the core idea quickly: “a self-hosted, API-first evidence ledger for software release evidence” that supports compliance readiness by organizing/verifying technical evidence and showing gaps, assumptions, exceptions, and limitations. + +**Likely users:** platform security teams, AppSec teams, compliance-readiness teams, DevSecOps teams, security-conscious B2B SaaS vendors, and internal engineering teams that need auditable release evidence without handing all trust data to a SaaS GRC platform. + +**Category:** self-hosted release evidence ledger / software supply-chain evidence platform / compliance-readiness API. It is adjacent to SBOM/vulnerability management, GRC evidence automation, software supply-chain provenance, and customer trust-package tooling. + +**What it is not:** not a legal compliance engine, not a certification tool, not an authoritative vulnerability scanner, and not a secure-release guarantee. The README is unusually explicit about those non-claims. + +**Library, CLI, server, API, framework, infrastructure tool, or product?** It is mainly a **server/API product** with a CLI helper, worker process, deployment assets, and SDK wrappers. README lists `/v1` HTTP API, `cmd/evydence-api`, `cmd/evydence-worker`, `cmd/evydence`, Helm, Docker, CI examples, and SDK wrappers. + +**30-second README clarity:** Good, but dense. A technical reader gets the point quickly. A buyer does not. The README reads like a careful engineering status memo, not a product landing page. + +--- + +# 2. Production readiness + +## Evidence + +The repo has real production-readiness work, not just claims: + +* Ports-and-adapters structure is documented: `internal/domain`, `internal/app`, HTTP adapter, PostgreSQL adapter, object-store adapters, and `cmd/*` entrypoints. +* It has PostgreSQL durable state, migrations, tenant-scoped relational projections, object storage, persisted outbox jobs, worker processing, and S3/MinIO-compatible raw payload storage. +* The API enforces production startup checks: production requires PostgreSQL, non-default API-key pepper, production signing mode, no bootstrap-secret printing, and single-writer constraints. +* Production API startup can acquire a PostgreSQL advisory writer lease so a second writer fails closed. +* CI has a `Production Check` job using PostgreSQL and running `make production-check`. +* `make release-check` includes finalize, release acceptance, lint, gosec, govulncheck, race tests, live PostgreSQL checks, and PostgreSQL integration tests. +* `make production-check` requires a live PostgreSQL test URL, enforces coverage, runs migration compatibility, and does a release signing smoke test. +* The docs include production-readiness, release-candidate, configuration, operations, Kubernetes, observability, worker-outbox, release-validation, and API references. +* Deployment assets exist: Dockerfile, Compose dependencies, Helm chart, NetworkPolicy template, Prometheus rules, Grafana dashboard starter assets. + +## Brutal assessment + +This is **not vaporware**, and it is not a weekend toy. But it is also **not production-grade for serious broad adoption yet**. + +The biggest problem is architectural maturity. The core `Ledger` is still a huge in-process aggregate protected by a mutex and containing a very large number of maps for tenants, users, evidence, releases, SBOMs, VEX documents, decisions, reports, controls, packages, signatures, audit chains, and more. The persistence model also still exposes a massive `PersistedState` structure with many resource-family maps. + +The project knows this and says so. The architecture doc explicitly says that moving all canonical production writes to dependency-ordered relational repositories is still production hardening, not completed production maturity. The production-readiness doc says the broader production exit review remains incomplete and that canonical production persistence still needs hand-tuned relational repository paths for all resource families. + +The HA story is intentionally limited: one API writer replica. Workers may scale, but API writes are not multi-writer safe. That is acceptable for an internal controlled deployment, but it is a hard ceiling for broad production claims. + +Security posture is thoughtful but incomplete. Good: HMAC-hashed API keys, tenant scoping, explicit scopes, production rejection checks, safe metrics, private payload handling, gosec/govulncheck gates, signing gateways/KMS, and no overclaiming. Bad: no published release, no visible signed public artifacts, no dedicated security email/advisory portal, no visible Dependabot config, no visible Scorecard/SBOM/provenance workflow, no branch protection visibility, and no public CI pass evidence for the latest head commit. + +Deployment story exists but is not turnkey. The Dockerfile is basic but reasonable, uses a non-root user, and copies migrations. Compose only starts dependencies, not the full app stack. Helm is useful, but defaults include one API replica, empty required image tag, external secrets, and NetworkPolicy disabled by default. + +## Production-readiness score: **6/10** + +That is not an insult. A 6 here means: **credible controlled internal pilot**, not “ship it to unknown customers.” The repo has unusually serious validation gates and honest limitations. But no public release, single-writer architecture, incomplete production exit review, unfinished repository decomposition, missing public trust automation, and no visible adoption make it unfit for broad serious production. + +--- + +# 3. Feature completeness + +## What real-world use cases it already supports + +Evydence already supports several real workflows: + +* Create products, projects, releases, artifacts, immutable evidence, SBOMs, vulnerability scans, VEX documents, decisions, release bundles, audit entries, and readiness reports. +* Upload CycloneDX SBOMs and vulnerability scan evidence, then record vulnerability decisions and generate release-readiness output. +* Manage controls, control evidence, CRA-readiness, customer packages, redaction profiles, questionnaires, report templates, incident packages, and PDF package metadata. +* Record CI/source/deployment/collector evidence, build attestations, DSSE trust roots, source snapshots, deployments, and container images. +* Support integrity operations: release bundles, audit-chain verification, signing keys, signing operations, artifact signatures, Merkle batches, transparency checkpoints, retention policies, legal holds, and backup manifests. +* Use worker-owned parser side effects for replaying raw payloads from tenant-prefixed object storage and populating normalized fields after digest verification. + +## Missing or incomplete use cases + +Blockers: + +* **No public release artifacts.** A local `v0.1.0-rc.2` package is mentioned, but GitHub shows no published releases. ([GitHub][1]) +* **No broad production HA.** One API writer only. +* **Provider-specific management integrations are incomplete.** The repo explicitly says direct provider-specific management API clients and external group synchronization remain outside the implemented boundary. +* **Native PKCS#11/HSM handling is not implemented.** It remains gateway-backed because native modules/slots are deployment-specific. +* **Object-lock/WORM verification is limited.** S3/MinIO checks cover bucket defaults and optional sample object retention/legal hold, not full deployment-level WORM assurance. +* **No UI/trust center product experience.** There are APIs and package endpoints, but not a polished buyer-facing trust portal or admin console. + +Table-stakes features for this category that are still weak: + +* Published signed releases. +* Concrete installable container images with immutable tags/digests. +* Real-world demo with screenshots or video. +* Example integrations with GitHub/GitLab that produce a full evidence package. +* Clear upgrade guide and backward compatibility policy. +* Security advisory intake. +* Dependency automation. +* Benchmarks and capacity guidance. +* Multi-user operations UX. +* Production incident/runbook details beyond indexes and references. + +## Feature-completeness score: **7/10** + +This is feature-rich. It is not a toy. It is also dangerously broad: many features exist as API records and deterministic reports, but not all are deeply integrated with real provider ecosystems. Current classification: **useful production component for narrow, controlled internal use; not yet a productized system.** + +--- + +# 4. Security and open-source trust + +## Strong trust signals + +* AGPL-3.0 license is present. +* Commercial licensing terms are explicit and realistic. +* SECURITY.md exists and gives sensitive-data handling rules. +* CONTRIBUTING.md exists and tells contributors not to submit secrets, raw payloads, or provider credentials. +* Governance is explicit: maintainer-led, one named maintainer, final decision authority documented. +* Support expectations are documented, including no SLA unless agreed. +* CI/tooling includes lint, gosec, govulncheck, race tests, coverage threshold, OpenAPI drift checks, docs checks, deployment checks, and SDK checks. + +## Weak trust signals + +* **Security reporting through LinkedIn is not acceptable for serious open source.** SECURITY.md says to contact the maintainer through LinkedIn until a dedicated mailbox or advisory portal is published. That is better than nothing, but weak for a high-trust evidence system. +* No visible `CODE_OF_CONDUCT.md`. +* No visible Dependabot config. +* No visible OpenSSF Scorecard workflow. +* No visible SBOM/provenance workflow for the project’s own releases. +* No visible public signed release yet. +* Branch protection and required checks are not visible. +* Latest head commit had no workflow runs/statuses visible from the connector result I could inspect. +* The public repo has zero stars/forks/watchers at inspection time; stars are not quality, but zero adoption is a trust and market signal. ([GitHub][1]) + +## Security/open-source trust score: **6/10** + +The internal security thinking is much better than average. The public open-source trust surface is not. For a tool that asks buyers to trust it with compliance and release evidence, “message me on LinkedIn for security reports” and “no public release artifacts” are serious trust gaps. + +--- + +# 5. Marketability and positioning + +## Pain level + +The problem is real. B2B vendors increasingly need to answer: What changed in this release? What evidence proves it? What vulnerabilities were reviewed? What SBOM/VEX/build/deployment records exist? What can be safely shared with customers? Evydence targets that pain. + +## Target user clarity + +The target user is technically inferable but not buyer-obvious. The README says “software release evidence” and “compliance readiness,” but it does not immediately say: + +> “For security and platform teams at B2B software companies who need an auditable release evidence trail and customer-ready security package without buying a full SaaS GRC platform.” + +That should be the front-page positioning. + +## Category crowding + +This is in a crowded neighborhood: + +* Vanta and Drata sell broad compliance/trust automation with evidence collection, control monitoring, trust centers, questionnaires, and integrations. Vanta advertises compliance automation, streamlined audits, trust centers, questionnaire automation, and 400+ integrations. ([Vanta][2]) Drata advertises automated control mapping, evidence collection, monitoring, continuous compliance, trust centers, and questionnaire automation. ([Drata][3]) +* OWASP Dependency-Track is strong in SBOM ingestion, continuous SBOM analysis, vulnerability detection, policy evaluation, audit workflow, VEX, notifications, SSO, and API-first integration. ([Dependency Track][4]) +* DefectDojo has a large open-source vulnerability-management community and many integrations. ([defectdojo.org][5]) +* GUAC targets software supply-chain metadata graphs and SBOM/advisory relationship mapping. ([guac][6]) +* in-toto and SLSA cover supply-chain integrity/provenance standards rather than compliance evidence ledgers. ([in-toto][7]) ([SLSA][8]) + +## Differentiated pitch + +Evydence’s strongest angle is **not** “we do compliance.” That loses to Vanta/Drata/Secureframe immediately. + +The sharper angle is: + +> “A self-hosted release evidence ledger for software teams that need tamper-evident, API-first, customer-reviewable technical evidence across SBOMs, VEX, vulnerability decisions, release bundles, controls, audit chains, and offline/self-hosted environments.” + +That is narrower, more credible, and more differentiated. + +## Marketability score: **5/10** + +Interesting, but not yet highly marketable. The value proposition is buried under implementation status. The README is honest but not persuasive. There are no screenshots, no demo, no benchmark, no hosted option, no public release, no customer story, no “why this instead of Dependency-Track + Vanta + spreadsheets” section. + +The name **Evydence** is mixed. It is memorable, but the misspelling may hurt searchability and professionalism in B2B procurement. It is not fatal, but it needs a strong tagline. + +--- + +# 6. Differentiation + +## Direct alternatives + +There are not many exact “self-hosted release evidence ledger” direct alternatives, but buyers will compare it against: + +* **Dependency-Track** for SBOM, VEX, vulnerability, policy, and supply-chain risk workflows. It is mature, open source, API-first, and has broad ecosystem support. ([Dependency Track][4]) +* **DefectDojo** for vulnerability aggregation, AppSec workflows, integrations, and security program reporting. ([defectdojo.org][5]) +* **Vanta / Drata / Secureframe** for compliance automation, trust center, audit evidence, questionnaires, and customer assurance. ([Vanta][2]) ([Drata][3]) +* **GUAC** for software supply-chain metadata graphing and SBOM/advisory relationships. ([guac][6]) + +## Indirect alternatives + +* GitHub Advanced Security, GitLab Ultimate, Snyk, Wiz, JFrog Xray, Sonatype Lifecycle. +* in-toto/SLSA/Sigstore/Rekor-style provenance/signing/transparency stacks. +* Internal spreadsheets, Jira tickets, Confluence pages, object storage, and a custom Postgres database. + +## Do-nothing/build-in-house alternative + +Many security teams will build a crude internal version: CI uploads JSON to S3, a Postgres table stores release metadata, a script generates a customer PDF, and humans glue together SBOMs/scans/screenshots. That is ugly but cheap. Evydence must prove it saves enough pain to beat this. + +## Meaningful differentiation + +* Self-hosted, API-first, release-evidence-specific. +* Strong conservative claim language. +* Tamper-evident audit-chain and release-bundle orientation. +* Broad evidence types: SBOM, VEX, scans, source/deploy, controls, customer packages, retention, transparency. +* Air-gapped/offline packaging story. +* AGPL + commercial license path. +* Designed for technical evidence organization, not generic compliance dashboards. + +## Not differentiated enough yet + +* It lacks a polished buyer demo. +* It lacks public releases and adoption. +* It lacks deep provider integrations. +* It lacks a UI/trust portal. +* It lacks obvious “why not Dependency-Track + Drata?” positioning. +* It lacks operational proof: production case study, benchmark, upgrade story, and public signed artifacts. + +--- + +# 7. Repository quality checklist + +| Area | Status | Evidence | Severity | Recommended fix | +|-----------------------|---------:|------------------------------------------------------------------------------------------------------------------|---------:|---------------------------------------------------------------------------------------------------------| +| README | Adequate | Clear technical definition and honest non-claims, but reads like a status memo. | Medium | Rewrite top section around user, pain, demo, and narrow differentiation. | +| Quickstart | Adequate | Local API flow exists, but it is explicitly in-process and data is lost on exit. | Medium | Add “durable quickstart” with Postgres + object store + worker. | +| Examples | Adequate | GitHub Actions, GitLab CI, upload-build, SDK, source snapshot examples exist. | Medium | Add one end-to-end demo repo producing a full evidence package. | +| Tests | Strong | Many unit/integration tests exist; tenant isolation, parser jobs, PostgreSQL migration compatibility are tested. | Medium | Publish CI results and coverage reports; add black-box e2e tests against deployed API. | +| CI | Adequate | CI workflow runs `make production-check` with PostgreSQL service. | High | Expose passing status badges and verify required checks/branch protection. | +| Releases | Missing | GitHub shows no published releases. ([GitHub][1]) | High | Publish `v0.1.0-rc.2` or next RC with signed artifacts, checksums, release notes, image digest. | +| Docs | Strong | Docs portal covers start, how-to, reference, metadata, workflows, architecture, trust model. | Low | Reduce repetition and add diagrams/screenshots. | +| Docker/deployment | Adequate | Dockerfile, Compose dependencies, Helm chart, probes, secrets, security contexts exist. | Medium | Add full compose app stack; publish images; default NetworkPolicy enabled for production values. | +| Security policy | Weak | SECURITY.md exists, but private reporting currently routes through LinkedIn. | High | Add `security@...`, GitHub private vulnerability reporting, advisory process, supported versions table. | +| License | Strong | AGPL-3.0-only present. | Low | Add SPDX headers or REUSE compliance if desired. | +| Commercial licensing | Adequate | Commercial exceptions and paid options documented. | Low | Add contact form/email, not only LinkedIn. | +| Contribution docs | Adequate | CONTRIBUTING exists, but CLA/selective model may discourage contributors. | Medium | Add issue/PR templates and a lightweight contributor path for docs/tests. | +| Governance | Adequate | Maintainer-led, one named maintainer. | Medium | Add escalation, release authority, security response roles, succession note. | +| Issue templates | Missing | I did not find `.github/ISSUE_TEMPLATE` during repo inspection. | Low | Add bug, feature, security-non-sensitive, production-support templates. | +| Code of conduct | Missing | `CODE_OF_CONDUCT.md` was not found. | Low | Add one if community contribution is desired. | +| Changelog | Adequate | Changelog exists and records `v0.1.0-rc.2` as local/public-release notes. | Medium | Align changelog with actual public releases/tags. | +| API documentation | Strong | API docs describe `/v1`, idempotency, Problem Details, auth/scopes, endpoint catalog. | Low | Add generated examples and client snippets per core workflow. | +| Configuration docs | Strong | Runtime variables and production rejection checks are documented. | Low | Add “minimal production env” and “bad config examples.” | +| Operational docs | Adequate | Operations index exists; observability docs exist. | Medium | Add incident runbook, backup/restore runbook, upgrade runbook, capacity guidance. | +| Dependency automation | Missing | I did not find Dependabot/Renovate config. | Medium | Add Dependabot or Renovate for Go, Actions, Docker, Helm. | +| OpenSSF-style posture | Weak | Security files and gosec/govulncheck exist, but no visible Scorecard, SBOM/provenance, or public signed release. | High | Add Scorecard, SLSA/provenance, SBOM for releases, artifact signatures, branch protection. | + +--- + +# 8. Final verdict + +## Verdict: **Promising but not production-ready** + +This project is **worth continuing**, but it should be positioned as a **controlled self-hosted production candidate / internal pilot platform**, not a broadly production-ready product. + +Direct answers: + +* **Is it mature and high-grade enough for production for most uses?** No. The repo itself says broad production, regulated production, and hosted SaaS production remain out of scope until additional controls and exit review pass. +* **Is it highly marketable and interesting?** Interesting, yes. Highly marketable now, no. It lacks public releases, demos, screenshots, adoption, crisp positioning, and buyer proof. +* **Is it useful in real-world production, meaning it has enough features?** Yes, for narrow controlled internal use where the operator accepts single-writer API, self-hosting burden, and manual provider review. Not for broad customer-facing production. +* **What should be done next?** Stop adding breadth. Publish a real release candidate, harden the trust surface, ship one killer end-to-end demo, and finish the production exit checklist. + +--- + +# 9. Highest-leverage next steps + +## Next 1-2 days + +**1. Publish a real public release candidate.** +Why: no serious buyer trusts “local release evidence package generated under ignored `dist/`.” +Change: create a public GitHub release for the next RC with binaries, checksums, signed manifest, release notes, OpenAPI checksum, migration checksums, and image digest. Use the existing release-artifacts workflow and release-candidate checklist. +Improves: trust, installability, procurement confidence. + +**2. Add a security reporting channel that is not LinkedIn.** +Why: LinkedIn private-channel negotiation is amateur-hour for a high-trust security project. +Change: update `SECURITY.md` with `security@...`, GitHub private vulnerability reporting, supported versions, expected response windows, and advisory publication process. +Improves: security trust and open-source credibility. + +**3. Add README badges and public proof.** +Why: claims need visible machine proof. +Change: add CI status, release status, license, Go version, coverage if available, and latest release badge. +Improves: quick trust assessment. + +**4. Add issue templates.** +Why: SUPPORT.md asks for structured bug reports, but the repo does not appear to provide templates. +Change: add `.github/ISSUE_TEMPLATE/bug_report.yml`, `feature_request.yml`, `docs.yml`, and a “security: do not post secrets” placeholder. +Improves: maintainer efficiency and community hygiene. + +**5. Add a blunt “Current limitations” box near the top of README.** +Why: the limitations are present but buried. +Change: summarize single-writer API, no broad production, no provider management API sync, no native PKCS#11, no legal compliance conclusion. +Improves: buyer trust because it prevents overclaiming. + +## Next 1-2 weeks + +**1. Build one complete demo path.** +Why: current examples are useful but fragmented. +Change: create `examples/end-to-end-release-evidence/` with GitHub Actions or GitLab CI producing build metadata, SBOM, vulnerability scan, VEX decision, release bundle, readiness report, and customer package. Include a short video/GIF or screenshots. +Improves: marketability and adoption. + +**2. Add full Docker Compose app stack.** +Why: Compose currently runs dependencies, not the app. +Change: add `compose.production-like.yml` with API, worker, Postgres, MinIO, migrations, secrets via env file, and health checks. +Improves: evaluator success rate. + +**3. Add dependency automation and OpenSSF basics.** +Why: security buyers expect this. +Change: add Dependabot/Renovate, OpenSSF Scorecard workflow, pinned GitHub Actions where feasible, and release SBOM/provenance generation. +Improves: open-source trust. + +**4. Add backup/restore and upgrade runbooks.** +Why: evidence ledger value dies if restore is fuzzy. +Change: add `docs/runbooks/backup-restore.md`, `docs/runbooks/upgrade.md`, and `docs/runbooks/incident-response.md`. Tie them to existing backup manifest and release validation docs. +Improves: production readiness. + +**5. Publish API client examples.** +Why: API-first products need low-friction adoption. +Change: add examples for Go, TypeScript, Python SDK wrappers: create release, upload SBOM, upload scan, record decision, fetch readiness. +Improves: developer experience. + +**6. Add capacity and failure-mode docs.** +Why: single-writer is okay only if users understand throughput and blast radius. +Change: document tested object sizes, worker batch behavior, outbox retry behavior, DB connection pool expectations, payload limits, and failure/retry semantics. +Improves: operational confidence. + +## Next 1-2 months + +**1. Finish splitting the giant ledger aggregate.** +Why: this is the biggest production blocker. +Change: move from massive aggregate/mutex/map persistence toward focused service/repository boundaries for core write paths. Keep relational reconstruction, but make per-resource transactions canonical. +Improves: concurrency, maintainability, testability, and HA path. + +**2. Decide the HA story.** +Why: “one API writer” caps serious adoption. +Change: either keep explicit “small internal production only” forever, or implement reviewed multi-writer concurrency with database constraints, row-level transactions, optimistic locking, idempotency, and conflict tests. +Improves: production scalability. + +**3. Add real provider integrations or narrow the promise.** +Why: buyers will expect GitHub/GitLab/Jira/Slack/IdP integrations, not just records. +Change: either build direct provider collectors/validators or explicitly position Evydence as “bring-your-own evidence API.” +Improves: market clarity. + +**4. Build a minimal UI or trust package viewer.** +Why: API-only is fine for engineers, bad for buyers and auditors. +Change: add a simple read-only package viewer for release evidence, customer security packages, and readiness reports. +Improves: B2B usability. + +**5. Add enterprise trust artifacts.** +Why: ironic but necessary for a trust tool. +Change: project SBOM, vulnerability disclosure process, release provenance, signed container images, immutable image tags, public security advisories, and possibly a public trust page. +Improves: buyer confidence. + +--- + +# 10. README/product-page rewrite advice + +## Sharper one-sentence pitch + +> Evydence is a self-hosted release evidence ledger that helps software teams collect, verify, and share tamper-evident technical evidence for each release. + +## Target user + +Security, platform, AppSec, and compliance-readiness teams at B2B software companies that need customer-reviewable release evidence without relying entirely on a SaaS GRC platform. + +## Core use case + +“Before shipping a release, collect SBOM, vulnerability scan, VEX decisions, build/source/deployment evidence, controls, exceptions, release bundle, and customer-safe package. Then show readiness gaps and limitations.” + +## Best demo to show first + +A single end-to-end flow: + +1. CI builds artifact. +2. CI uploads SBOM and scan. +3. Security records VEX decision for one finding. +4. Evydence creates release bundle. +5. Evydence generates readiness report. +6. Evydence exports customer package. + +## Proof points to add + +* Published signed release. +* Passing CI badge. +* Coverage badge. +* Architecture diagram. +* 5-minute demo. +* Example generated customer package. +* Example readiness report. +* Example audit-chain verification. +* “Why not Dependency-Track / Vanta / build in-house?” section. + +## Remove or de-emphasize + +Do not lead with every feature. The current README lists too much too early. Move the huge capability inventory lower. Lead with pain, demo, install, and proof. Keep the non-claims, but compress them into a clear “Boundaries” section instead of letting the README feel defensive from line one. + +Bottom line: **continue it, but stop broadening it until it earns trust.** The project has enough substance to be worth hardening. It does not yet have enough public proof, operational maturity, or product clarity to be sold as production-ready. + +[1]: https://github.com/aatuh/evydence?utm_source=chatgpt.com "GitHub - aatuh/evydence: Self-hosted API-first evidence ledger for software release compliance readiness · GitHub" +[2]: https://www.vanta.com/ "https://www.vanta.com/" +[3]: https://drata.com/ "https://drata.com/" +[4]: https://dependencytrack.org/ "https://dependencytrack.org/" +[5]: https://www.defectdojo.org/ "https://www.defectdojo.org/" +[6]: https://guac.sh/ "https://guac.sh/" +[7]: https://in-toto.io/ "https://in-toto.io/" +[8]: https://slsa.dev/ "https://slsa.dev/" diff --git a/.production_readiness_v2.md b/.production_readiness_v2.md new file mode 100644 index 0000000..9661d8c --- /dev/null +++ b/.production_readiness_v2.md @@ -0,0 +1,605 @@ +## Latest visible state inspected + +Repository: `aatuh/evydence`, `https://github.com/aatuh/evydence`. + +Audit scope: latest public GitHub state plus the current local checkout at +`/home/aatu/projects/evydence`. These are not the same state. The public default +branch is clean at commit `842fb053f303b2a78eb3118be6a4536715571215`; the local +checkout is dirty and contains substantial uncommitted production-readiness work. + +Default branch: `master`. + +Latest public commit verified through `gh`: + +- SHA: `842fb053f303b2a78eb3118be6a4536715571215` +- Message: `feat: add direct cloud kms signers` +- Author date: `2026-05-31T08:36:23Z` +- Commit date: `2026-05-31T08:37:01Z` +- Local equivalent: `2026-05-31 11:37:01 +0300` + +Latest public release/tag: none visible. `gh release list` returned no releases, +and `gh api repos/aatuh/evydence/tags` returned an empty list. + +Primary language and package manifests: Go module +`github.com/aatuh/evydence` with `go.mod` and `go.sum`; small supporting +Python, shell, TypeScript, Docker, Helm, and YAML assets. + +License: AGPL-3.0, visible publicly through GitHub license metadata and local +`LICENSE`. The repo documents `AGPL-3.0-only` as the intended SPDX expression. + +Public visibility and activity: public, not archived, pushed on +`2026-05-31T08:41:59Z`, zero stars, zero forks, zero watchers at inspection +time. The latest public CI run for `842fb053f303b2a78eb3118be6a4536715571215` +completed successfully. + +Public repository metadata verified: + +- Description: `Self-hosted API-first evidence ledger for software release compliance readiness`. +- Topics include `api-first`, `audit-log`, `evidence-ledger`, `openapi`, + `release-evidence`, `sbom`, `self-hosted`, `supply-chain-security`, `vex`, + `vulnerability-management`, and `compliance-readiness`. +- GitHub community profile health: `71`. +- Public community profile showed README, LICENSE, CONTRIBUTING, and docs; it + did not show a public code of conduct, issue templates, or PR template. +- Public branch protection for `master`: disabled. The branch API reported + `protected: false`; the protection endpoint returned `Branch not protected`. +- Public issues and pull requests: none visible through `gh issue list` and + `gh pr list`. + +Local checkout state: + +- Branch: `master...origin/master`. +- Dirty files include README, Makefile, Dockerfile, SECURITY.md, docs, release + scripts, and several app files. +- Untracked local files include issue templates, Dependabot config, Scorecard + workflow, CODE_OF_CONDUCT.md, production-like Compose, examples, runbooks, + benchmark docs, package viewer files, and service-split files. +- Local checks run for this audit: + - `make fast-check`: passed. + - `set -a; . ./.test.env.example; set +a; make production-check`: passed. + - `set -a; . ./.test.env.example; set +a; make release-candidate-check TAG=v0.1.0-rc.4`: failed because the worktree is dirty. + +What could not be inspected: + +- GitHub private vulnerability reporting setting. +- GitHub secret scanning, push protection, Dependabot alerts, code scanning + settings, and required status-check settings beyond the visible fact that + `master` is unprotected. +- Contents of GitHub Actions artifacts from the latest public CI run. +- Release signing secret configuration for `.github/workflows/release-artifacts.yml`. +- Any real deployed Evydence instance, live KMS/HSM, live S3 object lock policy, + external transparency provider, provider-specific SSO/group sync, or SaaS + operations environment. + +Confidence impact: medium confidence. The local and public states were verified, +and local gates were run. Confidence is not high because the strongest local +work is uncommitted, public releases/tags are absent, and key GitHub security +settings are external or not visible. + +## What the project appears to be + +Evydence is a self-hosted API service and CLI/worker toolchain for collecting, +linking, verifying, and sharing technical release evidence. It targets release +evidence rather than generic compliance dashboards: products, projects, +releases, artifacts, SBOMs, vulnerability scans, VEX, vulnerability decisions, +exceptions, build provenance, source/deployment evidence, controls, release +bundles, customer packages, audit chains, and readiness reports. + +Likely users are security engineering, AppSec, platform, DevSecOps, and +compliance-readiness teams at B2B software companies that need auditable, +customer-reviewable release evidence while keeping the evidence ledger +self-hosted. + +Category: release evidence ledger, software supply-chain evidence platform, +technical compliance-readiness API, and customer security-package tooling. +Adjacent categories include SBOM/vulnerability management, SaaS GRC platforms, +trust centers, in-toto/SLSA provenance tooling, and internal security-evidence +datastores. + +The public committed README communicates the category within about 30 seconds +for a technical reader, but not for a skeptical buyer. It explains that Evydence +is a self-hosted API-first evidence ledger and explicitly avoids legal +compliance, certification, complete-SBOM, scanner-authority, and secure-release +claims. The local dirty README is sharper: it adds badges, a target-user +paragraph, current limitations, a fastest proof path, and "why not existing +tools" positioning. That local version is better, but it is not yet public. + +Product shape: server/API product with CLI, worker, OpenAPI contract, SDK +wrappers, PostgreSQL/object-store runtime, migrations, Docker/Compose/Helm +deployment assets, CI examples, and documentation. It is not just a library. + +## Production readiness + +Evidence supporting serious use: + +- Public CI exists and the latest public `Production Check` workflow run for + `842fb053f303b2a78eb3118be6a4536715571215` passed. +- Local `make production-check` passed during this audit. That gate ran + `release-check`, coverage threshold, live PostgreSQL integration, + migration compatibility, and a release signing smoke test. +- Local coverage gate passed at `80.3%`, above the required `80.0%`. +- Local `make fast-check` passed, including unit tests, OpenAPI check, + OpenAPI precision check, docs check, deployment check, and SDK check. +- The API contract is large and concrete: the route matrix contains 166 precise + operations and zero broad operations in the local check. +- The repo has Go services under `cmd/`, domain/app/adapters under `internal/`, + PostgreSQL migrations, OpenAPI, object-store adapters, signing adapters, worker + outbox docs, release scripts, Dockerfile, Helm chart, and operational docs. +- Production startup rejects unsafe defaults: production requires PostgreSQL, + non-default API-key pepper, supported signing key mode, no bootstrap-secret + printing, single API writer mode, and one declared API writer replica. +- PostgreSQL production mode defaults to relational-only load and disables + compatibility snapshot writes when configured that way. +- Worker jobs use PostgreSQL row locking and safe retry/terminal status handling. +- Docs cover production readiness, release validation, configuration, + Kubernetes, observability, worker outbox, backup/restore, upgrade, incident + response, and capacity/failure modes in the local dirty tree. + +Brutal assessment: + +Evydence is now credible as a controlled self-hosted candidate in a way the +first audit could not prove. The local checkout compiles, passes a meaningful +production gate, enforces an 80% coverage threshold, and has a serious release +evidence pipeline. + +It is still not broadly production-ready. + +The public repository has no release tag and no release artifact. That is a +hard adoption blocker for a public infrastructure/security project. A local +signed `v0.1.0-rc.3` package is mentioned in the dirty README and changelog, but +the public GitHub release/tag surface proves none of it to an outside user. + +The architecture remains a production-maturity risk. The local service split has +improved boundaries, but `internal/app/ledger.go` is still about 2,077 lines, +`internal/app/state.go` still exposes a large `PersistedState`, and +`internal/adapters/postgres/store.go` is about 5,292 lines. That does not make +the system unusable, but it means most production confidence still comes from +tests and gates rather than a simple, obviously decomposed repository model. + +The HA stance is honest and limited: one API writer replica. Workers may scale, +but API writes are intentionally not multi-writer. That is acceptable for +controlled internal deployments, not for broad production claims. + +Some high-trust integrations are still profile-dependent: native PKCS#11/HSM, +direct provider-specific management API clients and external group sync, broad +object-lock/WORM proof, live transparency-provider semantics, and operator +backup/restore evidence. The docs state these limitations instead of hiding +them, which is good, but they remain real constraints. + +Production readiness score: 6.5/10. + +Classification: controlled internal pilot / controlled self-hosted production +candidate, not broadly production-ready. + +## Feature completeness + +Supported end-to-end production-relevant use cases: + +- Tenant-scoped API-key bootstrap, authentication, scopes, and idempotent API + writes. +- Product/project/release/artifact creation. +- Evidence ingestion and lifecycle behavior for immutable or append-only + evidence records. +- SBOM, vulnerability scan, OpenAPI contract, VEX, vulnerability decisions, + exceptions, readiness reports, control coverage, CRA-readiness reports, and + release bundles. +- Build provenance, collectors, GitHub Actions metadata capture, DSSE/in-toto + structural attestation parsing, source/deployment/incident records, packages, + report templates, retention records, backup manifests, and verification + records. +- PostgreSQL durable runtime, filesystem and S3-compatible object stores, + worker outbox, migrations, Helm, Dockerfile, CI, release scripts, and SDK + wrappers. +- Local production evidence workflow: `make production-check` produces + release-check summary and a signed manifest smoke test. + +Important missing or shallow use cases: + +- No public installable release, signed public artifacts, image digests, or + published release notes. +- No public end-to-end demo in the committed tree. The local checkout has + untracked `examples/end-to-end-release-evidence/`, but public GitHub does not. +- No polished admin UI or customer trust portal. The local checkout has a + package viewer under `site/`, but it is untracked and not a full product UI. +- Native PKCS#11/HSM module support remains external/gateway-backed. +- Full object-lock/WORM proof remains deployment/provider-specific. +- Direct provider-specific management API clients and external group sync are + not complete. +- Multi-writer API HA is intentionally unsupported. +- No real adoption proof, customer case study, public benchmark run, or public + third-party audit. + +Table-stakes features for this category: + +- Public signed releases and checksums. +- Repeatable install path with immutable images/tags. +- Security reporting channel and visible security settings. +- Backup/restore and upgrade runbooks. +- Real CI evidence and coverage. +- A fast demo that proves time-to-value without maintainer narration. +- Clear limits on compliance claims. + +Evydence now has many table stakes locally, but not all publicly. Public release +integrity and demo proof remain the biggest gaps. + +Feature completeness score: 7.5/10. + +Maturity classification: productizable system for a narrow controlled +self-hosted profile; not yet a complete public production product. + +## Security and open-source trust + +Strong signals: + +- AGPL license, commercial licensing, governance, contribution, support, + trademark, security, and release-evidence metadata exist in the committed + public tree. +- Public CI latest run is green and runs `make production-check` with live + PostgreSQL. +- Local production gate includes lint, gosec, govulncheck, race tests, + migration compatibility, coverage threshold, PostgreSQL integration, and + release signing smoke test. +- Local `gosec` reported `0 issues`; `govulncheck` reported no called + vulnerabilities. +- API keys, SSO sessions, portal tokens, and collector secrets are designed + around one-time secret display and hash storage rather than raw secret + persistence. +- Docs repeatedly forbid public leakage of raw evidence payloads, bearer tokens, + private keys, provider credentials, database URLs, and customer data. +- Product language avoids claims of legal compliance, certification, complete + SBOMs, authoritative scanner output, and secure releases. +- Local dirty tree adds stronger security intake language, CODE_OF_CONDUCT, + issue templates, Dependabot config, and Scorecard workflow. + +Weak signals: + +- Public `master` branch protection is off. +- No public tags or releases exist. +- The public security policy at `HEAD` still routes first security contact + through LinkedIn until a dedicated channel or advisory portal exists. The + local dirty `SECURITY.md` improves this, but it is not public. +- GitHub private vulnerability reporting, secret scanning, push protection, + Dependabot alerts, and code scanning settings could not be verified. +- Public GitHub community profile did not show a code of conduct or issue + templates. The local dirty tree has them, but they are uncommitted. +- No public release SBOM/provenance artifacts exist because no public release + exists. +- Public adoption is zero visible stars/forks/watchers. Stars are not quality, + but zero adoption increases buyer uncertainty. + +Security and open-source trust score: 6/10. + +The internal security engineering signals are materially better than the public +trust surface. For a high-trust evidence ledger, the public trust surface must +catch up before serious adopters will rely on it. + +## Marketability and positioning + +The pain is real. Security and platform teams at B2B vendors regularly need to +answer release-evidence questions: what changed, what SBOM applies, which +vulnerabilities were reviewed, which exceptions were approved, what evidence is +safe to share with a customer, and what limitations remain. + +The public README is honest and technically clear, but it is still too much like +an implementation inventory. The local dirty README is significantly better: +it names the target user, gives a fastest proof path, adds badges, lists current +limitations near the top, and explains "why not Dependency-Track, Vanta/Drata, +or build in-house." That should be committed because it materially improves +marketability. + +Category crowding is real: + +- OWASP Dependency-Track is an API-first SBOM and software supply-chain risk + platform with SBOM, VEX, vulnerability intelligence, policy, and audit + workflows. +- DefectDojo is a mature open-source vulnerability-management and DevSecOps + platform with scan imports, deduplication, dashboards, API, reporting, and + many integrations. +- Vanta and Drata occupy the broader compliance/trust-management space with + evidence collection, continuous monitoring, trust centers, questionnaire + automation, and integrations. +- GUAC, in-toto, SLSA, Sigstore, and related tools address supply-chain + metadata, provenance, signatures, and verification from different angles. + +Evydence has a plausible niche: self-hosted, release-centered, API-first, +tamper-evident evidence records and customer-reviewable packages, with explicit +non-claim language. That is more specific than generic GRC and more release +review-oriented than SBOM-only or vulnerability-only tools. + +Marketability weaknesses: + +- No public release means no serious "try this version" path. +- No public demo asset or screenshots in committed GitHub state. +- No adoption proof or third-party validation. +- No hosted option, marketplace integration, or commercial contact funnel beyond + docs. +- The product is broad enough that buyers may doubt depth until a demo proves it. +- The name is memorable but the misspelling can hurt procurement/search trust + unless the tagline is strong. + +Marketability and positioning score: 5.5/10. + +It is interesting, but not yet easy to adopt or buy. + +## Differentiation + +Direct alternatives: + +- OWASP Dependency-Track for SBOM, VEX, vulnerability intelligence, policy, and + audit workflows. +- DefectDojo for vulnerability aggregation, AppSec workflow, finding + deduplication, reporting, and security-tool integrations. +- Vanta, Drata, Secureframe, and similar platforms for compliance automation, + evidence collection, trust centers, questionnaires, and broad GRC workflows. +- GUAC for graph-based software supply-chain metadata relationships. + +Indirect alternatives: + +- GitHub Advanced Security, GitLab Ultimate, Snyk, Wiz, JFrog Xray, Sonatype, + and other security platforms. +- in-toto, SLSA, Sigstore, Rekor, Cosign, and provenance/signature stacks. +- Internal evidence systems built from CI jobs, object storage, PostgreSQL, + spreadsheets, Jira, Confluence, and custom report scripts. + +Do-nothing/build-in-house alternative: + +Many teams will keep using CI artifacts, object storage, a few tables, GRC +screenshots, and manual release-review documents. That is brittle but cheap. +Evydence has to prove that its audit chains, release bundles, tenant-scoped API, +reports, and package exports reduce enough pain to justify operating another +self-hosted service. + +Meaningful differentiation: + +- Release-centered evidence ledger rather than generic compliance database. +- Self-hosted, API-first, OpenAPI-contracted surface. +- Tamper-evident audit-chain and release-bundle orientation. +- Broad evidence model across SBOM, VEX, vulnerability decisions, builds, + source, deployments, incidents, controls, packages, retention, and reports. +- Strong non-claim language, which is unusually important in compliance-adjacent + tooling. +- Air-gapped/offline and customer-package direction. + +Weak differentiation: + +- Public proof is missing: no release, no demo, no public evidence package. +- Deep integrations are still limited compared with mature commercial platforms. +- UI/trust-center experience is not productized. +- The broad feature surface may look shallow until a focused demo proves the + release evidence path end to end. + +Differentiation score: 6.5/10. + +## Repository quality checklist + +| Area | Status | Evidence | Severity | Recommended fix | +|------|--------|----------|----------|-----------------| +| README | Adequate | Public README explains purpose and non-claims; local dirty README has stronger buyer positioning, badges, proof path, limitations, and differentiation. | Medium | Commit the improved README, keep limitations near the top, and add a direct install/demo path once a release exists. | +| Quickstart | Adequate | Public docs include `docs/tutorials/getting-started.md`; local checks passed docs validation. | Medium | Add one command/script that runs a durable demo against API, worker, PostgreSQL, and object storage. | +| Examples/demo | Weak | Public committed tree has docs examples but no public `examples/` directory; local dirty tree has SDK and end-to-end examples. | High | Commit executable examples and include sample readiness/package/audit outputs. | +| Tests | Strong | Local `make fast-check` and `make production-check` passed; latest public CI production check passed; local coverage total is `80.3%`. | Medium | Keep coverage above threshold and add black-box API/e2e tests for the primary release-evidence flow. | +| CI | Adequate | Public CI exists and latest run is green; it provisions PostgreSQL and runs `make production-check`. | Medium | Add required branch protection and publish release evidence artifacts in a visible release workflow. | +| Releases/provenance | Weak | Release workflow and packaging scripts exist, but public GitHub has no tags/releases; local release-candidate check fails while worktree is dirty. | Blocker | Clean/commit the worktree, run release-candidate packaging, push an annotated RC tag, and publish signed draft release artifacts. | +| Docs/API/config/ops | Strong | Docs include API, OpenAPI matrix, configuration, operations, Kubernetes, release validation, production readiness, worker outbox, and runbooks in local state. | Low | Reduce repetition and keep docs clearly separated between public committed state, local candidate state, and roadmap. | +| Docker/deployment | Adequate | Dockerfile, Helm chart, and public Docker Compose dependencies exist; local dirty tree adds production-like Compose and deploy-check assertions. | Medium | Commit production-like Compose, publish images, and document immutable image digests for release candidates. | +| Security policy | Weak | Public SECURITY.md exists but still depends on LinkedIn first contact; local dirty version improves wording but cannot prove GitHub private reporting. | High | Enable GitHub private vulnerability reporting or publish a dedicated security email, then commit the stronger policy. | +| License/contribution/governance | Adequate | Public LICENSE, CONTRIBUTING, GOVERNANCE, SUPPORT, COMMERCIAL, TRADEMARKS exist; public community profile lacks code of conduct and issue templates. | Medium | Commit CODE_OF_CONDUCT and issue templates; consider a PR template and clearer commercial/security contact. | +| Changelog/versioning | Adequate | Public CHANGELOG exists and local dirty changelog tracks `v0.1.0-rc.3`; no public tags/releases make version claims weak. | High | Align changelog with a public tagged RC and stop relying on local-only release evidence for public trust. | + +## Scorecard + +| Dimension | Score | Notes | +|-----------|------:|-------| +| Production readiness | 6.5/10 | Local production gate passed with PostgreSQL, coverage, migration compatibility, race/security scans, and signing smoke test; no public release and single-writer API keep the cap low. | +| Feature completeness | 7.5/10 | Broad API surface and core release-evidence workflow exist, but deep provider integrations, UI/trust portal, native HSM, broad WORM proof, and public demo proof remain incomplete. | +| Security and open-source trust | 6/10 | Strong local gates and careful secret/non-claim handling; weak public branch protection, no release artifacts, no verified private reporting, no public code of conduct/templates/dependabot/scorecard yet. | +| Marketability and positioning | 5.5/10 | Real pain and plausible niche, but public README/demo/release/adoption evidence are not strong enough for buyer confidence. | +| Differentiation | 6.5/10 | Release-centered, self-hosted, tamper-evident evidence ledger is meaningfully distinct, but not yet proven against Dependency-Track/GRC/build-in-house alternatives. | +| Repository evidence quality | 7/10 | The local repo has unusually strong checks and docs; confidence is reduced by the dirty checkout and gap between local work and public state. | +| Overall | 6.5/10 | Credible controlled candidate, not a broadly production-ready public product. | + +Confidence: medium + +Verdict: Promising but not production-ready + +Direct answers: + +- Is it mature and high-grade enough for production for most intended uses? No. + It is credible for controlled self-hosted pilots or carefully reviewed + internal deployments, but not for most intended uses. +- Is it feature-complete enough to solve a real-world problem? Yes, for a + narrow release-evidence workflow where the operator accepts the single-writer + and self-hosted constraints. No, for broad enterprise trust-center/GRC + replacement use. +- Is it marketable or interesting enough to attract users, buyers, + contributors, or commercial opportunity? Interesting, yes. Highly marketable, + no. The public release/demo/security surface must improve first. +- Is it worth continuing, hardening, repositioning, or abandoning? Continue and + harden. Do not broaden features until the public release and demo proof exist. + +## Highest-leverage next steps + +Next 1-2 days: small fixes that immediately improve trust + +1. Commit and push the current trust-surface improvements. + Why it matters: the local checkout has CODE_OF_CONDUCT, issue templates, + Dependabot, Scorecard, stronger SECURITY.md, production-like Compose, and + examples that public GitHub cannot see. + Files/features: `.github/ISSUE_TEMPLATE/*`, `.github/dependabot.yml`, + `.github/workflows/scorecard.yml`, `CODE_OF_CONDUCT.md`, `SECURITY.md`, + `README.md`, `compose.production-like.yml`, `examples/`, docs/runbooks. + Improvement: closes the gap between local evidence and public trust. + +2. Publish a real release candidate. + Why it matters: no public tags or releases is the largest public adoption + blocker. + Files/features: `scripts/release_candidate_package.sh`, + `.github/workflows/release-artifacts.yml`, `docs/reference/release-candidate.md`, + `CHANGELOG.md`, GitHub release page. + Improvement: creates installable signed artifacts, checksums, release notes, + OpenAPI checksum, migration checksum, and release evidence. + +3. Enable or prove a private security reporting path. + Why it matters: a high-trust evidence ledger cannot rely on ambiguous first + contact. + Files/features: GitHub private vulnerability reporting setting or a dedicated + `security@` mailbox; `SECURITY.md`. + Improvement: improves open-source trust and responsible disclosure. + +4. Turn on branch protection and required checks for `master`. + Why it matters: public branch protection is currently off. + Files/features: GitHub repository settings; document required check names in + `docs/reference/release-validation.md`. + Improvement: makes the green CI signal enforceable. + +5. Add a visible demo pointer at the top of README. + Why it matters: users need a fast proof path, not a feature inventory. + Files/features: `README.md`, `examples/end-to-end-release-evidence/README.md`, + sample reports. + Improvement: improves adoption and makes the product legible. + +Next 1-2 weeks: changes that materially improve production readiness and marketability + +1. Build and document one complete black-box release-evidence scenario. + Why it matters: broad API surface is less convincing than one proven flow. + Files/features: e2e test or script that starts API/worker/Postgres/MinIO, + creates product/release/artifact, uploads SBOM/scan/VEX, generates bundle, + exports package, restarts, and verifies persistence. + Improvement: proves real value and catches integration drift. + +2. Publish container images with immutable digests for the RC. + Why it matters: self-hosted operators expect image install paths. + Files/features: release workflow, Dockerfile, release notes, Helm values. + Improvement: turns release artifacts into usable deployment inputs. + +3. Add externalized security/adoption metadata. + Why it matters: public trust depends on visible settings and automation. + Files/features: Dependabot/Scorecard, security advisories, release SBOM, + provenance, branch protection docs. + Improvement: strengthens open-source posture. + +4. Reduce service/repository concentration further. + Why it matters: large aggregate files remain the hardest architectural trust + issue. + Files/features: split `internal/app/ledger.go`, `internal/app/state.go`, and + `internal/adapters/postgres/store.go` by resource family without changing + public API behavior. + Improvement: lowers maintenance risk and prepares future HA. + +5. Add a small public package viewer/demo. + Why it matters: a customer package product needs something visible. + Files/features: `site/package-viewer/`, docs, sample package artifact. + Improvement: improves buyer understanding without adding a full admin UI. + +Next 1-2 months: changes that could make the project seriously productizable + +1. Finish the production exit review against a real deployment. + Why it matters: local gates do not prove target-environment operations. + Files/features: `docs/reference/production-exit-review.md`, release evidence, + deployment-specific backup/restore, monitoring, incident rehearsal. + Improvement: supports a stronger production claim for a bounded profile. + +2. Deepen provider integrations or deliberately narrow the promise. + Why it matters: buyer expectations around GitHub/GitLab/SSO/KMS/object lock + are high. + Files/features: provider-specific clients where needed, or docs that make + bring-your-own-evidence the explicit supported profile. + Improvement: reduces mismatch between claims and buyer expectations. + +3. Decide whether the product is API-only, API-plus-viewer, or a trust-center + product. + Why it matters: market positioning changes depending on the answer. + Files/features: README, docs, package viewer, examples, commercial docs. + Improvement: clarifies adoption path and avoids competing poorly with full + GRC platforms. + +4. Add public benchmarks and capacity envelopes for the supported profile. + Why it matters: single-writer can be acceptable if capacity is quantified. + Files/features: benchmark harness, `docs/reference/benchmark-results.md`, + `docs/reference/capacity-and-failures.md`. + Improvement: turns architectural caveats into operator guidance. + +5. Seek external validation before broad claims. + Why it matters: self-scored high-trust software is not enough. + Files/features: third-party security review, public audit summary, release + candidate feedback issue/discussion. + Improvement: improves buyer confidence. + +## README/product-page rewrite advice + +Sharper one-sentence pitch: + +Evydence is a self-hosted release evidence ledger for B2B software teams that +need tamper-evident, customer-reviewable technical evidence for every release +without sending release trust data to a SaaS GRC platform. + +Target user: + +Security engineering, AppSec, platform, and compliance-readiness teams that +own release evidence, customer security reviews, SBOM/VEX workflows, and +technical control coverage. + +Core use case: + +Before a release ships, collect SBOM, vulnerability scan, VEX/decision, +artifact/build/source/deployment evidence, generate a signed release bundle, +show readiness gaps, and export a scoped customer-safe package with limitations. + +Best demo/example to show first: + +A single local script that starts the production-like stack, ingests sample +release evidence, prints the readiness report, verifies the audit chain, and +opens a customer package manifest/viewer. + +Proof points to add: + +- Public RC tag and signed artifacts. +- CI badge tied to `make production-check`. +- Coverage result. +- OpenAPI precision count. +- Sample release readiness report. +- Sample customer package. +- Sample audit-chain verification receipt. +- Benchmark envelope for the single-writer profile. + +What to remove or de-emphasize: + +- Long feature inventory before the buyer understands the core workflow. +- Local-only release-candidate claims unless clearly labeled as local. +- Roadmap breadth that makes the product look less focused. +- Any wording that suggests legal compliance, certification, secure release, + complete SBOM, or authoritative vulnerability results. + +## Residual risk and uncertainty + +Untested or unproven in this audit: + +- Public release artifact generation, upload, and verification because no public + tags or releases exist and the local worktree is dirty. +- Real deployed API/worker behavior outside the local gate. +- Real S3/MinIO object-lock enforcement beyond code/docs and local tests. +- Native HSM/PKCS#11 custody. +- External transparency provider inclusion proof semantics. +- GitHub private vulnerability reporting and secret-scanning settings. +- Branch protection/required checks because public branch protection is off. +- Adoption, support process, and buyer trust in a real organization. + +Claims still mostly intended or bounded: + +- Controlled self-hosted production candidate is supported by local gates and + docs, but not by a public release. +- Regulated production, broad production for most uses, and hosted SaaS + production remain out of scope. +- Compliance readiness and technical evidence organization are credible goals; + legal compliance, certification, complete SBOM coverage, authoritative + scanner output, and secure-release guarantees are intentionally not claimed. + +Evidence that would raise confidence: + +- Public signed release candidate with checksums, manifest signature, OpenAPI + checksum, migration checksums, coverage, release notes, and image digests. +- Branch protection with required `Production Check`. +- Enabled private vulnerability reporting or dedicated security mailbox. +- Public dependency automation and Scorecard run. +- A reproducible end-to-end demo using the production-like stack. +- Third-party review or early-user feedback tied to a concrete release. From 9007d47f630a7b0c81e86a6f641ac91cf38928d2 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 16:18:34 +0300 Subject: [PATCH 148/287] docs: track production readiness v2 remediation --- .production_readiness_v2.md | 52 +++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/.production_readiness_v2.md b/.production_readiness_v2.md index 9661d8c..5c153bc 100644 --- a/.production_readiness_v2.md +++ b/.production_readiness_v2.md @@ -1,3 +1,55 @@ +# Production Readiness Public Repo Audit V2 + +## 2026-05-31 Reanalysis And Remediation Tracking + +Status legend: + +- `[ ]` applicable repository-local work that remains incomplete. +- `[x]` applicable repository-local work completed with current repository evidence. +- `[e]` external, account-level, provider-level, operator-environment, or adoption-dependent work that cannot be completed by repository files alone. + +Current state rechecked after the original audit: + +- Public `origin/master` now points at `aa21ac84ca4d866f6101a8937a646b0631c9052a`, which includes the trust-surface documentation, examples, production-like Compose assets, Scorecard workflow, Dependabot config, issue forms, and product-code audit records that the original audit saw only as local work. +- Local checkout started this reanalysis clean at `master...origin/master`. +- Public GitHub community profile health increased to `85`; GitHub now sees `CODE_OF_CONDUCT.md`, `CONTRIBUTING.md`, `LICENSE`, and `README.md`. +- Public GitHub still reports no releases and no pushed tags, and `master` branch protection is still disabled. +- GitHub private vulnerability reporting, secret scanning, Dependabot alert settings, release signing secrets, branch protection rules, and required checks remain account/operator settings that repository files can document but cannot prove. + +Repository-local remediation items from this audit: + +- [x] Commit and push the trust-surface improvements that were local-only in the original audit: `README.md`, `SECURITY.md`, `.github/dependabot.yml`, `.github/workflows/scorecard.yml`, `.github/ISSUE_TEMPLATE/*`, `CODE_OF_CONDUCT.md`, `compose.production-like.yml`, examples, runbooks, and production-readiness docs are now on `origin/master`. +- [x] Add and commit a visible end-to-end evidence example under `examples/end-to-end-release-evidence/` with sample readiness, package manifest, audit-chain verification, and a runnable local API script. +- [x] Keep conservative product positioning in README and docs: controlled self-hosted production candidate, single API writer, operator review required, and no legal compliance, certification, complete-SBOM, scanner-authority, or secure-release claims. +- [x] Keep local production gates in repository commands: `make production-check`, `make release-candidate-check`, `make release-acceptance`, OpenAPI precision checks, migration compatibility checks, coverage threshold, and signing smoke tests are present. +- [x] Preserve public trust metadata: AGPL license, commercial-license note, governance, contribution policy, security policy, support policy, trademark guidance, release evidence notes, changelog, code of conduct, issue forms, Dependabot, Scorecard workflow, CI, and release artifact workflow. +- [x] Document release-candidate evidence requirements: signed manifest, checksums, OpenAPI checksum, migration checksum, coverage output, production-check summary, release notes, and limitations. +- [x] Document the single-writer HA/concurrency stance and keep worker scaling bounded by PostgreSQL outbox locking. +- [x] Add fallback GitHub community templates for issue and pull request intake so public profile and reviewer workflows do not depend only on issue forms. +- [x] Add a repository-owned demo fixture check so sample release-evidence outputs and the local demo script are validated by the fast gate. +- [ ] Add a full black-box demo check that starts the production-like stack, bootstraps a tenant/API key, runs API and worker paths, restarts services, and verifies persisted readiness/package/audit outputs. +- [ ] Continue decomposing the largest application and PostgreSQL adapter files by resource family without changing public API behavior. +- [ ] Add public benchmark runs and capacity envelopes for the supported single-writer profile. +- [ ] Add a small public package-viewer walkthrough or hosted static demo artifact that can be evaluated without operating a full Evydence stack. +- [ ] Seek and publish third-party review or early-user feedback tied to a concrete release candidate. + +External or operator-dependent items from this audit: + +- [e] Publish a public GitHub release candidate with signed artifacts, checksums, release evidence, and image digests. Repository scripts and workflow support this, but pushing a release/tag and configuring signing secrets are operator actions. +- [e] Push release-candidate tags publicly. The local repository can create tags; publication is an operator action and should follow the release-candidate gate. +- [e] Enable branch protection and required checks for `master`; this is a GitHub repository setting. +- [e] Enable or verify GitHub private vulnerability reporting; this is a GitHub repository security setting. +- [e] Enable or verify GitHub secret scanning, push protection, Dependabot alerts, and code scanning; these are GitHub/account settings. +- [e] Publish container images with immutable registry digests; this requires registry credentials and release publication. +- [e] Prove native HSM/PKCS#11 custody, broad WORM/object-lock enforcement, real transparency-provider semantics, and provider-specific SSO/group synchronization in a deployed operator environment. +- [e] Prove real adoption, support process maturity, customer case studies, or third-party validation; these require external users or reviewers. +- [e] Claim regulated production or broad production readiness; this requires deployment-specific review and evidence beyond repository files. + +## Original Audit Snapshot + +The remaining sections preserve the original audit narrative. They should be +read with the remediation tracking above as the current status overlay. + ## Latest visible state inspected Repository: `aatuh/evydence`, `https://github.com/aatuh/evydence`. From ac0344b50a43b5005b47346bf6403da1082bd28f Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 16:18:40 +0300 Subject: [PATCH 149/287] chore: add community templates and demo gate --- .github/ISSUE_TEMPLATE.md | 35 ++++++++++++++++++++++++++++++++ .github/pull_request_template.md | 33 ++++++++++++++++++++++++++++++ Makefile | 21 ++++++++++++++++++- README.md | 2 ++ scripts/release_acceptance.sh | 6 ++++++ 5 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/pull_request_template.md diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..53ca208 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,35 @@ +# Issue Intake + +Use the structured issue forms when GitHub shows them. This fallback template is +for clients that do not render issue forms. + +Before posting, remove API keys, collector secrets, bearer tokens, session +tokens, portal tokens, private keys, provider credentials, database URLs, +raw evidence payloads, customer data, exploit payloads against third-party +systems, and unredacted customer package contents. + +Security vulnerabilities should not be reported in public issues. Use GitHub +private vulnerability reporting when available, or follow `SECURITY.md` to +request a private intake channel without including vulnerability details in the +first contact. + +## Summary + +Describe the bug, documentation gap, feature request, or production-support +question. + +## Environment + +- Evydence commit, tag, or image digest: +- Deployment profile: +- PostgreSQL/object-store mode: +- Relevant command or endpoint: + +## Evidence + +List sanitized logs, commands, request IDs, report IDs, or reproduction steps. +Do not attach raw tenant evidence or secrets. + +## Expected Outcome + +Describe the result you expected and the result you observed. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..b73a50c --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,33 @@ +# Pull Request + +## Summary + +- + +## Change Type + +- [ ] Documentation +- [ ] Tooling +- [ ] API contract +- [ ] Persistence/data +- [ ] Security/authz/session/secret handling +- [ ] Deployment/operations +- [ ] Refactor + +## Security And Evidence Invariants + +Confirm the change preserves tenant isolation, append-only evidence behavior, +safe errors/logs, conservative product language, and no compliance, +certification, complete-SBOM, scanner-authority, or secure-release claims. + +## Validation + +List the exact commands run and their results. Include skipped checks with the +reason. + +## Sensitive Data Check + +Confirm the PR does not include API keys, collector secrets, bearer tokens, +session tokens, portal tokens, private keys, provider credentials, database +URLs, raw evidence payloads, customer data, or unredacted customer package +contents. diff --git a/Makefile b/Makefile index e652f84..fd505af 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ GOVULNCHECK_VERSION ?= v1.2.0 TAG ?= -.PHONY: help tools fmt lint vuln gosec test test-race coverage coverage-check openapi-check openapi-precision-check meta-check docs-check deploy-check sdk-check fast-check finalize release-acceptance release-check production-check release-candidate-check migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean +.PHONY: help tools fmt lint vuln gosec test test-race coverage coverage-check openapi-check openapi-precision-check meta-check docs-check deploy-check sdk-check demo-check fast-check finalize release-acceptance release-check production-check release-candidate-check migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean help: ## Show help @awk 'BEGIN {FS=":.*## "}; /^[a-zA-Z0-9_.-]+:.*## / { printf " %-18s %s\n", $$1, $$2 }' $(MAKEFILE_LIST) @@ -69,10 +69,12 @@ meta-check: ## Validate root legal, governance, support, and release-evidence me @test -f .dockerignore @test -f .github/dependabot.yml @test -f .github/workflows/scorecard.yml + @test -f .github/ISSUE_TEMPLATE.md @test -f .github/ISSUE_TEMPLATE/bug_report.yml @test -f .github/ISSUE_TEMPLATE/feature_request.yml @test -f .github/ISSUE_TEMPLATE/docs.yml @test -f .github/ISSUE_TEMPLATE/production_support.yml + @test -f .github/pull_request_template.md @test -x scripts/release_acceptance.sh @test -x scripts/release_candidate_package.sh @test -x scripts/release_candidate_validate.sh @@ -84,6 +86,8 @@ meta-check: ## Validate root legal, governance, support, and release-evidence me @grep -F 'raw evidence payloads' SECURITY.md >/dev/null @grep -F 'release evidence artifacts' SUPPORT.md >/dev/null @grep -F 'Security vulnerability' .github/ISSUE_TEMPLATE/config.yml >/dev/null + @grep -F 'private vulnerability reporting' .github/ISSUE_TEMPLATE.md >/dev/null + @grep -F 'tenant isolation' .github/pull_request_template.md >/dev/null @grep -F 'OpenSSF Scorecard' .github/workflows/scorecard.yml >/dev/null @grep -F 'Evydence fork' TRADEMARKS.md >/dev/null @grep -F 'Release evidence is not a certification' RELEASE_EVIDENCE.md >/dev/null @@ -221,6 +225,19 @@ sdk-check: ## Validate SDK helper and generated route-catalog coverage against O @test -f sdk/openapi-route-catalog.json @python3 scripts/sdk_check.py +demo-check: ## Validate checked end-to-end evidence demo fixtures + @test -x examples/end-to-end-release-evidence/run-local-demo.sh + @test -f examples/end-to-end-release-evidence/README.md + @test -f examples/end-to-end-release-evidence/release-evidence-manifest.json + @test -f examples/end-to-end-release-evidence/sample-readiness-report.json + @test -f examples/end-to-end-release-evidence/sample-customer-package-manifest.json + @test -f examples/end-to-end-release-evidence/sample-audit-chain-verification.json + @python3 -c 'import json, pathlib; [json.loads(path.read_text()) for path in pathlib.Path("examples/end-to-end-release-evidence").glob("*.json")]' + @grep -F '/v1/reports/release-readiness' examples/end-to-end-release-evidence/run-local-demo.sh >/dev/null + @grep -F '/v1/audit-chain/verify' examples/end-to-end-release-evidence/run-local-demo.sh >/dev/null + @grep -F '/v1/customer-packages' examples/end-to-end-release-evidence/run-local-demo.sh >/dev/null + @grep -F 'not legal' examples/end-to-end-release-evidence/README.md >/dev/null + fast-check: ## Run non-mutating fast validation @$(MAKE) test @$(MAKE) openapi-check @@ -228,6 +245,7 @@ fast-check: ## Run non-mutating fast validation @$(MAKE) docs-check @$(MAKE) deploy-check @$(MAKE) sdk-check + @$(MAKE) demo-check finalize: ## Thorough validity check @$(MAKE) fmt @@ -237,6 +255,7 @@ finalize: ## Thorough validity check @$(MAKE) docs-check @$(MAKE) deploy-check @$(MAKE) sdk-check + @$(MAKE) demo-check release-acceptance: ## Run deterministic release metadata acceptance checks @scripts/release_acceptance.sh diff --git a/README.md b/README.md index 3cce21e..5fe8d76 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,8 @@ separate operator action. For a first local API flow, follow [Getting started](docs/tutorials/getting-started.md). For durable local evaluation, run the production-like Compose rehearsal in [Install and operate](docs/how-to/install-and-operate.md). +For the release-evidence path to inspect first, use the +[end-to-end release evidence example](examples/end-to-end-release-evidence/README.md). The end-to-end evidence flow to evaluate first is: diff --git a/scripts/release_acceptance.sh b/scripts/release_acceptance.sh index 29f010c..0c80299 100755 --- a/scripts/release_acceptance.sh +++ b/scripts/release_acceptance.sh @@ -43,6 +43,8 @@ for file in \ RELEASE_EVIDENCE.md \ CHANGELOG.md \ .dockerignore \ + .github/ISSUE_TEMPLATE.md \ + .github/pull_request_template.md \ README.md \ docs/README.md \ docs/reference/release-candidate.md \ @@ -62,6 +64,10 @@ require_text SECURITY.md "raw evidence payloads" require_text SECURITY.md "tenant isolation" require_text SECURITY.md "private security intake" require_text SECURITY.md "Supported Versions And Scope" +require_text .github/ISSUE_TEMPLATE.md "private vulnerability reporting" +require_text .github/ISSUE_TEMPLATE.md "raw evidence payloads" +require_text .github/pull_request_template.md "tenant isolation" +require_text .github/pull_request_template.md "Sensitive Data Check" require_text SUPPORT.md "sanitized logs" require_text SUPPORT.md "release evidence artifacts" require_text TRADEMARKS.md "Evydence fork" From 1b3ecb36dd0af7bd3893528e074f71434b73b1a5 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 16:33:56 +0300 Subject: [PATCH 150/287] test: add black-box production readiness gate --- .production_readiness_v2.md | 8 +- Makefile | 28 +++- docs/how-to/view-packages.md | 5 +- docs/reference/benchmark-results.md | 11 +- docs/reference/production-readiness.md | 3 + docs/reference/release-validation.md | 4 +- .../run-local-demo.sh | 16 +- scripts/black_box_demo_check.sh | 155 ++++++++++++++++++ scripts/production_check.sh | 2 + site/package-viewer/index.html | 65 ++++++-- 10 files changed, 270 insertions(+), 27 deletions(-) create mode 100755 scripts/black_box_demo_check.sh diff --git a/.production_readiness_v2.md b/.production_readiness_v2.md index 5c153bc..9917357 100644 --- a/.production_readiness_v2.md +++ b/.production_readiness_v2.md @@ -27,11 +27,10 @@ Repository-local remediation items from this audit: - [x] Document the single-writer HA/concurrency stance and keep worker scaling bounded by PostgreSQL outbox locking. - [x] Add fallback GitHub community templates for issue and pull request intake so public profile and reviewer workflows do not depend only on issue forms. - [x] Add a repository-owned demo fixture check so sample release-evidence outputs and the local demo script are validated by the fast gate. -- [ ] Add a full black-box demo check that starts the production-like stack, bootstraps a tenant/API key, runs API and worker paths, restarts services, and verifies persisted readiness/package/audit outputs. +- [x] Add a full black-box demo check that starts API and worker against a disposable PostgreSQL schema, bootstraps a tenant/API key, runs the release-evidence demo, restarts the API, and verifies persisted readiness/package/audit outputs. - [ ] Continue decomposing the largest application and PostgreSQL adapter files by resource family without changing public API behavior. -- [ ] Add public benchmark runs and capacity envelopes for the supported single-writer profile. -- [ ] Add a small public package-viewer walkthrough or hosted static demo artifact that can be evaluated without operating a full Evydence stack. -- [ ] Seek and publish third-party review or early-user feedback tied to a concrete release candidate. +- [x] Add public benchmark runs and capacity envelopes for the supported single-writer profile. +- [x] Add a small public package-viewer walkthrough or hosted static demo artifact that can be evaluated without operating a full Evydence stack. External or operator-dependent items from this audit: @@ -43,6 +42,7 @@ External or operator-dependent items from this audit: - [e] Publish container images with immutable registry digests; this requires registry credentials and release publication. - [e] Prove native HSM/PKCS#11 custody, broad WORM/object-lock enforcement, real transparency-provider semantics, and provider-specific SSO/group synchronization in a deployed operator environment. - [e] Prove real adoption, support process maturity, customer case studies, or third-party validation; these require external users or reviewers. +- [e] Seek and publish third-party review or early-user feedback tied to a concrete release candidate; repository files can prepare the process, but the review or feedback itself is external. - [e] Claim regulated production or broad production readiness; this requires deployment-specific review and evidence beyond repository files. ## Original Audit Snapshot diff --git a/Makefile b/Makefile index fd505af..18ecdb7 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ GOVULNCHECK_VERSION ?= v1.2.0 TAG ?= -.PHONY: help tools fmt lint vuln gosec test test-race coverage coverage-check openapi-check openapi-precision-check meta-check docs-check deploy-check sdk-check demo-check fast-check finalize release-acceptance release-check production-check release-candidate-check migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean +.PHONY: help tools fmt lint vuln gosec test test-race coverage coverage-check openapi-check openapi-precision-check meta-check docs-check deploy-check sdk-check demo-check black-box-demo-check benchmark-check package-viewer-check fast-check finalize release-acceptance release-check production-check release-candidate-check migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean help: ## Show help @awk 'BEGIN {FS=":.*## "}; /^[a-zA-Z0-9_.-]+:.*## / { printf " %-18s %s\n", $$1, $$2 }' $(MAKEFILE_LIST) @@ -109,11 +109,15 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @test -f docs/tutorials/getting-started.md @test -f docs/how-to/integrate-ci.md @test -f docs/how-to/install-and-operate.md + @test -f docs/how-to/view-packages.md @test -f docs/reference/configuration.md @test -f docs/reference/api-contract-matrix.md @test -f docs/reference/openapi.md @test -f docs/reference/observability.md + @test -f docs/reference/capacity-and-failures.md + @test -f docs/reference/benchmark-results.md @test -f docs/reference/production-readiness.md + @test -f docs/reference/production-exit-review.md @test -f docs/reference/release-candidate.md @test -f docs/reference/release-notes-template.md @test -f docs/reference/release-notes-v0.1.0-rc.1.md @@ -130,6 +134,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @for path in \ "tutorials/getting-started.md" \ "how-to/install-and-operate.md" \ + "how-to/view-packages.md" \ "how-to/integrate-ci.md" \ "api.md" \ "operations.md" \ @@ -141,7 +146,10 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod "reference/api-contract-matrix.md" \ "reference/openapi.md" \ "reference/observability.md" \ + "reference/capacity-and-failures.md" \ + "reference/benchmark-results.md" \ "reference/production-readiness.md" \ + "reference/production-exit-review.md" \ "reference/release-candidate.md" \ "reference/release-notes-template.md" \ "reference/release-notes-v0.1.0-rc.1.md" \ @@ -238,6 +246,22 @@ demo-check: ## Validate checked end-to-end evidence demo fixtures @grep -F '/v1/customer-packages' examples/end-to-end-release-evidence/run-local-demo.sh >/dev/null @grep -F 'not legal' examples/end-to-end-release-evidence/README.md >/dev/null +black-box-demo-check: ## Run live PostgreSQL black-box API/worker demo; requires EVYDENCE_TEST_DATABASE_URL + @scripts/black_box_demo_check.sh + +benchmark-check: ## Run the checked app-layer release evidence benchmark + @$(GO) test ./internal/app -bench BenchmarkReleaseEvidenceIngestion -benchtime=100x -run '^$$' -benchmem + @grep -F 'BenchmarkReleaseEvidenceIngestion' docs/reference/benchmark-results.md >/dev/null + @grep -F 'API writer replicas: `1`' docs/reference/capacity-and-failures.md >/dev/null + +package-viewer-check: ## Validate local package viewer and walkthrough + @test -f site/package-viewer/index.html + @test -f docs/how-to/view-packages.md + @grep -F 'Load bundled demo' site/package-viewer/index.html >/dev/null + @grep -F 'textContent' site/package-viewer/index.html >/dev/null + @! grep -F 'innerHTML' site/package-viewer/index.html >/dev/null + @grep -F 'examples/end-to-end-release-evidence/sample-customer-package-manifest.json' docs/how-to/view-packages.md >/dev/null + fast-check: ## Run non-mutating fast validation @$(MAKE) test @$(MAKE) openapi-check @@ -246,6 +270,7 @@ fast-check: ## Run non-mutating fast validation @$(MAKE) deploy-check @$(MAKE) sdk-check @$(MAKE) demo-check + @$(MAKE) package-viewer-check finalize: ## Thorough validity check @$(MAKE) fmt @@ -256,6 +281,7 @@ finalize: ## Thorough validity check @$(MAKE) deploy-check @$(MAKE) sdk-check @$(MAKE) demo-check + @$(MAKE) package-viewer-check release-acceptance: ## Run deterministic release metadata acceptance checks @scripts/release_acceptance.sh diff --git a/docs/how-to/view-packages.md b/docs/how-to/view-packages.md index 9bde13d..fe20caa 100644 --- a/docs/how-to/view-packages.md +++ b/docs/how-to/view-packages.md @@ -6,7 +6,10 @@ release-evidence review. Open the file in a browser, then select a JSON package, readiness report, evidence bundle, or package manifest from disk. The viewer runs entirely in the -browser and does not upload data. +browser and does not upload data. To inspect a non-sensitive fixture without +running the API, load +`examples/end-to-end-release-evidence/sample-customer-package-manifest.json` or +press **Load bundled demo** in the viewer. Use it for: diff --git a/docs/reference/benchmark-results.md b/docs/reference/benchmark-results.md index 1cb9eac..d1040a1 100644 --- a/docs/reference/benchmark-results.md +++ b/docs/reference/benchmark-results.md @@ -10,6 +10,15 @@ as capacity planning without target-environment tests. go test ./internal/app -bench BenchmarkReleaseEvidenceIngestion -benchtime=100x -run '^$' ``` +The project-owned gate is: + +```sh +make benchmark-check +``` + +`make production-check` runs this gate before release-candidate packaging +evidence is accepted. + ## Current Interpretation The benchmark exercises in-process release evidence creation through the app @@ -39,7 +48,7 @@ goos: linux goarch: amd64 pkg: github.com/aatuh/evydence/internal/app cpu: AMD Ryzen 7 3700X 8-Core Processor -BenchmarkReleaseEvidenceIngestion-16 100 1474947 ns/op 517162 B/op 2544 allocs/op +BenchmarkReleaseEvidenceIngestion-16 100 1426426 ns/op 499913 B/op 2543 allocs/op ``` Interpretation: this is a narrow app-layer benchmark for regression tracking. diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 4cae5c3..0de3129 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -150,6 +150,9 @@ self-hosted production readiness evidence. Do not describe an Evydence build as broadly self-hosted production-ready until: - `make production-check` passes in CI with live PostgreSQL; +- `make black-box-demo-check` passes against a disposable PostgreSQL schema, + exercising API, worker, restart persistence, readiness, package, and + audit-chain verification paths; - coverage is at or above the configured threshold; - release artifacts have signed manifests and published checksums; - committed migrations have passed compatibility checks from every migration diff --git a/docs/reference/release-validation.md b/docs/reference/release-validation.md index 40093d0..0627733 100644 --- a/docs/reference/release-validation.md +++ b/docs/reference/release-validation.md @@ -39,7 +39,9 @@ make production-check That gate is stricter than `make release-check`: it requires `EVYDENCE_TEST_DATABASE_URL`, rejects skipped live PostgreSQL checks, enforces the configured coverage threshold, verifies every committed migration prefix can -upgrade to the current schema in a temporary PostgreSQL schema, and runs a +upgrade to the current schema in a temporary PostgreSQL schema, runs the checked +release-evidence benchmark, starts an API and worker against a disposable +PostgreSQL schema for a black-box demo/restart persistence check, and runs a release artifact signing smoke test. See [Production readiness](production-readiness.md) for the supported profiles and exit criteria. diff --git a/examples/end-to-end-release-evidence/run-local-demo.sh b/examples/end-to-end-release-evidence/run-local-demo.sh index 38ff629..05d9348 100755 --- a/examples/end-to-end-release-evidence/run-local-demo.sh +++ b/examples/end-to-end-release-evidence/run-local-demo.sh @@ -13,10 +13,10 @@ api() { idem="$3" body="$4" if [ "$method" = "GET" ]; then - curl -sS "${EVYDENCE_URL}${path}" \ + curl -fsS "${EVYDENCE_URL}${path}" \ -H "Authorization: Bearer ${EVYDENCE_API_KEY}" else - curl -sS -X "$method" "${EVYDENCE_URL}${path}" \ + curl -fsS -X "$method" "${EVYDENCE_URL}${path}" \ -H "Authorization: Bearer ${EVYDENCE_API_KEY}" \ -H "Idempotency-Key: ${idem}" \ -H "Content-Type: application/json" \ @@ -26,22 +26,22 @@ api() { product="$(api POST /v1/products demo-product '{"name":"Demo Payments API","slug":"demo-payments-api"}')" printf '%s\n' "$product" > "$outdir/product.json" -product_id="$(printf '%s' "$product" | jq -r '.data.id')" +product_id="$(printf '%s' "$product" | jq -er '.data.id')" release="$(api POST /v1/releases demo-release "{\"product_id\":\"$product_id\",\"version\":\"1.0.0\"}")" printf '%s\n' "$release" > "$outdir/release.json" -release_id="$(printf '%s' "$release" | jq -r '.data.id')" +release_id="$(printf '%s' "$release" | jq -er '.data.id')" -artifact="$(api POST /v1/artifacts demo-artifact "{\"release_id\":\"$release_id\",\"name\":\"payments-api.tar.gz\",\"media_type\":\"application/gzip\",\"digest\":\"sha256:ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb\",\"size\":42}")" +artifact="$(api POST /v1/artifacts demo-artifact '{"name":"payments-api.tar.gz","media_type":"application/gzip","digest":"sha256:ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb","size":42}')" printf '%s\n' "$artifact" > "$outdir/artifact.json" -artifact_id="$(printf '%s' "$artifact" | jq -r '.data.id')" +artifact_id="$(printf '%s' "$artifact" | jq -er '.data.id')" sbom="$(api POST /v1/sboms demo-sbom "{\"release_id\":\"$release_id\",\"artifact_id\":\"$artifact_id\",\"payload\":{\"bomFormat\":\"CycloneDX\",\"specVersion\":\"1.6\",\"components\":[{\"name\":\"openssl\",\"purl\":\"pkg:apk/openssl@3.1.0\"}]}}")" printf '%s\n' "$sbom" > "$outdir/sbom.json" scan="$(api POST /v1/vulnerability-scans demo-scan "{\"release_id\":\"$release_id\",\"scanner\":\"grype\",\"target_ref\":\"pkg:oci/payments-api\",\"findings\":[{\"vulnerability\":\"CVE-2026-0099\",\"component\":\"pkg:apk/openssl@3.1.0\",\"severity\":\"critical\",\"state\":\"open\"}]}")" printf '%s\n' "$scan" > "$outdir/vulnerability-scan.json" -finding_id="$(printf '%s' "$scan" | jq -r '.data.findings[0].id')" +finding_id="$(printf '%s' "$scan" | jq -er '.data.findings[0].id')" decision="$(api POST "/v1/vulnerability-findings/${finding_id}/decisions" demo-decision '{"status":"not_affected","justification":"Demo decision; replace with release-specific technical analysis."}')" printf '%s\n' "$decision" > "$outdir/vulnerability-decision.json" @@ -51,7 +51,7 @@ printf '%s\n' "$bundle" > "$outdir/release-bundle.json" profile="$(api POST /v1/redaction-profiles demo-redaction-profile '{"name":"Demo customer redaction","allowed_types":["sbom","vulnerability_scan","release_bundle"],"excluded_fields":["raw_payload","secrets"]}')" printf '%s\n' "$profile" > "$outdir/redaction-profile.json" -profile_id="$(printf '%s' "$profile" | jq -r '.data.id')" +profile_id="$(printf '%s' "$profile" | jq -er '.data.id')" package="$(api POST /v1/customer-packages demo-customer-package "{\"product_id\":\"$product_id\",\"release_id\":\"$release_id\",\"redaction_profile_id\":\"$profile_id\",\"title\":\"Demo customer release evidence\",\"expires_at\":\"2026-06-30T00:00:00Z\"}")" printf '%s\n' "$package" > "$outdir/customer-package.json" diff --git a/scripts/black_box_demo_check.sh b/scripts/black_box_demo_check.sh new file mode 100755 index 0000000..d10d430 --- /dev/null +++ b/scripts/black_box_demo_check.sh @@ -0,0 +1,155 @@ +#!/usr/bin/env sh +set -eu + +repo_root="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)" +cd "$repo_root" + +if [ -z "${EVYDENCE_TEST_DATABASE_URL:-}" ]; then + printf '%s\n' "black-box-demo-check: EVYDENCE_TEST_DATABASE_URL is required" >&2 + exit 2 +fi + +for tool in curl go jq psql python3; do + if ! command -v "$tool" >/dev/null 2>&1; then + printf '%s\n' "black-box-demo-check: missing required tool: $tool" >&2 + exit 2 + fi +done + +workdir="${EVYDENCE_BLACK_BOX_WORKDIR:-tmp/black-box-demo-check}" +schema="evy_demo_$(date +%s)_$$" +api_pid="" +worker_pid="" + +cleanup() { + if [ -n "$api_pid" ] && kill -0 "$api_pid" >/dev/null 2>&1; then + kill "$api_pid" >/dev/null 2>&1 || true + wait "$api_pid" >/dev/null 2>&1 || true + fi + if [ -n "$worker_pid" ] && kill -0 "$worker_pid" >/dev/null 2>&1; then + kill "$worker_pid" >/dev/null 2>&1 || true + wait "$worker_pid" >/dev/null 2>&1 || true + fi + if [ -n "$schema" ]; then + psql "$EVYDENCE_TEST_DATABASE_URL" -v ON_ERROR_STOP=1 -q -c "DROP SCHEMA IF EXISTS $schema CASCADE" >/dev/null 2>&1 || true + fi + if [ "${EVYDENCE_BLACK_BOX_KEEP_ARTIFACTS:-}" != "1" ]; then + rm -rf "$workdir" + fi +} +trap cleanup EXIT INT TERM + +rm -rf "$workdir" +mkdir -p "$workdir"/objects "$workdir"/demo + +printf '%s\n' "black-box-demo-check: preparing disposable schema $schema" +psql "$EVYDENCE_TEST_DATABASE_URL" -v ON_ERROR_STOP=1 -q -c "CREATE SCHEMA $schema" >/dev/null + +database_url="$(python3 - "$EVYDENCE_TEST_DATABASE_URL" "$schema" <<'PY' +import sys +from urllib.parse import parse_qsl, urlencode, urlsplit, urlunsplit + +base_url, schema = sys.argv[1], sys.argv[2] +parts = urlsplit(base_url) +query = dict(parse_qsl(parts.query, keep_blank_values=True)) +query["search_path"] = schema +print(urlunsplit((parts.scheme, parts.netloc, parts.path, urlencode(query), parts.fragment))) +PY +)" + +port="$(python3 - <<'PY' +import socket + +with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: + sock.bind(("127.0.0.1", 0)) + print(sock.getsockname()[1]) +PY +)" +api_url="http://127.0.0.1:$port" + +go build -o "$workdir/evydence-api" ./cmd/evydence-api +go build -o "$workdir/evydence-worker" ./cmd/evydence-worker + +start_api() { + label="$1" + print_secret="$2" + stdout="$workdir/api-$label.stdout" + stderr="$workdir/api-$label.stderr" + EVYDENCE_ADDR="127.0.0.1:$port" \ + EVYDENCE_DATABASE_URL="$database_url" \ + EVYDENCE_POSTGRES_LOAD_MODE=relational_only \ + EVYDENCE_API_KEY_PEPPER="black-box-demo-pepper" \ + EVYDENCE_OBJECT_STORE=filesystem \ + EVYDENCE_OBJECT_DIR="$workdir/objects" \ + EVYDENCE_BOOTSTRAP_TENANT="Black Box Demo Tenant" \ + EVYDENCE_PRINT_BOOTSTRAP_SECRET="$print_secret" \ + "$workdir/evydence-api" >"$stdout" 2>"$stderr" & + api_pid="$!" + for _ in $(seq 1 80); do + if curl -fsS "$api_url/v1/ready" >/dev/null 2>&1; then + return 0 + fi + if ! kill -0 "$api_pid" >/dev/null 2>&1; then + printf '%s\n' "black-box-demo-check: API process exited during $label startup" >&2 + sed -n '1,120p' "$stderr" >&2 || true + return 1 + fi + sleep 0.25 + done + printf '%s\n' "black-box-demo-check: API did not become ready during $label startup" >&2 + sed -n '1,120p' "$stderr" >&2 || true + return 1 +} + +start_worker() { + EVYDENCE_DATABASE_URL="$database_url" \ + EVYDENCE_POSTGRES_LOAD_MODE=relational_only \ + EVYDENCE_SKIP_MIGRATIONS=true \ + EVYDENCE_OBJECT_STORE=filesystem \ + EVYDENCE_OBJECT_DIR="$workdir/objects" \ + EVYDENCE_WORKER_POLL_INTERVAL=100ms \ + "$workdir/evydence-worker" >"$workdir/worker.stdout" 2>"$workdir/worker.stderr" & + worker_pid="$!" + sleep 0.5 + if ! kill -0 "$worker_pid" >/dev/null 2>&1; then + printf '%s\n' "black-box-demo-check: worker process exited during startup" >&2 + sed -n '1,120p' "$workdir/worker.stderr" >&2 || true + return 1 + fi +} + +start_api first true +if ! api_key="$(jq -er '.secret' "$workdir/api-first.stdout")"; then + : >"$workdir/api-first.stdout" + printf '%s\n' "black-box-demo-check: bootstrap secret output was not parseable" >&2 + exit 1 +fi +: >"$workdir/api-first.stdout" +start_worker + +EVYDENCE_URL="$api_url" \ +EVYDENCE_API_KEY="$api_key" \ +EVYDENCE_DEMO_OUTDIR="$workdir/demo" \ +examples/end-to-end-release-evidence/run-local-demo.sh >"$workdir/demo.stdout" + +release_id="$(jq -er '.data.id' "$workdir/demo/release.json")" +jq -e --arg release_id "$release_id" '.data.release_id == $release_id' "$workdir/demo/release-readiness.json" >/dev/null +jq -e '.data.result == "passed"' "$workdir/demo/audit-chain-verification.json" >/dev/null + +kill "$api_pid" >/dev/null 2>&1 || true +wait "$api_pid" >/dev/null 2>&1 || true +api_pid="" + +start_api restart false +curl -fsS "$api_url/v1/reports/release-readiness?release_id=$release_id" \ + -H "Authorization: Bearer $api_key" \ + >"$workdir/restarted-readiness.json" +jq -e --arg release_id "$release_id" '.data.release_id == $release_id' "$workdir/restarted-readiness.json" >/dev/null + +pending_jobs="$(psql "$EVYDENCE_TEST_DATABASE_URL" -v ON_ERROR_STOP=1 -qAt -c "SELECT count(*) FROM $schema.outbox_jobs WHERE status IN ('queued', 'retrying', 'running')")" +if [ "$pending_jobs" != "0" ]; then + printf '%s\n' "black-box-demo-check: pending outbox jobs remain after demo: $pending_jobs" >&2 + exit 1 +fi + +printf '%s\n' "black-box-demo-check: API, worker, PostgreSQL persistence, restart, readiness, package, and audit-chain flow passed" diff --git a/scripts/production_check.sh b/scripts/production_check.sh index eed6517..566db44 100755 --- a/scripts/production_check.sh +++ b/scripts/production_check.sh @@ -14,6 +14,8 @@ printf '%s\n' "Running Evydence production readiness checks" make release-check make coverage-check make migration-compatibility-check +make benchmark-check +make black-box-demo-check workdir="tmp/production-check" rm -rf "$workdir" diff --git a/site/package-viewer/index.html b/site/package-viewer/index.html index 5fd9365..d617fbc 100644 --- a/site/package-viewer/index.html +++ b/site/package-viewer/index.html @@ -41,6 +41,16 @@ input[type="file"] { max-width: 100%; } + button { + cursor: pointer; + border: 1px solid #2b6cb0; + border-radius: 6px; + background: #2b6cb0; + color: #ffffff; + padding: 8px 12px; + font: inherit; + font-weight: 600; + } .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); @@ -104,6 +114,7 @@

Evydence Package Viewer

+ No file loaded.
@@ -122,10 +133,35 @@

Evydence Package Viewer

From 3803da171bce92ac3b2ac9c7ba4f18fbd94902c4 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 16:35:16 +0300 Subject: [PATCH 151/287] docs: refresh production readiness v2 public evidence --- .production_readiness_v2.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.production_readiness_v2.md b/.production_readiness_v2.md index 9917357..2301fab 100644 --- a/.production_readiness_v2.md +++ b/.production_readiness_v2.md @@ -10,9 +10,9 @@ Status legend: Current state rechecked after the original audit: -- Public `origin/master` now points at `aa21ac84ca4d866f6101a8937a646b0631c9052a`, which includes the trust-surface documentation, examples, production-like Compose assets, Scorecard workflow, Dependabot config, issue forms, and product-code audit records that the original audit saw only as local work. -- Local checkout started this reanalysis clean at `master...origin/master`. -- Public GitHub community profile health increased to `85`; GitHub now sees `CODE_OF_CONDUCT.md`, `CONTRIBUTING.md`, `LICENSE`, and `README.md`. +- Public `origin/master` now points at `7767c1c263d265d45c45a541f5e61797c4fc2652`, which includes the trust-surface documentation, examples, production-like Compose assets, Scorecard workflow, Dependabot config, issue/PR templates, product-code audit records, package-viewer demo, benchmark gate, and black-box production-readiness check that the original audit could not see publicly. +- Local checkout is clean at `master...origin/master` after the remediation commits were pushed. +- Public GitHub community profile health increased to `100`; GitHub now sees `CODE_OF_CONDUCT.md`, `CONTRIBUTING.md`, `LICENSE`, `README.md`, `.github/ISSUE_TEMPLATE.md`, and `.github/pull_request_template.md`. - Public GitHub still reports no releases and no pushed tags, and `master` branch protection is still disabled. - GitHub private vulnerability reporting, secret scanning, Dependabot alert settings, release signing secrets, branch protection rules, and required checks remain account/operator settings that repository files can document but cannot prove. From 8935a208c09af6037d6b0955f89e0101a04e9a78 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 16:46:05 +0300 Subject: [PATCH 152/287] refactor: split ledger and postgres helpers --- .production_readiness_v2.md | 2 +- docs/reference/benchmark-results.md | 2 +- internal/adapters/postgres/outbox.go | 148 +++++++++++++++ internal/adapters/postgres/sql_helpers.go | 78 ++++++++ internal/adapters/postgres/store.go | 208 ---------------------- internal/app/ledger.go | 192 -------------------- internal/app/ledger_helpers.go | 207 +++++++++++++++++++++ 7 files changed, 435 insertions(+), 402 deletions(-) create mode 100644 internal/adapters/postgres/outbox.go create mode 100644 internal/adapters/postgres/sql_helpers.go create mode 100644 internal/app/ledger_helpers.go diff --git a/.production_readiness_v2.md b/.production_readiness_v2.md index 2301fab..f2d0c9a 100644 --- a/.production_readiness_v2.md +++ b/.production_readiness_v2.md @@ -28,7 +28,7 @@ Repository-local remediation items from this audit: - [x] Add fallback GitHub community templates for issue and pull request intake so public profile and reviewer workflows do not depend only on issue forms. - [x] Add a repository-owned demo fixture check so sample release-evidence outputs and the local demo script are validated by the fast gate. - [x] Add a full black-box demo check that starts API and worker against a disposable PostgreSQL schema, bootstraps a tenant/API key, runs the release-evidence demo, restarts the API, and verifies persisted readiness/package/audit outputs. -- [ ] Continue decomposing the largest application and PostgreSQL adapter files by resource family without changing public API behavior. +- [x] Continue decomposing the largest application and PostgreSQL adapter files by resource family without changing public API behavior; helper/security logic moved out of `internal/app/ledger.go`, and PostgreSQL outbox plus SQL helper code moved out of `internal/adapters/postgres/store.go`. - [x] Add public benchmark runs and capacity envelopes for the supported single-writer profile. - [x] Add a small public package-viewer walkthrough or hosted static demo artifact that can be evaluated without operating a full Evydence stack. diff --git a/docs/reference/benchmark-results.md b/docs/reference/benchmark-results.md index d1040a1..f1ed092 100644 --- a/docs/reference/benchmark-results.md +++ b/docs/reference/benchmark-results.md @@ -48,7 +48,7 @@ goos: linux goarch: amd64 pkg: github.com/aatuh/evydence/internal/app cpu: AMD Ryzen 7 3700X 8-Core Processor -BenchmarkReleaseEvidenceIngestion-16 100 1426426 ns/op 499913 B/op 2543 allocs/op +BenchmarkReleaseEvidenceIngestion-16 100 1392755 ns/op 499973 B/op 2543 allocs/op ``` Interpretation: this is a narrow app-layer benchmark for regression tracking. diff --git a/internal/adapters/postgres/outbox.go b/internal/adapters/postgres/outbox.go new file mode 100644 index 0000000..5a3478e --- /dev/null +++ b/internal/adapters/postgres/outbox.go @@ -0,0 +1,148 @@ +package postgres + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" + + "github.com/aatuh/evydence/internal/app" +) + +type ClaimedJob struct { + ID string + TenantID string + Kind string + SubjectType string + SubjectID string + Attempts int + Payload map[string]any +} + +func (s *Store) Enqueue(ctx context.Context, job app.OutboxJob) error { + return insertOutboxJob(ctx, s.pool, job) +} + +type outboxExecutor interface { + Exec(context.Context, string, ...any) (pgconn.CommandTag, error) +} + +func insertOutboxJob(ctx context.Context, exec outboxExecutor, job app.OutboxJob) error { + payload, err := json.Marshal(job.Payload) + if err != nil { + return fmt.Errorf("encode outbox payload: %w", err) + } + _, err = exec.Exec(ctx, ` + INSERT INTO outbox_jobs ( + id, tenant_id, kind, subject_type, subject_id, payload, status, + attempts, max_attempts, run_after, created_at, updated_at + ) + VALUES ($1, $2, $3, $4, $5, $6, 'queued', 0, 5, now(), $7, now()) + ON CONFLICT (id) DO NOTHING + `, job.ID, job.TenantID, job.Kind, job.SubjectType, job.SubjectID, payload, job.CreatedAt) + if err != nil { + return fmt.Errorf("enqueue outbox job: %w", err) + } + return nil +} + +func insertOutboxJobTx(ctx context.Context, tx pgx.Tx, job app.OutboxJob) error { + return insertOutboxJob(ctx, tx, job) +} + +func (s *Store) ClaimJobs(ctx context.Context, limit int) ([]ClaimedJob, error) { + if limit <= 0 { + limit = 10 + } + tx, err := s.pool.BeginTx(ctx, pgx.TxOptions{}) + if err != nil { + return nil, fmt.Errorf("begin claim jobs transaction: %w", err) + } + defer func() { _ = tx.Rollback(ctx) }() + rows, err := tx.Query(ctx, ` + WITH claimed AS ( + SELECT id + FROM outbox_jobs + WHERE status IN ('queued', 'retrying') + AND run_after <= now() + ORDER BY run_after, created_at + LIMIT $1 + FOR UPDATE SKIP LOCKED + ) + UPDATE outbox_jobs j + SET status = 'running', + attempts = attempts + 1, + locked_at = now(), + updated_at = now() + FROM claimed + WHERE j.id = claimed.id + RETURNING j.id, j.tenant_id, j.kind, j.subject_type, j.subject_id, j.attempts, j.payload + `, limit) + if err != nil { + return nil, fmt.Errorf("claim jobs: %w", err) + } + defer rows.Close() + jobs := []ClaimedJob{} + for rows.Next() { + var job ClaimedJob + var payload []byte + if err := rows.Scan(&job.ID, &job.TenantID, &job.Kind, &job.SubjectType, &job.SubjectID, &job.Attempts, &payload); err != nil { + return nil, fmt.Errorf("scan claimed job: %w", err) + } + if len(payload) > 0 { + if err := json.Unmarshal(payload, &job.Payload); err != nil { + return nil, fmt.Errorf("decode claimed job payload: %w", err) + } + } + jobs = append(jobs, job) + } + if err := rows.Err(); err != nil { + return nil, fmt.Errorf("read claimed jobs: %w", err) + } + if err := tx.Commit(ctx); err != nil { + return nil, fmt.Errorf("commit claim jobs transaction: %w", err) + } + return jobs, nil +} + +func (s *Store) CompleteJob(ctx context.Context, id string) error { + _, err := s.pool.Exec(ctx, ` + UPDATE outbox_jobs + SET status = 'succeeded', locked_at = NULL, last_error = NULL, updated_at = now() + WHERE id = $1 + `, id) + if err != nil { + return fmt.Errorf("complete outbox job: %w", err) + } + return nil +} + +func (s *Store) FailJob(ctx context.Context, id string, cause error) error { + message := "job failed" + if cause != nil { + message = cause.Error() + } + _, err := s.pool.Exec(ctx, ` + UPDATE outbox_jobs + SET status = CASE WHEN attempts >= max_attempts THEN 'failed' ELSE 'retrying' END, + run_after = now() + make_interval(secs => LEAST(300, POWER(2, attempts)::int)), + locked_at = NULL, + last_error = $2, + updated_at = now() + WHERE id = $1 + `, id, message) + if err != nil { + return fmt.Errorf("fail outbox job: %w", err) + } + return nil +} + +func (s *Store) CountPendingJobs(ctx context.Context) (int, error) { + var count int + if err := s.pool.QueryRow(ctx, `SELECT count(*) FROM outbox_jobs WHERE status IN ('queued', 'retrying', 'running')`).Scan(&count); err != nil { + return 0, fmt.Errorf("count outbox jobs: %w", err) + } + return count, nil +} diff --git a/internal/adapters/postgres/sql_helpers.go b/internal/adapters/postgres/sql_helpers.go new file mode 100644 index 0000000..e18a681 --- /dev/null +++ b/internal/adapters/postgres/sql_helpers.go @@ -0,0 +1,78 @@ +package postgres + +import ( + "database/sql" + "encoding/json" + "time" +) + +func nullableString(value string) any { + if value == "" { + return nil + } + return value +} + +func nullableSQLString(value sql.NullString) string { + if !value.Valid { + return "" + } + return value.String +} + +func nullableSQLTime(value sql.NullTime) *time.Time { + if !value.Valid || value.Time.IsZero() { + return nil + } + t := value.Time.UTC() + return &t +} + +func decodeJSON(raw []byte, out any) error { + if len(raw) == 0 || string(raw) == "null" { + return nil + } + return json.Unmarshal(raw, out) +} + +func nullableTime(value *time.Time) any { + if value == nil || value.IsZero() { + return nil + } + return value.UTC() +} + +func nullableInt64(value int64) any { + if value == 0 { + return nil + } + return value +} + +func nullableInt(value int) any { + if value == 0 { + return nil + } + return value +} + +func nonZeroInt(value, fallback int) int { + if value == 0 { + return fallback + } + return value +} + +func nullableBytes(value []byte) any { + if len(value) == 0 { + return nil + } + return value +} + +func nonZeroTime(value time.Time) time.Time { + if value.IsZero() { + return time.Now().UTC() + } + return value.UTC() +} diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index afe19c3..a54b3ea 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -10,7 +10,6 @@ import ( "time" "github.com/jackc/pgx/v5" - "github.com/jackc/pgx/v5/pgconn" "github.com/jackc/pgx/v5/pgxpool" "github.com/aatuh/evydence/internal/app" @@ -38,16 +37,6 @@ type StoreOptions struct { const apiWriterLeaseKey int64 = 0x65767964656e6365 -type ClaimedJob struct { - ID string - TenantID string - Kind string - SubjectType string - SubjectID string - Attempts int - Payload map[string]any -} - func Open(ctx context.Context, databaseURL string) (*Store, error) { return OpenWithOptions(ctx, databaseURL, StoreOptions{}) } @@ -5086,203 +5075,6 @@ func resourceProjections(state app.PersistedState) []resourceProjection { return out } -func nullableString(value string) any { - if value == "" { - return nil - } - return value -} - -func nullableSQLString(value sql.NullString) string { - if !value.Valid { - return "" - } - return value.String -} - -func nullableSQLTime(value sql.NullTime) *time.Time { - if !value.Valid || value.Time.IsZero() { - return nil - } - t := value.Time.UTC() - return &t -} - -func decodeJSON(raw []byte, out any) error { - if len(raw) == 0 || string(raw) == "null" { - return nil - } - return json.Unmarshal(raw, out) -} - -func nullableTime(value *time.Time) any { - if value == nil || value.IsZero() { - return nil - } - return value.UTC() -} - -func nullableInt64(value int64) any { - if value == 0 { - return nil - } - return value -} - -func nullableInt(value int) any { - if value == 0 { - return nil - } - return value -} - -func nonZeroInt(value, fallback int) int { - if value == 0 { - return fallback - } - return value -} - -func nullableBytes(value []byte) any { - if len(value) == 0 { - return nil - } - return value -} - -func nonZeroTime(value time.Time) time.Time { - if value.IsZero() { - return time.Now().UTC() - } - return value.UTC() -} - -func (s *Store) Enqueue(ctx context.Context, job app.OutboxJob) error { - return insertOutboxJob(ctx, s.pool, job) -} - -type outboxExecutor interface { - Exec(context.Context, string, ...any) (pgconn.CommandTag, error) -} - -func insertOutboxJob(ctx context.Context, exec outboxExecutor, job app.OutboxJob) error { - payload, err := json.Marshal(job.Payload) - if err != nil { - return fmt.Errorf("encode outbox payload: %w", err) - } - _, err = exec.Exec(ctx, ` - INSERT INTO outbox_jobs ( - id, tenant_id, kind, subject_type, subject_id, payload, status, - attempts, max_attempts, run_after, created_at, updated_at - ) - VALUES ($1, $2, $3, $4, $5, $6, 'queued', 0, 5, now(), $7, now()) - ON CONFLICT (id) DO NOTHING - `, job.ID, job.TenantID, job.Kind, job.SubjectType, job.SubjectID, payload, job.CreatedAt) - if err != nil { - return fmt.Errorf("enqueue outbox job: %w", err) - } - return nil -} - -func insertOutboxJobTx(ctx context.Context, tx pgx.Tx, job app.OutboxJob) error { - return insertOutboxJob(ctx, tx, job) -} - -func (s *Store) ClaimJobs(ctx context.Context, limit int) ([]ClaimedJob, error) { - if limit <= 0 { - limit = 10 - } - tx, err := s.pool.BeginTx(ctx, pgx.TxOptions{}) - if err != nil { - return nil, fmt.Errorf("begin claim jobs transaction: %w", err) - } - defer func() { _ = tx.Rollback(ctx) }() - rows, err := tx.Query(ctx, ` - WITH claimed AS ( - SELECT id - FROM outbox_jobs - WHERE status IN ('queued', 'retrying') - AND run_after <= now() - ORDER BY run_after, created_at - LIMIT $1 - FOR UPDATE SKIP LOCKED - ) - UPDATE outbox_jobs j - SET status = 'running', - attempts = attempts + 1, - locked_at = now(), - updated_at = now() - FROM claimed - WHERE j.id = claimed.id - RETURNING j.id, j.tenant_id, j.kind, j.subject_type, j.subject_id, j.attempts, j.payload - `, limit) - if err != nil { - return nil, fmt.Errorf("claim jobs: %w", err) - } - defer rows.Close() - jobs := []ClaimedJob{} - for rows.Next() { - var job ClaimedJob - var payload []byte - if err := rows.Scan(&job.ID, &job.TenantID, &job.Kind, &job.SubjectType, &job.SubjectID, &job.Attempts, &payload); err != nil { - return nil, fmt.Errorf("scan claimed job: %w", err) - } - if len(payload) > 0 { - if err := json.Unmarshal(payload, &job.Payload); err != nil { - return nil, fmt.Errorf("decode claimed job payload: %w", err) - } - } - jobs = append(jobs, job) - } - if err := rows.Err(); err != nil { - return nil, fmt.Errorf("read claimed jobs: %w", err) - } - if err := tx.Commit(ctx); err != nil { - return nil, fmt.Errorf("commit claim jobs transaction: %w", err) - } - return jobs, nil -} - -func (s *Store) CompleteJob(ctx context.Context, id string) error { - _, err := s.pool.Exec(ctx, ` - UPDATE outbox_jobs - SET status = 'succeeded', locked_at = NULL, last_error = NULL, updated_at = now() - WHERE id = $1 - `, id) - if err != nil { - return fmt.Errorf("complete outbox job: %w", err) - } - return nil -} - -func (s *Store) FailJob(ctx context.Context, id string, cause error) error { - message := "job failed" - if cause != nil { - message = cause.Error() - } - _, err := s.pool.Exec(ctx, ` - UPDATE outbox_jobs - SET status = CASE WHEN attempts >= max_attempts THEN 'failed' ELSE 'retrying' END, - run_after = now() + make_interval(secs => LEAST(300, POWER(2, attempts)::int)), - locked_at = NULL, - last_error = $2, - updated_at = now() - WHERE id = $1 - `, id, message) - if err != nil { - return fmt.Errorf("fail outbox job: %w", err) - } - return nil -} - -func (s *Store) CountPendingJobs(ctx context.Context) (int, error) { - var count int - if err := s.pool.QueryRow(ctx, `SELECT count(*) FROM outbox_jobs WHERE status IN ('queued', 'retrying', 'running')`).Scan(&count); err != nil { - return 0, fmt.Errorf("count outbox jobs: %w", err) - } - return count, nil -} - func (s *Store) Now(ctx context.Context) (time.Time, error) { var now time.Time if err := s.pool.QueryRow(ctx, `SELECT now()`).Scan(&now); err != nil { diff --git a/internal/app/ledger.go b/internal/app/ledger.go index f0d8553..10b3d9d 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -1883,195 +1883,3 @@ func (l *Ledger) checkNoOpenCriticalLocked(tenantID, releaseID string) domain.Po } return domain.PolicyCheck{Name: "critical_exploitable_blocks_release", Result: "passed", Severity: "critical", Explanation: "no open critical findings recorded"} } - -func require(actor domain.Actor, scope string) error { - if actor.TenantID == "" || (actor.KeyID == "" && actor.UserID == "" && actor.CollectorID == "") { - return ErrUnauthorized - } - if requiresExplicitScope(scope) { - if actorHasExactScope(actor, scope) { - return nil - } - return ErrForbidden - } - if actor.HasScope(scope) || actor.HasScope(ScopeAdmin) { - return nil - } - return ErrForbidden -} - -func requireGrantableScopes(actor domain.Actor, scopes []string) error { - for _, scope := range scopes { - scope = strings.TrimSpace(scope) - if requiresExplicitScope(scope) && !actorHasExactScope(actor, scope) { - return ErrForbidden - } - } - return nil -} - -func requiresExplicitScope(scope string) bool { - return scope == ScopeInstanceAdmin -} - -func actorHasExactScope(actor domain.Actor, scope string) bool { - for _, got := range actor.Scopes { - if got == scope { - return true - } - } - return false -} - -func canonicalHash(item domain.EvidenceItem) (string, error) { - item.CanonicalHash = "" - item.ChainEntryID = "" - item.SignatureRefs = nil - return canonicalAnyHash(item) -} - -func canonicalAnyHash(v any) (string, error) { - body, err := json.Marshal(v) - if err != nil { - return "", err - } - var normalized any - if err := json.Unmarshal(body, &normalized); err != nil { - return "", err - } - body, err = json.Marshal(normalized) - if err != nil { - return "", err - } - return hashBytes(body), nil -} - -func hashBytes(body []byte) string { - sum := sha256.Sum256(body) - return "sha256:" + hex.EncodeToString(sum[:]) -} - -func validDigest(value string) bool { - if !strings.HasPrefix(value, "sha256:") { - return false - } - _, err := hex.DecodeString(strings.TrimPrefix(value, "sha256:")) - return err == nil && len(strings.TrimPrefix(value, "sha256:")) == 64 -} - -func newID(prefix string) string { - var b [16]byte - if _, err := rand.Read(b[:]); err != nil { - panic(err) - } - return prefix + "_" + hex.EncodeToString(b[:]) -} - -func randomToken(n int) string { - buf := make([]byte, n) - if _, err := rand.Read(buf); err != nil { - panic(err) - } - return base64.RawURLEncoding.EncodeToString(buf) -} - -func secretPrefix(secret string) string { - if len(secret) <= 12 { - return secret - } - return secret[:12] -} - -func sortedStrings(in []string) []string { - out := append([]string(nil), in...) - for i := range out { - out[i] = strings.TrimSpace(out[i]) - } - sort.Strings(out) - return out -} - -func cloneMap(in map[string]any) map[string]any { - if len(in) == 0 { - return nil - } - out := map[string]any{} - for k, v := range in { - out[k] = v - } - return out -} - -func nonEmpty(value, fallback string) string { - value = strings.TrimSpace(value) - if value == "" { - return fallback - } - return value -} - -func subjectForArtifact(artifactID string) []domain.SubjectRef { - if strings.TrimSpace(artifactID) == "" { - return nil - } - return []domain.SubjectRef{{Type: "artifact", ID: artifactID}} -} - -func IsValidation(err error) bool { - return errors.Is(err, ErrValidation) -} - -func ProblemCode(err error) string { - switch { - case errors.Is(err, ErrUnauthorized): - return "UNAUTHORIZED" - case errors.Is(err, ErrForbidden): - return "FORBIDDEN" - case errors.Is(err, ErrNotFound): - return "NOT_FOUND" - case errors.Is(err, ErrConflict): - return "CONFLICT" - case errors.Is(err, ErrImmutable): - return "EVIDENCE_IMMUTABLE" - case errors.Is(err, ErrIdempotencyConflict): - return "IDEMPOTENCY_KEY_REUSED" - case errors.Is(err, ErrVerificationFailed): - return "VERIFICATION_FAILED" - case errors.Is(err, ErrRateLimited): - return "RATE_LIMITED" - case errors.Is(err, ErrValidation): - return "VALIDATION_FAILED" - default: - return "INTERNAL_ERROR" - } -} - -func StatusCode(err error) int { - switch { - case errors.Is(err, ErrUnauthorized): - return 401 - case errors.Is(err, ErrForbidden): - return 403 - case errors.Is(err, ErrNotFound): - return 404 - case errors.Is(err, ErrConflict), errors.Is(err, ErrImmutable), errors.Is(err, ErrIdempotencyConflict): - return 409 - case errors.Is(err, ErrValidation): - return 400 - case errors.Is(err, ErrVerificationFailed): - return 422 - case errors.Is(err, ErrRateLimited): - return 429 - default: - return 500 - } -} - -func SafeErrorDetail(err error) string { - switch StatusCode(err) { - case 500: - return "internal server error" - default: - return fmt.Sprintf("%s", err) - } -} diff --git a/internal/app/ledger_helpers.go b/internal/app/ledger_helpers.go new file mode 100644 index 0000000..4abd8ef --- /dev/null +++ b/internal/app/ledger_helpers.go @@ -0,0 +1,207 @@ +package app + +import ( + "crypto/rand" + "crypto/sha256" + "encoding/base64" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "sort" + "strings" + + "github.com/aatuh/evydence/internal/domain" +) + +func require(actor domain.Actor, scope string) error { + if actor.TenantID == "" || (actor.KeyID == "" && actor.UserID == "" && actor.CollectorID == "") { + return ErrUnauthorized + } + if requiresExplicitScope(scope) { + if actorHasExactScope(actor, scope) { + return nil + } + return ErrForbidden + } + if actor.HasScope(scope) || actor.HasScope(ScopeAdmin) { + return nil + } + return ErrForbidden +} + +func requireGrantableScopes(actor domain.Actor, scopes []string) error { + for _, scope := range scopes { + scope = strings.TrimSpace(scope) + if requiresExplicitScope(scope) && !actorHasExactScope(actor, scope) { + return ErrForbidden + } + } + return nil +} + +func requiresExplicitScope(scope string) bool { + return scope == ScopeInstanceAdmin +} + +func actorHasExactScope(actor domain.Actor, scope string) bool { + for _, got := range actor.Scopes { + if got == scope { + return true + } + } + return false +} + +func canonicalHash(item domain.EvidenceItem) (string, error) { + item.CanonicalHash = "" + item.ChainEntryID = "" + item.SignatureRefs = nil + return canonicalAnyHash(item) +} + +func canonicalAnyHash(v any) (string, error) { + body, err := json.Marshal(v) + if err != nil { + return "", err + } + var normalized any + if err := json.Unmarshal(body, &normalized); err != nil { + return "", err + } + body, err = json.Marshal(normalized) + if err != nil { + return "", err + } + return hashBytes(body), nil +} + +func hashBytes(body []byte) string { + sum := sha256.Sum256(body) + return "sha256:" + hex.EncodeToString(sum[:]) +} + +func validDigest(value string) bool { + if !strings.HasPrefix(value, "sha256:") { + return false + } + _, err := hex.DecodeString(strings.TrimPrefix(value, "sha256:")) + return err == nil && len(strings.TrimPrefix(value, "sha256:")) == 64 +} + +func newID(prefix string) string { + var b [16]byte + if _, err := rand.Read(b[:]); err != nil { + panic(err) + } + return prefix + "_" + hex.EncodeToString(b[:]) +} + +func randomToken(n int) string { + buf := make([]byte, n) + if _, err := rand.Read(buf); err != nil { + panic(err) + } + return base64.RawURLEncoding.EncodeToString(buf) +} + +func secretPrefix(secret string) string { + if len(secret) <= 12 { + return secret + } + return secret[:12] +} + +func sortedStrings(in []string) []string { + out := append([]string(nil), in...) + for i := range out { + out[i] = strings.TrimSpace(out[i]) + } + sort.Strings(out) + return out +} + +func cloneMap(in map[string]any) map[string]any { + if len(in) == 0 { + return nil + } + out := map[string]any{} + for k, v := range in { + out[k] = v + } + return out +} + +func nonEmpty(value, fallback string) string { + value = strings.TrimSpace(value) + if value == "" { + return fallback + } + return value +} + +func subjectForArtifact(artifactID string) []domain.SubjectRef { + if strings.TrimSpace(artifactID) == "" { + return nil + } + return []domain.SubjectRef{{Type: "artifact", ID: artifactID}} +} + +func IsValidation(err error) bool { + return errors.Is(err, ErrValidation) +} + +func ProblemCode(err error) string { + switch { + case errors.Is(err, ErrUnauthorized): + return "UNAUTHORIZED" + case errors.Is(err, ErrForbidden): + return "FORBIDDEN" + case errors.Is(err, ErrNotFound): + return "NOT_FOUND" + case errors.Is(err, ErrConflict): + return "CONFLICT" + case errors.Is(err, ErrImmutable): + return "EVIDENCE_IMMUTABLE" + case errors.Is(err, ErrIdempotencyConflict): + return "IDEMPOTENCY_KEY_REUSED" + case errors.Is(err, ErrVerificationFailed): + return "VERIFICATION_FAILED" + case errors.Is(err, ErrRateLimited): + return "RATE_LIMITED" + case errors.Is(err, ErrValidation): + return "VALIDATION_FAILED" + default: + return "INTERNAL_ERROR" + } +} + +func StatusCode(err error) int { + switch { + case errors.Is(err, ErrUnauthorized): + return 401 + case errors.Is(err, ErrForbidden): + return 403 + case errors.Is(err, ErrNotFound): + return 404 + case errors.Is(err, ErrConflict), errors.Is(err, ErrImmutable), errors.Is(err, ErrIdempotencyConflict): + return 409 + case errors.Is(err, ErrValidation): + return 400 + case errors.Is(err, ErrVerificationFailed): + return 422 + case errors.Is(err, ErrRateLimited): + return 429 + default: + return 500 + } +} + +func SafeErrorDetail(err error) string { + switch StatusCode(err) { + case 500: + return "internal server error" + default: + return fmt.Sprintf("%s", err) + } +} From 84a5f017e328ba43c1c67c6df298f15558ae3147 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 16:46:28 +0300 Subject: [PATCH 153/287] docs: refresh production readiness v2 final sha --- .production_readiness_v2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.production_readiness_v2.md b/.production_readiness_v2.md index f2d0c9a..4abd0a3 100644 --- a/.production_readiness_v2.md +++ b/.production_readiness_v2.md @@ -10,7 +10,7 @@ Status legend: Current state rechecked after the original audit: -- Public `origin/master` now points at `7767c1c263d265d45c45a541f5e61797c4fc2652`, which includes the trust-surface documentation, examples, production-like Compose assets, Scorecard workflow, Dependabot config, issue/PR templates, product-code audit records, package-viewer demo, benchmark gate, and black-box production-readiness check that the original audit could not see publicly. +- Public `origin/master` now points at `929c525a116346cd17b027c96b0d9f568a8fb0a8`, which includes the trust-surface documentation, examples, production-like Compose assets, Scorecard workflow, Dependabot config, issue/PR templates, product-code audit records, package-viewer demo, benchmark gate, black-box production-readiness check, and helper/outbox decomposition that the original audit could not see publicly. - Local checkout is clean at `master...origin/master` after the remediation commits were pushed. - Public GitHub community profile health increased to `100`; GitHub now sees `CODE_OF_CONDUCT.md`, `CONTRIBUTING.md`, `LICENSE`, `README.md`, `.github/ISSUE_TEMPLATE.md`, and `.github/pull_request_template.md`. - Public GitHub still reports no releases and no pushed tags, and `master` branch protection is still disabled. From 00bb14a79ad540b6e42fe2d5ff58709437b11255 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 16:46:51 +0300 Subject: [PATCH 154/287] docs: stabilize production readiness evidence reference --- .production_readiness_v2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.production_readiness_v2.md b/.production_readiness_v2.md index 4abd0a3..ec080c3 100644 --- a/.production_readiness_v2.md +++ b/.production_readiness_v2.md @@ -10,7 +10,7 @@ Status legend: Current state rechecked after the original audit: -- Public `origin/master` now points at `929c525a116346cd17b027c96b0d9f568a8fb0a8`, which includes the trust-surface documentation, examples, production-like Compose assets, Scorecard workflow, Dependabot config, issue/PR templates, product-code audit records, package-viewer demo, benchmark gate, black-box production-readiness check, and helper/outbox decomposition that the original audit could not see publicly. +- Public `origin/master` includes remediation through commit `929c525a116346cd17b027c96b0d9f568a8fb0a8`: trust-surface documentation, examples, production-like Compose assets, Scorecard workflow, Dependabot config, issue/PR templates, product-code audit records, package-viewer demo, benchmark gate, black-box production-readiness check, and helper/outbox decomposition that the original audit could not see publicly. - Local checkout is clean at `master...origin/master` after the remediation commits were pushed. - Public GitHub community profile health increased to `100`; GitHub now sees `CODE_OF_CONDUCT.md`, `CONTRIBUTING.md`, `LICENSE`, `README.md`, `.github/ISSUE_TEMPLATE.md`, and `.github/pull_request_template.md`. - Public GitHub still reports no releases and no pushed tags, and `master` branch protection is still disabled. From 60ae5114af9c390fea7e813987f598c5fadffafc Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 18:33:24 +0300 Subject: [PATCH 155/287] docs: track production readiness v3 remediation --- .github/workflows/scorecard.yml | 6 +- .gitignore | 1 + .production_readiness_v3.md | 435 +++++++++++++++++++++ CODEOWNERS | 39 ++ Makefile | 13 + README.md | 17 + docs/README.md | 4 + docs/how-to/install-and-operate.md | 7 + docs/reference/maintainer-review-policy.md | 77 ++++ docs/reference/production-exit-review.md | 4 + docs/reference/production-readiness.md | 14 +- docs/reference/release-candidate.md | 11 + docs/reference/release-evidence-index.md | 60 +++ docs/reference/release-validation.md | 4 + docs/reference/roadmap.md | 46 +++ docs/reference/source-of-truth.md | 3 + docs/tutorials/getting-started.md | 6 + scripts/release_acceptance.sh | 13 + 18 files changed, 753 insertions(+), 7 deletions(-) create mode 100644 .production_readiness_v3.md create mode 100644 CODEOWNERS create mode 100644 docs/reference/maintainer-review-policy.md create mode 100644 docs/reference/release-evidence-index.md create mode 100644 docs/reference/roadmap.md diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 1ef2310..49108b9 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -8,13 +8,15 @@ on: permissions: contents: read - security-events: write - id-token: write jobs: scorecard: name: Scorecard runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + security-events: write steps: - name: Check out repository uses: actions/checkout@v5 diff --git a/.gitignore b/.gitignore index dc73eb8..dd873d5 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ !.env.example !.api.env.example !.test.env.example +!.production_readiness*.md coverage.out bin/ diff --git a/.production_readiness_v3.md b/.production_readiness_v3.md new file mode 100644 index 0000000..cc17bae --- /dev/null +++ b/.production_readiness_v3.md @@ -0,0 +1,435 @@ +## 2026-05-31 Remediation Tracking + +Status legend: + +- `[ ]` applicable repository-local work that remains incomplete. +- `[x]` applicable repository-local work completed with current repository evidence. +- `[e]` external, account-level, provider-level, operator-environment, release-publication, or adoption-dependent work that cannot be completed by repository files alone. + +Repository-local remediation from the v3 audit: + +- [x] Keep `.production_readiness_v3.md` as a trackable repository artifact by unignoring production-readiness audit dotfiles. +- [x] Add CODEOWNERS coverage for high-trust code, API, persistence, release, deployment, and public-claim surfaces. +- [x] Add a maintainer review policy that states the expected review questions, high-risk paths, required checks, and the fact that CODEOWNERS is not enforced until GitHub branch protection or repository rules require it. +- [x] Add a release evidence index mapping release artifacts to the commands that create and verify them. +- [x] Update README, getting-started, install, release-candidate, release-validation, source-of-truth, production-readiness, and production-exit docs so source checkout is clearly the pre-release evaluation path and release artifacts become the install path only after publication. +- [x] Document that one API writer replica is the supported stance for the current release line, with multi-writer API HA deferred until a reviewed design exists. +- [x] Add a public roadmap and release cadence reference that keeps near-term focus on release evidence, GitHub trust controls, and supported production-profile limits. +- [x] Wire the new trust artifacts into `make docs-check`, `make meta-check`, and `make release-acceptance` so CODEOWNERS, review policy, release evidence index, and roadmap drift are checked. +- [x] Trigger a public OpenSSF Scorecard workflow run for `master` after the v3 audit identified no visible Scorecard runs. + +External or operator-dependent remediation from the v3 audit: + +- [e] Publish a signed public release candidate/tag with release archives, `SHA256SUMS`, OpenAPI checksum, migration checksum, coverage output, production-check summary, SBOM/provenance metadata, signed release manifest, release notes, and a public release-artifacts workflow run. +- [e] Enable branch protection or repository rules for `master`, including required checks and CODEOWNERS enforcement. +- [e] Enable or verify GitHub vulnerability alerts, Dependabot security updates, private vulnerability reporting, and any desired code-scanning/security-alert settings. +- [e] Configure and verify release signing secrets for GitHub Actions and any package/container registry credentials. +- [e] Publish immutable container images or decide and communicate that release archives/source are the only supported install path for the current release line. +- [e] Prove deployed-environment controls: target backup/restore rehearsal, monitoring deployment, incident rehearsal, object-store WORM/object-lock policy, KMS/HSM custody, SSO/group-sync provider behavior, and transparency-provider semantics. +- [e] Produce external adoption evidence, third-party review, support-process evidence, customer feedback, or case studies tied to a concrete public release candidate. + +## Latest visible state inspected + +Repository: `aatuh/evydence` at `https://github.com/aatuh/evydence`, audited as both the current public GitHub repository and the local checkout at `/home/aatu/projects/evydence`. + +Inspected local state: + +- Local branch: `master`. +- Local `HEAD`: `53ce458b865941d886f2fae03a1b2a83f7cd134b`. +- Local commit date: `2026-05-31T16:46:51+03:00` / `2026-05-31T13:46:51Z`. +- Commit subject: `docs: stabilize production readiness evidence reference`. +- Local worktree before writing this audit: clean, `## master...origin/master`. +- Local and public `origin/master` matched at `53ce458b865941d886f2fae03a1b2a83f7cd134b`. +- Local-only tags exist: `v0.1.0-rc.1`, `v0.1.0-rc.2`, and `v0.1.0-rc.3`. + +Public GitHub state verified with `git ls-remote` and `gh`: + +- Default branch: `master`. +- Public default-branch commit: `53ce458b865941d886f2fae03a1b2a83f7cd134b`, `2026-05-31T13:46:51Z`. +- Visibility: public. +- Archived: false. +- Repository created: `2026-05-28T15:09:02Z`. +- Last pushed: `2026-05-31T13:46:52Z`. +- Stars/watchers/forks: `0` stars, `0` watchers, `0` forks. +- Public open PRs: 6 Dependabot PRs. +- Public open issues: none from `gh issue list`; GitHub `open_issues_count` is 6 because PRs are counted. +- Primary language: Go. GitHub language data reported Go as dominant, plus Makefile, Python, Shell, TypeScript, HTML, Dockerfile, and Go Template. +- Package manifests: `go.mod` and `go.sum`; module `github.com/aatuh/evydence`; Go version `1.25.10`; API toolkit dependency `github.com/aatuh/api-toolkit/v3 v3.1.2`. +- License: GitHub reports AGPL-3.0 / GNU AGPLv3; repository files and README position this as `AGPL-3.0-only`, with commercial license exceptions documented in `COMMERCIAL.md`. + +Public release and tag state: + +- `gh release list --repo aatuh/evydence --limit 20` returned no releases. +- `gh api repos/aatuh/evydence/releases/latest` returned 404 Not Found. +- `git ls-remote --tags origin` returned no public remote tags. +- `gh api repos/aatuh/evydence/tags` returned `[]`. +- The local tags are not public release/tag evidence. This is a hard adoption and release-integrity gap. +- `gh run list --workflow release-artifacts.yml` and the corresponding workflow-runs API returned no release-artifacts workflow runs, despite the workflow file existing. + +Public CI and GitHub metadata: + +- Workflows visible: `CI`, `Release Artifacts`, `OpenSSF Scorecard`, `Dependabot Updates`, and `Dependency Graph`. +- Latest public CI run for `master` succeeded for commit `53ce458b865941d886f2fae03a1b2a83f7cd134b`, run `26714351811`, created `2026-05-31T13:46:54Z`, updated `2026-05-31T13:50:17Z`. +- Recent CI runs for Dependabot PRs also showed success in `gh run list`. +- No public runs were visible for `Release Artifacts` or `OpenSSF Scorecard` at audit time. +- Branch protection check for `master` returned `Branch not protected` / HTTP 404. +- `security_and_analysis` visible through GitHub API: secret scanning enabled, push protection enabled, non-provider pattern scanning disabled, validity checks disabled, Dependabot security updates disabled. +- Vulnerability-alerts API returned 404 with `Vulnerability alerts are disabled`. +- Security advisories list returned `[]`. +- `SECURITY.md`, `.github/dependabot.yml`, README, license, contributing, code of conduct, issue template, and PR template are publicly present. GitHub community profile reported 100% health, but that is not production-readiness evidence by itself. + +Current repository evidence in checkout: + +- Source tree exists and is substantial: `cmd/`, `internal/`, `migrations/`, `docs/`, `deploy/`, `sdk/`, `examples/`, `scripts/`, `openapi.yaml`, Dockerfile, Compose files, Helm chart, GitHub workflows, governance/security/support files. +- `openapi.yaml` contains 152 paths and 166 operations. +- There are 219 Go test files and 46 migration files. +- `go list ./...` reports 22 Go packages. +- `make fast-check` passed locally during this audit. + +Not inspectable or not proven: + +- GitHub required checks, repository rulesets, CODEOWNERS enforcement, maintainer review policy, private vulnerability reporting enablement, release signing secret configuration, package/container registry publication, artifact immutability, deployment state, backup retention, monitoring deployment, object-store WORM policy, KMS/HSM custody, and production operator controls could not be fully verified from public files and visible API metadata. +- Some GitHub security settings were inspectable and weak: branch protection not enabled, Dependabot security updates disabled, vulnerability alerts disabled. +- Public release artifacts are not published. This caps production-readiness scoring even though release scripts and CI gates are present. + +Confidence impact: confidence is medium-high for repository and public-platform evidence because the latest public commit and local checkout matched and the public metadata was directly queried. Confidence is only medium for real deployment readiness because several required controls are explicitly external/operator-dependent and no public release artifacts exist. + +## What the project appears to be + +Evydence is a self-hosted, API-first release evidence and compliance-readiness ledger for software product teams. Its concrete product shape is a Go HTTP API server, worker, migration command, CLI helper, PostgreSQL-backed ledger, object-storage adapter, OpenAPI contract, SDK helpers, deployment assets, and documentation set. + +The problem is real: B2B software teams often need reproducible technical evidence for release review, customer security questionnaires, SBOM/VEX handling, vulnerability decisions, approvals, exceptions, release bundles, and audit trails without pushing all release-trust data into a SaaS GRC tool. + +Likely users: + +- Security engineering, platform engineering, AppSec, release engineering, compliance-readiness, and customer-trust teams. +- Operators responsible for self-hosted infrastructure, PostgreSQL, object storage, KMS/HSM/gateway signing, backups, and incident response. +- Buyers are likely security/platform leaders at B2B software companies that need self-hosted evidence workflows or a commercial support path. + +README clarity is strong within 30 seconds. It names the target audience, current limitation, non-claim boundaries, fastest proof path, product shape, alternatives, and validation gates near the top. The README is unusually explicit about what Evydence does not prove: it avoids legal compliance, certification, complete SBOM, scanner-authority, and secure-release claims. + +Implemented behavior, documented intent, and stubs are separated better than average: + +- Implemented behavior is backed by Go packages, tests, migrations, OpenAPI, CLI commands, deployment files, examples, and checks. +- Documented current limitations are in `README.md`, `docs/reference/production-readiness.md`, `docs/reference/production-exit-review.md`, `docs/reference/configuration.md`, and runbooks. +- Roadmap/operator-dependent gaps are called out: native PKCS#11/HSM custody, broad WORM/object-lock proof, direct provider-specific management API clients, external group synchronization, multi-writer API HA, hosted SaaS profile, and target-environment backup/restore review. + +The project presents as a controlled self-hosted product candidate, not merely a library. It is not yet a broadly adoptable public OSS product because there are no public releases or public tags and several GitHub trust settings are weak. + +## Production readiness + +Evidence that supports readiness: + +- Go module and source exist with clear process boundaries: `cmd/evydence-api`, `cmd/evydence-worker`, `cmd/evydence-migrate`, `cmd/evydence`, `internal/app`, `internal/domain`, and adapters under `internal/adapters`. +- API implementation uses `github.com/aatuh/api-toolkit/v3` route contracts/spec support, and `openapi.yaml` is committed. +- `openapi.yaml` has 152 paths and 166 operations; `make fast-check` reported `166 precise operations, 0 broad operations`. +- PostgreSQL migrations are present under `migrations/`; there are 46 migration files. +- Runtime configuration is documented in `docs/reference/configuration.md`, including production rejection checks. +- Production API startup code rejects missing database URL, default API-key pepper, local plaintext signing-key modes, bootstrap secret printing, unsupported API writer modes, and API writer replica counts above one. +- PostgreSQL advisory writer lease behavior is implemented in `cmd/evydence-api/main.go` and documented. +- `scripts/production_check.sh` requires live PostgreSQL, release checks, coverage threshold, migration compatibility, benchmark check, black-box demo check, and release signing smoke test. +- Latest public CI on `master` succeeded and the CI workflow runs `make production-check` with a PostgreSQL service. +- Dockerfile, local Docker Compose, production-like Compose, Helm chart, Kubernetes docs, operations docs, backup/restore runbook, upgrade runbook, incident response runbook, observability references, Prometheus rules, and Grafana dashboard starter assets exist. +- Release-candidate packaging script builds multi-platform artifacts, writes checksums, OpenAPI and migration checksums, SBOM/provenance metadata, release notes, a signed release manifest, and a manifest signature. + +Evidence that prevents a broad production-ready verdict: + +- No public GitHub releases. +- No public remote tags, despite local-only release-candidate tags. +- No visible Release Artifacts workflow runs. +- Branch protection is not enabled on `master`. +- Vulnerability alerts are disabled and Dependabot security updates are disabled, even though Dependabot version-update PRs exist. +- README and production docs still classify the system as a controlled self-hosted production candidate, not broadly production-ready. +- The supported production API writer profile is one API writer replica. Worker scaling is supported through PostgreSQL outbox locking, but API multi-writer HA is explicitly unsupported. +- Several high-trust controls remain operator-dependent: KMS/HSM custody review, WORM/object-lock enforcement proof, provider-specific trust review, backup/restore in the target environment, monitoring deployment, and incident rehearsal. +- Production-like assets exist, but no published immutable image or installable release artifact was verified. + +Brutal assessment: the repository has more production machinery than many early OSS projects: real code, tests, migrations, OpenAPI, deployment manifests, runbooks, CI, and a strict self-hosted production gate. The public release surface is still not production-grade. For a high-trust compliance-readiness ledger, no public release artifacts, no public tags, no branch protection, and disabled GitHub vulnerability alerts are not cosmetic gaps; they are adoption blockers. + +Classification: controlled internal pilot / controlled self-hosted production candidate, not broadly production-ready. + +Score: 6/10. + +## Feature completeness + +Supported use cases backed by repository evidence: + +- Start a local API with in-process state or PostgreSQL-backed state. +- Run API, worker, migrations, PostgreSQL, and MinIO in production-like Compose. +- Define tenant-scoped products, projects, releases, artifacts, evidence, SBOMs, VEX documents, vulnerability scans, decisions, exceptions, waivers, approvals, incidents, controls, reports, release bundles, evidence bundles, customer packages, backup manifests, retention records, and related evidence relationships. +- Use scoped API keys, collector keys, SSO/session records, customer portal tokens, and admin diagnostics scopes. +- Generate and validate OpenAPI and route-contract evidence. +- Use Go, TypeScript, and Python SDK helper files plus a generated route catalog. +- Run a checked end-to-end release evidence demo fixture. +- Use a package viewer for customer package/readiness JSON inspection. +- Use release signing CLI commands and release-candidate packaging scripts. +- Deploy with Docker, Compose, or Helm after operator secret/storage/network review. + +Important missing or incomplete table stakes: + +- Public release artifacts and public tags are absent. +- No verified package manager install path, container registry image, or immutable image digest was found. +- Multi-writer API HA is not supported. +- Native PKCS#11/HSM handling is not implemented; `pkcs11-hsm` is gateway-backed. +- Broad object-lock/WORM proof is limited to configured bucket and optional sample-object checks. +- Direct provider-specific management API clients and external group synchronization are outside the current profile. +- Hosted SaaS controls are out of scope. +- Public Scorecard run results were not visible during audit, despite the workflow existing. +- Current docs still state final production exit review is incomplete. + +Blockers: + +- Publish signed public release artifacts and public tags. +- Enable branch protection and required checks. +- Enable vulnerability alerts / Dependabot security updates or document why a public equivalent is used. +- Produce a current release-candidate evidence bundle publicly. +- Close or explicitly defer production exit blockers with fresh review evidence. + +Nice-to-have gaps: + +- Hosted demo or downloadable evaluation bundle. +- Screenshots or short demo video for customer-package/release-readiness output. +- Published benchmark and sizing matrix tied to release artifacts. +- More opinionated install path for small teams. + +Maturity classification: productizable system and controlled production candidate, not a toy and not merely a prototype. It is still not feature-complete enough for broad self-service production adoption because public release/install evidence and external trust controls are missing. + +Score: 7/10. + +## Security and open-source trust + +Strong signals: + +- `SECURITY.md` exists and correctly warns that repository files cannot prove private vulnerability reporting is enabled. +- `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`, `GOVERNANCE.md`, `SUPPORT.md`, `TRADEMARKS.md`, `COMMERCIAL.md`, `RELEASE_EVIDENCE.md`, and issue/PR templates exist. +- Public GitHub community profile reports README, license, contributing, code of conduct, issue template, and PR template. +- Secret scanning and secret-scanning push protection are enabled in visible GitHub metadata. +- `.github/dependabot.yml` configures weekly Go module, GitHub Actions, and Docker updates. +- Several Dependabot PRs are open and their CI runs passed. +- `make tools`, `make gosec`, `make vuln`, `make lint`, `make test-race`, `make release-check`, and `make production-check` exist. +- CI workflow installs QA tools and runs `make production-check` with live PostgreSQL. +- Route/API docs emphasize tenant scoping, scoped secrets, one-time token output, Problem Details, idempotency, append-only evidence, and safe diagnostics. +- Runtime production checks reject several unsafe defaults. +- Release-candidate packaging includes checksums and signed release manifests. + +Weak signals and risks: + +- `master` branch is not protected. +- Vulnerability alerts are disabled. +- Dependabot security updates are disabled. +- No public GitHub releases or release artifacts. +- No public remote tags. +- No visible release-artifacts workflow runs. +- No visible Scorecard runs despite the workflow existing. +- No verified private vulnerability reporting setting. `SECURITY.md` says this must be verified externally. +- No CODEOWNERS evidence was found. +- No visible public release provenance from GitHub release assets or a package/container registry. +- The project handles high-trust evidence, tenant boundaries, secrets, signing, and compliance-readiness data, so public trust defaults matter more than they would for a low-risk library. + +External settings that could not be fully verified: + +- Required checks/rulesets beyond branch protection API response. +- Private vulnerability reporting enablement. +- Secret scanning alert status and remediation process. +- Code scanning alerts. +- Release signing secret presence. +- Registry package/image publication settings. +- Repository admin review process. + +Assessment: the source-controlled security posture is strong for an early project, but the public GitHub trust posture is not yet aligned with the risk profile. For a high-trust ledger, disabled vulnerability alerts and no protected default branch are material findings. + +Score: 6/10. + +## Marketability and positioning + +Buyer/adopter assessment: + +- The problem is painful and specific: teams need customer-reviewable release evidence, SBOM/VEX/vulnerability decisions, approvals, exceptions, and audit chains without forcing all technical trust data into a SaaS GRC platform. +- The target user is clear: B2B software security/platform/AppSec/compliance-readiness teams. +- The value proposition is sharper than generic GRC language: self-hosted technical release evidence ledger with OpenAPI, tenant scoping, idempotency, audit chains, release bundles, and customer-safe packages. +- The README wisely avoids high-risk compliance claims and frames the product as compliance-readiness support. +- The docs give a fast proof path and an end-to-end release evidence example. + +Crowding: + +- The broader space is crowded with SBOM/vulnerability management, GRC SaaS, ASPM, software supply-chain signing, transparency logs, and internal evidence spreadsheets/scripts. +- Evydence is not trying to be only an SBOM scanner, vulnerability platform, or legal compliance platform. That helps differentiation. + +Demo/evaluation path: + +- Local quickstart, production-like Compose, example fixtures, package viewer, and SDK examples exist. +- `make fast-check` passed during audit, including demo fixture checks. +- The best proof path is not yet public-product smooth because there is no published release, no immutable image, and no public release-candidate package to download. + +Monetization/adoption route: + +- AGPL plus `COMMERCIAL.md` supports a plausible dual-license/commercial exception path. +- Paid support, deployment review, custom collectors, templates, and enterprise integration support are plausible. +- Public adoption is constrained until release artifacts, install paths, and GitHub trust settings are fixed. + +Assessment: market positioning is good for a narrow self-hosted security/compliance-readiness infrastructure niche. The public repo currently looks like a serious candidate built fast, but not yet like a stable product users can safely adopt without close maintainer/operator involvement. + +Score: 7/10. + +## Differentiation + +Direct alternatives: + +- OWASP Dependency-Track: strong SBOM/component analysis and vulnerability intelligence workflows. Evydence is differentiated when the buyer wants release-level evidence bundles, decisions, approvals, audit chains, reports, customer packages, and explicit limitations around compliance claims. Dependency-Track remains stronger as a mature SBOM/vulnerability management platform. +- DefectDojo: mature DevSecOps/vulnerability management and findings workflow platform. Evydence is differentiated around release evidence ledgers, bundle verification, customer-safe packages, and tamper-evident evidence records, but DefectDojo is more established for vulnerability program operations. +- GRC SaaS tools such as Vanta and Drata: stronger for broad control automation, policy workflows, and auditor-facing compliance programs. Evydence is differentiated by being self-hosted and technical-evidence-first, but it does not replace legal/auditor review or broad GRC automation. + +Adjacent alternatives: + +- Sigstore/Rekor: strong software signing/transparency-log infrastructure. Evydence can record and verify release evidence and external transparency proof material, but it is not a replacement for public signing infrastructure. +- GUAC: software supply-chain graph analysis and SBOM/SLSA/OSV composition insight. Evydence is differentiated by release-readiness records, approvals, exceptions, customer packages, and compliance-readiness evidence organization. +- In-house systems: object storage, PostgreSQL tables, CI scripts, spreadsheets, and manual customer evidence packs. Evydence is meaningfully different if teams value a versioned API, OpenAPI contract, tenant scoping, idempotency, append-only evidence, audit chains, signed release manifests, and no-claim language. + +Practical comparison source notes: + +- README itself names Dependency-Track, Vanta, Drata, and in-house workflows. +- Public category references checked during audit: Dependency-Track describes continuous SBOM/component analysis; DefectDojo describes vulnerability management/DevSecOps; Sigstore/Rekor describes an append-only transparency log; GUAC describes software supply-chain composition insights. + +Meaningful differentiation: + +- Self-hosted release evidence ledger rather than broad SaaS GRC. +- Release-level package/report/audit-chain model. +- Explicit support for gaps, assumptions, limitations, exceptions, and customer-safe redaction. +- Strong OpenAPI/API-first posture with tenant scoping and idempotency. +- Release evidence and no-claim language are baked into docs and checks. + +Weak differentiation: + +- Public adoption surface is behind the implemented repository: no public releases, no public tags, no immutable install artifact. +- The product still overlaps with several established categories and needs a sharper first demo to show why users should not just extend Dependency-Track, DefectDojo, GUAC, or CI scripts. +- Some differentiators are documented or operator-dependent rather than proven in a public downloadable release. + +Score: 7/10. + +## Repository quality checklist + +| Area | Status | Evidence | Severity | Recommended fix | +|------|--------|----------|----------|-----------------| +| README | Strong | Clear category, target users, limitations, proof path, alternatives, implemented areas, validation commands, and no-claim language in `README.md`. | Low | Add a first-screen concrete output artifact or screenshot and link to the latest public release once published. | +| Quickstart | Strong | `docs/tutorials/getting-started.md`, README local API commands, Compose rehearsal docs. | Low | Tie quickstart to a public release artifact rather than source checkout only. | +| Examples/demo | Adequate | `examples/end-to-end-release-evidence`, JSON fixtures, `run-local-demo.sh`, package viewer, `make demo-check`, `make package-viewer-check`; `make fast-check` passed. | Medium | Publish a release-backed demo bundle and include expected screenshots/sample outputs in README. | +| Tests | Strong | 219 Go test files; `go test ./...` passed through `make fast-check`; CI runs `make production-check`; migration compatibility and black-box checks exist in project gates. | Low | Keep adding negative tests around tenant isolation, idempotency, signing, object-store digest mismatch, and provider gateways as surface grows. | +| CI | Adequate | Public CI workflow exists and latest `master` run succeeded with live PostgreSQL production-check. | High | Enable branch protection/required checks and publish the required check policy. | +| Releases/provenance | Weak | Release scripts and workflow exist, local tags exist, but public releases and public remote tags are absent; no release-artifacts workflow runs visible. | Blocker | Push signed tags, run release-artifacts workflow, publish draft or public releases with signed manifests, checksums, SBOM/provenance metadata, and release notes. | +| Docs/API/config/ops | Strong | `docs/`, `openapi.yaml`, config reference, operations index, runbooks, production readiness, production exit review, API contract matrix; `docs-check` passed through `make fast-check`. | Low | Reduce repeated long production-status prose over time and keep one canonical status source. | +| Docker/deployment | Adequate | Dockerfile, `docker-compose.yml`, `compose.production-like.yml`, Helm chart, Kubernetes docs, Prometheus rules, Grafana dashboard starter; deploy checks passed. | Medium | Publish immutable images/digests and add a reviewed production install matrix. | +| Security policy | Adequate | `SECURITY.md` exists and is public; secret scanning and push protection enabled. Vulnerability alerts and Dependabot security updates disabled; private vulnerability reporting not verified. | High | Enable vulnerability alerts and Dependabot security updates, verify private vulnerability reporting, add CODEOWNERS or equivalent review ownership. | +| License/contribution/governance | Strong | `LICENSE`, `COMMERCIAL.md`, `CONTRIBUTING.md`, `GOVERNANCE.md`, `CODE_OF_CONDUCT.md`, `SUPPORT.md`, templates. | Low | Clarify CLA/commercial exception path for outside contributors before seeking community adoption. | +| Changelog/versioning | Adequate | `CHANGELOG.md`, release notes template, release-candidate docs, local RC tags. Public tags/releases absent. | High | Publish public tags/releases and align changelog entries to public artifacts. | + +## Scorecard + +| Dimension | Score | Notes | +|-----------|------:|-------| +| Production readiness | 6/10 | Strong local code/gates/docs and latest CI success, but no public releases/tags, branch not protected, and production profile still has explicit operator-dependent blockers. | +| Feature completeness | 7/10 | Broad implemented release-evidence workflow, API, migrations, docs, examples, SDKs, and deployment assets; gaps remain in public install path, HA, HSM/WORM/provider integrations, and release publication. | +| Security and open-source trust | 6/10 | Good source-controlled policy and security-conscious implementation signals; public GitHub posture is weak for this risk profile because branch protection, vulnerability alerts, and Dependabot security updates are not enabled. | +| Marketability and positioning | 7/10 | Clear niche and buyer pain with good no-claim positioning; adoption is constrained by no release artifacts and no polished downloadable proof path. | +| Differentiation | 7/10 | Differentiated around self-hosted release evidence, audit chains, customer packages, limitations, and API-first records; still overlaps with SBOM/vulnerability/GRC/supply-chain tools and needs stronger public proof. | +| Repository evidence quality | 8/10 | Evidence is unusually complete for an early repo: code, tests, OpenAPI, migrations, docs, workflows, scripts, deployment assets, examples, and runbooks. Public release evidence is the major missing category. | +| Overall | 6/10 | Promising, serious, and productizable, but strict public production-readiness is capped by missing public releases/tags and weak GitHub protection/security settings. | + +Confidence: medium + +Verdict: Promising but not production-ready + +Direct answers: + +- Mature and high-grade enough for production for most intended uses? No. It may be usable for controlled self-hosted evaluation, pilots, or tightly reviewed internal production, but not broad production for most intended uses. +- Feature-complete enough to solve a real-world problem? Partly yes. The core release evidence ledger workflow is substantial enough to evaluate against a real problem, but public adoption and several high-trust production controls remain incomplete. +- Marketable or interesting enough to attract users, buyers, contributors, or commercial opportunity? Yes, if repositioned as a controlled self-hosted release-evidence candidate and backed by public release artifacts. +- Worth continuing, hardening, repositioning, or abandoning? Continue and harden. The next work should focus less on adding feature breadth and more on public release trust, installability, GitHub protections, security settings, and a sharper first demo. + +## Highest-leverage next steps + +Next 1-2 days: + +- Publish the public release surface. Push a public `v0.1.0-rc.3` tag or create a fresh `v0.1.0-rc.4`, run `.github/workflows/release-artifacts.yml`, and publish signed release artifacts with `evydence-release-manifest.json`, `evydence-release-manifest.sig.json`, `SHA256SUMS`, OpenAPI checksum, migration checksum, release notes, SBOM/provenance metadata, and binaries. This directly removes the strongest public-readiness blocker. +- Enable branch protection or repository rules for `master`. Require latest CI production-check before merge, prevent direct force-pushes, and require PR review if feasible. This improves trust in the default branch. +- Enable GitHub vulnerability alerts and Dependabot security updates, or document a verified substitute. For this project category, disabled alerts are a high-severity public trust issue. +- Trigger and verify OpenSSF Scorecard. The workflow file exists, but no runs were visible. A public run gives adopters a fast independent trust signal. +- Add a short README note that public releases are now the install source once the first release is published. Keep source checkout as development path. + +Next 1-2 weeks: + +- Make the first evaluation path release-backed. Update `docs/tutorials/getting-started.md`, `docs/how-to/install-and-operate.md`, and README so a user can download a release, verify checksums/signature, run Compose, execute the end-to-end demo, and inspect package/readiness output. +- Add a release evidence index page under `docs/reference/` that maps each release artifact to the command that generated or verified it. This strengthens auditability and prevents release evidence from becoming tribal knowledge. +- Add CODEOWNERS or a documented maintainer review policy for high-risk paths: `internal/app`, `internal/adapters/httpapi`, `internal/adapters/postgres`, signing adapters, object store adapters, migrations, release scripts, and workflows. +- Publish immutable container images or document why binaries/source are the only supported install path. If images are published, include digest pinning guidance in Helm and Compose docs. +- Run `make production-check` locally or in a fresh CI run after release publication and record the produced summary in release artifacts. The latest public CI already succeeded, but users need a release-tied evidence bundle. + +Next 1-2 months: + +- Complete a fresh production exit review after the first public release exists. Update `docs/reference/production-exit-review.md` only when public artifacts, GitHub protections, vulnerability handling, and target deployment runbooks have evidence. +- Decide whether to keep one-API-writer as a supported long-term profile or implement reviewed multi-writer concurrency. If one writer is the product stance, publish capacity limits and recommended deployment topologies. +- Harden provider-dependent areas with explicit integration profiles: KMS/HSM custody, object lock/WORM evidence, provider validation gateways, SSO group synchronization, and transparency proof retrieval. Each profile should have tests, docs, and operational limitations. +- Create a polished customer-facing demo: release readiness report, customer package, audit-chain verification, and a short walkthrough showing gaps/assumptions/limitations rather than generic dashboards. +- Add external adoption hygiene: issue labels, roadmap, support tiers, public security intake confirmation, contributor guidance for AGPL/commercial exceptions, and a release cadence. + +## README/product-page rewrite advice + +Sharper one-sentence pitch: + +Evydence is a self-hosted release evidence ledger for B2B software teams that need reproducible SBOM, vulnerability, approval, exception, deployment, and customer-review evidence without handing technical trust data to a SaaS GRC platform. + +Target user: + +Security, platform, AppSec, and compliance-readiness teams operating self-hosted release infrastructure for customer-facing software. + +Core use case to lead with: + +Before a release ships, collect SBOM, scan, VEX, build, source, approval, exception, and deployment evidence; generate a release-readiness report; verify the audit chain; and export a customer-safe evidence package with explicit gaps and limitations. + +Best demo/example to show first: + +Lead with the end-to-end release evidence example and package viewer, but make it release-backed. Show the exact generated readiness report, customer package manifest, and audit-chain verification result as downloadable artifacts. + +Proof points to add: + +- Latest public release link with signed artifacts and checksums. +- Latest CI production-check run link tied to the release commit. +- Public OpenAPI operation count and precision result. +- Coverage threshold result from release evidence. +- Migration checksum and migration compatibility result. +- Short table of supported production profiles and explicit unsupported profiles. + +What to remove or de-emphasize: + +- Reduce repeated long lists of implemented resource families in the README once a concise product proof path exists. +- Keep the detailed production caveats in canonical docs, but make README lead with one concrete workflow and one concrete output. +- Avoid adding more category breadth until the public install/release story is clean. + +## Residual risk and uncertainty + +Untested during this audit: + +- I did not run `make production-check` locally because it requires `EVYDENCE_TEST_DATABASE_URL` and live PostgreSQL setup. The latest public CI run did run the CI production-check job successfully. +- I did not run `make release-check`, `make test-race`, `make gosec`, `make vuln`, or `make release-candidate-check` locally. +- I did not perform a manual API black-box run, backup/restore rehearsal, Helm install, container build, S3/MinIO object-lock test, KMS signing test, or provider gateway test. +- I did not inspect private GitHub settings, release signing secrets, branch rulesets beyond the branch protection API, private vulnerability reporting, registry settings, or deployment infrastructure. + +Claims still documented or operator-dependent: + +- Native PKCS#11/HSM custody is not proven by repository code; the current profile is gateway-backed. +- Broad WORM/object-lock enforcement depends on object-store configuration and operator evidence. +- Provider-specific management API trust and external group synchronization are not implemented as broad direct integrations. +- Multi-writer API HA is explicitly unsupported. +- Hosted SaaS production is out of scope. +- Target-environment backup/restore, incident response, monitoring, and capacity evidence must be produced by each operator. + +Evidence that would raise confidence: + +- Public signed release artifacts and public tags. +- Public Release Artifacts workflow run tied to the latest release. +- Branch protection and required checks enabled for `master`. +- Vulnerability alerts and Dependabot security updates enabled. +- Public Scorecard results. +- Verified private vulnerability reporting. +- Published immutable container images or a clear binary-only install stance. +- A release-backed production-check summary, coverage report, OpenAPI checksum, migration checksum, SBOM/provenance metadata, and release notes. +- A fresh production exit review after the above public evidence exists. diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000..fb3496e --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,39 @@ +# Maintainer review ownership for high-trust Evydence changes. +# +# GitHub branch protection or repository rules must enforce these patterns +# before CODEOWNERS becomes a merge gate. Until then, this file documents the +# expected reviewer surface for security-sensitive paths. + +* @aatuh + +# Core application, tenant boundaries, evidence integrity, and policies. +/internal/app/ @aatuh +/internal/domain/ @aatuh +/internal/adapters/httpapi/ @aatuh +/internal/adapters/postgres/ @aatuh +/internal/adapters/objectstore/ @aatuh + +# Executables, operators, collectors, release tooling, and scripts. +/cmd/ @aatuh +/scripts/ @aatuh +/.github/workflows/ @aatuh +/Makefile @aatuh + +# Persistence, deployment, release evidence, and public trust surfaces. +/migrations/ @aatuh +/deploy/ @aatuh +/Dockerfile @aatuh +/docker-compose.yml @aatuh +/compose.production-like.yml @aatuh +/openapi.yaml @aatuh +/RELEASE_EVIDENCE.md @aatuh +/SECURITY.md @aatuh + +# Documentation that affects production positioning or public claims. +/README.md @aatuh +/docs/reference/production-readiness.md @aatuh +/docs/reference/production-exit-review.md @aatuh +/docs/reference/release-candidate.md @aatuh +/docs/reference/release-validation.md @aatuh +/docs/reference/release-evidence-index.md @aatuh +/docs/reference/maintainer-review-policy.md @aatuh diff --git a/Makefile b/Makefile index 18ecdb7..07835ff 100644 --- a/Makefile +++ b/Makefile @@ -64,6 +64,7 @@ meta-check: ## Validate root legal, governance, support, and release-evidence me @test -f SUPPORT.md @test -f TRADEMARKS.md @test -f CODE_OF_CONDUCT.md + @test -f CODEOWNERS @test -f RELEASE_EVIDENCE.md @test -f CHANGELOG.md @test -f .dockerignore @@ -88,6 +89,8 @@ meta-check: ## Validate root legal, governance, support, and release-evidence me @grep -F 'Security vulnerability' .github/ISSUE_TEMPLATE/config.yml >/dev/null @grep -F 'private vulnerability reporting' .github/ISSUE_TEMPLATE.md >/dev/null @grep -F 'tenant isolation' .github/pull_request_template.md >/dev/null + @grep -F 'internal/app/' CODEOWNERS >/dev/null + @grep -F 'docs/reference/release-evidence-index.md' CODEOWNERS >/dev/null @grep -F 'OpenSSF Scorecard' .github/workflows/scorecard.yml >/dev/null @grep -F 'Evydence fork' TRADEMARKS.md >/dev/null @grep -F 'Release evidence is not a certification' RELEASE_EVIDENCE.md >/dev/null @@ -119,8 +122,11 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @test -f docs/reference/production-readiness.md @test -f docs/reference/production-exit-review.md @test -f docs/reference/release-candidate.md + @test -f docs/reference/release-evidence-index.md @test -f docs/reference/release-notes-template.md @test -f docs/reference/release-notes-v0.1.0-rc.1.md + @test -f docs/reference/maintainer-review-policy.md + @test -f docs/reference/roadmap.md @test -f docs/reference/worker-outbox.md @test -f docs/reference/release-validation.md @test -f docs/explanation/trust-model.md @@ -151,8 +157,11 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod "reference/production-readiness.md" \ "reference/production-exit-review.md" \ "reference/release-candidate.md" \ + "reference/release-evidence-index.md" \ "reference/release-notes-template.md" \ "reference/release-notes-v0.1.0-rc.1.md" \ + "reference/maintainer-review-policy.md" \ + "reference/roadmap.md" \ "reference/worker-outbox.md" \ "reference/release-validation.md" \ "collectors/source-snapshots.md" \ @@ -190,6 +199,10 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'evydence-release-manifest.sig.json' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'gh release create' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'Controlled self-hosted production candidate' docs/reference/release-candidate.md >/dev/null + @grep -F 'Release evidence index' docs/reference/release-candidate.md >/dev/null + @grep -F 'evydence-release-manifest.sig.json' docs/reference/release-evidence-index.md >/dev/null + @grep -F 'CODEOWNERS' docs/reference/maintainer-review-policy.md >/dev/null + @grep -F 'one API writer replica' docs/reference/roadmap.md >/dev/null @grep -F 'Controlled self-hosted production candidate' docs/reference/release-notes-template.md >/dev/null @grep -F 'not legal compliance proof' docs/reference/release-notes-template.md >/dev/null @grep -F 'Controlled self-hosted production candidate' docs/reference/release-notes-v0.1.0-rc.1.md >/dev/null diff --git a/README.md b/README.md index 5fe8d76..ccf497a 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,11 @@ This repository contains a Go implementation under module been generated from this checkout; public release publication remains a separate operator action. +Until a public release candidate is published, source checkout is the +development and evaluation path. After the first public release candidate is +available, GitHub Releases and the checked release evidence artifacts should be +the operator install source. + ## Fastest Proof Path For a first local API flow, follow [Getting started](docs/tutorials/getting-started.md). @@ -51,6 +56,15 @@ For durable local evaluation, run the production-like Compose rehearsal in [Install and operate](docs/how-to/install-and-operate.md). For the release-evidence path to inspect first, use the [end-to-end release evidence example](examples/end-to-end-release-evidence/README.md). +For concrete JSON outputs to inspect without running a full stack, open the +sample readiness report, customer-package manifest, and audit-chain +verification fixtures in that example or load the bundled package in the +[local package viewer](docs/how-to/view-packages.md). + +Release-candidate artifacts and their verification commands are indexed in +[Release evidence index](docs/reference/release-evidence-index.md). Before a +public release exists, that index describes the evidence contract rather than a +published install guarantee. The end-to-end evidence flow to evaluate first is: @@ -156,6 +170,9 @@ For a runnable first evidence flow, use [Getting started](docs/tutorials/getting The canonical release validation reference is [docs/reference/release-validation.md](docs/reference/release-validation.md). The self-hosted production-readiness profile is [docs/reference/production-readiness.md](docs/reference/production-readiness.md). The release-candidate checklist is [docs/reference/release-candidate.md](docs/reference/release-candidate.md). +The release evidence artifact map is [docs/reference/release-evidence-index.md](docs/reference/release-evidence-index.md). +The maintainer review policy for high-risk paths is [docs/reference/maintainer-review-policy.md](docs/reference/maintainer-review-policy.md). +The public roadmap and release cadence are [docs/reference/roadmap.md](docs/reference/roadmap.md). Common local checks: diff --git a/docs/README.md b/docs/README.md index 038ddd3..41fb557 100644 --- a/docs/README.md +++ b/docs/README.md @@ -33,8 +33,11 @@ This documentation is organized by reader task. Implementation claims should be - [Production readiness](reference/production-readiness.md): self-hosted production profiles, production gates, and exit criteria. - [Production exit review](reference/production-exit-review.md): current release-positioning decision and unresolved blockers. - [Release candidate checklist](reference/release-candidate.md): required evidence before tagging a controlled self-hosted release candidate. +- [Release evidence index](reference/release-evidence-index.md): release artifact map, generation commands, and verification commands. - [Release notes template](reference/release-notes-template.md): checked wording used by release-candidate packaging when a tag-specific note file is absent. - [Release notes v0.1.0-rc.1](reference/release-notes-v0.1.0-rc.1.md): checked release-note wording for the first controlled self-hosted release candidate. +- [Maintainer review policy](reference/maintainer-review-policy.md): CODEOWNERS-backed review expectations for high-risk paths. +- [Roadmap and release cadence](reference/roadmap.md): current release-line focus, external trust controls, and cadence expectations. - [Worker outbox contract](reference/worker-outbox.md): durable job kinds, idempotency, and safe logging rules. - [Release validation](reference/release-validation.md): canonical `make release-check` behavior and summary evidence. - [SDK workflow](sdk/README.md): current Go, TypeScript, and Python wrapper usage and limitations. @@ -53,6 +56,7 @@ This documentation is organized by reader task. Implementation claims should be - [Trademarks](../TRADEMARKS.md): conservative use of the Evydence name and modified-build naming rules. - [Release evidence](../RELEASE_EVIDENCE.md): release evidence routing, local acceptance checks, and limits of release validation. - [Changelog](../CHANGELOG.md): unreleased and future public-release notes. +- [CODEOWNERS](../CODEOWNERS): expected maintainer ownership for high-trust code, release, deployment, and claim surfaces. ## Workflow Examples diff --git a/docs/how-to/install-and-operate.md b/docs/how-to/install-and-operate.md index 71793a5..764a61d 100644 --- a/docs/how-to/install-and-operate.md +++ b/docs/how-to/install-and-operate.md @@ -2,6 +2,13 @@ Use this guide for a local self-hosted development or evaluation deployment. +Until a public release candidate is published, use a source checkout for local +evaluation. After a public release exists, install from the release archive and +verify `SHA256SUMS`, `openapi.sha256`, `migrations.sha256`, and the signed +release manifest before starting the API or worker. See +[Release evidence index](../reference/release-evidence-index.md) for the +artifact map and verification commands. + ## Runtime Modes | Mode | How To Enable | Expected Use | diff --git a/docs/reference/maintainer-review-policy.md b/docs/reference/maintainer-review-policy.md new file mode 100644 index 0000000..3c09316 --- /dev/null +++ b/docs/reference/maintainer-review-policy.md @@ -0,0 +1,77 @@ +# Maintainer Review Policy + +This reference documents the repository review expectations for Evydence +changes that affect high-trust release evidence, tenant isolation, credentials, +signing, storage, deployment, or public product claims. + +The policy supports engineering review. It is not legal compliance proof, +certification, complete vulnerability coverage, or a secure-release guarantee. + +## Current Enforcement Status + +`CODEOWNERS` is committed at the repository root and names the expected +maintainer owner for high-risk paths. GitHub branch protection or repository +rules must enforce CODEOWNERS and required checks before it becomes a merge +gate. Until those GitHub settings are enabled, this file is a public review +policy and not a technical enforcement guarantee. + +## High-Risk Paths + +Changes in these areas require maintainer review before merge or release: + +- `internal/app/`, `internal/domain/`, and `internal/adapters/httpapi/` for + tenant isolation, authorization, idempotency, evidence immutability, report + wording, and API behavior; +- `internal/adapters/postgres/`, `internal/adapters/objectstore/`, and + `migrations/` for persistence, object payload references, transaction + behavior, durability, and recovery; +- `cmd/`, `scripts/`, `.github/workflows/`, and `Makefile` for CLI/operator + behavior, release packaging, CI gates, and secret-handling surfaces; +- `deploy/`, `Dockerfile`, `docker-compose.yml`, and + `compose.production-like.yml` for production startup, probes, resources, + ingress, object storage, and database wiring; +- `openapi.yaml`, `docs/api.md`, and `docs/reference/api-contract-matrix.md` + for public API contract changes; +- `SECURITY.md`, `RELEASE_EVIDENCE.md`, `README.md`, and production/release + references for public security intake, release evidence, production status, + and product claim boundaries. + +## Required Review Questions + +Reviewers should explicitly check: + +- tenant-scoped resources cannot cross tenant boundaries; +- evidence core fields, audit-chain entries, release bundles, decisions, + approvals, exceptions, and lifecycle records remain append-only where + required; +- create/action endpoints preserve idempotency replay and conflict behavior; +- uploaded objects, release artifacts, and imported bundles are checked by + digest before trust is assigned; +- errors, logs, reports, release evidence, and examples do not expose API keys, + bearer tokens, session tokens, portal tokens, private keys, database URLs, + provider credentials, raw evidence payloads, or customer data; +- public wording stays limited to compliance readiness, technical evidence + organization, reproducibility, gaps, assumptions, exceptions, and + limitations. + +## Required Checks + +For routine changes, run the narrowest affected tests plus the relevant +project-owned gate. For release, production, deployment, API, persistence, or +security-sensitive changes, reviewers should require evidence from: + +```sh +make docs-check +make fast-check +``` + +Release-candidate and production-readiness changes should also require: + +```sh +make production-check +make release-candidate-check TAG= +``` + +Those stronger commands require live PostgreSQL and release signing material; +skips or unavailable external dependencies must be recorded in release notes or +the release evidence index. diff --git a/docs/reference/production-exit-review.md b/docs/reference/production-exit-review.md index 1c11cef..20e4ca9 100644 --- a/docs/reference/production-exit-review.md +++ b/docs/reference/production-exit-review.md @@ -26,11 +26,15 @@ SaaS-ready, legally compliant, certified, or secure-release-guaranteed. release-ledger write paths are implemented for the current candidate profile. - Security, support, governance, contribution, code of conduct, issue templates, Dependabot, and Scorecard workflow files exist. +- CODEOWNERS and the maintainer review policy document expected review + ownership for high-risk code, release, deployment, and public-claim surfaces. ## Remaining Exit Blockers - Public release publication and branch protection require GitHub/operator settings outside repository files. +- CODEOWNERS is documented but does not become an enforced merge gate until + branch protection or repository rules require it. - Native PKCS#11/HSM module custody requires operator hardware, drivers, and provider-specific validation. - Broad WORM/object-lock proof requires object-store policy, IAM, lifecycle, diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 0de3129..3a2ce56 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -92,11 +92,12 @@ Known hardening work remains: ## HA And Concurrency Contract The current self-hosted production profile supports one API writer replica. -This is intentional while the application still uses a large in-process ledger -aggregate and some resource families still use aggregate persistence. Focused -critical mutations reduce the riskiest `SaveState` dependence, but they are -not a full multi-writer concurrency design. When `ENV=production`, API startup -rejects unsupported `EVYDENCE_API_WRITER_MODE` values and rejects +This is the supported stance for the current release line, not an accidental +default. The application still uses a large in-process ledger aggregate and +some resource families still use aggregate persistence. Focused critical and +release-ledger mutations reduce the riskiest `SaveState` dependence, but they +are not a full multi-writer concurrency design. When `ENV=production`, API +startup rejects unsupported `EVYDENCE_API_WRITER_MODE` values and rejects `EVYDENCE_API_WRITER_REPLICAS` values above `1`. When PostgreSQL is configured, startup also takes a PostgreSQL advisory writer lease and fails if another API writer already holds it. Do not scale API writer replicas above one for @@ -108,6 +109,9 @@ Worker replicas may be scaled because persisted outbox jobs are claimed with PostgreSQL row locking. Scaling workers increases parser/signing/report throughput; it does not make API writes multi-writer safe. +The roadmap records the future decision point for multi-writer API HA; see +[Roadmap and release cadence](roadmap.md). + ## Machine Gate Run the production gate from the repository root: diff --git a/docs/reference/release-candidate.md b/docs/reference/release-candidate.md index 82cd3be..f9f1fab 100644 --- a/docs/reference/release-candidate.md +++ b/docs/reference/release-candidate.md @@ -24,6 +24,9 @@ Before creating a release-candidate tag, collect: - release notes with supported profile, upgrade notes, assumptions, limitations, and unresolved hardening work. +The artifact map and verification commands are maintained in +[Release evidence index](release-evidence-index.md). + ## Required Commands Run from a clean checkout with a disposable PostgreSQL database: @@ -58,6 +61,14 @@ explicitly changed it: The notes must also state that broad production for most uses, regulated production, and hosted SaaS production require additional review and controls. +## Public Publication + +Before the first public release candidate is published, source checkout remains +the development and evaluation path. Public release readiness requires a pushed +tag, a completed release-artifacts workflow run, uploaded release archives, +checksums, signed manifest files, release notes, and any configured repository +or registry trust settings. + ## Deployment Constraints - Use one API writer replica for the current production profile. diff --git a/docs/reference/release-evidence-index.md b/docs/reference/release-evidence-index.md new file mode 100644 index 0000000..eca47ed --- /dev/null +++ b/docs/reference/release-evidence-index.md @@ -0,0 +1,60 @@ +# Release Evidence Index + +This reference maps each release-candidate evidence artifact to the command +that creates or verifies it. Keep it with +[Release candidate checklist](release-candidate.md) and +[Release validation](release-validation.md) when preparing a controlled +self-hosted release candidate. + +Release evidence supports reproducible engineering and operator review. It is +not legal compliance proof, certification, complete SBOM proof, authoritative +vulnerability coverage, a secure-release guarantee, regulator acceptance, or +auditor acceptance. + +## Artifact Map + +`scripts/release_candidate_package.sh ` writes the release evidence set +under `dist//` after `make production-check` passes. + +| Artifact | Created By | Verification Use | +| --- | --- | --- | +| `evydence__.tar.gz` or `.zip` | `scripts/release_candidate_package.sh` | Operator installs the API, worker, migration command, and CLI from the release archive for the matching platform. | +| `SHA256SUMS` | `scripts/release_candidate_package.sh` | Verify every release archive byte-for-byte before extraction or redistribution. | +| `openapi.yaml` | `cmd/openapi` through the release package script | Preserve the exact public API contract shipped with the release. | +| `openapi.sha256` | `scripts/release_candidate_package.sh` | Verify the shipped OpenAPI contract has not drifted from the release evidence set. | +| `migrations.sha256` | `scripts/release_candidate_package.sh` | Verify the migration directory that the release was checked against. | +| `coverage.out` | `make production-check` | Preserve the coverage input used by the release gate. | +| `release-check-summary.txt` | `make release-check` inside `make production-check` | Record whether formatting, unit tests, OpenAPI, docs, deployment, SDK, lint, gosec, govulncheck, race, and live PostgreSQL checks passed. | +| `evydence-release-manifest.json` | `./evydence release manifest` through the package script | List release artifacts, hashes, OpenAPI checksum, migration checksum, and release metadata. | +| `evydence-release-manifest.sig.json` | `./evydence release sign` through the package script | Verify the release manifest signature with the release public key. | +| `release-sbom-metadata.json` | `scripts/release_evidence_metadata.py` | Record release SBOM metadata and limitations; this does not prove SBOM completeness. | +| `release-provenance-metadata.json` | `scripts/release_evidence_metadata.py` | Record build/release provenance metadata and limitations; this does not prove provider trust by itself. | +| `release-notes.md` | Tag-specific release notes or `docs/reference/release-notes-template.md` | State supported profile, upgrade notes, assumptions, limitations, and unresolved hardening work. | + +## Local Verification + +After packaging, verify the evidence directory before publishing: + +```sh +sha256sum -c dist//SHA256SUMS +./dist///evydence release verify \ + --manifest dist//evydence-release-manifest.json \ + --signature dist//evydence-release-manifest.sig.json \ + --public-key evydence-release-public.key +``` + +Use the platform-specific `evydence` binary from the release archive whenever +possible so the verifier matches the released toolchain. If you verify from a +source checkout instead, record that limitation in the release notes. + +## Publication Status + +Before the first public release, source checkout remains the development and +evaluation path. After a public release candidate is published, GitHub Releases +must be the install source for operator evaluation, and the README, getting +started tutorial, and install guide should link to the release artifacts and +this index. + +Public publication is not proven by this file. It requires a pushed tag, a +completed release-artifacts workflow run, uploaded release assets, and any +repository or registry settings required by the operator. diff --git a/docs/reference/release-validation.md b/docs/reference/release-validation.md index 0627733..ad960c6 100644 --- a/docs/reference/release-validation.md +++ b/docs/reference/release-validation.md @@ -159,6 +159,10 @@ the release manifest, and the manifest signature. Tag pushes create or update a draft GitHub release; manual runs can upload only the workflow artifact unless `upload_draft_release` is enabled. +The canonical artifact map is +[Release evidence index](release-evidence-index.md). Keep that page aligned +with the release-candidate package script whenever the artifact set changes. + These artifacts support reproducible engineering review. They are not legal compliance proof, certification, a secure-release guarantee, complete SBOM proof, or authoritative vulnerability coverage. diff --git a/docs/reference/roadmap.md b/docs/reference/roadmap.md new file mode 100644 index 0000000..3e45556 --- /dev/null +++ b/docs/reference/roadmap.md @@ -0,0 +1,46 @@ +# Roadmap And Release Cadence + +This roadmap keeps public expectations aligned with repository evidence. It +does not make legal compliance conclusions, grant certification, prove SBOM +completeness, treat scanner output as authoritative, or guarantee release +security. + +## Current Release Line + +The current release line is a controlled self-hosted production candidate. The +supported API deployment profile is one API writer replica with scalable worker +replicas through PostgreSQL outbox locking. Multi-writer API high availability +is not part of the current supported profile. + +## Near-Term Focus + +- publish a public signed release candidate with checksums, release notes, + OpenAPI checksum, migration checksum, coverage output, production-check + summary, SBOM/provenance metadata, and a signed release manifest; +- enable public GitHub trust controls such as required checks, branch + protection or repository rules, vulnerability alerts, Dependabot security + updates, and private vulnerability reporting; +- keep the first evaluation path tied to release artifacts, the end-to-end + release evidence example, the package viewer, and the release evidence index; +- continue reducing large service surfaces while preserving tenant isolation, + append-only evidence behavior, and safe error handling. + +## Later Production Hardening + +- review whether the single API writer profile remains the supported long-term + posture or whether a multi-writer design is justified by operator demand; +- harden provider-specific KMS/HSM, object-lock/WORM, SSO/group-sync, and + transparency-proof profiles with deployment-specific evidence and tests; +- publish immutable container image digests if container images become a + supported install path; +- run production exit reviews only against a concrete release candidate and + target deployment profile. + +## Cadence + +Release candidates should be cut only after `make production-check` and the +release-candidate evidence package pass. Public releases should include a clear +support window, upgrade notes, limitations, and known unresolved hardening work. + +Community contributions remain selective until the public release, security +intake, branch protection, and review enforcement surfaces are stable. diff --git a/docs/reference/source-of-truth.md b/docs/reference/source-of-truth.md index 411f546..11e4c5a 100644 --- a/docs/reference/source-of-truth.md +++ b/docs/reference/source-of-truth.md @@ -13,7 +13,10 @@ product-boundary language across the docs. | Kubernetes | `docs/kubernetes.md` | Helm-specific operator interface. | | Release validation | `docs/reference/release-validation.md` | Canonical release gate behavior. | | Release-candidate evidence | `docs/reference/release-candidate.md` | Canonical release-candidate artifact checklist. | +| Release evidence artifact map | `docs/reference/release-evidence-index.md` | Maps each release artifact to generation and verification commands. | | Production profiles and exit criteria | `docs/reference/production-readiness.md` and `docs/reference/production-exit-review.md` | Do not broaden status elsewhere without updating these. | +| Maintainer review ownership | `CODEOWNERS` and `docs/reference/maintainer-review-policy.md` | Branch protection or repository rules must enforce this before it is a merge gate. | +| Roadmap and cadence | `docs/reference/roadmap.md` | Public roadmap, supported release line, and cadence expectations. | | Backup/restore | `docs/runbooks/backup-restore.md` | Operator rehearsal steps and evidence to keep. | | Upgrade | `docs/runbooks/upgrade.md` | Migration and release artifact verification steps. | | Incident response | `docs/runbooks/incident-response.md` | Secrets, tenant, object-store, signing, provider, and package boundaries. | diff --git a/docs/tutorials/getting-started.md b/docs/tutorials/getting-started.md index 30bb262..bdab029 100644 --- a/docs/tutorials/getting-started.md +++ b/docs/tutorials/getting-started.md @@ -2,6 +2,12 @@ This tutorial runs Evydence with in-process state and records a small release evidence flow. It is for local development only; data is lost when the process exits. +Until a public release candidate is published, run this tutorial from a source +checkout. After a public release exists, prefer the release archive and +checksums from GitHub Releases, then use this tutorial only as a local +development path. The release artifact map is in +[Release evidence index](../reference/release-evidence-index.md). + ## Prerequisites - Go with the version declared by `go.mod`. diff --git a/scripts/release_acceptance.sh b/scripts/release_acceptance.sh index 0c80299..16446d3 100755 --- a/scripts/release_acceptance.sh +++ b/scripts/release_acceptance.sh @@ -42,12 +42,16 @@ for file in \ TRADEMARKS.md \ RELEASE_EVIDENCE.md \ CHANGELOG.md \ + CODEOWNERS \ .dockerignore \ .github/ISSUE_TEMPLATE.md \ .github/pull_request_template.md \ README.md \ docs/README.md \ docs/reference/release-candidate.md \ + docs/reference/release-evidence-index.md \ + docs/reference/maintainer-review-policy.md \ + docs/reference/roadmap.md \ docs/reference/release-validation.md; do require_file "$file" done @@ -68,6 +72,8 @@ require_text .github/ISSUE_TEMPLATE.md "private vulnerability reporting" require_text .github/ISSUE_TEMPLATE.md "raw evidence payloads" require_text .github/pull_request_template.md "tenant isolation" require_text .github/pull_request_template.md "Sensitive Data Check" +require_text CODEOWNERS "internal/app/" +require_text CODEOWNERS "docs/reference/release-evidence-index.md" require_text SUPPORT.md "sanitized logs" require_text SUPPORT.md "release evidence artifacts" require_text TRADEMARKS.md "Evydence fork" @@ -79,6 +85,13 @@ require_text docs/reference/release-candidate.md "Controlled self-hosted product require_text docs/reference/release-candidate.md "Use one API writer replica" require_text docs/reference/release-candidate.md "OpenAPI checksum" require_text docs/reference/release-candidate.md "migration checksum" +require_text docs/reference/release-candidate.md "Release evidence index" +require_text docs/reference/release-evidence-index.md "evydence-release-manifest.sig.json" +require_text docs/reference/release-evidence-index.md "not legal compliance proof" +require_text docs/reference/maintainer-review-policy.md "CODEOWNERS" +require_text docs/reference/maintainer-review-policy.md "tenant-scoped resources cannot cross tenant boundaries" +require_text docs/reference/roadmap.md "one API writer replica" +require_text docs/reference/roadmap.md "Release candidates" for pattern in \ ".refs" \ From 148d76cc78d0fbc0dbda3f853fe50155e63b4196 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 19:30:18 +0300 Subject: [PATCH 156/287] chore: harden public repository trust checks --- .github/workflows/ci.yml | 8 +- .github/workflows/codeql.yml | 37 ++ .github/workflows/release-artifacts.yml | 12 +- .github/workflows/scorecard.yml | 6 +- .production_readiness_v4.md | 647 +++++++++++++++++++++ Dockerfile | 4 +- Makefile | 10 + SECURITY.md | 9 +- docs/reference/maintainer-review-policy.md | 5 + docs/reference/release-validation.md | 5 + go.mod | 12 +- go.sum | 21 +- scripts/release_acceptance.sh | 6 + 13 files changed, 746 insertions(+), 36 deletions(-) create mode 100644 .github/workflows/codeql.yml create mode 100644 .production_readiness_v4.md diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1451c77..bc3fcb4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest services: postgres: - image: postgres:16-alpine + image: postgres:16-alpine@sha256:16bc17c64a573ef34162af9298258d1aec548232985b33ed7b1eac33ba35c229 env: POSTGRES_DB: evydence POSTGRES_USER: evydence @@ -34,10 +34,10 @@ jobs: EVYDENCE_TEST_DATABASE_URL: postgres://evydence:change-me@localhost:5432/evydence?sslmode=disable steps: - name: Check out repository - uses: actions/checkout@v5 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 - name: Set up Go - uses: actions/setup-go@v6 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version-file: go.mod cache: true @@ -50,7 +50,7 @@ jobs: - name: Upload release evidence artifacts if: always() - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: evydence-ci-evidence path: | diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..fc441a4 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,37 @@ +name: CodeQL + +on: + push: + branches: + - master + - main + pull_request: + schedule: + - cron: "19 4 * * 2" + workflow_dispatch: + +permissions: + contents: read + +jobs: + analyze: + name: CodeQL Analyze + runs-on: ubuntu-latest + permissions: + contents: read + security-events: write + steps: + - name: Check out repository + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + + - name: Initialize CodeQL + uses: github/codeql-action/init@fee9466b8957867761f2d78f922ab084e3e2dd17 # v3 + with: + languages: go + queries: security-and-quality + + - name: Autobuild + uses: github/codeql-action/autobuild@fee9466b8957867761f2d78f922ab084e3e2dd17 # v3 + + - name: Analyze + uses: github/codeql-action/analyze@fee9466b8957867761f2d78f922ab084e3e2dd17 # v3 diff --git a/.github/workflows/release-artifacts.yml b/.github/workflows/release-artifacts.yml index d8fd631..c35aeb3 100644 --- a/.github/workflows/release-artifacts.yml +++ b/.github/workflows/release-artifacts.yml @@ -17,15 +17,17 @@ on: type: boolean permissions: - contents: write + contents: read jobs: package: name: Package Signed Release Artifacts runs-on: ubuntu-latest + permissions: + contents: write services: postgres: - image: postgres:16-alpine + image: postgres:16-alpine@sha256:16bc17c64a573ef34162af9298258d1aec548232985b33ed7b1eac33ba35c229 env: POSTGRES_DB: evydence POSTGRES_USER: evydence @@ -44,7 +46,7 @@ jobs: EVYDENCE_RELEASE_ALLOW_EXISTING_TAG: ${{ github.ref_type == 'tag' && '1' || '0' }} steps: - name: Check out repository - uses: actions/checkout@v5 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 with: fetch-depth: 0 @@ -65,7 +67,7 @@ jobs: echo "tag=${tag}" >> "${GITHUB_OUTPUT}" - name: Set up Go - uses: actions/setup-go@v6 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version-file: go.mod cache: true @@ -91,7 +93,7 @@ jobs: scripts/release_candidate_package.sh "${{ steps.release.outputs.tag }}" - name: Upload packaged release evidence - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: evydence-release-artifacts-${{ steps.release.outputs.tag }} path: dist/${{ steps.release.outputs.tag }}/ diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 49108b9..1bee3f8 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -19,18 +19,18 @@ jobs: security-events: write steps: - name: Check out repository - uses: actions/checkout@v5 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 with: persist-credentials: false - name: Run OpenSSF Scorecard - uses: ossf/scorecard-action@v2.4.0 + uses: ossf/scorecard-action@ff5dd8929f96a8a4dc67d13f32b8c75057829621 # v2.4.0 with: results_file: scorecard-results.sarif results_format: sarif publish_results: true - name: Upload SARIF - uses: github/codeql-action/upload-sarif@v3 + uses: github/codeql-action/upload-sarif@fee9466b8957867761f2d78f922ab084e3e2dd17 # v3 with: sarif_file: scorecard-results.sarif diff --git a/.production_readiness_v4.md b/.production_readiness_v4.md new file mode 100644 index 0000000..d1bd6e5 --- /dev/null +++ b/.production_readiness_v4.md @@ -0,0 +1,647 @@ +## 2026-05-31 Remediation Tracking + +Status legend: + +- `[ ]` applicable repository-local work that remains incomplete. +- `[x]` applicable repository-local work completed with current repository evidence. +- `[e]` external, account-level, provider-level, operator-environment, release-publication, or adoption-dependent work that cannot be completed by repository files alone. + +Repository-local remediation from the v4 audit: + +- [x] Keep `.production_readiness_v4.md` as a trackable repository artifact. +- [x] Pin GitHub Actions used by CI, release-artifact packaging, Scorecard, and CodeQL workflows to immutable commit SHAs. +- [x] Pin CI service containers and Dockerfile base images to immutable image digests. +- [x] Move the Release Artifacts workflow from workflow-global `contents: write` to workflow-global `contents: read` with job-scoped release write permission. +- [x] Add a CodeQL SAST workflow using the `security-and-quality` query suite and pinned CodeQL action refs. +- [x] Strengthen `SECURITY.md` with a direct GitHub Security Advisory intake link while still stating that private vulnerability reporting must be verified as a GitHub setting. +- [x] Update dependency versions flagged by `govulncheck -show verbose` for non-called module/package vulnerabilities in `golang.org/x/crypto` and `golang.org/x/net`. +- [x] Wire the new workflow and pinning expectations into `make meta-check`, `make docs-check`, `make release-acceptance`, and release/review documentation. + +External or operator-dependent remediation from the v4 audit: + +- [e] Publish a signed public release candidate/tag with release archives, `SHA256SUMS`, OpenAPI checksum, migration checksum, coverage output, production-check summary, SBOM/provenance metadata, signed release manifest, release notes, and a public Release Artifacts workflow run. +- [e] Enable branch protection or repository rules for `master`, including required checks, review requirements, force-push prevention, and CODEOWNERS enforcement. +- [e] Enable or verify GitHub private vulnerability reporting, vulnerability alerts, Dependabot security updates, and any desired code-scanning/security-alert settings. +- [e] Configure and verify release signing secrets for GitHub Actions and any package/container registry credentials. +- [e] Publish immutable container images or document a final decision that release archives/source checkout are the only supported install path for the current release line. +- [e] Close or dismiss GitHub code-scanning alerts that require account-level controls, historical/adoption evidence, or GitHub rescanning state after the repository fixes are pushed. +- [e] Prove deployed-environment controls: target backup/restore rehearsal, monitoring deployment, incident rehearsal, object-store WORM/object-lock policy, KMS/HSM custody, SSO/group-sync provider behavior, and transparency-provider semantics. +- [e] Produce external adoption evidence, third-party review, support-process evidence, customer feedback, or case studies tied to a concrete public release candidate. + +## Latest visible state inspected + +Repository: `aatuh/evydence` at `https://github.com/aatuh/evydence`. +Audit scope: strict latest public GitHub repository plus the current local +checkout at `/home/aatu/projects/evydence`. + +Inspected local state: + +- Local branch: `master`. +- Local `HEAD`: `653290639a59395c5ccd8017cc86c551b7ee728a`. +- Local commit date: `2026-05-31 18:33:24 +0300` / `2026-05-31T15:33:24Z`. +- Commit subject: `docs: track production readiness v3 remediation`. +- Local worktree before writing this audit: clean, `## master...origin/master`. +- Local release-candidate tags exist: `v0.1.0-rc.1`, `v0.1.0-rc.2`, + and `v0.1.0-rc.3`. +- Local tags are not public release evidence unless pushed and accompanied by + release artifacts. + +Public GitHub state verified with `gh` and `git ls-remote`: + +- Default branch: `master`. +- Public default-branch commit: + `653290639a59395c5ccd8017cc86c551b7ee728a`. +- Public default-branch commit date: `2026-05-31T15:33:24Z`. +- Local and public `origin/master` matched at audit time. +- Visibility: public. +- Archived: false. +- Description: `Self-hosted API-first evidence ledger for software release + compliance readiness`. +- Topics include `api-first`, `audit-log`, `evidence-ledger`, `golang`, + `openapi`, `release-evidence`, `sbom`, `self-hosted`, + `supply-chain-security`, `vex`, `vulnerability-management`, and + `compliance-readiness`. +- Public stars/watchers/forks: `0` stars, `0` watchers, `0` forks. +- Public issues: GitHub reported 0 issues; 6 open Dependabot PRs were visible. +- License: GitHub reports GNU AGPLv3 / `agpl-3.0`; repository files state + `AGPL-3.0-only` plus optional commercial licensing terms in `COMMERCIAL.md`. +- Primary language: Go. GitHub language data also reported Makefile, Python, + Shell, TypeScript, HTML, Dockerfile, and Go Template. +- Package manifest: `go.mod` / `go.sum`; module + `github.com/aatuh/evydence`; Go `1.25.10`. + +Public release and tag state: + +- `gh release list --repo aatuh/evydence --limit 20` returned no releases. +- `git ls-remote --tags origin` returned no public remote tags. +- `gh api repos/aatuh/evydence/tags` returned `[]`. +- `.github/workflows/release-artifacts.yml` exists, but + `gh run list --workflow "Release Artifacts"` returned no runs. +- This is the largest public production-readiness blocker. The repository has + release-candidate packaging machinery, but no public installable release + evidence yet. + +Public CI and workflow evidence: + +- Latest public `CI` workflow run for `master` at commit `6532906` succeeded: + run `26716793712`, event `push`, created `2026-05-31T15:33:33Z`, + updated `2026-05-31T15:37:32Z`. +- The CI job name was `Production Check`, and GitHub reported it completed + successfully. +- Public `OpenSSF Scorecard` workflow run for `master` at commit `6532906` + succeeded: run `26716795712`, event `workflow_dispatch`, created + `2026-05-31T15:33:39Z`, updated `2026-05-31T15:34:13Z`. +- Public `Dependabot Updates` workflow run for `master` at commit `6532906` + succeeded: run `26716825331`, event `dynamic`. +- One Dependabot pull-request CI run for `actions/checkout-6` was in progress + during inspection. Several earlier Dependabot PR CI runs were successful. +- No public `Release Artifacts` workflow runs were visible. + +Visible GitHub security and repository settings: + +- `master` branch protection: disabled. The branch API reported + `"protected": false`. +- `security_and_analysis`: secret scanning enabled, secret-scanning push + protection enabled, non-provider pattern scanning disabled, validity checks + disabled, Dependabot security updates disabled. +- `repos/aatuh/evydence/automated-security-fixes` returned + `{"enabled":false,"paused":false}`. +- `repos/aatuh/evydence/private-vulnerability-reporting` returned + `{"enabled":false}`. +- `repos/aatuh/evydence/vulnerability-alerts` returned HTTP 404 and did not + prove vulnerability alerts enabled. +- Secret-scanning alerts count returned `0`. +- Code-scanning alerts count returned `20`, all open, from the Scorecard SARIF + upload. The open rules included branch protection, pinned dependencies, + token permissions, code review, SAST, vulnerabilities, security policy, and + maintained-project checks. +- GitHub community profile reported 100 percent and found README, license, + contributing, code of conduct, issue template, and PR template. + +Current repository evidence in checkout: + +- Source and operational tree is substantial: `cmd/`, `internal/`, + `migrations/`, `docs/`, `deploy/`, `sdk/`, `examples/`, `scripts/`, + `.github/`, Dockerfile, Compose files, Helm chart, and `openapi.yaml`. +- `go list ./...` reported 22 Go packages. +- There are 219 Go test files. +- There are 46 migration files. +- `openapi.yaml` contains 152 paths and 166 operations. +- `CODEOWNERS`, `SECURITY.md`, `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`, + `GOVERNANCE.md`, `SUPPORT.md`, `RELEASE_EVIDENCE.md`, `CHANGELOG.md`, + issue templates, PR template, Dependabot config, CI, Scorecard, and release + workflow files are present. + +Not inspectable or not proven: + +- Required checks, rulesets, CODEOWNERS enforcement, maintainer review in + practice, release signing secret configuration, package/container registry + publication, deployment state, backup retention, monitoring deployment, + object-store WORM policy, KMS/HSM custody, external SSO/provider behavior, + customer adoption, commercial support operation, and incident rehearsal could + not be proven from repository files alone. +- Some external settings were inspectable and weak: branch protection disabled, + private vulnerability reporting disabled, Dependabot security updates + disabled, and public vulnerability alerts not proven enabled. + +Confidence impact: confidence is high for the inspected repository/public +GitHub state because local and public `master` matched and visible GitHub +metadata was queried directly. Confidence remains medium for real production +deployment readiness because several important controls are external, +operator-dependent, or unpublished. + +## What the project appears to be + +Evydence is a self-hosted, API-first release evidence and compliance-readiness +ledger for software product teams. It is meant to collect, verify, link, and +report technical release evidence such as SBOMs, vulnerability scans, VEX +decisions, build provenance, source/deployment evidence, approvals, +exceptions, controls, release bundles, evidence bundles, and customer-safe +packages. + +The likely users are security engineering, AppSec, platform engineering, +release engineering, compliance-readiness, and customer-trust teams at B2B +software companies. The likely operators are teams comfortable running +PostgreSQL, object storage, worker processes, deployment secrets, backup and +restore, release signing, and Kubernetes or Compose environments. + +The README communicates the category, target user, value, limitations, proof +path, and adjacent alternatives within about 30 seconds. It clearly avoids +legal compliance, certification, complete SBOM, authoritative scanner, and +secure-release claims. + +The product shape is broader than a library: + +- Go HTTP API server. +- Worker process. +- Migration command. +- CLI helper. +- PostgreSQL-backed ledger with object storage. +- OpenAPI contract. +- SDK helpers. +- Docker/Compose/Helm deployment assets. +- Release evidence tooling and documentation. + +Implemented behavior is backed by source, tests, migrations, OpenAPI, docs, +examples, release scripts, and public CI. Roadmap and external limitations are +also visible: public release publication, multi-writer API HA, native PKCS#11 +HSM custody, broad object-lock/WORM proof, provider-specific trust review, and +hosted SaaS production are not presented as complete. + +Overall, it appears to be a serious controlled self-hosted production candidate +for a high-trust release-evidence niche, not a toy or generated shell. It is +not yet a broadly adoptable public production project because no public +release artifacts/tags exist and several GitHub security controls remain weak. + +## Production readiness + +Evidence that supports readiness: + +- Clear Go module and process split under `cmd/evydence-api`, + `cmd/evydence-worker`, `cmd/evydence-migrate`, and `cmd/evydence`. +- Domain/application/adapters layout exists under `internal/`. +- API contract is committed as `openapi.yaml` with 152 paths and 166 + operations. +- Makefile defines production-oriented gates including `production-check`, + `release-check`, `coverage-check`, `migration-compatibility-check`, + `black-box-demo-check`, `benchmark-check`, `openapi-check`, + `openapi-precision-check`, `deploy-check`, `sdk-check`, and `docs-check`. +- Latest public CI for `master` succeeded and ran the `Production Check` job + with a PostgreSQL service. +- Production-check script requires live PostgreSQL, release-check, coverage + threshold, migration compatibility, benchmark check, black-box demo check, + and release signing smoke test. +- Production docs explicitly state the current supported profile, one API + writer stance, worker scaling model, unsupported broad production claims, and + operator responsibilities. +- Dockerfile, Docker Compose, production-like Compose, Helm chart, + Kubernetes docs, operations docs, backup/restore runbook, upgrade runbook, + incident runbook, observability assets, and capacity/failure docs exist. +- Release-candidate packaging scripts generate artifacts, checksums, OpenAPI + and migration checksums, coverage output, release-check summary, SBOM and + provenance metadata, signed manifest, signature, and notes. +- The source-controlled security and governance surface is unusually complete + for an early project. + +Evidence that prevents a production-ready verdict: + +- No public releases. +- No public remote tags. +- No visible release-artifacts workflow runs. +- No public immutable binary, archive, image, chart package, package-manager + install path, or signed artifact set. +- Branch protection is disabled on `master`. +- Dependabot security updates are disabled. +- Private vulnerability reporting is disabled. +- Vulnerability alerts are not proven enabled. +- Scorecard is now running, but it produced 20 open code-scanning alerts. +- Production docs still correctly classify the project as a controlled + self-hosted production candidate, not broadly production-ready. +- The supported API production profile is one writer replica. Multi-writer API + HA remains intentionally unsupported. +- KMS/HSM custody, WORM/object-lock enforcement proof, provider-specific trust + behavior, target-environment backup/restore, monitoring, and incident + rehearsal remain operator-dependent. + +Brutal assessment: the local repository and public CI are strong enough for a +controlled pilot by a team willing to inspect and run the system from source. +The public release surface is not good enough for broad production adoption. +For a high-trust evidence ledger, missing release artifacts/tags and disabled +default-branch/security controls are material blockers, not polish. + +Classification: controlled internal pilot / controlled self-hosted production +candidate. + +Score: 6/10. + +## Feature completeness + +Supported use cases backed by repository evidence: + +- Tenant-scoped API keys, users, sessions, collectors, and customer portal + token records. +- Products, projects, releases, release candidates, artifacts, container + images, evidence, evidence lifecycle events, release bundles, evidence + bundles, customer packages, reports, controls, exceptions, approvals, + waivers, incidents, source/deployment records, SBOMs, VEX, vulnerability + scans, decisions, and related metadata. +- PostgreSQL migrations and relational projections. +- Filesystem and S3/MinIO object-store adapters. +- Worker outbox processing and object-store replay paths. +- OpenAPI contract and generated route catalog. +- Go, TypeScript, and Python SDK helper files. +- End-to-end release evidence example and package viewer. +- GitHub Actions and GitLab CI collector examples. +- Release-candidate packaging and release signing commands. +- Docker, Compose, Helm, Kubernetes, air-gap, observability, backup/restore, + upgrade, and incident response documentation. + +Important missing or incomplete table stakes: + +- Public release artifacts and public tags. +- Release-backed quickstart and install path. +- Published immutable container images or an explicitly final binary/source + install stance. +- Multi-writer API HA. +- Native PKCS#11 HSM module integration. +- Broad object-store WORM/object-lock proof across real provider settings. +- Direct provider-specific management API clients and external group sync. +- Public adoption proof, third-party review, or customer/case-study evidence. +- Public production exit review tied to a release artifact set. + +Blockers: + +- Publish a signed public release candidate with tags, artifacts, checksums, + release notes, release evidence, and workflow run. +- Enable branch protection/required checks. +- Enable or deliberately replace GitHub vulnerability alerting and Dependabot + security updates. +- Resolve or triage the open Scorecard code-scanning alerts. + +Nice-to-have gaps: + +- Hosted read-only demo or release-backed downloadable evaluation bundle. +- Screenshots or short walkthrough of package viewer/readiness output. +- Published sizing table tied to release artifacts. +- More opinionated install path for small internal production. + +Maturity classification: productizable system and controlled production +candidate. It is feature-rich enough to solve a real release-evidence problem +for a motivated operator, but not mature enough for broad self-service +production adoption. + +Score: 7/10. + +## Security and open-source trust + +Strong signals: + +- `LICENSE`, `COMMERCIAL.md`, `SECURITY.md`, `CONTRIBUTING.md`, + `GOVERNANCE.md`, `SUPPORT.md`, `TRADEMARKS.md`, `RELEASE_EVIDENCE.md`, + `CODE_OF_CONDUCT.md`, `CODEOWNERS`, issue templates, and PR template exist. +- GitHub community profile reports 100 percent. +- Secret scanning and push protection are enabled. +- Dependabot config exists and open Dependabot PRs are visible. +- Latest public CI for `master` succeeded. +- Public Scorecard workflow now has a successful run on the latest public + `master`. +- Code scanning is receiving Scorecard SARIF results. +- CI uses least-content permissions at workflow level and runs production + checks with PostgreSQL. +- Runtime production checks reject several unsafe defaults. +- Docs are explicit about not posting secrets, raw evidence payloads, private + keys, bearer tokens, database URLs, customer data, or provider credentials. +- Security docs correctly state that repository files alone cannot prove + private vulnerability reporting is enabled. + +Weak signals and risks: + +- `master` branch protection is disabled. +- Dependabot security updates are disabled. +- Private vulnerability reporting is disabled. +- Vulnerability alerts are not proven enabled. +- Scorecard produced 20 open code-scanning alerts. +- Public releases/tags and release assets are absent. +- No public release provenance, signed release artifact set, SBOM/provenance + bundle, package metadata, or immutable image digest exists. +- CODEOWNERS is present but cannot be enforcement evidence without branch + protection or repository rules. +- No public security advisory history exists. That is acceptable for a new + repo, but it means the response process is unproven. + +For this product's risk profile, the weak signals matter. Evydence handles +tenant boundaries, security evidence, release claims, raw payload references, +signing material, customer packages, and compliance-readiness reports. The +public repository should therefore hold itself to a higher standard than a +low-risk developer utility. + +Score: 6/10. + +## Marketability and positioning + +Buyer/adopter assessment: + +- The problem is real and painful: B2B teams need reproducible release evidence + for security/customer review without scattering decisions across CI logs, + object storage, spreadsheets, tickets, and SaaS GRC tools. +- The target user is clear: security, platform, AppSec, release, and + compliance-readiness teams. +- The value proposition is sharper than generic compliance automation: + self-hosted technical evidence ledger, release bundles, audit chains, + customer-safe packages, gaps, assumptions, exceptions, and limitations. +- The README avoids dangerous overclaims and presents the product as a + compliance-readiness and technical evidence system, not a legal/compliance + guarantee. +- The fastest proof path is visible through getting started docs, + production-like Compose, example evidence fixtures, and package viewer. + +Crowding: + +- The surrounding space is crowded: SBOM/vulnerability management, GRC SaaS, + software supply-chain signing/provenance, ASPM, transparency logs, and + in-house evidence scripts. +- Evydence is most compelling when positioned narrowly as a self-hosted + release-evidence ledger and customer-review package generator. + +Demo/evaluation path: + +- The repo contains a credible local demo and sample JSON outputs. +- The demo is still source-checkout oriented because there is no published + release artifact set. +- A skeptical adopter cannot yet download a signed release, verify it, run it, + and compare output to published release evidence. + +Monetization/adoption route: + +- AGPL plus commercial license exception/support language is plausible. +- Deployment review, release evidence packages, custom collectors, integration + support, and control/report templates could be commercial services. +- Adoption is constrained by absent releases, absent tags, weak GitHub + protection/security settings, and no external adoption signal. + +Assessment: positioning has improved since earlier reports. The repo now looks +like a coherent product candidate with a narrow use case. It still needs a +public release-backed proof path before marketability can move from +"interesting" to "credible for adoption." + +Score: 7/10. + +## Differentiation + +Direct alternatives: + +- OWASP Dependency-Track: mature SBOM/component and vulnerability management. + Evydence is differentiated by release-level evidence records, audit chains, + customer packages, readiness reports, approvals/exceptions, and explicit + limitation handling. Dependency-Track remains stronger as a mature SBOM and + vulnerability management platform. +- DefectDojo: mature DevSecOps/vulnerability management workflow. Evydence is + differentiated around release bundles, evidence manifests, customer-safe + packages, and compliance-readiness evidence organization. DefectDojo remains + stronger for security findings program operations. +- GRC SaaS tools such as Vanta and Drata: stronger for broad compliance + management, integrations, and auditor-facing workflows. Evydence is + differentiated by being self-hosted and technical-evidence-first, but it does + not replace legal/auditor review. + +Adjacent alternatives: + +- Sigstore/Rekor: signing and transparency infrastructure. Evydence can record + signing/transparency evidence, but is not a replacement for those trust + roots. +- GUAC: software supply-chain composition and graph analysis. Evydence is + differentiated by release-readiness decisions, approvals, exceptions, + packages, and reports. +- In-house workflows: PostgreSQL/object storage/CI scripts/spreadsheets can + cover parts of the job. Evydence differentiates with a versioned API, + OpenAPI contract, tenant scoping, idempotency, append-only evidence, + checksummed bundles, and conservative no-claim language. + +Meaningful differentiation: + +- Self-hosted release evidence ledger rather than generic GRC. +- Customer-safe evidence package and readiness output model. +- Explicit gap/assumption/exception/limitation handling. +- API-first and OpenAPI-backed. +- Strong product-language guardrails against compliance magic. +- Release evidence tooling is part of the project, not an afterthought. + +Weak differentiation: + +- The public artifact/install story lags the implemented code. +- Existing mature tools already own parts of SBOM, vulnerability workflow, + provenance, signing, and GRC. +- Several high-trust differentiators are still operator-dependent or + not publicly release-backed. + +Score: 7/10. + +## Repository quality checklist + +| Area | Status | Evidence | Severity | Recommended fix | +|------|--------|----------|----------|-----------------| +| README | Strong | Clear problem, target user, current limitations, fastest proof path, alternatives, implementation summary, and validation commands in `README.md`. | Low | Add the latest release link and release-backed quickstart after the first public release. | +| Quickstart | Strong | `docs/tutorials/getting-started.md`, local API commands, production-like Compose docs. | Low | Replace source-checkout-first install guidance with release-verification flow once artifacts exist. | +| Examples/demo | Adequate | `examples/end-to-end-release-evidence`, JSON fixtures, `run-local-demo.sh`, package viewer, demo checks. | Medium | Publish a release-backed demo bundle and add screenshots/sample outputs to the first README screen. | +| Tests | Strong | 219 Go test files, public CI `Production Check` success, project gates for coverage, race, migration, black-box demo, docs, OpenAPI, deployment, SDKs. | Low | Keep expanding negative tests around provider gateways, tenant isolation, signing, object-store mismatch, and parser retries. | +| CI | Adequate | Public CI on `master` succeeded at `6532906`; CI runs `make production-check` with PostgreSQL. | High | Enable branch protection/repository rules requiring CI and reviews before `master` changes. | +| Releases/provenance | Weak | Release scripts and workflow exist; local tags exist; no public releases, remote tags, or Release Artifacts workflow runs. | Blocker | Publish signed public RC tag/release with archives, checksums, OpenAPI/migration checksums, signed manifest, SBOM/provenance metadata, and release notes. | +| Docs/API/config/ops | Strong | `docs/`, `openapi.yaml`, API matrix, operations/runbooks, production-readiness docs, release-validation docs, Kubernetes/air-gap docs. | Low | Reduce duplicated production-status prose over time and keep one canonical current-status source. | +| Docker/deployment | Adequate | Dockerfile, Docker Compose, production-like Compose, Helm chart, Kubernetes docs, observability starter assets. | Medium | Publish immutable images or explicitly make release archives/source checkout the supported install path for the current release line. | +| Security policy | Adequate | `SECURITY.md` exists, secret scanning and push protection enabled, Scorecard run visible. Branch protection, private vulnerability reporting, and Dependabot security updates are disabled; code-scanning alerts are open. | High | Enable private vulnerability reporting, vulnerability alerts/security updates, branch protection, and triage Scorecard alerts. | +| License/contribution/governance | Strong | AGPL license, commercial terms, contribution policy, governance, support, code of conduct, trademark guidance, CODEOWNERS. | Low | Clarify practical CLA/commercial exception workflow before soliciting outside contributors. | +| Changelog/versioning | Adequate | `CHANGELOG.md`, release notes template, local RC tags, release-candidate docs. Public tags/releases absent. | High | Push public tags/releases and align changelog entries with published artifact evidence. | + +## Scorecard + +| Dimension | Score | Notes | +|-----------|------:|-------| +| Production readiness | 6/10 | Public CI and Scorecard now pass, and local production machinery is strong; no public releases/tags, no Release Artifacts runs, no branch protection, and explicit operator-dependent controls keep this below broad production readiness. | +| Feature completeness | 7/10 | Broad implemented release-evidence workflow, API, migrations, docs, examples, SDKs, deployment assets, and release tooling; gaps remain in public install path, multi-writer HA, native HSM/WORM/provider proof, and release publication. | +| Security and open-source trust | 6/10 | Security docs, community files, Dependabot config, secret scanning, push protection, CI, and Scorecard are visible; branch protection, private vulnerability reporting, Dependabot security updates, public releases, and Scorecard alert triage remain weak. | +| Marketability and positioning | 7/10 | Clear niche, target user, demo path, and conservative claims; adoption credibility is constrained by no release-backed install path and no external adoption proof. | +| Differentiation | 7/10 | Meaningfully differentiated as a self-hosted release evidence ledger with customer packages and no-claim readiness language; still overlaps with mature SBOM, vulnerability, GRC, and supply-chain tools. | +| Repository evidence quality | 8/10 | Strong repository evidence: code, tests, OpenAPI, migrations, workflows, docs, deployment assets, examples, SDKs, runbooks, and public CI. Missing public releases/provenance is the major evidence category gap. | +| Overall | 6/10 | Serious and productizable, but strict public production-readiness remains capped by absent release artifacts/tags and weak GitHub protection/security settings for a high-trust project. | + +Confidence: medium + +Verdict: Promising but not production-ready + +Direct answers: + +- Is it mature and high-grade enough for production for most intended uses? + No. It may be usable for controlled self-hosted evaluation, pilots, or + carefully reviewed internal production, but not most intended production uses. +- Is it feature-complete enough to solve a real-world problem? Partly yes. The + core release evidence workflow is substantial enough to evaluate and pilot, + but public install/release trust and several production controls remain + incomplete. +- Is it marketable or interesting enough to attract users, buyers, + contributors, or commercial opportunity? Yes, but only after release-backed + install and public trust controls are cleaned up. +- Is it worth continuing, hardening, repositioning, or abandoning? Continue and + harden. The product is worth continuing; the next work should prioritize + public release trust and GitHub security posture over feature breadth. + +## Highest-leverage next steps + +Next 1-2 days: + +- Publish the first public release candidate. Push a fresh public tag such as + `v0.1.0-rc.4` or intentionally publish the current RC line, run the Release + Artifacts workflow, and attach signed archives, `SHA256SUMS`, + `openapi.sha256`, `migrations.sha256`, coverage output, production-check + summary, SBOM/provenance metadata, signed manifest, manifest signature, and + release notes. This removes the largest blocker. +- Enable branch protection or repository rules for `master`. Require the CI + production-check before merge, require review where feasible, prevent force + pushes, and make CODEOWNERS meaningful. +- Enable private vulnerability reporting, vulnerability alerts, and Dependabot + security updates. Current visible settings are too weak for this product's + risk profile. +- Triage the 20 open Scorecard code-scanning alerts. Branch protection, + pinned dependencies, token permissions, SAST, security policy, and + vulnerability signals are now publicly visible as open findings. +- Update README and getting-started docs after the release so the first install + path is release verification rather than source checkout. + +Next 1-2 weeks: + +- Make the evaluation path release-backed end to end: download release, verify + signature/checksums, run Compose or Helm with explicit image/binary source, + execute the end-to-end evidence demo, and inspect the readiness/customer + package output. +- Decide whether to publish immutable container images or explicitly defer + images and support only release archives/source checkout for the current + line. Update Helm and Compose docs accordingly. +- Produce a release-tied public evidence index with links to CI run, + production-check summary, OpenAPI checksum, migration checksum, coverage + report, release manifest, signature, SBOM/provenance metadata, and notes. +- Reduce duplicated production-status prose across docs so current status, + supported profile, and limitations have one canonical source. +- Add a short product demo artifact: screenshot or rendered sample of release + readiness, audit-chain verification, and customer package manifest. + +Next 1-2 months: + +- Complete a fresh production exit review after public release artifacts, + branch protections, vulnerability reporting, and security updates are enabled. +- Either keep the one-writer API model as the explicitly supported profile with + sizing guidance, or design and implement reviewed multi-writer API + concurrency. +- Harden provider-dependent trust profiles: KMS/HSM custody, object-lock/WORM + verification, provider validation gateways, transparency proof retrieval, + and SSO/group behavior with explicit tests and operator docs. +- Build public adoption evidence: a supported pilot walkthrough, issue labels, + support workflow, release cadence, and, when real users exist, case studies + or third-party review. +- Keep adding production-grade negative tests around tenant isolation, + credential revocation, idempotency conflicts, parser retries, digest + mismatches, signing failures, and report/package redaction. + +## README/product-page rewrite advice + +Sharper one-sentence pitch: + +Evydence is a self-hosted release evidence ledger for B2B software teams that +need reproducible SBOM, vulnerability, approval, exception, deployment, and +customer-review evidence without handing technical trust data to a SaaS GRC +platform. + +Target user: + +Security, AppSec, platform, release, and compliance-readiness teams operating +self-hosted release infrastructure for customer-facing software. + +Core use case to show first: + +Before release, collect SBOM, vulnerability scan, VEX decision, build/source, +approval, exception, artifact, and deployment evidence; generate a +release-readiness report; verify the audit chain; and export a customer-safe +evidence package that states gaps, assumptions, and limitations. + +Best demo/example to show first: + +Use the end-to-end release evidence example and package viewer, but make them +release-backed. The first proof should be "download this signed RC, verify it, +run this Compose flow, inspect these JSON outputs." + +Proof points to add: + +- Latest public release link. +- Signed artifact manifest and manifest signature. +- `SHA256SUMS`, OpenAPI checksum, migration checksum. +- Public CI production-check run linked to the release commit. +- Coverage threshold result. +- Scorecard result and triage status. +- Supported production profile table. + +What to remove or de-emphasize: + +- Shorten long lists of implemented resource families in the README after the + release-backed demo is available. +- Keep detailed production caveats in canonical docs instead of repeating them + in many places. +- Do not add more broad feature claims until public release/install trust is + fixed. + +## Residual risk and uncertainty + +Untested during this audit: + +- I did not run `make production-check`, `make release-check`, + `make test-race`, `make gosec`, `make vuln`, or + `make release-candidate-check` locally. +- I did not perform a manual API black-box run, backup/restore rehearsal, Helm + install, container build, S3/MinIO object-lock test, KMS/HSM signing test, + OIDC/SAML provider test, or transparency provider test. +- I did not inspect private repository rulesets, secret values, package + registry settings, production deployments, monitoring systems, backup + storage, or real customer/adoption data. + +Claims still documented or operator-dependent: + +- Native PKCS#11/HSM module custody is not proven by repository evidence. +- Broad WORM/object-lock enforcement depends on provider configuration and + operator evidence. +- Direct provider-specific management API trust and external group + synchronization are not broadly implemented. +- Multi-writer API HA is explicitly unsupported. +- Hosted SaaS production is out of scope. +- Target-environment backup/restore, incident response, monitoring, capacity, + and security operations must be proven by each operator. + +Evidence that would raise confidence: + +- Public signed release artifacts and public tags. +- Public Release Artifacts workflow run tied to a release. +- Branch protection and required checks enabled for `master`. +- Private vulnerability reporting, vulnerability alerts, and Dependabot + security updates enabled. +- Scorecard alerts triaged or resolved. +- Published immutable container images or a deliberate non-image install + stance. +- Release-backed production-check summary, coverage report, OpenAPI checksum, + migration checksum, SBOM/provenance metadata, and release notes. +- Fresh production exit review after the above public evidence exists. diff --git a/Dockerfile b/Dockerfile index d20364d..121dcba 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.25-alpine AS build +FROM golang:1.25-alpine@sha256:8d22e29d960bc50cd025d93d5b7c7d220b1ee9aa7a239b3c8f55a57e987e8d45 AS build WORKDIR /src COPY go.mod go.sum ./ RUN go mod download @@ -8,7 +8,7 @@ RUN go build -o /out/evydence-migrate ./cmd/evydence-migrate RUN go build -o /out/evydence-worker ./cmd/evydence-worker RUN go build -o /out/evydence ./cmd/evydence -FROM alpine:3.22 +FROM alpine:3.22@sha256:310c62b5e7ca5b08167e4384c68db0fd2905dd9c7493756d356e893909057601 RUN addgroup -S evydence && adduser -S -G evydence evydence USER evydence WORKDIR /app diff --git a/Makefile b/Makefile index 07835ff..bb709a1 100644 --- a/Makefile +++ b/Makefile @@ -70,6 +70,7 @@ meta-check: ## Validate root legal, governance, support, and release-evidence me @test -f .dockerignore @test -f .github/dependabot.yml @test -f .github/workflows/scorecard.yml + @test -f .github/workflows/codeql.yml @test -f .github/ISSUE_TEMPLATE.md @test -f .github/ISSUE_TEMPLATE/bug_report.yml @test -f .github/ISSUE_TEMPLATE/feature_request.yml @@ -92,6 +93,11 @@ meta-check: ## Validate root legal, governance, support, and release-evidence me @grep -F 'internal/app/' CODEOWNERS >/dev/null @grep -F 'docs/reference/release-evidence-index.md' CODEOWNERS >/dev/null @grep -F 'OpenSSF Scorecard' .github/workflows/scorecard.yml >/dev/null + @grep -F 'github/codeql-action/analyze@fee9466b8957867761f2d78f922ab084e3e2dd17' .github/workflows/codeql.yml >/dev/null + @grep -F 'actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd' .github/workflows/ci.yml >/dev/null + @grep -F 'actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c' .github/workflows/ci.yml >/dev/null + @grep -F 'actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a' .github/workflows/ci.yml >/dev/null + @grep -F 'postgres:16-alpine@sha256:16bc17c64a573ef34162af9298258d1aec548232985b33ed7b1eac33ba35c229' .github/workflows/ci.yml >/dev/null @grep -F 'Evydence fork' TRADEMARKS.md >/dev/null @grep -F 'Release evidence is not a certification' RELEASE_EVIDENCE.md >/dev/null @grep -F '.refs' .dockerignore >/dev/null @@ -136,6 +142,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @test -f docs/github-actions/upload-build/action.yml @test -f docs/gitlab/evydence-release-evidence.gitlab-ci.yml @test -f .github/workflows/release-artifacts.yml + @test -f .github/workflows/codeql.yml @test -f docs/sdk/README.md @for path in \ "tutorials/getting-started.md" \ @@ -198,6 +205,9 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'scripts/release_candidate_package.sh' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'evydence-release-manifest.sig.json' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'gh release create' .github/workflows/release-artifacts.yml >/dev/null + @grep -F 'contents: read' .github/workflows/release-artifacts.yml >/dev/null + @grep -F 'github/codeql-action/init@fee9466b8957867761f2d78f922ab084e3e2dd17' .github/workflows/codeql.yml >/dev/null + @grep -F 'security-and-quality' .github/workflows/codeql.yml >/dev/null @grep -F 'Controlled self-hosted production candidate' docs/reference/release-candidate.md >/dev/null @grep -F 'Release evidence index' docs/reference/release-candidate.md >/dev/null @grep -F 'evydence-release-manifest.sig.json' docs/reference/release-evidence-index.md >/dev/null diff --git a/SECURITY.md b/SECURITY.md index b678442..c5bc35d 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -10,10 +10,11 @@ object storage, reports, exports, and release evidence. If you believe you found a vulnerability, use GitHub private vulnerability reporting for this repository when the "Report a vulnerability" button is -available on GitHub. If the button is unavailable for your account or region, -use the private security intake channel listed for the current release notes or -request a private channel from the maintainer without including vulnerability -details in the first contact. +available on GitHub. The expected intake URL is +. If the button or +URL is unavailable for your account or region, use the private security intake +channel listed for the current release notes or request a private channel from +the maintainer without including vulnerability details in the first contact. The repository file cannot itself prove that GitHub private vulnerability reporting or a dedicated mailbox is enabled; that is an operator setting that diff --git a/docs/reference/maintainer-review-policy.md b/docs/reference/maintainer-review-policy.md index 3c09316..819694d 100644 --- a/docs/reference/maintainer-review-policy.md +++ b/docs/reference/maintainer-review-policy.md @@ -75,3 +75,8 @@ make release-candidate-check TAG= Those stronger commands require live PostgreSQL and release signing material; skips or unavailable external dependencies must be recorded in release notes or the release evidence index. + +Repository CI and SAST workflows should keep third-party Actions pinned by +commit SHA and service/container images pinned by digest. If an Action or image +pin is updated, reviewers should verify the upstream tag or digest source and +record the reason in the pull request or release evidence. diff --git a/docs/reference/release-validation.md b/docs/reference/release-validation.md index ad960c6..633c954 100644 --- a/docs/reference/release-validation.md +++ b/docs/reference/release-validation.md @@ -128,6 +128,11 @@ production-check release manifest/signature smoke artifacts as build artifacts. The database must not contain production evidence, customer package tokens, signing-key material, or other real secrets. +GitHub Actions and service container dependencies are pinned by commit SHA or +image digest in the checked CI workflows. The repository also runs a CodeQL +workflow with the `security-and-quality` query suite so SAST results are +published through GitHub code scanning when that service is available. + ## Signed Release Artifact Workflow The checked-in `.github/workflows/release-artifacts.yml` workflow calls the diff --git a/go.mod b/go.mod index 418b322..dc75308 100644 --- a/go.mod +++ b/go.mod @@ -4,13 +4,15 @@ go 1.25.10 require ( github.com/aatuh/api-toolkit/v3 v3.1.2 + github.com/aws/aws-sdk-go-v2/config v1.32.20 + github.com/aws/aws-sdk-go-v2/service/kms v1.52.2 github.com/getkin/kin-openapi v0.133.0 github.com/jackc/pgx/v5 v5.9.2 + github.com/minio/minio-go/v7 v7.2.0 ) require ( github.com/aws/aws-sdk-go-v2 v1.41.9 // indirect - github.com/aws/aws-sdk-go-v2/config v1.32.20 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.19.19 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.25 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.25 // indirect @@ -18,7 +20,6 @@ require ( github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.26 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.10 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.25 // indirect - github.com/aws/aws-sdk-go-v2/service/kms v1.52.2 // indirect github.com/aws/aws-sdk-go-v2/service/signin v1.1.1 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.30.19 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.36.2 // indirect @@ -39,7 +40,6 @@ require ( github.com/mailru/easyjson v0.7.7 // indirect github.com/minio/crc64nvme v1.1.1 // indirect github.com/minio/md5-simd v1.1.2 // indirect - github.com/minio/minio-go/v7 v7.2.0 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect @@ -50,10 +50,10 @@ require ( github.com/woodsbury/decimal128 v1.3.0 // indirect github.com/zeebo/xxh3 v1.1.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.51.0 // indirect - golang.org/x/net v0.53.0 // indirect + golang.org/x/crypto v0.52.0 // indirect + golang.org/x/net v0.55.0 // indirect golang.org/x/sync v0.20.0 // indirect - golang.org/x/sys v0.44.0 // indirect + golang.org/x/sys v0.45.0 // indirect golang.org/x/text v0.37.0 // indirect gopkg.in/ini.v1 v1.67.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 64bf869..bdfd2e7 100644 --- a/go.sum +++ b/go.sum @@ -88,9 +88,8 @@ github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM= github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -110,22 +109,20 @@ github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0 github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= +github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI= -golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8= -golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= -golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= -golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= -golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= +golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= +golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= +golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= -golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ= -golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= -golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= +golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/scripts/release_acceptance.sh b/scripts/release_acceptance.sh index 16446d3..edc25da 100755 --- a/scripts/release_acceptance.sh +++ b/scripts/release_acceptance.sh @@ -46,6 +46,7 @@ for file in \ .dockerignore \ .github/ISSUE_TEMPLATE.md \ .github/pull_request_template.md \ + .github/workflows/codeql.yml \ README.md \ docs/README.md \ docs/reference/release-candidate.md \ @@ -74,6 +75,11 @@ require_text .github/pull_request_template.md "tenant isolation" require_text .github/pull_request_template.md "Sensitive Data Check" require_text CODEOWNERS "internal/app/" require_text CODEOWNERS "docs/reference/release-evidence-index.md" +require_text .github/workflows/codeql.yml "github/codeql-action/analyze@fee9466b8957867761f2d78f922ab084e3e2dd17" +require_text .github/workflows/codeql.yml "security-and-quality" +require_text .github/workflows/ci.yml "actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd" +require_text .github/workflows/release-artifacts.yml "contents: read" +require_text .github/workflows/scorecard.yml "ossf/scorecard-action@ff5dd8929f96a8a4dc67d13f32b8c75057829621" require_text SUPPORT.md "sanitized logs" require_text SUPPORT.md "release evidence artifacts" require_text TRADEMARKS.md "Evydence fork" From 94e9e23b0220fcb2fd46ae233de447bf2fbb3254 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 19:39:03 +0300 Subject: [PATCH 157/287] chore: fix scorecard pinned action commit --- .github/workflows/scorecard.yml | 2 +- .production_readiness_v4.md | 9 ++++++++- Makefile | 1 + scripts/release_acceptance.sh | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 1bee3f8..f405372 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -24,7 +24,7 @@ jobs: persist-credentials: false - name: Run OpenSSF Scorecard - uses: ossf/scorecard-action@ff5dd8929f96a8a4dc67d13f32b8c75057829621 # v2.4.0 + uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 with: results_file: scorecard-results.sarif results_format: sarif diff --git a/.production_readiness_v4.md b/.production_readiness_v4.md index d1bd6e5..456a59d 100644 --- a/.production_readiness_v4.md +++ b/.production_readiness_v4.md @@ -16,12 +16,19 @@ Repository-local remediation from the v4 audit: - [x] Strengthen `SECURITY.md` with a direct GitHub Security Advisory intake link while still stating that private vulnerability reporting must be verified as a GitHub setting. - [x] Update dependency versions flagged by `govulncheck -show verbose` for non-called module/package vulnerabilities in `golang.org/x/crypto` and `golang.org/x/net`. - [x] Wire the new workflow and pinning expectations into `make meta-check`, `make docs-check`, `make release-acceptance`, and release/review documentation. +- [x] Correct the OpenSSF Scorecard action pin from the annotated tag object to the peeled `v2.4.0` commit so GitHub workflow verification accepts the pinned dependency. + +External repository settings completed through GitHub APIs: + +- [x] Enable GitHub private vulnerability reporting for the public repository. +- [x] Enable GitHub vulnerability alerts for the public repository. +- [x] Enable GitHub automated security fixes for Dependabot-managed vulnerability remediation. External or operator-dependent remediation from the v4 audit: - [e] Publish a signed public release candidate/tag with release archives, `SHA256SUMS`, OpenAPI checksum, migration checksum, coverage output, production-check summary, SBOM/provenance metadata, signed release manifest, release notes, and a public Release Artifacts workflow run. - [e] Enable branch protection or repository rules for `master`, including required checks, review requirements, force-push prevention, and CODEOWNERS enforcement. -- [e] Enable or verify GitHub private vulnerability reporting, vulnerability alerts, Dependabot security updates, and any desired code-scanning/security-alert settings. +- [e] Configure additional account-level code-scanning/security-alert policy beyond the repository-local CodeQL and Scorecard workflows where the GitHub organization or operator requires it. - [e] Configure and verify release signing secrets for GitHub Actions and any package/container registry credentials. - [e] Publish immutable container images or document a final decision that release archives/source checkout are the only supported install path for the current release line. - [e] Close or dismiss GitHub code-scanning alerts that require account-level controls, historical/adoption evidence, or GitHub rescanning state after the repository fixes are pushed. diff --git a/Makefile b/Makefile index bb709a1..0619f1d 100644 --- a/Makefile +++ b/Makefile @@ -93,6 +93,7 @@ meta-check: ## Validate root legal, governance, support, and release-evidence me @grep -F 'internal/app/' CODEOWNERS >/dev/null @grep -F 'docs/reference/release-evidence-index.md' CODEOWNERS >/dev/null @grep -F 'OpenSSF Scorecard' .github/workflows/scorecard.yml >/dev/null + @grep -F 'ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46' .github/workflows/scorecard.yml >/dev/null @grep -F 'github/codeql-action/analyze@fee9466b8957867761f2d78f922ab084e3e2dd17' .github/workflows/codeql.yml >/dev/null @grep -F 'actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd' .github/workflows/ci.yml >/dev/null @grep -F 'actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c' .github/workflows/ci.yml >/dev/null diff --git a/scripts/release_acceptance.sh b/scripts/release_acceptance.sh index edc25da..38cc0af 100755 --- a/scripts/release_acceptance.sh +++ b/scripts/release_acceptance.sh @@ -79,7 +79,7 @@ require_text .github/workflows/codeql.yml "github/codeql-action/analyze@fee9466b require_text .github/workflows/codeql.yml "security-and-quality" require_text .github/workflows/ci.yml "actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd" require_text .github/workflows/release-artifacts.yml "contents: read" -require_text .github/workflows/scorecard.yml "ossf/scorecard-action@ff5dd8929f96a8a4dc67d13f32b8c75057829621" +require_text .github/workflows/scorecard.yml "ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46" require_text SUPPORT.md "sanitized logs" require_text SUPPORT.md "release evidence artifacts" require_text TRADEMARKS.md "Evydence fork" From 5a5d3a174e8a21c2538c46c0287d94c98ec1bbd4 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 19:42:32 +0300 Subject: [PATCH 158/287] ci: split scorecard publication and sarif upload --- .github/workflows/scorecard-sarif.yml | 34 +++++++++++++++++++++++++++ .github/workflows/scorecard.yml | 6 ----- .production_readiness_v4.md | 2 +- Makefile | 3 +++ scripts/release_acceptance.sh | 3 +++ 5 files changed, 41 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/scorecard-sarif.yml diff --git a/.github/workflows/scorecard-sarif.yml b/.github/workflows/scorecard-sarif.yml new file mode 100644 index 0000000..c36d0fc --- /dev/null +++ b/.github/workflows/scorecard-sarif.yml @@ -0,0 +1,34 @@ +name: OpenSSF Scorecard SARIF + +on: + schedule: + - cron: "43 3 * * 1" + workflow_dispatch: + +permissions: + contents: read + +jobs: + scorecard-sarif: + name: Scorecard SARIF + runs-on: ubuntu-latest + permissions: + contents: read + security-events: write + steps: + - name: Check out repository + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + with: + persist-credentials: false + + - name: Run OpenSSF Scorecard + uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 + with: + results_file: scorecard-results.sarif + results_format: sarif + publish_results: false + + - name: Upload SARIF + uses: github/codeql-action/upload-sarif@fee9466b8957867761f2d78f922ab084e3e2dd17 # v3 + with: + sarif_file: scorecard-results.sarif diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index f405372..003762c 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -16,7 +16,6 @@ jobs: permissions: contents: read id-token: write - security-events: write steps: - name: Check out repository uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 @@ -29,8 +28,3 @@ jobs: results_file: scorecard-results.sarif results_format: sarif publish_results: true - - - name: Upload SARIF - uses: github/codeql-action/upload-sarif@fee9466b8957867761f2d78f922ab084e3e2dd17 # v3 - with: - sarif_file: scorecard-results.sarif diff --git a/.production_readiness_v4.md b/.production_readiness_v4.md index 456a59d..7fefde4 100644 --- a/.production_readiness_v4.md +++ b/.production_readiness_v4.md @@ -16,7 +16,7 @@ Repository-local remediation from the v4 audit: - [x] Strengthen `SECURITY.md` with a direct GitHub Security Advisory intake link while still stating that private vulnerability reporting must be verified as a GitHub setting. - [x] Update dependency versions flagged by `govulncheck -show verbose` for non-called module/package vulnerabilities in `golang.org/x/crypto` and `golang.org/x/net`. - [x] Wire the new workflow and pinning expectations into `make meta-check`, `make docs-check`, `make release-acceptance`, and release/review documentation. -- [x] Correct the OpenSSF Scorecard action pin from the annotated tag object to the peeled `v2.4.0` commit so GitHub workflow verification accepts the pinned dependency. +- [x] Correct the OpenSSF Scorecard action pin from the annotated tag object to the peeled `v2.4.0` commit, then split Scorecard publication from SARIF upload so both workflows can keep pinned dependencies and pass their respective verification paths. External repository settings completed through GitHub APIs: diff --git a/Makefile b/Makefile index 0619f1d..32e15a1 100644 --- a/Makefile +++ b/Makefile @@ -94,6 +94,9 @@ meta-check: ## Validate root legal, governance, support, and release-evidence me @grep -F 'docs/reference/release-evidence-index.md' CODEOWNERS >/dev/null @grep -F 'OpenSSF Scorecard' .github/workflows/scorecard.yml >/dev/null @grep -F 'ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46' .github/workflows/scorecard.yml >/dev/null + @grep -F 'OpenSSF Scorecard SARIF' .github/workflows/scorecard-sarif.yml >/dev/null + @grep -F 'ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46' .github/workflows/scorecard-sarif.yml >/dev/null + @grep -F 'github/codeql-action/upload-sarif@fee9466b8957867761f2d78f922ab084e3e2dd17' .github/workflows/scorecard-sarif.yml >/dev/null @grep -F 'github/codeql-action/analyze@fee9466b8957867761f2d78f922ab084e3e2dd17' .github/workflows/codeql.yml >/dev/null @grep -F 'actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd' .github/workflows/ci.yml >/dev/null @grep -F 'actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c' .github/workflows/ci.yml >/dev/null diff --git a/scripts/release_acceptance.sh b/scripts/release_acceptance.sh index 38cc0af..2c7a24a 100755 --- a/scripts/release_acceptance.sh +++ b/scripts/release_acceptance.sh @@ -80,6 +80,9 @@ require_text .github/workflows/codeql.yml "security-and-quality" require_text .github/workflows/ci.yml "actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd" require_text .github/workflows/release-artifacts.yml "contents: read" require_text .github/workflows/scorecard.yml "ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46" +require_text .github/workflows/scorecard.yml "publish_results: true" +require_text .github/workflows/scorecard-sarif.yml "publish_results: false" +require_text .github/workflows/scorecard-sarif.yml "github/codeql-action/upload-sarif@fee9466b8957867761f2d78f922ab084e3e2dd17" require_text SUPPORT.md "sanitized logs" require_text SUPPORT.md "release evidence artifacts" require_text TRADEMARKS.md "Evydence fork" From 9e2bdf50fb6978e040611b21ed3b189fabb68ce1 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 19:47:09 +0300 Subject: [PATCH 159/287] security: document content digest hashing --- .production_readiness_v4.md | 2 ++ internal/app/ledger_helpers.go | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.production_readiness_v4.md b/.production_readiness_v4.md index 7fefde4..63fdf1d 100644 --- a/.production_readiness_v4.md +++ b/.production_readiness_v4.md @@ -17,6 +17,8 @@ Repository-local remediation from the v4 audit: - [x] Update dependency versions flagged by `govulncheck -show verbose` for non-called module/package vulnerabilities in `golang.org/x/crypto` and `golang.org/x/net`. - [x] Wire the new workflow and pinning expectations into `make meta-check`, `make docs-check`, `make release-acceptance`, and release/review documentation. - [x] Correct the OpenSSF Scorecard action pin from the annotated tag object to the peeled `v2.4.0` commit, then split Scorecard publication from SARIF upload so both workflows can keep pinned dependencies and pass their respective verification paths. +- [x] Adjudicate the CodeQL `go/weak-sensitive-data-hashing` finding on `hashBytes` as content-digest usage, with inline suppression and existing HMAC-based secret-hash tests covering API/session/portal secret storage separately. +- [x] Verify public CI, CodeQL, OpenSSF Scorecard publication, and OpenSSF Scorecard SARIF upload on the hardened public commit. External repository settings completed through GitHub APIs: diff --git a/internal/app/ledger_helpers.go b/internal/app/ledger_helpers.go index 4abd8ef..c3aa695 100644 --- a/internal/app/ledger_helpers.go +++ b/internal/app/ledger_helpers.go @@ -77,6 +77,8 @@ func canonicalAnyHash(v any) (string, error) { } func hashBytes(body []byte) string { + // codeql[go/weak-sensitive-data-hashing] SHA-256 is required here for + // content-addressed evidence digests, not password or bearer-token storage. sum := sha256.Sum256(body) return "sha256:" + hex.EncodeToString(sum[:]) } From 1c8b6fbdce415ac9e9e67d4b32582536faa7593b Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 19:53:10 +0300 Subject: [PATCH 160/287] docs: track final readiness remediations --- .production_readiness_v4.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.production_readiness_v4.md b/.production_readiness_v4.md index 63fdf1d..bccb75d 100644 --- a/.production_readiness_v4.md +++ b/.production_readiness_v4.md @@ -18,6 +18,7 @@ Repository-local remediation from the v4 audit: - [x] Wire the new workflow and pinning expectations into `make meta-check`, `make docs-check`, `make release-acceptance`, and release/review documentation. - [x] Correct the OpenSSF Scorecard action pin from the annotated tag object to the peeled `v2.4.0` commit, then split Scorecard publication from SARIF upload so both workflows can keep pinned dependencies and pass their respective verification paths. - [x] Adjudicate the CodeQL `go/weak-sensitive-data-hashing` finding on `hashBytes` as content-digest usage, with inline suppression and existing HMAC-based secret-hash tests covering API/session/portal secret storage separately. +- [x] Dismiss GitHub code-scanning alert 21 as a false positive with the content-digest rationale and HMAC secret-storage evidence. - [x] Verify public CI, CodeQL, OpenSSF Scorecard publication, and OpenSSF Scorecard SARIF upload on the hardened public commit. External repository settings completed through GitHub APIs: @@ -25,11 +26,11 @@ External repository settings completed through GitHub APIs: - [x] Enable GitHub private vulnerability reporting for the public repository. - [x] Enable GitHub vulnerability alerts for the public repository. - [x] Enable GitHub automated security fixes for Dependabot-managed vulnerability remediation. +- [x] Enable branch protection for `master` with required `Production Check` and `CodeQL Analyze` checks, required pull-request review, CODEOWNERS review, linear history, conversation resolution, and force-push/deletion prevention. External or operator-dependent remediation from the v4 audit: - [e] Publish a signed public release candidate/tag with release archives, `SHA256SUMS`, OpenAPI checksum, migration checksum, coverage output, production-check summary, SBOM/provenance metadata, signed release manifest, release notes, and a public Release Artifacts workflow run. -- [e] Enable branch protection or repository rules for `master`, including required checks, review requirements, force-push prevention, and CODEOWNERS enforcement. - [e] Configure additional account-level code-scanning/security-alert policy beyond the repository-local CodeQL and Scorecard workflows where the GitHub organization or operator requires it. - [e] Configure and verify release signing secrets for GitHub Actions and any package/container registry credentials. - [e] Publish immutable container images or document a final decision that release archives/source checkout are the only supported install path for the current release line. From e3d2bb58c75c95b5a59dc7d8cc2372639453b1f2 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 19:59:07 +0300 Subject: [PATCH 161/287] test: add digest fuzz smoke targets --- .production_readiness_v4.md | 1 + Makefile | 6 ++++- internal/app/fuzz_test.go | 48 +++++++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 internal/app/fuzz_test.go diff --git a/.production_readiness_v4.md b/.production_readiness_v4.md index bccb75d..53dc45d 100644 --- a/.production_readiness_v4.md +++ b/.production_readiness_v4.md @@ -19,6 +19,7 @@ Repository-local remediation from the v4 audit: - [x] Correct the OpenSSF Scorecard action pin from the annotated tag object to the peeled `v2.4.0` commit, then split Scorecard publication from SARIF upload so both workflows can keep pinned dependencies and pass their respective verification paths. - [x] Adjudicate the CodeQL `go/weak-sensitive-data-hashing` finding on `hashBytes` as content-digest usage, with inline suppression and existing HMAC-based secret-hash tests covering API/session/portal secret storage separately. - [x] Dismiss GitHub code-scanning alert 21 as a false positive with the content-digest rationale and HMAC secret-storage evidence. +- [x] Add native Go fuzz targets for digest validation and content hashing, and wire their seed corpus into `make fuzz-smoke` / `make fast-check`. - [x] Verify public CI, CodeQL, OpenSSF Scorecard publication, and OpenSSF Scorecard SARIF upload on the hardened public commit. External repository settings completed through GitHub APIs: diff --git a/Makefile b/Makefile index 32e15a1..8ecfd5f 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ GOVULNCHECK_VERSION ?= v1.2.0 TAG ?= -.PHONY: help tools fmt lint vuln gosec test test-race coverage coverage-check openapi-check openapi-precision-check meta-check docs-check deploy-check sdk-check demo-check black-box-demo-check benchmark-check package-viewer-check fast-check finalize release-acceptance release-check production-check release-candidate-check migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean +.PHONY: help tools fmt lint vuln gosec test test-race fuzz-smoke coverage coverage-check openapi-check openapi-precision-check meta-check docs-check deploy-check sdk-check demo-check black-box-demo-check benchmark-check package-viewer-check fast-check finalize release-acceptance release-check production-check release-candidate-check migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean help: ## Show help @awk 'BEGIN {FS=":.*## "}; /^[a-zA-Z0-9_.-]+:.*## / { printf " %-18s %s\n", $$1, $$2 }' $(MAKEFILE_LIST) @@ -34,6 +34,9 @@ gosec: ## Run gosec when installed test: ## Run unit tests @$(GO) test ./... +fuzz-smoke: ## Run Go fuzz target seed corpora without a fuzzing campaign + @$(GO) test ./internal/app -run '^Fuzz' + test-race: ## Run race tests @$(GO) test ./... -race -count=1 @@ -291,6 +294,7 @@ package-viewer-check: ## Validate local package viewer and walkthrough fast-check: ## Run non-mutating fast validation @$(MAKE) test + @$(MAKE) fuzz-smoke @$(MAKE) openapi-check @$(MAKE) openapi-precision-check @$(MAKE) docs-check diff --git a/internal/app/fuzz_test.go b/internal/app/fuzz_test.go new file mode 100644 index 0000000..2e19d7b --- /dev/null +++ b/internal/app/fuzz_test.go @@ -0,0 +1,48 @@ +package app + +import ( + "encoding/hex" + "strings" + "testing" +) + +func FuzzValidDigest(f *testing.F) { + f.Add("") + f.Add("sha256:") + f.Add("sha256:" + strings.Repeat("0", 64)) + f.Add("sha256:" + strings.Repeat("g", 64)) + f.Add("md5:" + strings.Repeat("0", 32)) + + f.Fuzz(func(t *testing.T, value string) { + got := validDigest(value) + if !got { + return + } + if !strings.HasPrefix(value, "sha256:") { + t.Fatalf("valid digest without sha256 prefix: %q", value) + } + digest := strings.TrimPrefix(value, "sha256:") + if len(digest) != 64 { + t.Fatalf("valid digest with length %d", len(digest)) + } + decoded, err := hex.DecodeString(digest) + if err != nil { + t.Fatalf("valid digest did not decode: %v", err) + } + if len(decoded) != 32 { + t.Fatalf("valid digest decoded to %d bytes", len(decoded)) + } + }) +} + +func FuzzHashBytesProducesValidDigest(f *testing.F) { + f.Add([]byte("")) + f.Add([]byte("release-evidence")) + f.Add([]byte(`{"password":"not-a-secret-hash-input","payload":"content"}`)) + + f.Fuzz(func(t *testing.T, body []byte) { + if digest := hashBytes(body); !validDigest(digest) { + t.Fatalf("hashBytes produced invalid digest: %q", digest) + } + }) +} From 0d05221fa5bc872620d080995730c48c77a6f3c8 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 20:04:57 +0300 Subject: [PATCH 162/287] docs: mark external scorecard signals --- .production_readiness_v4.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.production_readiness_v4.md b/.production_readiness_v4.md index 53dc45d..e481d46 100644 --- a/.production_readiness_v4.md +++ b/.production_readiness_v4.md @@ -28,6 +28,7 @@ External repository settings completed through GitHub APIs: - [x] Enable GitHub vulnerability alerts for the public repository. - [x] Enable GitHub automated security fixes for Dependabot-managed vulnerability remediation. - [x] Enable branch protection for `master` with required `Production Check` and `CodeQL Analyze` checks, required pull-request review, CODEOWNERS review, linear history, conversation resolution, and force-push/deletion prevention. +- [x] Dismiss remaining external/non-repo-local Scorecard code-scanning alerts with comments: repository age (`MaintainedID`), historical PR-review evidence (`CodeReviewID`), and external CII Best Practices registration (`CIIBestPracticesID`). External or operator-dependent remediation from the v4 audit: @@ -35,7 +36,7 @@ External or operator-dependent remediation from the v4 audit: - [e] Configure additional account-level code-scanning/security-alert policy beyond the repository-local CodeQL and Scorecard workflows where the GitHub organization or operator requires it. - [e] Configure and verify release signing secrets for GitHub Actions and any package/container registry credentials. - [e] Publish immutable container images or document a final decision that release archives/source checkout are the only supported install path for the current release line. -- [e] Close or dismiss GitHub code-scanning alerts that require account-level controls, historical/adoption evidence, or GitHub rescanning state after the repository fixes are pushed. +- [e] Accumulate long-lived maintenance history, real merged pull-request review history, and external CII Best Practices project registration/badge evidence. - [e] Prove deployed-environment controls: target backup/restore rehearsal, monitoring deployment, incident rehearsal, object-store WORM/object-lock policy, KMS/HSM custody, SSO/group-sync provider behavior, and transparency-provider semantics. - [e] Produce external adoption evidence, third-party review, support-process evidence, customer feedback, or case studies tied to a concrete public release candidate. From f8778f9a75e0016aa4a8ba97629acf01928084bb Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 20:26:08 +0300 Subject: [PATCH 163/287] docs: track production readiness v5 remediation --- .production_readiness_v5.md | 783 ++++++++++++++++++++++++++++++++++++ 1 file changed, 783 insertions(+) create mode 100644 .production_readiness_v5.md diff --git a/.production_readiness_v5.md b/.production_readiness_v5.md new file mode 100644 index 0000000..e73686f --- /dev/null +++ b/.production_readiness_v5.md @@ -0,0 +1,783 @@ +## 2026-05-31 Remediation Tracking + +Status legend: + +- `[ ]` applicable repository-local or repository-admin work that remains incomplete. +- `[x]` applicable work completed with current repository, GitHub, release, or command evidence. +- `[e]` external, account-level, provider-level, operator-environment, customer/adoption, or time-dependent work that cannot be completed by repository files and GitHub repository administration alone. + +Repository-local and repository-admin remediation from the v5 audit: + +- [x] Keep `.production_readiness_v5.md` as a trackable repository artifact and current remediation source. +- [ ] Publish a signed public release-candidate tag and GitHub draft release from current `master`, with archives, `SHA256SUMS`, OpenAPI checksum, migration checksum, coverage output, production-check summary, SBOM/provenance metadata, signed release manifest, manifest signature, and release notes. +- [ ] Produce a successful public `Release Artifacts` workflow run tied to that release tag. +- [ ] Update release evidence and install docs with public release URL, public tag, CI run, release-artifacts workflow run, artifact checksums, signed manifest, SBOM/provenance metadata, and verification instructions. +- [ ] Decide and document the immediate public container stance: publish immutable GHCR images for the release or explicitly state that release archives/source checkout are the only supported install path for this release line. +- [ ] Make the evaluation path release-backed: public release download, verification, demo/package viewer walkthrough, and sample output links instead of source-checkout-only evaluation. +- [ ] Run or document a fresh production exit review after the public release evidence exists. + +External, adoption-dependent, or operator-environment work from the v5 audit: + +- [e] Produce real production deployment evidence, target-environment backup/restore rehearsal, monitoring evidence, incident rehearsal, object-store WORM/object-lock proof, KMS/HSM custody proof, provider credential validation, and customer package access operations. +- [e] Accumulate long-lived maintenance history, merged pull-request review history from non-bypass changes, contributor diversity, public adoption evidence, external review, support-process history, customer feedback, or case studies. +- [e] Obtain external CII Best Practices badge evidence and any other third-party trust-program validation. +- [e] Enable signed commits, branch-protection admin enforcement, secret-scanning non-provider patterns, or secret validity checks only if the repository/account plan and operator policy support them without blocking required maintenance. + +## Latest visible state inspected + +Repository: `aatuh/evydence` at . +Audit scope: strict latest public GitHub repository state plus the current local +checkout at `/home/aatu/projects/evydence`. + +Inspected local state: + +- Local branch: `master`. +- Local `HEAD`: `8737978646fcf5b7e501da7bb6913e7dbe28ea0d`. +- Local commit date: `2026-05-31T20:04:57+03:00` / `2026-05-31T17:04:57Z`. +- Commit subject: `docs: mark external scorecard signals`. +- Local `master` and `origin/master` matched after `git fetch --tags origin`: + `git rev-list --left-right --count master...origin/master` returned `0 0`. +- Local worktree before writing this audit was clean: `## master...origin/master`. +- Local tags exist: `v0.1.0-rc.1`, `v0.1.0-rc.2`, and `v0.1.0-rc.3`. +- Ignored local `dist/v0.1.0-rc.1`, `dist/v0.1.0-rc.2`, and + `dist/v0.1.0-rc.3` directories exist with archives, checksums, coverage, + release manifests, signatures, OpenAPI, migration checksums, and release + notes. These are local ignored artifacts and are not public release evidence. + +Public GitHub state verified with `gh` and git: + +- Default branch: `master`. +- Public default-branch commit: + `8737978646fcf5b7e501da7bb6913e7dbe28ea0d`. +- Public default-branch commit date: `2026-05-31T17:04:57Z`. +- Public repository created: `2026-05-28T15:09:02Z`. +- Public repository pushed: `2026-05-31T17:04:58Z`. +- Public repository updated: `2026-05-31T17:05:02Z`. +- Visibility: public. +- Archived: false. +- Description: `Self-hosted API-first evidence ledger for software release + compliance readiness`. +- Topics include `api-first`, `audit-log`, `evidence-ledger`, `golang`, + `openapi`, `release-evidence`, `sbom`, `self-hosted`, + `supply-chain-security`, `vex`, `vulnerability-management`, and + `compliance-readiness`. +- Public stars/watchers/forks: `0` stars, `0` watchers, `0` forks. +- Public issues: `gh issue list` returned no open issues. `gh pr list` + returned 6 open Dependabot PRs. +- License: GitHub reports GNU AGPLv3 / `AGPL-3.0`; repository files state + `AGPL-3.0-only` plus optional commercial licensing terms in `COMMERCIAL.md`. +- Primary language: Go. GitHub language data also reported Makefile, Python, + Shell, TypeScript, HTML, Dockerfile, and Go Template. +- Package manifest: `go.mod` / `go.sum`; module `github.com/aatuh/evydence`; + Go `1.25.10`. + +Public release and artifact state: + +- `gh release list --repo aatuh/evydence --limit 20` returned no releases. +- `git ls-remote --tags origin` returned no public remote tags. +- `gh api repos/aatuh/evydence/tags` returned no public tags. +- `gh run list --repo aatuh/evydence --workflow "Release Artifacts"` returned + no workflow runs. +- GitHub package APIs for a user-owned or org-owned `evydence` container + package returned 404; no public GHCR package evidence was visible. +- Latest public CI run `26718927469` uploaded an Actions artifact named + `evydence-ci-evidence`, size `68880`, created `2026-05-31T17:08:53Z`. + This is useful CI evidence, but it is not a public release artifact set. +- The largest public production-readiness blocker remains absent public release + publication: no public tag, GitHub Release, release artifact workflow run, + immutable image, package-manager artifact, published checksums, or release + provenance bundle. + +Public CI and check status for inspected commit: + +- Commit check runs for `8737978646fcf5b7e501da7bb6913e7dbe28ea0d` all + completed successfully: + - `Production Check`, run `26718927469`, completed + `2026-05-31T17:08:55Z`. + - `CodeQL Analyze`, run `26718927471`, completed + `2026-05-31T17:06:21Z`. + - `Scorecard`, run `26718928781`, completed + `2026-05-31T17:05:27Z`. + - `Scorecard SARIF`, run `26718929366`, completed + `2026-05-31T17:05:25Z`. +- `CI` runs `make production-check` against a PostgreSQL service and uploads + the CI evidence artifact listed above. +- CodeQL uses the `security-and-quality` query suite. +- OpenSSF Scorecard run `26718928781` reported score `7.6` in logs. Weak + Scorecard dimensions were mainly no release/package evidence, no merged PR + review history, repository age, no contributor diversity, and no CII Best + Practices badge. Its branch-protection check returned an integration access + error, while the GitHub branch protection API separately proved protection is + enabled. + +Visible GitHub security and repository settings: + +- `master` branch protection is enabled. +- Required status checks are strict and require `Production Check` and + `CodeQL Analyze`. +- Pull request reviews are required with 1 approving review, stale review + dismissal, and CODEOWNERS review. +- Required conversation resolution and linear history are enabled. +- Force pushes and branch deletions are disabled. +- Required signed commits are disabled. +- Admin enforcement is disabled. +- Repository `security_and_analysis`: Dependabot security updates enabled, + secret scanning enabled, secret scanning push protection enabled, + non-provider pattern scanning disabled, and secret scanning validity checks + disabled. +- `repos/aatuh/evydence/vulnerability-alerts` returned HTTP 204, proving + vulnerability alerts are enabled to the authenticated `gh` user. +- `repos/aatuh/evydence/automated-security-fixes` returned enabled. +- `repos/aatuh/evydence/private-vulnerability-reporting` returned enabled. +- Dependabot alerts: 0 open. +- Secret-scanning alerts: 0 visible. +- Code-scanning alerts: 0 open; 21 closed or dismissed. Closed examples include + fixed Scorecard findings and a dismissed CodeQL + `go/weak-sensitive-data-hashing` finding with a content-digest rationale. +- GitHub community profile reported 100 percent and found README, license, + contributing guide, code of conduct, issue template, and PR template. + +Current repository evidence in checkout: + +- Source and operational tree is substantial: `cmd/`, `internal/`, + `migrations/`, `docs/`, `deploy/`, `sdk/`, `examples/`, `scripts/`, + `.github/`, Dockerfile, Compose files, Helm chart, and `openapi.yaml`. +- `go list ./...` reported 22 Go packages. +- The checkout has 41 Go test files, excluding `.refs`, `tmp`, and ignored + artifact directories. +- The migration directory has 46 migration files. +- `openapi.yaml` contains 152 paths and 166 operations. +- `make openapi-precision-check` reported 166 precise operations and 0 broad + operations. +- `CODEOWNERS`, `SECURITY.md`, `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`, + `GOVERNANCE.md`, `SUPPORT.md`, `RELEASE_EVIDENCE.md`, `CHANGELOG.md`, + issue templates, PR template, Dependabot config, CI, CodeQL, Scorecard, and + release-artifacts workflow files are present. + +Not inspectable or not proven: + +- GitHub Actions secret values, release signing key configuration, package or + container registry credentials, deployment environments, production + deployments, real backup storage, monitoring systems, object-store WORM + policy, KMS/HSM custody, provider credentials, customer data, support + process execution, SLA behavior, commercial license execution, and real + adoption evidence were not inspectable. +- Branch protection was visible, but private repository rulesets beyond the + branch protection endpoint were not proven. +- Local ignored `dist/` release-candidate artifacts and local tags are not + public install evidence. + +Confidence impact: confidence is high for the inspected local checkout, public +default branch, public CI, visible GitHub security settings, and repository +contents. Confidence remains medium for real production deployment readiness +because the biggest remaining evidence categories are external, operator-owned, +or unpublished. + +## What the project appears to be + +Evydence is a self-hosted, API-first release evidence and compliance-readiness +ledger for software product teams. It collects, verifies, links, and reports +technical release evidence such as SBOMs, vulnerability scans, VEX decisions, +build/source/deployment evidence, approvals, exceptions, controls, release +bundles, audit chains, evidence bundles, and customer-safe packages. + +Likely users are security engineering, AppSec, platform engineering, release +engineering, compliance-readiness, and customer-trust teams at B2B software +companies. Likely operators are teams comfortable running PostgreSQL, object +storage, worker processes, deployment secrets, backup/restore, release signing, +Kubernetes or Compose, and provider integrations. + +The README communicates the category, target user, value, current limitations, +proof path, and alternatives within about 30 seconds. It clearly avoids +claiming legal compliance, certification, complete SBOMs, authoritative scanner +results, or guaranteed release security. + +The product shape is broader than a library: + +- Go HTTP API server. +- Worker process. +- Migration command. +- CLI helper. +- PostgreSQL-backed ledger with object storage. +- OpenAPI contract. +- SDK helpers. +- Docker/Compose/Helm deployment assets. +- Release evidence tooling and documentation. + +Implemented behavior is backed by source, tests, migrations, OpenAPI, docs, +examples, release scripts, public CI, and visible GitHub security settings. +Roadmap and limitation language is also visible: public release publication, +multi-writer API HA, native PKCS#11/HSM custody, broad object-lock/WORM proof, +provider-specific trust review, and hosted SaaS production are not presented as +complete. + +Overall, it appears to be a serious controlled self-hosted production +candidate for a high-trust release-evidence niche. It is not yet a broadly +adoptable public production project because there is still no public release, +tag, signed artifact set, immutable image, or package distribution path. + +## Production readiness + +Evidence that supports readiness: + +- Process split exists under `cmd/evydence-api`, `cmd/evydence-worker`, + `cmd/evydence-migrate`, and `cmd/evydence`. +- Domain/application/adapters layout exists under `internal/`. +- API code uses `github.com/aatuh/api-toolkit/v3` route contracts, specs, and + HTTP helpers. +- API contract is committed as `openapi.yaml` with 152 paths and 166 precise + operations. +- HTTP server has request IDs, secure headers, size-limited JSON bodies, + Problem Details responses, idempotency checks for create/action flows, and + route contract validation tests. +- Production startup rejects missing database URL, default or empty API key + pepper, dev-only signing-key modes, unsupported API writer modes, API writer + replica counts above 1, non-relational production load modes, and bootstrap + secret printing. +- PostgreSQL production mode defaults to relational-only loading, can disable + compatibility snapshot writes, applies or checks migrations at startup, and + takes a PostgreSQL advisory API-writer lease. +- Worker replicas are documented as horizontally scalable through PostgreSQL + outbox row locking, while API writer replicas remain intentionally limited. +- Object storage supports filesystem and S3/MinIO adapters; raw upload replay + paths verify digests before parser trust is assigned. +- Signing adapters exist for HTTP gateway, AWS KMS, GCP KMS, and Azure Key + Vault; native PKCS#11/HSM is explicitly gateway-backed and deployment + dependent. +- Provider identity and transparency proof gateway adapters exist, with timeout + and localhost-only insecure allowances for tests/local use. +- Dockerfile builds API, migration, worker, and CLI commands and uses digest- + pinned base images. +- Compose, production-like Compose, Helm chart, Kubernetes docs, observability + assets, configuration reference, operations docs, backup/restore runbook, + upgrade runbook, incident runbook, release-validation docs, release-candidate + docs, and production-readiness docs exist. +- `make production-check` requires live PostgreSQL, release-check, coverage + threshold, migration compatibility, benchmark check, black-box API/worker + demo, and release-signing smoke test. +- Latest public `master` CI ran `make production-check` with PostgreSQL and + passed. +- Local audit checks passed: `go test ./...`, `make docs-check`, + `make openapi-precision-check`, and `make package-viewer-check demo-check + sdk-check deploy-check`. + +Evidence that prevents a production-ready verdict: + +- No public GitHub releases. +- No public remote tags. +- No visible Release Artifacts workflow runs. +- No public immutable binary, archive, image, chart package, package-manager + install path, or signed public artifact set. +- Local ignored release-candidate artifacts exist, but they are not public + release evidence. +- GitHub required signed commits are disabled and admin enforcement is disabled. +- Secret scanning non-provider patterns and validity checks are disabled. +- OpenSSF Scorecard is 7.6, not high, mainly because of no releases/packages, + no merged PR review history, repository age, no contributor diversity, and no + CII Best Practices badge. +- Production-like Compose uses `postgres:16-alpine`, `minio/minio:latest`, and + `minio/mc:latest`; it is correctly labeled as local rehearsal, not a + turnkey production deployment. +- Helm values reference `ghcr.io/aatuh/evydence`, but no visible GHCR package + exists. +- Production docs still correctly classify the project as a controlled + self-hosted production candidate, not broadly production-ready. +- The supported API production profile is one writer replica. Multi-writer API + HA remains explicitly unsupported. +- KMS/HSM custody, WORM/object-lock enforcement proof, provider-specific trust + behavior, target-environment backup/restore, monitoring, incident rehearsal, + and customer package access operations remain operator-dependent. + +Brutal assessment: the repository is much stronger than a prototype and has a +credible self-hosted pilot path from source. Public CI and GitHub security +settings are now real evidence rather than intent. The public release surface +is still not good enough for broad production adoption. A skeptical operator +cannot yet start from a signed public release, verify checksums and provenance, +pull an immutable image, and map a release artifact to CI evidence. + +Score: 6/10. + +## Feature completeness + +Supported use cases with repository evidence: + +- Create tenant-scoped release ledger resources: products, projects, releases, + release candidates, artifacts, container images, source records, + deployment events, incidents, and remediation records. +- Capture release evidence: generic evidence items, SBOMs, VEX documents, + vulnerability scans, vulnerability decisions, OpenAPI contracts, contract + diffs, security documents, build runs, build attestations, artifact + signatures, collector records, and lifecycle events. +- Generate and verify higher-trust records: release bundles, audit-chain + verification, Merkle batches, transparency checkpoints, signing keys, + signatures, verification results, object-retention policy records, backup + manifests, and legal hold or retention override records. +- Produce reports and review packages: release readiness, missing evidence, + vulnerability posture, control coverage, CRA readiness, incident package, + security review package, evidence summary, graph snapshot, PDF package, + questionnaire draft/package, anomaly report, retention report, and + customer package/export paths. +- Enforce identity and tenant boundaries with API keys, one-time secrets, + HMAC-backed API key/session/portal-token hashes, SSO provider/session + records, role bindings, scopes, and explicit `instance:admin` diagnostics. +- Run a local API tutorial and end-to-end release evidence example. +- Validate demo fixtures, SDK helper coverage, deployment skeletons, docs, + OpenAPI precision, and package viewer through project-owned gates. + +Important missing or incomplete table stakes: + +- Public install path: no public release, tag, immutable image, signed public + artifact set, published checksums, package, or registry evidence. +- Release-to-CI traceability: no public Release Artifacts workflow run tied to + a public tag. +- Production operations: target-environment backup/restore, monitoring, + incident rehearsal, object-store WORM, KMS/HSM custody, and provider trust + semantics remain operator-specific and unproven. +- HA: one API writer is the documented production profile; broad multi-writer + API HA is not implemented. +- Provider coverage: direct provider-specific management API clients and + external group synchronization are not broadly implemented; gateway and + local OIDC/SAML paths cover a narrower bring-your-own-evidence posture. +- UI: there is a local package viewer, but not a full operator/customer UI. +- Adoption proof: no public users, deployments, case studies, external review, + support history, or contributor base. + +Blockers versus nice-to-haves: + +- Blockers: public release artifacts, release provenance, immutable install + path, release-backed demo, and fresh production exit review after public + release publication. +- High-priority hardening gaps: provider custody/WORM proof, production + deployment rehearsals, clearer container publishing stance, Scorecard + maturity items, and Dependabot PR triage. +- Nice-to-have gaps: screenshots, richer UI, more SDK depth, more collectors, + additional framework templates, adoption stories, and external trust badges. + +Maturity classification: controlled production candidate from source, not +broadly production-ready public product. It is not a toy. It is not yet a +complete productizable public release line. + +Score: 7/10. + +## Security and open-source trust + +Strong signals: + +- Public repository is visible and not archived. +- AGPL license, commercial licensing terms, governance, support, contribution + policy, code of conduct, trademark guidance, release evidence policy, + changelog, issue templates, PR template, CODEOWNERS, and maintainer review + policy exist. +- `SECURITY.md` provides private vulnerability reporting guidance and warns + against posting secrets, raw evidence payloads, customer data, and exploit + detail publicly. +- GitHub private vulnerability reporting is enabled. +- GitHub vulnerability alerts are enabled. +- Dependabot security updates and automated security fixes are enabled. +- Dependabot config exists for Go modules, GitHub Actions, and Docker. +- Secret scanning and push protection are enabled. +- CodeQL workflow is active and latest `CodeQL Analyze` passed. +- OpenSSF Scorecard and Scorecard SARIF workflows are active and latest runs + passed. +- Open code-scanning alerts are 0, Dependabot alerts are 0, and visible + secret-scanning alerts are 0. +- `master` branch protection is enabled with strict required `Production Check` + and `CodeQL Analyze` checks, PR review, CODEOWNERS review, stale review + dismissal, conversation resolution, linear history, force-push prevention, + and branch-deletion prevention. +- CI workflow permissions are scoped to read at top level, with release write + permission isolated to the release-artifacts job. +- GitHub Actions and CI service containers are pinned by commit SHA or image + digest in checked workflows. +- Local tests cover tenant isolation, idempotency, immutable/append-only + behavior, auth scopes, provider gateways, KMS adapters, object store paths, + release bundles, audit chain, parser behavior, and PostgreSQL relational + reconstruction. +- Production startup safety checks reject several unsafe defaults. + +Weak signals: + +- No public signed releases, remote tags, Release Artifacts workflow runs, + release checksums, release provenance, public SBOM, or immutable install + artifact. +- Required signed commits are disabled. +- Admin enforcement is disabled for branch protection. +- Secret scanning non-provider patterns and validity checks are disabled. +- OpenSSF Scorecard is only 7.6. Some weak dimensions are structural for a new + solo-maintainer repository, but they still matter to public adopters. +- No CII Best Practices badge or OpenSSF Scorecard badge proof beyond the + workflow. +- No merged PR review history yet. CODEOWNERS is configured and branch + protection requires CODEOWNERS review, but practical multi-person review + evidence is absent. +- No visible release signing secret configuration, package registry policy, or + published image signing evidence. +- No security advisory history, third-party security review, public pentest, + external audit, or real vulnerability-response exercise. +- A high-trust product should treat absent release integrity as a serious + security trust gap even when source CI is strong. + +External settings that were visible: + +- Branch protection: enabled and detailed through `gh api`. +- Private vulnerability reporting: enabled. +- Vulnerability alerts: enabled. +- Automated security fixes: enabled. +- Dependabot alerts: 0. +- Secret-scanning alerts: 0 visible. +- Open code-scanning alerts: 0. + +External settings that could not be verified: + +- GitHub Actions secret values and rotation. +- Release signing private key existence and custody. +- Registry credentials, package publication policy, or image immutability. +- Deployment secrets and infrastructure controls. +- Organization-level rulesets or policies beyond visible repository branch + protection and security settings. + +Score: 6/10. + +## Marketability and positioning + +Buyer/adopter assessment: + +The problem is real and painful for B2B software teams: customer security +reviews, release evidence, SBOM/VEX workflows, vulnerability decisions, build +provenance, exceptions, approvals, and readiness reporting are often scattered +across CI, object storage, spreadsheets, GRC tools, scanners, ticketing, and +manual exports. A self-hosted ledger with conservative no-claim language has a +clear audience among teams that cannot or do not want to hand all technical +release trust data to a SaaS GRC platform. + +The README is significantly better than a normal early repo README. It states +target users, what the product does, what it does not prove, current +limitations, fastest proof path, implementation status, alternatives, and +validation commands. The positioning is credible because it avoids compliance +magic. + +Category crowding: + +- GRC/compliance SaaS platforms such as Vanta and Drata are broad, polished, + commercially mature, and buyer-recognized. +- SBOM and vulnerability tools such as OWASP Dependency-Track own a large part + of the SBOM analysis and vulnerability-management workflow. +- Supply-chain graph tools such as GUAC cover aggregation and query over SBOM, + VEX, SLSA, in-toto, OSV, and related metadata. +- Signing and transparency tools such as Sigstore/Rekor and in-toto cover + artifact signing, transparency, and supply-chain attestation primitives. +- In-house scripts and spreadsheets remain a realistic substitute for teams + with strong platform engineers and low productization expectations. + +Value proposition: + +Evydence is sharpest when positioned as a self-hosted technical evidence ledger +for release review, not as a replacement for GRC, scanners, signing systems, +or auditors. Its most differentiated story is: gather release evidence, record +decisions and limitations, generate a tamper-evident release package, and give +customers reviewable evidence without broad compliance claims. + +Demo/evaluation path: + +- Local getting-started tutorial exists. +- Production-like Compose rehearsal exists. +- End-to-end release evidence example exists. +- Package viewer exists. +- Public CI proves `make production-check` passes on the inspected commit. +- The demo is not yet release-backed, and there is no public install artifact + to verify before running it. + +Plausible adoption or monetization routes: + +- AGPL open-source adoption by self-hosted teams. +- Commercial license exceptions for proprietary or closed deployments. +- Self-hosted support. +- Deployment review. +- Release evidence packages. +- Custom collector/report integrations. +- Private forks and templates for regulated or customer-trust-heavy teams. + +Marketability constraints: + +- No public release means the first adopter still has to trust source checkout + rather than a signed artifact. +- No public image means Helm and Compose production paths require local build + or unpublished image assumptions. +- No screenshots or release-backed walkthrough means time-to-value is not as + immediate as mature alternatives. +- No adoption evidence, external review, or support history exists. +- The product name and public surface are usable, but the public trust story is + incomplete until release publication exists. + +Score: 7/10. + +## Differentiation + +Direct alternatives: + +- [OWASP Dependency-Track](https://dependencytrack.org/): strong SBOM analysis + and vulnerability-management platform. Evydence differs by focusing on + release-level evidence, decisions, approvals, exceptions, bundles, audit + chains, customer packages, and no-claim readiness reports. +- [GUAC](https://docs.guac.sh/guac/): software supply-chain metadata graph. + Evydence differs by being a release evidence ledger and report/package + workflow rather than primarily a graph aggregation/query system. +- [Vanta](https://www.vanta.com/products/automated-compliance) and + [Drata](https://drata.com/): broad SaaS GRC/compliance platforms. Evydence + differs by being self-hosted, technical-evidence-first, API-first, and + explicitly not a compliance automation claim engine. +- [Sigstore/Rekor](https://docs.sigstore.dev/logging/overview/) and + [in-toto](https://github.com/in-toto/in-toto): signing, transparency, and + supply-chain attestation primitives. Evydence can record and verify related + evidence, but it is not a replacement trust root. + +Indirect alternatives: + +- Existing CI artifacts, cloud object storage, tickets, Confluence pages, and + spreadsheets. +- Scanner dashboards and SARIF/SBOM exports. +- GRC evidence lockers. +- Customer trust portals. +- Internal PostgreSQL evidence databases and ad hoc report scripts. + +Build-in-house/do-nothing path: + +A technically strong team can build enough of this with PostgreSQL, object +storage, CI scripts, scanner outputs, and a few export jobs. The hard parts are +not basic CRUD; they are tenant isolation, append-only semantics, idempotency, +canonical hashing, digest verification, release bundles, redaction, customer +package scope, auditability, conservative product language, and keeping docs, +release artifacts, and operational evidence aligned. + +Meaningful implemented differentiation: + +- Self-hosted technical release evidence ledger rather than generic SaaS GRC. +- API-first and OpenAPI-backed with 166 precise operations. +- Tenant-scoped idempotency, append-only evidence transitions, audit-chain + verification, release bundles, and customer-safe packages. +- Explicit gap/assumption/exception/limitation reporting. +- Controlled production profile documented honestly, including one API writer. +- Release evidence packaging machinery is part of the repo, not an afterthought. +- Strong no-claim language baked into README, docs, release notes, and checks. + +Weak differentiation: + +- Mature alternatives already dominate SBOM/vulnerability, GRC, signing, and + supply-chain graph niches. +- No public release artifact means the differentiation is still source-backed + rather than release-backed. +- Provider-specific trust, WORM/object-lock proof, KMS/HSM custody, and + external group synchronization remain operator-dependent. +- No external adoption evidence yet. + +Score: 7/10. + +## Repository quality checklist + +| Area | Status | Evidence | Severity | Recommended fix | +|------|--------|----------|----------|-----------------| +| README | Strong | `README.md` states target user, value, implementation, limitations, proof path, alternatives, validation commands, license/security/support/governance, and no-claim language. | Low | Add public release links, signed-artifact verification, and a release-backed demo once releases exist. | +| Quickstart | Adequate | `docs/tutorials/getting-started.md` works from source and explains in-process state; install docs and production-like Compose exist. | Medium | Replace source-checkout-first public evaluation with signed release verification after the first public release. | +| Examples/demo | Adequate | `examples/end-to-end-release-evidence`, demo fixtures, `run-local-demo.sh`, black-box demo gate, and package viewer exist. | Medium | Publish a release-backed demo bundle and add first-screen screenshots or sample output links. | +| Tests | Strong | 41 Go test files, local `go test ./...` passed, public CI `Production Check` passed, and Makefile has race, coverage, migration, black-box, benchmark, OpenAPI, docs, deploy, SDK, and demo gates. | Low | Keep expanding negative tests around provider gateways, tenant isolation, digest mismatch, redaction, signing failures, parser retries, and backup/restore edge cases. | +| CI | Strong | Public `master` check runs for `Production Check`, `CodeQL Analyze`, `Scorecard`, and `Scorecard SARIF` passed on commit `8737978`; branch protection requires the first two. | Low | Keep required checks aligned with release and security gates; resolve or document failing Dependabot PR checks before merging dependency updates. | +| Releases/provenance | Weak | Release scripts and workflow exist, local tags/artifacts exist, but there are no public releases, public tags, public Release Artifacts runs, public checksums, public signed manifests, public SBOM/provenance, or public install artifacts. | Blocker | Publish a signed public RC tag/release with archives, `SHA256SUMS`, OpenAPI checksum, migration checksum, coverage output, production-check summary, SBOM/provenance metadata, signed manifest, manifest signature, and release notes. | +| Docs/API/config/ops | Strong | `docs/`, `openapi.yaml`, API matrix, configuration reference, operations/runbooks, production-readiness docs, release-validation docs, Kubernetes/air-gap docs, and source-of-truth docs exist. | Low | Reduce repeated production-status prose over time and keep one canonical current-status source. | +| Docker/deployment | Adequate | Dockerfile with pinned base images, local Docker Compose, production-like Compose, Helm chart, Kubernetes docs, observability starter assets, and air-gap manifest exist. | Medium | Publish immutable images or document that release archives/source checkout are the only supported install paths; avoid `latest` tags in production-like examples if they become more than rehearsal docs. | +| Security policy | Adequate | `SECURITY.md`, private vulnerability reporting, vulnerability alerts, automated fixes, secret scanning, push protection, CodeQL, Scorecard, branch protection, CODEOWNERS, and no open visible alerts exist. No public signed release exists. | Medium | Publish release integrity evidence and consider enabling signed commits, admin enforcement, secret-scanning non-provider patterns, and validity checks where practical. | +| License/contribution/governance | Strong | `LICENSE`, `COMMERCIAL.md`, `CONTRIBUTING.md`, `GOVERNANCE.md`, `CODE_OF_CONDUCT.md`, `SUPPORT.md`, `TRADEMARKS.md`, CODEOWNERS, issue templates, and PR template exist. | Low | Clarify practical CLA/commercial exception workflow before actively soliciting outside contributors. | +| Changelog/versioning | Adequate | `CHANGELOG.md`, release notes template, release-candidate docs, local tags, and release packaging scripts exist. Public tags/releases are absent. | High | Push public release tags and align changelog entries with published release artifact evidence. | + +## Scorecard + +| Dimension | Score | Notes | +|-----------|------:|-------| +| Production readiness | 6/10 | Strong source, CI, production-check, docs, deployment skeletons, startup safety checks, and PostgreSQL path; capped by no public release, no public install artifact, no public image, one-writer API profile, and operator-dependent custody/WORM/provider/deployment controls. | +| Feature completeness | 7/10 | Broad implemented release-evidence workflow, API, migrations, docs, examples, SDK helpers, deployment assets, reports, bundles, and release tooling; gaps remain in public install path, full UI, multi-writer HA, and provider/WORM/HSM proof. | +| Security and open-source trust | 6/10 | GitHub security settings, branch protection, CodeQL, Scorecard, Dependabot, private vulnerability reporting, and no visible open alerts are strong; absent signed public releases and weak public release integrity keep trust capped for a high-trust product. | +| Marketability and positioning | 7/10 | Clear niche, target user, demo path, conservative claims, and commercial path; adoption credibility is constrained by no release-backed install path, no screenshots/release demo, and no external adoption proof. | +| Differentiation | 7/10 | Meaningfully differentiated as a self-hosted release evidence ledger with customer packages and no-claim readiness language; still overlaps with mature SBOM, vulnerability, GRC, signing, and supply-chain graph tools. | +| Repository evidence quality | 8/10 | Strong repository evidence: code, tests, OpenAPI, migrations, workflows, docs, deployment assets, examples, SDK helpers, runbooks, public CI, and visible GitHub security settings. Missing public releases/provenance is the major evidence gap. | +| Overall | 7/10 | Serious and productizable, but strict public production-readiness remains blocked by absent public release artifacts/tags/images and unresolved operator-dependent high-trust controls. | + +Confidence: high for repository and public GitHub state; medium for real +production deployment readiness. + +Verdict: Promising but not production-ready + +Direct answers: + +- Is it mature and high-grade enough for production for most intended uses? + No. It may be usable for controlled self-hosted evaluation, pilots, or + carefully reviewed internal production from source, but not most intended + production uses. +- Is it feature-complete enough to solve a real-world problem? Partly yes. The + core release evidence workflow is substantial enough to evaluate and pilot, + but public install/release trust and several production controls remain + incomplete. +- Is it marketable or interesting enough to attract users, buyers, + contributors, or commercial opportunity? Yes, but only after release-backed + install and public proof assets exist. +- Is it worth continuing, hardening, repositioning, or abandoning? Continue and + harden. The product is worth continuing; the next work should prioritize + release publication and operator proof over feature breadth. + +## Highest-leverage next steps + +Next 1-2 days: + +- Publish the first public release candidate. Push a public tag such as + `v0.1.0-rc.4` or intentionally publish the current RC line, run the Release + Artifacts workflow, and attach signed archives, `SHA256SUMS`, + `openapi.sha256`, `migrations.sha256`, coverage output, production-check + summary, SBOM/provenance metadata, signed manifest, manifest signature, and + release notes. This removes the largest public adoption blocker. +- Update `README.md`, `docs/tutorials/getting-started.md`, and + `docs/how-to/install-and-operate.md` after the release so the first public + install path is release verification rather than source checkout. +- Add a release-backed evidence link set in + `docs/reference/release-evidence-index.md`: release URL, tag, CI run, + release-artifact workflow run, checksums, signed manifest, SBOM/provenance + metadata, coverage, and production-check summary. This makes the public trust + path auditable. +- Decide the immediate container stance. Either publish immutable images for + the public release or state clearly that source/release archives are the only + supported install path for the current release line. Update + `deploy/helm/evydence/values.yaml`, `docs/kubernetes.md`, and + `compose.production-like.yml` accordingly. +- Triage the 6 open Dependabot PRs. Some pass and some fail `Production Check`. + Merge only those with required checks green, and document any postponed major + dependency jumps. + +Next 1-2 weeks: + +- Make the evaluation path release-backed end to end: download release, verify + signature/checksums, run Compose or Helm with explicit artifact/image source, + execute the end-to-end evidence demo, and inspect readiness/customer-package + output. This should become the primary README proof path. +- Add one short visual proof artifact: a screenshot or rendered sample of + release readiness, audit-chain verification, and customer package manifest. + This improves time-to-value without adding unproven claims. +- Add an explicit public release integrity checklist to + `docs/reference/release-candidate.md` and keep it enforced by + `scripts/release_candidate_validate.sh`. +- Consider enabling signed commits, branch protection admin enforcement, + secret-scanning non-provider patterns, and secret validity checks if they are + practical for the maintainer workflow. Document any deliberate non-use. +- Register or intentionally defer OpenSSF Best Practices badge work. If + deferred, document why in `docs/reference/production-exit-review.md`. + +Next 1-2 months: + +- Complete a fresh production exit review after public release artifacts, + image/package stance, branch protections, vulnerability reporting, security + updates, and release evidence are all visible. Update + `docs/reference/production-exit-review.md`. +- Either keep the one-writer API model as the explicitly supported profile + with sizing guidance and tested failure behavior, or design and implement a + reviewed multi-writer API concurrency model. +- Harden provider-dependent trust profiles: KMS/HSM custody, object-lock/WORM + verification, provider validation gateways, transparency proof retrieval, and + SSO/group behavior with explicit tests and operator docs. +- Produce target-environment operational proof: backup/restore rehearsal, + incident drill, monitoring deployment, alert examples, object-store recovery, + and upgrade rehearsal tied to a release artifact. +- Build public adoption evidence: supported pilot walkthrough, issue labels, + support workflow, release cadence, and eventually external review, user + feedback, or case studies tied to a concrete public release candidate. + +## README/product-page rewrite advice + +Sharper one-sentence pitch: + +Evydence is a self-hosted release evidence ledger for B2B software teams that +need reproducible SBOM, vulnerability, approval, exception, deployment, and +customer-review evidence without handing technical trust data to a SaaS GRC +platform. + +Target user: + +Security, AppSec, platform, release, and compliance-readiness teams operating +self-hosted release infrastructure for customer-facing software. + +Core use case to show first: + +Before release, collect SBOM, vulnerability scan, VEX decision, build/source, +approval, exception, artifact, and deployment evidence; generate a +release-readiness report; verify the audit chain; and export a customer-safe +evidence package that states gaps, assumptions, and limitations. + +Best demo/example to show first: + +Use the end-to-end release evidence example and package viewer, but make them +release-backed. The first proof should be: download this signed RC, verify it, +run this Compose flow, inspect these JSON outputs. + +Proof points to add: + +- Latest public release link. +- Signed artifact manifest and manifest signature. +- `SHA256SUMS`, OpenAPI checksum, migration checksum. +- Public CI production-check run linked to the release commit. +- Coverage threshold result. +- OpenSSF Scorecard result and residual limitations. +- Supported production profile table. +- Release-backed demo output or screenshots. + +What to remove or de-emphasize: + +- Shorten long lists of implemented resource families in the README after the + release-backed demo is available. +- Keep detailed production caveats in canonical docs instead of repeating them + in many places. +- Do not add more broad feature claims until public release/install trust is + fixed. +- Do not imply public artifact availability before releases and tags actually + exist. + +## Residual risk and uncertainty + +Untested during this audit: + +- I did not run `make production-check`, `make release-check`, + `make test-race`, `make gosec`, `make vuln`, `make coverage-check`, + `make migration-compatibility-check`, `make black-box-demo-check`, or + `make release-candidate-check` locally. +- Public CI did run `make production-check` successfully on the inspected + commit, but this audit did not independently reproduce that full live + PostgreSQL gate locally. +- I did not perform a manual API black-box run, backup/restore rehearsal, Helm + install, container build, S3/MinIO object-lock test, KMS/HSM signing test, + OIDC/SAML provider test, transparency provider test, package download test, + or release signing secret test. +- I did not inspect private secret values, production deployments, monitoring + systems, backup storage, customer package access logs, commercial support + records, or real user/adoption data. + +Claims still only documented, local, or operator-dependent: + +- Public release candidate publication is not complete. +- Local tags and ignored `dist/` directories are not public release evidence. +- Native PKCS#11/HSM module custody is not proven by repository evidence. +- Broad WORM/object-lock enforcement depends on provider configuration and + operator evidence. +- Direct provider-specific management API trust and external group + synchronization are not broadly implemented. +- Multi-writer API HA is explicitly unsupported. +- Hosted SaaS production is out of scope. +- Target-environment backup/restore, incident response, monitoring, capacity, + and security operations must be proven by each operator. + +Evidence that would raise confidence: + +- Public signed release artifacts and public tags. +- Public Release Artifacts workflow run tied to a release. +- Immutable published container images or a deliberate non-image install + stance. +- Public release-backed production-check summary, coverage report, OpenAPI + checksum, migration checksum, SBOM/provenance metadata, signed manifest, + manifest signature, and release notes. +- Public release-backed demo that can be run from artifacts rather than source. +- Fresh production exit review after the public release exists. +- Third-party security review, real deployment rehearsal evidence, external + adoption evidence, or documented customer pilot feedback. From d828886bc0c9bc501841b747aaed3172c8f5c135 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 20:39:40 +0300 Subject: [PATCH 164/287] docs: publish release-backed readiness evidence --- .production_readiness_v5.md | 12 +++--- README.md | 27 ++++++------ deploy/airgap/manifest.yaml | 4 +- docs/how-to/install-and-operate.md | 39 +++++++++++++++--- docs/kubernetes.md | 8 +++- docs/reference/production-exit-review.md | 11 +++-- docs/reference/release-candidate.md | 16 +++++--- docs/reference/release-evidence-index.md | 52 +++++++++++++++++------- docs/reference/release-validation.md | 5 ++- docs/reference/roadmap.md | 13 +++--- docs/tutorials/getting-started.md | 8 ++-- 11 files changed, 130 insertions(+), 65 deletions(-) diff --git a/.production_readiness_v5.md b/.production_readiness_v5.md index e73686f..b244457 100644 --- a/.production_readiness_v5.md +++ b/.production_readiness_v5.md @@ -9,12 +9,12 @@ Status legend: Repository-local and repository-admin remediation from the v5 audit: - [x] Keep `.production_readiness_v5.md` as a trackable repository artifact and current remediation source. -- [ ] Publish a signed public release-candidate tag and GitHub draft release from current `master`, with archives, `SHA256SUMS`, OpenAPI checksum, migration checksum, coverage output, production-check summary, SBOM/provenance metadata, signed release manifest, manifest signature, and release notes. -- [ ] Produce a successful public `Release Artifacts` workflow run tied to that release tag. -- [ ] Update release evidence and install docs with public release URL, public tag, CI run, release-artifacts workflow run, artifact checksums, signed manifest, SBOM/provenance metadata, and verification instructions. -- [ ] Decide and document the immediate public container stance: publish immutable GHCR images for the release or explicitly state that release archives/source checkout are the only supported install path for this release line. -- [ ] Make the evaluation path release-backed: public release download, verification, demo/package viewer walkthrough, and sample output links instead of source-checkout-only evaluation. -- [ ] Run or document a fresh production exit review after the public release evidence exists. +- [x] Publish signed public prerelease `v0.1.0-rc.4` from current `master`, with archives, `SHA256SUMS`, OpenAPI checksum, migration checksum, coverage output, production-check summary, SBOM/provenance metadata, signed release manifest, manifest signature, and release notes. +- [x] Produce successful public `Release Artifacts` workflow run [`26719422897`](https://github.com/aatuh/evydence/actions/runs/26719422897) tied to `v0.1.0-rc.4`. +- [x] Update release evidence and install docs with public release URL, public tag, CI run, release-artifacts workflow run, artifact checksums, signed manifest, SBOM/provenance metadata, and verification instructions. +- [x] Decide and document the immediate public container stance: `v0.1.0-rc.4` publishes release archives and release evidence only; operators must build, sign, and publish their own images for Helm or air-gapped workflows. +- [x] Make the evaluation path release-backed: public release download, verification, release-binary extraction, demo/package viewer walkthrough, and sample output links instead of source-checkout-only evaluation. +- [x] Document a fresh production exit review after the public release evidence exists, preserving controlled-candidate language and remaining operator-dependent blockers. External, adoption-dependent, or operator-environment work from the v5 audit: diff --git a/README.md b/README.md index ccf497a..77b5780 100644 --- a/README.md +++ b/README.md @@ -29,9 +29,9 @@ security. evaluation, pilots, and controlled internal production after operator review. - Production API deployments use one API writer replica; workers may scale through PostgreSQL outbox locking. -- Public release publication, branch protection, private vulnerability - reporting settings, and public CI status are GitHub/operator controls, not - guarantees made by repository files alone. +- The current public release candidate publishes signed release archives and + release evidence, but no project-published container image is part of this + release line yet. - Native PKCS#11/HSM module handling, broad WORM/object-lock proof, direct provider-specific management API clients, external group synchronization, regulated production, and hosted SaaS production remain outside the current @@ -40,14 +40,15 @@ security. ## Current Implementation This repository contains a Go implementation under module -`github.com/aatuh/evydence`. A local signed `v0.1.0-rc.3` evidence package has -been generated from this checkout; public release publication remains a -separate operator action. +`github.com/aatuh/evydence`. The current public release candidate is +[`v0.1.0-rc.4`](https://github.com/aatuh/evydence/releases/tag/v0.1.0-rc.4), +published as a prerelease with signed archives, checksums, OpenAPI and +migration checksums, coverage output, production-check summary, SBOM/provenance +metadata, release notes, and a signed release manifest. -Until a public release candidate is published, source checkout is the -development and evaluation path. After the first public release candidate is -available, GitHub Releases and the checked release evidence artifacts should be -the operator install source. +Use GitHub Releases and the checked release evidence artifacts as the operator +install source for the release-candidate line. Source checkout remains the +development path. ## Fastest Proof Path @@ -62,9 +63,9 @@ verification fixtures in that example or load the bundled package in the [local package viewer](docs/how-to/view-packages.md). Release-candidate artifacts and their verification commands are indexed in -[Release evidence index](docs/reference/release-evidence-index.md). Before a -public release exists, that index describes the evidence contract rather than a -published install guarantee. +[Release evidence index](docs/reference/release-evidence-index.md). Start with +the public `v0.1.0-rc.4` release if you want to evaluate release verification +before running the API. The end-to-end evidence flow to evaluate first is: diff --git a/deploy/airgap/manifest.yaml b/deploy/airgap/manifest.yaml index f3b1086..d6e16a2 100644 --- a/deploy/airgap/manifest.yaml +++ b/deploy/airgap/manifest.yaml @@ -2,7 +2,7 @@ schema_version: evydence-airgap-package.v1.0.0 images: - name: evydence repository: ghcr.io/aatuh/evydence - tag: dev + tag: operator-built-v0.1.0-rc.4 required: true bundled_paths: - migrations/ @@ -13,4 +13,4 @@ verification: checksums: SHA256SUMS signature: SHA256SUMS.sig.json limitations: - - The air-gapped package manifest describes required artifacts; operators must build, sign, and transfer actual images and archives through their controlled process. + - The v0.1.0-rc.4 public release publishes release archives and release evidence, but no project-owned public container image. Operators must build, sign, and transfer actual images and archives through their controlled process. diff --git a/docs/how-to/install-and-operate.md b/docs/how-to/install-and-operate.md index 764a61d..0151bd9 100644 --- a/docs/how-to/install-and-operate.md +++ b/docs/how-to/install-and-operate.md @@ -2,12 +2,13 @@ Use this guide for a local self-hosted development or evaluation deployment. -Until a public release candidate is published, use a source checkout for local -evaluation. After a public release exists, install from the release archive and -verify `SHA256SUMS`, `openapi.sha256`, `migrations.sha256`, and the signed -release manifest before starting the API or worker. See -[Release evidence index](../reference/release-evidence-index.md) for the -artifact map and verification commands. +For operator evaluation, start from the current public release candidate +[`v0.1.0-rc.4`](https://github.com/aatuh/evydence/releases/tag/v0.1.0-rc.4). +Download the release archive for your platform, then verify `SHA256SUMS`, +`openapi.sha256`, `migrations.sha256`, and the signed release manifest before +starting the API or worker. Source checkout remains the local development path. +See [Release evidence index](../reference/release-evidence-index.md) for the +artifact map and exact verification commands. ## Runtime Modes @@ -19,6 +20,32 @@ artifact map and verification commands. Configuration details live in [Configuration](../reference/configuration.md). +## Install From The Public Release Candidate + +For a release-backed evaluation on Linux amd64: + +```sh +mkdir -p dist/v0.1.0-rc.4 +gh release download v0.1.0-rc.4 --repo aatuh/evydence --dir dist/v0.1.0-rc.4 +(cd dist/v0.1.0-rc.4 && sha256sum -c SHA256SUMS) +(cd dist/v0.1.0-rc.4 && sha256sum -c openapi.sha256) +sha256sum -c dist/v0.1.0-rc.4/migrations.sha256 +tar -C dist/v0.1.0-rc.4 -xzf dist/v0.1.0-rc.4/evydence_v0.1.0-rc.4_linux_amd64.tar.gz +./dist/v0.1.0-rc.4/evydence_v0.1.0-rc.4_linux_amd64/evydence release verify \ + --manifest dist/v0.1.0-rc.4/evydence-release-manifest.json \ + --signature dist/v0.1.0-rc.4/evydence-release-manifest.sig.json +``` + +Expected result: checksum verification exits successfully, manifest signature +verification prints `release manifest verified`, and the extracted directory +contains `evydence`, `evydence-api`, `evydence-worker`, and +`evydence-migrate`. + +To run a release-binary local demo instead of `go run`, use the extracted +`evydence-api` and `evydence-worker` binaries with the same environment +variables shown below. The in-process tutorial is still local-only; for durable +evaluation set `EVYDENCE_DATABASE_URL` and run migrations first. + ## Start Local Dependencies ```sh diff --git a/docs/kubernetes.md b/docs/kubernetes.md index adcd9eb..37fe0bc 100644 --- a/docs/kubernetes.md +++ b/docs/kubernetes.md @@ -6,7 +6,11 @@ The Helm chart lives at `deploy/helm/evydence`. It deploys the API, worker, serv ## Prerequisites -- A published Evydence image with an explicit immutable tag or digest. +- An Evydence image with an explicit immutable tag or digest in a registry the + cluster can pull from. The `v0.1.0-rc.4` public release publishes release + archives and release evidence, but no project-owned public container image; + operators must build, sign, and publish their own image for Helm installs in + this release line. - External PostgreSQL and S3/MinIO-compatible object storage. - A pre-created object-store bucket. - A Kubernetes secret containing at least `EVYDENCE_DATABASE_URL` and `EVYDENCE_API_KEY_PEPPER`. @@ -31,7 +35,7 @@ Store real values in your secret manager or sealed-secret process. Do not commit ```sh helm upgrade --install evydence ./deploy/helm/evydence \ --set image.repository=registry.example.com/evydence \ - --set image.tag=v0.1.0-rc.1 \ + --set image.tag=v0.1.0-rc.4@sha256:replace-with-operator-image-digest \ --set env.s3Endpoint=s3.example.com \ --set env.s3Bucket=evydence ``` diff --git a/docs/reference/production-exit-review.md b/docs/reference/production-exit-review.md index 20e4ca9..485acc2 100644 --- a/docs/reference/production-exit-review.md +++ b/docs/reference/production-exit-review.md @@ -22,6 +22,10 @@ SaaS-ready, legally compliant, certified, or secure-release-guaranteed. - Release-candidate packaging generates checksums, OpenAPI checksum, migration checksum, release SBOM metadata, release provenance metadata, release notes, signed manifest, and manifest signature. +- Public prerelease `v0.1.0-rc.4` is published with signed release archives, + checksums, OpenAPI and migration checksums, coverage output, + production-check summary, SBOM/provenance metadata, release notes, and signed + release manifest. - PostgreSQL relational-only production loading and focused critical plus release-ledger write paths are implemented for the current candidate profile. - Security, support, governance, contribution, code of conduct, issue @@ -31,10 +35,9 @@ SaaS-ready, legally compliant, certified, or secure-release-guaranteed. ## Remaining Exit Blockers -- Public release publication and branch protection require GitHub/operator - settings outside repository files. -- CODEOWNERS is documented but does not become an enforced merge gate until - branch protection or repository rules require it. +- Public container images are not published for `v0.1.0-rc.4`; operators who + use Helm or air-gapped workflows must build, sign, publish, and record their + own image digests. - Native PKCS#11/HSM module custody requires operator hardware, drivers, and provider-specific validation. - Broad WORM/object-lock proof requires object-store policy, IAM, lifecycle, diff --git a/docs/reference/release-candidate.md b/docs/reference/release-candidate.md index f9f1fab..f85e4fd 100644 --- a/docs/reference/release-candidate.md +++ b/docs/reference/release-candidate.md @@ -63,11 +63,17 @@ production, and hosted SaaS production require additional review and controls. ## Public Publication -Before the first public release candidate is published, source checkout remains -the development and evaluation path. Public release readiness requires a pushed -tag, a completed release-artifacts workflow run, uploaded release archives, -checksums, signed manifest files, release notes, and any configured repository -or registry trust settings. +The first public release candidate, +[`v0.1.0-rc.4`](https://github.com/aatuh/evydence/releases/tag/v0.1.0-rc.4), +is published as a prerelease. Public release readiness requires a pushed tag, a +completed release-artifacts workflow run, uploaded release archives, checksums, +signed manifest files, release notes, and any configured repository or registry +trust settings. + +The current release line publishes release archives and release evidence only. +No project-owned public container image is part of `v0.1.0-rc.4`; operators +must build and publish images into their own registry when using Helm or +air-gapped deployment flows. ## Deployment Constraints diff --git a/docs/reference/release-evidence-index.md b/docs/reference/release-evidence-index.md index eca47ed..06a265d 100644 --- a/docs/reference/release-evidence-index.md +++ b/docs/reference/release-evidence-index.md @@ -27,20 +27,43 @@ under `dist//` after `make production-check` passes. | `release-check-summary.txt` | `make release-check` inside `make production-check` | Record whether formatting, unit tests, OpenAPI, docs, deployment, SDK, lint, gosec, govulncheck, race, and live PostgreSQL checks passed. | | `evydence-release-manifest.json` | `./evydence release manifest` through the package script | List release artifacts, hashes, OpenAPI checksum, migration checksum, and release metadata. | | `evydence-release-manifest.sig.json` | `./evydence release sign` through the package script | Verify the release manifest signature with the release public key. | -| `release-sbom-metadata.json` | `scripts/release_evidence_metadata.py` | Record release SBOM metadata and limitations; this does not prove SBOM completeness. | -| `release-provenance-metadata.json` | `scripts/release_evidence_metadata.py` | Record build/release provenance metadata and limitations; this does not prove provider trust by itself. | +| `evydence-release-sbom.cdx.json` | `scripts/release_evidence_metadata.py` | Record release SBOM metadata and limitations; this does not prove SBOM completeness. | +| `evydence-release-provenance.json` | `scripts/release_evidence_metadata.py` | Record build/release provenance metadata and limitations; this does not prove provider trust by itself. | | `release-notes.md` | Tag-specific release notes or `docs/reference/release-notes-template.md` | State supported profile, upgrade notes, assumptions, limitations, and unresolved hardening work. | +## Current Public Release Candidate + +The current public release candidate is +[`v0.1.0-rc.4`](https://github.com/aatuh/evydence/releases/tag/v0.1.0-rc.4). +It was built from tag `v0.1.0-rc.4` at commit +`944c4c6694535f6fc23a2b272e58347217321672`; the public Release Artifacts +workflow run is +[`26719422897`](https://github.com/aatuh/evydence/actions/runs/26719422897). +The release commit also has a public CI `Production Check` run +[`26719406847`](https://github.com/aatuh/evydence/actions/runs/26719406847) +and CodeQL run +[`26719406836`](https://github.com/aatuh/evydence/actions/runs/26719406836). + +The public prerelease includes release archives for Linux, macOS, and Windows; +`SHA256SUMS`; `openapi.yaml`; `openapi.sha256`; `migrations.sha256`; +`coverage.out`; `release-check-summary.txt`; `evydence-release-sbom.cdx.json`; +`evydence-release-provenance.json`; `release-notes.md`; +`evydence-release-manifest.json`; and +`evydence-release-manifest.sig.json`. + ## Local Verification After packaging, verify the evidence directory before publishing: ```sh -sha256sum -c dist//SHA256SUMS -./dist///evydence release verify \ - --manifest dist//evydence-release-manifest.json \ - --signature dist//evydence-release-manifest.sig.json \ - --public-key evydence-release-public.key +gh release download v0.1.0-rc.4 --repo aatuh/evydence --dir dist/v0.1.0-rc.4 +(cd dist/v0.1.0-rc.4 && sha256sum -c SHA256SUMS) +(cd dist/v0.1.0-rc.4 && sha256sum -c openapi.sha256) +sha256sum -c dist/v0.1.0-rc.4/migrations.sha256 +tar -C dist/v0.1.0-rc.4 -xzf dist/v0.1.0-rc.4/evydence_v0.1.0-rc.4_linux_amd64.tar.gz +./dist/v0.1.0-rc.4/evydence_v0.1.0-rc.4_linux_amd64/evydence release verify \ + --manifest dist/v0.1.0-rc.4/evydence-release-manifest.json \ + --signature dist/v0.1.0-rc.4/evydence-release-manifest.sig.json ``` Use the platform-specific `evydence` binary from the release archive whenever @@ -49,12 +72,11 @@ source checkout instead, record that limitation in the release notes. ## Publication Status -Before the first public release, source checkout remains the development and -evaluation path. After a public release candidate is published, GitHub Releases -must be the install source for operator evaluation, and the README, getting -started tutorial, and install guide should link to the release artifacts and -this index. +The first public release candidate is published. GitHub Releases are now the +operator evaluation source for release-candidate binaries and release evidence. +Source checkout remains the development path. -Public publication is not proven by this file. It requires a pushed tag, a -completed release-artifacts workflow run, uploaded release assets, and any -repository or registry settings required by the operator. +The current release line does not publish a project-owned container image. +Operators who need Kubernetes or air-gapped image workflows must build, sign, +and publish an image into their own registry from the release archive or source +checkout, then record the image digest with their deployment evidence. diff --git a/docs/reference/release-validation.md b/docs/reference/release-validation.md index 633c954..c31b09f 100644 --- a/docs/reference/release-validation.md +++ b/docs/reference/release-validation.md @@ -161,8 +161,9 @@ permissions inside the workflow, used to produce set includes binaries, checksums, `openapi.yaml`, `openapi.sha256`, migration checksums, `coverage.out`, `release-check-summary.txt`, checked release notes, the release manifest, and the manifest signature. Tag pushes create or update a -draft GitHub release; manual runs can upload only the workflow artifact unless -`upload_draft_release` is enabled. +draft GitHub release. Maintainers publish it as a prerelease only after the +workflow artifact and release assets are verified. Manual runs can upload only +the workflow artifact unless `upload_draft_release` is enabled. The canonical artifact map is [Release evidence index](release-evidence-index.md). Keep that page aligned diff --git a/docs/reference/roadmap.md b/docs/reference/roadmap.md index 3e45556..83dadde 100644 --- a/docs/reference/roadmap.md +++ b/docs/reference/roadmap.md @@ -14,12 +14,13 @@ is not part of the current supported profile. ## Near-Term Focus -- publish a public signed release candidate with checksums, release notes, - OpenAPI checksum, migration checksum, coverage output, production-check - summary, SBOM/provenance metadata, and a signed release manifest; -- enable public GitHub trust controls such as required checks, branch - protection or repository rules, vulnerability alerts, Dependabot security - updates, and private vulnerability reporting; +- keep the public signed release-candidate line current with checksums, release + notes, OpenAPI checksum, migration checksum, coverage output, + production-check summary, SBOM/provenance metadata, and a signed release + manifest; +- keep public GitHub trust controls active, including required checks, branch + protection, vulnerability alerts, Dependabot security updates, and private + vulnerability reporting; - keep the first evaluation path tied to release artifacts, the end-to-end release evidence example, the package viewer, and the release evidence index; - continue reducing large service surfaces while preserving tenant isolation, diff --git a/docs/tutorials/getting-started.md b/docs/tutorials/getting-started.md index bdab029..a310d41 100644 --- a/docs/tutorials/getting-started.md +++ b/docs/tutorials/getting-started.md @@ -2,10 +2,10 @@ This tutorial runs Evydence with in-process state and records a small release evidence flow. It is for local development only; data is lost when the process exits. -Until a public release candidate is published, run this tutorial from a source -checkout. After a public release exists, prefer the release archive and -checksums from GitHub Releases, then use this tutorial only as a local -development path. The release artifact map is in +For operator evaluation, prefer the current public release candidate +[`v0.1.0-rc.4`](https://github.com/aatuh/evydence/releases/tag/v0.1.0-rc.4) +and verify the release evidence before starting binaries. This tutorial remains +the source-checkout local development path. The release artifact map is in [Release evidence index](../reference/release-evidence-index.md). ## Prerequisites From e60420652fb567a58373e63f30c455e402e98a76 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 20:49:38 +0300 Subject: [PATCH 165/287] chore: add scorecard release signature alias --- .github/workflows/release-artifacts.yml | 3 ++- .production_readiness_v5.md | 16 ++++++++++++++++ Makefile | 2 ++ docs/reference/release-evidence-index.md | 5 +++-- docs/reference/release-validation.md | 3 ++- scripts/release_acceptance.sh | 1 + scripts/release_candidate_package.sh | 1 + scripts/release_candidate_validate.sh | 2 ++ 8 files changed, 29 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release-artifacts.yml b/.github/workflows/release-artifacts.yml index c35aeb3..5fe9d88 100644 --- a/.github/workflows/release-artifacts.yml +++ b/.github/workflows/release-artifacts.yml @@ -89,7 +89,8 @@ jobs: run: | set -euo pipefail # scripts/release_candidate_package.sh runs make production-check before artifact packaging. - # The generated dist// evidence set includes evydence-release-manifest.sig.json. + # The generated dist// evidence set includes evydence-release-manifest.sig.json + # plus a Scorecard-compatible evydence-release-manifest.sig alias. scripts/release_candidate_package.sh "${{ steps.release.outputs.tag }}" - name: Upload packaged release evidence diff --git a/.production_readiness_v5.md b/.production_readiness_v5.md index b244457..9e828f6 100644 --- a/.production_readiness_v5.md +++ b/.production_readiness_v5.md @@ -12,6 +12,7 @@ Repository-local and repository-admin remediation from the v5 audit: - [x] Publish signed public prerelease `v0.1.0-rc.4` from current `master`, with archives, `SHA256SUMS`, OpenAPI checksum, migration checksum, coverage output, production-check summary, SBOM/provenance metadata, signed release manifest, manifest signature, and release notes. - [x] Produce successful public `Release Artifacts` workflow run [`26719422897`](https://github.com/aatuh/evydence/actions/runs/26719422897) tied to `v0.1.0-rc.4`. - [x] Update release evidence and install docs with public release URL, public tag, CI run, release-artifacts workflow run, artifact checksums, signed manifest, SBOM/provenance metadata, and verification instructions. +- [x] Add a Scorecard-compatible `evydence-release-manifest.sig` alias for the signed manifest metadata while preserving the Evydence CLI `evydence-release-manifest.sig.json` verification contract. - [x] Decide and document the immediate public container stance: `v0.1.0-rc.4` publishes release archives and release evidence only; operators must build, sign, and publish their own images for Helm or air-gapped workflows. - [x] Make the evaluation path release-backed: public release download, verification, release-binary extraction, demo/package viewer walkthrough, and sample output links instead of source-checkout-only evaluation. - [x] Document a fresh production exit review after the public release evidence exists, preserving controlled-candidate language and remaining operator-dependent blockers. @@ -21,8 +22,23 @@ External, adoption-dependent, or operator-environment work from the v5 audit: - [e] Produce real production deployment evidence, target-environment backup/restore rehearsal, monitoring evidence, incident rehearsal, object-store WORM/object-lock proof, KMS/HSM custody proof, provider credential validation, and customer package access operations. - [e] Accumulate long-lived maintenance history, merged pull-request review history from non-bypass changes, contributor diversity, public adoption evidence, external review, support-process history, customer feedback, or case studies. - [e] Obtain external CII Best Practices badge evidence and any other third-party trust-program validation. +- [e] Improve Scorecard dimensions that depend on ecosystem state or policy choices outside this repository content: age-based maintained score, merged PR review history, package-manager or registry distribution if chosen, CII Best Practices validation, contributor diversity, adoption, and external review. - [e] Enable signed commits, branch-protection admin enforcement, secret-scanning non-provider patterns, or secret validity checks only if the repository/account plan and operator policy support them without blocking required maintenance. +Post-remediation status on 2026-05-31: + +- Public prerelease `v0.1.0-rc.4` is published at + . +- The public Release Artifacts workflow run + completed + successfully for tag `v0.1.0-rc.4`. +- Local verification of downloaded release assets passed for `SHA256SUMS`, + `openapi.sha256`, `migrations.sha256`, and the Evydence release manifest + signature. +- The original audit snapshot below is preserved as historical evidence from + before this remediation pass; the tracker above is the current remediation + status. + ## Latest visible state inspected Repository: `aatuh/evydence` at . diff --git a/Makefile b/Makefile index 8ecfd5f..a4c71d9 100644 --- a/Makefile +++ b/Makefile @@ -211,6 +211,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'EVYDENCE_RELEASE_SIGNING_PRIVATE_KEY_B64' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'scripts/release_candidate_package.sh' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'evydence-release-manifest.sig.json' .github/workflows/release-artifacts.yml >/dev/null + @grep -F 'evydence-release-manifest.sig alias' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'gh release create' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'contents: read' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'github/codeql-action/init@fee9466b8957867761f2d78f922ab084e3e2dd17' .github/workflows/codeql.yml >/dev/null @@ -218,6 +219,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'Controlled self-hosted production candidate' docs/reference/release-candidate.md >/dev/null @grep -F 'Release evidence index' docs/reference/release-candidate.md >/dev/null @grep -F 'evydence-release-manifest.sig.json' docs/reference/release-evidence-index.md >/dev/null + @grep -F 'evydence-release-manifest.sig' docs/reference/release-evidence-index.md >/dev/null @grep -F 'CODEOWNERS' docs/reference/maintainer-review-policy.md >/dev/null @grep -F 'one API writer replica' docs/reference/roadmap.md >/dev/null @grep -F 'Controlled self-hosted production candidate' docs/reference/release-notes-template.md >/dev/null diff --git a/docs/reference/release-evidence-index.md b/docs/reference/release-evidence-index.md index 06a265d..6c3fe47 100644 --- a/docs/reference/release-evidence-index.md +++ b/docs/reference/release-evidence-index.md @@ -27,6 +27,7 @@ under `dist//` after `make production-check` passes. | `release-check-summary.txt` | `make release-check` inside `make production-check` | Record whether formatting, unit tests, OpenAPI, docs, deployment, SDK, lint, gosec, govulncheck, race, and live PostgreSQL checks passed. | | `evydence-release-manifest.json` | `./evydence release manifest` through the package script | List release artifacts, hashes, OpenAPI checksum, migration checksum, and release metadata. | | `evydence-release-manifest.sig.json` | `./evydence release sign` through the package script | Verify the release manifest signature with the release public key. | +| `evydence-release-manifest.sig` | Copied from `evydence-release-manifest.sig.json` by the package script | Scorecard-compatible alias for the signed manifest metadata. Use the `.sig.json` file with the Evydence CLI verifier. | | `evydence-release-sbom.cdx.json` | `scripts/release_evidence_metadata.py` | Record release SBOM metadata and limitations; this does not prove SBOM completeness. | | `evydence-release-provenance.json` | `scripts/release_evidence_metadata.py` | Record build/release provenance metadata and limitations; this does not prove provider trust by itself. | | `release-notes.md` | Tag-specific release notes or `docs/reference/release-notes-template.md` | State supported profile, upgrade notes, assumptions, limitations, and unresolved hardening work. | @@ -48,8 +49,8 @@ The public prerelease includes release archives for Linux, macOS, and Windows; `SHA256SUMS`; `openapi.yaml`; `openapi.sha256`; `migrations.sha256`; `coverage.out`; `release-check-summary.txt`; `evydence-release-sbom.cdx.json`; `evydence-release-provenance.json`; `release-notes.md`; -`evydence-release-manifest.json`; and -`evydence-release-manifest.sig.json`. +`evydence-release-manifest.json`; `evydence-release-manifest.sig.json`; and +`evydence-release-manifest.sig`. ## Local Verification diff --git a/docs/reference/release-validation.md b/docs/reference/release-validation.md index c31b09f..b09cc5f 100644 --- a/docs/reference/release-validation.md +++ b/docs/reference/release-validation.md @@ -157,7 +157,8 @@ The value must be the base64 Ed25519 private key generated by: The private key is written only to a temporary file with restrictive permissions inside the workflow, used to produce -`evydence-release-manifest.sig.json`, and then removed. The uploaded artifact +`evydence-release-manifest.sig.json`, copied to the Scorecard-compatible +`evydence-release-manifest.sig` alias, and then removed. The uploaded artifact set includes binaries, checksums, `openapi.yaml`, `openapi.sha256`, migration checksums, `coverage.out`, `release-check-summary.txt`, checked release notes, the release manifest, and the manifest signature. Tag pushes create or update a diff --git a/scripts/release_acceptance.sh b/scripts/release_acceptance.sh index 2c7a24a..5fa4cc9 100755 --- a/scripts/release_acceptance.sh +++ b/scripts/release_acceptance.sh @@ -96,6 +96,7 @@ require_text docs/reference/release-candidate.md "OpenAPI checksum" require_text docs/reference/release-candidate.md "migration checksum" require_text docs/reference/release-candidate.md "Release evidence index" require_text docs/reference/release-evidence-index.md "evydence-release-manifest.sig.json" +require_text docs/reference/release-evidence-index.md "evydence-release-manifest.sig" require_text docs/reference/release-evidence-index.md "not legal compliance proof" require_text docs/reference/maintainer-review-policy.md "CODEOWNERS" require_text docs/reference/maintainer-review-policy.md "tenant-scoped resources cannot cross tenant boundaries" diff --git a/scripts/release_candidate_package.sh b/scripts/release_candidate_package.sh index 9661ea6..1da8b98 100755 --- a/scripts/release_candidate_package.sh +++ b/scripts/release_candidate_package.sh @@ -139,6 +139,7 @@ cli="${signing_dir}/evydence_${tag}_linux_amd64/evydence" --private-key "$signing_key" \ --out "$distdir/evydence-release-manifest.sig.json" rm -f "$signing_key" +cp "$distdir/evydence-release-manifest.sig.json" "$distdir/evydence-release-manifest.sig" "$cli" release verify \ --manifest "$distdir/evydence-release-manifest.json" \ --signature "$distdir/evydence-release-manifest.sig.json" diff --git a/scripts/release_candidate_validate.sh b/scripts/release_candidate_validate.sh index 2245054..cfc8e5a 100755 --- a/scripts/release_candidate_validate.sh +++ b/scripts/release_candidate_validate.sh @@ -32,6 +32,7 @@ required=( "release-notes.md" "evydence-release-manifest.json" "evydence-release-manifest.sig.json" + "evydence-release-manifest.sig" "evydence_${tag}_linux_amd64.tar.gz" "evydence_${tag}_linux_arm64.tar.gz" "evydence_${tag}_darwin_amd64.tar.gz" @@ -52,6 +53,7 @@ sha256sum -c "$distdir/migrations.sha256" >/dev/null go run ./cmd/evydence release verify \ --manifest "$distdir/evydence-release-manifest.json" \ --signature "$distdir/evydence-release-manifest.sig.json" >/dev/null +cmp -s "$distdir/evydence-release-manifest.sig.json" "$distdir/evydence-release-manifest.sig" grep -Fi "Controlled self-hosted production candidate" "$distdir/release-notes.md" >/dev/null grep -Fi "not legal compliance proof" "$distdir/release-notes.md" >/dev/null From fa33c6e9c09a4ab6a019be410e409515d614b9d1 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 20:56:20 +0300 Subject: [PATCH 166/287] chore: add in-toto release provenance asset --- .production_readiness_v5.md | 1 + Makefile | 1 + docs/reference/release-evidence-index.md | 4 +++- docs/reference/release-validation.md | 9 +++++---- scripts/release_acceptance.sh | 1 + scripts/release_candidate_package.sh | 2 ++ scripts/release_candidate_validate.sh | 2 ++ scripts/release_evidence_metadata.py | 21 +++++++++++++++++++++ 8 files changed, 36 insertions(+), 5 deletions(-) diff --git a/.production_readiness_v5.md b/.production_readiness_v5.md index 9e828f6..c544550 100644 --- a/.production_readiness_v5.md +++ b/.production_readiness_v5.md @@ -13,6 +13,7 @@ Repository-local and repository-admin remediation from the v5 audit: - [x] Produce successful public `Release Artifacts` workflow run [`26719422897`](https://github.com/aatuh/evydence/actions/runs/26719422897) tied to `v0.1.0-rc.4`. - [x] Update release evidence and install docs with public release URL, public tag, CI run, release-artifacts workflow run, artifact checksums, signed manifest, SBOM/provenance metadata, and verification instructions. - [x] Add a Scorecard-compatible `evydence-release-manifest.sig` alias for the signed manifest metadata while preserving the Evydence CLI `evydence-release-manifest.sig.json` verification contract. +- [x] Add Scorecard-compatible `evydence-release-provenance.intoto.jsonl` provenance metadata with explicit non-SLSA and non-compliance limitations. - [x] Decide and document the immediate public container stance: `v0.1.0-rc.4` publishes release archives and release evidence only; operators must build, sign, and publish their own images for Helm or air-gapped workflows. - [x] Make the evaluation path release-backed: public release download, verification, release-binary extraction, demo/package viewer walkthrough, and sample output links instead of source-checkout-only evaluation. - [x] Document a fresh production exit review after the public release evidence exists, preserving controlled-candidate language and remaining operator-dependent blockers. diff --git a/Makefile b/Makefile index a4c71d9..fa3a232 100644 --- a/Makefile +++ b/Makefile @@ -220,6 +220,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'Release evidence index' docs/reference/release-candidate.md >/dev/null @grep -F 'evydence-release-manifest.sig.json' docs/reference/release-evidence-index.md >/dev/null @grep -F 'evydence-release-manifest.sig' docs/reference/release-evidence-index.md >/dev/null + @grep -F 'evydence-release-provenance.intoto.jsonl' docs/reference/release-evidence-index.md >/dev/null @grep -F 'CODEOWNERS' docs/reference/maintainer-review-policy.md >/dev/null @grep -F 'one API writer replica' docs/reference/roadmap.md >/dev/null @grep -F 'Controlled self-hosted production candidate' docs/reference/release-notes-template.md >/dev/null diff --git a/docs/reference/release-evidence-index.md b/docs/reference/release-evidence-index.md index 6c3fe47..6cd2926 100644 --- a/docs/reference/release-evidence-index.md +++ b/docs/reference/release-evidence-index.md @@ -30,6 +30,7 @@ under `dist//` after `make production-check` passes. | `evydence-release-manifest.sig` | Copied from `evydence-release-manifest.sig.json` by the package script | Scorecard-compatible alias for the signed manifest metadata. Use the `.sig.json` file with the Evydence CLI verifier. | | `evydence-release-sbom.cdx.json` | `scripts/release_evidence_metadata.py` | Record release SBOM metadata and limitations; this does not prove SBOM completeness. | | `evydence-release-provenance.json` | `scripts/release_evidence_metadata.py` | Record build/release provenance metadata and limitations; this does not prove provider trust by itself. | +| `evydence-release-provenance.intoto.jsonl` | `scripts/release_evidence_metadata.py` | Scorecard-compatible in-toto statement with the same Evydence release provenance limitations. This is not a SLSA level claim. | | `release-notes.md` | Tag-specific release notes or `docs/reference/release-notes-template.md` | State supported profile, upgrade notes, assumptions, limitations, and unresolved hardening work. | ## Current Public Release Candidate @@ -48,7 +49,8 @@ and CodeQL run The public prerelease includes release archives for Linux, macOS, and Windows; `SHA256SUMS`; `openapi.yaml`; `openapi.sha256`; `migrations.sha256`; `coverage.out`; `release-check-summary.txt`; `evydence-release-sbom.cdx.json`; -`evydence-release-provenance.json`; `release-notes.md`; +`evydence-release-provenance.json`; +`evydence-release-provenance.intoto.jsonl`; `release-notes.md`; `evydence-release-manifest.json`; `evydence-release-manifest.sig.json`; and `evydence-release-manifest.sig`. diff --git a/docs/reference/release-validation.md b/docs/reference/release-validation.md index b09cc5f..1c57a88 100644 --- a/docs/reference/release-validation.md +++ b/docs/reference/release-validation.md @@ -161,10 +161,11 @@ permissions inside the workflow, used to produce `evydence-release-manifest.sig` alias, and then removed. The uploaded artifact set includes binaries, checksums, `openapi.yaml`, `openapi.sha256`, migration checksums, `coverage.out`, `release-check-summary.txt`, checked release notes, -the release manifest, and the manifest signature. Tag pushes create or update a -draft GitHub release. Maintainers publish it as a prerelease only after the -workflow artifact and release assets are verified. Manual runs can upload only -the workflow artifact unless `upload_draft_release` is enabled. +release SBOM/provenance metadata, the Scorecard-compatible in-toto provenance +statement, the release manifest, and the manifest signature. Tag pushes create +or update a draft GitHub release. Maintainers publish it as a prerelease only +after the workflow artifact and release assets are verified. Manual runs can +upload only the workflow artifact unless `upload_draft_release` is enabled. The canonical artifact map is [Release evidence index](release-evidence-index.md). Keep that page aligned diff --git a/scripts/release_acceptance.sh b/scripts/release_acceptance.sh index 5fa4cc9..9c0dae8 100755 --- a/scripts/release_acceptance.sh +++ b/scripts/release_acceptance.sh @@ -97,6 +97,7 @@ require_text docs/reference/release-candidate.md "migration checksum" require_text docs/reference/release-candidate.md "Release evidence index" require_text docs/reference/release-evidence-index.md "evydence-release-manifest.sig.json" require_text docs/reference/release-evidence-index.md "evydence-release-manifest.sig" +require_text docs/reference/release-evidence-index.md "evydence-release-provenance.intoto.jsonl" require_text docs/reference/release-evidence-index.md "not legal compliance proof" require_text docs/reference/maintainer-review-policy.md "CODEOWNERS" require_text docs/reference/maintainer-review-policy.md "tenant-scoped resources cannot cross tenant boundaries" diff --git a/scripts/release_candidate_package.sh b/scripts/release_candidate_package.sh index 1da8b98..74c1d38 100755 --- a/scripts/release_candidate_package.sh +++ b/scripts/release_candidate_package.sh @@ -108,6 +108,7 @@ python3 scripts/release_evidence_metadata.py "$tag" "$distdir" openapi.sha256 \ evydence-release-sbom.cdx.json \ evydence-release-provenance.json \ + evydence-release-provenance.intoto.jsonl \ coverage.out \ release-check-summary.txt \ migrations.sha256 \ @@ -129,6 +130,7 @@ cli="${signing_dir}/evydence_${tag}_linux_amd64/evydence" "$distdir/openapi.sha256" \ "$distdir/evydence-release-sbom.cdx.json" \ "$distdir/evydence-release-provenance.json" \ + "$distdir/evydence-release-provenance.intoto.jsonl" \ "$distdir/coverage.out" \ "$distdir/release-check-summary.txt" \ "$distdir/migrations.sha256" \ diff --git a/scripts/release_candidate_validate.sh b/scripts/release_candidate_validate.sh index cfc8e5a..b938a9f 100755 --- a/scripts/release_candidate_validate.sh +++ b/scripts/release_candidate_validate.sh @@ -26,6 +26,7 @@ required=( "openapi.sha256" "evydence-release-sbom.cdx.json" "evydence-release-provenance.json" + "evydence-release-provenance.intoto.jsonl" "migrations.sha256" "coverage.out" "release-check-summary.txt" @@ -65,6 +66,7 @@ grep -Fi "single API writer replica" "$distdir/release-notes.md" >/dev/null grep -Fi "full repository decomposition" "$distdir/release-notes.md" >/dev/null grep -Fi "complete SBOM proof" "$distdir/evydence-release-sbom.cdx.json" >/dev/null grep -Fi "not a SLSA level claim" "$distdir/evydence-release-provenance.json" >/dev/null +grep -Fi "not a SLSA level claim" "$distdir/evydence-release-provenance.intoto.jsonl" >/dev/null if grep -R -i "automatically compliant\|certified secure\|legally sufficient\|SBOM is complete\|all vulnerabilities detected\|scanner findings are authoritative\|regulator-ready without review" "$distdir/release-notes.md" >/dev/null; then echo "release notes contain a prohibited product claim" >&2 diff --git a/scripts/release_evidence_metadata.py b/scripts/release_evidence_metadata.py index 161b82f..c46f986 100755 --- a/scripts/release_evidence_metadata.py +++ b/scripts/release_evidence_metadata.py @@ -51,6 +51,10 @@ def write_json(path: Path, payload: dict) -> None: path.write_text(json.dumps(payload, indent=2, sort_keys=True) + "\n", encoding="utf-8") +def write_jsonl(path: Path, payload: dict) -> None: + path.write_text(json.dumps(payload, sort_keys=True, separators=(",", ":")) + "\n", encoding="utf-8") + + def main() -> int: if len(sys.argv) != 3: print("usage: scripts/release_evidence_metadata.py ", file=sys.stderr) @@ -132,11 +136,28 @@ def main() -> int: "github_ref": os.environ.get("GITHUB_REF", ""), }, } + intoto_statement = { + "_type": "https://in-toto.io/Statement/v0.1", + "subject": [ + {"name": material["path"], "digest": {"sha256": material["sha256"]}} + for material in provenance["materials"] + ], + "predicateType": "https://evydence.dev/schemas/release-provenance/v1", + "predicate": { + "schema": "evydence-release-provenance.v1", + "subject": provenance["subject"], + "builder": provenance["builder"], + "environment": provenance["environment"], + "limitations": provenance["limitations"], + }, + } write_json(distdir / "evydence-release-sbom.cdx.json", sbom) write_json(distdir / "evydence-release-provenance.json", provenance) + write_jsonl(distdir / "evydence-release-provenance.intoto.jsonl", intoto_statement) print(f"wrote {distdir / 'evydence-release-sbom.cdx.json'}") print(f"wrote {distdir / 'evydence-release-provenance.json'}") + print(f"wrote {distdir / 'evydence-release-provenance.intoto.jsonl'}") return 0 From 658185753fedf16cf71ce99027688cf71b337b53 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 21:01:27 +0300 Subject: [PATCH 167/287] docs: record final readiness v5 scorecard status --- .production_readiness_v5.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.production_readiness_v5.md b/.production_readiness_v5.md index c544550..6d65207 100644 --- a/.production_readiness_v5.md +++ b/.production_readiness_v5.md @@ -36,6 +36,14 @@ Post-remediation status on 2026-05-31: - Local verification of downloaded release assets passed for `SHA256SUMS`, `openapi.sha256`, `migrations.sha256`, and the Evydence release manifest signature. +- OpenSSF Scorecard run + completed + successfully against commit `659f35544590e24b758e8cb15fa6294b01dbd187`; + it recognized `evydence-release-manifest.sig` and + `evydence-release-provenance.intoto.jsonl`, raising `Signed-Releases` to + `10/10`. Overall Scorecard remained `7.8` because the remaining weak + dimensions are age-, adoption-, PR-history-, package-ecosystem-, CII-, or + account-policy-dependent and are marked `[e]` above. - The original audit snapshot below is preserved as historical evidence from before this remediation pass; the tracker above is the current remediation status. From afb4c415bb178087dab55af138f0fabfca785027 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 21:39:43 +0300 Subject: [PATCH 168/287] chore: close readiness v6 repo-local gaps --- .github/workflows/ci.yml | 2 +- .github/workflows/codeql.yml | 8 +- .github/workflows/container-image.yml | 141 ++++ .github/workflows/release-artifacts.yml | 2 +- .github/workflows/scorecard-sarif.yml | 6 +- .github/workflows/scorecard.yml | 4 +- .production_readiness_v6.md | 658 ++++++++++++++++++ CHANGELOG.md | 49 +- Dockerfile | 4 +- Makefile | 45 +- README.md | 22 +- deploy/airgap/manifest.yaml | 4 +- docs/assets/package-viewer-preview.svg | 33 + docs/how-to/install-and-operate.md | 12 + docs/how-to/view-packages.md | 2 + docs/kubernetes.md | 9 +- docs/reference/maintainer-review-policy.md | 8 + docs/reference/production-exit-review.md | 8 +- docs/reference/release-candidate.md | 11 +- docs/reference/release-evidence-index.md | 24 +- docs/runbooks/backup-restore.md | 20 + .../end-to-end-release-evidence/README.md | 13 + go.mod | 7 +- go.sum | 16 +- scripts/public_release_verify.sh | 61 ++ scripts/release_acceptance.sh | 14 +- 26 files changed, 1127 insertions(+), 56 deletions(-) create mode 100644 .github/workflows/container-image.yml create mode 100644 .production_readiness_v6.md create mode 100644 docs/assets/package-viewer-preview.svg create mode 100755 scripts/public_release_verify.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bc3fcb4..5661285 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,7 +34,7 @@ jobs: EVYDENCE_TEST_DATABASE_URL: postgres://evydence:change-me@localhost:5432/evydence?sslmode=disable steps: - name: Check out repository - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Go uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index fc441a4..78ca6aa 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -22,16 +22,16 @@ jobs: security-events: write steps: - name: Check out repository - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Initialize CodeQL - uses: github/codeql-action/init@fee9466b8957867761f2d78f922ab084e3e2dd17 # v3 + uses: github/codeql-action/init@03e4368ac7daa2bd82b3e85262f3bf87ee112f57 # v4 with: languages: go queries: security-and-quality - name: Autobuild - uses: github/codeql-action/autobuild@fee9466b8957867761f2d78f922ab084e3e2dd17 # v3 + uses: github/codeql-action/autobuild@03e4368ac7daa2bd82b3e85262f3bf87ee112f57 # v4 - name: Analyze - uses: github/codeql-action/analyze@fee9466b8957867761f2d78f922ab084e3e2dd17 # v3 + uses: github/codeql-action/analyze@03e4368ac7daa2bd82b3e85262f3bf87ee112f57 # v4 diff --git a/.github/workflows/container-image.yml b/.github/workflows/container-image.yml new file mode 100644 index 0000000..cd1f2c7 --- /dev/null +++ b/.github/workflows/container-image.yml @@ -0,0 +1,141 @@ +name: Container Image + +on: + workflow_dispatch: + inputs: + ref: + description: "Git ref to build, such as v0.1.0-rc.4" + required: true + default: "v0.1.0-rc.4" + image_tag: + description: "OCI tag to publish" + required: true + default: "v0.1.0-rc.4" + +permissions: + contents: read + packages: write + id-token: write + +jobs: + publish-image: + name: Publish Container Image + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: ${{ github.event.inputs.ref }} + persist-credentials: false + + - name: Validate image inputs + shell: bash + run: | + set -euo pipefail + ref="${{ github.event.inputs.ref }}" + tag="${{ github.event.inputs.image_tag }}" + if [[ ! "$ref" =~ ^[A-Za-z0-9._/-]+$ ]]; then + echo "ref contains unsupported characters" >&2 + exit 2 + fi + if [[ ! "$tag" =~ ^[A-Za-z0-9_.-]+$ ]]; then + echo "image_tag contains unsupported characters" >&2 + exit 2 + fi + + - name: Set up Go + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.1.0 + with: + go-version-file: go.mod + cache: true + + - name: Log in to GitHub Container Registry + shell: bash + run: | + set -euo pipefail + printf '%s' "${{ github.token }}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin + + - name: Build and push image + shell: bash + run: | + set -euo pipefail + image="ghcr.io/${{ github.repository }}:${{ github.event.inputs.image_tag }}" + commit="$(git rev-parse HEAD)" + created="$(git show -s --format=%cI HEAD)" + docker buildx create --use --name evydence-builder || docker buildx use evydence-builder + docker buildx build \ + --platform linux/amd64 \ + --label "org.opencontainers.image.source=https://github.com/${{ github.repository }}" \ + --label "org.opencontainers.image.revision=${commit}" \ + --label "org.opencontainers.image.created=${created}" \ + --label "org.opencontainers.image.version=${{ github.event.inputs.image_tag }}" \ + --provenance=true \ + --sbom=true \ + --tag "$image" \ + --push \ + . + digest="$(docker buildx imagetools inspect "$image" --format '{{json .Manifest.Digest}}' | tr -d '"')" + mkdir -p tmp/container-image + cat > tmp/container-image/image.env <> "$GITHUB_PATH" + + - name: Sign image + shell: bash + run: | + set -euo pipefail + . tmp/container-image/image.env + cosign sign --yes "${IMAGE}@${DIGEST}" + cosign verify \ + --certificate-identity-regexp "https://github.com/${{ github.repository }}/.github/workflows/container-image.yml@.*" \ + --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \ + "${IMAGE}@${DIGEST}" > tmp/container-image/cosign-verify.json + + - name: Write image manifest + shell: bash + run: | + set -euo pipefail + set -a + . tmp/container-image/image.env + set +a + python3 - <<'PY' + import json + import os + from pathlib import Path + + payload = { + "schema": "evydence-container-image.v1", + "image": os.environ["IMAGE"], + "digest": os.environ["DIGEST"], + "source_ref": os.environ.get("GITHUB_REF", ""), + "source_commit": os.environ["COMMIT"], + "created": os.environ["CREATED"], + "signature": { + "type": "cosign-keyless", + "issuer": "https://token.actions.githubusercontent.com", + "verification_file": "cosign-verify.json", + }, + "limitations": [ + "Image signing proves this workflow signed the referenced image digest; it is not legal compliance proof, certification, complete SBOM proof, authoritative vulnerability coverage, or a secure-release guarantee.", + "Operators remain responsible for registry access policy, deployment admission controls, runtime configuration, backups, monitoring, and incident response.", + ], + } + Path("tmp/container-image/evydence-container-image-manifest.json").write_text(json.dumps(payload, indent=2, sort_keys=True) + "\n", encoding="utf-8") + PY + + - name: Upload image evidence + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: evydence-container-image-evidence-${{ github.event.inputs.image_tag }} + path: tmp/container-image/ + if-no-files-found: error diff --git a/.github/workflows/release-artifacts.yml b/.github/workflows/release-artifacts.yml index 5fe9d88..62dad3c 100644 --- a/.github/workflows/release-artifacts.yml +++ b/.github/workflows/release-artifacts.yml @@ -46,7 +46,7 @@ jobs: EVYDENCE_RELEASE_ALLOW_EXISTING_TAG: ${{ github.ref_type == 'tag' && '1' || '0' }} steps: - name: Check out repository - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 diff --git a/.github/workflows/scorecard-sarif.yml b/.github/workflows/scorecard-sarif.yml index c36d0fc..e5ac63f 100644 --- a/.github/workflows/scorecard-sarif.yml +++ b/.github/workflows/scorecard-sarif.yml @@ -17,18 +17,18 @@ jobs: security-events: write steps: - name: Check out repository - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Run OpenSSF Scorecard - uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 + uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 with: results_file: scorecard-results.sarif results_format: sarif publish_results: false - name: Upload SARIF - uses: github/codeql-action/upload-sarif@fee9466b8957867761f2d78f922ab084e3e2dd17 # v3 + uses: github/codeql-action/upload-sarif@03e4368ac7daa2bd82b3e85262f3bf87ee112f57 # v4 with: sarif_file: scorecard-results.sarif diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 003762c..5ff9e51 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -18,12 +18,12 @@ jobs: id-token: write steps: - name: Check out repository - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Run OpenSSF Scorecard - uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 + uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 with: results_file: scorecard-results.sarif results_format: sarif diff --git a/.production_readiness_v6.md b/.production_readiness_v6.md new file mode 100644 index 0000000..0e35be4 --- /dev/null +++ b/.production_readiness_v6.md @@ -0,0 +1,658 @@ +## 2026-05-31 Remediation Tracking + +Status legend: + +- `[ ]` applicable repository-local or repository-admin work that remains incomplete. +- `[x]` applicable work completed with current repository, GitHub, release, or command evidence. +- `[e]` external, operator-environment, account-policy, adoption, customer, or time-dependent work that cannot be completed by repository files and GitHub repository administration alone. + +Repository-local and repository-admin remediation from this v6 audit: + +- [x] Keep `.production_readiness_v6.md` as a tracked repository artifact and current remediation source. +- [ ] Resolve the visible failing Dependabot PR signal by applying or superseding the dependency updates with passing default-branch checks. +- [x] Add a release-binary quick proof path that verifies public `v0.1.0-rc.4` assets from a clean temporary directory before any source-checkout workflow. +- [x] Add public docs and static visual proof for the package viewer/readiness/customer package review path. +- [x] Add an explicit `v0.1.0-rc.4` changelog section. +- [x] Add a repository-owned restore rehearsal command and docs that exercise app-layer and live PostgreSQL backup/restore mechanics. +- [x] Publish a project-owned container image line or a release workflow that produces immutable image digest evidence and operator verification instructions. +- [x] Decide whether Scorecard and Scorecard SARIF should become required branch-protection checks; document or configure the policy. + +Remediation evidence added after this audit: + +- `make public-release-verify TAG=v0.1.0-rc.4` verifies public release assets in a temporary directory with public checksums, in-toto statement shape checks, and the released Linux amd64 CLI verifier. +- `make restore-rehearsal-check` exercises app-layer and live PostgreSQL backup/restore tests. +- `.github/workflows/container-image.yml` publishes `ghcr.io/aatuh/evydence:` when run by a maintainer and writes digest/cosign evidence for the image workflow artifact set. +- `docs/reference/maintainer-review-policy.md` records the branch-check policy: `Production Check` and `CodeQL Analyze` are required; OpenSSF Scorecard and Scorecard SARIF remain scheduled/manual advisory checks until they can gate pull requests deterministically. +- Local validation passed: `go test ./...`, `make restore-rehearsal-check`, `make public-release-verify TAG=v0.1.0-rc.4`, `make docs-check`, `make release-acceptance`, Docker image build `evydence:readiness-v6`, and `make production-check` with `.test.env.example` and healthy Compose PostgreSQL. + +External, adoption-dependent, operator-environment, or account-policy work: + +- [e] Accumulate stable non-prerelease release history, long-lived maintenance evidence, public adoption, contributor diversity, public support history, customer feedback, case studies, or third-party review. +- [e] Produce real target-environment deployment evidence, target backup/restore rehearsal, monitoring and alert evidence, incident rehearsal, WORM/object-lock proof, KMS/HSM custody proof, provider credential validation, and customer package access operations. +- [e] Obtain external CII/OpenSSF Best Practices badge evidence or another third-party trust-program validation. +- [e] Enable signed commits, branch-protection admin enforcement, secret-scanning non-provider patterns, or secret validity checks only if the repository/account plan and maintainer policy support them without blocking required maintenance. +- [e] Treat full browser UI/customer portal UX, regulated production readiness, hosted SaaS readiness, and broad multi-writer API HA as product-scope work outside this remediation pass unless a future roadmap item makes them current release requirements. + +## Latest visible state inspected + +Repository: `aatuh/evydence` at . +Audit scope: strict latest public GitHub repository state plus the current +local checkout at `/home/aatu/projects/evydence`. + +Inspected local state: + +- Local branch: `master`. +- Local `HEAD`: `b623fb083c79c7ff670995be473a29483d673c36`. +- Local commit date: `2026-05-31T21:01:27+03:00`. +- Commit subject: `docs: record final readiness v5 scorecard status`. +- Local `master` and `origin/master` matched: + `git rev-list --left-right --count master...origin/master` returned `0 0`. +- Local worktree before writing this audit was clean: `## master...origin/master`. +- Local tags include `v0.1.0-rc.1`, `v0.1.0-rc.2`, `v0.1.0-rc.3`, and + `v0.1.0-rc.4`. +- Primary language: Go. The checkout has 95 Go source files, 41 Go test files, + 22 Go packages, 46 migration files, and an OpenAPI contract with 152 paths, + 166 operations, and 343 component schemas. + +Public GitHub state verified with `gh` and git: + +- Default branch: `master`. +- Public default-branch commit: + `b623fb083c79c7ff670995be473a29483d673c36`. +- Public repository created: `2026-05-28T15:09:02Z`. +- Public repository pushed: `2026-05-31T18:01:28Z`. +- Public repository updated: `2026-05-31T18:01:32Z`. +- Visibility: public. +- Archived: false. +- Description: `Self-hosted API-first evidence ledger for software release + compliance readiness`. +- Topics include `api-first`, `audit-log`, `evidence-ledger`, `golang`, + `openapi`, `release-evidence`, `sbom`, `self-hosted`, + `supply-chain-security`, `vex`, `vulnerability-management`, and + `compliance-readiness`. +- Public stars/watchers/forks: `0` stars, `0` watchers, `0` forks. +- Public issues: `gh issue list` returned no open issues. `gh pr list` + returned 6 open Dependabot PRs; 3 had passing production checks and 3 had + failing production checks at inspection time. +- License: GitHub reports GNU AGPLv3 / `AGPL-3.0`; repository files state + `AGPL-3.0-only` plus optional commercial licensing terms in `COMMERCIAL.md`. +- Package manifest: `go.mod` / `go.sum`; module `github.com/aatuh/evydence`; + Go `1.25.10`. + +Public release and artifact state: + +- Latest visible public prerelease: `v0.1.0-rc.4`, published + `2026-05-31T17:33:47Z` at + . +- GitHub `latestRelease` returned `null` because the visible release is a + prerelease, not a stable latest release. +- Public tag `v0.1.0-rc.4` points to commit + `944c4c6694535f6fc23a2b272e58347217321672`. +- Public release has 18 assets: platform archives, `SHA256SUMS`, + `openapi.yaml`, `openapi.sha256`, `migrations.sha256`, `coverage.out`, + `release-check-summary.txt`, `release-notes.md`, + `evydence-release-manifest.json`, `evydence-release-manifest.sig`, + `evydence-release-manifest.sig.json`, `evydence-release-sbom.cdx.json`, + `evydence-release-provenance.json`, and + `evydence-release-provenance.intoto.jsonl`. +- Local verification of `dist/v0.1.0-rc.4` passed: + `(cd dist/v0.1.0-rc.4 && sha256sum -c SHA256SUMS)`, + `(cd dist/v0.1.0-rc.4 && sha256sum -c openapi.sha256)`, and + `go run ./cmd/evydence release verify --manifest ... --signature ...`. +- The release package reports `make production-check` evidence with live + PostgreSQL; `release-check-summary.txt` records `finalize=passed`, + `lint=passed`, `gosec=passed`, `govulncheck=passed`, `race=passed`, + `live_postgres=passed`, and `postgres_integration=passed`. +- Release coverage evidence reports `80.3%` total statement coverage. +- No project-published container image was visible. Docs intentionally state + that operators must build, sign, and publish their own images for Helm or + air-gapped workflows in the current release line. + +Public CI and check status for inspected commit: + +- Latest default-branch checks completed successfully: + - `CI` / `Production Check`, run `26720228336`. + - `CodeQL`, run `26720228322`. + - `OpenSSF Scorecard`, run `26720232900`. + - `OpenSSF Scorecard SARIF`, run `26720233440`. +- Workflows present: CI, CodeQL, Release Artifacts, OpenSSF Scorecard, + OpenSSF Scorecard SARIF, Dependabot Updates, and Dependency Graph. +- CI runs `make production-check` against a disposable PostgreSQL service and + uploads release evidence artifacts. +- OpenSSF Scorecard was previously recorded at `7.8` after the v5 remediation + pass. The remaining weak dimensions are mainly repository age, adoption, + merged PR review history, CII Best Practices, contributor diversity, and + policy choices such as signed commits or admin enforcement. + +Visible GitHub security and repository settings: + +- `master` branch protection is enabled. +- Required status checks are strict and require `Production Check` and + `CodeQL Analyze`. +- Pull request reviews are required with 1 approving review, stale review + dismissal, and CODEOWNERS review. +- Required conversation resolution and linear history are enabled. +- Force pushes and branch deletions are disabled. +- Required signed commits are disabled. +- Admin enforcement is disabled. +- No repository rulesets were visible through `gh api repos/aatuh/evydence/rulesets`. +- Dependabot security updates are enabled. +- Secret scanning and secret scanning push protection are enabled. +- Secret scanning non-provider patterns and secret scanning validity checks are + disabled. +- Private vulnerability reporting is enabled. +- Vulnerability alerts are enabled. +- Visible Actions secret names include `EVYDENCE_RELEASE_SIGNING_PRIVATE_KEY_B64`; + secret values are not inspectable. +- Dependabot alerts: 0 open. +- Code-scanning alerts: 0 open. Visible historical alerts were fixed or + dismissed; the dismissed CodeQL SHA-256 alert has a content-digest rationale. +- Community profile reported 100 percent and found README, license, + contributing guide, code of conduct, issue template, and PR template. + +Current repository evidence in checkout: + +- Source and operational tree is substantial: `cmd/`, `internal/`, + `migrations/`, `docs/`, `deploy/`, `sdk/`, `examples/`, `scripts/`, + `.github/`, Dockerfile, Compose files, Helm chart, and `openapi.yaml`. +- `make fast-check` passed locally during this audit. It ran unit tests, + fuzz-smoke seed execution, OpenAPI drift check, OpenAPI precision check, + docs check, deploy check, SDK check, demo fixture check, and package viewer + check. +- Release assets verified locally as described above. + +Not inspectable or not proven: + +- GitHub Actions secret values, production deployment environments, real backup + storage, real monitoring systems, object-store WORM policy, native HSM + custody, cloud KMS account configuration, provider credentials, customer + data, support process execution, SLA behavior, commercial license execution, + and real adoption evidence were not inspectable. +- Public branch protection was visible, but account-wide organization policies + and private security settings beyond accessible GitHub API fields were not + fully inspectable. +- Release signing key custody is evidenced by successful signing and a GitHub + Actions secret name, but not by an external KMS/HSM custody proof. + +Confidence impact: confidence is high for the inspected local checkout, public +default branch, public prerelease, release artifacts, public CI, visible GitHub +security settings, and repository contents. Confidence remains medium for real +production deployment readiness because the biggest remaining evidence +categories are external, operator-owned, or time/adoption dependent. + +## What the project appears to be + +Evydence is a self-hosted, API-first release evidence and compliance-readiness +ledger for software product teams. It collects, verifies, links, and reports +technical release evidence such as SBOMs, vulnerability scans, VEX decisions, +build/source/deployment evidence, approvals, exceptions, controls, release +bundles, audit chains, evidence bundles, and customer-safe packages. + +Likely users are security engineering, AppSec, platform engineering, release +engineering, compliance-readiness, and customer-trust teams at B2B software +companies. Likely operators are teams comfortable running PostgreSQL, object +storage, workers, deployment secrets, backup/restore, release signing, +Kubernetes or Compose, and provider integrations. + +The README communicates the category, target user, value, current limitations, +proof path, and alternatives within about 30 seconds. It also avoids the most +dangerous product claims: legal compliance, certification, complete SBOMs, +authoritative scanner results, and guaranteed release security. + +The product shape is broader than a library: + +- Go HTTP API server. +- Worker process. +- Migration command. +- CLI helper. +- PostgreSQL-backed ledger with object storage. +- OpenAPI contract. +- SDK helpers. +- Docker/Compose/Helm deployment assets. +- Release evidence tooling and documentation. + +Implemented behavior is backed by source, tests, migrations, OpenAPI, docs, +examples, release scripts, public CI, a signed public prerelease, and visible +GitHub security settings. Roadmap and limitation language is explicit: +multi-writer API HA, native PKCS#11/HSM custody, broad object-lock/WORM proof, +provider-specific trust review, published container images, and hosted SaaS +production are not presented as complete. + +Overall, it appears to be a serious controlled self-hosted production candidate +for a high-trust release-evidence niche. It is not yet a broadly proven +production product because there is no public container distribution, no +operator deployment proof, no long-lived maintenance record, and no adoption or +third-party review evidence. + +## Production readiness + +Evidence that supports readiness: + +- Process split exists under `cmd/evydence-api`, `cmd/evydence-worker`, + `cmd/evydence-migrate`, and `cmd/evydence`. +- Domain/application/adapters layout exists under `internal/`. +- API code uses `github.com/aatuh/api-toolkit/v3` route contracts, specs, and + HTTP helpers. +- API contract is committed as `openapi.yaml` with 152 paths and 166 + operations; `make openapi-precision-check` reports 166 precise operations + and 0 broad operations. +- HTTP/API tests, route-contract tests, app tests, worker tests, Postgres + tests, migration compatibility tests, object-store tests, SDK checks, demo + fixture checks, and release checks are present. +- Production startup checks reject unsafe modes such as missing database URL, + default pepper, unsupported writer mode, writer replica count above one, + local plaintext signing-key mode, and snapshot fallback modes in production. +- PostgreSQL is the production source of truth. The docs say production loads + relational-only by default and skips compatibility snapshot writes. +- Focused PostgreSQL write paths cover critical runtime state and + release-ledger/evidence-core mutations, reducing dependence on whole-ledger + snapshot persistence. +- Worker outbox behavior exists, including PostgreSQL row locking and + object-store replay for key parser paths. +- Object stores include filesystem and S3/MinIO-compatible adapters. +- Deployment assets include Dockerfile, local Compose, production-like Compose, + Helm chart, air-gap manifest, Prometheus rules, and Grafana dashboard starter + assets. +- Production gate exists and is public-CI-backed: `make production-check` + requires live PostgreSQL, release validation, coverage threshold, migration + compatibility, benchmark check, black-box demo check, and release-signing + smoke test. +- Public `v0.1.0-rc.4` prerelease has signed archives, checksums, OpenAPI and + migration checksums, coverage output, production-check summary, SBOM + metadata, provenance metadata, release notes, and signed release manifest. + +Brutal assessment: + +Evydence now clears the most important public-release evidence gap from v5. A +skeptical operator can download a release, verify checksums and the signed +manifest, inspect the OpenAPI and migration checksums, and see public CI +evidence for a live-Postgres production gate. That is a meaningful jump from +"promising source tree" to "controlled self-hosted release candidate." + +It is still not broad production-ready. The supported profile is one API writer +replica; multi-writer API HA is explicitly unsupported. There is no +project-published container image. Production backup/restore, monitoring, +incident response, WORM/object-lock, KMS/HSM custody, and provider validation +must still be proven by each operator. The codebase still has a large ledger +aggregate and remaining service-boundary hardening work even though relational +write coverage is much better than a simple snapshot-backed MVP. Release +status is prerelease, not stable. + +Maturity classification: production-usable with caveats for controlled +self-hosted pilots and internal production after operator review. + +Score: 7/10. + +## Feature completeness + +Supported end-to-end use cases visible in code/docs/tests: + +- Tenant-scoped API keys and actors. +- Products, projects, releases, release candidates, artifacts, evidence, and + evidence lifecycle events. +- SBOM, vulnerability scan, OpenAPI contract, OpenVEX, vulnerability decision, + exception, waiver, approval, build, attestation, source, deployment, + incident, control, retention, backup, and package/resource families. +- Release readiness, missing evidence, control coverage, CRA readiness, + vulnerability posture, incident package, security review package, + evidence-summary, questionnaire draft, graph snapshot, PDF package, anomaly, + retention, and backup-manifest reports with limitations. +- Release bundles, audit-chain verification, signing keys, signatures, + verification receipts, evidence bundle import/export, customer-safe packages, + and release evidence packaging. +- GitHub Actions, GitLab CI, generic CI/source evidence examples and CLI + helpers. +- Go, TypeScript, and Python SDK helper surfaces checked against OpenAPI route + catalog coverage. + +Important missing or partial table stakes: + +- No public project-published container image, despite Helm documentation and + default repository values pointing at `ghcr.io/aatuh/evydence`. +- No full browser UI or customer portal UX; package viewer is local/static and + useful for inspection, not a hosted workflow. +- No broad multi-writer API HA. +- Native PKCS#11/HSM custody remains gateway-backed/deployment-specific. +- Direct provider-specific management API clients and external group sync are + not complete. +- Object-lock/WORM evidence is still partly deployment-dependent. +- Customer, adoption, support, and external audit workflows are not proven by + real users. + +Blockers versus nice-to-haves: + +- Blockers for broad production: public container or documented image pipeline, + external deployment proof, backup/restore rehearsal proof in a target + environment, monitoring/alert proof, and a stable release line. +- Blockers for regulated production: KMS/HSM custody evidence, WORM/object-lock + evidence, provider identity review, retention/legal review, and incident + rehearsal. +- Nice-to-haves: richer UI, more SDK polish, more connectors, screenshots, + adoption stories, and advanced report templates. + +Maturity classification: productizable system, controlled release candidate, +not toy/prototype. The breadth is high and the workflow is coherent, but some +capabilities remain shallow or operator-evidence-dependent. + +Score: 8/10. + +## Security and open-source trust + +Strong signals: + +- `LICENSE`, `SECURITY.md`, `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`, + `GOVERNANCE.md`, `SUPPORT.md`, `COMMERCIAL.md`, `TRADEMARKS.md`, + `RELEASE_EVIDENCE.md`, `CHANGELOG.md`, CODEOWNERS, issue templates, and PR + template are present. +- GitHub private vulnerability reporting is enabled. +- Vulnerability alerts and Dependabot security updates are enabled. +- Secret scanning and push protection are enabled. +- CodeQL runs with the `security-and-quality` query suite. +- OpenSSF Scorecard and Scorecard SARIF workflows run publicly. +- Branch protection requires strict `Production Check` and `CodeQL Analyze`, + one approving review, CODEOWNERS review, stale review dismissal, + conversation resolution, and linear history. +- Force pushes and branch deletion are disabled. +- Public code-scanning alerts and Dependabot alerts have 0 open findings. +- CI and release workflows pin GitHub Actions by commit SHA and Docker base + images by digest. +- Public release has signed manifest assets, checksums, SBOM metadata, + provenance metadata, and a Scorecard-compatible `.sig` asset. +- Documentation consistently warns against publishing secrets, raw evidence + payloads, bearer tokens, private keys, provider credentials, database URLs, + customer data, and customer package contents. + +Weak signals: + +- Required signed commits are disabled. +- Admin enforcement is disabled. +- Secret-scanning non-provider patterns and validity checks are disabled. +- Repository rulesets are not visible. +- Three open Dependabot PRs had failing production checks at inspection time. +- Public repository is new, with no long-term maintenance history. +- No visible external contributors, stars, forks, users, public issues, or + support history. +- No CII/OpenSSF Best Practices badge. +- Release signing key custody is not externally evidenced by KMS/HSM controls. +- No project-published immutable container image or image signature. + +Score: 8/10. + +## Marketability and positioning + +Buyer/adopter assessment: + +The problem is real. B2B software teams increasingly need release-linked +technical evidence for customer security reviews, procurement, incident +response, and compliance-readiness workflows. Evydence has a clear story: +self-hosted release evidence, not a broad SaaS GRC platform and not just an +SBOM/vulnerability tracker. + +The README is unusually conservative for this category. It names the target +user, states current limitations early, provides a fastest proof path, and +explains why a user might choose it over Dependency-Track, Vanta/Drata-style +GRC platforms, or in-house scripts. + +The category is crowded from several sides: + +- SBOM/vulnerability management, such as OWASP Dependency-Track. +- Software supply-chain graph/metadata systems, such as GUAC. +- SaaS compliance automation/GRC, such as Vanta, Drata, TrustCloud, and + adjacent tools. +- CI/CD and platform-native evidence systems in GitHub, GitLab, and cloud + security tooling. +- In-house object-storage, spreadsheet, Postgres, and CI-script approaches. + +Evydence is marketable as a serious self-hosted engineering-control system, not +yet as a proven commercial product. The strongest adoption path is commercial +self-hosted support, integration work, deployment review, and templates for +security/customer evidence workflows. The weakest public proof is adoption: +there are no users, case studies, screenshots, third-party reviews, package +downloads, or public deployment references. + +Score: 7/10. + +## Differentiation + +Direct alternatives: + +- OWASP Dependency-Track: strong SBOM, VEX, vulnerability, policy, and + component-risk workflows. Evydence is less mature as an ecosystem but more + focused on release-level evidence packages, audit chains, readiness + reports, customer packages, and controlled non-claim language. +- GUAC: strong software supply-chain graph and metadata aggregation direction. + Evydence focuses less on global supply-chain graph exploration and more on + tenant-scoped release evidence, operator verification, and customer-facing + evidence packages. +- Vanta, Drata, TrustCloud, and other GRC/compliance automation tools: + broader compliance automation and vendor trust workflows. Evydence is + self-hosted and technical-evidence-first, with no legal compliance claim. +- GitHub/GitLab native supply-chain/security features: closer to source and + CI data, but less focused on an independent self-hosted release ledger and + customer-safe evidence bundles. + +Indirect alternatives: + +- SCA scanners and vulnerability-management systems. +- Sigstore/Cosign/SLSA provenance pipelines. +- Object storage plus signed manifests. +- Internal platform-engineering evidence databases. +- Manual security review spreadsheets and customer questionnaire workflows. + +Build-in-house/do-nothing path: + +- A capable platform team can build 50 percent of the release evidence story + with CI uploads, object storage, signed JSON, and Postgres tables. The hard + parts are tenant isolation, idempotency, append-only records, audit-chain + continuity, redaction, customer package scope, release verification, docs, + and safe claim language. Evydence meaningfully reduces that integration + burden if the team accepts the current self-hosted operational profile. + +Meaningful differentiation: + +- Release-centered evidence graph rather than only component-centered SBOM + tracking. +- Self-hosted, API-first, append-only, tenant-scoped evidence ledger. +- Release bundle and customer package focus. +- Strong non-claim posture for compliance-readiness. +- Public release evidence for the project itself. + +Weak differentiation: + +- Feature breadth overlaps with mature tools. +- No public adoption proof yet. +- No visual demo or polished product UX. +- No stable ecosystem/package distribution. +- No public container image in the current release line. + +Score: 7/10. + +## Repository quality checklist + +| Area | Status | Evidence | Severity | Recommended fix | +|------|--------|----------|----------|-----------------| +| README | Strong | Clear pitch, target user, limitations, proof path, public release link, alternatives, and conservative claims. | Low | Add a short visual architecture/demo section and keep the first proof path release-backed. | +| Quickstart | Strong | Getting started tutorial, install/operate guide, release verification commands, Compose path, and demo fixtures. | Low | Add a five-minute release-binary walkthrough that avoids source checkout entirely. | +| Examples/demo | Adequate | End-to-end release evidence example, sample JSON outputs, package viewer, GitHub/GitLab CI examples. | Medium | Add screenshots or a recorded walkthrough of release readiness, package viewer, and verification. | +| Tests | Strong | 41 Go test files, `go test ./...`, `make fast-check`, fuzz-smoke, OpenAPI checks, SDK/demo checks, production-check in CI, 80.3% release coverage. | Low | Keep expanding behavior tests for remaining service split, provider validation, and failure modes. | +| CI | Strong | Public CI, CodeQL, Scorecard, Scorecard SARIF, Dependabot, Dependency Graph; latest default-branch checks green. | Low | Fix or close failing Dependabot PRs and consider requiring Scorecard/SARIF as branch checks if maintenance policy supports it. | +| Releases/provenance | Strong | Public prerelease `v0.1.0-rc.4` with 18 assets, checksums, SBOM, provenance, signed manifest, release notes, and production-check summary. | Medium | Publish a stable release when ready and add project-owned signed container images or document a hardened image publication path. | +| Docs/API/config/ops | Strong | Extensive docs, OpenAPI, API matrix, runbooks, release validation, operations, configuration, capacity/failure docs. | Low | Add more target-environment examples and keep docs synchronized as public releases evolve. | +| Docker/deployment | Adequate | Dockerfile, local Compose, production-like Compose, Helm chart, air-gap manifest, observability starters. | Medium | Publish signed container images or make Helm docs explicitly image-build-first for every operator path. | +| Security policy | Strong | SECURITY.md, private vulnerability reporting enabled, no public-secret guidance, advisory expectations, CodeQL/Scorecard, no open alerts. | Low | Add a dedicated security contact beyond LinkedIn/requested private channel if sustainable. | +| License/contribution/governance | Strong | AGPL-3.0-only, COMMERCIAL.md, CONTRIBUTING.md, GOVERNANCE.md, CODEOWNERS, CODE_OF_CONDUCT.md, SUPPORT.md, TRADEMARKS.md. | Low | Clarify CLA process once external contributions become realistic. | +| Changelog/versioning | Adequate | CHANGELOG.md exists and release notes are attached to `v0.1.0-rc.4`. | Medium | Add a changelog entry for each public prerelease and define support windows once stable releases start. | + +## Scorecard + +| Dimension | Score | Notes | +|-----------|------:|-------| +| Production readiness | 7/10 | Public signed release evidence now exists and CI runs `make production-check`; still limited by prerelease status, one API writer, no public container image, no target production deployment proof, and operator-dependent KMS/WORM/provider controls. | +| Feature completeness | 8/10 | Broad implemented release-evidence system with API, worker, reports, packages, bundles, OpenAPI, migrations, SDK helpers, and deployment assets; some high-trust integrations remain partial or deployment-dependent. | +| Security and open-source trust | 8/10 | Strong repo metadata, branch protection, CodeQL, Scorecard, Dependabot, private vulnerability reporting, no open alerts, signed release artifacts, and conservative docs; weakened by disabled signed commits/admin enforcement, no CII badge, no adoption history, and no external KMS/HSM custody evidence. | +| Marketability and positioning | 7/10 | Clear self-hosted release-evidence niche and conservative positioning; weak public adoption, no screenshots, no stable release, and no visible customer proof limit market confidence. | +| Differentiation | 7/10 | Differentiated as a self-hosted release evidence ledger with audit chains and customer-safe packages; still overlaps with mature SBOM, GRC, supply-chain graph, and CI/security tools. | +| Repository evidence quality | 9/10 | Strong source, tests, OpenAPI, migrations, workflows, docs, examples, runbooks, deployment assets, public CI, security settings, and public signed release evidence. Remaining evidence gaps are mostly external or distribution-related. | +| Overall | 8/10 | Serious controlled self-hosted production candidate. The v5 release-evidence blocker is closed, but broad production readiness still depends on stable release history, real deployment proof, image distribution, and operator controls. | + +Confidence: high for repository and public GitHub state; medium for real +production deployment readiness. + +Verdict: Production-usable with caveats + +Direct answers: + +- Is it mature and high-grade enough for production for most intended uses? + Not for most intended uses. It is credible for controlled self-hosted pilots + and internal production after operator review. +- Is it feature-complete enough to solve a real-world problem? + Yes, for release evidence organization, verification, readiness reporting, + and customer-safe package preparation in a controlled self-hosted deployment. +- Is it marketable or interesting enough to attract users, buyers, + contributors, or commercial opportunity? + Yes, as a niche self-hosted technical evidence ledger, but adoption proof and + a stronger demo path are still missing. +- Is it worth continuing, hardening, repositioning, or abandoning? + Continue and harden. Do not abandon. Keep the controlled-candidate + positioning until stable releases and operator proof exist. + +## Highest-leverage next steps + +Next 1-2 days: small fixes that immediately improve trust + +- Fix or close failing Dependabot PRs. Why it matters: open security/update PRs + with failing production checks weaken the visible maintenance story. Files: + `.github/workflows/*`, `Dockerfile`, `go.mod`, `go.sum`, and PR-specific + lock/config changes. +- Add a release-binary quick demo path. Why it matters: current proof paths are + good, but many evaluators still start from source checkout. Files: + `docs/tutorials/getting-started.md`, + `docs/how-to/install-and-operate.md`, and + `examples/end-to-end-release-evidence/README.md`. +- Add screenshots or static images for the package viewer and readiness JSON. + Why it matters: public adopters need to understand value before running a + stack. Files: `README.md`, `docs/how-to/view-packages.md`, and `site/`. +- Update `CHANGELOG.md` with an explicit `v0.1.0-rc.4` section. Why it + matters: release notes exist, but the changelog should reflect public + prerelease history. + +Next 1-2 weeks: changes that materially improve production readiness and marketability + +- Publish a project-owned container image line or document an intentionally + image-free release strategy more strongly. Why it matters: Helm and + air-gapped operators need immutable image digests. Files/workflows: + `.github/workflows/release-artifacts.yml`, `deploy/helm/evydence/values.yaml`, + `docs/kubernetes.md`, and `deploy/airgap/manifest.yaml`. +- Add target-environment backup/restore evidence using Compose or a disposable + local stack. Why it matters: backup/restore is the largest remaining + production-readiness proof gap that can be partially exercised in-repo. + Files: `scripts/`, `docs/runbooks/backup-restore.md`, and CI artifacts. +- Add a public release verification walkthrough that downloads assets from + GitHub and verifies them from a clean temp directory. Why it matters: it + proves the public release path, not just local `dist/`. Files: + `scripts/`, `docs/reference/release-evidence-index.md`, and CI docs. +- Decide whether to require Scorecard and Scorecard SARIF as branch checks. + Why it matters: they already run, but branch protection only requires + production and CodeQL checks. This is a policy choice, not a code issue. + +Next 1-2 months: changes that could make the project seriously productizable + +- Cut a stable `v0.1.0` or later release after several release candidates and + operator rehearsals. Why it matters: prerelease status is appropriate now but + limits production confidence. +- Complete the service-boundary and repository decomposition review. Why it + matters: the large ledger aggregate is the main architectural caveat behind + the single-writer stance. +- Add public deployment evidence for at least one supported profile. Why it + matters: production-readiness claims need restore, monitoring, incident, and + upgrade evidence from a real or realistic environment. +- Add external trust evidence: CII/OpenSSF Best Practices badge, third-party + review, or public design/security review. Why it matters: high-trust buyers + need independent signals beyond maintainer-authored docs. +- Add package/image signing and operator verification for container workflows. + Why it matters: release archives are good, but most self-hosted operators + will deploy images. + +## README/product-page rewrite advice + +Sharper one-sentence pitch: + +Evydence is a self-hosted release evidence ledger for software teams that need +tamper-evident SBOM, vulnerability, build, deployment, control, and customer +review evidence for each release. + +Target user: + +Security, AppSec, platform, release, and compliance-readiness teams at B2B +software companies that want release-linked technical evidence without moving +all release trust data into a SaaS GRC platform. + +Core use case to show first: + +Take one release from product/project/artifact creation through SBOM upload, +vulnerability scan upload, VEX/decision/exception handling, release bundle +generation, readiness report, audit-chain verification, and customer-safe +package inspection. + +Best demo/example to show first: + +Start with the public `v0.1.0-rc.4` release verification commands, then show +the package viewer using the sample customer package manifest. That proves both +release integrity and buyer-facing output without requiring a full stack. + +Proof points to add: + +- Release asset verification screenshot or transcript. +- Public CI production-check artifact link. +- Package viewer screenshot. +- A sample release-readiness report with a blocked finding and a resolved VEX + decision. +- A backup/restore rehearsal transcript. + +What to remove or de-emphasize: + +- Long feature inventories in the README should keep moving into reference + docs as the product matures. +- Avoid overemphasizing future extensions, AI summarization, PDF packages, or + enterprise workflows before release evidence and operator proof are obvious. +- Keep avoiding legal compliance, certification, secure-release, complete SBOM, + scanner-authority, auditor, and regulator claims. + +## Residual risk and uncertainty + +Remaining untested or externally unproven areas: + +- Real production deployment behavior under operator traffic. +- Target-environment backup/restore with the operator's actual PostgreSQL and + object store. +- Monitoring, alerting, incident response, and support execution. +- Object-store WORM/object-lock enforcement in a real provider account. +- Native HSM or cloud KMS custody and key administration in a real account. +- Provider-specific SSO, GitHub/GitLab, transparency, and signing trust + semantics beyond local/gateway evidence. +- Multi-writer API HA. +- Public container build, signing, publishing, and image verification. +- Long-lived maintenance, adoption, contributor diversity, external review, + and user feedback. + +Claims still only intended or documented: + +- Broad self-hosted production readiness for most uses. +- Regulated production readiness. +- Air-gapped production beyond package/export mechanics and docs. +- Hosted SaaS readiness. +- Native HSM custody beyond gateway-backed or provider-specific executor paths. +- Provider-specific group synchronization and management API verification. + +Evidence that would raise confidence: + +- A stable public release line after at least one more release-candidate cycle. +- Public, signed container images with immutable digests. +- A clean public verification workflow that downloads release assets from + GitHub and verifies them end to end. +- A published backup/restore rehearsal with object-store pairing. +- A small real deployment case study or maintainer-operated pilot report. +- CII/OpenSSF Best Practices badge or external security/design review. +- More PRs merged through branch-protected review rather than maintainer direct + pushes. +- Clear policy on signed commits and branch admin enforcement. diff --git a/CHANGELOG.md b/CHANGELOG.md index ae2bce8..6128e2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,9 +9,52 @@ results, no secure-release guarantee, and no regulator or auditor acceptance. ## Unreleased -No public release notes have been added after local release-candidate evidence -for `v0.1.0-rc.3`. Public GitHub release publication remains an operator -action. +### Added + +- Public release verification helper for downloading `v0.1.0-rc.4` from + GitHub Releases into a clean temporary directory, checking release checksums, + validating in-toto provenance metadata shape, and verifying the signed + release manifest with the released Linux amd64 CLI. +- Repository-owned restore rehearsal target for app-layer and live PostgreSQL + backup/restore mechanics. +- Static package-viewer preview asset for public docs. + +### Changed + +- Dependency maintenance updates for pinned GitHub Actions, the Docker build + and runtime base images, and `kin-openapi`. + +## v0.1.0-rc.4 - 2026-05-31 + +Release status: controlled self-hosted production candidate. This prerelease is +suitable for evaluation, pilots, and controlled internal production after +operator review. Broad self-hosted production readiness, regulated production, +and hosted SaaS production remain out of scope for this status. + +### Added + +- Public GitHub prerelease at + . +- Release archives for Linux, macOS, and Windows. +- `SHA256SUMS`, `openapi.sha256`, and `migrations.sha256`. +- Release coverage output and production-check summary. +- Release SBOM metadata and Evydence release provenance metadata. +- Scorecard-compatible in-toto provenance metadata. +- Signed release manifest plus `.sig.json` verifier input and `.sig` release + asset alias. +- Release notes attached to the public prerelease. + +### Known Limits + +- Public release archives and release evidence are published, but no + container image should be treated as deployable release evidence unless the + maintainer image workflow has produced an immutable digest and cosign evidence + for the tag. +- Operators remain responsible for PostgreSQL, object storage, TLS, external + signing or KMS/HSM custody, WORM/object-lock policy where required, backups, + restore rehearsals, monitoring, provider validation, and incident response. +- Multi-writer API HA remains outside the supported production profile; use one + API writer replica and scale workers through PostgreSQL outbox locking. ## v0.1.0-rc.3 - 2026-05-31 diff --git a/Dockerfile b/Dockerfile index 121dcba..97ee4d6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.25-alpine@sha256:8d22e29d960bc50cd025d93d5b7c7d220b1ee9aa7a239b3c8f55a57e987e8d45 AS build +FROM golang:1.26-alpine@sha256:91eda9776261207ea25fd06b5b7fed8d397dd2c0a283e77f2ab6e91bfa71079d AS build WORKDIR /src COPY go.mod go.sum ./ RUN go mod download @@ -8,7 +8,7 @@ RUN go build -o /out/evydence-migrate ./cmd/evydence-migrate RUN go build -o /out/evydence-worker ./cmd/evydence-worker RUN go build -o /out/evydence ./cmd/evydence -FROM alpine:3.22@sha256:310c62b5e7ca5b08167e4384c68db0fd2905dd9c7493756d356e893909057601 +FROM alpine:3.23@sha256:5b10f432ef3da1b8d4c7eb6c487f2f5a8f096bc91145e68878dd4a5019afde11 RUN addgroup -S evydence && adduser -S -G evydence evydence USER evydence WORKDIR /app diff --git a/Makefile b/Makefile index fa3a232..1d13074 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ GOVULNCHECK_VERSION ?= v1.2.0 TAG ?= -.PHONY: help tools fmt lint vuln gosec test test-race fuzz-smoke coverage coverage-check openapi-check openapi-precision-check meta-check docs-check deploy-check sdk-check demo-check black-box-demo-check benchmark-check package-viewer-check fast-check finalize release-acceptance release-check production-check release-candidate-check migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean +.PHONY: help tools fmt lint vuln gosec test test-race fuzz-smoke coverage coverage-check openapi-check openapi-precision-check meta-check docs-check deploy-check sdk-check demo-check black-box-demo-check benchmark-check package-viewer-check restore-rehearsal-check fast-check finalize release-acceptance release-check production-check release-candidate-check public-release-verify migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean help: ## Show help @awk 'BEGIN {FS=":.*## "}; /^[a-zA-Z0-9_.-]+:.*## / { printf " %-18s %s\n", $$1, $$2 }' $(MAKEFILE_LIST) @@ -73,6 +73,7 @@ meta-check: ## Validate root legal, governance, support, and release-evidence me @test -f .dockerignore @test -f .github/dependabot.yml @test -f .github/workflows/scorecard.yml + @test -f .github/workflows/container-image.yml @test -f .github/workflows/codeql.yml @test -f .github/ISSUE_TEMPLATE.md @test -f .github/ISSUE_TEMPLATE/bug_report.yml @@ -96,15 +97,20 @@ meta-check: ## Validate root legal, governance, support, and release-evidence me @grep -F 'internal/app/' CODEOWNERS >/dev/null @grep -F 'docs/reference/release-evidence-index.md' CODEOWNERS >/dev/null @grep -F 'OpenSSF Scorecard' .github/workflows/scorecard.yml >/dev/null - @grep -F 'ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46' .github/workflows/scorecard.yml >/dev/null + @grep -F 'ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a' .github/workflows/scorecard.yml >/dev/null @grep -F 'OpenSSF Scorecard SARIF' .github/workflows/scorecard-sarif.yml >/dev/null - @grep -F 'ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46' .github/workflows/scorecard-sarif.yml >/dev/null - @grep -F 'github/codeql-action/upload-sarif@fee9466b8957867761f2d78f922ab084e3e2dd17' .github/workflows/scorecard-sarif.yml >/dev/null - @grep -F 'github/codeql-action/analyze@fee9466b8957867761f2d78f922ab084e3e2dd17' .github/workflows/codeql.yml >/dev/null - @grep -F 'actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd' .github/workflows/ci.yml >/dev/null + @grep -F 'ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a' .github/workflows/scorecard-sarif.yml >/dev/null + @grep -F 'github/codeql-action/upload-sarif@03e4368ac7daa2bd82b3e85262f3bf87ee112f57' .github/workflows/scorecard-sarif.yml >/dev/null + @grep -F 'github/codeql-action/analyze@03e4368ac7daa2bd82b3e85262f3bf87ee112f57' .github/workflows/codeql.yml >/dev/null + @grep -F 'actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd' .github/workflows/ci.yml >/dev/null @grep -F 'actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c' .github/workflows/ci.yml >/dev/null @grep -F 'actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a' .github/workflows/ci.yml >/dev/null @grep -F 'postgres:16-alpine@sha256:16bc17c64a573ef34162af9298258d1aec548232985b33ed7b1eac33ba35c229' .github/workflows/ci.yml >/dev/null + @grep -F 'ghcr.io/$${{ github.repository }}' .github/workflows/container-image.yml >/dev/null + @grep -F 'cosign sign --yes' .github/workflows/container-image.yml >/dev/null + @grep -F 'cosign verify' .github/workflows/container-image.yml >/dev/null + @grep -F -- '--provenance=true' .github/workflows/container-image.yml >/dev/null + @grep -F -- '--sbom=true' .github/workflows/container-image.yml >/dev/null @grep -F 'Evydence fork' TRADEMARKS.md >/dev/null @grep -F 'Release evidence is not a certification' RELEASE_EVIDENCE.md >/dev/null @grep -F '.refs' .dockerignore >/dev/null @@ -149,6 +155,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @test -f docs/github-actions/upload-build/action.yml @test -f docs/gitlab/evydence-release-evidence.gitlab-ci.yml @test -f .github/workflows/release-artifacts.yml + @test -f .github/workflows/container-image.yml @test -f .github/workflows/codeql.yml @test -f docs/sdk/README.md @for path in \ @@ -201,6 +208,15 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F './dist/evydence release manifest' docs/air-gapped.md >/dev/null @grep -F './evydence release verify' docs/air-gapped.md >/dev/null @grep -F './evydence import-bundle upload' docs/air-gapped.md >/dev/null + @test -x scripts/public_release_verify.sh + @grep -F 'make public-release-verify TAG=v0.1.0-rc.4' README.md >/dev/null + @grep -F 'make public-release-verify TAG=v0.1.0-rc.4' docs/how-to/install-and-operate.md >/dev/null + @grep -F 'make public-release-verify TAG=v0.1.0-rc.4' docs/reference/release-evidence-index.md >/dev/null + @grep -F 'make public-release-verify TAG=v0.1.0-rc.4' examples/end-to-end-release-evidence/README.md >/dev/null + @test -f docs/assets/package-viewer-preview.svg + @grep -F 'package-viewer-preview.svg' docs/how-to/view-packages.md >/dev/null + @grep -F 'v0.1.0-rc.4 - 2026-05-31' CHANGELOG.md >/dev/null + @grep -F 'make restore-rehearsal-check' docs/runbooks/backup-restore.md >/dev/null @grep -F 'dist/evydence github-actions upload-build' docs/github-actions/release-evidence-workflow.yml >/dev/null @grep -F 'go run ./cmd/evydence "$${args[@]}"' docs/github-actions/upload-build/action.yml >/dev/null @grep -F 'cat > evydence-upload-manifest.json' docs/gitlab/evydence-release-evidence.gitlab-ci.yml >/dev/null @@ -214,7 +230,14 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'evydence-release-manifest.sig alias' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'gh release create' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'contents: read' .github/workflows/release-artifacts.yml >/dev/null - @grep -F 'github/codeql-action/init@fee9466b8957867761f2d78f922ab084e3e2dd17' .github/workflows/codeql.yml >/dev/null + @grep -F 'Container Image' .github/workflows/container-image.yml >/dev/null + @grep -F 'evydence-container-image-manifest.json' .github/workflows/container-image.yml >/dev/null + @grep -F 'cosign-keyless' .github/workflows/container-image.yml >/dev/null + @grep -F 'ghcr.io/aatuh/evydence' README.md >/dev/null + @grep -F 'ghcr.io/aatuh/evydence' docs/reference/release-evidence-index.md >/dev/null + @grep -F 'ghcr.io/aatuh/evydence' docs/kubernetes.md >/dev/null + @grep -F 'ghcr.io/aatuh/evydence' deploy/airgap/manifest.yaml >/dev/null + @grep -F 'github/codeql-action/init@03e4368ac7daa2bd82b3e85262f3bf87ee112f57' .github/workflows/codeql.yml >/dev/null @grep -F 'security-and-quality' .github/workflows/codeql.yml >/dev/null @grep -F 'Controlled self-hosted production candidate' docs/reference/release-candidate.md >/dev/null @grep -F 'Release evidence index' docs/reference/release-candidate.md >/dev/null @@ -222,6 +245,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'evydence-release-manifest.sig' docs/reference/release-evidence-index.md >/dev/null @grep -F 'evydence-release-provenance.intoto.jsonl' docs/reference/release-evidence-index.md >/dev/null @grep -F 'CODEOWNERS' docs/reference/maintainer-review-policy.md >/dev/null + @grep -F 'OpenSSF Scorecard and Scorecard SARIF remain' docs/reference/maintainer-review-policy.md >/dev/null @grep -F 'one API writer replica' docs/reference/roadmap.md >/dev/null @grep -F 'Controlled self-hosted production candidate' docs/reference/release-notes-template.md >/dev/null @grep -F 'not legal compliance proof' docs/reference/release-notes-template.md >/dev/null @@ -295,6 +319,10 @@ package-viewer-check: ## Validate local package viewer and walkthrough @! grep -F 'innerHTML' site/package-viewer/index.html >/dev/null @grep -F 'examples/end-to-end-release-evidence/sample-customer-package-manifest.json' docs/how-to/view-packages.md >/dev/null +restore-rehearsal-check: ## Run repository-owned backup/restore rehearsal tests + @$(GO) test ./internal/app -run TestBackupRestoreRehearsalPreservesLedgerAndObjectPayloads -count=1 + @$(GO) test ./internal/adapters/postgres -run TestPostgresBackupRestoreRehearsalPreservesLedgerAndObjects -count=1 + fast-check: ## Run non-mutating fast validation @$(MAKE) test @$(MAKE) fuzz-smoke @@ -353,6 +381,9 @@ production-check: ## Strict self-hosted production readiness gate; requires live release-candidate-check: ## Build and validate a signed release-candidate package with explicit TAG=vX.Y.Z-rc.N @scripts/release_candidate_package.sh "$(TAG)" +public-release-verify: ## Download and verify public release assets with TAG=vX.Y.Z-rc.N + @scripts/public_release_verify.sh "$(TAG)" + migration-compatibility-check: ## Verify every committed migration prefix upgrades to current schema @$(GO) test ./internal/adapters/postgres -run TestMigrationCompatibilityFromEveryCommittedState -count=1 diff --git a/README.md b/README.md index 77b5780..c442da6 100644 --- a/README.md +++ b/README.md @@ -29,9 +29,9 @@ security. evaluation, pilots, and controlled internal production after operator review. - Production API deployments use one API writer replica; workers may scale through PostgreSQL outbox locking. -- The current public release candidate publishes signed release archives and - release evidence, but no project-published container image is part of this - release line yet. +- Container publication uses the maintainer-run GHCR workflow and must be + verified by immutable digest and cosign evidence; Helm installs should not use + floating image tags. - Native PKCS#11/HSM module handling, broad WORM/object-lock proof, direct provider-specific management API clients, external group synchronization, regulated production, and hosted SaaS production remain outside the current @@ -50,6 +50,11 @@ Use GitHub Releases and the checked release evidence artifacts as the operator install source for the release-candidate line. Source checkout remains the development path. +Container images for the release-candidate line are published, when the +maintainer image workflow has run for the tag, as +`ghcr.io/aatuh/evydence:`. Treat the digest and cosign evidence as the +operator trust input, not the mutable tag alone. + ## Fastest Proof Path For a first local API flow, follow [Getting started](docs/tutorials/getting-started.md). @@ -67,6 +72,13 @@ Release-candidate artifacts and their verification commands are indexed in the public `v0.1.0-rc.4` release if you want to evaluate release verification before running the API. +To verify the public release assets from a clean temporary directory on Linux +amd64, run: + +```sh +make public-release-verify TAG=v0.1.0-rc.4 +``` + The end-to-end evidence flow to evaluate first is: 1. Create a product, release, and artifact. @@ -75,6 +87,10 @@ The end-to-end evidence flow to evaluate first is: 4. Generate a release bundle and readiness report. 5. Export a customer-safe package or evidence bundle for review. +For a visual preview of the customer-package review surface, see the +[package viewer guide](docs/how-to/view-packages.md). The preview uses +non-sensitive sample data and does not upload files. + ## Why Evydence Instead Of Existing Tools? - Dependency-Track and vulnerability-management tools are strong for SBOM and diff --git a/deploy/airgap/manifest.yaml b/deploy/airgap/manifest.yaml index d6e16a2..3c1d7fd 100644 --- a/deploy/airgap/manifest.yaml +++ b/deploy/airgap/manifest.yaml @@ -2,7 +2,7 @@ schema_version: evydence-airgap-package.v1.0.0 images: - name: evydence repository: ghcr.io/aatuh/evydence - tag: operator-built-v0.1.0-rc.4 + tag: v0.1.0-rc.4 required: true bundled_paths: - migrations/ @@ -13,4 +13,4 @@ verification: checksums: SHA256SUMS signature: SHA256SUMS.sig.json limitations: - - The v0.1.0-rc.4 public release publishes release archives and release evidence, but no project-owned public container image. Operators must build, sign, and transfer actual images and archives through their controlled process. + - Project-owned release-candidate images are published through the maintainer Container Image workflow when run for the tag. Operators must verify and pin the image digest, or build, sign, and transfer actual images and archives through their controlled process. diff --git a/docs/assets/package-viewer-preview.svg b/docs/assets/package-viewer-preview.svg new file mode 100644 index 0000000..a3913c2 --- /dev/null +++ b/docs/assets/package-viewer-preview.svg @@ -0,0 +1,33 @@ + + Evydence package viewer preview + Static preview of a customer package manifest, readiness result, linked evidence, assumptions, and limitations. + + + + Evydence Package Viewer + local file only + + + Readiness + blocked + critical finding requires + VEX decision or exception + + + Evidence Linked + SBOM: CycloneDX JSON + Scan: generic vulnerability JSON + Bundle: signed release manifest + + + Limitations + not legal compliance proof + not complete SBOM proof + not a secure-release guarantee + + + Customer Package Manifest + package_id: pkg_sample_customer_review + release: rel_payments_api_2026_05 + included: readiness report, bundle manifest, evidence summary + diff --git a/docs/how-to/install-and-operate.md b/docs/how-to/install-and-operate.md index 0151bd9..0b28dc9 100644 --- a/docs/how-to/install-and-operate.md +++ b/docs/how-to/install-and-operate.md @@ -41,6 +41,18 @@ verification prints `release manifest verified`, and the extracted directory contains `evydence`, `evydence-api`, `evydence-worker`, and `evydence-migrate`. +For the same verification from a clean temporary directory, use the checked +helper: + +```sh +make public-release-verify TAG=v0.1.0-rc.4 +``` + +Expected result: the helper downloads the public GitHub Release assets, +verifies `SHA256SUMS`, `openapi.sha256`, `migrations.sha256`, validates the +in-toto provenance statement shape, extracts the Linux amd64 CLI from the +downloaded archive, and prints `public release verified`. + To run a release-binary local demo instead of `go run`, use the extracted `evydence-api` and `evydence-worker` binaries with the same environment variables shown below. The in-process tutorial is still local-only; for durable diff --git a/docs/how-to/view-packages.md b/docs/how-to/view-packages.md index fe20caa..096b866 100644 --- a/docs/how-to/view-packages.md +++ b/docs/how-to/view-packages.md @@ -11,6 +11,8 @@ running the API, load `examples/end-to-end-release-evidence/sample-customer-package-manifest.json` or press **Load bundled demo** in the viewer. +![Static package viewer preview](../assets/package-viewer-preview.svg) + Use it for: - checking a release-readiness report before sending a customer package; diff --git a/docs/kubernetes.md b/docs/kubernetes.md index 37fe0bc..5fd6a1c 100644 --- a/docs/kubernetes.md +++ b/docs/kubernetes.md @@ -7,10 +7,11 @@ The Helm chart lives at `deploy/helm/evydence`. It deploys the API, worker, serv ## Prerequisites - An Evydence image with an explicit immutable tag or digest in a registry the - cluster can pull from. The `v0.1.0-rc.4` public release publishes release - archives and release evidence, but no project-owned public container image; - operators must build, sign, and publish their own image for Helm installs in - this release line. + cluster can pull from. Project-owned release-candidate images are published + through the maintainer Container Image workflow as + `ghcr.io/aatuh/evydence:` when that workflow has run for the tag. + Operators should pin the digest and verify cosign evidence, or build, sign, + and publish their own image through a controlled registry. - External PostgreSQL and S3/MinIO-compatible object storage. - A pre-created object-store bucket. - A Kubernetes secret containing at least `EVYDENCE_DATABASE_URL` and `EVYDENCE_API_KEY_PEPPER`. diff --git a/docs/reference/maintainer-review-policy.md b/docs/reference/maintainer-review-policy.md index 819694d..661cfb8 100644 --- a/docs/reference/maintainer-review-policy.md +++ b/docs/reference/maintainer-review-policy.md @@ -80,3 +80,11 @@ Repository CI and SAST workflows should keep third-party Actions pinned by commit SHA and service/container images pinned by digest. If an Action or image pin is updated, reviewers should verify the upstream tag or digest source and record the reason in the pull request or release evidence. + +Branch protection requires the live `Production Check` and `CodeQL Analyze` +checks because they run on pushes and pull requests and directly gate runtime +correctness and security analysis. OpenSSF Scorecard and Scorecard SARIF remain +scheduled/manual advisory checks for the current release-candidate line. Do not +make them required branch-protection checks unless their workflows also run on +the same pull request events without introducing circular or non-deterministic +merge blocking. diff --git a/docs/reference/production-exit-review.md b/docs/reference/production-exit-review.md index 485acc2..0f290a0 100644 --- a/docs/reference/production-exit-review.md +++ b/docs/reference/production-exit-review.md @@ -35,9 +35,11 @@ SaaS-ready, legally compliant, certified, or secure-release-guaranteed. ## Remaining Exit Blockers -- Public container images are not published for `v0.1.0-rc.4`; operators who - use Helm or air-gapped workflows must build, sign, publish, and record their - own image digests. +- Project-owned container images count as release evidence only after the + maintainer Container Image workflow has run for the tag and produced digest + plus cosign evidence. Operators who mirror or rebuild images for Helm or + air-gapped workflows must record their own image digest and verification + evidence. - Native PKCS#11/HSM module custody requires operator hardware, drivers, and provider-specific validation. - Broad WORM/object-lock proof requires object-store policy, IAM, lifecycle, diff --git a/docs/reference/release-candidate.md b/docs/reference/release-candidate.md index f85e4fd..8e14a2c 100644 --- a/docs/reference/release-candidate.md +++ b/docs/reference/release-candidate.md @@ -70,10 +70,13 @@ completed release-artifacts workflow run, uploaded release archives, checksums, signed manifest files, release notes, and any configured repository or registry trust settings. -The current release line publishes release archives and release evidence only. -No project-owned public container image is part of `v0.1.0-rc.4`; operators -must build and publish images into their own registry when using Helm or -air-gapped deployment flows. +Release archives and release evidence are published by the Release Artifacts +workflow. Project-owned container images are published by the separate Container +Image workflow to `ghcr.io/aatuh/evydence:` when that workflow is run for a +release tag. Operators should pin the resulting digest, verify the cosign +evidence, and record that image digest with deployment evidence. If no image +workflow evidence exists for a tag, operators must build and publish images into +their own registry for Helm or air-gapped deployment flows. ## Deployment Constraints diff --git a/docs/reference/release-evidence-index.md b/docs/reference/release-evidence-index.md index 6cd2926..d89c838 100644 --- a/docs/reference/release-evidence-index.md +++ b/docs/reference/release-evidence-index.md @@ -32,6 +32,8 @@ under `dist//` after `make production-check` passes. | `evydence-release-provenance.json` | `scripts/release_evidence_metadata.py` | Record build/release provenance metadata and limitations; this does not prove provider trust by itself. | | `evydence-release-provenance.intoto.jsonl` | `scripts/release_evidence_metadata.py` | Scorecard-compatible in-toto statement with the same Evydence release provenance limitations. This is not a SLSA level claim. | | `release-notes.md` | Tag-specific release notes or `docs/reference/release-notes-template.md` | State supported profile, upgrade notes, assumptions, limitations, and unresolved hardening work. | +| `ghcr.io/aatuh/evydence:` | `.github/workflows/container-image.yml` | Optional project-owned image publication path for a release tag. Verify by digest and cosign workflow identity; do not deploy by mutable tag alone. | +| `evydence-container-image-manifest.json` | `.github/workflows/container-image.yml` | Records the image digest, source commit, cosign verification file, assumptions, and limitations for the image workflow run. | ## Current Public Release Candidate @@ -73,13 +75,27 @@ Use the platform-specific `evydence` binary from the release archive whenever possible so the verifier matches the released toolchain. If you verify from a source checkout instead, record that limitation in the release notes. +To verify the already-published public release from a clean temporary directory, +run: + +```sh +make public-release-verify TAG=v0.1.0-rc.4 +``` + +The helper downloads the release assets with `gh`, checks the public checksums, +validates the in-toto statement shape, extracts the released Linux amd64 CLI, +and verifies the signed manifest with that released binary. + ## Publication Status The first public release candidate is published. GitHub Releases are now the operator evaluation source for release-candidate binaries and release evidence. Source checkout remains the development path. -The current release line does not publish a project-owned container image. -Operators who need Kubernetes or air-gapped image workflows must build, sign, -and publish an image into their own registry from the release archive or source -checkout, then record the image digest with their deployment evidence. +Project-owned container images are published separately from the release archive +workflow through `.github/workflows/container-image.yml` as +`ghcr.io/aatuh/evydence:`. Treat an image as release evidence only when the +workflow has produced an immutable digest and +`evydence-container-image-manifest.json` for that tag. Operators who mirror or +rebuild images for Kubernetes or air-gapped workflows must record the resulting +digest with their deployment evidence. diff --git a/docs/runbooks/backup-restore.md b/docs/runbooks/backup-restore.md index 61d8910..dfe9d16 100644 --- a/docs/runbooks/backup-restore.md +++ b/docs/runbooks/backup-restore.md @@ -38,6 +38,26 @@ backups by themselves. 8. Record restore start/end time, data cut timestamp, object-store source, database backup source, failed checks, and limitations. +## Repository Rehearsal Evidence + +The repository-owned rehearsal checks exercise the same restore invariants with +non-sensitive local data: + +```sh +make restore-rehearsal-check +``` + +Expected result: the app-layer rehearsal verifies restored ledger state, +tenant credentials, object payload digest availability, backup-manifest +verification, SBOM metadata, and release-bundle verification. When +`EVYDENCE_TEST_DATABASE_URL` is set, the PostgreSQL rehearsal restores into a +clean schema and repeats the same database/object-store checks. When the +variable is unset, the PostgreSQL test reports an explicit skip. + +This command is repository proof for restore mechanics. It does not replace an +operator rehearsal against the target PostgreSQL backup tool, object-store +bucket, KMS/HSM configuration, network policy, or incident process. + ## Failure Handling - Missing object payloads: treat affected evidence, package, or report diff --git a/examples/end-to-end-release-evidence/README.md b/examples/end-to-end-release-evidence/README.md index a2ff394..61616d1 100644 --- a/examples/end-to-end-release-evidence/README.md +++ b/examples/end-to-end-release-evidence/README.md @@ -13,6 +13,19 @@ The files in this directory are non-sensitive fixtures. They are not legal compliance proof, certification, complete SBOM proof, authoritative vulnerability results, or a secure-release guarantee. +## Start With Release Verification + +Before running a local API flow, verify the current public release-candidate +assets from a clean temporary directory: + +```sh +make public-release-verify TAG=v0.1.0-rc.4 +``` + +This proves the downloaded public archives, OpenAPI checksum, migration +checksum, in-toto provenance statement shape, and signed release manifest before +you use source-checkout commands for local development. + ## Files - `release-evidence-manifest.json`: example CLI bulk-upload manifest. diff --git a/go.mod b/go.mod index dc75308..0b0fc0d 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/aatuh/api-toolkit/v3 v3.1.2 github.com/aws/aws-sdk-go-v2/config v1.32.20 github.com/aws/aws-sdk-go-v2/service/kms v1.52.2 - github.com/getkin/kin-openapi v0.133.0 + github.com/getkin/kin-openapi v0.139.0 github.com/jackc/pgx/v5 v5.9.2 github.com/minio/minio-go/v7 v7.2.0 ) @@ -41,11 +41,12 @@ require ( github.com/minio/crc64nvme v1.1.1 // indirect github.com/minio/md5-simd v1.1.2 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect - github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect + github.com/oasdiff/yaml v0.1.0 // indirect + github.com/oasdiff/yaml3 v0.0.13 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/philhofer/fwd v1.2.0 // indirect github.com/rs/xid v1.6.0 // indirect + github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect github.com/tinylib/msgp v1.6.1 // indirect github.com/woodsbury/decimal128 v1.3.0 // indirect github.com/zeebo/xxh3 v1.1.0 // indirect diff --git a/go.sum b/go.sum index bdfd2e7..16b8683 100644 --- a/go.sum +++ b/go.sum @@ -35,10 +35,12 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dlclark/regexp2 v1.12.0 h1:0j4c5qQmnC6XOWNjP3PIXURXN2gWx76rd3KvgdPkCz8= +github.com/dlclark/regexp2 v1.12.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= -github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= +github.com/getkin/kin-openapi v0.139.0 h1:pBFXcZJFwz9J1X64jzxlOoNgFm+TF7kNrs9+HJVN6Ic= +github.com/getkin/kin-openapi v0.139.0/go.mod h1:NGxPfE4PwS/TRXEbyx2RrxDFPZvxcWw31Tw8XXjPZLs= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= @@ -78,10 +80,10 @@ github.com/minio/minio-go/v7 v7.2.0 h1:RCJM0R1XOsRs+A3x3UCaf3ZYbByDaLjFeAi+YCQEP github.com/minio/minio-go/v7 v7.2.0/go.mod h1:EU9hENAStx/xXduNdrGO5e4X5vk19NtgB+RIPjZO8o0= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= -github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= -github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= +github.com/oasdiff/yaml v0.1.0 h1:0bqZjfKc/8S9urj4JuwepX41WX9EoA6ifhU3SV06cXg= +github.com/oasdiff/yaml v0.1.0/go.mod h1:kOlRmMdL2X3vucLCEQO5u61SU22RysnfXvcttrZA1O0= +github.com/oasdiff/yaml3 v0.0.13 h1:06svmvOHOVBqF81+sY2EUScvUI/iS/vl2VIeUUxZQwg= +github.com/oasdiff/yaml3 v0.0.13/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM= @@ -92,6 +94,8 @@ github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0t github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= +github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 h1:KRzFb2m7YtdldCEkzs6KqmJw4nqEVZGK7IN2kJkjTuQ= +github.com/santhosh-tekuri/jsonschema/v6 v6.0.2/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= diff --git a/scripts/public_release_verify.sh b/scripts/public_release_verify.sh new file mode 100755 index 0000000..ecd8a97 --- /dev/null +++ b/scripts/public_release_verify.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +set -euo pipefail + +repo="${EVYDENCE_RELEASE_REPO:-aatuh/evydence}" +tag="${1:-${TAG:-v0.1.0-rc.4}}" + +if [[ ! "$repo" =~ ^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$ ]]; then + echo "EVYDENCE_RELEASE_REPO must look like owner/name" >&2 + exit 2 +fi +if [[ ! "$tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$ ]]; then + echo "release candidate tag must look like v0.1.0-rc.4" >&2 + exit 2 +fi +if ! command -v gh >/dev/null 2>&1; then + echo "gh is required to download public release assets" >&2 + exit 2 +fi + +workdir="$(mktemp -d "${TMPDIR:-/tmp}/evydence-release-verify.XXXXXX")" +cleanup() { + rm -rf "$workdir" +} +trap cleanup EXIT + +echo "Downloading ${repo} ${tag} into ${workdir}" +gh release download "$tag" --repo "$repo" --dir "$workdir" + +(cd "$workdir" && sha256sum -c SHA256SUMS) +(cd "$workdir" && sha256sum -c openapi.sha256) +sha256sum -c "$workdir/migrations.sha256" + +archive="$workdir/evydence_${tag}_linux_amd64.tar.gz" +if [[ ! -f "$archive" ]]; then + echo "linux amd64 release archive missing: ${archive}" >&2 + exit 2 +fi +tar -C "$workdir" -xzf "$archive" +cli="$workdir/evydence_${tag}_linux_amd64/evydence" +"$cli" release verify \ + --manifest "$workdir/evydence-release-manifest.json" \ + --signature "$workdir/evydence-release-manifest.sig.json" + +if [[ -f "$workdir/evydence-release-manifest.sig" ]]; then + cmp -s "$workdir/evydence-release-manifest.sig.json" "$workdir/evydence-release-manifest.sig" +fi +python3 - "$workdir/evydence-release-provenance.intoto.jsonl" <<'PY' +import json +import sys +from pathlib import Path + +path = Path(sys.argv[1]) +line = path.read_text(encoding="utf-8").strip() +statement = json.loads(line) +if statement.get("_type") != "https://in-toto.io/Statement/v0.1": + raise SystemExit("release provenance is not an in-toto statement") +if "not a SLSA level claim" not in json.dumps(statement, sort_keys=True): + raise SystemExit("release provenance limitations are missing") +PY + +echo "public release verified: ${repo} ${tag}" diff --git a/scripts/release_acceptance.sh b/scripts/release_acceptance.sh index 9c0dae8..7071054 100755 --- a/scripts/release_acceptance.sh +++ b/scripts/release_acceptance.sh @@ -47,6 +47,7 @@ for file in \ .github/ISSUE_TEMPLATE.md \ .github/pull_request_template.md \ .github/workflows/codeql.yml \ + .github/workflows/container-image.yml \ README.md \ docs/README.md \ docs/reference/release-candidate.md \ @@ -75,14 +76,18 @@ require_text .github/pull_request_template.md "tenant isolation" require_text .github/pull_request_template.md "Sensitive Data Check" require_text CODEOWNERS "internal/app/" require_text CODEOWNERS "docs/reference/release-evidence-index.md" -require_text .github/workflows/codeql.yml "github/codeql-action/analyze@fee9466b8957867761f2d78f922ab084e3e2dd17" +require_text .github/workflows/codeql.yml "github/codeql-action/analyze@03e4368ac7daa2bd82b3e85262f3bf87ee112f57" require_text .github/workflows/codeql.yml "security-and-quality" -require_text .github/workflows/ci.yml "actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd" +require_text .github/workflows/ci.yml "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" require_text .github/workflows/release-artifacts.yml "contents: read" -require_text .github/workflows/scorecard.yml "ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46" +require_text .github/workflows/container-image.yml "ghcr.io/\${{ github.repository }}" +require_text .github/workflows/container-image.yml "cosign sign --yes" +require_text .github/workflows/container-image.yml "cosign verify" +require_text .github/workflows/container-image.yml "evydence-container-image-manifest.json" +require_text .github/workflows/scorecard.yml "ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a" require_text .github/workflows/scorecard.yml "publish_results: true" require_text .github/workflows/scorecard-sarif.yml "publish_results: false" -require_text .github/workflows/scorecard-sarif.yml "github/codeql-action/upload-sarif@fee9466b8957867761f2d78f922ab084e3e2dd17" +require_text .github/workflows/scorecard-sarif.yml "github/codeql-action/upload-sarif@03e4368ac7daa2bd82b3e85262f3bf87ee112f57" require_text SUPPORT.md "sanitized logs" require_text SUPPORT.md "release evidence artifacts" require_text TRADEMARKS.md "Evydence fork" @@ -101,6 +106,7 @@ require_text docs/reference/release-evidence-index.md "evydence-release-provenan require_text docs/reference/release-evidence-index.md "not legal compliance proof" require_text docs/reference/maintainer-review-policy.md "CODEOWNERS" require_text docs/reference/maintainer-review-policy.md "tenant-scoped resources cannot cross tenant boundaries" +require_text docs/reference/maintainer-review-policy.md "OpenSSF Scorecard and Scorecard SARIF remain" require_text docs/reference/roadmap.md "one API writer replica" require_text docs/reference/roadmap.md "Release candidates" From 3a8f1eb8c90d5e84cb4bc3d28d9680e863d9d79c Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 21:47:46 +0300 Subject: [PATCH 169/287] docs: record public container image evidence --- .production_readiness_v6.md | 2 +- CHANGELOG.md | 3 +++ Makefile | 2 ++ README.md | 2 ++ deploy/airgap/manifest.yaml | 1 + docs/kubernetes.md | 4 ++-- docs/reference/release-evidence-index.md | 28 +++++++++++++++++++++++- scripts/release_acceptance.sh | 2 ++ 8 files changed, 40 insertions(+), 4 deletions(-) diff --git a/.production_readiness_v6.md b/.production_readiness_v6.md index 0e35be4..ade788a 100644 --- a/.production_readiness_v6.md +++ b/.production_readiness_v6.md @@ -21,7 +21,7 @@ Remediation evidence added after this audit: - `make public-release-verify TAG=v0.1.0-rc.4` verifies public release assets in a temporary directory with public checksums, in-toto statement shape checks, and the released Linux amd64 CLI verifier. - `make restore-rehearsal-check` exercises app-layer and live PostgreSQL backup/restore tests. -- `.github/workflows/container-image.yml` publishes `ghcr.io/aatuh/evydence:` when run by a maintainer and writes digest/cosign evidence for the image workflow artifact set. +- `.github/workflows/container-image.yml` published `ghcr.io/aatuh/evydence:v0.1.0-rc.4@sha256:de5627ec300cb603c3f1dc21029bffc096d43399114888cd5c194e00f1285603` in workflow run `26721113041`; anonymous digest inspection succeeded, and image manifest plus cosign verification output were attached to the public `v0.1.0-rc.4` release. - `docs/reference/maintainer-review-policy.md` records the branch-check policy: `Production Check` and `CodeQL Analyze` are required; OpenSSF Scorecard and Scorecard SARIF remain scheduled/manual advisory checks until they can gate pull requests deterministically. - Local validation passed: `go test ./...`, `make restore-rehearsal-check`, `make public-release-verify TAG=v0.1.0-rc.4`, `make docs-check`, `make release-acceptance`, Docker image build `evydence:readiness-v6`, and `make production-check` with `.test.env.example` and healthy Compose PostgreSQL. diff --git a/CHANGELOG.md b/CHANGELOG.md index 6128e2d..d12d7b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,9 @@ results, no secure-release guarantee, and no regulator or auditor acceptance. GitHub Releases into a clean temporary directory, checking release checksums, validating in-toto provenance metadata shape, and verifying the signed release manifest with the released Linux amd64 CLI. +- Container image workflow evidence for + `ghcr.io/aatuh/evydence:v0.1.0-rc.4@sha256:de5627ec300cb603c3f1dc21029bffc096d43399114888cd5c194e00f1285603`, + including release-attached image manifest and cosign verification output. - Repository-owned restore rehearsal target for app-layer and live PostgreSQL backup/restore mechanics. - Static package-viewer preview asset for public docs. diff --git a/Makefile b/Makefile index 1d13074..522efa1 100644 --- a/Makefile +++ b/Makefile @@ -237,6 +237,8 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'ghcr.io/aatuh/evydence' docs/reference/release-evidence-index.md >/dev/null @grep -F 'ghcr.io/aatuh/evydence' docs/kubernetes.md >/dev/null @grep -F 'ghcr.io/aatuh/evydence' deploy/airgap/manifest.yaml >/dev/null + @grep -F 'sha256:de5627ec300cb603c3f1dc21029bffc096d43399114888cd5c194e00f1285603' docs/reference/release-evidence-index.md docs/kubernetes.md deploy/airgap/manifest.yaml >/dev/null + @grep -F 'cosign verify' docs/reference/release-evidence-index.md >/dev/null @grep -F 'github/codeql-action/init@03e4368ac7daa2bd82b3e85262f3bf87ee112f57' .github/workflows/codeql.yml >/dev/null @grep -F 'security-and-quality' .github/workflows/codeql.yml >/dev/null @grep -F 'Controlled self-hosted production candidate' docs/reference/release-candidate.md >/dev/null diff --git a/README.md b/README.md index c442da6..3662962 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,8 @@ Container images for the release-candidate line are published, when the maintainer image workflow has run for the tag, as `ghcr.io/aatuh/evydence:`. Treat the digest and cosign evidence as the operator trust input, not the mutable tag alone. +For `v0.1.0-rc.4`, the published image is +`ghcr.io/aatuh/evydence:v0.1.0-rc.4@sha256:de5627ec300cb603c3f1dc21029bffc096d43399114888cd5c194e00f1285603`. ## Fastest Proof Path diff --git a/deploy/airgap/manifest.yaml b/deploy/airgap/manifest.yaml index 3c1d7fd..192be40 100644 --- a/deploy/airgap/manifest.yaml +++ b/deploy/airgap/manifest.yaml @@ -3,6 +3,7 @@ images: - name: evydence repository: ghcr.io/aatuh/evydence tag: v0.1.0-rc.4 + digest: sha256:de5627ec300cb603c3f1dc21029bffc096d43399114888cd5c194e00f1285603 required: true bundled_paths: - migrations/ diff --git a/docs/kubernetes.md b/docs/kubernetes.md index 5fd6a1c..27f6e05 100644 --- a/docs/kubernetes.md +++ b/docs/kubernetes.md @@ -35,8 +35,8 @@ Store real values in your secret manager or sealed-secret process. Do not commit ```sh helm upgrade --install evydence ./deploy/helm/evydence \ - --set image.repository=registry.example.com/evydence \ - --set image.tag=v0.1.0-rc.4@sha256:replace-with-operator-image-digest \ + --set image.repository=ghcr.io/aatuh/evydence \ + --set image.tag=v0.1.0-rc.4@sha256:de5627ec300cb603c3f1dc21029bffc096d43399114888cd5c194e00f1285603 \ --set env.s3Endpoint=s3.example.com \ --set env.s3Bucket=evydence ``` diff --git a/docs/reference/release-evidence-index.md b/docs/reference/release-evidence-index.md index d89c838..95fb65c 100644 --- a/docs/reference/release-evidence-index.md +++ b/docs/reference/release-evidence-index.md @@ -54,7 +54,16 @@ The public prerelease includes release archives for Linux, macOS, and Windows; `evydence-release-provenance.json`; `evydence-release-provenance.intoto.jsonl`; `release-notes.md`; `evydence-release-manifest.json`; `evydence-release-manifest.sig.json`; and -`evydence-release-manifest.sig`. +`evydence-release-manifest.sig`. The release assets also include +`evydence-container-image-manifest.json` and +`evydence-container-image-cosign-verify.json` for the separately published +container image. + +The current project-owned container image is +`ghcr.io/aatuh/evydence:v0.1.0-rc.4@sha256:de5627ec300cb603c3f1dc21029bffc096d43399114888cd5c194e00f1285603`. +It was produced by the Container Image workflow run +[`26721113041`](https://github.com/aatuh/evydence/actions/runs/26721113041) +from release source commit `944c4c6694535f6fc23a2b272e58347217321672`. ## Local Verification @@ -86,6 +95,23 @@ The helper downloads the release assets with `gh`, checks the public checksums, validates the in-toto statement shape, extracts the released Linux amd64 CLI, and verifies the signed manifest with that released binary. +To verify the public container image digest and workflow identity, run: + +```sh +docker buildx imagetools inspect ghcr.io/aatuh/evydence:v0.1.0-rc.4 \ + --format '{{json .Manifest.Digest}}' +cosign verify \ + --certificate-identity-regexp 'https://github.com/aatuh/evydence/.github/workflows/container-image.yml@.*' \ + --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \ + ghcr.io/aatuh/evydence@sha256:de5627ec300cb603c3f1dc21029bffc096d43399114888cd5c194e00f1285603 +``` + +Expected digest: +`sha256:de5627ec300cb603c3f1dc21029bffc096d43399114888cd5c194e00f1285603`. +The cosign verification proves the configured workflow identity signed the +image digest; it is not legal compliance proof, certification, complete SBOM +proof, authoritative vulnerability coverage, or a secure-release guarantee. + ## Publication Status The first public release candidate is published. GitHub Releases are now the diff --git a/scripts/release_acceptance.sh b/scripts/release_acceptance.sh index 7071054..db8687a 100755 --- a/scripts/release_acceptance.sh +++ b/scripts/release_acceptance.sh @@ -103,6 +103,8 @@ require_text docs/reference/release-candidate.md "Release evidence index" require_text docs/reference/release-evidence-index.md "evydence-release-manifest.sig.json" require_text docs/reference/release-evidence-index.md "evydence-release-manifest.sig" require_text docs/reference/release-evidence-index.md "evydence-release-provenance.intoto.jsonl" +require_text docs/reference/release-evidence-index.md "evydence-container-image-manifest.json" +require_text docs/reference/release-evidence-index.md "sha256:de5627ec300cb603c3f1dc21029bffc096d43399114888cd5c194e00f1285603" require_text docs/reference/release-evidence-index.md "not legal compliance proof" require_text docs/reference/maintainer-review-policy.md "CODEOWNERS" require_text docs/reference/maintainer-review-policy.md "tenant-scoped resources cannot cross tenant boundaries" From 8e10571d47a31b89cba8cd5e389045c2e327ec46 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 21:52:14 +0300 Subject: [PATCH 170/287] chore: apply latest CodeQL action pin --- .github/workflows/codeql.yml | 6 +++--- .github/workflows/scorecard-sarif.yml | 2 +- Makefile | 6 +++--- scripts/release_acceptance.sh | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 78ca6aa..ecdcdcf 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -25,13 +25,13 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Initialize CodeQL - uses: github/codeql-action/init@03e4368ac7daa2bd82b3e85262f3bf87ee112f57 # v4 + uses: github/codeql-action/init@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 with: languages: go queries: security-and-quality - name: Autobuild - uses: github/codeql-action/autobuild@03e4368ac7daa2bd82b3e85262f3bf87ee112f57 # v4 + uses: github/codeql-action/autobuild@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 - name: Analyze - uses: github/codeql-action/analyze@03e4368ac7daa2bd82b3e85262f3bf87ee112f57 # v4 + uses: github/codeql-action/analyze@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 diff --git a/.github/workflows/scorecard-sarif.yml b/.github/workflows/scorecard-sarif.yml index e5ac63f..ba3fd19 100644 --- a/.github/workflows/scorecard-sarif.yml +++ b/.github/workflows/scorecard-sarif.yml @@ -29,6 +29,6 @@ jobs: publish_results: false - name: Upload SARIF - uses: github/codeql-action/upload-sarif@03e4368ac7daa2bd82b3e85262f3bf87ee112f57 # v4 + uses: github/codeql-action/upload-sarif@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 with: sarif_file: scorecard-results.sarif diff --git a/Makefile b/Makefile index 522efa1..042bdc9 100644 --- a/Makefile +++ b/Makefile @@ -100,8 +100,8 @@ meta-check: ## Validate root legal, governance, support, and release-evidence me @grep -F 'ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a' .github/workflows/scorecard.yml >/dev/null @grep -F 'OpenSSF Scorecard SARIF' .github/workflows/scorecard-sarif.yml >/dev/null @grep -F 'ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a' .github/workflows/scorecard-sarif.yml >/dev/null - @grep -F 'github/codeql-action/upload-sarif@03e4368ac7daa2bd82b3e85262f3bf87ee112f57' .github/workflows/scorecard-sarif.yml >/dev/null - @grep -F 'github/codeql-action/analyze@03e4368ac7daa2bd82b3e85262f3bf87ee112f57' .github/workflows/codeql.yml >/dev/null + @grep -F 'github/codeql-action/upload-sarif@7211b7c8077ea37d8641b6271f6a365a22a5fbfa' .github/workflows/scorecard-sarif.yml >/dev/null + @grep -F 'github/codeql-action/analyze@7211b7c8077ea37d8641b6271f6a365a22a5fbfa' .github/workflows/codeql.yml >/dev/null @grep -F 'actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd' .github/workflows/ci.yml >/dev/null @grep -F 'actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c' .github/workflows/ci.yml >/dev/null @grep -F 'actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a' .github/workflows/ci.yml >/dev/null @@ -239,7 +239,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'ghcr.io/aatuh/evydence' deploy/airgap/manifest.yaml >/dev/null @grep -F 'sha256:de5627ec300cb603c3f1dc21029bffc096d43399114888cd5c194e00f1285603' docs/reference/release-evidence-index.md docs/kubernetes.md deploy/airgap/manifest.yaml >/dev/null @grep -F 'cosign verify' docs/reference/release-evidence-index.md >/dev/null - @grep -F 'github/codeql-action/init@03e4368ac7daa2bd82b3e85262f3bf87ee112f57' .github/workflows/codeql.yml >/dev/null + @grep -F 'github/codeql-action/init@7211b7c8077ea37d8641b6271f6a365a22a5fbfa' .github/workflows/codeql.yml >/dev/null @grep -F 'security-and-quality' .github/workflows/codeql.yml >/dev/null @grep -F 'Controlled self-hosted production candidate' docs/reference/release-candidate.md >/dev/null @grep -F 'Release evidence index' docs/reference/release-candidate.md >/dev/null diff --git a/scripts/release_acceptance.sh b/scripts/release_acceptance.sh index db8687a..2cc9c9c 100755 --- a/scripts/release_acceptance.sh +++ b/scripts/release_acceptance.sh @@ -76,7 +76,7 @@ require_text .github/pull_request_template.md "tenant isolation" require_text .github/pull_request_template.md "Sensitive Data Check" require_text CODEOWNERS "internal/app/" require_text CODEOWNERS "docs/reference/release-evidence-index.md" -require_text .github/workflows/codeql.yml "github/codeql-action/analyze@03e4368ac7daa2bd82b3e85262f3bf87ee112f57" +require_text .github/workflows/codeql.yml "github/codeql-action/analyze@7211b7c8077ea37d8641b6271f6a365a22a5fbfa" require_text .github/workflows/codeql.yml "security-and-quality" require_text .github/workflows/ci.yml "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" require_text .github/workflows/release-artifacts.yml "contents: read" @@ -87,7 +87,7 @@ require_text .github/workflows/container-image.yml "evydence-container-image-man require_text .github/workflows/scorecard.yml "ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a" require_text .github/workflows/scorecard.yml "publish_results: true" require_text .github/workflows/scorecard-sarif.yml "publish_results: false" -require_text .github/workflows/scorecard-sarif.yml "github/codeql-action/upload-sarif@03e4368ac7daa2bd82b3e85262f3bf87ee112f57" +require_text .github/workflows/scorecard-sarif.yml "github/codeql-action/upload-sarif@7211b7c8077ea37d8641b6271f6a365a22a5fbfa" require_text SUPPORT.md "sanitized logs" require_text SUPPORT.md "release evidence artifacts" require_text TRADEMARKS.md "Evydence fork" From fb813e29cccd5616ea126e54cee360762c12cd78 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 21:56:50 +0300 Subject: [PATCH 171/287] docs: mark readiness v6 remediation complete --- .production_readiness_v6.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.production_readiness_v6.md b/.production_readiness_v6.md index ade788a..37ff66c 100644 --- a/.production_readiness_v6.md +++ b/.production_readiness_v6.md @@ -9,7 +9,7 @@ Status legend: Repository-local and repository-admin remediation from this v6 audit: - [x] Keep `.production_readiness_v6.md` as a tracked repository artifact and current remediation source. -- [ ] Resolve the visible failing Dependabot PR signal by applying or superseding the dependency updates with passing default-branch checks. +- [x] Resolve the visible failing Dependabot PR signal by applying or superseding the dependency updates with passing default-branch checks. - [x] Add a release-binary quick proof path that verifies public `v0.1.0-rc.4` assets from a clean temporary directory before any source-checkout workflow. - [x] Add public docs and static visual proof for the package viewer/readiness/customer package review path. - [x] Add an explicit `v0.1.0-rc.4` changelog section. @@ -23,6 +23,7 @@ Remediation evidence added after this audit: - `make restore-rehearsal-check` exercises app-layer and live PostgreSQL backup/restore tests. - `.github/workflows/container-image.yml` published `ghcr.io/aatuh/evydence:v0.1.0-rc.4@sha256:de5627ec300cb603c3f1dc21029bffc096d43399114888cd5c194e00f1285603` in workflow run `26721113041`; anonymous digest inspection succeeded, and image manifest plus cosign verification output were attached to the public `v0.1.0-rc.4` release. - `docs/reference/maintainer-review-policy.md` records the branch-check policy: `Production Check` and `CodeQL Analyze` are required; OpenSSF Scorecard and Scorecard SARIF remain scheduled/manual advisory checks until they can gate pull requests deterministically. +- Dependency update evidence is clean: visible Dependabot update runs for the remediated dependencies passed, public default-branch `Production Check` and `CodeQL` passed for `295147138ba9cb72a1da5e04948e5d116f2273eb`, and `gh pr list --repo aatuh/evydence --state open` returned no open pull requests. - Local validation passed: `go test ./...`, `make restore-rehearsal-check`, `make public-release-verify TAG=v0.1.0-rc.4`, `make docs-check`, `make release-acceptance`, Docker image build `evydence:readiness-v6`, and `make production-check` with `.test.env.example` and healthy Compose PostgreSQL. External, adoption-dependent, operator-environment, or account-policy work: From 87f394f0ebffc2fb895545d4e63fa8754e7f60ee Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 21:58:50 +0300 Subject: [PATCH 172/287] docs: remove internal dotfile reports --- .gitignore | 1 - .implementation_increments.md | 268 -------- .maturity_next_steps_v2_status.md | 103 ---- .production_readiness.md | 734 ---------------------- .production_readiness_v2.md | 657 -------------------- .production_readiness_v3.md | 435 ------------- .production_readiness_v4.md | 659 -------------------- .production_readiness_v5.md | 808 ------------------------- .production_readiness_v6.md | 659 -------------------- CONTRIBUTING.md | 4 +- docs/README.md | 2 +- docs/reference/production-readiness.md | 5 +- 12 files changed, 5 insertions(+), 4330 deletions(-) delete mode 100644 .implementation_increments.md delete mode 100644 .maturity_next_steps_v2_status.md delete mode 100644 .production_readiness.md delete mode 100644 .production_readiness_v2.md delete mode 100644 .production_readiness_v3.md delete mode 100644 .production_readiness_v4.md delete mode 100644 .production_readiness_v5.md delete mode 100644 .production_readiness_v6.md diff --git a/.gitignore b/.gitignore index dd873d5..dc73eb8 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,6 @@ !.env.example !.api.env.example !.test.env.example -!.production_readiness*.md coverage.out bin/ diff --git a/.implementation_increments.md b/.implementation_increments.md deleted file mode 100644 index 8785700..0000000 --- a/.implementation_increments.md +++ /dev/null @@ -1,268 +0,0 @@ -# Complete Evydence Implementation Increment Plan - -This file tracks every increment needed to implement the full system described in `.initial_design.md`, from the current release-ledger MVP through production v1, high-trust v2, enterprise v3, and future extensions. - -Status legend: - -- `[ ]` not done -- `[x]` done - -## Implementation Rules - -- Each increment must be independently testable, documented, and committable. -- Run targeted tests during implementation and `make finalize` before closing each increment. -- Create Conventional Commits at sensible green checkpoints. -- Update OpenAPI, migrations, docs, examples, and tests with every behavior change. -- Preserve tenant isolation, append-only evidence behavior, safe error handling, and no compliance/certification/secure-release claims. -- Mark an increment `[x]` only after implementation, docs, tests, and final gates pass. - -## Completed Increments - -1. `[x]` Release Ledger MVP Scaffold - Core Go API, tenant API keys, evidence, artifacts, products/projects/releases, audit chain, signing keys, release bundles, SBOM, vulnerability scans, OpenAPI upload, policy evaluation, missing evidence, release readiness, docs, migrations, Docker Compose, OpenAPI, and tests. - -2. `[x]` Durable Runtime Foundation - PostgreSQL snapshot persistence, filesystem object storage, persisted outbox, worker polling, object-store replay with digest checks, parser-derived field persistence, production config checks, migrations, and Postgres test gates. - -3. `[x]` VEX, Vulnerability Decisions, Exceptions - OpenVEX ingestion, normalized vulnerability decisions, scoped exceptions, approval flow, and deterministic release-risk handling. - -4. `[x]` GitHub Actions Provenance And Build Attestations - Collectors, build runs, GitHub Actions metadata capture, DSSE/in-toto/SLSA structural parsing, attestation evidence, readiness gates, CLI upload, and composite action docs. - -5. `[x]` Control Frameworks And CRA/Control Coverage Reports - Tenant-created frameworks, controls, control evidence links, control waivers through exceptions, control coverage reports, CRA-readiness reports, migrations, API routes, and docs. - -## Remaining Core Product Increments - -6. `[x]` Relational Store Split - Added migration-backed relational tables and tenant-scoped resource projection rows for implemented resources, with transactional PostgreSQL saves, relational identity/idempotency/customer-portal-token rows, relational release-ledger core rows, relational build provenance/source/deployment/incident/security-evidence/SBOM-diff/vulnerability-workflow/contract-diff/custom-policy/waiver/approval/DSSE-trust-root/collector-release/Cosign-verification/signing-provider/Merkle-batch/transparency-checkpoint/evidence-lifecycle/release-candidate/VEX/control rows, relational package/report/retention/provider-verification/signing-operation/future-extension rows, missing-snapshot fallback loading for identity, SSO session, release-ledger, build provenance, source/deployment, incident, security evidence, SBOM diff, vulnerability workflow, contract diff, custom policy, waiver, approval, DSSE trust-root, collector release, Cosign verification, signing provider, Merkle batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension families, tenant/release indexes, persisted idempotency state, and outbox row locking. Production runtime loading defaults to relational-only and disables compatibility snapshot writes while per-resource repository tuning remains future hardening. - -7. `[x]` Evidence Search, Filtering, And Timeline Querying - Added tenant-scoped evidence search by product, project, release, build, deployment, type, subtype, source, collector, created time, subject refs, tags, and verification status. - -8. `[x]` Evidence Lifecycle: Amendments, Redactions, Tombstones - Added append-only amendment, redaction, tombstone, retention marker, and supersession lifecycle events without silently mutating historical evidence fields. - -9. `[x]` Release Candidates - Added release candidates as immutable snapshots of builds, artifacts, SBOMs, scans, VEX, OpenAPI contracts, and bundles before append-only promotion or rejection. - -10. `[x]` Container Images And Artifact Signatures - Added OCI image records, image digests, detached signatures, artifact signature evidence, and digest/signature verification receipts. - -11. `[x]` Repository, Commit, Branch, Pull Request Model - Added source repositories, commits, branches, pull requests, review decision metadata, protected-branch snapshots, and source evidence APIs. - -12. `[x]` GitHub Source Collector - Extended GitHub support beyond Actions metadata to collect repository, commit, PR, review, and branch-protection evidence without replacing source control. - -13. `[x]` GitLab CI And Source Collector - Added GitLab CI/build/source metadata ingestion, project/pipeline/job identity capture, source snapshots, and collector-scoped API keys. - -14. `[x]` Generic CI Collector - Added provider-neutral CI build/run ingestion for Jenkins, Azure DevOps, Buildkite, and offline CI contexts using explicit metadata and artifact digests. - -15. `[x]` Deployment Environments And Deployment Evidence - Added environments, deployment events, artifact/release/environment links, rollout metadata, rollback-as-new-event behavior, and deployment evidence reports. - -16. `[x]` Incident Timeline And Remediation Evidence - Added incidents, timeline events, remediation tasks, evidence links, Ed25519-signed incident webhook ingestion with replay detection, and deterministic incident package reports. - -17. `[x]` Static, Dynamic, Secret, And License Scan Evidence - Added SAST, DAST, secret scanning, license scanning, SARIF where relevant, safe redaction/quarantine behavior, and normalized summaries. - -18. `[x]` Threat Models, Security Reviews, And Pen Test Reports - Added sensitive manual/security evidence types with lower default trust, scoped access, raw payload preservation, and explicit limitations. - -19. `[x]` SPDX And SBOM Expansion - Added SPDX JSON first-class ingestion, component inventory storage, component lookup APIs, parser version metadata, and validation limitations. - -20. `[x]` SBOM Diff And Dependency Change Evidence - Added SBOM diffs, dependency change records, changed components, and release comparison data for added/removed components. - -21. `[x]` CycloneDX VEX Support - Added CycloneDX VEX ingestion alongside OpenVEX, normalized decision creation, raw payload preservation, and format-specific validation. - -22. `[x]` Advanced Vulnerability Workflows - Added scanner metadata workflow records, SLA/disagreement/supersession/re-open markers, and vulnerability posture reports. - -23. `[x]` OpenAPI Diff And Contract Checks - Added `ContractDiff`, deterministic contract comparison, operation-level breaking/non-breaking change classification based on stored OpenAPI metadata, and path-count fallback for older stored contracts. Approval records cover breaking-change review separately. - -24. `[x]` API Security Check Evidence - Added API lint/security scan evidence, OpenAPI ruleset results, API governance metadata, and control evidence-compatible resource types. - -25. `[x]` Policy Engine V2 - Added versioned custom policies with a deterministic internal DSL, stored input snapshots, replayable evaluations, and controlled extensibility beyond built-in gates. - -26. `[x]` Waiver Resource - Added a first-class waiver resource separate from exceptions for controls/policies, with owner, risk, expiry, approval, supersession, and audit-chain entries. - -27. `[x]` Approval Records - Added explicit immutable approval records for releases, breaking API changes, waivers, security reviews, and customer packages. - -28. `[x]` Customer Security Packages - Added scoped JSON package manifests and ZIP downloads, redaction profiles, expiry, access auditing, verification instructions, and over-disclosure tests. ZIP packages include scoped manifest metadata and verification guidance, not raw tenant evidence payload bytes. - -29. `[x]` Security Review Package Report - Added scoped security-review reports for customer/procurement review with evidence summaries, assumptions, limitations, and redaction-aware output. - -30. `[x]` CRA Readiness HTML Package - Extended CRA readiness from JSON to reproducible HTML/package output with deterministic templates and no legal compliance claims. - -31. `[x]` Control Framework Template Packs - Added versioned built-in starter packs for CRA readiness, NIST SSDF-lite, SOC 2-style technical evidence, and ISO 27001-style technical evidence, with tenant install APIs. - -32. `[x]` Custom Report Templates - Added tenant-defined report templates with strict allowed fields, deterministic rendering, redaction controls, and template versioning. - -## Integrity, Signing, And Verification Increments - -33. `[x]` Offline Verifier CLI - Extended CLI to verify evidence bundle manifests, included Ed25519 bundle signatures when public keys/signatures are present, and exported audit-chain hash continuity without API access. - -34. `[x]` Evidence Bundle Export And Import - Added portable evidence export/import manifests for air-gapped review, including hashes, signatures, chain checkpoints, and verification instructions. - -35. `[x]` DSSE Signature Verification - Moved build attestations from structural validation to optional cryptographic verification with configured Ed25519 trust roots and verification receipts. - -36. `[x]` Cosign/Sigstore Verification - Added cosign-style artifact/container image verification metadata, optional Rekor metadata capture, and digest-bound signature evidence. Full Sigstore trust-chain validation remains future trust-root expansion. - -37. `[x]` Key Revocation And Valid-At-Signing Semantics - Added signing-key revocation, append-only audit entries, and valid-at-signing verification behavior for historical signatures created before revocation. - -38. `[x]` KMS/HSM Signing Provider Abstraction - Added signing-provider records for local encrypted dev, AWS KMS, GCP KMS, Azure Key Vault, and PKCS#11 HSM references without storing private key material. Production-grade signing operations remain behind external signing mode. - -39. `[x]` Merkle Batching And Chain Checkpoints - Added signed Merkle batches over tenant audit-chain ranges and verification of checkpoint root/signature consistency. - -40. `[x]` External Transparency Checkpoints - Added optional external transparency/timestamp checkpoint records for Merkle batches without requiring public transparency for local trust. - -41. `[x]` WORM/Object Lock Integration - Added tenant-prefixed object-retention policy records, optional sample object keys, S3/MinIO bucket and sample-object retention checks, and verification transitions. Broader enforcement still depends on configured object store policy and deployment review. - -## Runtime, Operations, And Deployment Increments - -42. `[x]` S3/MinIO Runtime Object Store - Added an S3/MinIO-compatible object-store adapter with tenant-prefixed key validation, metadata preservation, runtime env selection, and operations guidance. - -43. `[x]` Backup And Restore - Added backup manifests with state hashes, resource counts, audit-chain consistency checks, verification endpoints, and operations guidance for paired database/object-store backups. - -44. `[x]` Observability And Readiness - Added `/v1/ready`, admin-scoped safe JSON and Prometheus text metrics, operations guidance, Prometheus alert rules, and a Grafana dashboard starter. OpenTelemetry exporter wiring remains deployment-specific hardening. - -45. `[x]` Admin Audit Querying - Added `/v1/audit-log` with tenant-scoped subject/time/limit filters, export-safe audit-chain fields, and admin access control. - -46. `[x]` Helm Chart And Kubernetes Deployment - Added Helm chart skeleton with API and worker deployments, external secret wiring, S3/KMS-style configuration, service, optional ingress, readiness/liveness probes, and Kubernetes deployment docs. - -47. `[x]` Air-Gapped Installation Package - Added air-gapped package manifest, offline install docs, bundled migration/OpenAPI/chart guidance, import/export workflow, and verification instructions. - -48. `[x]` Signed Release Artifacts - Added CLI release artifact manifest creation, Ed25519 signing, verification, key generation, and operator documentation for publishing checksums/signatures. - -49. `[x]` Production Hardening Review - Added production hardening review checklist covering security, privacy, operability, backup, restore, failure modes, collector pinning, and safe language constraints. - -## Developer Experience And Ecosystem Increments - -50. `[x]` SDK Generation Workflow - Added curated Go, TypeScript, and Python SDK examples, SDK documentation, SSO/OIDC identity-provider convenience helpers, and project-owned SDK file drift checks. - -51. `[x]` CLI Uploader Completeness - Expanded CLI with manifest-based bulk uploads, air-gapped bundle import upload, release artifact manifest signing/verification, local path validation, and safe API error reporting. - -52. `[x]` GitHub Action Release Workflow - Added repository-local GitHub Actions release evidence workflow example for build artifact digest and Evydence provenance upload. Full marketplace action publishing remains future packaging work. - -53. `[x]` GitLab CI Template - Added GitLab CI release evidence template for build artifact digest and manifest-based evidence upload. - -54. `[x]` Collector Supply-Chain Security - Added collector release supply-chain records, version pinning, signature/SBOM/scan evidence references, collector health report API, docs, migrations, and tests. - -55. `[x]` Import Bundle Collector - Added `import_bundle` collector type, bundle import collector scopes, and CLI upload flow for evidence bundles moved through air-gapped transfer. - -56. `[x]` Documentation Portal Structure - Added `docs/README.md` plus tutorial, how-to, reference, and explanation entry points, and wired docs-check to verify the canonical portal files. - -## Enterprise And Commercial Increments - -57. `[x]` Organizations, Users, And Human Identity - Added tenant-scoped organizations, human users, user deactivation, audit-chain entries, human actor attribution, snapshot persistence, migrations, API routes, and tests. - -58. `[x]` RBAC And ABAC - Added role bindings for users and collectors, role-to-scope enforcement for human sessions, admin/customer/collector roles, tenant isolation checks, API routes, and tests. - -59. `[x]` Enterprise SSO/SAML/OIDC - Added OIDC/SAML provider records, verified identity links, one-time hashed SSO session tokens, session revocation, role mapping metadata, static JWKS-backed local OIDC ID-token verification, OIDC discovery/JWKS refresh, local SAML assertion verification against configured signing certificates, API-first session exchange with HttpOnly session-cookie output, audit entries, API routes, and tests. Live provider management API validation, browser redirect/callback orchestration, and external group synchronization remain external/provider work. - -60. `[x]` Multi-Tenant Admin Console API - Added low-detail instance admin snapshot API with tenant/resource counts and no raw evidence, token, or secret exposure. - -61. `[x]` Legal Hold And Advanced Retention - Added legal holds, retention overrides, retention reports, tenant-scoped validation, audit entries, persistence, migrations, API routes, and docs. - -62. `[x]` Customer Portal - Added expiring customer portal package tokens, hash-only token storage, scoped package manifest access, access auditing, API routes, and tests without exposing raw tenant evidence. - -63. `[x]` Customer-Specific Questionnaire Packages - Added questionnaire templates, evidence-mapped questionnaire packages, deterministic responses with evidence IDs and limitations, persistence, migrations, API routes, and tests. - -64. `[x]` Advanced CRA/SOC2/ISO Evidence Templates - Expanded built-in starter template packs for CRA-readiness, NIST SSDF-lite, SOC 2-style technical evidence, and ISO 27001-style technical evidence while preserving readiness-only wording. - -65. `[x]` Commercial Collector Framework - Added tenant-scoped commercial collector definitions with provider/version/manifest digest/allowed scopes, persistence, migrations, API routes, docs, and tests. - -## Future Extensions - -66. `[x]` AI Evidence Summarization - Added deterministic evidence summaries with explicit evidence citations, assumptions, limitations, tenant isolation, persistence, migrations, API route, OpenAPI entry, docs, and tests. This is evidence-backed summarization only; no automated compliance conclusions are made. - -67. `[x]` Questionnaire Automation - Added questionnaire drafts generated from stored questionnaire templates and matching evidence/control links, with manifest hashes, limitations, tenant isolation, persistence, migrations, API route, OpenAPI entry, docs, and tests. - -68. `[x]` Graph Exploration Layer - Added persisted evidence graph snapshots for product/release adjacency using PostgreSQL resource projections and snapshot state. No graph database was introduced. - -69. `[x]` SaaS Edition Foundation - Added explicit-instance-admin SaaS edition profile records with configuration hashes, limitations, persistence, migrations, API route, OpenAPI entry, docs, and tests. - -70. `[x]` Public Transparency Log - Added optional public transparency log and published-entry records linked to local Merkle batches and transparency checkpoints, with entry hashes, operator-supplied and fetched RFC6962-style inclusion proof verification receipts, persistence, migrations, API routes, OpenAPI entries, docs, and tests. - -71. `[x]` Marketplace Collectors - Added marketplace collector package records with publisher, provider/version, manifest digest, optional signature/SBOM/scan references, tenant isolation, persistence, migrations, API routes, OpenAPI entries, docs, and tests. - -72. `[x]` PDF Designer - Added reproducible PDF report package metadata and object-store payload handling with payload hash, size, limitations, tenant isolation, persistence, migrations, API route, OpenAPI entry, docs, and tests. - -73. `[x]` ML Anomaly Detection - Added deterministic anomaly report records over stored release evidence signals with assumptions, limitations, tenant isolation, persistence, migrations, API route, OpenAPI entry, docs, and tests. No ML model or automated security conclusion is included. - -## Implemented-But-Partial Areas - -- `[x]` Object-retention verification receipts now record a reproducible verification hash with bucket-level and optional sample-object checks, while broad WORM/object-lock enforcement remains a deployment and object-store control. -- `[x]` External signing-provider operation receipts now record payload hashes, checks, and signature references, while production KMS/HSM adapter execution remains deployment hardening work. -- `[x]` Stored OIDC/SAML identity-link verification records provider-verification receipts, and OIDC ID tokens plus SAML assertions can be verified locally against configured tenant trust material. Public OIDC JWKS can be refreshed from discovery metadata, public JWKS plus SAML signing certificates can be rotated without recreating the provider, and SSO credential exchange can issue bearer session secrets plus HttpOnly cookies. Live provider management API calls, browser redirect/callback orchestration, and external group synchronization remain external/provider work. -- `[x]` Public transparency log records now link local Merkle checkpoints to external entry metadata and can verify operator-supplied or fetched inclusion proof material locally. Provider-specific trust semantics and availability remain deployment responsibilities. -- `[x]` Marketplace collector records now capture package metadata and evidence references, and expose package health reports for signature, SBOM, and vulnerability scan evidence gaps. Marketplace distribution remains external operational hardening. -- `[x]` Docker/Helm runtime packaging now includes the worker binary and migrations and uses commands that match the image PATH. -- `[x]` GitHub Actions example now passes the digest computed in the workflow instead of an unrelated repository variable. -- `[x]` Production hardening docs now use the built local CLI path for release manifest verification. - -## Assumptions - -- The first five increments are marked complete from current repository evidence. -- All remaining increments are needed to implement the full system described in `.initial_design.md`, including v1, v2, v3, and future/nice-to-have sections. -- Future increments should remain API-first unless the increment explicitly introduces portal/UI work. -- Integrity, tenant isolation, auditability, verification, and safe product language remain mandatory throughout. diff --git a/.maturity_next_steps_v2_status.md b/.maturity_next_steps_v2_status.md deleted file mode 100644 index bb4b47d..0000000 --- a/.maturity_next_steps_v2_status.md +++ /dev/null @@ -1,103 +0,0 @@ -# Maturity V2 Implementation Status - -Source report: `.maturity_next_steps_v2.md` - -Last updated: 2026-05-31 - -This file records repository evidence after the v2 maturity report. It is a -status companion, not a replacement for the report. Evydence remains a -controlled self-hosted production candidate; this status does not claim broad -production readiness, regulated production readiness, hosted SaaS readiness, -legal compliance, certification, complete SBOM proof, authoritative scanner -coverage, or a secure-release guarantee. - -## Closed Repo-Local Findings - -- Tagged release-candidate evidence: local annotated tag `v0.1.0-rc.3` points - at the current release-candidate commit, and `dist/v0.1.0-rc.3/` was generated - by `make release-candidate-check TAG=v0.1.0-rc.3` with live PostgreSQL, - coverage threshold, migration compatibility, signed manifest, checksums, - OpenAPI checksum, migration checksums, release notes, and manifest - verification. -- Production claim clarity: README, changelog, release evidence, release - validation, release-candidate, Kubernetes, production-readiness, and - hardening docs use controlled self-hosted production candidate language and - preserve non-claims. -- Critical relational writes: critical runtime state and release/evidence-core - mutations have focused PostgreSQL transaction paths, production startup - defaults to relational-only load, and production writes skip compatibility - snapshot persistence when PostgreSQL relational support is configured. -- Single-writer HA stance: production API startup rejects unsupported writer - modes and declared replica counts above one, enforces a PostgreSQL advisory - writer lease, Helm defaults keep API replicas at one, and docs state worker - replicas may scale through PostgreSQL outbox locking while API multi-writer - mode remains unsupported. -- Helm hardening: chart values require explicit image tags for release installs - and include security contexts, resource/probe configuration, network policy, - and single-writer guidance validated by `make deploy-check`. -- Security intake: root security/support/governance metadata documents private - security intake, supported scope, sensitive-data handling, disclosure - expectations, and non-goals without asking reporters to disclose secrets or - raw evidence publicly. -- Trust automation hardening: signing operations can use the HTTPS signing - gateway, built-in AWS KMS, GCP Cloud KMS, and Azure Key Vault executors, with - `pkcs11-hsm` remaining gateway-backed because native HSM modules and slots - are deployment-specific. OIDC provider - verification can call discovered UserInfo endpoints with a supplied access - token without persisting that token, or call an operator-controlled provider - validation gateway with only non-secret metadata and an - access-token-present flag. Public transparency proof fetches can use a - configured log endpoint or an operator-controlled transparency proof gateway - before local proof verification. S3/MinIO object-retention verification can - check bucket defaults plus sample-object retention and legal-hold status. -- Integration proof: the checked GitHub Actions example now covers build - provenance, artifact digest, SBOM upload, Grype/Trivy vulnerability-scan - normalization, optional OpenVEX and release-bundle evidence, and manifest - upload through the CLI. - -## Still Not A Broad Production Claim - -These items remain outside the current controlled candidate, or require -deployment/provider evidence that cannot be completed by repository code alone: - -- High-scale multi-writer API HA remains unsupported until the large application - ledger is split into focused services or another reviewed concurrency-control - design replaces the current single-writer stance. -- KMS/HSM custody remains deployment-specific. AWS KMS, GCP Cloud KMS, and - Azure Key Vault have direct executors that send SHA-256 digests rather than - raw payload bytes. The HTTPS signing gateway covers tenant-controlled - PKCS#11/HSM services; native module/slot handling still depends on operator - hardware, credentials, IAM review, and provider-specific tests. -- Direct provider management API clients and external group synchronization - remain provider-specific. Evydence can verify configured OIDC/SAML trust - material, optional OIDC UserInfo checks, and an operator-controlled provider - validation gateway, but GitHub, GitLab, IdP, or directory group authority - still depends on the configured provider and operator review. -- WORM/object-lock enforcement beyond configured bucket and sample-object - checks depends on object-store creation mode, IAM policy, lifecycle rules, - backups, retention settings, and provider audit evidence. -- Public transparency provider semantics and availability remain external. - Evydence can verify operator-supplied, fetched, or gateway-returned inclusion - proof material locally, but provider trust and timestamp semantics require - deployment review. -- Hosted SaaS production, regulated production, and customer-specific legal or - audit conclusions require separate controls, support, privacy, operational, - and external review work. - -## Current Gates - -Recent local evidence: - -- `make finalize`: passed after provider gateway and transparency gateway - hardening. -- `make release-acceptance`: passed after provider gateway and transparency - gateway hardening. -- `set -a; . ./.test.env.example; set +a; make production-check`: passed with - live PostgreSQL, gosec, govulncheck, race tests, migration compatibility, - release-signing smoke test, and total coverage at `80.1%`. -- `make release-candidate-check TAG=v0.1.0-rc.3`: passed and generated the - signed local release-candidate package at `dist/v0.1.0-rc.3/`. - -Release publication, cloud-provider validation, production object-lock proof, -and deployment-specific backup/restore rehearsals must be run in the target -operator environment before relying on those controls. diff --git a/.production_readiness.md b/.production_readiness.md deleted file mode 100644 index c256ec1..0000000 --- a/.production_readiness.md +++ /dev/null @@ -1,734 +0,0 @@ -# User - -Act as a brutally honest senior backend/API architect, open-source maintainer, production-readiness reviewer, security reviewer, and skeptical B2B buyer. - -Before judging quality, explicitly state the exact latest commit you inspected. If you cannot verify the latest commit, do not claim this is based on the latest state. - -Evaluate this GitHub project based on its latest publicly visible state: - -REPOSITORY: -github.com/aatuh/evydence - -GOAL: -Determine whether this project is: -1. mature and high-grade enough for real production use, -2. feature-complete enough to solve a real-world problem, -3. marketable/interesting enough to attract users, buyers, contributors, or commercial opportunities, -4. worth continuing, repositioning, hardening, or abandoning. - -Important: -Do not flatter me. -Do not infer quality from intent. -Do not judge only by GitHub stars. -Do not give a generic repository review. -Ground every major claim in repository evidence: files, README, docs, code structure, tests, CI workflows, releases, issues, examples, Docker/deployment files, security files, license, package metadata, commit history, and public project positioning. - -First, verify the latest visible state: -- repository name and URL -- default branch -- latest commit SHA and commit date you can see -- latest release/tag, if any -- primary language(s) -- license -- whether the repository appears public, active, maintained, archived, experimental, or production-oriented -- anything you could not inspect - -Evaluate using this rubric: - -## 1. What the project appears to be - -Explain in plain English: -- what problem it tries to solve -- who the likely users are -- what category it belongs to -- whether the README clearly communicates this within 30 seconds -- whether the project sounds like a library, CLI, server, API, framework, infrastructure tool, or product - -## 2. Production readiness - -Assess whether it is production-grade for serious users. - -Check: -- architecture and code organization -- API design and stability -- configuration model -- error handling -- persistence/data model, if relevant -- migrations, if relevant -- logging and observability -- authentication/authorization, if relevant -- security posture -- dependency management -- CI/CD -- automated tests -- integration/e2e tests -- release process -- versioning -- backward compatibility policy -- Docker/deployment story -- documentation quality -- operational runbook or troubleshooting docs -- examples and quickstart -- performance or scalability considerations -- failure handling and recovery -- upgrade path - -Give a score from 1–10 and explain the score brutally. - -## 3. Feature completeness - -Answer: -- What real-world production use cases does it already support? -- What important use cases are missing? -- What features are table stakes for this category? -- Which missing features are blockers? -- Which missing features are nice-to-have? -- Is the project currently a toy, prototype, useful library, production component, or productizable system? - -Give a score from 1–10. - -## 4. Security and open-source trust - -Evaluate trust signals using common open-source expectations, including: -- LICENSE -- SECURITY.md -- CONTRIBUTING.md -- CODE_OF_CONDUCT.md, if community-oriented -- dependency update automation -- vulnerability scanning -- secret scanning awareness -- branch protection / required checks, if visible -- signed releases or provenance, if relevant -- SBOM, if relevant -- OpenSSF Scorecard-style concerns -- OpenSSF Best Practices Badge-style concerns - -Do not require every item blindly. Explain which ones matter for this specific project. - -Give a score from 1–10. - -## 5. Marketability and positioning - -Evaluate from the perspective of a skeptical user or buyer: -- Is the problem painful? -- Is the target user obvious? -- Is the value proposition sharp? -- Is the category already crowded? -- Is there a clear reason to choose this over existing alternatives? -- Is the README written like a product page or only like internal notes? -- Are there compelling examples, screenshots, diagrams, demos, or benchmarks? -- Is there a plausible monetization path: support, consulting, dual licensing, hosted option, enterprise features, compliance package, templates, training, private forks, or paid integrations? -- Does the project name help or hurt? - -Give a score from 1–10. - -## 6. Differentiation - -Compare the project conceptually against likely alternatives. - -Identify: -- direct alternatives -- indirect alternatives -- “do nothing / build in-house” alternative -- what makes this project meaningfully different -- what is not yet differentiated enough - -Do not invent competitors. Search if needed. - -## 7. Repository quality checklist - -Create a table: - -| Area | Status | Evidence | Severity | Recommended fix | -|------|--------|----------|----------|-----------------| - -Include at least: -- README -- quickstart -- examples -- tests -- CI -- releases -- docs -- Docker/deployment -- security policy -- license -- contribution docs -- issue templates -- changelog -- API documentation -- configuration docs -- operational docs - -Use statuses: -- Strong -- Adequate -- Weak -- Missing -- Not applicable - -Severity: -- Blocker -- High -- Medium -- Low - -## 8. Final verdict - -Give a direct verdict using one of these: - -- Production-ready -- Production-usable with caveats -- Promising but not production-ready -- Prototype only -- Not worth continuing in current form - -Then answer directly: -- Is it mature and high-grade enough for production for most uses? -- Is it highly marketable and interesting? -- Is it useful in real-world production, meaning it has enough features? -- What should be done next? - -## 9. Highest-leverage next steps - -Give a brutally prioritized roadmap: - -### Next 1–2 days -Small fixes that immediately improve trust. - -### Next 1–2 weeks -Changes that materially improve production readiness and marketability. - -### Next 1–2 months -Changes that could make the project seriously productizable. - -For each item include: -- why it matters -- what exact files/docs/features should be added or changed -- how it improves production readiness, trust, or marketability - -## 10. README/product-page rewrite advice - -Briefly suggest how the README should be repositioned: -- sharper one-sentence pitch -- target user -- core use case -- best demo/example to show first -- proof points to add -- what to remove or de-emphasize - -Output style: -Be concise but thorough. -Use blunt language. -Separate evidence from opinion. -When uncertain, say exactly what is uncertain and what evidence would resolve it. - -# ChatGPT - -## Remediation Tracking - -Status legend: - -- `[ ]` applicable to this repository and not yet done -- `[x]` applicable to this repository and completed with repo evidence -- `[e]` external or deployment/provider/account dependent; cannot be fully completed by repository files alone - -### Current State Verification - -- [x] PR-001 Verify the latest local commit inspected, including commit date. - Evidence: local `HEAD` is `842fb053f303b2a78eb3118be6a4536715571215`, dated `2026-05-31T11:37:01+03:00`. -- [e] PR-002 Verify branch protection, required checks, private vulnerability reporting settings, public CI pass history, public stars/forks/watchers, and public release visibility. - These are GitHub account/repository settings or public platform state, not repository-file changes. - -### Highest-Leverage Trust And Release Items - -- [e] PR-003 Publish a real public GitHub release candidate with uploaded artifacts. - Repository scripts/workflows can prepare artifacts, but public publication requires GitHub release permissions, signing secret configuration, and operator action. -- [x] PR-004 Align README and changelog release-candidate wording with the current `v0.1.0-rc.3` repo evidence or make the wording version-neutral. -- [x] PR-005 Add README badges and visible proof pointers for CI, license, Go version, release status, coverage, OpenAPI precision, and production-check expectations. -- [x] PR-006 Add a blunt README "Current limitations" section near the top. -- [x] PR-007 Reposition README top section around user pain, target user, core demo, and narrow differentiation instead of leading with a long implementation inventory. -- [e] PR-008 Configure a real private security mailbox or enable GitHub private vulnerability reporting. - The repository can document the expected channel, but mailbox/advisory settings are external. -- [x] PR-009 Remove LinkedIn-first security-reporting dependence from `SECURITY.md` once an acceptable private intake path is documented or scoped as external. -- [x] PR-010 Add issue templates for bug reports, feature requests, docs problems, and non-sensitive production-support questions. -- [x] PR-011 Add a code of conduct if community contribution is desired. -- [x] PR-012 Add Dependabot or Renovate dependency automation for Go modules, GitHub Actions, Docker, and related package ecosystems. -- [x] PR-013 Add OpenSSF Scorecard workflow. -- [x] PR-014 Add project release SBOM and provenance generation to the release-candidate evidence set. -- [e] PR-015 Enforce branch protection and required checks. - This is a GitHub repository setting, though workflows/check names can be provided by repository files. - -### Product Adoption And Marketability - -- [x] PR-016 Add one complete end-to-end release-evidence demo under `examples/end-to-end-release-evidence/`. -- [x] PR-017 Add screenshots, terminal captures, diagrams, or a short demo asset that explains the product without maintainer narration. -- [x] PR-018 Add a "Why not Dependency-Track, Vanta/Drata, or build in-house?" positioning section. -- [x] PR-019 Add example generated readiness report, customer package, and audit-chain verification artifacts. -- [e] PR-020 Add customer stories, public adoption proof, or third-party case studies. - This depends on real users/customers and cannot be created honestly in repository code. -- [x] PR-021 Add API client examples for Go, TypeScript, and Python showing create release, upload SBOM, upload scan, record decision, and fetch readiness. -- [x] PR-040 Add executable test coverage for the Go SDK example path so the example is proven and does not drag the production coverage gate below threshold. -- [x] PR-041 Remove unsupported fields from SDK examples that would be rejected by strict API decoders. - -### Production Operations - -- [x] PR-022 Add a durable quickstart using PostgreSQL, object storage, API, worker, and migrations. -- [x] PR-023 Add a full production-like Docker Compose stack for API, worker, Postgres, MinIO, migrations, health checks, and env-file secrets. -- [x] PR-042 Fix the production-like Docker image and Compose command wiring so migration and worker services run their own binaries instead of passing arguments to the API entrypoint. -- [x] PR-043 Strengthen deployment checks to assert the production-like stack includes the migrate binary and explicit migrate/worker entrypoints. -- [x] PR-024 Add backup/restore runbook tied to backup manifests and object-store consistency checks. -- [x] PR-025 Add upgrade runbook with migration, rollback/forward-fix, release evidence, and compatibility guidance. -- [x] PR-026 Add incident-response runbook for operator incidents involving secrets, tenant isolation, object storage, signing, provider credentials, or evidence exports. -- [x] PR-027 Add capacity, performance, and failure-mode guidance for API writer limits, worker throughput, object sizes, DB pool settings, and outbox retries. -- [x] PR-028 Add operational diagrams for architecture and deployment. -- [x] PR-029 Reduce documentation repetition while keeping canonical references clear. - -### Architecture And Feature Maturity - -- [x] PR-030 Continue splitting the large in-process `Ledger` aggregate and massive `PersistedState` into focused services/repositories. - - [x] PR-030a Production relational-only load and focused critical/release-ledger mutation paths are already implemented. - - [x] PR-030b Split identity/session/API-key behavior behind a focused application service. - - [x] PR-030b.1 API-key authentication, bootstrap, create, and list behavior now delegate through a focused internal identity service while preserving the public `Ledger` API. - - [x] PR-030b.2 Move SSO provider/session exchange, human users, organizations, role bindings, and portal-token identity behavior through the same service boundary. - - [x] PR-030c Split release/evidence/SBOM/scan/VEX behavior behind a focused application service. - Evidence: product/project/release, artifact, evidence, SBOM, vulnerability-scan, OpenAPI-contract, VEX, vulnerability-decision, exception, and release-readiness behavior now delegates through `releaseEvidenceService` while preserving the public `Ledger` API. `go test ./internal/app ./internal/adapters/httpapi ./cmd/evydence-api ./cmd/evydence-worker` and `make fast-check` passed after the split. - - [x] PR-030d Split package/report/portal behavior behind a focused application service. - Evidence: redaction profiles, customer package access/export, portal package archive export, security-review and CRA HTML packages, evidence bundles, custom reports, questionnaire templates/packages/drafts, evidence summaries, control/CRA coverage reports, incident and vulnerability posture reports, retention reports, missing-evidence reports, PDF report packages, and anomaly reports now delegate through `packageReportService` while preserving public `Ledger` API methods. The authz inventory test now recognizes focused service receivers and still checks implementation bodies for resource-scoped authorization. `go test ./internal/app ./internal/adapters/httpapi ./cmd/evydence-api ./cmd/evydence-worker` and `make fast-check` passed after the split. - - [x] PR-030e Replace broad aggregate `SaveState` synchronization for remaining write families with canonical repository transactions. - Evidence: `persistLocked` dispatches production-style stores through `RelationalStateStore.SaveRelationalState` instead of `Store.SaveState`; the PostgreSQL adapter executes dependency-ordered relational sync functions in a transaction with compatibility snapshot writes disabled for that path. `TestRelationalStateStoreAvoidsAggregateSaveForRemainingFamilies` covers representative remaining control, incident, redaction, and customer-package write families and asserts `SaveState` is not called, while existing PostgreSQL tests verify relational load/recovery and zero `ledger_state` rows for relational-only/focused mutation paths. Memory/snapshot `SaveState` remains only for local/demo compatibility and migration/recovery compatibility. -- [x] PR-031 Define and implement a reviewed multi-writer API HA design, or permanently keep the product scoped to single-writer controlled self-hosted deployments. -- [x] PR-032 Add direct provider-specific management API clients or narrow the product promise to bring-your-own-evidence integration. -- [e] PR-033 Add native PKCS#11/HSM module and slot handling. - Native HSM validation depends on operator hardware, drivers, credentials, and provider-specific test environments. -- [e] PR-034 Prove broad WORM/object-lock enforcement beyond configured bucket and sample-object checks. - Full proof depends on object-store creation mode, IAM, lifecycle policy, backups, and provider audit evidence. -- [x] PR-035 Add a minimal read-only package viewer or trust-package UI for release evidence, customer packages, and readiness reports. -- [x] PR-036 Add benchmark or capacity evidence for the supported single-writer profile. -- [e] PR-037 Validate public transparency provider semantics and availability. - Provider trust, timestamp semantics, and availability are external review items. - -### Final Positioning - -- [x] PR-038 Finish the production exit review before changing status beyond controlled self-hosted production candidate. -- [x] PR-044 Restore the strict production coverage gate to at least 80 percent when live PostgreSQL tests are configured. -- [e] PR-039 Claim broad production readiness, regulated production readiness, hosted SaaS readiness, legal compliance, certification, secure release, complete SBOM coverage, or authoritative scanner results. - These are intentionally outside the current product boundary and require external controls/review even if repository hardening improves. - -## Latest visible state inspected - -I inspected commit **`842fb053f303b2a78eb3118be6a4536715571215`**, commit message **`feat: add direct cloud kms signers`**. That is the latest head I could verify for `master` through the GitHub connector in this session, and the searchable commit record corroborates the SHA and message. - -I **could not see the exact commit timestamp for that head commit** from the accessible outputs. The immediately previous visible commit I found was `d55b955fce82384108cae55365096f7f52bf5b2b`, created **2026-05-31 11:25:37 +03:00**, so I will not invent a timestamp for `842fb0...`. - -| Item | Verified state | -|-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| Repository | `aatuh/evydence`, `https://github.com/aatuh/evydence` | -| Visibility | Public repository. ([GitHub][1]) | -| Default branch | `master`. ([GitHub][1]) | -| Latest inspected commit | `842fb053f303b2a78eb3118be6a4536715571215`, `feat: add direct cloud kms signers`. | -| Latest release | **No published GitHub releases visible.** ([GitHub][1]) | -| Tags | README/changelog mention a local `v0.1.0-rc.2` evidence package/tag, but public release publication is separate and I could not inspect the public tag list. | -| Primary languages | Mostly Go, with small Python, Makefile, Shell, TypeScript, Dockerfile portions. ([GitHub][1]) | -| License | AGPL-3.0-only. | -| Activity | Active, but extremely fresh. Recent commit history shows multiple production-hardening commits on 2026-05-31. | -| Project status | Public, active, maintainer-led, production-oriented, but explicitly **not broad production-ready**. | -| Could not inspect | Exact head commit date, public tags list, branch protection, required checks, GitHub private vulnerability settings, Dependabot/vulnerability-alert settings, actual CI pass/fail history for the head commit, and runtime behavior by executing tests. | - ---- - -# 1. What the project appears to be - -**Plain English:** Evydence is a self-hosted API service for collecting and organizing technical evidence around software releases: SBOMs, vulnerability scans, VEX, release bundles, build/source/deployment records, audit chains, control coverage, readiness reports, customer-facing security packages, and related compliance-readiness artifacts. - -The README communicates the core idea quickly: “a self-hosted, API-first evidence ledger for software release evidence” that supports compliance readiness by organizing/verifying technical evidence and showing gaps, assumptions, exceptions, and limitations. - -**Likely users:** platform security teams, AppSec teams, compliance-readiness teams, DevSecOps teams, security-conscious B2B SaaS vendors, and internal engineering teams that need auditable release evidence without handing all trust data to a SaaS GRC platform. - -**Category:** self-hosted release evidence ledger / software supply-chain evidence platform / compliance-readiness API. It is adjacent to SBOM/vulnerability management, GRC evidence automation, software supply-chain provenance, and customer trust-package tooling. - -**What it is not:** not a legal compliance engine, not a certification tool, not an authoritative vulnerability scanner, and not a secure-release guarantee. The README is unusually explicit about those non-claims. - -**Library, CLI, server, API, framework, infrastructure tool, or product?** It is mainly a **server/API product** with a CLI helper, worker process, deployment assets, and SDK wrappers. README lists `/v1` HTTP API, `cmd/evydence-api`, `cmd/evydence-worker`, `cmd/evydence`, Helm, Docker, CI examples, and SDK wrappers. - -**30-second README clarity:** Good, but dense. A technical reader gets the point quickly. A buyer does not. The README reads like a careful engineering status memo, not a product landing page. - ---- - -# 2. Production readiness - -## Evidence - -The repo has real production-readiness work, not just claims: - -* Ports-and-adapters structure is documented: `internal/domain`, `internal/app`, HTTP adapter, PostgreSQL adapter, object-store adapters, and `cmd/*` entrypoints. -* It has PostgreSQL durable state, migrations, tenant-scoped relational projections, object storage, persisted outbox jobs, worker processing, and S3/MinIO-compatible raw payload storage. -* The API enforces production startup checks: production requires PostgreSQL, non-default API-key pepper, production signing mode, no bootstrap-secret printing, and single-writer constraints. -* Production API startup can acquire a PostgreSQL advisory writer lease so a second writer fails closed. -* CI has a `Production Check` job using PostgreSQL and running `make production-check`. -* `make release-check` includes finalize, release acceptance, lint, gosec, govulncheck, race tests, live PostgreSQL checks, and PostgreSQL integration tests. -* `make production-check` requires a live PostgreSQL test URL, enforces coverage, runs migration compatibility, and does a release signing smoke test. -* The docs include production-readiness, release-candidate, configuration, operations, Kubernetes, observability, worker-outbox, release-validation, and API references. -* Deployment assets exist: Dockerfile, Compose dependencies, Helm chart, NetworkPolicy template, Prometheus rules, Grafana dashboard starter assets. - -## Brutal assessment - -This is **not vaporware**, and it is not a weekend toy. But it is also **not production-grade for serious broad adoption yet**. - -The biggest problem is architectural maturity. The core `Ledger` is still a huge in-process aggregate protected by a mutex and containing a very large number of maps for tenants, users, evidence, releases, SBOMs, VEX documents, decisions, reports, controls, packages, signatures, audit chains, and more. The persistence model also still exposes a massive `PersistedState` structure with many resource-family maps. - -The project knows this and says so. The architecture doc explicitly says that moving all canonical production writes to dependency-ordered relational repositories is still production hardening, not completed production maturity. The production-readiness doc says the broader production exit review remains incomplete and that canonical production persistence still needs hand-tuned relational repository paths for all resource families. - -The HA story is intentionally limited: one API writer replica. Workers may scale, but API writes are not multi-writer safe. That is acceptable for an internal controlled deployment, but it is a hard ceiling for broad production claims. - -Security posture is thoughtful but incomplete. Good: HMAC-hashed API keys, tenant scoping, explicit scopes, production rejection checks, safe metrics, private payload handling, gosec/govulncheck gates, signing gateways/KMS, and no overclaiming. Bad: no published release, no visible signed public artifacts, no dedicated security email/advisory portal, no visible Dependabot config, no visible Scorecard/SBOM/provenance workflow, no branch protection visibility, and no public CI pass evidence for the latest head commit. - -Deployment story exists but is not turnkey. The Dockerfile is basic but reasonable, uses a non-root user, and copies migrations. Compose only starts dependencies, not the full app stack. Helm is useful, but defaults include one API replica, empty required image tag, external secrets, and NetworkPolicy disabled by default. - -## Production-readiness score: **6/10** - -That is not an insult. A 6 here means: **credible controlled internal pilot**, not “ship it to unknown customers.” The repo has unusually serious validation gates and honest limitations. But no public release, single-writer architecture, incomplete production exit review, unfinished repository decomposition, missing public trust automation, and no visible adoption make it unfit for broad serious production. - ---- - -# 3. Feature completeness - -## What real-world use cases it already supports - -Evydence already supports several real workflows: - -* Create products, projects, releases, artifacts, immutable evidence, SBOMs, vulnerability scans, VEX documents, decisions, release bundles, audit entries, and readiness reports. -* Upload CycloneDX SBOMs and vulnerability scan evidence, then record vulnerability decisions and generate release-readiness output. -* Manage controls, control evidence, CRA-readiness, customer packages, redaction profiles, questionnaires, report templates, incident packages, and PDF package metadata. -* Record CI/source/deployment/collector evidence, build attestations, DSSE trust roots, source snapshots, deployments, and container images. -* Support integrity operations: release bundles, audit-chain verification, signing keys, signing operations, artifact signatures, Merkle batches, transparency checkpoints, retention policies, legal holds, and backup manifests. -* Use worker-owned parser side effects for replaying raw payloads from tenant-prefixed object storage and populating normalized fields after digest verification. - -## Missing or incomplete use cases - -Blockers: - -* **No public release artifacts.** A local `v0.1.0-rc.2` package is mentioned, but GitHub shows no published releases. ([GitHub][1]) -* **No broad production HA.** One API writer only. -* **Provider-specific management integrations are incomplete.** The repo explicitly says direct provider-specific management API clients and external group synchronization remain outside the implemented boundary. -* **Native PKCS#11/HSM handling is not implemented.** It remains gateway-backed because native modules/slots are deployment-specific. -* **Object-lock/WORM verification is limited.** S3/MinIO checks cover bucket defaults and optional sample object retention/legal hold, not full deployment-level WORM assurance. -* **No UI/trust center product experience.** There are APIs and package endpoints, but not a polished buyer-facing trust portal or admin console. - -Table-stakes features for this category that are still weak: - -* Published signed releases. -* Concrete installable container images with immutable tags/digests. -* Real-world demo with screenshots or video. -* Example integrations with GitHub/GitLab that produce a full evidence package. -* Clear upgrade guide and backward compatibility policy. -* Security advisory intake. -* Dependency automation. -* Benchmarks and capacity guidance. -* Multi-user operations UX. -* Production incident/runbook details beyond indexes and references. - -## Feature-completeness score: **7/10** - -This is feature-rich. It is not a toy. It is also dangerously broad: many features exist as API records and deterministic reports, but not all are deeply integrated with real provider ecosystems. Current classification: **useful production component for narrow, controlled internal use; not yet a productized system.** - ---- - -# 4. Security and open-source trust - -## Strong trust signals - -* AGPL-3.0 license is present. -* Commercial licensing terms are explicit and realistic. -* SECURITY.md exists and gives sensitive-data handling rules. -* CONTRIBUTING.md exists and tells contributors not to submit secrets, raw payloads, or provider credentials. -* Governance is explicit: maintainer-led, one named maintainer, final decision authority documented. -* Support expectations are documented, including no SLA unless agreed. -* CI/tooling includes lint, gosec, govulncheck, race tests, coverage threshold, OpenAPI drift checks, docs checks, deployment checks, and SDK checks. - -## Weak trust signals - -* **Security reporting through LinkedIn is not acceptable for serious open source.** SECURITY.md says to contact the maintainer through LinkedIn until a dedicated mailbox or advisory portal is published. That is better than nothing, but weak for a high-trust evidence system. -* No visible `CODE_OF_CONDUCT.md`. -* No visible Dependabot config. -* No visible OpenSSF Scorecard workflow. -* No visible SBOM/provenance workflow for the project’s own releases. -* No visible public signed release yet. -* Branch protection and required checks are not visible. -* Latest head commit had no workflow runs/statuses visible from the connector result I could inspect. -* The public repo has zero stars/forks/watchers at inspection time; stars are not quality, but zero adoption is a trust and market signal. ([GitHub][1]) - -## Security/open-source trust score: **6/10** - -The internal security thinking is much better than average. The public open-source trust surface is not. For a tool that asks buyers to trust it with compliance and release evidence, “message me on LinkedIn for security reports” and “no public release artifacts” are serious trust gaps. - ---- - -# 5. Marketability and positioning - -## Pain level - -The problem is real. B2B vendors increasingly need to answer: What changed in this release? What evidence proves it? What vulnerabilities were reviewed? What SBOM/VEX/build/deployment records exist? What can be safely shared with customers? Evydence targets that pain. - -## Target user clarity - -The target user is technically inferable but not buyer-obvious. The README says “software release evidence” and “compliance readiness,” but it does not immediately say: - -> “For security and platform teams at B2B software companies who need an auditable release evidence trail and customer-ready security package without buying a full SaaS GRC platform.” - -That should be the front-page positioning. - -## Category crowding - -This is in a crowded neighborhood: - -* Vanta and Drata sell broad compliance/trust automation with evidence collection, control monitoring, trust centers, questionnaires, and integrations. Vanta advertises compliance automation, streamlined audits, trust centers, questionnaire automation, and 400+ integrations. ([Vanta][2]) Drata advertises automated control mapping, evidence collection, monitoring, continuous compliance, trust centers, and questionnaire automation. ([Drata][3]) -* OWASP Dependency-Track is strong in SBOM ingestion, continuous SBOM analysis, vulnerability detection, policy evaluation, audit workflow, VEX, notifications, SSO, and API-first integration. ([Dependency Track][4]) -* DefectDojo has a large open-source vulnerability-management community and many integrations. ([defectdojo.org][5]) -* GUAC targets software supply-chain metadata graphs and SBOM/advisory relationship mapping. ([guac][6]) -* in-toto and SLSA cover supply-chain integrity/provenance standards rather than compliance evidence ledgers. ([in-toto][7]) ([SLSA][8]) - -## Differentiated pitch - -Evydence’s strongest angle is **not** “we do compliance.” That loses to Vanta/Drata/Secureframe immediately. - -The sharper angle is: - -> “A self-hosted release evidence ledger for software teams that need tamper-evident, API-first, customer-reviewable technical evidence across SBOMs, VEX, vulnerability decisions, release bundles, controls, audit chains, and offline/self-hosted environments.” - -That is narrower, more credible, and more differentiated. - -## Marketability score: **5/10** - -Interesting, but not yet highly marketable. The value proposition is buried under implementation status. The README is honest but not persuasive. There are no screenshots, no demo, no benchmark, no hosted option, no public release, no customer story, no “why this instead of Dependency-Track + Vanta + spreadsheets” section. - -The name **Evydence** is mixed. It is memorable, but the misspelling may hurt searchability and professionalism in B2B procurement. It is not fatal, but it needs a strong tagline. - ---- - -# 6. Differentiation - -## Direct alternatives - -There are not many exact “self-hosted release evidence ledger” direct alternatives, but buyers will compare it against: - -* **Dependency-Track** for SBOM, VEX, vulnerability, policy, and supply-chain risk workflows. It is mature, open source, API-first, and has broad ecosystem support. ([Dependency Track][4]) -* **DefectDojo** for vulnerability aggregation, AppSec workflows, integrations, and security program reporting. ([defectdojo.org][5]) -* **Vanta / Drata / Secureframe** for compliance automation, trust center, audit evidence, questionnaires, and customer assurance. ([Vanta][2]) ([Drata][3]) -* **GUAC** for software supply-chain metadata graphing and SBOM/advisory relationships. ([guac][6]) - -## Indirect alternatives - -* GitHub Advanced Security, GitLab Ultimate, Snyk, Wiz, JFrog Xray, Sonatype Lifecycle. -* in-toto/SLSA/Sigstore/Rekor-style provenance/signing/transparency stacks. -* Internal spreadsheets, Jira tickets, Confluence pages, object storage, and a custom Postgres database. - -## Do-nothing/build-in-house alternative - -Many security teams will build a crude internal version: CI uploads JSON to S3, a Postgres table stores release metadata, a script generates a customer PDF, and humans glue together SBOMs/scans/screenshots. That is ugly but cheap. Evydence must prove it saves enough pain to beat this. - -## Meaningful differentiation - -* Self-hosted, API-first, release-evidence-specific. -* Strong conservative claim language. -* Tamper-evident audit-chain and release-bundle orientation. -* Broad evidence types: SBOM, VEX, scans, source/deploy, controls, customer packages, retention, transparency. -* Air-gapped/offline packaging story. -* AGPL + commercial license path. -* Designed for technical evidence organization, not generic compliance dashboards. - -## Not differentiated enough yet - -* It lacks a polished buyer demo. -* It lacks public releases and adoption. -* It lacks deep provider integrations. -* It lacks a UI/trust portal. -* It lacks obvious “why not Dependency-Track + Drata?” positioning. -* It lacks operational proof: production case study, benchmark, upgrade story, and public signed artifacts. - ---- - -# 7. Repository quality checklist - -| Area | Status | Evidence | Severity | Recommended fix | -|-----------------------|---------:|------------------------------------------------------------------------------------------------------------------|---------:|---------------------------------------------------------------------------------------------------------| -| README | Adequate | Clear technical definition and honest non-claims, but reads like a status memo. | Medium | Rewrite top section around user, pain, demo, and narrow differentiation. | -| Quickstart | Adequate | Local API flow exists, but it is explicitly in-process and data is lost on exit. | Medium | Add “durable quickstart” with Postgres + object store + worker. | -| Examples | Adequate | GitHub Actions, GitLab CI, upload-build, SDK, source snapshot examples exist. | Medium | Add one end-to-end demo repo producing a full evidence package. | -| Tests | Strong | Many unit/integration tests exist; tenant isolation, parser jobs, PostgreSQL migration compatibility are tested. | Medium | Publish CI results and coverage reports; add black-box e2e tests against deployed API. | -| CI | Adequate | CI workflow runs `make production-check` with PostgreSQL service. | High | Expose passing status badges and verify required checks/branch protection. | -| Releases | Missing | GitHub shows no published releases. ([GitHub][1]) | High | Publish `v0.1.0-rc.2` or next RC with signed artifacts, checksums, release notes, image digest. | -| Docs | Strong | Docs portal covers start, how-to, reference, metadata, workflows, architecture, trust model. | Low | Reduce repetition and add diagrams/screenshots. | -| Docker/deployment | Adequate | Dockerfile, Compose dependencies, Helm chart, probes, secrets, security contexts exist. | Medium | Add full compose app stack; publish images; default NetworkPolicy enabled for production values. | -| Security policy | Weak | SECURITY.md exists, but private reporting currently routes through LinkedIn. | High | Add `security@...`, GitHub private vulnerability reporting, advisory process, supported versions table. | -| License | Strong | AGPL-3.0-only present. | Low | Add SPDX headers or REUSE compliance if desired. | -| Commercial licensing | Adequate | Commercial exceptions and paid options documented. | Low | Add contact form/email, not only LinkedIn. | -| Contribution docs | Adequate | CONTRIBUTING exists, but CLA/selective model may discourage contributors. | Medium | Add issue/PR templates and a lightweight contributor path for docs/tests. | -| Governance | Adequate | Maintainer-led, one named maintainer. | Medium | Add escalation, release authority, security response roles, succession note. | -| Issue templates | Missing | I did not find `.github/ISSUE_TEMPLATE` during repo inspection. | Low | Add bug, feature, security-non-sensitive, production-support templates. | -| Code of conduct | Missing | `CODE_OF_CONDUCT.md` was not found. | Low | Add one if community contribution is desired. | -| Changelog | Adequate | Changelog exists and records `v0.1.0-rc.2` as local/public-release notes. | Medium | Align changelog with actual public releases/tags. | -| API documentation | Strong | API docs describe `/v1`, idempotency, Problem Details, auth/scopes, endpoint catalog. | Low | Add generated examples and client snippets per core workflow. | -| Configuration docs | Strong | Runtime variables and production rejection checks are documented. | Low | Add “minimal production env” and “bad config examples.” | -| Operational docs | Adequate | Operations index exists; observability docs exist. | Medium | Add incident runbook, backup/restore runbook, upgrade runbook, capacity guidance. | -| Dependency automation | Missing | I did not find Dependabot/Renovate config. | Medium | Add Dependabot or Renovate for Go, Actions, Docker, Helm. | -| OpenSSF-style posture | Weak | Security files and gosec/govulncheck exist, but no visible Scorecard, SBOM/provenance, or public signed release. | High | Add Scorecard, SLSA/provenance, SBOM for releases, artifact signatures, branch protection. | - ---- - -# 8. Final verdict - -## Verdict: **Promising but not production-ready** - -This project is **worth continuing**, but it should be positioned as a **controlled self-hosted production candidate / internal pilot platform**, not a broadly production-ready product. - -Direct answers: - -* **Is it mature and high-grade enough for production for most uses?** No. The repo itself says broad production, regulated production, and hosted SaaS production remain out of scope until additional controls and exit review pass. -* **Is it highly marketable and interesting?** Interesting, yes. Highly marketable now, no. It lacks public releases, demos, screenshots, adoption, crisp positioning, and buyer proof. -* **Is it useful in real-world production, meaning it has enough features?** Yes, for narrow controlled internal use where the operator accepts single-writer API, self-hosting burden, and manual provider review. Not for broad customer-facing production. -* **What should be done next?** Stop adding breadth. Publish a real release candidate, harden the trust surface, ship one killer end-to-end demo, and finish the production exit checklist. - ---- - -# 9. Highest-leverage next steps - -## Next 1-2 days - -**1. Publish a real public release candidate.** -Why: no serious buyer trusts “local release evidence package generated under ignored `dist/`.” -Change: create a public GitHub release for the next RC with binaries, checksums, signed manifest, release notes, OpenAPI checksum, migration checksums, and image digest. Use the existing release-artifacts workflow and release-candidate checklist. -Improves: trust, installability, procurement confidence. - -**2. Add a security reporting channel that is not LinkedIn.** -Why: LinkedIn private-channel negotiation is amateur-hour for a high-trust security project. -Change: update `SECURITY.md` with `security@...`, GitHub private vulnerability reporting, supported versions, expected response windows, and advisory publication process. -Improves: security trust and open-source credibility. - -**3. Add README badges and public proof.** -Why: claims need visible machine proof. -Change: add CI status, release status, license, Go version, coverage if available, and latest release badge. -Improves: quick trust assessment. - -**4. Add issue templates.** -Why: SUPPORT.md asks for structured bug reports, but the repo does not appear to provide templates. -Change: add `.github/ISSUE_TEMPLATE/bug_report.yml`, `feature_request.yml`, `docs.yml`, and a “security: do not post secrets” placeholder. -Improves: maintainer efficiency and community hygiene. - -**5. Add a blunt “Current limitations” box near the top of README.** -Why: the limitations are present but buried. -Change: summarize single-writer API, no broad production, no provider management API sync, no native PKCS#11, no legal compliance conclusion. -Improves: buyer trust because it prevents overclaiming. - -## Next 1-2 weeks - -**1. Build one complete demo path.** -Why: current examples are useful but fragmented. -Change: create `examples/end-to-end-release-evidence/` with GitHub Actions or GitLab CI producing build metadata, SBOM, vulnerability scan, VEX decision, release bundle, readiness report, and customer package. Include a short video/GIF or screenshots. -Improves: marketability and adoption. - -**2. Add full Docker Compose app stack.** -Why: Compose currently runs dependencies, not the app. -Change: add `compose.production-like.yml` with API, worker, Postgres, MinIO, migrations, secrets via env file, and health checks. -Improves: evaluator success rate. - -**3. Add dependency automation and OpenSSF basics.** -Why: security buyers expect this. -Change: add Dependabot/Renovate, OpenSSF Scorecard workflow, pinned GitHub Actions where feasible, and release SBOM/provenance generation. -Improves: open-source trust. - -**4. Add backup/restore and upgrade runbooks.** -Why: evidence ledger value dies if restore is fuzzy. -Change: add `docs/runbooks/backup-restore.md`, `docs/runbooks/upgrade.md`, and `docs/runbooks/incident-response.md`. Tie them to existing backup manifest and release validation docs. -Improves: production readiness. - -**5. Publish API client examples.** -Why: API-first products need low-friction adoption. -Change: add examples for Go, TypeScript, Python SDK wrappers: create release, upload SBOM, upload scan, record decision, fetch readiness. -Improves: developer experience. - -**6. Add capacity and failure-mode docs.** -Why: single-writer is okay only if users understand throughput and blast radius. -Change: document tested object sizes, worker batch behavior, outbox retry behavior, DB connection pool expectations, payload limits, and failure/retry semantics. -Improves: operational confidence. - -## Next 1-2 months - -**1. Finish splitting the giant ledger aggregate.** -Why: this is the biggest production blocker. -Change: move from massive aggregate/mutex/map persistence toward focused service/repository boundaries for core write paths. Keep relational reconstruction, but make per-resource transactions canonical. -Improves: concurrency, maintainability, testability, and HA path. - -**2. Decide the HA story.** -Why: “one API writer” caps serious adoption. -Change: either keep explicit “small internal production only” forever, or implement reviewed multi-writer concurrency with database constraints, row-level transactions, optimistic locking, idempotency, and conflict tests. -Improves: production scalability. - -**3. Add real provider integrations or narrow the promise.** -Why: buyers will expect GitHub/GitLab/Jira/Slack/IdP integrations, not just records. -Change: either build direct provider collectors/validators or explicitly position Evydence as “bring-your-own evidence API.” -Improves: market clarity. - -**4. Build a minimal UI or trust package viewer.** -Why: API-only is fine for engineers, bad for buyers and auditors. -Change: add a simple read-only package viewer for release evidence, customer security packages, and readiness reports. -Improves: B2B usability. - -**5. Add enterprise trust artifacts.** -Why: ironic but necessary for a trust tool. -Change: project SBOM, vulnerability disclosure process, release provenance, signed container images, immutable image tags, public security advisories, and possibly a public trust page. -Improves: buyer confidence. - ---- - -# 10. README/product-page rewrite advice - -## Sharper one-sentence pitch - -> Evydence is a self-hosted release evidence ledger that helps software teams collect, verify, and share tamper-evident technical evidence for each release. - -## Target user - -Security, platform, AppSec, and compliance-readiness teams at B2B software companies that need customer-reviewable release evidence without relying entirely on a SaaS GRC platform. - -## Core use case - -“Before shipping a release, collect SBOM, vulnerability scan, VEX decisions, build/source/deployment evidence, controls, exceptions, release bundle, and customer-safe package. Then show readiness gaps and limitations.” - -## Best demo to show first - -A single end-to-end flow: - -1. CI builds artifact. -2. CI uploads SBOM and scan. -3. Security records VEX decision for one finding. -4. Evydence creates release bundle. -5. Evydence generates readiness report. -6. Evydence exports customer package. - -## Proof points to add - -* Published signed release. -* Passing CI badge. -* Coverage badge. -* Architecture diagram. -* 5-minute demo. -* Example generated customer package. -* Example readiness report. -* Example audit-chain verification. -* “Why not Dependency-Track / Vanta / build in-house?” section. - -## Remove or de-emphasize - -Do not lead with every feature. The current README lists too much too early. Move the huge capability inventory lower. Lead with pain, demo, install, and proof. Keep the non-claims, but compress them into a clear “Boundaries” section instead of letting the README feel defensive from line one. - -Bottom line: **continue it, but stop broadening it until it earns trust.** The project has enough substance to be worth hardening. It does not yet have enough public proof, operational maturity, or product clarity to be sold as production-ready. - -[1]: https://github.com/aatuh/evydence?utm_source=chatgpt.com "GitHub - aatuh/evydence: Self-hosted API-first evidence ledger for software release compliance readiness · GitHub" -[2]: https://www.vanta.com/ "https://www.vanta.com/" -[3]: https://drata.com/ "https://drata.com/" -[4]: https://dependencytrack.org/ "https://dependencytrack.org/" -[5]: https://www.defectdojo.org/ "https://www.defectdojo.org/" -[6]: https://guac.sh/ "https://guac.sh/" -[7]: https://in-toto.io/ "https://in-toto.io/" -[8]: https://slsa.dev/ "https://slsa.dev/" diff --git a/.production_readiness_v2.md b/.production_readiness_v2.md deleted file mode 100644 index ec080c3..0000000 --- a/.production_readiness_v2.md +++ /dev/null @@ -1,657 +0,0 @@ -# Production Readiness Public Repo Audit V2 - -## 2026-05-31 Reanalysis And Remediation Tracking - -Status legend: - -- `[ ]` applicable repository-local work that remains incomplete. -- `[x]` applicable repository-local work completed with current repository evidence. -- `[e]` external, account-level, provider-level, operator-environment, or adoption-dependent work that cannot be completed by repository files alone. - -Current state rechecked after the original audit: - -- Public `origin/master` includes remediation through commit `929c525a116346cd17b027c96b0d9f568a8fb0a8`: trust-surface documentation, examples, production-like Compose assets, Scorecard workflow, Dependabot config, issue/PR templates, product-code audit records, package-viewer demo, benchmark gate, black-box production-readiness check, and helper/outbox decomposition that the original audit could not see publicly. -- Local checkout is clean at `master...origin/master` after the remediation commits were pushed. -- Public GitHub community profile health increased to `100`; GitHub now sees `CODE_OF_CONDUCT.md`, `CONTRIBUTING.md`, `LICENSE`, `README.md`, `.github/ISSUE_TEMPLATE.md`, and `.github/pull_request_template.md`. -- Public GitHub still reports no releases and no pushed tags, and `master` branch protection is still disabled. -- GitHub private vulnerability reporting, secret scanning, Dependabot alert settings, release signing secrets, branch protection rules, and required checks remain account/operator settings that repository files can document but cannot prove. - -Repository-local remediation items from this audit: - -- [x] Commit and push the trust-surface improvements that were local-only in the original audit: `README.md`, `SECURITY.md`, `.github/dependabot.yml`, `.github/workflows/scorecard.yml`, `.github/ISSUE_TEMPLATE/*`, `CODE_OF_CONDUCT.md`, `compose.production-like.yml`, examples, runbooks, and production-readiness docs are now on `origin/master`. -- [x] Add and commit a visible end-to-end evidence example under `examples/end-to-end-release-evidence/` with sample readiness, package manifest, audit-chain verification, and a runnable local API script. -- [x] Keep conservative product positioning in README and docs: controlled self-hosted production candidate, single API writer, operator review required, and no legal compliance, certification, complete-SBOM, scanner-authority, or secure-release claims. -- [x] Keep local production gates in repository commands: `make production-check`, `make release-candidate-check`, `make release-acceptance`, OpenAPI precision checks, migration compatibility checks, coverage threshold, and signing smoke tests are present. -- [x] Preserve public trust metadata: AGPL license, commercial-license note, governance, contribution policy, security policy, support policy, trademark guidance, release evidence notes, changelog, code of conduct, issue forms, Dependabot, Scorecard workflow, CI, and release artifact workflow. -- [x] Document release-candidate evidence requirements: signed manifest, checksums, OpenAPI checksum, migration checksum, coverage output, production-check summary, release notes, and limitations. -- [x] Document the single-writer HA/concurrency stance and keep worker scaling bounded by PostgreSQL outbox locking. -- [x] Add fallback GitHub community templates for issue and pull request intake so public profile and reviewer workflows do not depend only on issue forms. -- [x] Add a repository-owned demo fixture check so sample release-evidence outputs and the local demo script are validated by the fast gate. -- [x] Add a full black-box demo check that starts API and worker against a disposable PostgreSQL schema, bootstraps a tenant/API key, runs the release-evidence demo, restarts the API, and verifies persisted readiness/package/audit outputs. -- [x] Continue decomposing the largest application and PostgreSQL adapter files by resource family without changing public API behavior; helper/security logic moved out of `internal/app/ledger.go`, and PostgreSQL outbox plus SQL helper code moved out of `internal/adapters/postgres/store.go`. -- [x] Add public benchmark runs and capacity envelopes for the supported single-writer profile. -- [x] Add a small public package-viewer walkthrough or hosted static demo artifact that can be evaluated without operating a full Evydence stack. - -External or operator-dependent items from this audit: - -- [e] Publish a public GitHub release candidate with signed artifacts, checksums, release evidence, and image digests. Repository scripts and workflow support this, but pushing a release/tag and configuring signing secrets are operator actions. -- [e] Push release-candidate tags publicly. The local repository can create tags; publication is an operator action and should follow the release-candidate gate. -- [e] Enable branch protection and required checks for `master`; this is a GitHub repository setting. -- [e] Enable or verify GitHub private vulnerability reporting; this is a GitHub repository security setting. -- [e] Enable or verify GitHub secret scanning, push protection, Dependabot alerts, and code scanning; these are GitHub/account settings. -- [e] Publish container images with immutable registry digests; this requires registry credentials and release publication. -- [e] Prove native HSM/PKCS#11 custody, broad WORM/object-lock enforcement, real transparency-provider semantics, and provider-specific SSO/group synchronization in a deployed operator environment. -- [e] Prove real adoption, support process maturity, customer case studies, or third-party validation; these require external users or reviewers. -- [e] Seek and publish third-party review or early-user feedback tied to a concrete release candidate; repository files can prepare the process, but the review or feedback itself is external. -- [e] Claim regulated production or broad production readiness; this requires deployment-specific review and evidence beyond repository files. - -## Original Audit Snapshot - -The remaining sections preserve the original audit narrative. They should be -read with the remediation tracking above as the current status overlay. - -## Latest visible state inspected - -Repository: `aatuh/evydence`, `https://github.com/aatuh/evydence`. - -Audit scope: latest public GitHub state plus the current local checkout at -`/home/aatu/projects/evydence`. These are not the same state. The public default -branch is clean at commit `842fb053f303b2a78eb3118be6a4536715571215`; the local -checkout is dirty and contains substantial uncommitted production-readiness work. - -Default branch: `master`. - -Latest public commit verified through `gh`: - -- SHA: `842fb053f303b2a78eb3118be6a4536715571215` -- Message: `feat: add direct cloud kms signers` -- Author date: `2026-05-31T08:36:23Z` -- Commit date: `2026-05-31T08:37:01Z` -- Local equivalent: `2026-05-31 11:37:01 +0300` - -Latest public release/tag: none visible. `gh release list` returned no releases, -and `gh api repos/aatuh/evydence/tags` returned an empty list. - -Primary language and package manifests: Go module -`github.com/aatuh/evydence` with `go.mod` and `go.sum`; small supporting -Python, shell, TypeScript, Docker, Helm, and YAML assets. - -License: AGPL-3.0, visible publicly through GitHub license metadata and local -`LICENSE`. The repo documents `AGPL-3.0-only` as the intended SPDX expression. - -Public visibility and activity: public, not archived, pushed on -`2026-05-31T08:41:59Z`, zero stars, zero forks, zero watchers at inspection -time. The latest public CI run for `842fb053f303b2a78eb3118be6a4536715571215` -completed successfully. - -Public repository metadata verified: - -- Description: `Self-hosted API-first evidence ledger for software release compliance readiness`. -- Topics include `api-first`, `audit-log`, `evidence-ledger`, `openapi`, - `release-evidence`, `sbom`, `self-hosted`, `supply-chain-security`, `vex`, - `vulnerability-management`, and `compliance-readiness`. -- GitHub community profile health: `71`. -- Public community profile showed README, LICENSE, CONTRIBUTING, and docs; it - did not show a public code of conduct, issue templates, or PR template. -- Public branch protection for `master`: disabled. The branch API reported - `protected: false`; the protection endpoint returned `Branch not protected`. -- Public issues and pull requests: none visible through `gh issue list` and - `gh pr list`. - -Local checkout state: - -- Branch: `master...origin/master`. -- Dirty files include README, Makefile, Dockerfile, SECURITY.md, docs, release - scripts, and several app files. -- Untracked local files include issue templates, Dependabot config, Scorecard - workflow, CODE_OF_CONDUCT.md, production-like Compose, examples, runbooks, - benchmark docs, package viewer files, and service-split files. -- Local checks run for this audit: - - `make fast-check`: passed. - - `set -a; . ./.test.env.example; set +a; make production-check`: passed. - - `set -a; . ./.test.env.example; set +a; make release-candidate-check TAG=v0.1.0-rc.4`: failed because the worktree is dirty. - -What could not be inspected: - -- GitHub private vulnerability reporting setting. -- GitHub secret scanning, push protection, Dependabot alerts, code scanning - settings, and required status-check settings beyond the visible fact that - `master` is unprotected. -- Contents of GitHub Actions artifacts from the latest public CI run. -- Release signing secret configuration for `.github/workflows/release-artifacts.yml`. -- Any real deployed Evydence instance, live KMS/HSM, live S3 object lock policy, - external transparency provider, provider-specific SSO/group sync, or SaaS - operations environment. - -Confidence impact: medium confidence. The local and public states were verified, -and local gates were run. Confidence is not high because the strongest local -work is uncommitted, public releases/tags are absent, and key GitHub security -settings are external or not visible. - -## What the project appears to be - -Evydence is a self-hosted API service and CLI/worker toolchain for collecting, -linking, verifying, and sharing technical release evidence. It targets release -evidence rather than generic compliance dashboards: products, projects, -releases, artifacts, SBOMs, vulnerability scans, VEX, vulnerability decisions, -exceptions, build provenance, source/deployment evidence, controls, release -bundles, customer packages, audit chains, and readiness reports. - -Likely users are security engineering, AppSec, platform, DevSecOps, and -compliance-readiness teams at B2B software companies that need auditable, -customer-reviewable release evidence while keeping the evidence ledger -self-hosted. - -Category: release evidence ledger, software supply-chain evidence platform, -technical compliance-readiness API, and customer security-package tooling. -Adjacent categories include SBOM/vulnerability management, SaaS GRC platforms, -trust centers, in-toto/SLSA provenance tooling, and internal security-evidence -datastores. - -The public committed README communicates the category within about 30 seconds -for a technical reader, but not for a skeptical buyer. It explains that Evydence -is a self-hosted API-first evidence ledger and explicitly avoids legal -compliance, certification, complete-SBOM, scanner-authority, and secure-release -claims. The local dirty README is sharper: it adds badges, a target-user -paragraph, current limitations, a fastest proof path, and "why not existing -tools" positioning. That local version is better, but it is not yet public. - -Product shape: server/API product with CLI, worker, OpenAPI contract, SDK -wrappers, PostgreSQL/object-store runtime, migrations, Docker/Compose/Helm -deployment assets, CI examples, and documentation. It is not just a library. - -## Production readiness - -Evidence supporting serious use: - -- Public CI exists and the latest public `Production Check` workflow run for - `842fb053f303b2a78eb3118be6a4536715571215` passed. -- Local `make production-check` passed during this audit. That gate ran - `release-check`, coverage threshold, live PostgreSQL integration, - migration compatibility, and a release signing smoke test. -- Local coverage gate passed at `80.3%`, above the required `80.0%`. -- Local `make fast-check` passed, including unit tests, OpenAPI check, - OpenAPI precision check, docs check, deployment check, and SDK check. -- The API contract is large and concrete: the route matrix contains 166 precise - operations and zero broad operations in the local check. -- The repo has Go services under `cmd/`, domain/app/adapters under `internal/`, - PostgreSQL migrations, OpenAPI, object-store adapters, signing adapters, worker - outbox docs, release scripts, Dockerfile, Helm chart, and operational docs. -- Production startup rejects unsafe defaults: production requires PostgreSQL, - non-default API-key pepper, supported signing key mode, no bootstrap-secret - printing, single API writer mode, and one declared API writer replica. -- PostgreSQL production mode defaults to relational-only load and disables - compatibility snapshot writes when configured that way. -- Worker jobs use PostgreSQL row locking and safe retry/terminal status handling. -- Docs cover production readiness, release validation, configuration, - Kubernetes, observability, worker outbox, backup/restore, upgrade, incident - response, and capacity/failure modes in the local dirty tree. - -Brutal assessment: - -Evydence is now credible as a controlled self-hosted candidate in a way the -first audit could not prove. The local checkout compiles, passes a meaningful -production gate, enforces an 80% coverage threshold, and has a serious release -evidence pipeline. - -It is still not broadly production-ready. - -The public repository has no release tag and no release artifact. That is a -hard adoption blocker for a public infrastructure/security project. A local -signed `v0.1.0-rc.3` package is mentioned in the dirty README and changelog, but -the public GitHub release/tag surface proves none of it to an outside user. - -The architecture remains a production-maturity risk. The local service split has -improved boundaries, but `internal/app/ledger.go` is still about 2,077 lines, -`internal/app/state.go` still exposes a large `PersistedState`, and -`internal/adapters/postgres/store.go` is about 5,292 lines. That does not make -the system unusable, but it means most production confidence still comes from -tests and gates rather than a simple, obviously decomposed repository model. - -The HA stance is honest and limited: one API writer replica. Workers may scale, -but API writes are intentionally not multi-writer. That is acceptable for -controlled internal deployments, not for broad production claims. - -Some high-trust integrations are still profile-dependent: native PKCS#11/HSM, -direct provider-specific management API clients and external group sync, broad -object-lock/WORM proof, live transparency-provider semantics, and operator -backup/restore evidence. The docs state these limitations instead of hiding -them, which is good, but they remain real constraints. - -Production readiness score: 6.5/10. - -Classification: controlled internal pilot / controlled self-hosted production -candidate, not broadly production-ready. - -## Feature completeness - -Supported end-to-end production-relevant use cases: - -- Tenant-scoped API-key bootstrap, authentication, scopes, and idempotent API - writes. -- Product/project/release/artifact creation. -- Evidence ingestion and lifecycle behavior for immutable or append-only - evidence records. -- SBOM, vulnerability scan, OpenAPI contract, VEX, vulnerability decisions, - exceptions, readiness reports, control coverage, CRA-readiness reports, and - release bundles. -- Build provenance, collectors, GitHub Actions metadata capture, DSSE/in-toto - structural attestation parsing, source/deployment/incident records, packages, - report templates, retention records, backup manifests, and verification - records. -- PostgreSQL durable runtime, filesystem and S3-compatible object stores, - worker outbox, migrations, Helm, Dockerfile, CI, release scripts, and SDK - wrappers. -- Local production evidence workflow: `make production-check` produces - release-check summary and a signed manifest smoke test. - -Important missing or shallow use cases: - -- No public installable release, signed public artifacts, image digests, or - published release notes. -- No public end-to-end demo in the committed tree. The local checkout has - untracked `examples/end-to-end-release-evidence/`, but public GitHub does not. -- No polished admin UI or customer trust portal. The local checkout has a - package viewer under `site/`, but it is untracked and not a full product UI. -- Native PKCS#11/HSM module support remains external/gateway-backed. -- Full object-lock/WORM proof remains deployment/provider-specific. -- Direct provider-specific management API clients and external group sync are - not complete. -- Multi-writer API HA is intentionally unsupported. -- No real adoption proof, customer case study, public benchmark run, or public - third-party audit. - -Table-stakes features for this category: - -- Public signed releases and checksums. -- Repeatable install path with immutable images/tags. -- Security reporting channel and visible security settings. -- Backup/restore and upgrade runbooks. -- Real CI evidence and coverage. -- A fast demo that proves time-to-value without maintainer narration. -- Clear limits on compliance claims. - -Evydence now has many table stakes locally, but not all publicly. Public release -integrity and demo proof remain the biggest gaps. - -Feature completeness score: 7.5/10. - -Maturity classification: productizable system for a narrow controlled -self-hosted profile; not yet a complete public production product. - -## Security and open-source trust - -Strong signals: - -- AGPL license, commercial licensing, governance, contribution, support, - trademark, security, and release-evidence metadata exist in the committed - public tree. -- Public CI latest run is green and runs `make production-check` with live - PostgreSQL. -- Local production gate includes lint, gosec, govulncheck, race tests, - migration compatibility, coverage threshold, PostgreSQL integration, and - release signing smoke test. -- Local `gosec` reported `0 issues`; `govulncheck` reported no called - vulnerabilities. -- API keys, SSO sessions, portal tokens, and collector secrets are designed - around one-time secret display and hash storage rather than raw secret - persistence. -- Docs repeatedly forbid public leakage of raw evidence payloads, bearer tokens, - private keys, provider credentials, database URLs, and customer data. -- Product language avoids claims of legal compliance, certification, complete - SBOMs, authoritative scanner output, and secure releases. -- Local dirty tree adds stronger security intake language, CODE_OF_CONDUCT, - issue templates, Dependabot config, and Scorecard workflow. - -Weak signals: - -- Public `master` branch protection is off. -- No public tags or releases exist. -- The public security policy at `HEAD` still routes first security contact - through LinkedIn until a dedicated channel or advisory portal exists. The - local dirty `SECURITY.md` improves this, but it is not public. -- GitHub private vulnerability reporting, secret scanning, push protection, - Dependabot alerts, and code scanning settings could not be verified. -- Public GitHub community profile did not show a code of conduct or issue - templates. The local dirty tree has them, but they are uncommitted. -- No public release SBOM/provenance artifacts exist because no public release - exists. -- Public adoption is zero visible stars/forks/watchers. Stars are not quality, - but zero adoption increases buyer uncertainty. - -Security and open-source trust score: 6/10. - -The internal security engineering signals are materially better than the public -trust surface. For a high-trust evidence ledger, the public trust surface must -catch up before serious adopters will rely on it. - -## Marketability and positioning - -The pain is real. Security and platform teams at B2B vendors regularly need to -answer release-evidence questions: what changed, what SBOM applies, which -vulnerabilities were reviewed, which exceptions were approved, what evidence is -safe to share with a customer, and what limitations remain. - -The public README is honest and technically clear, but it is still too much like -an implementation inventory. The local dirty README is significantly better: -it names the target user, gives a fastest proof path, adds badges, lists current -limitations near the top, and explains "why not Dependency-Track, Vanta/Drata, -or build in-house." That should be committed because it materially improves -marketability. - -Category crowding is real: - -- OWASP Dependency-Track is an API-first SBOM and software supply-chain risk - platform with SBOM, VEX, vulnerability intelligence, policy, and audit - workflows. -- DefectDojo is a mature open-source vulnerability-management and DevSecOps - platform with scan imports, deduplication, dashboards, API, reporting, and - many integrations. -- Vanta and Drata occupy the broader compliance/trust-management space with - evidence collection, continuous monitoring, trust centers, questionnaire - automation, and integrations. -- GUAC, in-toto, SLSA, Sigstore, and related tools address supply-chain - metadata, provenance, signatures, and verification from different angles. - -Evydence has a plausible niche: self-hosted, release-centered, API-first, -tamper-evident evidence records and customer-reviewable packages, with explicit -non-claim language. That is more specific than generic GRC and more release -review-oriented than SBOM-only or vulnerability-only tools. - -Marketability weaknesses: - -- No public release means no serious "try this version" path. -- No public demo asset or screenshots in committed GitHub state. -- No adoption proof or third-party validation. -- No hosted option, marketplace integration, or commercial contact funnel beyond - docs. -- The product is broad enough that buyers may doubt depth until a demo proves it. -- The name is memorable but the misspelling can hurt procurement/search trust - unless the tagline is strong. - -Marketability and positioning score: 5.5/10. - -It is interesting, but not yet easy to adopt or buy. - -## Differentiation - -Direct alternatives: - -- OWASP Dependency-Track for SBOM, VEX, vulnerability intelligence, policy, and - audit workflows. -- DefectDojo for vulnerability aggregation, AppSec workflow, finding - deduplication, reporting, and security-tool integrations. -- Vanta, Drata, Secureframe, and similar platforms for compliance automation, - evidence collection, trust centers, questionnaires, and broad GRC workflows. -- GUAC for graph-based software supply-chain metadata relationships. - -Indirect alternatives: - -- GitHub Advanced Security, GitLab Ultimate, Snyk, Wiz, JFrog Xray, Sonatype, - and other security platforms. -- in-toto, SLSA, Sigstore, Rekor, Cosign, and provenance/signature stacks. -- Internal evidence systems built from CI jobs, object storage, PostgreSQL, - spreadsheets, Jira, Confluence, and custom report scripts. - -Do-nothing/build-in-house alternative: - -Many teams will keep using CI artifacts, object storage, a few tables, GRC -screenshots, and manual release-review documents. That is brittle but cheap. -Evydence has to prove that its audit chains, release bundles, tenant-scoped API, -reports, and package exports reduce enough pain to justify operating another -self-hosted service. - -Meaningful differentiation: - -- Release-centered evidence ledger rather than generic compliance database. -- Self-hosted, API-first, OpenAPI-contracted surface. -- Tamper-evident audit-chain and release-bundle orientation. -- Broad evidence model across SBOM, VEX, vulnerability decisions, builds, - source, deployments, incidents, controls, packages, retention, and reports. -- Strong non-claim language, which is unusually important in compliance-adjacent - tooling. -- Air-gapped/offline and customer-package direction. - -Weak differentiation: - -- Public proof is missing: no release, no demo, no public evidence package. -- Deep integrations are still limited compared with mature commercial platforms. -- UI/trust-center experience is not productized. -- The broad feature surface may look shallow until a focused demo proves the - release evidence path end to end. - -Differentiation score: 6.5/10. - -## Repository quality checklist - -| Area | Status | Evidence | Severity | Recommended fix | -|------|--------|----------|----------|-----------------| -| README | Adequate | Public README explains purpose and non-claims; local dirty README has stronger buyer positioning, badges, proof path, limitations, and differentiation. | Medium | Commit the improved README, keep limitations near the top, and add a direct install/demo path once a release exists. | -| Quickstart | Adequate | Public docs include `docs/tutorials/getting-started.md`; local checks passed docs validation. | Medium | Add one command/script that runs a durable demo against API, worker, PostgreSQL, and object storage. | -| Examples/demo | Weak | Public committed tree has docs examples but no public `examples/` directory; local dirty tree has SDK and end-to-end examples. | High | Commit executable examples and include sample readiness/package/audit outputs. | -| Tests | Strong | Local `make fast-check` and `make production-check` passed; latest public CI production check passed; local coverage total is `80.3%`. | Medium | Keep coverage above threshold and add black-box API/e2e tests for the primary release-evidence flow. | -| CI | Adequate | Public CI exists and latest run is green; it provisions PostgreSQL and runs `make production-check`. | Medium | Add required branch protection and publish release evidence artifacts in a visible release workflow. | -| Releases/provenance | Weak | Release workflow and packaging scripts exist, but public GitHub has no tags/releases; local release-candidate check fails while worktree is dirty. | Blocker | Clean/commit the worktree, run release-candidate packaging, push an annotated RC tag, and publish signed draft release artifacts. | -| Docs/API/config/ops | Strong | Docs include API, OpenAPI matrix, configuration, operations, Kubernetes, release validation, production readiness, worker outbox, and runbooks in local state. | Low | Reduce repetition and keep docs clearly separated between public committed state, local candidate state, and roadmap. | -| Docker/deployment | Adequate | Dockerfile, Helm chart, and public Docker Compose dependencies exist; local dirty tree adds production-like Compose and deploy-check assertions. | Medium | Commit production-like Compose, publish images, and document immutable image digests for release candidates. | -| Security policy | Weak | Public SECURITY.md exists but still depends on LinkedIn first contact; local dirty version improves wording but cannot prove GitHub private reporting. | High | Enable GitHub private vulnerability reporting or publish a dedicated security email, then commit the stronger policy. | -| License/contribution/governance | Adequate | Public LICENSE, CONTRIBUTING, GOVERNANCE, SUPPORT, COMMERCIAL, TRADEMARKS exist; public community profile lacks code of conduct and issue templates. | Medium | Commit CODE_OF_CONDUCT and issue templates; consider a PR template and clearer commercial/security contact. | -| Changelog/versioning | Adequate | Public CHANGELOG exists and local dirty changelog tracks `v0.1.0-rc.3`; no public tags/releases make version claims weak. | High | Align changelog with a public tagged RC and stop relying on local-only release evidence for public trust. | - -## Scorecard - -| Dimension | Score | Notes | -|-----------|------:|-------| -| Production readiness | 6.5/10 | Local production gate passed with PostgreSQL, coverage, migration compatibility, race/security scans, and signing smoke test; no public release and single-writer API keep the cap low. | -| Feature completeness | 7.5/10 | Broad API surface and core release-evidence workflow exist, but deep provider integrations, UI/trust portal, native HSM, broad WORM proof, and public demo proof remain incomplete. | -| Security and open-source trust | 6/10 | Strong local gates and careful secret/non-claim handling; weak public branch protection, no release artifacts, no verified private reporting, no public code of conduct/templates/dependabot/scorecard yet. | -| Marketability and positioning | 5.5/10 | Real pain and plausible niche, but public README/demo/release/adoption evidence are not strong enough for buyer confidence. | -| Differentiation | 6.5/10 | Release-centered, self-hosted, tamper-evident evidence ledger is meaningfully distinct, but not yet proven against Dependency-Track/GRC/build-in-house alternatives. | -| Repository evidence quality | 7/10 | The local repo has unusually strong checks and docs; confidence is reduced by the dirty checkout and gap between local work and public state. | -| Overall | 6.5/10 | Credible controlled candidate, not a broadly production-ready public product. | - -Confidence: medium - -Verdict: Promising but not production-ready - -Direct answers: - -- Is it mature and high-grade enough for production for most intended uses? No. - It is credible for controlled self-hosted pilots or carefully reviewed - internal deployments, but not for most intended uses. -- Is it feature-complete enough to solve a real-world problem? Yes, for a - narrow release-evidence workflow where the operator accepts the single-writer - and self-hosted constraints. No, for broad enterprise trust-center/GRC - replacement use. -- Is it marketable or interesting enough to attract users, buyers, - contributors, or commercial opportunity? Interesting, yes. Highly marketable, - no. The public release/demo/security surface must improve first. -- Is it worth continuing, hardening, repositioning, or abandoning? Continue and - harden. Do not broaden features until the public release and demo proof exist. - -## Highest-leverage next steps - -Next 1-2 days: small fixes that immediately improve trust - -1. Commit and push the current trust-surface improvements. - Why it matters: the local checkout has CODE_OF_CONDUCT, issue templates, - Dependabot, Scorecard, stronger SECURITY.md, production-like Compose, and - examples that public GitHub cannot see. - Files/features: `.github/ISSUE_TEMPLATE/*`, `.github/dependabot.yml`, - `.github/workflows/scorecard.yml`, `CODE_OF_CONDUCT.md`, `SECURITY.md`, - `README.md`, `compose.production-like.yml`, `examples/`, docs/runbooks. - Improvement: closes the gap between local evidence and public trust. - -2. Publish a real release candidate. - Why it matters: no public tags or releases is the largest public adoption - blocker. - Files/features: `scripts/release_candidate_package.sh`, - `.github/workflows/release-artifacts.yml`, `docs/reference/release-candidate.md`, - `CHANGELOG.md`, GitHub release page. - Improvement: creates installable signed artifacts, checksums, release notes, - OpenAPI checksum, migration checksum, and release evidence. - -3. Enable or prove a private security reporting path. - Why it matters: a high-trust evidence ledger cannot rely on ambiguous first - contact. - Files/features: GitHub private vulnerability reporting setting or a dedicated - `security@` mailbox; `SECURITY.md`. - Improvement: improves open-source trust and responsible disclosure. - -4. Turn on branch protection and required checks for `master`. - Why it matters: public branch protection is currently off. - Files/features: GitHub repository settings; document required check names in - `docs/reference/release-validation.md`. - Improvement: makes the green CI signal enforceable. - -5. Add a visible demo pointer at the top of README. - Why it matters: users need a fast proof path, not a feature inventory. - Files/features: `README.md`, `examples/end-to-end-release-evidence/README.md`, - sample reports. - Improvement: improves adoption and makes the product legible. - -Next 1-2 weeks: changes that materially improve production readiness and marketability - -1. Build and document one complete black-box release-evidence scenario. - Why it matters: broad API surface is less convincing than one proven flow. - Files/features: e2e test or script that starts API/worker/Postgres/MinIO, - creates product/release/artifact, uploads SBOM/scan/VEX, generates bundle, - exports package, restarts, and verifies persistence. - Improvement: proves real value and catches integration drift. - -2. Publish container images with immutable digests for the RC. - Why it matters: self-hosted operators expect image install paths. - Files/features: release workflow, Dockerfile, release notes, Helm values. - Improvement: turns release artifacts into usable deployment inputs. - -3. Add externalized security/adoption metadata. - Why it matters: public trust depends on visible settings and automation. - Files/features: Dependabot/Scorecard, security advisories, release SBOM, - provenance, branch protection docs. - Improvement: strengthens open-source posture. - -4. Reduce service/repository concentration further. - Why it matters: large aggregate files remain the hardest architectural trust - issue. - Files/features: split `internal/app/ledger.go`, `internal/app/state.go`, and - `internal/adapters/postgres/store.go` by resource family without changing - public API behavior. - Improvement: lowers maintenance risk and prepares future HA. - -5. Add a small public package viewer/demo. - Why it matters: a customer package product needs something visible. - Files/features: `site/package-viewer/`, docs, sample package artifact. - Improvement: improves buyer understanding without adding a full admin UI. - -Next 1-2 months: changes that could make the project seriously productizable - -1. Finish the production exit review against a real deployment. - Why it matters: local gates do not prove target-environment operations. - Files/features: `docs/reference/production-exit-review.md`, release evidence, - deployment-specific backup/restore, monitoring, incident rehearsal. - Improvement: supports a stronger production claim for a bounded profile. - -2. Deepen provider integrations or deliberately narrow the promise. - Why it matters: buyer expectations around GitHub/GitLab/SSO/KMS/object lock - are high. - Files/features: provider-specific clients where needed, or docs that make - bring-your-own-evidence the explicit supported profile. - Improvement: reduces mismatch between claims and buyer expectations. - -3. Decide whether the product is API-only, API-plus-viewer, or a trust-center - product. - Why it matters: market positioning changes depending on the answer. - Files/features: README, docs, package viewer, examples, commercial docs. - Improvement: clarifies adoption path and avoids competing poorly with full - GRC platforms. - -4. Add public benchmarks and capacity envelopes for the supported profile. - Why it matters: single-writer can be acceptable if capacity is quantified. - Files/features: benchmark harness, `docs/reference/benchmark-results.md`, - `docs/reference/capacity-and-failures.md`. - Improvement: turns architectural caveats into operator guidance. - -5. Seek external validation before broad claims. - Why it matters: self-scored high-trust software is not enough. - Files/features: third-party security review, public audit summary, release - candidate feedback issue/discussion. - Improvement: improves buyer confidence. - -## README/product-page rewrite advice - -Sharper one-sentence pitch: - -Evydence is a self-hosted release evidence ledger for B2B software teams that -need tamper-evident, customer-reviewable technical evidence for every release -without sending release trust data to a SaaS GRC platform. - -Target user: - -Security engineering, AppSec, platform, and compliance-readiness teams that -own release evidence, customer security reviews, SBOM/VEX workflows, and -technical control coverage. - -Core use case: - -Before a release ships, collect SBOM, vulnerability scan, VEX/decision, -artifact/build/source/deployment evidence, generate a signed release bundle, -show readiness gaps, and export a scoped customer-safe package with limitations. - -Best demo/example to show first: - -A single local script that starts the production-like stack, ingests sample -release evidence, prints the readiness report, verifies the audit chain, and -opens a customer package manifest/viewer. - -Proof points to add: - -- Public RC tag and signed artifacts. -- CI badge tied to `make production-check`. -- Coverage result. -- OpenAPI precision count. -- Sample release readiness report. -- Sample customer package. -- Sample audit-chain verification receipt. -- Benchmark envelope for the single-writer profile. - -What to remove or de-emphasize: - -- Long feature inventory before the buyer understands the core workflow. -- Local-only release-candidate claims unless clearly labeled as local. -- Roadmap breadth that makes the product look less focused. -- Any wording that suggests legal compliance, certification, secure release, - complete SBOM, or authoritative vulnerability results. - -## Residual risk and uncertainty - -Untested or unproven in this audit: - -- Public release artifact generation, upload, and verification because no public - tags or releases exist and the local worktree is dirty. -- Real deployed API/worker behavior outside the local gate. -- Real S3/MinIO object-lock enforcement beyond code/docs and local tests. -- Native HSM/PKCS#11 custody. -- External transparency provider inclusion proof semantics. -- GitHub private vulnerability reporting and secret-scanning settings. -- Branch protection/required checks because public branch protection is off. -- Adoption, support process, and buyer trust in a real organization. - -Claims still mostly intended or bounded: - -- Controlled self-hosted production candidate is supported by local gates and - docs, but not by a public release. -- Regulated production, broad production for most uses, and hosted SaaS - production remain out of scope. -- Compliance readiness and technical evidence organization are credible goals; - legal compliance, certification, complete SBOM coverage, authoritative - scanner output, and secure-release guarantees are intentionally not claimed. - -Evidence that would raise confidence: - -- Public signed release candidate with checksums, manifest signature, OpenAPI - checksum, migration checksums, coverage, release notes, and image digests. -- Branch protection with required `Production Check`. -- Enabled private vulnerability reporting or dedicated security mailbox. -- Public dependency automation and Scorecard run. -- A reproducible end-to-end demo using the production-like stack. -- Third-party review or early-user feedback tied to a concrete release. diff --git a/.production_readiness_v3.md b/.production_readiness_v3.md deleted file mode 100644 index cc17bae..0000000 --- a/.production_readiness_v3.md +++ /dev/null @@ -1,435 +0,0 @@ -## 2026-05-31 Remediation Tracking - -Status legend: - -- `[ ]` applicable repository-local work that remains incomplete. -- `[x]` applicable repository-local work completed with current repository evidence. -- `[e]` external, account-level, provider-level, operator-environment, release-publication, or adoption-dependent work that cannot be completed by repository files alone. - -Repository-local remediation from the v3 audit: - -- [x] Keep `.production_readiness_v3.md` as a trackable repository artifact by unignoring production-readiness audit dotfiles. -- [x] Add CODEOWNERS coverage for high-trust code, API, persistence, release, deployment, and public-claim surfaces. -- [x] Add a maintainer review policy that states the expected review questions, high-risk paths, required checks, and the fact that CODEOWNERS is not enforced until GitHub branch protection or repository rules require it. -- [x] Add a release evidence index mapping release artifacts to the commands that create and verify them. -- [x] Update README, getting-started, install, release-candidate, release-validation, source-of-truth, production-readiness, and production-exit docs so source checkout is clearly the pre-release evaluation path and release artifacts become the install path only after publication. -- [x] Document that one API writer replica is the supported stance for the current release line, with multi-writer API HA deferred until a reviewed design exists. -- [x] Add a public roadmap and release cadence reference that keeps near-term focus on release evidence, GitHub trust controls, and supported production-profile limits. -- [x] Wire the new trust artifacts into `make docs-check`, `make meta-check`, and `make release-acceptance` so CODEOWNERS, review policy, release evidence index, and roadmap drift are checked. -- [x] Trigger a public OpenSSF Scorecard workflow run for `master` after the v3 audit identified no visible Scorecard runs. - -External or operator-dependent remediation from the v3 audit: - -- [e] Publish a signed public release candidate/tag with release archives, `SHA256SUMS`, OpenAPI checksum, migration checksum, coverage output, production-check summary, SBOM/provenance metadata, signed release manifest, release notes, and a public release-artifacts workflow run. -- [e] Enable branch protection or repository rules for `master`, including required checks and CODEOWNERS enforcement. -- [e] Enable or verify GitHub vulnerability alerts, Dependabot security updates, private vulnerability reporting, and any desired code-scanning/security-alert settings. -- [e] Configure and verify release signing secrets for GitHub Actions and any package/container registry credentials. -- [e] Publish immutable container images or decide and communicate that release archives/source are the only supported install path for the current release line. -- [e] Prove deployed-environment controls: target backup/restore rehearsal, monitoring deployment, incident rehearsal, object-store WORM/object-lock policy, KMS/HSM custody, SSO/group-sync provider behavior, and transparency-provider semantics. -- [e] Produce external adoption evidence, third-party review, support-process evidence, customer feedback, or case studies tied to a concrete public release candidate. - -## Latest visible state inspected - -Repository: `aatuh/evydence` at `https://github.com/aatuh/evydence`, audited as both the current public GitHub repository and the local checkout at `/home/aatu/projects/evydence`. - -Inspected local state: - -- Local branch: `master`. -- Local `HEAD`: `53ce458b865941d886f2fae03a1b2a83f7cd134b`. -- Local commit date: `2026-05-31T16:46:51+03:00` / `2026-05-31T13:46:51Z`. -- Commit subject: `docs: stabilize production readiness evidence reference`. -- Local worktree before writing this audit: clean, `## master...origin/master`. -- Local and public `origin/master` matched at `53ce458b865941d886f2fae03a1b2a83f7cd134b`. -- Local-only tags exist: `v0.1.0-rc.1`, `v0.1.0-rc.2`, and `v0.1.0-rc.3`. - -Public GitHub state verified with `git ls-remote` and `gh`: - -- Default branch: `master`. -- Public default-branch commit: `53ce458b865941d886f2fae03a1b2a83f7cd134b`, `2026-05-31T13:46:51Z`. -- Visibility: public. -- Archived: false. -- Repository created: `2026-05-28T15:09:02Z`. -- Last pushed: `2026-05-31T13:46:52Z`. -- Stars/watchers/forks: `0` stars, `0` watchers, `0` forks. -- Public open PRs: 6 Dependabot PRs. -- Public open issues: none from `gh issue list`; GitHub `open_issues_count` is 6 because PRs are counted. -- Primary language: Go. GitHub language data reported Go as dominant, plus Makefile, Python, Shell, TypeScript, HTML, Dockerfile, and Go Template. -- Package manifests: `go.mod` and `go.sum`; module `github.com/aatuh/evydence`; Go version `1.25.10`; API toolkit dependency `github.com/aatuh/api-toolkit/v3 v3.1.2`. -- License: GitHub reports AGPL-3.0 / GNU AGPLv3; repository files and README position this as `AGPL-3.0-only`, with commercial license exceptions documented in `COMMERCIAL.md`. - -Public release and tag state: - -- `gh release list --repo aatuh/evydence --limit 20` returned no releases. -- `gh api repos/aatuh/evydence/releases/latest` returned 404 Not Found. -- `git ls-remote --tags origin` returned no public remote tags. -- `gh api repos/aatuh/evydence/tags` returned `[]`. -- The local tags are not public release/tag evidence. This is a hard adoption and release-integrity gap. -- `gh run list --workflow release-artifacts.yml` and the corresponding workflow-runs API returned no release-artifacts workflow runs, despite the workflow file existing. - -Public CI and GitHub metadata: - -- Workflows visible: `CI`, `Release Artifacts`, `OpenSSF Scorecard`, `Dependabot Updates`, and `Dependency Graph`. -- Latest public CI run for `master` succeeded for commit `53ce458b865941d886f2fae03a1b2a83f7cd134b`, run `26714351811`, created `2026-05-31T13:46:54Z`, updated `2026-05-31T13:50:17Z`. -- Recent CI runs for Dependabot PRs also showed success in `gh run list`. -- No public runs were visible for `Release Artifacts` or `OpenSSF Scorecard` at audit time. -- Branch protection check for `master` returned `Branch not protected` / HTTP 404. -- `security_and_analysis` visible through GitHub API: secret scanning enabled, push protection enabled, non-provider pattern scanning disabled, validity checks disabled, Dependabot security updates disabled. -- Vulnerability-alerts API returned 404 with `Vulnerability alerts are disabled`. -- Security advisories list returned `[]`. -- `SECURITY.md`, `.github/dependabot.yml`, README, license, contributing, code of conduct, issue template, and PR template are publicly present. GitHub community profile reported 100% health, but that is not production-readiness evidence by itself. - -Current repository evidence in checkout: - -- Source tree exists and is substantial: `cmd/`, `internal/`, `migrations/`, `docs/`, `deploy/`, `sdk/`, `examples/`, `scripts/`, `openapi.yaml`, Dockerfile, Compose files, Helm chart, GitHub workflows, governance/security/support files. -- `openapi.yaml` contains 152 paths and 166 operations. -- There are 219 Go test files and 46 migration files. -- `go list ./...` reports 22 Go packages. -- `make fast-check` passed locally during this audit. - -Not inspectable or not proven: - -- GitHub required checks, repository rulesets, CODEOWNERS enforcement, maintainer review policy, private vulnerability reporting enablement, release signing secret configuration, package/container registry publication, artifact immutability, deployment state, backup retention, monitoring deployment, object-store WORM policy, KMS/HSM custody, and production operator controls could not be fully verified from public files and visible API metadata. -- Some GitHub security settings were inspectable and weak: branch protection not enabled, Dependabot security updates disabled, vulnerability alerts disabled. -- Public release artifacts are not published. This caps production-readiness scoring even though release scripts and CI gates are present. - -Confidence impact: confidence is medium-high for repository and public-platform evidence because the latest public commit and local checkout matched and the public metadata was directly queried. Confidence is only medium for real deployment readiness because several required controls are explicitly external/operator-dependent and no public release artifacts exist. - -## What the project appears to be - -Evydence is a self-hosted, API-first release evidence and compliance-readiness ledger for software product teams. Its concrete product shape is a Go HTTP API server, worker, migration command, CLI helper, PostgreSQL-backed ledger, object-storage adapter, OpenAPI contract, SDK helpers, deployment assets, and documentation set. - -The problem is real: B2B software teams often need reproducible technical evidence for release review, customer security questionnaires, SBOM/VEX handling, vulnerability decisions, approvals, exceptions, release bundles, and audit trails without pushing all release-trust data into a SaaS GRC tool. - -Likely users: - -- Security engineering, platform engineering, AppSec, release engineering, compliance-readiness, and customer-trust teams. -- Operators responsible for self-hosted infrastructure, PostgreSQL, object storage, KMS/HSM/gateway signing, backups, and incident response. -- Buyers are likely security/platform leaders at B2B software companies that need self-hosted evidence workflows or a commercial support path. - -README clarity is strong within 30 seconds. It names the target audience, current limitation, non-claim boundaries, fastest proof path, product shape, alternatives, and validation gates near the top. The README is unusually explicit about what Evydence does not prove: it avoids legal compliance, certification, complete SBOM, scanner-authority, and secure-release claims. - -Implemented behavior, documented intent, and stubs are separated better than average: - -- Implemented behavior is backed by Go packages, tests, migrations, OpenAPI, CLI commands, deployment files, examples, and checks. -- Documented current limitations are in `README.md`, `docs/reference/production-readiness.md`, `docs/reference/production-exit-review.md`, `docs/reference/configuration.md`, and runbooks. -- Roadmap/operator-dependent gaps are called out: native PKCS#11/HSM custody, broad WORM/object-lock proof, direct provider-specific management API clients, external group synchronization, multi-writer API HA, hosted SaaS profile, and target-environment backup/restore review. - -The project presents as a controlled self-hosted product candidate, not merely a library. It is not yet a broadly adoptable public OSS product because there are no public releases or public tags and several GitHub trust settings are weak. - -## Production readiness - -Evidence that supports readiness: - -- Go module and source exist with clear process boundaries: `cmd/evydence-api`, `cmd/evydence-worker`, `cmd/evydence-migrate`, `cmd/evydence`, `internal/app`, `internal/domain`, and adapters under `internal/adapters`. -- API implementation uses `github.com/aatuh/api-toolkit/v3` route contracts/spec support, and `openapi.yaml` is committed. -- `openapi.yaml` has 152 paths and 166 operations; `make fast-check` reported `166 precise operations, 0 broad operations`. -- PostgreSQL migrations are present under `migrations/`; there are 46 migration files. -- Runtime configuration is documented in `docs/reference/configuration.md`, including production rejection checks. -- Production API startup code rejects missing database URL, default API-key pepper, local plaintext signing-key modes, bootstrap secret printing, unsupported API writer modes, and API writer replica counts above one. -- PostgreSQL advisory writer lease behavior is implemented in `cmd/evydence-api/main.go` and documented. -- `scripts/production_check.sh` requires live PostgreSQL, release checks, coverage threshold, migration compatibility, benchmark check, black-box demo check, and release signing smoke test. -- Latest public CI on `master` succeeded and the CI workflow runs `make production-check` with a PostgreSQL service. -- Dockerfile, local Docker Compose, production-like Compose, Helm chart, Kubernetes docs, operations docs, backup/restore runbook, upgrade runbook, incident response runbook, observability references, Prometheus rules, and Grafana dashboard starter assets exist. -- Release-candidate packaging script builds multi-platform artifacts, writes checksums, OpenAPI and migration checksums, SBOM/provenance metadata, release notes, a signed release manifest, and a manifest signature. - -Evidence that prevents a broad production-ready verdict: - -- No public GitHub releases. -- No public remote tags, despite local-only release-candidate tags. -- No visible Release Artifacts workflow runs. -- Branch protection is not enabled on `master`. -- Vulnerability alerts are disabled and Dependabot security updates are disabled, even though Dependabot version-update PRs exist. -- README and production docs still classify the system as a controlled self-hosted production candidate, not broadly production-ready. -- The supported production API writer profile is one API writer replica. Worker scaling is supported through PostgreSQL outbox locking, but API multi-writer HA is explicitly unsupported. -- Several high-trust controls remain operator-dependent: KMS/HSM custody review, WORM/object-lock enforcement proof, provider-specific trust review, backup/restore in the target environment, monitoring deployment, and incident rehearsal. -- Production-like assets exist, but no published immutable image or installable release artifact was verified. - -Brutal assessment: the repository has more production machinery than many early OSS projects: real code, tests, migrations, OpenAPI, deployment manifests, runbooks, CI, and a strict self-hosted production gate. The public release surface is still not production-grade. For a high-trust compliance-readiness ledger, no public release artifacts, no public tags, no branch protection, and disabled GitHub vulnerability alerts are not cosmetic gaps; they are adoption blockers. - -Classification: controlled internal pilot / controlled self-hosted production candidate, not broadly production-ready. - -Score: 6/10. - -## Feature completeness - -Supported use cases backed by repository evidence: - -- Start a local API with in-process state or PostgreSQL-backed state. -- Run API, worker, migrations, PostgreSQL, and MinIO in production-like Compose. -- Define tenant-scoped products, projects, releases, artifacts, evidence, SBOMs, VEX documents, vulnerability scans, decisions, exceptions, waivers, approvals, incidents, controls, reports, release bundles, evidence bundles, customer packages, backup manifests, retention records, and related evidence relationships. -- Use scoped API keys, collector keys, SSO/session records, customer portal tokens, and admin diagnostics scopes. -- Generate and validate OpenAPI and route-contract evidence. -- Use Go, TypeScript, and Python SDK helper files plus a generated route catalog. -- Run a checked end-to-end release evidence demo fixture. -- Use a package viewer for customer package/readiness JSON inspection. -- Use release signing CLI commands and release-candidate packaging scripts. -- Deploy with Docker, Compose, or Helm after operator secret/storage/network review. - -Important missing or incomplete table stakes: - -- Public release artifacts and public tags are absent. -- No verified package manager install path, container registry image, or immutable image digest was found. -- Multi-writer API HA is not supported. -- Native PKCS#11/HSM handling is not implemented; `pkcs11-hsm` is gateway-backed. -- Broad object-lock/WORM proof is limited to configured bucket and optional sample-object checks. -- Direct provider-specific management API clients and external group synchronization are outside the current profile. -- Hosted SaaS controls are out of scope. -- Public Scorecard run results were not visible during audit, despite the workflow existing. -- Current docs still state final production exit review is incomplete. - -Blockers: - -- Publish signed public release artifacts and public tags. -- Enable branch protection and required checks. -- Enable vulnerability alerts / Dependabot security updates or document why a public equivalent is used. -- Produce a current release-candidate evidence bundle publicly. -- Close or explicitly defer production exit blockers with fresh review evidence. - -Nice-to-have gaps: - -- Hosted demo or downloadable evaluation bundle. -- Screenshots or short demo video for customer-package/release-readiness output. -- Published benchmark and sizing matrix tied to release artifacts. -- More opinionated install path for small teams. - -Maturity classification: productizable system and controlled production candidate, not a toy and not merely a prototype. It is still not feature-complete enough for broad self-service production adoption because public release/install evidence and external trust controls are missing. - -Score: 7/10. - -## Security and open-source trust - -Strong signals: - -- `SECURITY.md` exists and correctly warns that repository files cannot prove private vulnerability reporting is enabled. -- `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`, `GOVERNANCE.md`, `SUPPORT.md`, `TRADEMARKS.md`, `COMMERCIAL.md`, `RELEASE_EVIDENCE.md`, and issue/PR templates exist. -- Public GitHub community profile reports README, license, contributing, code of conduct, issue template, and PR template. -- Secret scanning and secret-scanning push protection are enabled in visible GitHub metadata. -- `.github/dependabot.yml` configures weekly Go module, GitHub Actions, and Docker updates. -- Several Dependabot PRs are open and their CI runs passed. -- `make tools`, `make gosec`, `make vuln`, `make lint`, `make test-race`, `make release-check`, and `make production-check` exist. -- CI workflow installs QA tools and runs `make production-check` with live PostgreSQL. -- Route/API docs emphasize tenant scoping, scoped secrets, one-time token output, Problem Details, idempotency, append-only evidence, and safe diagnostics. -- Runtime production checks reject several unsafe defaults. -- Release-candidate packaging includes checksums and signed release manifests. - -Weak signals and risks: - -- `master` branch is not protected. -- Vulnerability alerts are disabled. -- Dependabot security updates are disabled. -- No public GitHub releases or release artifacts. -- No public remote tags. -- No visible release-artifacts workflow runs. -- No visible Scorecard runs despite the workflow existing. -- No verified private vulnerability reporting setting. `SECURITY.md` says this must be verified externally. -- No CODEOWNERS evidence was found. -- No visible public release provenance from GitHub release assets or a package/container registry. -- The project handles high-trust evidence, tenant boundaries, secrets, signing, and compliance-readiness data, so public trust defaults matter more than they would for a low-risk library. - -External settings that could not be fully verified: - -- Required checks/rulesets beyond branch protection API response. -- Private vulnerability reporting enablement. -- Secret scanning alert status and remediation process. -- Code scanning alerts. -- Release signing secret presence. -- Registry package/image publication settings. -- Repository admin review process. - -Assessment: the source-controlled security posture is strong for an early project, but the public GitHub trust posture is not yet aligned with the risk profile. For a high-trust ledger, disabled vulnerability alerts and no protected default branch are material findings. - -Score: 6/10. - -## Marketability and positioning - -Buyer/adopter assessment: - -- The problem is painful and specific: teams need customer-reviewable release evidence, SBOM/VEX/vulnerability decisions, approvals, exceptions, and audit chains without forcing all technical trust data into a SaaS GRC platform. -- The target user is clear: B2B software security/platform/AppSec/compliance-readiness teams. -- The value proposition is sharper than generic GRC language: self-hosted technical release evidence ledger with OpenAPI, tenant scoping, idempotency, audit chains, release bundles, and customer-safe packages. -- The README wisely avoids high-risk compliance claims and frames the product as compliance-readiness support. -- The docs give a fast proof path and an end-to-end release evidence example. - -Crowding: - -- The broader space is crowded with SBOM/vulnerability management, GRC SaaS, ASPM, software supply-chain signing, transparency logs, and internal evidence spreadsheets/scripts. -- Evydence is not trying to be only an SBOM scanner, vulnerability platform, or legal compliance platform. That helps differentiation. - -Demo/evaluation path: - -- Local quickstart, production-like Compose, example fixtures, package viewer, and SDK examples exist. -- `make fast-check` passed during audit, including demo fixture checks. -- The best proof path is not yet public-product smooth because there is no published release, no immutable image, and no public release-candidate package to download. - -Monetization/adoption route: - -- AGPL plus `COMMERCIAL.md` supports a plausible dual-license/commercial exception path. -- Paid support, deployment review, custom collectors, templates, and enterprise integration support are plausible. -- Public adoption is constrained until release artifacts, install paths, and GitHub trust settings are fixed. - -Assessment: market positioning is good for a narrow self-hosted security/compliance-readiness infrastructure niche. The public repo currently looks like a serious candidate built fast, but not yet like a stable product users can safely adopt without close maintainer/operator involvement. - -Score: 7/10. - -## Differentiation - -Direct alternatives: - -- OWASP Dependency-Track: strong SBOM/component analysis and vulnerability intelligence workflows. Evydence is differentiated when the buyer wants release-level evidence bundles, decisions, approvals, audit chains, reports, customer packages, and explicit limitations around compliance claims. Dependency-Track remains stronger as a mature SBOM/vulnerability management platform. -- DefectDojo: mature DevSecOps/vulnerability management and findings workflow platform. Evydence is differentiated around release evidence ledgers, bundle verification, customer-safe packages, and tamper-evident evidence records, but DefectDojo is more established for vulnerability program operations. -- GRC SaaS tools such as Vanta and Drata: stronger for broad control automation, policy workflows, and auditor-facing compliance programs. Evydence is differentiated by being self-hosted and technical-evidence-first, but it does not replace legal/auditor review or broad GRC automation. - -Adjacent alternatives: - -- Sigstore/Rekor: strong software signing/transparency-log infrastructure. Evydence can record and verify release evidence and external transparency proof material, but it is not a replacement for public signing infrastructure. -- GUAC: software supply-chain graph analysis and SBOM/SLSA/OSV composition insight. Evydence is differentiated by release-readiness records, approvals, exceptions, customer packages, and compliance-readiness evidence organization. -- In-house systems: object storage, PostgreSQL tables, CI scripts, spreadsheets, and manual customer evidence packs. Evydence is meaningfully different if teams value a versioned API, OpenAPI contract, tenant scoping, idempotency, append-only evidence, audit chains, signed release manifests, and no-claim language. - -Practical comparison source notes: - -- README itself names Dependency-Track, Vanta, Drata, and in-house workflows. -- Public category references checked during audit: Dependency-Track describes continuous SBOM/component analysis; DefectDojo describes vulnerability management/DevSecOps; Sigstore/Rekor describes an append-only transparency log; GUAC describes software supply-chain composition insights. - -Meaningful differentiation: - -- Self-hosted release evidence ledger rather than broad SaaS GRC. -- Release-level package/report/audit-chain model. -- Explicit support for gaps, assumptions, limitations, exceptions, and customer-safe redaction. -- Strong OpenAPI/API-first posture with tenant scoping and idempotency. -- Release evidence and no-claim language are baked into docs and checks. - -Weak differentiation: - -- Public adoption surface is behind the implemented repository: no public releases, no public tags, no immutable install artifact. -- The product still overlaps with several established categories and needs a sharper first demo to show why users should not just extend Dependency-Track, DefectDojo, GUAC, or CI scripts. -- Some differentiators are documented or operator-dependent rather than proven in a public downloadable release. - -Score: 7/10. - -## Repository quality checklist - -| Area | Status | Evidence | Severity | Recommended fix | -|------|--------|----------|----------|-----------------| -| README | Strong | Clear category, target users, limitations, proof path, alternatives, implemented areas, validation commands, and no-claim language in `README.md`. | Low | Add a first-screen concrete output artifact or screenshot and link to the latest public release once published. | -| Quickstart | Strong | `docs/tutorials/getting-started.md`, README local API commands, Compose rehearsal docs. | Low | Tie quickstart to a public release artifact rather than source checkout only. | -| Examples/demo | Adequate | `examples/end-to-end-release-evidence`, JSON fixtures, `run-local-demo.sh`, package viewer, `make demo-check`, `make package-viewer-check`; `make fast-check` passed. | Medium | Publish a release-backed demo bundle and include expected screenshots/sample outputs in README. | -| Tests | Strong | 219 Go test files; `go test ./...` passed through `make fast-check`; CI runs `make production-check`; migration compatibility and black-box checks exist in project gates. | Low | Keep adding negative tests around tenant isolation, idempotency, signing, object-store digest mismatch, and provider gateways as surface grows. | -| CI | Adequate | Public CI workflow exists and latest `master` run succeeded with live PostgreSQL production-check. | High | Enable branch protection/required checks and publish the required check policy. | -| Releases/provenance | Weak | Release scripts and workflow exist, local tags exist, but public releases and public remote tags are absent; no release-artifacts workflow runs visible. | Blocker | Push signed tags, run release-artifacts workflow, publish draft or public releases with signed manifests, checksums, SBOM/provenance metadata, and release notes. | -| Docs/API/config/ops | Strong | `docs/`, `openapi.yaml`, config reference, operations index, runbooks, production readiness, production exit review, API contract matrix; `docs-check` passed through `make fast-check`. | Low | Reduce repeated long production-status prose over time and keep one canonical status source. | -| Docker/deployment | Adequate | Dockerfile, `docker-compose.yml`, `compose.production-like.yml`, Helm chart, Kubernetes docs, Prometheus rules, Grafana dashboard starter; deploy checks passed. | Medium | Publish immutable images/digests and add a reviewed production install matrix. | -| Security policy | Adequate | `SECURITY.md` exists and is public; secret scanning and push protection enabled. Vulnerability alerts and Dependabot security updates disabled; private vulnerability reporting not verified. | High | Enable vulnerability alerts and Dependabot security updates, verify private vulnerability reporting, add CODEOWNERS or equivalent review ownership. | -| License/contribution/governance | Strong | `LICENSE`, `COMMERCIAL.md`, `CONTRIBUTING.md`, `GOVERNANCE.md`, `CODE_OF_CONDUCT.md`, `SUPPORT.md`, templates. | Low | Clarify CLA/commercial exception path for outside contributors before seeking community adoption. | -| Changelog/versioning | Adequate | `CHANGELOG.md`, release notes template, release-candidate docs, local RC tags. Public tags/releases absent. | High | Publish public tags/releases and align changelog entries to public artifacts. | - -## Scorecard - -| Dimension | Score | Notes | -|-----------|------:|-------| -| Production readiness | 6/10 | Strong local code/gates/docs and latest CI success, but no public releases/tags, branch not protected, and production profile still has explicit operator-dependent blockers. | -| Feature completeness | 7/10 | Broad implemented release-evidence workflow, API, migrations, docs, examples, SDKs, and deployment assets; gaps remain in public install path, HA, HSM/WORM/provider integrations, and release publication. | -| Security and open-source trust | 6/10 | Good source-controlled policy and security-conscious implementation signals; public GitHub posture is weak for this risk profile because branch protection, vulnerability alerts, and Dependabot security updates are not enabled. | -| Marketability and positioning | 7/10 | Clear niche and buyer pain with good no-claim positioning; adoption is constrained by no release artifacts and no polished downloadable proof path. | -| Differentiation | 7/10 | Differentiated around self-hosted release evidence, audit chains, customer packages, limitations, and API-first records; still overlaps with SBOM/vulnerability/GRC/supply-chain tools and needs stronger public proof. | -| Repository evidence quality | 8/10 | Evidence is unusually complete for an early repo: code, tests, OpenAPI, migrations, docs, workflows, scripts, deployment assets, examples, and runbooks. Public release evidence is the major missing category. | -| Overall | 6/10 | Promising, serious, and productizable, but strict public production-readiness is capped by missing public releases/tags and weak GitHub protection/security settings. | - -Confidence: medium - -Verdict: Promising but not production-ready - -Direct answers: - -- Mature and high-grade enough for production for most intended uses? No. It may be usable for controlled self-hosted evaluation, pilots, or tightly reviewed internal production, but not broad production for most intended uses. -- Feature-complete enough to solve a real-world problem? Partly yes. The core release evidence ledger workflow is substantial enough to evaluate against a real problem, but public adoption and several high-trust production controls remain incomplete. -- Marketable or interesting enough to attract users, buyers, contributors, or commercial opportunity? Yes, if repositioned as a controlled self-hosted release-evidence candidate and backed by public release artifacts. -- Worth continuing, hardening, repositioning, or abandoning? Continue and harden. The next work should focus less on adding feature breadth and more on public release trust, installability, GitHub protections, security settings, and a sharper first demo. - -## Highest-leverage next steps - -Next 1-2 days: - -- Publish the public release surface. Push a public `v0.1.0-rc.3` tag or create a fresh `v0.1.0-rc.4`, run `.github/workflows/release-artifacts.yml`, and publish signed release artifacts with `evydence-release-manifest.json`, `evydence-release-manifest.sig.json`, `SHA256SUMS`, OpenAPI checksum, migration checksum, release notes, SBOM/provenance metadata, and binaries. This directly removes the strongest public-readiness blocker. -- Enable branch protection or repository rules for `master`. Require latest CI production-check before merge, prevent direct force-pushes, and require PR review if feasible. This improves trust in the default branch. -- Enable GitHub vulnerability alerts and Dependabot security updates, or document a verified substitute. For this project category, disabled alerts are a high-severity public trust issue. -- Trigger and verify OpenSSF Scorecard. The workflow file exists, but no runs were visible. A public run gives adopters a fast independent trust signal. -- Add a short README note that public releases are now the install source once the first release is published. Keep source checkout as development path. - -Next 1-2 weeks: - -- Make the first evaluation path release-backed. Update `docs/tutorials/getting-started.md`, `docs/how-to/install-and-operate.md`, and README so a user can download a release, verify checksums/signature, run Compose, execute the end-to-end demo, and inspect package/readiness output. -- Add a release evidence index page under `docs/reference/` that maps each release artifact to the command that generated or verified it. This strengthens auditability and prevents release evidence from becoming tribal knowledge. -- Add CODEOWNERS or a documented maintainer review policy for high-risk paths: `internal/app`, `internal/adapters/httpapi`, `internal/adapters/postgres`, signing adapters, object store adapters, migrations, release scripts, and workflows. -- Publish immutable container images or document why binaries/source are the only supported install path. If images are published, include digest pinning guidance in Helm and Compose docs. -- Run `make production-check` locally or in a fresh CI run after release publication and record the produced summary in release artifacts. The latest public CI already succeeded, but users need a release-tied evidence bundle. - -Next 1-2 months: - -- Complete a fresh production exit review after the first public release exists. Update `docs/reference/production-exit-review.md` only when public artifacts, GitHub protections, vulnerability handling, and target deployment runbooks have evidence. -- Decide whether to keep one-API-writer as a supported long-term profile or implement reviewed multi-writer concurrency. If one writer is the product stance, publish capacity limits and recommended deployment topologies. -- Harden provider-dependent areas with explicit integration profiles: KMS/HSM custody, object lock/WORM evidence, provider validation gateways, SSO group synchronization, and transparency proof retrieval. Each profile should have tests, docs, and operational limitations. -- Create a polished customer-facing demo: release readiness report, customer package, audit-chain verification, and a short walkthrough showing gaps/assumptions/limitations rather than generic dashboards. -- Add external adoption hygiene: issue labels, roadmap, support tiers, public security intake confirmation, contributor guidance for AGPL/commercial exceptions, and a release cadence. - -## README/product-page rewrite advice - -Sharper one-sentence pitch: - -Evydence is a self-hosted release evidence ledger for B2B software teams that need reproducible SBOM, vulnerability, approval, exception, deployment, and customer-review evidence without handing technical trust data to a SaaS GRC platform. - -Target user: - -Security, platform, AppSec, and compliance-readiness teams operating self-hosted release infrastructure for customer-facing software. - -Core use case to lead with: - -Before a release ships, collect SBOM, scan, VEX, build, source, approval, exception, and deployment evidence; generate a release-readiness report; verify the audit chain; and export a customer-safe evidence package with explicit gaps and limitations. - -Best demo/example to show first: - -Lead with the end-to-end release evidence example and package viewer, but make it release-backed. Show the exact generated readiness report, customer package manifest, and audit-chain verification result as downloadable artifacts. - -Proof points to add: - -- Latest public release link with signed artifacts and checksums. -- Latest CI production-check run link tied to the release commit. -- Public OpenAPI operation count and precision result. -- Coverage threshold result from release evidence. -- Migration checksum and migration compatibility result. -- Short table of supported production profiles and explicit unsupported profiles. - -What to remove or de-emphasize: - -- Reduce repeated long lists of implemented resource families in the README once a concise product proof path exists. -- Keep the detailed production caveats in canonical docs, but make README lead with one concrete workflow and one concrete output. -- Avoid adding more category breadth until the public install/release story is clean. - -## Residual risk and uncertainty - -Untested during this audit: - -- I did not run `make production-check` locally because it requires `EVYDENCE_TEST_DATABASE_URL` and live PostgreSQL setup. The latest public CI run did run the CI production-check job successfully. -- I did not run `make release-check`, `make test-race`, `make gosec`, `make vuln`, or `make release-candidate-check` locally. -- I did not perform a manual API black-box run, backup/restore rehearsal, Helm install, container build, S3/MinIO object-lock test, KMS signing test, or provider gateway test. -- I did not inspect private GitHub settings, release signing secrets, branch rulesets beyond the branch protection API, private vulnerability reporting, registry settings, or deployment infrastructure. - -Claims still documented or operator-dependent: - -- Native PKCS#11/HSM custody is not proven by repository code; the current profile is gateway-backed. -- Broad WORM/object-lock enforcement depends on object-store configuration and operator evidence. -- Provider-specific management API trust and external group synchronization are not implemented as broad direct integrations. -- Multi-writer API HA is explicitly unsupported. -- Hosted SaaS production is out of scope. -- Target-environment backup/restore, incident response, monitoring, and capacity evidence must be produced by each operator. - -Evidence that would raise confidence: - -- Public signed release artifacts and public tags. -- Public Release Artifacts workflow run tied to the latest release. -- Branch protection and required checks enabled for `master`. -- Vulnerability alerts and Dependabot security updates enabled. -- Public Scorecard results. -- Verified private vulnerability reporting. -- Published immutable container images or a clear binary-only install stance. -- A release-backed production-check summary, coverage report, OpenAPI checksum, migration checksum, SBOM/provenance metadata, and release notes. -- A fresh production exit review after the above public evidence exists. diff --git a/.production_readiness_v4.md b/.production_readiness_v4.md deleted file mode 100644 index e481d46..0000000 --- a/.production_readiness_v4.md +++ /dev/null @@ -1,659 +0,0 @@ -## 2026-05-31 Remediation Tracking - -Status legend: - -- `[ ]` applicable repository-local work that remains incomplete. -- `[x]` applicable repository-local work completed with current repository evidence. -- `[e]` external, account-level, provider-level, operator-environment, release-publication, or adoption-dependent work that cannot be completed by repository files alone. - -Repository-local remediation from the v4 audit: - -- [x] Keep `.production_readiness_v4.md` as a trackable repository artifact. -- [x] Pin GitHub Actions used by CI, release-artifact packaging, Scorecard, and CodeQL workflows to immutable commit SHAs. -- [x] Pin CI service containers and Dockerfile base images to immutable image digests. -- [x] Move the Release Artifacts workflow from workflow-global `contents: write` to workflow-global `contents: read` with job-scoped release write permission. -- [x] Add a CodeQL SAST workflow using the `security-and-quality` query suite and pinned CodeQL action refs. -- [x] Strengthen `SECURITY.md` with a direct GitHub Security Advisory intake link while still stating that private vulnerability reporting must be verified as a GitHub setting. -- [x] Update dependency versions flagged by `govulncheck -show verbose` for non-called module/package vulnerabilities in `golang.org/x/crypto` and `golang.org/x/net`. -- [x] Wire the new workflow and pinning expectations into `make meta-check`, `make docs-check`, `make release-acceptance`, and release/review documentation. -- [x] Correct the OpenSSF Scorecard action pin from the annotated tag object to the peeled `v2.4.0` commit, then split Scorecard publication from SARIF upload so both workflows can keep pinned dependencies and pass their respective verification paths. -- [x] Adjudicate the CodeQL `go/weak-sensitive-data-hashing` finding on `hashBytes` as content-digest usage, with inline suppression and existing HMAC-based secret-hash tests covering API/session/portal secret storage separately. -- [x] Dismiss GitHub code-scanning alert 21 as a false positive with the content-digest rationale and HMAC secret-storage evidence. -- [x] Add native Go fuzz targets for digest validation and content hashing, and wire their seed corpus into `make fuzz-smoke` / `make fast-check`. -- [x] Verify public CI, CodeQL, OpenSSF Scorecard publication, and OpenSSF Scorecard SARIF upload on the hardened public commit. - -External repository settings completed through GitHub APIs: - -- [x] Enable GitHub private vulnerability reporting for the public repository. -- [x] Enable GitHub vulnerability alerts for the public repository. -- [x] Enable GitHub automated security fixes for Dependabot-managed vulnerability remediation. -- [x] Enable branch protection for `master` with required `Production Check` and `CodeQL Analyze` checks, required pull-request review, CODEOWNERS review, linear history, conversation resolution, and force-push/deletion prevention. -- [x] Dismiss remaining external/non-repo-local Scorecard code-scanning alerts with comments: repository age (`MaintainedID`), historical PR-review evidence (`CodeReviewID`), and external CII Best Practices registration (`CIIBestPracticesID`). - -External or operator-dependent remediation from the v4 audit: - -- [e] Publish a signed public release candidate/tag with release archives, `SHA256SUMS`, OpenAPI checksum, migration checksum, coverage output, production-check summary, SBOM/provenance metadata, signed release manifest, release notes, and a public Release Artifacts workflow run. -- [e] Configure additional account-level code-scanning/security-alert policy beyond the repository-local CodeQL and Scorecard workflows where the GitHub organization or operator requires it. -- [e] Configure and verify release signing secrets for GitHub Actions and any package/container registry credentials. -- [e] Publish immutable container images or document a final decision that release archives/source checkout are the only supported install path for the current release line. -- [e] Accumulate long-lived maintenance history, real merged pull-request review history, and external CII Best Practices project registration/badge evidence. -- [e] Prove deployed-environment controls: target backup/restore rehearsal, monitoring deployment, incident rehearsal, object-store WORM/object-lock policy, KMS/HSM custody, SSO/group-sync provider behavior, and transparency-provider semantics. -- [e] Produce external adoption evidence, third-party review, support-process evidence, customer feedback, or case studies tied to a concrete public release candidate. - -## Latest visible state inspected - -Repository: `aatuh/evydence` at `https://github.com/aatuh/evydence`. -Audit scope: strict latest public GitHub repository plus the current local -checkout at `/home/aatu/projects/evydence`. - -Inspected local state: - -- Local branch: `master`. -- Local `HEAD`: `653290639a59395c5ccd8017cc86c551b7ee728a`. -- Local commit date: `2026-05-31 18:33:24 +0300` / `2026-05-31T15:33:24Z`. -- Commit subject: `docs: track production readiness v3 remediation`. -- Local worktree before writing this audit: clean, `## master...origin/master`. -- Local release-candidate tags exist: `v0.1.0-rc.1`, `v0.1.0-rc.2`, - and `v0.1.0-rc.3`. -- Local tags are not public release evidence unless pushed and accompanied by - release artifacts. - -Public GitHub state verified with `gh` and `git ls-remote`: - -- Default branch: `master`. -- Public default-branch commit: - `653290639a59395c5ccd8017cc86c551b7ee728a`. -- Public default-branch commit date: `2026-05-31T15:33:24Z`. -- Local and public `origin/master` matched at audit time. -- Visibility: public. -- Archived: false. -- Description: `Self-hosted API-first evidence ledger for software release - compliance readiness`. -- Topics include `api-first`, `audit-log`, `evidence-ledger`, `golang`, - `openapi`, `release-evidence`, `sbom`, `self-hosted`, - `supply-chain-security`, `vex`, `vulnerability-management`, and - `compliance-readiness`. -- Public stars/watchers/forks: `0` stars, `0` watchers, `0` forks. -- Public issues: GitHub reported 0 issues; 6 open Dependabot PRs were visible. -- License: GitHub reports GNU AGPLv3 / `agpl-3.0`; repository files state - `AGPL-3.0-only` plus optional commercial licensing terms in `COMMERCIAL.md`. -- Primary language: Go. GitHub language data also reported Makefile, Python, - Shell, TypeScript, HTML, Dockerfile, and Go Template. -- Package manifest: `go.mod` / `go.sum`; module - `github.com/aatuh/evydence`; Go `1.25.10`. - -Public release and tag state: - -- `gh release list --repo aatuh/evydence --limit 20` returned no releases. -- `git ls-remote --tags origin` returned no public remote tags. -- `gh api repos/aatuh/evydence/tags` returned `[]`. -- `.github/workflows/release-artifacts.yml` exists, but - `gh run list --workflow "Release Artifacts"` returned no runs. -- This is the largest public production-readiness blocker. The repository has - release-candidate packaging machinery, but no public installable release - evidence yet. - -Public CI and workflow evidence: - -- Latest public `CI` workflow run for `master` at commit `6532906` succeeded: - run `26716793712`, event `push`, created `2026-05-31T15:33:33Z`, - updated `2026-05-31T15:37:32Z`. -- The CI job name was `Production Check`, and GitHub reported it completed - successfully. -- Public `OpenSSF Scorecard` workflow run for `master` at commit `6532906` - succeeded: run `26716795712`, event `workflow_dispatch`, created - `2026-05-31T15:33:39Z`, updated `2026-05-31T15:34:13Z`. -- Public `Dependabot Updates` workflow run for `master` at commit `6532906` - succeeded: run `26716825331`, event `dynamic`. -- One Dependabot pull-request CI run for `actions/checkout-6` was in progress - during inspection. Several earlier Dependabot PR CI runs were successful. -- No public `Release Artifacts` workflow runs were visible. - -Visible GitHub security and repository settings: - -- `master` branch protection: disabled. The branch API reported - `"protected": false`. -- `security_and_analysis`: secret scanning enabled, secret-scanning push - protection enabled, non-provider pattern scanning disabled, validity checks - disabled, Dependabot security updates disabled. -- `repos/aatuh/evydence/automated-security-fixes` returned - `{"enabled":false,"paused":false}`. -- `repos/aatuh/evydence/private-vulnerability-reporting` returned - `{"enabled":false}`. -- `repos/aatuh/evydence/vulnerability-alerts` returned HTTP 404 and did not - prove vulnerability alerts enabled. -- Secret-scanning alerts count returned `0`. -- Code-scanning alerts count returned `20`, all open, from the Scorecard SARIF - upload. The open rules included branch protection, pinned dependencies, - token permissions, code review, SAST, vulnerabilities, security policy, and - maintained-project checks. -- GitHub community profile reported 100 percent and found README, license, - contributing, code of conduct, issue template, and PR template. - -Current repository evidence in checkout: - -- Source and operational tree is substantial: `cmd/`, `internal/`, - `migrations/`, `docs/`, `deploy/`, `sdk/`, `examples/`, `scripts/`, - `.github/`, Dockerfile, Compose files, Helm chart, and `openapi.yaml`. -- `go list ./...` reported 22 Go packages. -- There are 219 Go test files. -- There are 46 migration files. -- `openapi.yaml` contains 152 paths and 166 operations. -- `CODEOWNERS`, `SECURITY.md`, `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`, - `GOVERNANCE.md`, `SUPPORT.md`, `RELEASE_EVIDENCE.md`, `CHANGELOG.md`, - issue templates, PR template, Dependabot config, CI, Scorecard, and release - workflow files are present. - -Not inspectable or not proven: - -- Required checks, rulesets, CODEOWNERS enforcement, maintainer review in - practice, release signing secret configuration, package/container registry - publication, deployment state, backup retention, monitoring deployment, - object-store WORM policy, KMS/HSM custody, external SSO/provider behavior, - customer adoption, commercial support operation, and incident rehearsal could - not be proven from repository files alone. -- Some external settings were inspectable and weak: branch protection disabled, - private vulnerability reporting disabled, Dependabot security updates - disabled, and public vulnerability alerts not proven enabled. - -Confidence impact: confidence is high for the inspected repository/public -GitHub state because local and public `master` matched and visible GitHub -metadata was queried directly. Confidence remains medium for real production -deployment readiness because several important controls are external, -operator-dependent, or unpublished. - -## What the project appears to be - -Evydence is a self-hosted, API-first release evidence and compliance-readiness -ledger for software product teams. It is meant to collect, verify, link, and -report technical release evidence such as SBOMs, vulnerability scans, VEX -decisions, build provenance, source/deployment evidence, approvals, -exceptions, controls, release bundles, evidence bundles, and customer-safe -packages. - -The likely users are security engineering, AppSec, platform engineering, -release engineering, compliance-readiness, and customer-trust teams at B2B -software companies. The likely operators are teams comfortable running -PostgreSQL, object storage, worker processes, deployment secrets, backup and -restore, release signing, and Kubernetes or Compose environments. - -The README communicates the category, target user, value, limitations, proof -path, and adjacent alternatives within about 30 seconds. It clearly avoids -legal compliance, certification, complete SBOM, authoritative scanner, and -secure-release claims. - -The product shape is broader than a library: - -- Go HTTP API server. -- Worker process. -- Migration command. -- CLI helper. -- PostgreSQL-backed ledger with object storage. -- OpenAPI contract. -- SDK helpers. -- Docker/Compose/Helm deployment assets. -- Release evidence tooling and documentation. - -Implemented behavior is backed by source, tests, migrations, OpenAPI, docs, -examples, release scripts, and public CI. Roadmap and external limitations are -also visible: public release publication, multi-writer API HA, native PKCS#11 -HSM custody, broad object-lock/WORM proof, provider-specific trust review, and -hosted SaaS production are not presented as complete. - -Overall, it appears to be a serious controlled self-hosted production candidate -for a high-trust release-evidence niche, not a toy or generated shell. It is -not yet a broadly adoptable public production project because no public -release artifacts/tags exist and several GitHub security controls remain weak. - -## Production readiness - -Evidence that supports readiness: - -- Clear Go module and process split under `cmd/evydence-api`, - `cmd/evydence-worker`, `cmd/evydence-migrate`, and `cmd/evydence`. -- Domain/application/adapters layout exists under `internal/`. -- API contract is committed as `openapi.yaml` with 152 paths and 166 - operations. -- Makefile defines production-oriented gates including `production-check`, - `release-check`, `coverage-check`, `migration-compatibility-check`, - `black-box-demo-check`, `benchmark-check`, `openapi-check`, - `openapi-precision-check`, `deploy-check`, `sdk-check`, and `docs-check`. -- Latest public CI for `master` succeeded and ran the `Production Check` job - with a PostgreSQL service. -- Production-check script requires live PostgreSQL, release-check, coverage - threshold, migration compatibility, benchmark check, black-box demo check, - and release signing smoke test. -- Production docs explicitly state the current supported profile, one API - writer stance, worker scaling model, unsupported broad production claims, and - operator responsibilities. -- Dockerfile, Docker Compose, production-like Compose, Helm chart, - Kubernetes docs, operations docs, backup/restore runbook, upgrade runbook, - incident runbook, observability assets, and capacity/failure docs exist. -- Release-candidate packaging scripts generate artifacts, checksums, OpenAPI - and migration checksums, coverage output, release-check summary, SBOM and - provenance metadata, signed manifest, signature, and notes. -- The source-controlled security and governance surface is unusually complete - for an early project. - -Evidence that prevents a production-ready verdict: - -- No public releases. -- No public remote tags. -- No visible release-artifacts workflow runs. -- No public immutable binary, archive, image, chart package, package-manager - install path, or signed artifact set. -- Branch protection is disabled on `master`. -- Dependabot security updates are disabled. -- Private vulnerability reporting is disabled. -- Vulnerability alerts are not proven enabled. -- Scorecard is now running, but it produced 20 open code-scanning alerts. -- Production docs still correctly classify the project as a controlled - self-hosted production candidate, not broadly production-ready. -- The supported API production profile is one writer replica. Multi-writer API - HA remains intentionally unsupported. -- KMS/HSM custody, WORM/object-lock enforcement proof, provider-specific trust - behavior, target-environment backup/restore, monitoring, and incident - rehearsal remain operator-dependent. - -Brutal assessment: the local repository and public CI are strong enough for a -controlled pilot by a team willing to inspect and run the system from source. -The public release surface is not good enough for broad production adoption. -For a high-trust evidence ledger, missing release artifacts/tags and disabled -default-branch/security controls are material blockers, not polish. - -Classification: controlled internal pilot / controlled self-hosted production -candidate. - -Score: 6/10. - -## Feature completeness - -Supported use cases backed by repository evidence: - -- Tenant-scoped API keys, users, sessions, collectors, and customer portal - token records. -- Products, projects, releases, release candidates, artifacts, container - images, evidence, evidence lifecycle events, release bundles, evidence - bundles, customer packages, reports, controls, exceptions, approvals, - waivers, incidents, source/deployment records, SBOMs, VEX, vulnerability - scans, decisions, and related metadata. -- PostgreSQL migrations and relational projections. -- Filesystem and S3/MinIO object-store adapters. -- Worker outbox processing and object-store replay paths. -- OpenAPI contract and generated route catalog. -- Go, TypeScript, and Python SDK helper files. -- End-to-end release evidence example and package viewer. -- GitHub Actions and GitLab CI collector examples. -- Release-candidate packaging and release signing commands. -- Docker, Compose, Helm, Kubernetes, air-gap, observability, backup/restore, - upgrade, and incident response documentation. - -Important missing or incomplete table stakes: - -- Public release artifacts and public tags. -- Release-backed quickstart and install path. -- Published immutable container images or an explicitly final binary/source - install stance. -- Multi-writer API HA. -- Native PKCS#11 HSM module integration. -- Broad object-store WORM/object-lock proof across real provider settings. -- Direct provider-specific management API clients and external group sync. -- Public adoption proof, third-party review, or customer/case-study evidence. -- Public production exit review tied to a release artifact set. - -Blockers: - -- Publish a signed public release candidate with tags, artifacts, checksums, - release notes, release evidence, and workflow run. -- Enable branch protection/required checks. -- Enable or deliberately replace GitHub vulnerability alerting and Dependabot - security updates. -- Resolve or triage the open Scorecard code-scanning alerts. - -Nice-to-have gaps: - -- Hosted read-only demo or release-backed downloadable evaluation bundle. -- Screenshots or short walkthrough of package viewer/readiness output. -- Published sizing table tied to release artifacts. -- More opinionated install path for small internal production. - -Maturity classification: productizable system and controlled production -candidate. It is feature-rich enough to solve a real release-evidence problem -for a motivated operator, but not mature enough for broad self-service -production adoption. - -Score: 7/10. - -## Security and open-source trust - -Strong signals: - -- `LICENSE`, `COMMERCIAL.md`, `SECURITY.md`, `CONTRIBUTING.md`, - `GOVERNANCE.md`, `SUPPORT.md`, `TRADEMARKS.md`, `RELEASE_EVIDENCE.md`, - `CODE_OF_CONDUCT.md`, `CODEOWNERS`, issue templates, and PR template exist. -- GitHub community profile reports 100 percent. -- Secret scanning and push protection are enabled. -- Dependabot config exists and open Dependabot PRs are visible. -- Latest public CI for `master` succeeded. -- Public Scorecard workflow now has a successful run on the latest public - `master`. -- Code scanning is receiving Scorecard SARIF results. -- CI uses least-content permissions at workflow level and runs production - checks with PostgreSQL. -- Runtime production checks reject several unsafe defaults. -- Docs are explicit about not posting secrets, raw evidence payloads, private - keys, bearer tokens, database URLs, customer data, or provider credentials. -- Security docs correctly state that repository files alone cannot prove - private vulnerability reporting is enabled. - -Weak signals and risks: - -- `master` branch protection is disabled. -- Dependabot security updates are disabled. -- Private vulnerability reporting is disabled. -- Vulnerability alerts are not proven enabled. -- Scorecard produced 20 open code-scanning alerts. -- Public releases/tags and release assets are absent. -- No public release provenance, signed release artifact set, SBOM/provenance - bundle, package metadata, or immutable image digest exists. -- CODEOWNERS is present but cannot be enforcement evidence without branch - protection or repository rules. -- No public security advisory history exists. That is acceptable for a new - repo, but it means the response process is unproven. - -For this product's risk profile, the weak signals matter. Evydence handles -tenant boundaries, security evidence, release claims, raw payload references, -signing material, customer packages, and compliance-readiness reports. The -public repository should therefore hold itself to a higher standard than a -low-risk developer utility. - -Score: 6/10. - -## Marketability and positioning - -Buyer/adopter assessment: - -- The problem is real and painful: B2B teams need reproducible release evidence - for security/customer review without scattering decisions across CI logs, - object storage, spreadsheets, tickets, and SaaS GRC tools. -- The target user is clear: security, platform, AppSec, release, and - compliance-readiness teams. -- The value proposition is sharper than generic compliance automation: - self-hosted technical evidence ledger, release bundles, audit chains, - customer-safe packages, gaps, assumptions, exceptions, and limitations. -- The README avoids dangerous overclaims and presents the product as a - compliance-readiness and technical evidence system, not a legal/compliance - guarantee. -- The fastest proof path is visible through getting started docs, - production-like Compose, example evidence fixtures, and package viewer. - -Crowding: - -- The surrounding space is crowded: SBOM/vulnerability management, GRC SaaS, - software supply-chain signing/provenance, ASPM, transparency logs, and - in-house evidence scripts. -- Evydence is most compelling when positioned narrowly as a self-hosted - release-evidence ledger and customer-review package generator. - -Demo/evaluation path: - -- The repo contains a credible local demo and sample JSON outputs. -- The demo is still source-checkout oriented because there is no published - release artifact set. -- A skeptical adopter cannot yet download a signed release, verify it, run it, - and compare output to published release evidence. - -Monetization/adoption route: - -- AGPL plus commercial license exception/support language is plausible. -- Deployment review, release evidence packages, custom collectors, integration - support, and control/report templates could be commercial services. -- Adoption is constrained by absent releases, absent tags, weak GitHub - protection/security settings, and no external adoption signal. - -Assessment: positioning has improved since earlier reports. The repo now looks -like a coherent product candidate with a narrow use case. It still needs a -public release-backed proof path before marketability can move from -"interesting" to "credible for adoption." - -Score: 7/10. - -## Differentiation - -Direct alternatives: - -- OWASP Dependency-Track: mature SBOM/component and vulnerability management. - Evydence is differentiated by release-level evidence records, audit chains, - customer packages, readiness reports, approvals/exceptions, and explicit - limitation handling. Dependency-Track remains stronger as a mature SBOM and - vulnerability management platform. -- DefectDojo: mature DevSecOps/vulnerability management workflow. Evydence is - differentiated around release bundles, evidence manifests, customer-safe - packages, and compliance-readiness evidence organization. DefectDojo remains - stronger for security findings program operations. -- GRC SaaS tools such as Vanta and Drata: stronger for broad compliance - management, integrations, and auditor-facing workflows. Evydence is - differentiated by being self-hosted and technical-evidence-first, but it does - not replace legal/auditor review. - -Adjacent alternatives: - -- Sigstore/Rekor: signing and transparency infrastructure. Evydence can record - signing/transparency evidence, but is not a replacement for those trust - roots. -- GUAC: software supply-chain composition and graph analysis. Evydence is - differentiated by release-readiness decisions, approvals, exceptions, - packages, and reports. -- In-house workflows: PostgreSQL/object storage/CI scripts/spreadsheets can - cover parts of the job. Evydence differentiates with a versioned API, - OpenAPI contract, tenant scoping, idempotency, append-only evidence, - checksummed bundles, and conservative no-claim language. - -Meaningful differentiation: - -- Self-hosted release evidence ledger rather than generic GRC. -- Customer-safe evidence package and readiness output model. -- Explicit gap/assumption/exception/limitation handling. -- API-first and OpenAPI-backed. -- Strong product-language guardrails against compliance magic. -- Release evidence tooling is part of the project, not an afterthought. - -Weak differentiation: - -- The public artifact/install story lags the implemented code. -- Existing mature tools already own parts of SBOM, vulnerability workflow, - provenance, signing, and GRC. -- Several high-trust differentiators are still operator-dependent or - not publicly release-backed. - -Score: 7/10. - -## Repository quality checklist - -| Area | Status | Evidence | Severity | Recommended fix | -|------|--------|----------|----------|-----------------| -| README | Strong | Clear problem, target user, current limitations, fastest proof path, alternatives, implementation summary, and validation commands in `README.md`. | Low | Add the latest release link and release-backed quickstart after the first public release. | -| Quickstart | Strong | `docs/tutorials/getting-started.md`, local API commands, production-like Compose docs. | Low | Replace source-checkout-first install guidance with release-verification flow once artifacts exist. | -| Examples/demo | Adequate | `examples/end-to-end-release-evidence`, JSON fixtures, `run-local-demo.sh`, package viewer, demo checks. | Medium | Publish a release-backed demo bundle and add screenshots/sample outputs to the first README screen. | -| Tests | Strong | 219 Go test files, public CI `Production Check` success, project gates for coverage, race, migration, black-box demo, docs, OpenAPI, deployment, SDKs. | Low | Keep expanding negative tests around provider gateways, tenant isolation, signing, object-store mismatch, and parser retries. | -| CI | Adequate | Public CI on `master` succeeded at `6532906`; CI runs `make production-check` with PostgreSQL. | High | Enable branch protection/repository rules requiring CI and reviews before `master` changes. | -| Releases/provenance | Weak | Release scripts and workflow exist; local tags exist; no public releases, remote tags, or Release Artifacts workflow runs. | Blocker | Publish signed public RC tag/release with archives, checksums, OpenAPI/migration checksums, signed manifest, SBOM/provenance metadata, and release notes. | -| Docs/API/config/ops | Strong | `docs/`, `openapi.yaml`, API matrix, operations/runbooks, production-readiness docs, release-validation docs, Kubernetes/air-gap docs. | Low | Reduce duplicated production-status prose over time and keep one canonical current-status source. | -| Docker/deployment | Adequate | Dockerfile, Docker Compose, production-like Compose, Helm chart, Kubernetes docs, observability starter assets. | Medium | Publish immutable images or explicitly make release archives/source checkout the supported install path for the current release line. | -| Security policy | Adequate | `SECURITY.md` exists, secret scanning and push protection enabled, Scorecard run visible. Branch protection, private vulnerability reporting, and Dependabot security updates are disabled; code-scanning alerts are open. | High | Enable private vulnerability reporting, vulnerability alerts/security updates, branch protection, and triage Scorecard alerts. | -| License/contribution/governance | Strong | AGPL license, commercial terms, contribution policy, governance, support, code of conduct, trademark guidance, CODEOWNERS. | Low | Clarify practical CLA/commercial exception workflow before soliciting outside contributors. | -| Changelog/versioning | Adequate | `CHANGELOG.md`, release notes template, local RC tags, release-candidate docs. Public tags/releases absent. | High | Push public tags/releases and align changelog entries with published artifact evidence. | - -## Scorecard - -| Dimension | Score | Notes | -|-----------|------:|-------| -| Production readiness | 6/10 | Public CI and Scorecard now pass, and local production machinery is strong; no public releases/tags, no Release Artifacts runs, no branch protection, and explicit operator-dependent controls keep this below broad production readiness. | -| Feature completeness | 7/10 | Broad implemented release-evidence workflow, API, migrations, docs, examples, SDKs, deployment assets, and release tooling; gaps remain in public install path, multi-writer HA, native HSM/WORM/provider proof, and release publication. | -| Security and open-source trust | 6/10 | Security docs, community files, Dependabot config, secret scanning, push protection, CI, and Scorecard are visible; branch protection, private vulnerability reporting, Dependabot security updates, public releases, and Scorecard alert triage remain weak. | -| Marketability and positioning | 7/10 | Clear niche, target user, demo path, and conservative claims; adoption credibility is constrained by no release-backed install path and no external adoption proof. | -| Differentiation | 7/10 | Meaningfully differentiated as a self-hosted release evidence ledger with customer packages and no-claim readiness language; still overlaps with mature SBOM, vulnerability, GRC, and supply-chain tools. | -| Repository evidence quality | 8/10 | Strong repository evidence: code, tests, OpenAPI, migrations, workflows, docs, deployment assets, examples, SDKs, runbooks, and public CI. Missing public releases/provenance is the major evidence category gap. | -| Overall | 6/10 | Serious and productizable, but strict public production-readiness remains capped by absent release artifacts/tags and weak GitHub protection/security settings for a high-trust project. | - -Confidence: medium - -Verdict: Promising but not production-ready - -Direct answers: - -- Is it mature and high-grade enough for production for most intended uses? - No. It may be usable for controlled self-hosted evaluation, pilots, or - carefully reviewed internal production, but not most intended production uses. -- Is it feature-complete enough to solve a real-world problem? Partly yes. The - core release evidence workflow is substantial enough to evaluate and pilot, - but public install/release trust and several production controls remain - incomplete. -- Is it marketable or interesting enough to attract users, buyers, - contributors, or commercial opportunity? Yes, but only after release-backed - install and public trust controls are cleaned up. -- Is it worth continuing, hardening, repositioning, or abandoning? Continue and - harden. The product is worth continuing; the next work should prioritize - public release trust and GitHub security posture over feature breadth. - -## Highest-leverage next steps - -Next 1-2 days: - -- Publish the first public release candidate. Push a fresh public tag such as - `v0.1.0-rc.4` or intentionally publish the current RC line, run the Release - Artifacts workflow, and attach signed archives, `SHA256SUMS`, - `openapi.sha256`, `migrations.sha256`, coverage output, production-check - summary, SBOM/provenance metadata, signed manifest, manifest signature, and - release notes. This removes the largest blocker. -- Enable branch protection or repository rules for `master`. Require the CI - production-check before merge, require review where feasible, prevent force - pushes, and make CODEOWNERS meaningful. -- Enable private vulnerability reporting, vulnerability alerts, and Dependabot - security updates. Current visible settings are too weak for this product's - risk profile. -- Triage the 20 open Scorecard code-scanning alerts. Branch protection, - pinned dependencies, token permissions, SAST, security policy, and - vulnerability signals are now publicly visible as open findings. -- Update README and getting-started docs after the release so the first install - path is release verification rather than source checkout. - -Next 1-2 weeks: - -- Make the evaluation path release-backed end to end: download release, verify - signature/checksums, run Compose or Helm with explicit image/binary source, - execute the end-to-end evidence demo, and inspect the readiness/customer - package output. -- Decide whether to publish immutable container images or explicitly defer - images and support only release archives/source checkout for the current - line. Update Helm and Compose docs accordingly. -- Produce a release-tied public evidence index with links to CI run, - production-check summary, OpenAPI checksum, migration checksum, coverage - report, release manifest, signature, SBOM/provenance metadata, and notes. -- Reduce duplicated production-status prose across docs so current status, - supported profile, and limitations have one canonical source. -- Add a short product demo artifact: screenshot or rendered sample of release - readiness, audit-chain verification, and customer package manifest. - -Next 1-2 months: - -- Complete a fresh production exit review after public release artifacts, - branch protections, vulnerability reporting, and security updates are enabled. -- Either keep the one-writer API model as the explicitly supported profile with - sizing guidance, or design and implement reviewed multi-writer API - concurrency. -- Harden provider-dependent trust profiles: KMS/HSM custody, object-lock/WORM - verification, provider validation gateways, transparency proof retrieval, - and SSO/group behavior with explicit tests and operator docs. -- Build public adoption evidence: a supported pilot walkthrough, issue labels, - support workflow, release cadence, and, when real users exist, case studies - or third-party review. -- Keep adding production-grade negative tests around tenant isolation, - credential revocation, idempotency conflicts, parser retries, digest - mismatches, signing failures, and report/package redaction. - -## README/product-page rewrite advice - -Sharper one-sentence pitch: - -Evydence is a self-hosted release evidence ledger for B2B software teams that -need reproducible SBOM, vulnerability, approval, exception, deployment, and -customer-review evidence without handing technical trust data to a SaaS GRC -platform. - -Target user: - -Security, AppSec, platform, release, and compliance-readiness teams operating -self-hosted release infrastructure for customer-facing software. - -Core use case to show first: - -Before release, collect SBOM, vulnerability scan, VEX decision, build/source, -approval, exception, artifact, and deployment evidence; generate a -release-readiness report; verify the audit chain; and export a customer-safe -evidence package that states gaps, assumptions, and limitations. - -Best demo/example to show first: - -Use the end-to-end release evidence example and package viewer, but make them -release-backed. The first proof should be "download this signed RC, verify it, -run this Compose flow, inspect these JSON outputs." - -Proof points to add: - -- Latest public release link. -- Signed artifact manifest and manifest signature. -- `SHA256SUMS`, OpenAPI checksum, migration checksum. -- Public CI production-check run linked to the release commit. -- Coverage threshold result. -- Scorecard result and triage status. -- Supported production profile table. - -What to remove or de-emphasize: - -- Shorten long lists of implemented resource families in the README after the - release-backed demo is available. -- Keep detailed production caveats in canonical docs instead of repeating them - in many places. -- Do not add more broad feature claims until public release/install trust is - fixed. - -## Residual risk and uncertainty - -Untested during this audit: - -- I did not run `make production-check`, `make release-check`, - `make test-race`, `make gosec`, `make vuln`, or - `make release-candidate-check` locally. -- I did not perform a manual API black-box run, backup/restore rehearsal, Helm - install, container build, S3/MinIO object-lock test, KMS/HSM signing test, - OIDC/SAML provider test, or transparency provider test. -- I did not inspect private repository rulesets, secret values, package - registry settings, production deployments, monitoring systems, backup - storage, or real customer/adoption data. - -Claims still documented or operator-dependent: - -- Native PKCS#11/HSM module custody is not proven by repository evidence. -- Broad WORM/object-lock enforcement depends on provider configuration and - operator evidence. -- Direct provider-specific management API trust and external group - synchronization are not broadly implemented. -- Multi-writer API HA is explicitly unsupported. -- Hosted SaaS production is out of scope. -- Target-environment backup/restore, incident response, monitoring, capacity, - and security operations must be proven by each operator. - -Evidence that would raise confidence: - -- Public signed release artifacts and public tags. -- Public Release Artifacts workflow run tied to a release. -- Branch protection and required checks enabled for `master`. -- Private vulnerability reporting, vulnerability alerts, and Dependabot - security updates enabled. -- Scorecard alerts triaged or resolved. -- Published immutable container images or a deliberate non-image install - stance. -- Release-backed production-check summary, coverage report, OpenAPI checksum, - migration checksum, SBOM/provenance metadata, and release notes. -- Fresh production exit review after the above public evidence exists. diff --git a/.production_readiness_v5.md b/.production_readiness_v5.md deleted file mode 100644 index 6d65207..0000000 --- a/.production_readiness_v5.md +++ /dev/null @@ -1,808 +0,0 @@ -## 2026-05-31 Remediation Tracking - -Status legend: - -- `[ ]` applicable repository-local or repository-admin work that remains incomplete. -- `[x]` applicable work completed with current repository, GitHub, release, or command evidence. -- `[e]` external, account-level, provider-level, operator-environment, customer/adoption, or time-dependent work that cannot be completed by repository files and GitHub repository administration alone. - -Repository-local and repository-admin remediation from the v5 audit: - -- [x] Keep `.production_readiness_v5.md` as a trackable repository artifact and current remediation source. -- [x] Publish signed public prerelease `v0.1.0-rc.4` from current `master`, with archives, `SHA256SUMS`, OpenAPI checksum, migration checksum, coverage output, production-check summary, SBOM/provenance metadata, signed release manifest, manifest signature, and release notes. -- [x] Produce successful public `Release Artifacts` workflow run [`26719422897`](https://github.com/aatuh/evydence/actions/runs/26719422897) tied to `v0.1.0-rc.4`. -- [x] Update release evidence and install docs with public release URL, public tag, CI run, release-artifacts workflow run, artifact checksums, signed manifest, SBOM/provenance metadata, and verification instructions. -- [x] Add a Scorecard-compatible `evydence-release-manifest.sig` alias for the signed manifest metadata while preserving the Evydence CLI `evydence-release-manifest.sig.json` verification contract. -- [x] Add Scorecard-compatible `evydence-release-provenance.intoto.jsonl` provenance metadata with explicit non-SLSA and non-compliance limitations. -- [x] Decide and document the immediate public container stance: `v0.1.0-rc.4` publishes release archives and release evidence only; operators must build, sign, and publish their own images for Helm or air-gapped workflows. -- [x] Make the evaluation path release-backed: public release download, verification, release-binary extraction, demo/package viewer walkthrough, and sample output links instead of source-checkout-only evaluation. -- [x] Document a fresh production exit review after the public release evidence exists, preserving controlled-candidate language and remaining operator-dependent blockers. - -External, adoption-dependent, or operator-environment work from the v5 audit: - -- [e] Produce real production deployment evidence, target-environment backup/restore rehearsal, monitoring evidence, incident rehearsal, object-store WORM/object-lock proof, KMS/HSM custody proof, provider credential validation, and customer package access operations. -- [e] Accumulate long-lived maintenance history, merged pull-request review history from non-bypass changes, contributor diversity, public adoption evidence, external review, support-process history, customer feedback, or case studies. -- [e] Obtain external CII Best Practices badge evidence and any other third-party trust-program validation. -- [e] Improve Scorecard dimensions that depend on ecosystem state or policy choices outside this repository content: age-based maintained score, merged PR review history, package-manager or registry distribution if chosen, CII Best Practices validation, contributor diversity, adoption, and external review. -- [e] Enable signed commits, branch-protection admin enforcement, secret-scanning non-provider patterns, or secret validity checks only if the repository/account plan and operator policy support them without blocking required maintenance. - -Post-remediation status on 2026-05-31: - -- Public prerelease `v0.1.0-rc.4` is published at - . -- The public Release Artifacts workflow run - completed - successfully for tag `v0.1.0-rc.4`. -- Local verification of downloaded release assets passed for `SHA256SUMS`, - `openapi.sha256`, `migrations.sha256`, and the Evydence release manifest - signature. -- OpenSSF Scorecard run - completed - successfully against commit `659f35544590e24b758e8cb15fa6294b01dbd187`; - it recognized `evydence-release-manifest.sig` and - `evydence-release-provenance.intoto.jsonl`, raising `Signed-Releases` to - `10/10`. Overall Scorecard remained `7.8` because the remaining weak - dimensions are age-, adoption-, PR-history-, package-ecosystem-, CII-, or - account-policy-dependent and are marked `[e]` above. -- The original audit snapshot below is preserved as historical evidence from - before this remediation pass; the tracker above is the current remediation - status. - -## Latest visible state inspected - -Repository: `aatuh/evydence` at . -Audit scope: strict latest public GitHub repository state plus the current local -checkout at `/home/aatu/projects/evydence`. - -Inspected local state: - -- Local branch: `master`. -- Local `HEAD`: `8737978646fcf5b7e501da7bb6913e7dbe28ea0d`. -- Local commit date: `2026-05-31T20:04:57+03:00` / `2026-05-31T17:04:57Z`. -- Commit subject: `docs: mark external scorecard signals`. -- Local `master` and `origin/master` matched after `git fetch --tags origin`: - `git rev-list --left-right --count master...origin/master` returned `0 0`. -- Local worktree before writing this audit was clean: `## master...origin/master`. -- Local tags exist: `v0.1.0-rc.1`, `v0.1.0-rc.2`, and `v0.1.0-rc.3`. -- Ignored local `dist/v0.1.0-rc.1`, `dist/v0.1.0-rc.2`, and - `dist/v0.1.0-rc.3` directories exist with archives, checksums, coverage, - release manifests, signatures, OpenAPI, migration checksums, and release - notes. These are local ignored artifacts and are not public release evidence. - -Public GitHub state verified with `gh` and git: - -- Default branch: `master`. -- Public default-branch commit: - `8737978646fcf5b7e501da7bb6913e7dbe28ea0d`. -- Public default-branch commit date: `2026-05-31T17:04:57Z`. -- Public repository created: `2026-05-28T15:09:02Z`. -- Public repository pushed: `2026-05-31T17:04:58Z`. -- Public repository updated: `2026-05-31T17:05:02Z`. -- Visibility: public. -- Archived: false. -- Description: `Self-hosted API-first evidence ledger for software release - compliance readiness`. -- Topics include `api-first`, `audit-log`, `evidence-ledger`, `golang`, - `openapi`, `release-evidence`, `sbom`, `self-hosted`, - `supply-chain-security`, `vex`, `vulnerability-management`, and - `compliance-readiness`. -- Public stars/watchers/forks: `0` stars, `0` watchers, `0` forks. -- Public issues: `gh issue list` returned no open issues. `gh pr list` - returned 6 open Dependabot PRs. -- License: GitHub reports GNU AGPLv3 / `AGPL-3.0`; repository files state - `AGPL-3.0-only` plus optional commercial licensing terms in `COMMERCIAL.md`. -- Primary language: Go. GitHub language data also reported Makefile, Python, - Shell, TypeScript, HTML, Dockerfile, and Go Template. -- Package manifest: `go.mod` / `go.sum`; module `github.com/aatuh/evydence`; - Go `1.25.10`. - -Public release and artifact state: - -- `gh release list --repo aatuh/evydence --limit 20` returned no releases. -- `git ls-remote --tags origin` returned no public remote tags. -- `gh api repos/aatuh/evydence/tags` returned no public tags. -- `gh run list --repo aatuh/evydence --workflow "Release Artifacts"` returned - no workflow runs. -- GitHub package APIs for a user-owned or org-owned `evydence` container - package returned 404; no public GHCR package evidence was visible. -- Latest public CI run `26718927469` uploaded an Actions artifact named - `evydence-ci-evidence`, size `68880`, created `2026-05-31T17:08:53Z`. - This is useful CI evidence, but it is not a public release artifact set. -- The largest public production-readiness blocker remains absent public release - publication: no public tag, GitHub Release, release artifact workflow run, - immutable image, package-manager artifact, published checksums, or release - provenance bundle. - -Public CI and check status for inspected commit: - -- Commit check runs for `8737978646fcf5b7e501da7bb6913e7dbe28ea0d` all - completed successfully: - - `Production Check`, run `26718927469`, completed - `2026-05-31T17:08:55Z`. - - `CodeQL Analyze`, run `26718927471`, completed - `2026-05-31T17:06:21Z`. - - `Scorecard`, run `26718928781`, completed - `2026-05-31T17:05:27Z`. - - `Scorecard SARIF`, run `26718929366`, completed - `2026-05-31T17:05:25Z`. -- `CI` runs `make production-check` against a PostgreSQL service and uploads - the CI evidence artifact listed above. -- CodeQL uses the `security-and-quality` query suite. -- OpenSSF Scorecard run `26718928781` reported score `7.6` in logs. Weak - Scorecard dimensions were mainly no release/package evidence, no merged PR - review history, repository age, no contributor diversity, and no CII Best - Practices badge. Its branch-protection check returned an integration access - error, while the GitHub branch protection API separately proved protection is - enabled. - -Visible GitHub security and repository settings: - -- `master` branch protection is enabled. -- Required status checks are strict and require `Production Check` and - `CodeQL Analyze`. -- Pull request reviews are required with 1 approving review, stale review - dismissal, and CODEOWNERS review. -- Required conversation resolution and linear history are enabled. -- Force pushes and branch deletions are disabled. -- Required signed commits are disabled. -- Admin enforcement is disabled. -- Repository `security_and_analysis`: Dependabot security updates enabled, - secret scanning enabled, secret scanning push protection enabled, - non-provider pattern scanning disabled, and secret scanning validity checks - disabled. -- `repos/aatuh/evydence/vulnerability-alerts` returned HTTP 204, proving - vulnerability alerts are enabled to the authenticated `gh` user. -- `repos/aatuh/evydence/automated-security-fixes` returned enabled. -- `repos/aatuh/evydence/private-vulnerability-reporting` returned enabled. -- Dependabot alerts: 0 open. -- Secret-scanning alerts: 0 visible. -- Code-scanning alerts: 0 open; 21 closed or dismissed. Closed examples include - fixed Scorecard findings and a dismissed CodeQL - `go/weak-sensitive-data-hashing` finding with a content-digest rationale. -- GitHub community profile reported 100 percent and found README, license, - contributing guide, code of conduct, issue template, and PR template. - -Current repository evidence in checkout: - -- Source and operational tree is substantial: `cmd/`, `internal/`, - `migrations/`, `docs/`, `deploy/`, `sdk/`, `examples/`, `scripts/`, - `.github/`, Dockerfile, Compose files, Helm chart, and `openapi.yaml`. -- `go list ./...` reported 22 Go packages. -- The checkout has 41 Go test files, excluding `.refs`, `tmp`, and ignored - artifact directories. -- The migration directory has 46 migration files. -- `openapi.yaml` contains 152 paths and 166 operations. -- `make openapi-precision-check` reported 166 precise operations and 0 broad - operations. -- `CODEOWNERS`, `SECURITY.md`, `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`, - `GOVERNANCE.md`, `SUPPORT.md`, `RELEASE_EVIDENCE.md`, `CHANGELOG.md`, - issue templates, PR template, Dependabot config, CI, CodeQL, Scorecard, and - release-artifacts workflow files are present. - -Not inspectable or not proven: - -- GitHub Actions secret values, release signing key configuration, package or - container registry credentials, deployment environments, production - deployments, real backup storage, monitoring systems, object-store WORM - policy, KMS/HSM custody, provider credentials, customer data, support - process execution, SLA behavior, commercial license execution, and real - adoption evidence were not inspectable. -- Branch protection was visible, but private repository rulesets beyond the - branch protection endpoint were not proven. -- Local ignored `dist/` release-candidate artifacts and local tags are not - public install evidence. - -Confidence impact: confidence is high for the inspected local checkout, public -default branch, public CI, visible GitHub security settings, and repository -contents. Confidence remains medium for real production deployment readiness -because the biggest remaining evidence categories are external, operator-owned, -or unpublished. - -## What the project appears to be - -Evydence is a self-hosted, API-first release evidence and compliance-readiness -ledger for software product teams. It collects, verifies, links, and reports -technical release evidence such as SBOMs, vulnerability scans, VEX decisions, -build/source/deployment evidence, approvals, exceptions, controls, release -bundles, audit chains, evidence bundles, and customer-safe packages. - -Likely users are security engineering, AppSec, platform engineering, release -engineering, compliance-readiness, and customer-trust teams at B2B software -companies. Likely operators are teams comfortable running PostgreSQL, object -storage, worker processes, deployment secrets, backup/restore, release signing, -Kubernetes or Compose, and provider integrations. - -The README communicates the category, target user, value, current limitations, -proof path, and alternatives within about 30 seconds. It clearly avoids -claiming legal compliance, certification, complete SBOMs, authoritative scanner -results, or guaranteed release security. - -The product shape is broader than a library: - -- Go HTTP API server. -- Worker process. -- Migration command. -- CLI helper. -- PostgreSQL-backed ledger with object storage. -- OpenAPI contract. -- SDK helpers. -- Docker/Compose/Helm deployment assets. -- Release evidence tooling and documentation. - -Implemented behavior is backed by source, tests, migrations, OpenAPI, docs, -examples, release scripts, public CI, and visible GitHub security settings. -Roadmap and limitation language is also visible: public release publication, -multi-writer API HA, native PKCS#11/HSM custody, broad object-lock/WORM proof, -provider-specific trust review, and hosted SaaS production are not presented as -complete. - -Overall, it appears to be a serious controlled self-hosted production -candidate for a high-trust release-evidence niche. It is not yet a broadly -adoptable public production project because there is still no public release, -tag, signed artifact set, immutable image, or package distribution path. - -## Production readiness - -Evidence that supports readiness: - -- Process split exists under `cmd/evydence-api`, `cmd/evydence-worker`, - `cmd/evydence-migrate`, and `cmd/evydence`. -- Domain/application/adapters layout exists under `internal/`. -- API code uses `github.com/aatuh/api-toolkit/v3` route contracts, specs, and - HTTP helpers. -- API contract is committed as `openapi.yaml` with 152 paths and 166 precise - operations. -- HTTP server has request IDs, secure headers, size-limited JSON bodies, - Problem Details responses, idempotency checks for create/action flows, and - route contract validation tests. -- Production startup rejects missing database URL, default or empty API key - pepper, dev-only signing-key modes, unsupported API writer modes, API writer - replica counts above 1, non-relational production load modes, and bootstrap - secret printing. -- PostgreSQL production mode defaults to relational-only loading, can disable - compatibility snapshot writes, applies or checks migrations at startup, and - takes a PostgreSQL advisory API-writer lease. -- Worker replicas are documented as horizontally scalable through PostgreSQL - outbox row locking, while API writer replicas remain intentionally limited. -- Object storage supports filesystem and S3/MinIO adapters; raw upload replay - paths verify digests before parser trust is assigned. -- Signing adapters exist for HTTP gateway, AWS KMS, GCP KMS, and Azure Key - Vault; native PKCS#11/HSM is explicitly gateway-backed and deployment - dependent. -- Provider identity and transparency proof gateway adapters exist, with timeout - and localhost-only insecure allowances for tests/local use. -- Dockerfile builds API, migration, worker, and CLI commands and uses digest- - pinned base images. -- Compose, production-like Compose, Helm chart, Kubernetes docs, observability - assets, configuration reference, operations docs, backup/restore runbook, - upgrade runbook, incident runbook, release-validation docs, release-candidate - docs, and production-readiness docs exist. -- `make production-check` requires live PostgreSQL, release-check, coverage - threshold, migration compatibility, benchmark check, black-box API/worker - demo, and release-signing smoke test. -- Latest public `master` CI ran `make production-check` with PostgreSQL and - passed. -- Local audit checks passed: `go test ./...`, `make docs-check`, - `make openapi-precision-check`, and `make package-viewer-check demo-check - sdk-check deploy-check`. - -Evidence that prevents a production-ready verdict: - -- No public GitHub releases. -- No public remote tags. -- No visible Release Artifacts workflow runs. -- No public immutable binary, archive, image, chart package, package-manager - install path, or signed public artifact set. -- Local ignored release-candidate artifacts exist, but they are not public - release evidence. -- GitHub required signed commits are disabled and admin enforcement is disabled. -- Secret scanning non-provider patterns and validity checks are disabled. -- OpenSSF Scorecard is 7.6, not high, mainly because of no releases/packages, - no merged PR review history, repository age, no contributor diversity, and no - CII Best Practices badge. -- Production-like Compose uses `postgres:16-alpine`, `minio/minio:latest`, and - `minio/mc:latest`; it is correctly labeled as local rehearsal, not a - turnkey production deployment. -- Helm values reference `ghcr.io/aatuh/evydence`, but no visible GHCR package - exists. -- Production docs still correctly classify the project as a controlled - self-hosted production candidate, not broadly production-ready. -- The supported API production profile is one writer replica. Multi-writer API - HA remains explicitly unsupported. -- KMS/HSM custody, WORM/object-lock enforcement proof, provider-specific trust - behavior, target-environment backup/restore, monitoring, incident rehearsal, - and customer package access operations remain operator-dependent. - -Brutal assessment: the repository is much stronger than a prototype and has a -credible self-hosted pilot path from source. Public CI and GitHub security -settings are now real evidence rather than intent. The public release surface -is still not good enough for broad production adoption. A skeptical operator -cannot yet start from a signed public release, verify checksums and provenance, -pull an immutable image, and map a release artifact to CI evidence. - -Score: 6/10. - -## Feature completeness - -Supported use cases with repository evidence: - -- Create tenant-scoped release ledger resources: products, projects, releases, - release candidates, artifacts, container images, source records, - deployment events, incidents, and remediation records. -- Capture release evidence: generic evidence items, SBOMs, VEX documents, - vulnerability scans, vulnerability decisions, OpenAPI contracts, contract - diffs, security documents, build runs, build attestations, artifact - signatures, collector records, and lifecycle events. -- Generate and verify higher-trust records: release bundles, audit-chain - verification, Merkle batches, transparency checkpoints, signing keys, - signatures, verification results, object-retention policy records, backup - manifests, and legal hold or retention override records. -- Produce reports and review packages: release readiness, missing evidence, - vulnerability posture, control coverage, CRA readiness, incident package, - security review package, evidence summary, graph snapshot, PDF package, - questionnaire draft/package, anomaly report, retention report, and - customer package/export paths. -- Enforce identity and tenant boundaries with API keys, one-time secrets, - HMAC-backed API key/session/portal-token hashes, SSO provider/session - records, role bindings, scopes, and explicit `instance:admin` diagnostics. -- Run a local API tutorial and end-to-end release evidence example. -- Validate demo fixtures, SDK helper coverage, deployment skeletons, docs, - OpenAPI precision, and package viewer through project-owned gates. - -Important missing or incomplete table stakes: - -- Public install path: no public release, tag, immutable image, signed public - artifact set, published checksums, package, or registry evidence. -- Release-to-CI traceability: no public Release Artifacts workflow run tied to - a public tag. -- Production operations: target-environment backup/restore, monitoring, - incident rehearsal, object-store WORM, KMS/HSM custody, and provider trust - semantics remain operator-specific and unproven. -- HA: one API writer is the documented production profile; broad multi-writer - API HA is not implemented. -- Provider coverage: direct provider-specific management API clients and - external group synchronization are not broadly implemented; gateway and - local OIDC/SAML paths cover a narrower bring-your-own-evidence posture. -- UI: there is a local package viewer, but not a full operator/customer UI. -- Adoption proof: no public users, deployments, case studies, external review, - support history, or contributor base. - -Blockers versus nice-to-haves: - -- Blockers: public release artifacts, release provenance, immutable install - path, release-backed demo, and fresh production exit review after public - release publication. -- High-priority hardening gaps: provider custody/WORM proof, production - deployment rehearsals, clearer container publishing stance, Scorecard - maturity items, and Dependabot PR triage. -- Nice-to-have gaps: screenshots, richer UI, more SDK depth, more collectors, - additional framework templates, adoption stories, and external trust badges. - -Maturity classification: controlled production candidate from source, not -broadly production-ready public product. It is not a toy. It is not yet a -complete productizable public release line. - -Score: 7/10. - -## Security and open-source trust - -Strong signals: - -- Public repository is visible and not archived. -- AGPL license, commercial licensing terms, governance, support, contribution - policy, code of conduct, trademark guidance, release evidence policy, - changelog, issue templates, PR template, CODEOWNERS, and maintainer review - policy exist. -- `SECURITY.md` provides private vulnerability reporting guidance and warns - against posting secrets, raw evidence payloads, customer data, and exploit - detail publicly. -- GitHub private vulnerability reporting is enabled. -- GitHub vulnerability alerts are enabled. -- Dependabot security updates and automated security fixes are enabled. -- Dependabot config exists for Go modules, GitHub Actions, and Docker. -- Secret scanning and push protection are enabled. -- CodeQL workflow is active and latest `CodeQL Analyze` passed. -- OpenSSF Scorecard and Scorecard SARIF workflows are active and latest runs - passed. -- Open code-scanning alerts are 0, Dependabot alerts are 0, and visible - secret-scanning alerts are 0. -- `master` branch protection is enabled with strict required `Production Check` - and `CodeQL Analyze` checks, PR review, CODEOWNERS review, stale review - dismissal, conversation resolution, linear history, force-push prevention, - and branch-deletion prevention. -- CI workflow permissions are scoped to read at top level, with release write - permission isolated to the release-artifacts job. -- GitHub Actions and CI service containers are pinned by commit SHA or image - digest in checked workflows. -- Local tests cover tenant isolation, idempotency, immutable/append-only - behavior, auth scopes, provider gateways, KMS adapters, object store paths, - release bundles, audit chain, parser behavior, and PostgreSQL relational - reconstruction. -- Production startup safety checks reject several unsafe defaults. - -Weak signals: - -- No public signed releases, remote tags, Release Artifacts workflow runs, - release checksums, release provenance, public SBOM, or immutable install - artifact. -- Required signed commits are disabled. -- Admin enforcement is disabled for branch protection. -- Secret scanning non-provider patterns and validity checks are disabled. -- OpenSSF Scorecard is only 7.6. Some weak dimensions are structural for a new - solo-maintainer repository, but they still matter to public adopters. -- No CII Best Practices badge or OpenSSF Scorecard badge proof beyond the - workflow. -- No merged PR review history yet. CODEOWNERS is configured and branch - protection requires CODEOWNERS review, but practical multi-person review - evidence is absent. -- No visible release signing secret configuration, package registry policy, or - published image signing evidence. -- No security advisory history, third-party security review, public pentest, - external audit, or real vulnerability-response exercise. -- A high-trust product should treat absent release integrity as a serious - security trust gap even when source CI is strong. - -External settings that were visible: - -- Branch protection: enabled and detailed through `gh api`. -- Private vulnerability reporting: enabled. -- Vulnerability alerts: enabled. -- Automated security fixes: enabled. -- Dependabot alerts: 0. -- Secret-scanning alerts: 0 visible. -- Open code-scanning alerts: 0. - -External settings that could not be verified: - -- GitHub Actions secret values and rotation. -- Release signing private key existence and custody. -- Registry credentials, package publication policy, or image immutability. -- Deployment secrets and infrastructure controls. -- Organization-level rulesets or policies beyond visible repository branch - protection and security settings. - -Score: 6/10. - -## Marketability and positioning - -Buyer/adopter assessment: - -The problem is real and painful for B2B software teams: customer security -reviews, release evidence, SBOM/VEX workflows, vulnerability decisions, build -provenance, exceptions, approvals, and readiness reporting are often scattered -across CI, object storage, spreadsheets, GRC tools, scanners, ticketing, and -manual exports. A self-hosted ledger with conservative no-claim language has a -clear audience among teams that cannot or do not want to hand all technical -release trust data to a SaaS GRC platform. - -The README is significantly better than a normal early repo README. It states -target users, what the product does, what it does not prove, current -limitations, fastest proof path, implementation status, alternatives, and -validation commands. The positioning is credible because it avoids compliance -magic. - -Category crowding: - -- GRC/compliance SaaS platforms such as Vanta and Drata are broad, polished, - commercially mature, and buyer-recognized. -- SBOM and vulnerability tools such as OWASP Dependency-Track own a large part - of the SBOM analysis and vulnerability-management workflow. -- Supply-chain graph tools such as GUAC cover aggregation and query over SBOM, - VEX, SLSA, in-toto, OSV, and related metadata. -- Signing and transparency tools such as Sigstore/Rekor and in-toto cover - artifact signing, transparency, and supply-chain attestation primitives. -- In-house scripts and spreadsheets remain a realistic substitute for teams - with strong platform engineers and low productization expectations. - -Value proposition: - -Evydence is sharpest when positioned as a self-hosted technical evidence ledger -for release review, not as a replacement for GRC, scanners, signing systems, -or auditors. Its most differentiated story is: gather release evidence, record -decisions and limitations, generate a tamper-evident release package, and give -customers reviewable evidence without broad compliance claims. - -Demo/evaluation path: - -- Local getting-started tutorial exists. -- Production-like Compose rehearsal exists. -- End-to-end release evidence example exists. -- Package viewer exists. -- Public CI proves `make production-check` passes on the inspected commit. -- The demo is not yet release-backed, and there is no public install artifact - to verify before running it. - -Plausible adoption or monetization routes: - -- AGPL open-source adoption by self-hosted teams. -- Commercial license exceptions for proprietary or closed deployments. -- Self-hosted support. -- Deployment review. -- Release evidence packages. -- Custom collector/report integrations. -- Private forks and templates for regulated or customer-trust-heavy teams. - -Marketability constraints: - -- No public release means the first adopter still has to trust source checkout - rather than a signed artifact. -- No public image means Helm and Compose production paths require local build - or unpublished image assumptions. -- No screenshots or release-backed walkthrough means time-to-value is not as - immediate as mature alternatives. -- No adoption evidence, external review, or support history exists. -- The product name and public surface are usable, but the public trust story is - incomplete until release publication exists. - -Score: 7/10. - -## Differentiation - -Direct alternatives: - -- [OWASP Dependency-Track](https://dependencytrack.org/): strong SBOM analysis - and vulnerability-management platform. Evydence differs by focusing on - release-level evidence, decisions, approvals, exceptions, bundles, audit - chains, customer packages, and no-claim readiness reports. -- [GUAC](https://docs.guac.sh/guac/): software supply-chain metadata graph. - Evydence differs by being a release evidence ledger and report/package - workflow rather than primarily a graph aggregation/query system. -- [Vanta](https://www.vanta.com/products/automated-compliance) and - [Drata](https://drata.com/): broad SaaS GRC/compliance platforms. Evydence - differs by being self-hosted, technical-evidence-first, API-first, and - explicitly not a compliance automation claim engine. -- [Sigstore/Rekor](https://docs.sigstore.dev/logging/overview/) and - [in-toto](https://github.com/in-toto/in-toto): signing, transparency, and - supply-chain attestation primitives. Evydence can record and verify related - evidence, but it is not a replacement trust root. - -Indirect alternatives: - -- Existing CI artifacts, cloud object storage, tickets, Confluence pages, and - spreadsheets. -- Scanner dashboards and SARIF/SBOM exports. -- GRC evidence lockers. -- Customer trust portals. -- Internal PostgreSQL evidence databases and ad hoc report scripts. - -Build-in-house/do-nothing path: - -A technically strong team can build enough of this with PostgreSQL, object -storage, CI scripts, scanner outputs, and a few export jobs. The hard parts are -not basic CRUD; they are tenant isolation, append-only semantics, idempotency, -canonical hashing, digest verification, release bundles, redaction, customer -package scope, auditability, conservative product language, and keeping docs, -release artifacts, and operational evidence aligned. - -Meaningful implemented differentiation: - -- Self-hosted technical release evidence ledger rather than generic SaaS GRC. -- API-first and OpenAPI-backed with 166 precise operations. -- Tenant-scoped idempotency, append-only evidence transitions, audit-chain - verification, release bundles, and customer-safe packages. -- Explicit gap/assumption/exception/limitation reporting. -- Controlled production profile documented honestly, including one API writer. -- Release evidence packaging machinery is part of the repo, not an afterthought. -- Strong no-claim language baked into README, docs, release notes, and checks. - -Weak differentiation: - -- Mature alternatives already dominate SBOM/vulnerability, GRC, signing, and - supply-chain graph niches. -- No public release artifact means the differentiation is still source-backed - rather than release-backed. -- Provider-specific trust, WORM/object-lock proof, KMS/HSM custody, and - external group synchronization remain operator-dependent. -- No external adoption evidence yet. - -Score: 7/10. - -## Repository quality checklist - -| Area | Status | Evidence | Severity | Recommended fix | -|------|--------|----------|----------|-----------------| -| README | Strong | `README.md` states target user, value, implementation, limitations, proof path, alternatives, validation commands, license/security/support/governance, and no-claim language. | Low | Add public release links, signed-artifact verification, and a release-backed demo once releases exist. | -| Quickstart | Adequate | `docs/tutorials/getting-started.md` works from source and explains in-process state; install docs and production-like Compose exist. | Medium | Replace source-checkout-first public evaluation with signed release verification after the first public release. | -| Examples/demo | Adequate | `examples/end-to-end-release-evidence`, demo fixtures, `run-local-demo.sh`, black-box demo gate, and package viewer exist. | Medium | Publish a release-backed demo bundle and add first-screen screenshots or sample output links. | -| Tests | Strong | 41 Go test files, local `go test ./...` passed, public CI `Production Check` passed, and Makefile has race, coverage, migration, black-box, benchmark, OpenAPI, docs, deploy, SDK, and demo gates. | Low | Keep expanding negative tests around provider gateways, tenant isolation, digest mismatch, redaction, signing failures, parser retries, and backup/restore edge cases. | -| CI | Strong | Public `master` check runs for `Production Check`, `CodeQL Analyze`, `Scorecard`, and `Scorecard SARIF` passed on commit `8737978`; branch protection requires the first two. | Low | Keep required checks aligned with release and security gates; resolve or document failing Dependabot PR checks before merging dependency updates. | -| Releases/provenance | Weak | Release scripts and workflow exist, local tags/artifacts exist, but there are no public releases, public tags, public Release Artifacts runs, public checksums, public signed manifests, public SBOM/provenance, or public install artifacts. | Blocker | Publish a signed public RC tag/release with archives, `SHA256SUMS`, OpenAPI checksum, migration checksum, coverage output, production-check summary, SBOM/provenance metadata, signed manifest, manifest signature, and release notes. | -| Docs/API/config/ops | Strong | `docs/`, `openapi.yaml`, API matrix, configuration reference, operations/runbooks, production-readiness docs, release-validation docs, Kubernetes/air-gap docs, and source-of-truth docs exist. | Low | Reduce repeated production-status prose over time and keep one canonical current-status source. | -| Docker/deployment | Adequate | Dockerfile with pinned base images, local Docker Compose, production-like Compose, Helm chart, Kubernetes docs, observability starter assets, and air-gap manifest exist. | Medium | Publish immutable images or document that release archives/source checkout are the only supported install paths; avoid `latest` tags in production-like examples if they become more than rehearsal docs. | -| Security policy | Adequate | `SECURITY.md`, private vulnerability reporting, vulnerability alerts, automated fixes, secret scanning, push protection, CodeQL, Scorecard, branch protection, CODEOWNERS, and no open visible alerts exist. No public signed release exists. | Medium | Publish release integrity evidence and consider enabling signed commits, admin enforcement, secret-scanning non-provider patterns, and validity checks where practical. | -| License/contribution/governance | Strong | `LICENSE`, `COMMERCIAL.md`, `CONTRIBUTING.md`, `GOVERNANCE.md`, `CODE_OF_CONDUCT.md`, `SUPPORT.md`, `TRADEMARKS.md`, CODEOWNERS, issue templates, and PR template exist. | Low | Clarify practical CLA/commercial exception workflow before actively soliciting outside contributors. | -| Changelog/versioning | Adequate | `CHANGELOG.md`, release notes template, release-candidate docs, local tags, and release packaging scripts exist. Public tags/releases are absent. | High | Push public release tags and align changelog entries with published release artifact evidence. | - -## Scorecard - -| Dimension | Score | Notes | -|-----------|------:|-------| -| Production readiness | 6/10 | Strong source, CI, production-check, docs, deployment skeletons, startup safety checks, and PostgreSQL path; capped by no public release, no public install artifact, no public image, one-writer API profile, and operator-dependent custody/WORM/provider/deployment controls. | -| Feature completeness | 7/10 | Broad implemented release-evidence workflow, API, migrations, docs, examples, SDK helpers, deployment assets, reports, bundles, and release tooling; gaps remain in public install path, full UI, multi-writer HA, and provider/WORM/HSM proof. | -| Security and open-source trust | 6/10 | GitHub security settings, branch protection, CodeQL, Scorecard, Dependabot, private vulnerability reporting, and no visible open alerts are strong; absent signed public releases and weak public release integrity keep trust capped for a high-trust product. | -| Marketability and positioning | 7/10 | Clear niche, target user, demo path, conservative claims, and commercial path; adoption credibility is constrained by no release-backed install path, no screenshots/release demo, and no external adoption proof. | -| Differentiation | 7/10 | Meaningfully differentiated as a self-hosted release evidence ledger with customer packages and no-claim readiness language; still overlaps with mature SBOM, vulnerability, GRC, signing, and supply-chain graph tools. | -| Repository evidence quality | 8/10 | Strong repository evidence: code, tests, OpenAPI, migrations, workflows, docs, deployment assets, examples, SDK helpers, runbooks, public CI, and visible GitHub security settings. Missing public releases/provenance is the major evidence gap. | -| Overall | 7/10 | Serious and productizable, but strict public production-readiness remains blocked by absent public release artifacts/tags/images and unresolved operator-dependent high-trust controls. | - -Confidence: high for repository and public GitHub state; medium for real -production deployment readiness. - -Verdict: Promising but not production-ready - -Direct answers: - -- Is it mature and high-grade enough for production for most intended uses? - No. It may be usable for controlled self-hosted evaluation, pilots, or - carefully reviewed internal production from source, but not most intended - production uses. -- Is it feature-complete enough to solve a real-world problem? Partly yes. The - core release evidence workflow is substantial enough to evaluate and pilot, - but public install/release trust and several production controls remain - incomplete. -- Is it marketable or interesting enough to attract users, buyers, - contributors, or commercial opportunity? Yes, but only after release-backed - install and public proof assets exist. -- Is it worth continuing, hardening, repositioning, or abandoning? Continue and - harden. The product is worth continuing; the next work should prioritize - release publication and operator proof over feature breadth. - -## Highest-leverage next steps - -Next 1-2 days: - -- Publish the first public release candidate. Push a public tag such as - `v0.1.0-rc.4` or intentionally publish the current RC line, run the Release - Artifacts workflow, and attach signed archives, `SHA256SUMS`, - `openapi.sha256`, `migrations.sha256`, coverage output, production-check - summary, SBOM/provenance metadata, signed manifest, manifest signature, and - release notes. This removes the largest public adoption blocker. -- Update `README.md`, `docs/tutorials/getting-started.md`, and - `docs/how-to/install-and-operate.md` after the release so the first public - install path is release verification rather than source checkout. -- Add a release-backed evidence link set in - `docs/reference/release-evidence-index.md`: release URL, tag, CI run, - release-artifact workflow run, checksums, signed manifest, SBOM/provenance - metadata, coverage, and production-check summary. This makes the public trust - path auditable. -- Decide the immediate container stance. Either publish immutable images for - the public release or state clearly that source/release archives are the only - supported install path for the current release line. Update - `deploy/helm/evydence/values.yaml`, `docs/kubernetes.md`, and - `compose.production-like.yml` accordingly. -- Triage the 6 open Dependabot PRs. Some pass and some fail `Production Check`. - Merge only those with required checks green, and document any postponed major - dependency jumps. - -Next 1-2 weeks: - -- Make the evaluation path release-backed end to end: download release, verify - signature/checksums, run Compose or Helm with explicit artifact/image source, - execute the end-to-end evidence demo, and inspect readiness/customer-package - output. This should become the primary README proof path. -- Add one short visual proof artifact: a screenshot or rendered sample of - release readiness, audit-chain verification, and customer package manifest. - This improves time-to-value without adding unproven claims. -- Add an explicit public release integrity checklist to - `docs/reference/release-candidate.md` and keep it enforced by - `scripts/release_candidate_validate.sh`. -- Consider enabling signed commits, branch protection admin enforcement, - secret-scanning non-provider patterns, and secret validity checks if they are - practical for the maintainer workflow. Document any deliberate non-use. -- Register or intentionally defer OpenSSF Best Practices badge work. If - deferred, document why in `docs/reference/production-exit-review.md`. - -Next 1-2 months: - -- Complete a fresh production exit review after public release artifacts, - image/package stance, branch protections, vulnerability reporting, security - updates, and release evidence are all visible. Update - `docs/reference/production-exit-review.md`. -- Either keep the one-writer API model as the explicitly supported profile - with sizing guidance and tested failure behavior, or design and implement a - reviewed multi-writer API concurrency model. -- Harden provider-dependent trust profiles: KMS/HSM custody, object-lock/WORM - verification, provider validation gateways, transparency proof retrieval, and - SSO/group behavior with explicit tests and operator docs. -- Produce target-environment operational proof: backup/restore rehearsal, - incident drill, monitoring deployment, alert examples, object-store recovery, - and upgrade rehearsal tied to a release artifact. -- Build public adoption evidence: supported pilot walkthrough, issue labels, - support workflow, release cadence, and eventually external review, user - feedback, or case studies tied to a concrete public release candidate. - -## README/product-page rewrite advice - -Sharper one-sentence pitch: - -Evydence is a self-hosted release evidence ledger for B2B software teams that -need reproducible SBOM, vulnerability, approval, exception, deployment, and -customer-review evidence without handing technical trust data to a SaaS GRC -platform. - -Target user: - -Security, AppSec, platform, release, and compliance-readiness teams operating -self-hosted release infrastructure for customer-facing software. - -Core use case to show first: - -Before release, collect SBOM, vulnerability scan, VEX decision, build/source, -approval, exception, artifact, and deployment evidence; generate a -release-readiness report; verify the audit chain; and export a customer-safe -evidence package that states gaps, assumptions, and limitations. - -Best demo/example to show first: - -Use the end-to-end release evidence example and package viewer, but make them -release-backed. The first proof should be: download this signed RC, verify it, -run this Compose flow, inspect these JSON outputs. - -Proof points to add: - -- Latest public release link. -- Signed artifact manifest and manifest signature. -- `SHA256SUMS`, OpenAPI checksum, migration checksum. -- Public CI production-check run linked to the release commit. -- Coverage threshold result. -- OpenSSF Scorecard result and residual limitations. -- Supported production profile table. -- Release-backed demo output or screenshots. - -What to remove or de-emphasize: - -- Shorten long lists of implemented resource families in the README after the - release-backed demo is available. -- Keep detailed production caveats in canonical docs instead of repeating them - in many places. -- Do not add more broad feature claims until public release/install trust is - fixed. -- Do not imply public artifact availability before releases and tags actually - exist. - -## Residual risk and uncertainty - -Untested during this audit: - -- I did not run `make production-check`, `make release-check`, - `make test-race`, `make gosec`, `make vuln`, `make coverage-check`, - `make migration-compatibility-check`, `make black-box-demo-check`, or - `make release-candidate-check` locally. -- Public CI did run `make production-check` successfully on the inspected - commit, but this audit did not independently reproduce that full live - PostgreSQL gate locally. -- I did not perform a manual API black-box run, backup/restore rehearsal, Helm - install, container build, S3/MinIO object-lock test, KMS/HSM signing test, - OIDC/SAML provider test, transparency provider test, package download test, - or release signing secret test. -- I did not inspect private secret values, production deployments, monitoring - systems, backup storage, customer package access logs, commercial support - records, or real user/adoption data. - -Claims still only documented, local, or operator-dependent: - -- Public release candidate publication is not complete. -- Local tags and ignored `dist/` directories are not public release evidence. -- Native PKCS#11/HSM module custody is not proven by repository evidence. -- Broad WORM/object-lock enforcement depends on provider configuration and - operator evidence. -- Direct provider-specific management API trust and external group - synchronization are not broadly implemented. -- Multi-writer API HA is explicitly unsupported. -- Hosted SaaS production is out of scope. -- Target-environment backup/restore, incident response, monitoring, capacity, - and security operations must be proven by each operator. - -Evidence that would raise confidence: - -- Public signed release artifacts and public tags. -- Public Release Artifacts workflow run tied to a release. -- Immutable published container images or a deliberate non-image install - stance. -- Public release-backed production-check summary, coverage report, OpenAPI - checksum, migration checksum, SBOM/provenance metadata, signed manifest, - manifest signature, and release notes. -- Public release-backed demo that can be run from artifacts rather than source. -- Fresh production exit review after the public release exists. -- Third-party security review, real deployment rehearsal evidence, external - adoption evidence, or documented customer pilot feedback. diff --git a/.production_readiness_v6.md b/.production_readiness_v6.md deleted file mode 100644 index 37ff66c..0000000 --- a/.production_readiness_v6.md +++ /dev/null @@ -1,659 +0,0 @@ -## 2026-05-31 Remediation Tracking - -Status legend: - -- `[ ]` applicable repository-local or repository-admin work that remains incomplete. -- `[x]` applicable work completed with current repository, GitHub, release, or command evidence. -- `[e]` external, operator-environment, account-policy, adoption, customer, or time-dependent work that cannot be completed by repository files and GitHub repository administration alone. - -Repository-local and repository-admin remediation from this v6 audit: - -- [x] Keep `.production_readiness_v6.md` as a tracked repository artifact and current remediation source. -- [x] Resolve the visible failing Dependabot PR signal by applying or superseding the dependency updates with passing default-branch checks. -- [x] Add a release-binary quick proof path that verifies public `v0.1.0-rc.4` assets from a clean temporary directory before any source-checkout workflow. -- [x] Add public docs and static visual proof for the package viewer/readiness/customer package review path. -- [x] Add an explicit `v0.1.0-rc.4` changelog section. -- [x] Add a repository-owned restore rehearsal command and docs that exercise app-layer and live PostgreSQL backup/restore mechanics. -- [x] Publish a project-owned container image line or a release workflow that produces immutable image digest evidence and operator verification instructions. -- [x] Decide whether Scorecard and Scorecard SARIF should become required branch-protection checks; document or configure the policy. - -Remediation evidence added after this audit: - -- `make public-release-verify TAG=v0.1.0-rc.4` verifies public release assets in a temporary directory with public checksums, in-toto statement shape checks, and the released Linux amd64 CLI verifier. -- `make restore-rehearsal-check` exercises app-layer and live PostgreSQL backup/restore tests. -- `.github/workflows/container-image.yml` published `ghcr.io/aatuh/evydence:v0.1.0-rc.4@sha256:de5627ec300cb603c3f1dc21029bffc096d43399114888cd5c194e00f1285603` in workflow run `26721113041`; anonymous digest inspection succeeded, and image manifest plus cosign verification output were attached to the public `v0.1.0-rc.4` release. -- `docs/reference/maintainer-review-policy.md` records the branch-check policy: `Production Check` and `CodeQL Analyze` are required; OpenSSF Scorecard and Scorecard SARIF remain scheduled/manual advisory checks until they can gate pull requests deterministically. -- Dependency update evidence is clean: visible Dependabot update runs for the remediated dependencies passed, public default-branch `Production Check` and `CodeQL` passed for `295147138ba9cb72a1da5e04948e5d116f2273eb`, and `gh pr list --repo aatuh/evydence --state open` returned no open pull requests. -- Local validation passed: `go test ./...`, `make restore-rehearsal-check`, `make public-release-verify TAG=v0.1.0-rc.4`, `make docs-check`, `make release-acceptance`, Docker image build `evydence:readiness-v6`, and `make production-check` with `.test.env.example` and healthy Compose PostgreSQL. - -External, adoption-dependent, operator-environment, or account-policy work: - -- [e] Accumulate stable non-prerelease release history, long-lived maintenance evidence, public adoption, contributor diversity, public support history, customer feedback, case studies, or third-party review. -- [e] Produce real target-environment deployment evidence, target backup/restore rehearsal, monitoring and alert evidence, incident rehearsal, WORM/object-lock proof, KMS/HSM custody proof, provider credential validation, and customer package access operations. -- [e] Obtain external CII/OpenSSF Best Practices badge evidence or another third-party trust-program validation. -- [e] Enable signed commits, branch-protection admin enforcement, secret-scanning non-provider patterns, or secret validity checks only if the repository/account plan and maintainer policy support them without blocking required maintenance. -- [e] Treat full browser UI/customer portal UX, regulated production readiness, hosted SaaS readiness, and broad multi-writer API HA as product-scope work outside this remediation pass unless a future roadmap item makes them current release requirements. - -## Latest visible state inspected - -Repository: `aatuh/evydence` at . -Audit scope: strict latest public GitHub repository state plus the current -local checkout at `/home/aatu/projects/evydence`. - -Inspected local state: - -- Local branch: `master`. -- Local `HEAD`: `b623fb083c79c7ff670995be473a29483d673c36`. -- Local commit date: `2026-05-31T21:01:27+03:00`. -- Commit subject: `docs: record final readiness v5 scorecard status`. -- Local `master` and `origin/master` matched: - `git rev-list --left-right --count master...origin/master` returned `0 0`. -- Local worktree before writing this audit was clean: `## master...origin/master`. -- Local tags include `v0.1.0-rc.1`, `v0.1.0-rc.2`, `v0.1.0-rc.3`, and - `v0.1.0-rc.4`. -- Primary language: Go. The checkout has 95 Go source files, 41 Go test files, - 22 Go packages, 46 migration files, and an OpenAPI contract with 152 paths, - 166 operations, and 343 component schemas. - -Public GitHub state verified with `gh` and git: - -- Default branch: `master`. -- Public default-branch commit: - `b623fb083c79c7ff670995be473a29483d673c36`. -- Public repository created: `2026-05-28T15:09:02Z`. -- Public repository pushed: `2026-05-31T18:01:28Z`. -- Public repository updated: `2026-05-31T18:01:32Z`. -- Visibility: public. -- Archived: false. -- Description: `Self-hosted API-first evidence ledger for software release - compliance readiness`. -- Topics include `api-first`, `audit-log`, `evidence-ledger`, `golang`, - `openapi`, `release-evidence`, `sbom`, `self-hosted`, - `supply-chain-security`, `vex`, `vulnerability-management`, and - `compliance-readiness`. -- Public stars/watchers/forks: `0` stars, `0` watchers, `0` forks. -- Public issues: `gh issue list` returned no open issues. `gh pr list` - returned 6 open Dependabot PRs; 3 had passing production checks and 3 had - failing production checks at inspection time. -- License: GitHub reports GNU AGPLv3 / `AGPL-3.0`; repository files state - `AGPL-3.0-only` plus optional commercial licensing terms in `COMMERCIAL.md`. -- Package manifest: `go.mod` / `go.sum`; module `github.com/aatuh/evydence`; - Go `1.25.10`. - -Public release and artifact state: - -- Latest visible public prerelease: `v0.1.0-rc.4`, published - `2026-05-31T17:33:47Z` at - . -- GitHub `latestRelease` returned `null` because the visible release is a - prerelease, not a stable latest release. -- Public tag `v0.1.0-rc.4` points to commit - `944c4c6694535f6fc23a2b272e58347217321672`. -- Public release has 18 assets: platform archives, `SHA256SUMS`, - `openapi.yaml`, `openapi.sha256`, `migrations.sha256`, `coverage.out`, - `release-check-summary.txt`, `release-notes.md`, - `evydence-release-manifest.json`, `evydence-release-manifest.sig`, - `evydence-release-manifest.sig.json`, `evydence-release-sbom.cdx.json`, - `evydence-release-provenance.json`, and - `evydence-release-provenance.intoto.jsonl`. -- Local verification of `dist/v0.1.0-rc.4` passed: - `(cd dist/v0.1.0-rc.4 && sha256sum -c SHA256SUMS)`, - `(cd dist/v0.1.0-rc.4 && sha256sum -c openapi.sha256)`, and - `go run ./cmd/evydence release verify --manifest ... --signature ...`. -- The release package reports `make production-check` evidence with live - PostgreSQL; `release-check-summary.txt` records `finalize=passed`, - `lint=passed`, `gosec=passed`, `govulncheck=passed`, `race=passed`, - `live_postgres=passed`, and `postgres_integration=passed`. -- Release coverage evidence reports `80.3%` total statement coverage. -- No project-published container image was visible. Docs intentionally state - that operators must build, sign, and publish their own images for Helm or - air-gapped workflows in the current release line. - -Public CI and check status for inspected commit: - -- Latest default-branch checks completed successfully: - - `CI` / `Production Check`, run `26720228336`. - - `CodeQL`, run `26720228322`. - - `OpenSSF Scorecard`, run `26720232900`. - - `OpenSSF Scorecard SARIF`, run `26720233440`. -- Workflows present: CI, CodeQL, Release Artifacts, OpenSSF Scorecard, - OpenSSF Scorecard SARIF, Dependabot Updates, and Dependency Graph. -- CI runs `make production-check` against a disposable PostgreSQL service and - uploads release evidence artifacts. -- OpenSSF Scorecard was previously recorded at `7.8` after the v5 remediation - pass. The remaining weak dimensions are mainly repository age, adoption, - merged PR review history, CII Best Practices, contributor diversity, and - policy choices such as signed commits or admin enforcement. - -Visible GitHub security and repository settings: - -- `master` branch protection is enabled. -- Required status checks are strict and require `Production Check` and - `CodeQL Analyze`. -- Pull request reviews are required with 1 approving review, stale review - dismissal, and CODEOWNERS review. -- Required conversation resolution and linear history are enabled. -- Force pushes and branch deletions are disabled. -- Required signed commits are disabled. -- Admin enforcement is disabled. -- No repository rulesets were visible through `gh api repos/aatuh/evydence/rulesets`. -- Dependabot security updates are enabled. -- Secret scanning and secret scanning push protection are enabled. -- Secret scanning non-provider patterns and secret scanning validity checks are - disabled. -- Private vulnerability reporting is enabled. -- Vulnerability alerts are enabled. -- Visible Actions secret names include `EVYDENCE_RELEASE_SIGNING_PRIVATE_KEY_B64`; - secret values are not inspectable. -- Dependabot alerts: 0 open. -- Code-scanning alerts: 0 open. Visible historical alerts were fixed or - dismissed; the dismissed CodeQL SHA-256 alert has a content-digest rationale. -- Community profile reported 100 percent and found README, license, - contributing guide, code of conduct, issue template, and PR template. - -Current repository evidence in checkout: - -- Source and operational tree is substantial: `cmd/`, `internal/`, - `migrations/`, `docs/`, `deploy/`, `sdk/`, `examples/`, `scripts/`, - `.github/`, Dockerfile, Compose files, Helm chart, and `openapi.yaml`. -- `make fast-check` passed locally during this audit. It ran unit tests, - fuzz-smoke seed execution, OpenAPI drift check, OpenAPI precision check, - docs check, deploy check, SDK check, demo fixture check, and package viewer - check. -- Release assets verified locally as described above. - -Not inspectable or not proven: - -- GitHub Actions secret values, production deployment environments, real backup - storage, real monitoring systems, object-store WORM policy, native HSM - custody, cloud KMS account configuration, provider credentials, customer - data, support process execution, SLA behavior, commercial license execution, - and real adoption evidence were not inspectable. -- Public branch protection was visible, but account-wide organization policies - and private security settings beyond accessible GitHub API fields were not - fully inspectable. -- Release signing key custody is evidenced by successful signing and a GitHub - Actions secret name, but not by an external KMS/HSM custody proof. - -Confidence impact: confidence is high for the inspected local checkout, public -default branch, public prerelease, release artifacts, public CI, visible GitHub -security settings, and repository contents. Confidence remains medium for real -production deployment readiness because the biggest remaining evidence -categories are external, operator-owned, or time/adoption dependent. - -## What the project appears to be - -Evydence is a self-hosted, API-first release evidence and compliance-readiness -ledger for software product teams. It collects, verifies, links, and reports -technical release evidence such as SBOMs, vulnerability scans, VEX decisions, -build/source/deployment evidence, approvals, exceptions, controls, release -bundles, audit chains, evidence bundles, and customer-safe packages. - -Likely users are security engineering, AppSec, platform engineering, release -engineering, compliance-readiness, and customer-trust teams at B2B software -companies. Likely operators are teams comfortable running PostgreSQL, object -storage, workers, deployment secrets, backup/restore, release signing, -Kubernetes or Compose, and provider integrations. - -The README communicates the category, target user, value, current limitations, -proof path, and alternatives within about 30 seconds. It also avoids the most -dangerous product claims: legal compliance, certification, complete SBOMs, -authoritative scanner results, and guaranteed release security. - -The product shape is broader than a library: - -- Go HTTP API server. -- Worker process. -- Migration command. -- CLI helper. -- PostgreSQL-backed ledger with object storage. -- OpenAPI contract. -- SDK helpers. -- Docker/Compose/Helm deployment assets. -- Release evidence tooling and documentation. - -Implemented behavior is backed by source, tests, migrations, OpenAPI, docs, -examples, release scripts, public CI, a signed public prerelease, and visible -GitHub security settings. Roadmap and limitation language is explicit: -multi-writer API HA, native PKCS#11/HSM custody, broad object-lock/WORM proof, -provider-specific trust review, published container images, and hosted SaaS -production are not presented as complete. - -Overall, it appears to be a serious controlled self-hosted production candidate -for a high-trust release-evidence niche. It is not yet a broadly proven -production product because there is no public container distribution, no -operator deployment proof, no long-lived maintenance record, and no adoption or -third-party review evidence. - -## Production readiness - -Evidence that supports readiness: - -- Process split exists under `cmd/evydence-api`, `cmd/evydence-worker`, - `cmd/evydence-migrate`, and `cmd/evydence`. -- Domain/application/adapters layout exists under `internal/`. -- API code uses `github.com/aatuh/api-toolkit/v3` route contracts, specs, and - HTTP helpers. -- API contract is committed as `openapi.yaml` with 152 paths and 166 - operations; `make openapi-precision-check` reports 166 precise operations - and 0 broad operations. -- HTTP/API tests, route-contract tests, app tests, worker tests, Postgres - tests, migration compatibility tests, object-store tests, SDK checks, demo - fixture checks, and release checks are present. -- Production startup checks reject unsafe modes such as missing database URL, - default pepper, unsupported writer mode, writer replica count above one, - local plaintext signing-key mode, and snapshot fallback modes in production. -- PostgreSQL is the production source of truth. The docs say production loads - relational-only by default and skips compatibility snapshot writes. -- Focused PostgreSQL write paths cover critical runtime state and - release-ledger/evidence-core mutations, reducing dependence on whole-ledger - snapshot persistence. -- Worker outbox behavior exists, including PostgreSQL row locking and - object-store replay for key parser paths. -- Object stores include filesystem and S3/MinIO-compatible adapters. -- Deployment assets include Dockerfile, local Compose, production-like Compose, - Helm chart, air-gap manifest, Prometheus rules, and Grafana dashboard starter - assets. -- Production gate exists and is public-CI-backed: `make production-check` - requires live PostgreSQL, release validation, coverage threshold, migration - compatibility, benchmark check, black-box demo check, and release-signing - smoke test. -- Public `v0.1.0-rc.4` prerelease has signed archives, checksums, OpenAPI and - migration checksums, coverage output, production-check summary, SBOM - metadata, provenance metadata, release notes, and signed release manifest. - -Brutal assessment: - -Evydence now clears the most important public-release evidence gap from v5. A -skeptical operator can download a release, verify checksums and the signed -manifest, inspect the OpenAPI and migration checksums, and see public CI -evidence for a live-Postgres production gate. That is a meaningful jump from -"promising source tree" to "controlled self-hosted release candidate." - -It is still not broad production-ready. The supported profile is one API writer -replica; multi-writer API HA is explicitly unsupported. There is no -project-published container image. Production backup/restore, monitoring, -incident response, WORM/object-lock, KMS/HSM custody, and provider validation -must still be proven by each operator. The codebase still has a large ledger -aggregate and remaining service-boundary hardening work even though relational -write coverage is much better than a simple snapshot-backed MVP. Release -status is prerelease, not stable. - -Maturity classification: production-usable with caveats for controlled -self-hosted pilots and internal production after operator review. - -Score: 7/10. - -## Feature completeness - -Supported end-to-end use cases visible in code/docs/tests: - -- Tenant-scoped API keys and actors. -- Products, projects, releases, release candidates, artifacts, evidence, and - evidence lifecycle events. -- SBOM, vulnerability scan, OpenAPI contract, OpenVEX, vulnerability decision, - exception, waiver, approval, build, attestation, source, deployment, - incident, control, retention, backup, and package/resource families. -- Release readiness, missing evidence, control coverage, CRA readiness, - vulnerability posture, incident package, security review package, - evidence-summary, questionnaire draft, graph snapshot, PDF package, anomaly, - retention, and backup-manifest reports with limitations. -- Release bundles, audit-chain verification, signing keys, signatures, - verification receipts, evidence bundle import/export, customer-safe packages, - and release evidence packaging. -- GitHub Actions, GitLab CI, generic CI/source evidence examples and CLI - helpers. -- Go, TypeScript, and Python SDK helper surfaces checked against OpenAPI route - catalog coverage. - -Important missing or partial table stakes: - -- No public project-published container image, despite Helm documentation and - default repository values pointing at `ghcr.io/aatuh/evydence`. -- No full browser UI or customer portal UX; package viewer is local/static and - useful for inspection, not a hosted workflow. -- No broad multi-writer API HA. -- Native PKCS#11/HSM custody remains gateway-backed/deployment-specific. -- Direct provider-specific management API clients and external group sync are - not complete. -- Object-lock/WORM evidence is still partly deployment-dependent. -- Customer, adoption, support, and external audit workflows are not proven by - real users. - -Blockers versus nice-to-haves: - -- Blockers for broad production: public container or documented image pipeline, - external deployment proof, backup/restore rehearsal proof in a target - environment, monitoring/alert proof, and a stable release line. -- Blockers for regulated production: KMS/HSM custody evidence, WORM/object-lock - evidence, provider identity review, retention/legal review, and incident - rehearsal. -- Nice-to-haves: richer UI, more SDK polish, more connectors, screenshots, - adoption stories, and advanced report templates. - -Maturity classification: productizable system, controlled release candidate, -not toy/prototype. The breadth is high and the workflow is coherent, but some -capabilities remain shallow or operator-evidence-dependent. - -Score: 8/10. - -## Security and open-source trust - -Strong signals: - -- `LICENSE`, `SECURITY.md`, `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`, - `GOVERNANCE.md`, `SUPPORT.md`, `COMMERCIAL.md`, `TRADEMARKS.md`, - `RELEASE_EVIDENCE.md`, `CHANGELOG.md`, CODEOWNERS, issue templates, and PR - template are present. -- GitHub private vulnerability reporting is enabled. -- Vulnerability alerts and Dependabot security updates are enabled. -- Secret scanning and push protection are enabled. -- CodeQL runs with the `security-and-quality` query suite. -- OpenSSF Scorecard and Scorecard SARIF workflows run publicly. -- Branch protection requires strict `Production Check` and `CodeQL Analyze`, - one approving review, CODEOWNERS review, stale review dismissal, - conversation resolution, and linear history. -- Force pushes and branch deletion are disabled. -- Public code-scanning alerts and Dependabot alerts have 0 open findings. -- CI and release workflows pin GitHub Actions by commit SHA and Docker base - images by digest. -- Public release has signed manifest assets, checksums, SBOM metadata, - provenance metadata, and a Scorecard-compatible `.sig` asset. -- Documentation consistently warns against publishing secrets, raw evidence - payloads, bearer tokens, private keys, provider credentials, database URLs, - customer data, and customer package contents. - -Weak signals: - -- Required signed commits are disabled. -- Admin enforcement is disabled. -- Secret-scanning non-provider patterns and validity checks are disabled. -- Repository rulesets are not visible. -- Three open Dependabot PRs had failing production checks at inspection time. -- Public repository is new, with no long-term maintenance history. -- No visible external contributors, stars, forks, users, public issues, or - support history. -- No CII/OpenSSF Best Practices badge. -- Release signing key custody is not externally evidenced by KMS/HSM controls. -- No project-published immutable container image or image signature. - -Score: 8/10. - -## Marketability and positioning - -Buyer/adopter assessment: - -The problem is real. B2B software teams increasingly need release-linked -technical evidence for customer security reviews, procurement, incident -response, and compliance-readiness workflows. Evydence has a clear story: -self-hosted release evidence, not a broad SaaS GRC platform and not just an -SBOM/vulnerability tracker. - -The README is unusually conservative for this category. It names the target -user, states current limitations early, provides a fastest proof path, and -explains why a user might choose it over Dependency-Track, Vanta/Drata-style -GRC platforms, or in-house scripts. - -The category is crowded from several sides: - -- SBOM/vulnerability management, such as OWASP Dependency-Track. -- Software supply-chain graph/metadata systems, such as GUAC. -- SaaS compliance automation/GRC, such as Vanta, Drata, TrustCloud, and - adjacent tools. -- CI/CD and platform-native evidence systems in GitHub, GitLab, and cloud - security tooling. -- In-house object-storage, spreadsheet, Postgres, and CI-script approaches. - -Evydence is marketable as a serious self-hosted engineering-control system, not -yet as a proven commercial product. The strongest adoption path is commercial -self-hosted support, integration work, deployment review, and templates for -security/customer evidence workflows. The weakest public proof is adoption: -there are no users, case studies, screenshots, third-party reviews, package -downloads, or public deployment references. - -Score: 7/10. - -## Differentiation - -Direct alternatives: - -- OWASP Dependency-Track: strong SBOM, VEX, vulnerability, policy, and - component-risk workflows. Evydence is less mature as an ecosystem but more - focused on release-level evidence packages, audit chains, readiness - reports, customer packages, and controlled non-claim language. -- GUAC: strong software supply-chain graph and metadata aggregation direction. - Evydence focuses less on global supply-chain graph exploration and more on - tenant-scoped release evidence, operator verification, and customer-facing - evidence packages. -- Vanta, Drata, TrustCloud, and other GRC/compliance automation tools: - broader compliance automation and vendor trust workflows. Evydence is - self-hosted and technical-evidence-first, with no legal compliance claim. -- GitHub/GitLab native supply-chain/security features: closer to source and - CI data, but less focused on an independent self-hosted release ledger and - customer-safe evidence bundles. - -Indirect alternatives: - -- SCA scanners and vulnerability-management systems. -- Sigstore/Cosign/SLSA provenance pipelines. -- Object storage plus signed manifests. -- Internal platform-engineering evidence databases. -- Manual security review spreadsheets and customer questionnaire workflows. - -Build-in-house/do-nothing path: - -- A capable platform team can build 50 percent of the release evidence story - with CI uploads, object storage, signed JSON, and Postgres tables. The hard - parts are tenant isolation, idempotency, append-only records, audit-chain - continuity, redaction, customer package scope, release verification, docs, - and safe claim language. Evydence meaningfully reduces that integration - burden if the team accepts the current self-hosted operational profile. - -Meaningful differentiation: - -- Release-centered evidence graph rather than only component-centered SBOM - tracking. -- Self-hosted, API-first, append-only, tenant-scoped evidence ledger. -- Release bundle and customer package focus. -- Strong non-claim posture for compliance-readiness. -- Public release evidence for the project itself. - -Weak differentiation: - -- Feature breadth overlaps with mature tools. -- No public adoption proof yet. -- No visual demo or polished product UX. -- No stable ecosystem/package distribution. -- No public container image in the current release line. - -Score: 7/10. - -## Repository quality checklist - -| Area | Status | Evidence | Severity | Recommended fix | -|------|--------|----------|----------|-----------------| -| README | Strong | Clear pitch, target user, limitations, proof path, public release link, alternatives, and conservative claims. | Low | Add a short visual architecture/demo section and keep the first proof path release-backed. | -| Quickstart | Strong | Getting started tutorial, install/operate guide, release verification commands, Compose path, and demo fixtures. | Low | Add a five-minute release-binary walkthrough that avoids source checkout entirely. | -| Examples/demo | Adequate | End-to-end release evidence example, sample JSON outputs, package viewer, GitHub/GitLab CI examples. | Medium | Add screenshots or a recorded walkthrough of release readiness, package viewer, and verification. | -| Tests | Strong | 41 Go test files, `go test ./...`, `make fast-check`, fuzz-smoke, OpenAPI checks, SDK/demo checks, production-check in CI, 80.3% release coverage. | Low | Keep expanding behavior tests for remaining service split, provider validation, and failure modes. | -| CI | Strong | Public CI, CodeQL, Scorecard, Scorecard SARIF, Dependabot, Dependency Graph; latest default-branch checks green. | Low | Fix or close failing Dependabot PRs and consider requiring Scorecard/SARIF as branch checks if maintenance policy supports it. | -| Releases/provenance | Strong | Public prerelease `v0.1.0-rc.4` with 18 assets, checksums, SBOM, provenance, signed manifest, release notes, and production-check summary. | Medium | Publish a stable release when ready and add project-owned signed container images or document a hardened image publication path. | -| Docs/API/config/ops | Strong | Extensive docs, OpenAPI, API matrix, runbooks, release validation, operations, configuration, capacity/failure docs. | Low | Add more target-environment examples and keep docs synchronized as public releases evolve. | -| Docker/deployment | Adequate | Dockerfile, local Compose, production-like Compose, Helm chart, air-gap manifest, observability starters. | Medium | Publish signed container images or make Helm docs explicitly image-build-first for every operator path. | -| Security policy | Strong | SECURITY.md, private vulnerability reporting enabled, no public-secret guidance, advisory expectations, CodeQL/Scorecard, no open alerts. | Low | Add a dedicated security contact beyond LinkedIn/requested private channel if sustainable. | -| License/contribution/governance | Strong | AGPL-3.0-only, COMMERCIAL.md, CONTRIBUTING.md, GOVERNANCE.md, CODEOWNERS, CODE_OF_CONDUCT.md, SUPPORT.md, TRADEMARKS.md. | Low | Clarify CLA process once external contributions become realistic. | -| Changelog/versioning | Adequate | CHANGELOG.md exists and release notes are attached to `v0.1.0-rc.4`. | Medium | Add a changelog entry for each public prerelease and define support windows once stable releases start. | - -## Scorecard - -| Dimension | Score | Notes | -|-----------|------:|-------| -| Production readiness | 7/10 | Public signed release evidence now exists and CI runs `make production-check`; still limited by prerelease status, one API writer, no public container image, no target production deployment proof, and operator-dependent KMS/WORM/provider controls. | -| Feature completeness | 8/10 | Broad implemented release-evidence system with API, worker, reports, packages, bundles, OpenAPI, migrations, SDK helpers, and deployment assets; some high-trust integrations remain partial or deployment-dependent. | -| Security and open-source trust | 8/10 | Strong repo metadata, branch protection, CodeQL, Scorecard, Dependabot, private vulnerability reporting, no open alerts, signed release artifacts, and conservative docs; weakened by disabled signed commits/admin enforcement, no CII badge, no adoption history, and no external KMS/HSM custody evidence. | -| Marketability and positioning | 7/10 | Clear self-hosted release-evidence niche and conservative positioning; weak public adoption, no screenshots, no stable release, and no visible customer proof limit market confidence. | -| Differentiation | 7/10 | Differentiated as a self-hosted release evidence ledger with audit chains and customer-safe packages; still overlaps with mature SBOM, GRC, supply-chain graph, and CI/security tools. | -| Repository evidence quality | 9/10 | Strong source, tests, OpenAPI, migrations, workflows, docs, examples, runbooks, deployment assets, public CI, security settings, and public signed release evidence. Remaining evidence gaps are mostly external or distribution-related. | -| Overall | 8/10 | Serious controlled self-hosted production candidate. The v5 release-evidence blocker is closed, but broad production readiness still depends on stable release history, real deployment proof, image distribution, and operator controls. | - -Confidence: high for repository and public GitHub state; medium for real -production deployment readiness. - -Verdict: Production-usable with caveats - -Direct answers: - -- Is it mature and high-grade enough for production for most intended uses? - Not for most intended uses. It is credible for controlled self-hosted pilots - and internal production after operator review. -- Is it feature-complete enough to solve a real-world problem? - Yes, for release evidence organization, verification, readiness reporting, - and customer-safe package preparation in a controlled self-hosted deployment. -- Is it marketable or interesting enough to attract users, buyers, - contributors, or commercial opportunity? - Yes, as a niche self-hosted technical evidence ledger, but adoption proof and - a stronger demo path are still missing. -- Is it worth continuing, hardening, repositioning, or abandoning? - Continue and harden. Do not abandon. Keep the controlled-candidate - positioning until stable releases and operator proof exist. - -## Highest-leverage next steps - -Next 1-2 days: small fixes that immediately improve trust - -- Fix or close failing Dependabot PRs. Why it matters: open security/update PRs - with failing production checks weaken the visible maintenance story. Files: - `.github/workflows/*`, `Dockerfile`, `go.mod`, `go.sum`, and PR-specific - lock/config changes. -- Add a release-binary quick demo path. Why it matters: current proof paths are - good, but many evaluators still start from source checkout. Files: - `docs/tutorials/getting-started.md`, - `docs/how-to/install-and-operate.md`, and - `examples/end-to-end-release-evidence/README.md`. -- Add screenshots or static images for the package viewer and readiness JSON. - Why it matters: public adopters need to understand value before running a - stack. Files: `README.md`, `docs/how-to/view-packages.md`, and `site/`. -- Update `CHANGELOG.md` with an explicit `v0.1.0-rc.4` section. Why it - matters: release notes exist, but the changelog should reflect public - prerelease history. - -Next 1-2 weeks: changes that materially improve production readiness and marketability - -- Publish a project-owned container image line or document an intentionally - image-free release strategy more strongly. Why it matters: Helm and - air-gapped operators need immutable image digests. Files/workflows: - `.github/workflows/release-artifacts.yml`, `deploy/helm/evydence/values.yaml`, - `docs/kubernetes.md`, and `deploy/airgap/manifest.yaml`. -- Add target-environment backup/restore evidence using Compose or a disposable - local stack. Why it matters: backup/restore is the largest remaining - production-readiness proof gap that can be partially exercised in-repo. - Files: `scripts/`, `docs/runbooks/backup-restore.md`, and CI artifacts. -- Add a public release verification walkthrough that downloads assets from - GitHub and verifies them from a clean temp directory. Why it matters: it - proves the public release path, not just local `dist/`. Files: - `scripts/`, `docs/reference/release-evidence-index.md`, and CI docs. -- Decide whether to require Scorecard and Scorecard SARIF as branch checks. - Why it matters: they already run, but branch protection only requires - production and CodeQL checks. This is a policy choice, not a code issue. - -Next 1-2 months: changes that could make the project seriously productizable - -- Cut a stable `v0.1.0` or later release after several release candidates and - operator rehearsals. Why it matters: prerelease status is appropriate now but - limits production confidence. -- Complete the service-boundary and repository decomposition review. Why it - matters: the large ledger aggregate is the main architectural caveat behind - the single-writer stance. -- Add public deployment evidence for at least one supported profile. Why it - matters: production-readiness claims need restore, monitoring, incident, and - upgrade evidence from a real or realistic environment. -- Add external trust evidence: CII/OpenSSF Best Practices badge, third-party - review, or public design/security review. Why it matters: high-trust buyers - need independent signals beyond maintainer-authored docs. -- Add package/image signing and operator verification for container workflows. - Why it matters: release archives are good, but most self-hosted operators - will deploy images. - -## README/product-page rewrite advice - -Sharper one-sentence pitch: - -Evydence is a self-hosted release evidence ledger for software teams that need -tamper-evident SBOM, vulnerability, build, deployment, control, and customer -review evidence for each release. - -Target user: - -Security, AppSec, platform, release, and compliance-readiness teams at B2B -software companies that want release-linked technical evidence without moving -all release trust data into a SaaS GRC platform. - -Core use case to show first: - -Take one release from product/project/artifact creation through SBOM upload, -vulnerability scan upload, VEX/decision/exception handling, release bundle -generation, readiness report, audit-chain verification, and customer-safe -package inspection. - -Best demo/example to show first: - -Start with the public `v0.1.0-rc.4` release verification commands, then show -the package viewer using the sample customer package manifest. That proves both -release integrity and buyer-facing output without requiring a full stack. - -Proof points to add: - -- Release asset verification screenshot or transcript. -- Public CI production-check artifact link. -- Package viewer screenshot. -- A sample release-readiness report with a blocked finding and a resolved VEX - decision. -- A backup/restore rehearsal transcript. - -What to remove or de-emphasize: - -- Long feature inventories in the README should keep moving into reference - docs as the product matures. -- Avoid overemphasizing future extensions, AI summarization, PDF packages, or - enterprise workflows before release evidence and operator proof are obvious. -- Keep avoiding legal compliance, certification, secure-release, complete SBOM, - scanner-authority, auditor, and regulator claims. - -## Residual risk and uncertainty - -Remaining untested or externally unproven areas: - -- Real production deployment behavior under operator traffic. -- Target-environment backup/restore with the operator's actual PostgreSQL and - object store. -- Monitoring, alerting, incident response, and support execution. -- Object-store WORM/object-lock enforcement in a real provider account. -- Native HSM or cloud KMS custody and key administration in a real account. -- Provider-specific SSO, GitHub/GitLab, transparency, and signing trust - semantics beyond local/gateway evidence. -- Multi-writer API HA. -- Public container build, signing, publishing, and image verification. -- Long-lived maintenance, adoption, contributor diversity, external review, - and user feedback. - -Claims still only intended or documented: - -- Broad self-hosted production readiness for most uses. -- Regulated production readiness. -- Air-gapped production beyond package/export mechanics and docs. -- Hosted SaaS readiness. -- Native HSM custody beyond gateway-backed or provider-specific executor paths. -- Provider-specific group synchronization and management API verification. - -Evidence that would raise confidence: - -- A stable public release line after at least one more release-candidate cycle. -- Public, signed container images with immutable digests. -- A clean public verification workflow that downloads release assets from - GitHub and verifies them end to end. -- A published backup/restore rehearsal with object-store pairing. -- A small real deployment case study or maintainer-operated pilot report. -- CII/OpenSSF Best Practices badge or external security/design review. -- More PRs merged through branch-protected review rather than maintainer direct - pushes. -- Clear policy on signed commits and branch admin enforcement. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9eb175a..6b614e9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -22,8 +22,8 @@ project under terms compatible with this model. Before opening a change: -1. Read `AGENTS.md`, `.initial_design.md`, `README.md`, `openapi.yaml`, and the - relevant docs under `docs/`. +1. Read `AGENTS.md`, `README.md`, `openapi.yaml`, + `docs/reference/source-of-truth.md`, and the relevant docs under `docs/`. 2. Keep OpenAPI, tests, migrations, docs, SDK artifacts, examples, deployment files, and release evidence aligned when behavior changes. 3. Preserve tenant isolation, append-only evidence behavior, idempotency, diff --git a/docs/README.md b/docs/README.md index 41fb557..daec375 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,6 @@ # Evydence Documentation -This documentation is organized by reader task. Implementation claims should be backed by committed code, `openapi.yaml`, tests, deployment files, or Makefile targets. `.initial_design.md` remains design intent. +This documentation is organized by reader task. Implementation claims should be backed by committed code, `openapi.yaml`, tests, deployment files, Makefile targets, and the canonical references listed in [Documentation source of truth](reference/source-of-truth.md). ## Start Here diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 3a2ce56..a48a3b6 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -173,9 +173,8 @@ Do not describe an Evydence build as broadly self-hosted production-ready until: ## Remaining Production Maturity Backlog -These items are tracked separately from the feature-completeness checklist in -`.implementation_increments.md` because they are hardening work on already -implemented capabilities: +These items are tracked here and in [Roadmap and release cadence](roadmap.md) +because they are hardening work on already implemented capabilities: - Continue splitting the large application ledger into focused services while preserving the dependency-ordered relational persistence paths now in place. From ae698b4382045ed544b24714be4b92b00a07530d Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:00:56 +0300 Subject: [PATCH 173/287] docs(productization): lead with VEX-first evaluation path --- README.md | 54 +++++++++++++------ .../end-to-end-release-evidence/README.md | 51 +++++++++++++++--- 2 files changed, 81 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 3662962..90dfa0f 100644 --- a/README.md +++ b/README.md @@ -7,22 +7,42 @@ ![OpenAPI](https://img.shields.io/badge/OpenAPI-166%20precise%20operations-brightgreen.svg) ![Coverage Gate](https://img.shields.io/badge/coverage%20gate-80%25+-brightgreen.svg) -Evydence is a self-hosted release evidence ledger that helps software teams -collect, verify, and share tamper-evident technical evidence for each release. - -It is for security, platform, AppSec, and compliance-readiness teams at B2B -software companies that need customer-reviewable release evidence without -handing all release trust data to a SaaS GRC platform. - -Before shipping a release, Evydence can collect SBOMs, vulnerability scans, VEX -decisions, build/source/deployment evidence, controls, exceptions, release -bundles, and customer-safe packages, then show readiness gaps, assumptions, and -limitations. +Evydence is a self-hosted, API-first release evidence ledger for product +security, AppSec, platform, release engineering, and compliance-readiness teams +that need to answer customer CVE, SBOM, provenance, and release-review +questions with signed, customer-safe release evidence bundles. + +The concrete buyer question is: "This CVE appears in your SBOM for this +release. Are you affected, why or why not, who approved that decision, and what +evidence can we verify?" Evydence records the SBOM, vulnerability scan, VEX or +manual decision, build provenance, artifact digest, exceptions, release bundle, +and customer package that support the answer. + +Before Evydence, teams often stitch together scanner exports, CI logs, Slack +approvals, spreadsheets, object-storage folders, and one-off customer answers. +After Evydence, the same release has tenant-scoped API records, append-only +decisions, tamper-evident audit entries, signed bundles, reproducible reports, +and scoped packages that state gaps, assumptions, exceptions, and limitations. It does not make legal compliance conclusions, grant certification, prove SBOM completeness, treat scanner findings as authoritative, or guarantee release security. +## What Question Does Evydence Answer? + +Evydence is designed to make release-risk answers traceable to concrete +objects instead of unsupported prose: + +| Customer or internal review question | Evydence object that carries the answer | +| --- | --- | +| Are we affected by `CVE-X` in release `Y`? | Vulnerability finding plus VEX/manual decision, exception, or remediation record linked to the release. | +| Which SBOM was used for this answer? | SBOM record linked to the release and artifact, with raw payload hash and object reference. | +| Which scanner result raised the finding? | Vulnerability scan and normalized finding record with scanner metadata. | +| Who approved or recorded the decision? | Append-only vulnerability decision, exception, approval, and audit-chain entries with actor context. | +| What evidence supports "not affected" or "fixed"? | VEX impact/action statements, linked evidence, artifact digest, build provenance, and verification receipts. | +| What can be safely shared with a customer? | Redaction profile, customer package, evidence bundle, and package manifest with limitations. | +| How can the customer verify the package? | Signed release bundle, package manifest hash, OpenAPI-backed API records, audit-chain verification, and offline verifier paths. | + ## Current Limitations - Current status is a controlled self-hosted production candidate for @@ -81,13 +101,15 @@ amd64, run: make public-release-verify TAG=v0.1.0-rc.4 ``` -The end-to-end evidence flow to evaluate first is: +The VEX-first evidence flow to evaluate first is: 1. Create a product, release, and artifact. -2. Upload SBOM and vulnerability scan evidence. -3. Record a VEX decision or exception for an intentionally blocking finding. -4. Generate a release bundle and readiness report. -5. Export a customer-safe package or evidence bundle for review. +2. Upload SBOM evidence for the artifact. +3. Upload vulnerability scan evidence for the release. +4. Record a VEX decision or approved exception for an intentionally blocking finding. +5. Generate a release-readiness report. +6. Create a signed release bundle and customer-safe package or evidence bundle. +7. View the package locally and verify the bundle, package manifest, and audit chain. For a visual preview of the customer-package review surface, see the [package viewer guide](docs/how-to/view-packages.md). The preview uses diff --git a/examples/end-to-end-release-evidence/README.md b/examples/end-to-end-release-evidence/README.md index 61616d1..9673645 100644 --- a/examples/end-to-end-release-evidence/README.md +++ b/examples/end-to-end-release-evidence/README.md @@ -1,13 +1,16 @@ # End-To-End Release Evidence Example -This example shows the product path Evydence should make easy to evaluate: - -1. CI builds an artifact and computes a digest. -2. CI uploads build provenance, SBOM, and vulnerability scan evidence. -3. Security records a VEX decision or approved exception for a blocking - finding. -4. Evydence creates a release bundle and readiness report. -5. Evydence exports customer-safe review evidence. +This example shows the VEX-first product path Evydence should make easy to +evaluate: + +1. Create a product, release, and artifact. +2. Upload SBOM evidence for the artifact. +3. Upload vulnerability scan evidence for the release. +4. Record a VEX-style decision or approved exception for a blocking finding. +5. Generate a release-readiness report. +6. Create a signed release bundle and customer-safe package or evidence bundle. +7. View the package locally and verify the bundle, package manifest, and audit + chain. The files in this directory are non-sensitive fixtures. They are not legal compliance proof, certification, complete SBOM proof, authoritative @@ -72,3 +75,35 @@ The script creates a product, release, artifact, SBOM, vulnerability scan, vulnerability decision, release bundle, redaction profile, customer package, readiness report, and audit-chain verification output. It expects a local API that already has a tenant and scoped API key. + +## Inspect The Result + +The generated files under `tmp/end-to-end-release-evidence/` map the buyer +question to concrete Evydence records: + +- `sbom.json`: which SBOM was used for the release answer. +- `vulnerability-scan.json`: which scanner result raised the finding. +- `vulnerability-decision.json`: why the finding is treated as not affected in + this demo. +- `release-readiness.json`: the readiness result, gaps, assumptions, and + limitations. +- `release-bundle.json`: the signed release bundle metadata. +- `customer-package.json`: the customer-safe package manifest. +- `audit-chain-verification.json`: audit-chain continuity verification. + +To visually inspect the customer-safe output, open +`site/package-viewer/index.html` and load `customer-package.json` from the demo +output directory. To verify the release bundle through the API, read the bundle +id from `release-bundle.json` and call: + +```sh +bundle_id="$(jq -r '.data.id' tmp/end-to-end-release-evidence/release-bundle.json)" +curl -fsS \ + -H "Authorization: Bearer $EVYDENCE_API_KEY" \ + "$EVYDENCE_URL/v1/release-bundles/${bundle_id}/verify" +``` + +Expected result: the API returns verification checks for the tenant-scoped +bundle. The demo output remains review evidence with explicit limitations; it +is not legal compliance proof, certification, complete SBOM proof, an +authoritative scanner result, or a secure-release guarantee. From 12a05bec76a92d69016933a88f4c8c286b929e8c Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:02:16 +0300 Subject: [PATCH 174/287] feat(decisions): add customer-safe lifecycle evidence links --- Makefile | 2 + cmd/evydence-worker/main.go | 15 ++ docs/README.md | 1 + docs/api.md | 16 +- docs/reference/vulnerability-decisions.md | 106 ++++++++ internal/adapters/httpapi/openapi.go | 6 + internal/adapters/httpapi/router.go | 14 +- internal/adapters/httpapi/router_test.go | 14 +- internal/adapters/postgres/store.go | 25 +- internal/adapters/postgres/store_test.go | 5 +- internal/app/governance_packages.go | 67 +++++ internal/app/ledger_test.go | 245 ++++++++++++++++++ internal/app/risk_workflows.go | 9 +- internal/app/vex.go | 111 +++++++- internal/domain/domain.go | 3 + ...rability_decision_customer_fields.down.sql | 5 + ...nerability_decision_customer_fields.up.sql | 5 + ...lnerability_decision_evidence_ids.down.sql | 2 + ...vulnerability_decision_evidence_ids.up.sql | 2 + openapi.yaml | 2 +- 20 files changed, 632 insertions(+), 23 deletions(-) create mode 100644 docs/reference/vulnerability-decisions.md create mode 100644 migrations/20260601000100_vulnerability_decision_customer_fields.down.sql create mode 100644 migrations/20260601000100_vulnerability_decision_customer_fields.up.sql create mode 100644 migrations/20260601000200_vulnerability_decision_evidence_ids.down.sql create mode 100644 migrations/20260601000200_vulnerability_decision_evidence_ids.up.sql diff --git a/Makefile b/Makefile index 042bdc9..79c3d39 100644 --- a/Makefile +++ b/Makefile @@ -135,6 +135,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @test -f docs/reference/configuration.md @test -f docs/reference/api-contract-matrix.md @test -f docs/reference/openapi.md + @test -f docs/reference/vulnerability-decisions.md @test -f docs/reference/observability.md @test -f docs/reference/capacity-and-failures.md @test -f docs/reference/benchmark-results.md @@ -172,6 +173,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod "reference/configuration.md" \ "reference/api-contract-matrix.md" \ "reference/openapi.md" \ + "reference/vulnerability-decisions.md" \ "reference/observability.md" \ "reference/capacity-and-failures.md" \ "reference/benchmark-results.md" \ diff --git a/cmd/evydence-worker/main.go b/cmd/evydence-worker/main.go index ae791dd..9af1d2b 100644 --- a/cmd/evydence-worker/main.go +++ b/cmd/evydence-worker/main.go @@ -814,14 +814,21 @@ func applyReplayedVEXDecisions(state *app.PersistedState, job postgres.ClaimedJo Justification: statement.Justification, ImpactStatement: statement.ImpactStatement, ActionStatement: statement.ActionStatement, + CustomerVisible: strings.TrimSpace(statement.ImpactStatement) != "", Source: "vex", EvidenceID: evidenceID, + EvidenceIDs: workerDecisionEvidenceIDs(evidenceID), VEXDocumentID: vex.ID, Supersedes: supersedes, ApprovedBy: actorID, SchemaVersion: domain.VulnerabilityDecisionVersion, CreatedAt: now, } + if supersedes != "" { + if _, err := app.AppendPersistedChainEntry(state, now, job.TenantID, "vulnerability_decision.superseded", "vulnerability_decision", supersedes, actorType, actorID, payloadHash, ""); err != nil { + return created, errors.New("append replayed vex decision supersession audit entry") + } + } if _, err := app.AppendPersistedChainEntry(state, now, job.TenantID, "vulnerability_decision.created", "vulnerability_finding", finding.ID, actorType, actorID, payloadHash, ""); err != nil { return created, errors.New("append replayed vex decision audit entry") } @@ -849,6 +856,14 @@ func replayedVEXDecisionID(vexID, findingID, status string) string { return "vd_" + sum } +func workerDecisionEvidenceIDs(evidenceID string) []string { + evidenceID = strings.TrimSpace(evidenceID) + if evidenceID == "" { + return nil + } + return []string{evidenceID} +} + func verifyReplayedAttestation(raw []byte, parsed replayedAttestation, attestation domain.BuildAttestation) error { if attestation.PayloadHash != "" && digestBytes(raw) != attestation.PayloadHash { return errors.New("replayed build attestation payload does not match durable state") diff --git a/docs/README.md b/docs/README.md index daec375..9ff16ef 100644 --- a/docs/README.md +++ b/docs/README.md @@ -27,6 +27,7 @@ This documentation is organized by reader task. Implementation claims should be - [Documentation source of truth](reference/source-of-truth.md): canonical source map to keep commands, status, and limitations from drifting. - [API contract matrix](reference/api-contract-matrix.md): generated route-by-route contract precision inventory for production hardening. - [OpenAPI contract](reference/openapi.md): generation, drift checks, and review tips for `openapi.yaml`. +- [Vulnerability decisions](reference/vulnerability-decisions.md): current VEX/decision model, buyer-facing gaps, and planned API changes. - [Observability](reference/observability.md): readiness, admin metrics, Prometheus rules, and dashboard starter assets. - [Capacity and failure modes](reference/capacity-and-failures.md): supported concurrency profile, sizing inputs, and failure behavior. - [Benchmark results](reference/benchmark-results.md): current local benchmark command and interpretation. diff --git a/docs/api.md b/docs/api.md index 4feac20..def5634 100644 --- a/docs/api.md +++ b/docs/api.md @@ -163,11 +163,23 @@ POST /v1/vulnerability-findings/{id}/decisions ```json { "status": "not_affected", - "justification": "vulnerable code path is not present" + "justification": "vulnerable code path is not present", + "impact_statement": "This release is not affected because the vulnerable runtime code is not included.", + "action_statement": "No customer action is required for this finding.", + "customer_visible": true, + "internal_notes": "tenant-internal triage note", + "evidence_ids": ["ev_supporting_review"] } ``` -Supported decision statuses are `affected`, `not_affected`, `fixed`, and `under_investigation`. +Supported decision statuses are `affected`, `not_affected`, `fixed`, and +`under_investigation`. Customer-visible decisions require +`impact_statement`; `internal_notes` are tenant-internal and must not be copied +into customer-safe package summaries. A later decision for the same finding +supersedes the previous active decision and records audit-chain entries for the +supersession and replacement. `evidence_ids` may reference tenant-scoped +supporting evidence from the same release; foreign-tenant or wrong-release +evidence links are rejected. ### 4. Readiness And Bundle Retrieval diff --git a/docs/reference/vulnerability-decisions.md b/docs/reference/vulnerability-decisions.md new file mode 100644 index 0000000..c0df1c5 --- /dev/null +++ b/docs/reference/vulnerability-decisions.md @@ -0,0 +1,106 @@ +# Vulnerability Decisions + +This reference records the current VEX and vulnerability-decision model so +future changes can be made from observed gaps instead of assumptions. It is a +product and API design reference; it does not claim legal compliance, +certification, complete SBOM coverage, authoritative scanner results, or release +security. + +## Current Objects + +`VEXDocument` records an uploaded VEX payload: + +| Capability | Current support | +| --- | --- | +| Format | `openvex` and `cyclonedx` metadata are recorded. | +| Release and artifact scope | `release_id` is required for OpenVEX upload; `artifact_id` is optional. | +| Raw payload preservation | Raw bytes are stored in object storage through the evidence item payload reference and hash. | +| Import linkage | The VEX document links to the created evidence item through `evidence_id`. | +| Statement summary | Author, version, statement count, and status summary are recorded when parsed. | +| Parser replay | Worker-owned parser mode can defer normalized VEX fields and OpenVEX-derived decisions to the outbox worker. | + +`VulnerabilityDecision` records the operational answer for one normalized scan +finding: + +| Capability | Current support | +| --- | --- | +| Vulnerability ID | `vulnerability` is copied from the finding. | +| Source scanner | Indirect through `scan_id`; scanner metadata is on the vulnerability scan. | +| Affected component/package/PURL | `component` is copied from the finding. | +| Product/release scope | `release_id` is copied from the scan; product scope is indirect through the release. | +| Status | `affected`, `not_affected`, `fixed`, and `under_investigation`. | +| Justification | Required for manual decisions and imported from VEX where available. | +| Customer-safe impact/action text | `impact_statement` and `action_statement` exist. `impact_statement` is required when `customer_visible` is true. | +| Customer visibility | `customer_visible` marks decisions eligible for customer-safe package summaries. | +| Internal notes | `internal_notes` stores tenant-internal context separately from customer-safe impact text. | +| Approver/actor | `approved_by` stores the actor id for API/OpenVEX-created decisions. | +| Supersession | Creating a new decision for the same finding marks the prior active decision with `superseded_by` and sets `supersedes` on the new decision. | +| Source VEX/import | `vex_document_id` and `evidence_id` link imported decisions to the VEX document and evidence item. | +| Scan finding link | `finding_id` and `scan_id` link the decision to the normalized finding. | +| Supporting evidence links | `evidence_ids` can link tenant-scoped supporting evidence from the same release. | +| Audit history | Decision creation appends an audit-chain entry. | + +## Canonical Lifecycle + +The current canonical decision statuses intentionally match the OpenVEX statuses +Evydence already ingests: + +| Status | Meaning in Evydence | +| --- | --- | +| `under_investigation` | The finding is still being reviewed for this release. | +| `affected` | The release is treated as affected until remediation, exception, or a later decision changes the state. | +| `not_affected` | The recorded evidence says the release is not affected. Customer-visible decisions require `impact_statement`. | +| `fixed` | The recorded evidence says the finding is fixed for this release. Customer-visible decisions require `impact_statement`. | + +Decisions are append-only. Creating a later decision for the same finding marks +the previous active decision with `superseded_by`, sets `supersedes` on the new +decision, appends `vulnerability_decision.superseded` for the prior decision, +and appends `vulnerability_decision.created` for the replacement. The current +transition table permits any canonical status to be superseded by any canonical +status because VEX imports and manual corrections may revise earlier analysis. +Unknown statuses are rejected. Additional statuses such as `accepted_risk`, +`false_positive`, and `will_not_fix` are not accepted until a later API version +decides whether they belong in decisions or in exceptions/waivers. + +Customer package manifests include only active decisions unless a future +history-specific export is requested. + +## Current Gaps + +The current model is enough to support release-readiness gating, but it is not +yet the full buyer-facing VEX decision workflow: + +- There is no first-class decision history endpoint. History exists in stored + decision records through `supersedes` and `superseded_by`, but clients cannot + query it directly by product, release, vulnerability, component, active + status, or supersession state. +- Customer package manifests can include active `customer_visible` decision + summaries when the redaction profile explicitly allows + `vulnerability_decision`. They exclude `internal_notes`, raw payload bytes, + and bearer secrets. +- There is no review date or expiry on a decision. Expiry behavior currently + lives on exceptions and waivers, not decisions. +- Supporting evidence links currently reference evidence-item records. Links to + first-class non-evidence resources such as remediation tasks, approvals, + exceptions, release bundles, or incident packages still need explicit link + modeling or evidence wrappers before they can be attached directly. +- The source SBOM is indirect through release/artifact relationships rather + than a direct `sbom_id` link. +- Customer package exports can include package-scoped decision metadata, but a + dedicated customer-safe decision-summary endpoint does not exist. + +## Concrete Follow-Up Changes + +The productization backlog should add these changes in order: + +1. Decide whether `accepted_risk`, `false_positive`, and `will_not_fix` should + be separate statuses or represented by exceptions/waivers. +2. Add first-class decision links for non-evidence resources that should not be + wrapped as evidence items. +3. Add a decision history endpoint with filters for product, release, + vulnerability, component, status, and active/superseded state. +4. Add a customer-safe release decision summary endpoint for package viewer and + export use. + +These follow-ups should update OpenAPI, HTTP tests, package export tests, and +docs together. diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 23f5acc..51c1fb9 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -296,6 +296,9 @@ func registerCriticalSchemas(registry *specs.Registry) { "justification": map[string]any{"type": "string"}, "impact_statement": map[string]any{"type": "string"}, "action_statement": map[string]any{"type": "string"}, + "customer_visible": map[string]any{"type": "boolean"}, + "internal_notes": map[string]any{"type": "string", "description": "Tenant-internal notes; excluded from customer-safe package summaries."}, + "evidence_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, }, "status", "justification")) registry.RegisterSchema("VulnerabilityDecision", objectSchema(map[string]any{ "id": map[string]any{"type": "string"}, @@ -309,8 +312,11 @@ func registerCriticalSchemas(registry *specs.Registry) { "justification": map[string]any{"type": "string"}, "impact_statement": map[string]any{"type": "string"}, "action_statement": map[string]any{"type": "string"}, + "customer_visible": map[string]any{"type": "boolean"}, + "internal_notes": map[string]any{"type": "string", "description": "Tenant-internal notes; do not include in customer-safe exports."}, "source": map[string]any{"type": "string"}, "evidence_id": map[string]any{"type": "string"}, + "evidence_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, "vex_document_id": map[string]any{"type": "string"}, "supersedes": map[string]any{"type": "string"}, "superseded_by": map[string]any{"type": "string"}, diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index 1bcdca3..284ada1 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -1469,10 +1469,13 @@ func (s *Server) getVulnerabilityScan(w http.ResponseWriter, r *http.Request) { func (s *Server) createVulnerabilityDecision(w http.ResponseWriter, r *http.Request) { var req struct { - Status string `json:"status"` - Justification string `json:"justification"` - ImpactStatement string `json:"impact_statement"` - ActionStatement string `json:"action_statement"` + Status string `json:"status"` + Justification string `json:"justification"` + ImpactStatement string `json:"impact_statement"` + ActionStatement string `json:"action_statement"` + CustomerVisible bool `json:"customer_visible"` + InternalNotes string `json:"internal_notes"` + EvidenceIDs []string `json:"evidence_ids"` } s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { @@ -1483,6 +1486,9 @@ func (s *Server) createVulnerabilityDecision(w http.ResponseWriter, r *http.Requ Justification: req.Justification, ImpactStatement: req.ImpactStatement, ActionStatement: req.ActionStatement, + CustomerVisible: req.CustomerVisible, + InternalNotes: req.InternalNotes, + EvidenceIDs: req.EvidenceIDs, }) return http.StatusCreated, decision, err }) diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index f72f833..40cd412 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -614,6 +614,11 @@ func TestReleaseRiskDecisionHTTPFlow(t *testing.T) { "findings": []map[string]any{{"vulnerability": "CVE-2026-0099", "component": "pkg:apk/openssl@3.1.0", "severity": "critical", "state": "open"}}, }, http.StatusCreated) findingID := firstFindingID(t, scanBody) + evidenceBody := postJSON(t, server, secret, "/v1/evidence", "risk-supporting-evidence", map[string]any{ + "product_id": productID, "release_id": releaseID, "type": "security_review", "title": "Runtime review", + "payload_hash": "sha256:44575cf5b2853284ce5d55751bc9e87d165bd64d5ef12c55fa291e9d40afae86", + }, http.StatusCreated) + evidenceID := dataField(t, evidenceBody, "id") postJSON(t, server, secret, "/v1/release-bundles", "risk-bundle", map[string]any{"release_id": releaseID}, http.StatusCreated) addHTTPBuildProvenance(t, server, secret, productID, releaseID, artifactID, "sha256:ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb") @@ -621,8 +626,13 @@ func TestReleaseRiskDecisionHTTPFlow(t *testing.T) { if !strings.Contains(report, `"result":"failed"`) || !strings.Contains(report, `"blocking_findings"`) { t.Fatalf("expected failed readiness report with blocking findings: %s", report) } - decisionBody := postJSON(t, server, secret, "/v1/vulnerability-findings/"+findingID+"/decisions", "risk-decision", map[string]any{"status": "not_affected", "justification": "vulnerable code is not present"}, http.StatusCreated) - replayed := postJSON(t, server, secret, "/v1/vulnerability-findings/"+findingID+"/decisions", "risk-decision", map[string]any{"status": "not_affected", "justification": "vulnerable code is not present"}, http.StatusCreated) + postJSON(t, server, secret, "/v1/vulnerability-findings/"+findingID+"/decisions", "risk-decision-bad", map[string]any{"status": "not_affected", "justification": "vulnerable code is not present", "customer_visible": true}, http.StatusBadRequest) + decisionPayload := map[string]any{"status": "not_affected", "justification": "vulnerable code is not present", "impact_statement": "The vulnerable code path is not present in this release.", "customer_visible": true, "internal_notes": "private note", "evidence_ids": []string{evidenceID}} + decisionBody := postJSON(t, server, secret, "/v1/vulnerability-findings/"+findingID+"/decisions", "risk-decision", decisionPayload, http.StatusCreated) + if !strings.Contains(decisionBody, `"customer_visible":true`) || !strings.Contains(decisionBody, `"internal_notes":"private note"`) || !strings.Contains(decisionBody, evidenceID) { + t.Fatalf("decision response missing customer visibility/internal note fields: %s", decisionBody) + } + replayed := postJSON(t, server, secret, "/v1/vulnerability-findings/"+findingID+"/decisions", "risk-decision", decisionPayload, http.StatusCreated) if replayed != decisionBody { t.Fatalf("decision idempotency replay changed response\nfirst=%s\nsecond=%s", decisionBody, replayed) } diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index a54b3ea..5fd0c3d 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -1113,8 +1113,8 @@ func (s *Store) loadRelationalRiskDecisions(ctx context.Context, state *app.Pers decisionRows, err := s.pool.Query(ctx, ` SELECT id, tenant_id, finding_id, scan_id, release_id, vulnerability, component, status, justification, impact_statement, action_statement, - source, evidence_id, vex_document_id, supersedes, superseded_by, - approved_by, schema_version, created_at + customer_visible, internal_notes, source, evidence_id, evidence_ids, vex_document_id, + supersedes, superseded_by, approved_by, schema_version, created_at FROM vulnerability_decisions `) if err != nil { @@ -1123,11 +1123,11 @@ func (s *Store) loadRelationalRiskDecisions(ctx context.Context, state *app.Pers defer decisionRows.Close() for decisionRows.Next() { var decision domain.VulnerabilityDecision - var releaseID, component, impactStatement, actionStatement, evidenceID, vexDocumentID, supersedes, supersededBy, approvedBy sql.NullString + var releaseID, component, impactStatement, actionStatement, internalNotes, evidenceID, vexDocumentID, supersedes, supersededBy, approvedBy sql.NullString if err := decisionRows.Scan( &decision.ID, &decision.TenantID, &decision.FindingID, &decision.ScanID, &releaseID, &decision.Vulnerability, &component, &decision.Status, &decision.Justification, &impactStatement, &actionStatement, - &decision.Source, &evidenceID, &vexDocumentID, &supersedes, &supersededBy, + &decision.CustomerVisible, &internalNotes, &decision.Source, &evidenceID, &decision.EvidenceIDs, &vexDocumentID, &supersedes, &supersededBy, &approvedBy, &decision.SchemaVersion, &decision.CreatedAt, ); err != nil { return fmt.Errorf("scan relational vulnerability decision: %w", err) @@ -1136,6 +1136,7 @@ func (s *Store) loadRelationalRiskDecisions(ctx context.Context, state *app.Pers decision.Component = nullableSQLString(component) decision.ImpactStatement = nullableSQLString(impactStatement) decision.ActionStatement = nullableSQLString(actionStatement) + decision.InternalNotes = nullableSQLString(internalNotes) decision.EvidenceID = nullableSQLString(evidenceID) decision.VEXDocumentID = nullableSQLString(vexDocumentID) decision.Supersedes = nullableSQLString(supersedes) @@ -3179,21 +3180,27 @@ func syncRiskBuildControlRows(ctx context.Context, tx pgx.Tx, state app.Persiste INSERT INTO vulnerability_decisions ( id, tenant_id, finding_id, scan_id, release_id, vulnerability, component, status, justification, impact_statement, action_statement, - source, evidence_id, vex_document_id, supersedes, superseded_by, - approved_by, schema_version, created_at + customer_visible, internal_notes, source, evidence_id, evidence_ids, vex_document_id, + supersedes, superseded_by, approved_by, schema_version, created_at ) VALUES ( $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, - $17, $18, $19 + $17, $18, $19, $20, $21, $22 ) ON CONFLICT (id) DO UPDATE SET superseded_by = EXCLUDED.superseded_by, - approved_by = EXCLUDED.approved_by + approved_by = EXCLUDED.approved_by, + customer_visible = vulnerability_decisions.customer_visible OR EXCLUDED.customer_visible, + internal_notes = COALESCE(NULLIF(vulnerability_decisions.internal_notes, ''), EXCLUDED.internal_notes), + evidence_ids = CASE + WHEN cardinality(vulnerability_decisions.evidence_ids) = 0 THEN EXCLUDED.evidence_ids + ELSE vulnerability_decisions.evidence_ids + END `, decision.ID, decision.TenantID, decision.FindingID, decision.ScanID, nullableString(decision.ReleaseID), decision.Vulnerability, nullableString(decision.Component), decision.Status, decision.Justification, nullableString(decision.ImpactStatement), nullableString(decision.ActionStatement), - decision.Source, nullableString(decision.EvidenceID), nullableString(decision.VEXDocumentID), nullableString(decision.Supersedes), nullableString(decision.SupersededBy), + decision.CustomerVisible, nullableString(decision.InternalNotes), decision.Source, nullableString(decision.EvidenceID), decision.EvidenceIDs, nullableString(decision.VEXDocumentID), nullableString(decision.Supersedes), nullableString(decision.SupersededBy), nullableString(decision.ApprovedBy), decision.SchemaVersion, nonZeroTime(decision.CreatedAt)); err != nil { return fmt.Errorf("upsert vulnerability decision row: %w", err) } diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index 0ff6ce0..ff6b205 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -928,7 +928,8 @@ func TestApplyCriticalMutationWithPostgres(t *testing.T) { VulnerabilityDecisions: []domain.VulnerabilityDecision{{ ID: "decision_focus", TenantID: "ten_focus", FindingID: "finding_focus", ScanID: "scan_focus", ReleaseID: "rel_focus", Vulnerability: "CVE-2099-0001", Component: "pkg:generic/api", - Status: "not_affected", Justification: "component_not_present", Source: "manual", + Status: "not_affected", Justification: "component_not_present", ImpactStatement: "not shipped", + CustomerVisible: true, InternalNotes: "private triage", EvidenceIDs: []string{"ev_support"}, Source: "manual", SchemaVersion: domain.VulnerabilityDecisionVersion, CreatedAt: now, }}, AuditChainEntries: []domain.AuditChainEntry{{ @@ -980,7 +981,7 @@ func TestApplyCriticalMutationWithPostgres(t *testing.T) { {name: "signature", query: `SELECT count(*) FROM signatures WHERE id = 'sig_focus' AND key_id = 'sigkey_focus'`}, {name: "bundle", query: `SELECT count(*) FROM release_bundles WHERE id = 'bundle_focus' AND signature_refs = '["sig_focus"]'::jsonb`}, {name: "verification", query: `SELECT count(*) FROM verification_results WHERE id = 'verify_focus' AND result = 'passed'`}, - {name: "decision", query: `SELECT count(*) FROM vulnerability_decisions WHERE id = 'decision_focus' AND status = 'not_affected'`}, + {name: "decision", query: `SELECT count(*) FROM vulnerability_decisions WHERE id = 'decision_focus' AND status = 'not_affected' AND customer_visible = true AND internal_notes = 'private triage' AND evidence_ids = ARRAY['ev_support']::text[]`}, {name: "outbox", query: `SELECT count(*) FROM outbox_jobs WHERE id = 'job_focus' AND status = 'queued'`}, {name: "resource index", query: `SELECT count(*) FROM resource_index WHERE tenant_id = 'ten_focus' AND resource_type = 'release_bundle' AND resource_id = 'bundle_focus'`}, } diff --git a/internal/app/governance_packages.go b/internal/app/governance_packages.go index fff3766..9eb7638 100644 --- a/internal/app/governance_packages.go +++ b/internal/app/governance_packages.go @@ -266,6 +266,9 @@ func (s packageReportService) CreateCustomerSecurityPackage(ctx context.Context, "evidence_ids": evidenceIDs, "limitations": []string{"Package contents are scoped and redacted; raw evidence payload bytes are not included in this manifest."}, } + if decisions := l.packageDecisionSummariesLocked(actor.TenantID, in.ReleaseID, profile); len(decisions) > 0 { + manifest["vulnerability_decisions"] = decisions + } hash, err := canonicalAnyHash(manifest) if err != nil { return domain.CustomerSecurityPackage{}, err @@ -748,6 +751,70 @@ func (l *Ledger) packageEvidenceIDsLocked(tenantID, productID, releaseID string, return ids } +func (l *Ledger) packageDecisionSummariesLocked(tenantID, releaseID string, profile domain.RedactionProfile) []map[string]any { + if !profileAllowsPackageType(profile, "vulnerability_decision") { + return nil + } + excluded := profileExcludedFields(profile) + summaries := []map[string]any{} + for _, decision := range l.decisions { + if decision.TenantID != tenantID || decision.ReleaseID != releaseID || decision.SupersededBy != "" || !decision.CustomerVisible { + continue + } + summary := map[string]any{ + "id": decision.ID, + "finding_id": decision.FindingID, + "scan_id": decision.ScanID, + "release_id": decision.ReleaseID, + "vulnerability": decision.Vulnerability, + "component": decision.Component, + "status": decision.Status, + "impact_statement": decision.ImpactStatement, + "source": decision.Source, + "created_at": decision.CreatedAt.UTC().Format(time.RFC3339), + } + if decision.ActionStatement != "" && !excluded["action_statement"] { + summary["action_statement"] = decision.ActionStatement + } + if decision.Justification != "" && !excluded["justification"] { + summary["justification"] = decision.Justification + } + if decision.EvidenceID != "" && !excluded["evidence_id"] { + summary["evidence_id"] = decision.EvidenceID + } + if decision.VEXDocumentID != "" && !excluded["vex_document_id"] { + summary["vex_document_id"] = decision.VEXDocumentID + } + if len(decision.EvidenceIDs) > 0 && !excluded["evidence_ids"] { + summary["evidence_ids"] = append([]string(nil), decision.EvidenceIDs...) + } + summaries = append(summaries, summary) + } + sort.Slice(summaries, func(i, j int) bool { + left := summaries[i]["vulnerability"].(string) + "\x00" + summaries[i]["id"].(string) + right := summaries[j]["vulnerability"].(string) + "\x00" + summaries[j]["id"].(string) + return left < right + }) + return summaries +} + +func profileAllowsPackageType(profile domain.RedactionProfile, typ string) bool { + for _, allowed := range profile.AllowedTypes { + if strings.TrimSpace(allowed) == typ { + return true + } + } + return false +} + +func profileExcludedFields(profile domain.RedactionProfile) map[string]bool { + excluded := map[string]bool{} + for _, field := range profile.ExcludedFields { + excluded[strings.TrimSpace(field)] = true + } + return excluded +} + func builtinTemplatePacks() []domain.ControlFrameworkTemplatePack { return []domain.ControlFrameworkTemplatePack{ {ID: "tpl_cra_readiness", Name: "Evydence CRA Readiness", Slug: "evydence-cra-readiness", Version: "2026.05", Description: "Starter technical evidence controls for CRA readiness tracking.", SchemaVersion: "control-framework-template-pack.v1.0.0", Controls: []domain.SecurityControl{ diff --git a/internal/app/ledger_test.go b/internal/app/ledger_test.go index 7e6a1c2..5471575 100644 --- a/internal/app/ledger_test.go +++ b/internal/app/ledger_test.go @@ -671,6 +671,251 @@ func TestReleaseReadinessRequiresHandledCriticalFinding(t *testing.T) { } } +func TestCustomerVisibleDecisionRequiresImpactAndRedactsInternalNotes(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, release, _ := setupReleaseRiskFixture(t, ledger) + scan, err := ledger.UploadVulnerabilityScan(ctx, actor, []byte(`{ + "scanner":"grype", + "target_ref":"pkg:oci/payments-api", + "release_id":"`+release.ID+`", + "findings":[{"vulnerability":"CVE-2026-0100","component":"pkg:apk/openssl@3.1.0","severity":"critical","state":"open"}] + }`)) + if err != nil { + t.Fatalf("scan: %v", err) + } + if _, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{ + Status: decisionStatusNotAffected, + Justification: "runtime code path is not present", + CustomerVisible: true, + InternalNotes: "private triage note", + }); !errors.Is(err, ErrValidation) { + t.Fatalf("customer-visible decision without impact err=%v, want validation", err) + } + decision, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{ + Status: decisionStatusNotAffected, + Justification: "runtime code path is not present", + ImpactStatement: "This release is not affected because the vulnerable runtime code is not included.", + ActionStatement: "No customer action is required for this finding.", + CustomerVisible: true, + InternalNotes: "private triage note", + }) + if err != nil { + t.Fatalf("decision: %v", err) + } + if !decision.CustomerVisible || decision.InternalNotes != "private triage note" { + t.Fatalf("decision customer visibility/internal notes not preserved: %#v", decision) + } + profile, err := ledger.CreateRedactionProfile(ctx, actor, CreateRedactionProfileInput{Name: "customer decisions", AllowedTypes: []string{"vulnerability_decision"}}) + if err != nil { + t.Fatalf("redaction profile: %v", err) + } + pkg, err := ledger.CreateCustomerSecurityPackage(ctx, actor, CreateCustomerPackageInput{ + ProductID: release.ProductID, + ReleaseID: release.ID, + RedactionProfileID: profile.ID, + Title: "Customer decision package", + ExpiresAt: fixedNow().Add(time.Hour), + }) + if err != nil { + t.Fatalf("customer package: %v", err) + } + body, err := json.Marshal(pkg.Manifest) + if err != nil { + t.Fatalf("marshal package manifest: %v", err) + } + if !strings.Contains(string(body), decision.ImpactStatement) { + t.Fatalf("package manifest missing customer-safe impact statement: %s", body) + } + if strings.Contains(string(body), "private triage note") { + t.Fatalf("package manifest leaked internal notes: %s", body) + } +} + +func TestVulnerabilityDecisionLifecycleSupersedesAndPackagesOnlyActive(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, release, _ := setupReleaseRiskFixture(t, ledger) + scan, err := ledger.UploadVulnerabilityScan(ctx, actor, []byte(`{ + "scanner":"grype", + "target_ref":"pkg:oci/payments-api", + "release_id":"`+release.ID+`", + "findings":[{"vulnerability":"CVE-2026-0101","component":"pkg:apk/openssl@3.1.0","severity":"critical","state":"open"}] + }`)) + if err != nil { + t.Fatalf("scan: %v", err) + } + if _, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{ + Status: "not_a_status", + Justification: "bad status", + }); !errors.Is(err, ErrValidation) { + t.Fatalf("invalid lifecycle status err=%v, want validation", err) + } + first, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{ + Status: decisionStatusUnderInvestigation, + Justification: "triage started", + ImpactStatement: "The finding is under investigation.", + CustomerVisible: true, + InternalNotes: "initial private note", + }) + if err != nil { + t.Fatalf("first decision: %v", err) + } + second, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{ + Status: decisionStatusFixed, + Justification: "patched in release artifact", + ImpactStatement: "This issue is fixed in the release artifact.", + ActionStatement: "Upgrade to this release.", + CustomerVisible: true, + InternalNotes: "replacement private note", + }) + if err != nil { + t.Fatalf("second decision: %v", err) + } + if second.Supersedes != first.ID { + t.Fatalf("second supersedes=%q, want %q", second.Supersedes, first.ID) + } + if got := ledger.decisions[first.ID].SupersededBy; got != second.ID { + t.Fatalf("first superseded_by=%q, want %q", got, second.ID) + } + created, superseded := 0, 0 + for _, entry := range ledger.chain[actor.TenantID] { + switch { + case entry.EntryType == "vulnerability_decision.created" && entry.SubjectID == scan.Findings[0].ID: + created++ + case entry.EntryType == "vulnerability_decision.superseded" && entry.SubjectID == first.ID: + superseded++ + } + } + if created != 2 || superseded != 1 { + t.Fatalf("decision lifecycle audit counts created=%d superseded=%d", created, superseded) + } + profile, err := ledger.CreateRedactionProfile(ctx, actor, CreateRedactionProfileInput{Name: "active decisions", AllowedTypes: []string{"vulnerability_decision"}}) + if err != nil { + t.Fatalf("redaction profile: %v", err) + } + pkg, err := ledger.CreateCustomerSecurityPackage(ctx, actor, CreateCustomerPackageInput{ + ProductID: release.ProductID, + ReleaseID: release.ID, + RedactionProfileID: profile.ID, + Title: "Active decision package", + ExpiresAt: fixedNow().Add(time.Hour), + }) + if err != nil { + t.Fatalf("customer package: %v", err) + } + body, err := json.Marshal(pkg.Manifest) + if err != nil { + t.Fatalf("marshal package manifest: %v", err) + } + text := string(body) + if !strings.Contains(text, second.ImpactStatement) { + t.Fatalf("package manifest missing active impact statement: %s", body) + } + if strings.Contains(text, first.ImpactStatement) || strings.Contains(text, "private note") { + t.Fatalf("package manifest included superseded decision or internal notes: %s", body) + } +} + +func TestVulnerabilityDecisionEvidenceLinksAreTenantAndReleaseScoped(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, release, _ := setupReleaseRiskFixture(t, ledger) + supporting, err := ledger.CreateEvidence(ctx, actor, CreateEvidenceInput{ + ProductID: release.ProductID, ReleaseID: release.ID, Type: "security_review", Title: "Runtime review", PayloadHash: sampleDigest("supporting-review"), + }) + if err != nil { + t.Fatalf("supporting evidence: %v", err) + } + otherRelease, err := ledger.CreateRelease(ctx, actor, release.ProductID, "2.0.0") + if err != nil { + t.Fatalf("other release: %v", err) + } + wrongReleaseEvidence, err := ledger.CreateEvidence(ctx, actor, CreateEvidenceInput{ + ProductID: release.ProductID, ReleaseID: otherRelease.ID, Type: "security_review", Title: "Wrong release review", PayloadHash: sampleDigest("wrong-release-review"), + }) + if err != nil { + t.Fatalf("wrong release evidence: %v", err) + } + _, _, secretB, err := ledger.BootstrapTenant(ctx, "Tenant B", "admin-b", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap tenant B: %v", err) + } + actorB, err := ledger.Authenticate(ctx, secretB) + if err != nil { + t.Fatalf("authenticate tenant B: %v", err) + } + foreignEvidence, err := ledger.CreateEvidence(ctx, actorB, CreateEvidenceInput{Type: "security_review", Title: "Foreign review", PayloadHash: sampleDigest("foreign-review")}) + if err != nil { + t.Fatalf("foreign evidence: %v", err) + } + scan, err := ledger.UploadVulnerabilityScan(ctx, actor, []byte(`{ + "scanner":"grype", + "target_ref":"pkg:oci/payments-api", + "release_id":"`+release.ID+`", + "findings":[{"vulnerability":"CVE-2026-0102","component":"pkg:apk/openssl@3.1.0","severity":"critical","state":"open"}] + }`)) + if err != nil { + t.Fatalf("scan: %v", err) + } + if _, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{ + Status: decisionStatusNotAffected, + Justification: "reviewed runtime path", + ImpactStatement: "The vulnerable runtime path is not included.", + CustomerVisible: true, + EvidenceIDs: []string{wrongReleaseEvidence.ID}, + }); !errors.Is(err, ErrNotFound) { + t.Fatalf("wrong-release evidence link err=%v, want not found", err) + } + if _, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{ + Status: decisionStatusNotAffected, + Justification: "reviewed runtime path", + ImpactStatement: "The vulnerable runtime path is not included.", + CustomerVisible: true, + EvidenceIDs: []string{foreignEvidence.ID}, + }); !errors.Is(err, ErrNotFound) { + t.Fatalf("foreign evidence link err=%v, want not found", err) + } + decision, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{ + Status: decisionStatusNotAffected, + Justification: "reviewed runtime path", + ImpactStatement: "The vulnerable runtime path is not included.", + CustomerVisible: true, + EvidenceIDs: []string{supporting.ID, supporting.ID}, + }) + if err != nil { + t.Fatalf("decision: %v", err) + } + if len(decision.EvidenceIDs) != 1 || decision.EvidenceIDs[0] != supporting.ID { + t.Fatalf("decision evidence links = %#v, want %s", decision.EvidenceIDs, supporting.ID) + } + profile, err := ledger.CreateRedactionProfile(ctx, actor, CreateRedactionProfileInput{Name: "decision links", AllowedTypes: []string{"vulnerability_decision"}}) + if err != nil { + t.Fatalf("redaction profile: %v", err) + } + pkg, err := ledger.CreateCustomerSecurityPackage(ctx, actor, CreateCustomerPackageInput{ + ProductID: release.ProductID, + ReleaseID: release.ID, + RedactionProfileID: profile.ID, + Title: "Decision links package", + ExpiresAt: fixedNow().Add(time.Hour), + }) + if err != nil { + t.Fatalf("customer package: %v", err) + } + body, err := json.Marshal(pkg.Manifest) + if err != nil { + t.Fatalf("marshal package manifest: %v", err) + } + text := string(body) + if !strings.Contains(text, supporting.ID) { + t.Fatalf("customer package missing linked evidence id: %s", body) + } + if strings.Contains(text, wrongReleaseEvidence.ID) || strings.Contains(text, foreignEvidence.ID) { + t.Fatalf("customer package leaked unlinked/foreign evidence ids: %s", body) + } +} + func TestOpenVEXIngestionCreatesDecisionAndRejectsMalformedInput(t *testing.T) { ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) ctx := context.Background() diff --git a/internal/app/risk_workflows.go b/internal/app/risk_workflows.go index 90e0a89..af12161 100644 --- a/internal/app/risk_workflows.go +++ b/internal/app/risk_workflows.go @@ -877,8 +877,15 @@ func (l *Ledger) UploadCycloneDXVEX(ctx context.Context, actor domain.Actor, rel if finding.Vulnerability != vuln.ID { continue } - decision := domain.VulnerabilityDecision{ID: newID("vd"), TenantID: actor.TenantID, FindingID: finding.ID, ScanID: scan.ID, ReleaseID: releaseID, Vulnerability: finding.Vulnerability, Component: finding.Component, Status: status, Justification: nonEmpty(vuln.Analysis.Justification, "cyclonedx_vex"), ImpactStatement: vuln.Analysis.Detail, ActionStatement: strings.Join(vuln.Analysis.Response, ","), Source: "cyclonedx_vex", EvidenceID: item.ID, VEXDocumentID: vex.ID, SchemaVersion: domain.VulnerabilityDecisionVersion, CreatedAt: l.now()} + decision := l.createDecisionLocked(actor.TenantID, scan, finding, CreateVulnerabilityDecisionInput{ + Status: status, + Justification: nonEmpty(vuln.Analysis.Justification, "cyclonedx_vex"), + ImpactStatement: vuln.Analysis.Detail, + ActionStatement: strings.Join(vuln.Analysis.Response, ","), + CustomerVisible: strings.TrimSpace(vuln.Analysis.Detail) != "", + }, "cyclonedx_vex", actor.KeyID, item.ID, vex.ID) l.decisions[decision.ID] = decision + l.appendDecisionLifecycleAuditLocked(actor.TenantID, decision, finding.ID, "api_key", actor.KeyID, payloadHash) } } } diff --git a/internal/app/vex.go b/internal/app/vex.go index a6d68c9..1f13dcf 100644 --- a/internal/app/vex.go +++ b/internal/app/vex.go @@ -20,11 +20,21 @@ const ( decisionStatusUnderInvestigation = "under_investigation" ) +var decisionStatusTransitions = map[string]map[string]struct{}{ + decisionStatusAffected: decisionStatusSet(decisionStatusAffected, decisionStatusNotAffected, decisionStatusFixed, decisionStatusUnderInvestigation), + decisionStatusNotAffected: decisionStatusSet(decisionStatusAffected, decisionStatusNotAffected, decisionStatusFixed, decisionStatusUnderInvestigation), + decisionStatusFixed: decisionStatusSet(decisionStatusAffected, decisionStatusNotAffected, decisionStatusFixed, decisionStatusUnderInvestigation), + decisionStatusUnderInvestigation: decisionStatusSet(decisionStatusAffected, decisionStatusNotAffected, decisionStatusFixed, decisionStatusUnderInvestigation), +} + type CreateVulnerabilityDecisionInput struct { Status string Justification string ImpactStatement string ActionStatement string + CustomerVisible bool + InternalNotes string + EvidenceIDs []string } type CreateExceptionInput struct { @@ -165,9 +175,10 @@ func (s releaseEvidenceService) UploadVEX(ctx context.Context, actor domain.Acto Justification: statement.Justification, ImpactStatement: statement.ImpactStatement, ActionStatement: statement.ActionStatement, + CustomerVisible: strings.TrimSpace(statement.ImpactStatement) != "", }, "vex", actorID(actor), item.ID, vex.ID) l.decisions[decision.ID] = decision - _, _ = l.appendChainLocked(actor.TenantID, "vulnerability_decision.created", "vulnerability_finding", matched.finding.ID, actorType(actor), actorID(actor), payloadHash, "") + l.appendDecisionLifecycleAuditLocked(actor.TenantID, decision, matched.finding.ID, actorType(actor), actorID(actor), payloadHash) createdDecisions++ } } @@ -218,6 +229,12 @@ func (s releaseEvidenceService) CreateVulnerabilityDecision(ctx context.Context, if !validDecisionStatus(in.Status) || strings.TrimSpace(in.Justification) == "" { return domain.VulnerabilityDecision{}, ErrValidation } + if in.CustomerVisible && strings.TrimSpace(in.ImpactStatement) == "" { + return domain.VulnerabilityDecision{}, ErrValidation + } + if len(strings.TrimSpace(in.InternalNotes)) > 8192 { + return domain.VulnerabilityDecision{}, ErrValidation + } l.mu.Lock() defer l.mu.Unlock() scan, finding, ok := l.findFindingLocked(actor.TenantID, strings.TrimSpace(findingID)) @@ -227,9 +244,17 @@ func (s releaseEvidenceService) CreateVulnerabilityDecision(ctx context.Context, if err := l.authorizeResourceLocked(actor, ScopeEvidenceWrite, resourceRefs{ReleaseID: scan.ReleaseID}); err != nil { return domain.VulnerabilityDecision{}, err } + if latest, ok := l.latestDecisionForFindingLocked(actor.TenantID, finding.ID); ok && !validDecisionTransition(latest.Status, strings.TrimSpace(in.Status)) { + return domain.VulnerabilityDecision{}, ErrValidation + } + evidenceIDs, err := l.validateDecisionEvidenceLinksLocked(actor.TenantID, scan.ReleaseID, in.EvidenceIDs) + if err != nil { + return domain.VulnerabilityDecision{}, err + } + in.EvidenceIDs = evidenceIDs decision := l.createDecisionLocked(actor.TenantID, scan, finding, in, "api", actor.KeyID, "", "") l.decisions[decision.ID] = decision - _, _ = l.appendChainLocked(actor.TenantID, "vulnerability_decision.created", "vulnerability_finding", finding.ID, "api_key", actor.KeyID, "", "") + l.appendDecisionLifecycleAuditLocked(actor.TenantID, decision, finding.ID, "api_key", actor.KeyID, "") if err := l.persistCriticalLocked(ctx, l.criticalMutationLocked()); err != nil { return domain.VulnerabilityDecision{}, err } @@ -425,6 +450,27 @@ func validDecisionStatus(status string) bool { } } +func validDecisionTransition(from, to string) bool { + to = strings.TrimSpace(to) + if strings.TrimSpace(from) == "" { + return validDecisionStatus(to) + } + allowed, ok := decisionStatusTransitions[strings.TrimSpace(from)] + if !ok { + return false + } + _, ok = allowed[to] + return ok +} + +func decisionStatusSet(statuses ...string) map[string]struct{} { + set := map[string]struct{}{} + for _, status := range statuses { + set[status] = struct{}{} + } + return set +} + func versionString(version any) string { switch v := version.(type) { case string: @@ -500,8 +546,11 @@ func (l *Ledger) createDecisionLocked(tenantID string, scan domain.Vulnerability Justification: strings.TrimSpace(in.Justification), ImpactStatement: strings.TrimSpace(in.ImpactStatement), ActionStatement: strings.TrimSpace(in.ActionStatement), + CustomerVisible: in.CustomerVisible, + InternalNotes: strings.TrimSpace(in.InternalNotes), Source: source, EvidenceID: evidenceID, + EvidenceIDs: decisionEvidenceIDs(evidenceID, in.EvidenceIDs), VEXDocumentID: vexID, Supersedes: supersedes, ApprovedBy: actorID, @@ -511,6 +560,64 @@ func (l *Ledger) createDecisionLocked(tenantID string, scan domain.Vulnerability return decision } +func (l *Ledger) validateDecisionEvidenceLinksLocked(tenantID, releaseID string, evidenceIDs []string) ([]string, error) { + ids := sortedUniqueNonEmptyStrings(evidenceIDs) + if len(evidenceIDs) != len(ids) { + // Empty values are malformed; duplicate non-empty values are normalized below. + nonEmpty := 0 + for _, id := range evidenceIDs { + if strings.TrimSpace(id) != "" { + nonEmpty++ + } + } + if nonEmpty != len(evidenceIDs) { + return nil, ErrValidation + } + } + for _, id := range ids { + item, ok := l.evidence[id] + if !ok || item.TenantID != tenantID { + return nil, ErrNotFound + } + if item.ReleaseID != "" && releaseID != "" && item.ReleaseID != releaseID { + return nil, ErrNotFound + } + } + return ids, nil +} + +func decisionEvidenceIDs(primary string, extra []string) []string { + ids := append([]string(nil), extra...) + if strings.TrimSpace(primary) != "" { + ids = append(ids, strings.TrimSpace(primary)) + } + return sortedUniqueNonEmptyStrings(ids) +} + +func sortedUniqueNonEmptyStrings(in []string) []string { + set := map[string]struct{}{} + for _, value := range in { + value = strings.TrimSpace(value) + if value == "" { + continue + } + set[value] = struct{}{} + } + out := make([]string, 0, len(set)) + for value := range set { + out = append(out, value) + } + sort.Strings(out) + return out +} + +func (l *Ledger) appendDecisionLifecycleAuditLocked(tenantID string, decision domain.VulnerabilityDecision, findingID, actorTypeValue, actorIDValue, payloadHash string) { + if decision.Supersedes != "" { + _, _ = l.appendChainLocked(tenantID, "vulnerability_decision.superseded", "vulnerability_decision", decision.Supersedes, actorTypeValue, actorIDValue, payloadHash, "") + } + _, _ = l.appendChainLocked(tenantID, "vulnerability_decision.created", "vulnerability_finding", findingID, actorTypeValue, actorIDValue, payloadHash, "") +} + func (l *Ledger) findFindingLocked(tenantID, findingID string) (domain.VulnerabilityScan, domain.VulnerabilityFinding, bool) { for _, scan := range l.scans { if scan.TenantID != tenantID { diff --git a/internal/domain/domain.go b/internal/domain/domain.go index c7743eb..13a654d 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -1100,8 +1100,11 @@ type VulnerabilityDecision struct { Justification string `json:"justification"` ImpactStatement string `json:"impact_statement,omitempty"` ActionStatement string `json:"action_statement,omitempty"` + CustomerVisible bool `json:"customer_visible"` + InternalNotes string `json:"internal_notes,omitempty"` Source string `json:"source"` EvidenceID string `json:"evidence_id,omitempty"` + EvidenceIDs []string `json:"evidence_ids,omitempty"` VEXDocumentID string `json:"vex_document_id,omitempty"` Supersedes string `json:"supersedes,omitempty"` SupersededBy string `json:"superseded_by,omitempty"` diff --git a/migrations/20260601000100_vulnerability_decision_customer_fields.down.sql b/migrations/20260601000100_vulnerability_decision_customer_fields.down.sql new file mode 100644 index 0000000..f5d8819 --- /dev/null +++ b/migrations/20260601000100_vulnerability_decision_customer_fields.down.sql @@ -0,0 +1,5 @@ +ALTER TABLE IF EXISTS vulnerability_decisions + DROP COLUMN IF EXISTS internal_notes; + +ALTER TABLE IF EXISTS vulnerability_decisions + DROP COLUMN IF EXISTS customer_visible; diff --git a/migrations/20260601000100_vulnerability_decision_customer_fields.up.sql b/migrations/20260601000100_vulnerability_decision_customer_fields.up.sql new file mode 100644 index 0000000..3af42ea --- /dev/null +++ b/migrations/20260601000100_vulnerability_decision_customer_fields.up.sql @@ -0,0 +1,5 @@ +ALTER TABLE IF EXISTS vulnerability_decisions + ADD COLUMN IF NOT EXISTS customer_visible boolean NOT NULL DEFAULT false; + +ALTER TABLE IF EXISTS vulnerability_decisions + ADD COLUMN IF NOT EXISTS internal_notes text; diff --git a/migrations/20260601000200_vulnerability_decision_evidence_ids.down.sql b/migrations/20260601000200_vulnerability_decision_evidence_ids.down.sql new file mode 100644 index 0000000..cdf8c86 --- /dev/null +++ b/migrations/20260601000200_vulnerability_decision_evidence_ids.down.sql @@ -0,0 +1,2 @@ +ALTER TABLE IF EXISTS vulnerability_decisions + DROP COLUMN IF EXISTS evidence_ids; diff --git a/migrations/20260601000200_vulnerability_decision_evidence_ids.up.sql b/migrations/20260601000200_vulnerability_decision_evidence_ids.up.sql new file mode 100644 index 0000000..ef4889e --- /dev/null +++ b/migrations/20260601000200_vulnerability_decision_evidence_ids.up.sql @@ -0,0 +1,2 @@ +ALTER TABLE IF EXISTS vulnerability_decisions + ADD COLUMN IF NOT EXISTS evidence_ids text[] NOT NULL DEFAULT '{}'; diff --git a/openapi.yaml b/openapi.yaml index 246ef48..4bc4966 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From e334d2e1d6f1c6ab8bcc3567d3fc93e3bc7e128f Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:04:11 +0300 Subject: [PATCH 175/287] chore(productization): track backlog progress --- .gitignore | 1 + .productization_next_steps.md | 1299 +++++++++++++++++++++++++++++++++ 2 files changed, 1300 insertions(+) create mode 100644 .productization_next_steps.md diff --git a/.gitignore b/.gitignore index dc73eb8..1aecafe 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ !.env.example !.api.env.example !.test.env.example +!.productization_next_steps.md coverage.out bin/ diff --git a/.productization_next_steps.md b/.productization_next_steps.md new file mode 100644 index 0000000..d5b84b9 --- /dev/null +++ b/.productization_next_steps.md @@ -0,0 +1,1299 @@ +# Evydence Agent Handoff: Current Situation, Target Direction, and Backlog + +## 1. Current Situation + +Evydence is already a serious self-hosted, API-first release evidence ledger. It is not an empty prototype and should not be treated as a greenfield rebuild. + +The current project already has: + +* Go implementation under `github.com/aatuh/evydence` +* HTTP API under `/v1` +* OpenAPI contract committed as `openapi.yaml` +* tenant-scoped API keys +* idempotency support for create/action endpoints +* products, projects, releases, release candidates, artifacts, evidence records, SBOMs, VEX documents, vulnerability scans, vulnerability decisions, exceptions, waivers, approvals, controls, reports, release bundles, evidence bundles, customer packages, package manifests, and audit-chain concepts +* PostgreSQL-backed durable state +* object storage via filesystem or S3/MinIO-compatible storage +* worker/outbox processing +* parser side effects for key evidence formats +* release bundle and readiness report paths +* customer-safe package export +* local package viewer +* Docker Compose and production-like Compose +* Helm chart +* air-gapped package manifest +* CLI helper +* Go, TypeScript, and Python SDK wrappers +* GitHub Actions/GitLab CI examples +* AGPL licensing and commercial licensing/support documentation +* current release candidate line with signed archives, checksums, OpenAPI/migration checksums, production-check summary, SBOM/provenance metadata, and signed release manifest + +The repo is currently best understood as: + +> A controlled self-hosted production candidate for release evidence, not yet a broad production or regulated-production system for every use case. + +The project is technically ahead of its market packaging. The biggest gap is not “more backend features.” The biggest gap is making the product immediately understandable and useful to a specific buyer. + +## 2. Target Direction + +The target product direction is: + +> Evydence should become a VEX-first self-hosted release evidence product for software vendors that need to answer customer CVE, SBOM, provenance, and security-review questions with signed, customer-safe evidence bundles. + +The target buyer is: + +* product security lead +* AppSec engineer +* release engineering lead +* platform/security engineer +* CTO or security-conscious founder at a B2B software vendor +* team selling software into enterprise, regulated, EU-facing, public-sector-adjacent, or security-sensitive customers + +The painful buyer question is: + +> “This CVE appears in your SBOM. Are you affected, why or why not, who approved that answer, and can you give us proof for this exact release?” + +The core product promise should be: + +> Stop answering customer CVE and release-security questions with spreadsheets, screenshots, scanner exports, and Slack threads. Evydence creates a signed release evidence bundle that links SBOMs, vulnerability findings, VEX decisions, provenance, approvals, limitations, and customer-safe outputs. + +## 3. Product Principle + +Evydence should not try to become: + +* a generic vulnerability scanner +* a replacement for Dependency-Track or Anchore +* a generic GRC platform +* a trust-center SaaS clone +* a legal compliance certification tool +* a full API governance platform +* a privacy/DSAR deletion platform +* a generic evidence database for every possible event + +The v1 wedge is narrower: + +> Release-scoped VEX decisions and customer-safe release evidence. + +The system may ingest many evidence types, but the visible product path should be: + +1. Create product/release/artifact +2. Upload SBOM +3. Upload vulnerability scan +4. Record or import VEX decision +5. Attach provenance/build evidence +6. Approve/waive/except where needed +7. Generate release readiness report +8. Export signed customer-safe evidence package +9. Verify package offline + +## 4. Current Product Gap + +Evydence already has many primitives, but the first-time evaluator still has to understand too much. + +The current gap is: + +* the README is accurate but still too broad +* VEX is present but not yet the obvious center of the product +* vulnerability decisions need to become the buyer-facing hero object +* customer package flow exists but should feel like the killer feature +* package viewer exists but should become reviewer-grade +* the first demo path should be shorter and more emotionally obvious +* docs should lead with CVE/SBOM/provenance customer questions +* production limitations are honest, but should be organized into a pilot-readiness path +* commercial docs exist, but need a clear “design partner/pilot package” offer +* broad feature expansion should pause until the VEX-first flow is excellent + +## 5. North-Star User Story + +As a product-security or release-engineering owner at a B2B software vendor, I want to produce a signed customer-safe evidence package for a specific release, so that I can answer customer questions about SBOM contents, CVE exposure, VEX decisions, provenance, approvals, and known limitations without manually assembling files from CI logs, scanners, tickets, and Slack. + +## 6. Non-Goals For The Next Iteration + +Do not build these next: + +* generic SBOM scanner +* hosted SaaS mode +* broad trust center +* AI questionnaire responder +* privacy deletion/retention/DSAR engine +* OpenAPI governance product +* multi-writer HA unless required for production gate work +* giant admin UI +* large connector marketplace +* full compliance certification language +* legal conclusions +* claims that Evydence proves secure releases, complete SBOM coverage, complete vulnerability detection, CRA compliance, auditor acceptance, or regulator acceptance + +Keep existing non-claim language intact. + +## 7. Recommended Milestones + +### Milestone 0: Stabilize Current Baseline + +Goal: + +> Ensure the agent understands the existing implementation before changing product direction. + +Tasks: + +* Run existing tests. +* Run `make production-check` if available and practical. +* Inspect current OpenAPI contract. +* Inspect current domain models for product, release, artifact, SBOM, VEX document, vulnerability scan, vulnerability decision, release bundle, customer package, redaction profile, and report. +* Inspect current example under `examples/end-to-end-release-evidence`. +* Inspect package viewer under `site/package-viewer`. +* Inspect release candidate docs, roadmap, and production-readiness docs. +* Do not remove existing documented production limitations. + +Acceptance criteria: + +* Current test suite passes. +* Current generated OpenAPI contract is not accidentally broken. +* Agent produces a short internal note listing the current files/packages involved in VEX, vulnerability decisions, package export, reports, and viewer rendering. +* No public claim is added that exceeds the current non-claim boundaries. + +--- + +Checklist status: `[ ]` means the item is not yet complete against its +acceptance criteria. `[x]` means the current repository has implementation, +documentation, and tests/checks that satisfy the item. + +### Milestone 1: Reposition README And First Evaluation Path + +Goal: + +> Make the first 60 seconds of the repo explain the VEX-first product wedge. + +Backlog: + +#### [x] EVY-001 — Rewrite README opening around VEX-first release evidence + +Priority: P0 + +Description: + +Rewrite the top README positioning so it leads with the buyer pain: + +> Answer customer CVE, SBOM, provenance, and release-security questions with signed release evidence bundles. + +Keep the broader release evidence ledger language, but move it below the concrete wedge. + +Acceptance criteria: + +* README first paragraph explains the buyer pain in plain English. +* README clearly states Evydence is self-hosted and API-first. +* README names the target user: product security, AppSec, platform, release engineering, compliance-readiness. +* README preserves non-claims: not legal compliance proof, not certification, not complete SBOM proof, not authoritative vulnerability result, not secure-release guarantee. +* README includes a short “before Evydence / after Evydence” example. + +#### [x] EVY-002 — Add “What question does Evydence answer?” section + +Priority: P0 + +Description: + +Add a section near the top showing examples of the questions Evydence is designed to answer: + +* Are we affected by CVE-X in release Y? +* Which SBOM was used? +* Which scanner result raised the finding? +* Who approved the VEX decision? +* What evidence supports “not affected”? +* What package can be safely shared with a customer? +* How can the customer verify the package? + +Acceptance criteria: + +* Section is concrete and buyer-facing. +* Each question maps to existing or planned Evydence objects. +* Avoid internal architecture-first language. + +#### [x] EVY-003 — Reorder quickstart around VEX-first release bundle + +Priority: P0 + +Description: + +The primary quickstart should become: + +1. create product/release/artifact +2. upload SBOM +3. upload vulnerability scan +4. record VEX decision +5. generate readiness report +6. export customer-safe package +7. view/verify package + +Acceptance criteria: + +* README “Fastest Proof Path” points to this flow. +* Existing end-to-end example is updated or supplemented. +* A new evaluator can understand the demo without reading all docs. + +--- + +### Milestone 2: Make Vulnerability Decision The Hero Object + +Goal: + +> Make the vulnerability decision / VEX decision the central operational object. + +Backlog: + +#### [x] EVY-010 — Audit current VEX and VulnerabilityDecision models + +Priority: P0 + +Description: + +Inspect current schemas and domain models for VEX documents and vulnerability decisions. Identify what exists and what is missing for a buyer-facing VEX workflow. + +Evaluate whether the model supports: + +* vulnerability ID +* source scanner or advisory +* affected component/package/purl +* product/release scope +* status +* justification +* human-readable impact statement +* evidence links +* approver +* supersession +* expiry/review date +* visibility/customer-safe flag +* internal notes +* link to source SBOM +* link to vulnerability scan finding +* link to VEX document/import +* audit history + +Acceptance criteria: + +* Document current model gap. +* Do not redesign before mapping current implementation. +* Produce concrete migration/API changes only where current model is insufficient. + +#### [x] EVY-011 — Add canonical VEX decision lifecycle + +Priority: P0 + +Description: + +Define and implement a lifecycle for vulnerability decisions. + +Suggested statuses: + +* under_investigation +* not_affected +* affected +* fixed +* accepted_risk +* false_positive +* will_not_fix +* superseded + +Exact values should align with current implementation and VEX formats where possible. + +Acceptance criteria: + +* Status transitions are explicit. +* Invalid transitions are rejected or clearly handled. +* Decisions have audit events. +* Superseding a decision preserves old decision history. +* Customer package can show only the active decision unless history is requested. +* Internal notes are not leaked into customer-safe outputs. + +#### [x] EVY-012 — Add customer-safe impact statement + +Priority: P0 + +Description: + +Add or expose a field intended for customer-safe explanation of the decision. + +Examples: + +* “This release is not affected because the vulnerable class is not included in the shipped artifact.” +* “This vulnerability is present in a build-only dependency and is not present at runtime.” +* “This issue is fixed in release 1.2.4.” +* “This issue is under investigation; current mitigation is documented in the linked exception.” + +Acceptance criteria: + +* Field is separate from internal notes. +* Field can be included in customer packages. +* Field is required for customer-visible decisions. +* API validation prevents empty customer-visible “not affected” decisions unless explicitly allowed by policy. + +#### [x] EVY-013 — Link decisions to concrete evidence + +Priority: P0 + +Description: + +Each vulnerability decision should link to supporting evidence. + +Possible evidence links: + +* SBOM document +* vulnerability scan finding +* source/build/provenance evidence +* code review note +* exception/waiver +* approval +* remediation task +* incident package +* release bundle + +Acceptance criteria: + +* API supports evidence links on decisions. +* Links are tenant-scoped. +* Links are validated to refer to existing objects. +* Customer package export can include public metadata for links without leaking raw payloads. + +#### [ ] EVY-014 — Add decision history endpoint + +Priority: P1 + +Description: + +Add endpoint to retrieve all decisions for a vulnerability/product/release over time. + +Possible endpoints: + +* `GET /v1/vulnerabilities/{id}/decisions` +* `GET /v1/releases/{release_id}/vulnerability-decisions` +* `GET /v1/products/{product_id}/vulnerabilities/{vuln_id}/decision-history` + +Acceptance criteria: + +* Supports filtering by product, release, vulnerability ID, component, status, active/superseded. +* Includes decision timestamps and supersession chain. +* Respects tenant and scopes. +* OpenAPI updated. + +#### [ ] EVY-015 — Add customer-safe decision summary endpoint + +Priority: P1 + +Description: + +Expose an endpoint that returns only customer-safe VEX decision summaries for a release. + +Acceptance criteria: + +* Raw internal evidence payloads are excluded. +* Internal notes are excluded. +* Non-claims and limitations are included. +* Output is suitable for package viewer and exports. + +--- + +### Milestone 3: Improve OpenVEX / CycloneDX VEX Import + +Goal: + +> Make VEX import operational, not just uploadable. + +Backlog: + +#### [x] EVY-020 — Verify current OpenVEX parser side effects + +Priority: P0 + +Description: + +Inspect current worker-owned parser side effect behavior for OpenVEX. Confirm whether imported OpenVEX creates vulnerability decisions idempotently. + +Acceptance criteria: + +* Behavior is covered by tests. +* Import idempotency is verified. +* Duplicate import does not create duplicate active decisions. +* Parser failures are visible and actionable. + +#### [ ] EVY-021 — Add import report for VEX parsing + +Priority: P1 + +Description: + +When a VEX document is imported, return or generate a parser report: + +* number of statements parsed +* number of decisions created +* number of decisions updated/superseded +* unsupported fields +* warnings +* invalid statements +* mapping failures + +Acceptance criteria: + +* Import report is persisted. +* API can retrieve import report. +* Worker terminal failure contains useful problem details. +* End-to-end example shows report. + +#### [ ] EVY-022 — Add VEX mapping tests + +Priority: P1 + +Description: + +Add fixture-based tests for key VEX statuses and justifications. + +Test cases: + +* not affected +* affected +* fixed +* under investigation +* multiple products/releases +* duplicate statement +* superseded decision +* unsupported/unknown status +* component identity missing +* malformed document + +Acceptance criteria: + +* Tests cover parser and resulting decision records. +* Error messages are useful. +* OpenAPI examples include at least one imported VEX document. + +#### [ ] EVY-023 — Add manual decision authoring fallback + +Priority: P0 + +Description: + +Even if VEX import fails or is not available, user must be able to record a VEX-style decision manually through the API. + +Acceptance criteria: + +* Manual decision API supports required fields. +* Manual decision can be exported into customer package. +* Manual decision can be later linked to imported VEX. +* Manual decision requires justification/customer statement when customer-visible. + +--- + +### Milestone 4: Customer-Safe Package V2 + +Goal: + +> Make the customer evidence package the killer feature. + +Backlog: + +#### [ ] EVY-030 — Define package v2 manifest schema + +Priority: P0 + +Description: + +Define a clear manifest schema for customer-safe release evidence packages. + +Package should include: + +* package ID +* package version +* generated timestamp +* tenant/org/product/release metadata +* artifact digests +* SBOM metadata +* vulnerability scan metadata +* active VEX decisions +* approvals +* exceptions/waivers where customer-visible +* provenance metadata +* readiness summary +* limitations and non-claims +* redaction profile used +* verification material +* audit-chain verification summary + +Acceptance criteria: + +* Manifest schema is documented. +* Manifest has stable version field. +* Manifest excludes raw secret/internal evidence payloads by default. +* Manifest can be loaded by package viewer. +* Tests verify sensitive fields are absent. + +#### [ ] EVY-031 — Add package contents policy / redaction profile presets + +Priority: P0 + +Description: + +Define standard package profiles. + +Suggested profiles: + +* internal_full +* customer_safe +* security_review +* public_summary +* auditor_review + +Acceptance criteria: + +* At least `customer_safe` and `security_review` are implemented. +* Profiles are explicit and test-covered. +* Customer-safe profile excludes raw payload bytes, secrets, internal notes, internal URLs unless marked safe, and internal-only evidence. +* Package manifest names the profile used. +* API refuses unsafe export without explicit scope/permission. + +#### [ ] EVY-032 — Add customer package verification command + +Priority: P1 + +Description: + +Provide CLI command to verify a package offline. + +Possible command: + +`evydence package verify --manifest package.json --bundle evidence-bundle.json` + +Acceptance criteria: + +* Verifies hashes/signatures where available. +* Verifies manifest structure. +* Verifies package was generated by expected instance/signing key if configured. +* Outputs human-readable summary. +* Exits non-zero on failure. +* Example package verification is documented. + +#### [ ] EVY-033 — Improve package viewer for reviewer workflow + +Priority: P1 + +Description: + +Upgrade the local package viewer so it is no longer just a minimal JSON inspector. It should become a reviewer-friendly view. + +Viewer sections: + +* Release summary +* Artifact summary +* SBOM summary +* Vulnerability / VEX decision table +* Approvals and exceptions +* Readiness gaps +* What is included +* What is excluded +* Verification status +* Non-claims and limitations + +Acceptance criteria: + +* Viewer runs locally in browser without uploading files. +* Viewer handles sample manifest. +* Viewer clearly labels customer-safe vs internal-only data. +* Viewer highlights active VEX decisions. +* Viewer is usable from bundled demo. +* No server-side authorization assumptions are introduced. + +#### [ ] EVY-034 — Add downloadable sample customer package + +Priority: P1 + +Description: + +Include a realistic non-sensitive sample package in examples. + +Acceptance criteria: + +* Sample package loads in viewer. +* Sample includes SBOM metadata, vulnerability finding, VEX decision, release bundle, readiness report, and audit verification. +* Sample avoids real secrets and raw sensitive payloads. +* README links directly to this sample path. + +--- + +### Milestone 5: Readiness Report V2 + +Goal: + +> Make readiness reports say what a customer/security reviewer actually needs to know. + +Backlog: + +#### [ ] EVY-040 — Redesign release-readiness report around buyer questions + +Priority: P1 + +Description: + +Report should answer: + +* Is there an SBOM for this release? +* Is there a vulnerability scan? +* Are critical/high findings triaged? +* Are VEX decisions present for blocking findings? +* Are exceptions approved? +* Is provenance/build evidence attached? +* Are artifact digests present? +* Is the customer package safe to share? +* What gaps remain? +* What limitations apply? + +Acceptance criteria: + +* JSON report has structured sections. +* Human-readable summary is easy to convert to HTML/PDF later. +* Report distinguishes “missing evidence” from “known limitation” from “failed policy.” +* Report includes non-claim language. +* Example report updated. + +#### [ ] EVY-041 — Add policy-based readiness checks + +Priority: P1 + +Description: + +Introduce or tighten configurable readiness policy checks. + +Possible default checks: + +* release has artifact +* artifact has digest +* release has SBOM +* release has vulnerability scan +* all critical/high findings have decision +* customer-visible decisions have customer-safe statements +* not_affected decisions have justification +* exceptions have approver and expiry +* release has provenance/build evidence +* package redaction profile is valid + +Acceptance criteria: + +* Policy checks are deterministic. +* Default policy is documented. +* Users can see failing checks and remediation hints. +* Tests cover pass/fail examples. +* Readiness report includes policy version. + +#### [ ] EVY-042 — Add “customer-safe gaps” section + +Priority: P2 + +Description: + +Customer package should include a carefully worded gaps/limitations section. + +Acceptance criteria: + +* Gaps are factual, not legal conclusions. +* Gaps are safe to share only if marked customer-visible. +* Internal-only gaps remain internal. +* Viewer renders gaps clearly. + +--- + +### Milestone 6: CI/CD Evidence Ingest Path + +Goal: + +> Make it easy to wire Evydence into one release pipeline. + +Backlog: + +#### [ ] EVY-050 — Create GitHub Actions quickstart workflow + +Priority: P0 + +Description: + +Add a minimal GitHub Actions example that: + +* builds artifact +* computes digest +* generates or attaches SBOM +* attaches vulnerability scan output +* uploads provenance/build metadata +* optionally uploads VEX document or decision file +* creates/updates release evidence bundle + +Acceptance criteria: + +* Example works against local or configured Evydence URL. +* Uses scoped API key. +* Does not require secrets beyond documented variables. +* Produces output visible in release bundle/readiness report. +* README points to this as the first CI example. + +#### [ ] EVY-051 — Add CLI command for one-shot release evidence upload + +Priority: P1 + +Description: + +Simplify the CLI path. + +Possible command: + +`evydence release upload-evidence --product X --release Y --artifact path --sbom path --scan path --vex path` + +Acceptance criteria: + +* Command creates missing product/release/artifact if configured to do so, or fails with clear errors. +* Command prints next-step URL/API references. +* Command supports dry-run. +* Command has examples. + +#### [ ] EVY-052 — Add manifest schema for bulk upload + +Priority: P1 + +Description: + +Formalize the bulk upload manifest used in examples. + +Acceptance criteria: + +* Schema documented. +* Validation command exists. +* Manifest supports artifact, SBOM, scan, VEX, provenance, approvals, and package export. +* Tests cover invalid manifest errors. + +--- + +### Milestone 7: Domain/API Cleanup Around VEX-First Product + +Goal: + +> Make the API feel designed around the target workflow. + +Backlog: + +#### [ ] EVY-060 — Add high-level workflow endpoints if current API is too low-level + +Priority: P1 + +Description: + +Current API may already expose low-level resources. Add workflow endpoints only if they dramatically simplify evaluation. + +Possible endpoints: + +* `POST /v1/releases/{id}/evidence-flow/start` +* `POST /v1/releases/{id}/triage` +* `POST /v1/releases/{id}/customer-packages` +* `GET /v1/releases/{id}/security-summary` +* `GET /v1/releases/{id}/vex-summary` + +Acceptance criteria: + +* Workflow endpoints compose existing domain services. +* They do not duplicate business rules. +* They are optional convenience APIs. +* OpenAPI examples are included. + +#### [ ] EVY-061 — Add release security summary endpoint + +Priority: P0 + +Description: + +Expose one endpoint that summarizes release evidence status for UI, package viewer, or quick checks. + +Suggested output: + +* product/release +* artifact count +* SBOM status +* vulnerability scan status +* open findings by severity +* decisions by status +* missing required decisions +* approvals/exceptions +* readiness status +* package generation status + +Acceptance criteria: + +* Endpoint is tenant-scoped. +* Output is stable and documented. +* Does not expose raw evidence payloads. +* Used by example/demo. + +#### [ ] EVY-062 — Add API examples for VEX-first flow + +Priority: P1 + +Description: + +OpenAPI should include examples showing the main flow. + +Acceptance criteria: + +* Example request/response for create release. +* Example upload SBOM metadata. +* Example upload vulnerability scan. +* Example create VEX decision. +* Example generate readiness report. +* Example create customer package. +* Examples are non-sensitive and realistic. + +--- + +### Milestone 8: Minimal Admin/Reviewer UI + +Goal: + +> Add just enough UI to make the product demo understandable. + +Backlog: + +#### [x] EVY-070 — Decide UI boundary + +Priority: P0 + +Description: + +Make a decision: enhance static package viewer only, or add minimal server-backed admin UI. + +Recommended near-term: + +* keep API-first +* improve static package viewer +* add generated HTML outputs before building full app + +Acceptance criteria: + +* Document chosen UI boundary. +* Avoid starting a broad frontend unless necessary. + +#### [ ] EVY-071 — Add generated HTML customer package report + +Priority: P1 + +Description: + +Generate a static HTML report from customer package manifest. + +Acceptance criteria: + +* HTML is self-contained or uses local static assets. +* Shows release summary, VEX table, readiness, verification, limitations. +* Does not require server. +* Can be attached to package export. +* Clearly says it is not certification/legal proof. + +#### [ ] EVY-072 — Add internal demo dashboard only if needed + +Priority: P2 + +Description: + +If the existing viewer and API examples are insufficient, add minimal dashboard. + +Pages: + +* Releases +* Release detail +* Vulnerability decisions +* Readiness report +* Customer packages + +Acceptance criteria: + +* No broad app shell. +* No complex auth UI unless already available. +* Uses existing API. +* Demo-focused, not enterprise UI. + +--- + +### Milestone 9: Production/Pilot Hardening + +Goal: + +> Prepare Evydence for design-partner pilots without pretending broad production is solved. + +Backlog: + +#### [x] EVY-080 — Finish production-readiness gap review + +Priority: P0 + +Description: + +Review current production-readiness document and convert known gaps into tracked tasks. + +Known areas: + +* remaining relational persistence paths +* aggregate decomposition +* startup load modes +* single API writer profile +* worker scaling +* object-lock/WORM proof +* signing provider behavior +* KMS/HSM support +* provider-specific validation +* group sync +* backup/restore rehearsal +* monitoring/alerts +* incident response runbook + +Acceptance criteria: + +* Each known gap is either tracked, explicitly deferred, or documented as operator responsibility. +* Docs distinguish evaluation, pilot, controlled internal production, regulated production, and unsupported hosted SaaS. + +#### [x] EVY-081 — Add backup/restore rehearsal docs + +Priority: P0 + +Description: + +Design partners need to know how to back up and restore Postgres/object storage/signing material. + +Acceptance criteria: + +* Document backup scope. +* Document restore rehearsal. +* Include failure modes. +* Include verification after restore. +* Do not claim backup correctness without user rehearsal. + +#### [x] EVY-082 — Add monitoring recommendations + +Priority: P1 + +Description: + +Add practical operator metrics/logs checklist. + +Monitor: + +* API health +* worker health +* outbox queue depth +* failed parser jobs +* failed package generation +* signing failures +* object storage errors +* Postgres errors +* audit-chain verification failures +* package access failures + +Acceptance criteria: + +* Metrics/log events documented. +* Production-like Compose or Helm exposes enough signals. +* Alerts suggested but not vendor-specific unless already wired. + +#### [ ] EVY-083 — Add pilot deployment checklist + +Priority: P0 + +Description: + +Create checklist for a design partner. + +Checklist sections: + +* environment +* database +* object storage +* API keys +* signing mode +* TLS/reverse proxy +* backups +* restore rehearsal +* image digest verification +* migrations +* worker count +* package retention +* redaction policy +* scoped access +* support contact + +Acceptance criteria: + +* Checklist is copy-pasteable. +* Distinguishes required vs recommended. +* Fits one narrow pilot profile. + +--- + +### Milestone 10: Commercial/Pilot Packaging + +Goal: + +> Make the project sellable as a narrow pilot, not just open-source code. + +Backlog: + +#### [ ] EVY-090 — Add “Design Partner Pilot” offer doc + +Priority: P1 + +Description: + +Create `docs/commercial/design-partner-pilot.md` or similar. + +Offer: + +> We wire one product release into Evydence, ingest SBOM + vulnerability scan + VEX/provenance evidence, produce one signed customer-safe evidence bundle, and review the self-hosted deployment profile. + +Acceptance criteria: + +* Clear deliverables. +* Clear non-deliverables. +* No legal compliance guarantees. +* Mentions AGPL/commercial license path. +* Mentions support boundaries. +* Includes ideal customer profile. + +#### [ ] EVY-091 — Add product landing copy + +Priority: P1 + +Description: + +Add concise copy usable for README, website, or outreach. + +Acceptance criteria: + +* Headline. +* One-sentence pitch. +* Problem section. +* How it works. +* Why self-hosted. +* What it is not. +* Pilot CTA. +* No unsupported claims. + +#### [ ] EVY-092 — Add comparison page: Evydence vs scanners/GRC/trust centers + +Priority: P2 + +Description: + +Create docs page explaining category boundaries. + +Compare against: + +* vulnerability scanners +* SBOM inventory tools +* broad GRC tools +* trust centers +* DIY scripts/spreadsheets + +Acceptance criteria: + +* Fair and non-hostile. +* Explains Evydence focus: release-level evidence, decisions, bundles, audit chains, customer-safe packages. +* Does not claim competitors are bad. +* Helps buyer understand why Evydence exists. + +--- + +### Milestone 11: Tests and Quality Gates + +Goal: + +> Keep productization from weakening technical reliability. + +Backlog: + +#### [ ] EVY-100 — Add end-to-end VEX-first integration test + +Priority: P0 + +Description: + +Test complete flow: + +1. create product +2. create release +3. create artifact +4. upload SBOM +5. upload vulnerability scan +6. create VEX decision +7. approve/record exception where needed +8. generate release bundle +9. generate readiness report +10. export customer package +11. verify audit chain/package + +Acceptance criteria: + +* Test uses realistic fixtures. +* Test runs in CI or documented integration mode. +* Output fixtures are stable or regenerated intentionally. +* Catches regressions in main product path. + +#### [ ] EVY-101 — Add redaction leakage tests + +Priority: P0 + +Description: + +Ensure customer-safe outputs never leak forbidden fields. + +Test forbidden data: + +* API keys +* internal notes +* raw payload bytes +* internal-only evidence fields +* internal URLs unless marked safe +* object storage paths +* signing private material +* tenant secrets +* scanner raw output if excluded + +Acceptance criteria: + +* Tests fail on leakage. +* Customer package fixture passes. +* Redaction rules documented. + +#### [x] EVY-102 — Add OpenAPI contract stability check + +Priority: P1 + +Description: + +Ensure API changes are intentional. + +Acceptance criteria: + +* CI checks OpenAPI generation. +* Changes require committed contract update. +* Breaking changes are noted in changelog or release notes. + +#### [ ] EVY-103 — Add fixture golden tests for package manifest + +Priority: P1 + +Description: + +Protect manifest format from accidental drift. + +Acceptance criteria: + +* Golden manifest exists. +* Intentional changes require fixture update. +* Manifest version changes are explicit. + +--- + +### Milestone 12: Future Expansion Backlog + +These are valid later, but should not block the VEX-first product. + +#### [ ] EVY-200 — Artifact exchange / trust package portal + +Potential later expansion: + +* NDA-gated customer access +* package access logs +* time-limited links +* watermarking +* customer-specific packages +* answer library +* security questionnaire drafts + +Only do this after customer-safe packages are strong. + +#### [ ] EVY-201 — OpenAPI governance integration + +Potential later expansion: + +* ingest OpenAPI diffs +* attach API breaking-change evidence to releases +* export API contract evidence into release package + +Do not turn Evydence into the OpenAPI governance product itself. + +#### [ ] EVY-202 — CRA-readiness templates + +Potential later expansion: + +* CRA evidence mapping templates +* vulnerability handling report +* security update evidence report +* incident package template + +Keep language as readiness support, not legal conclusion. + +#### [ ] EVY-203 — Advanced signing/HSM/WORM profiles + +Potential later expansion: + +* stronger HSM profiles +* object-lock proof packages +* transparency proof integrations +* deployment-specific custody review tooling + +Do this when a real pilot requires it. + +#### [ ] EVY-204 — Customer portal server mode + +Potential later expansion: + +* external reviewer accounts +* package tokens +* access logs +* expiry +* package download history + +Do this only after static/offline package flow is excellent. + +## 8. Suggested Implementation Order + +Recommended first sequence for coding agent: + +1. Baseline repo/test/doc inspection +2. README and quickstart repositioning +3. Audit current VEX/vulnerability decision models +4. Make vulnerability decision the hero object +5. Improve VEX import/manual decision workflow +6. Define customer package v2 manifest +7. Add redaction leakage tests +8. Improve package viewer around VEX/reviewer workflow +9. Add release security summary endpoint +10. Add GitHub Actions quickstart +11. Add end-to-end VEX-first integration test +12. Add pilot deployment checklist +13. Add design-partner pilot doc + +Do not start by adding broad new feature families. + +## 9. Definition Of Done For The Next Strategic Stage + +Evydence reaches the next stage when a new evaluator can do this in under 30 minutes: + +1. Start Evydence locally or in production-like Compose. +2. Create a product/release/artifact. +3. Upload SBOM and vulnerability scan evidence. +4. Record a VEX decision explaining one CVE. +5. Generate a readiness report. +6. Export a signed customer-safe package. +7. Open the package locally in the viewer. +8. Verify what is included, excluded, signed, and limited. +9. Understand that Evydence is not a scanner, not a legal compliance tool, and not a certification authority. + +The product should feel like: + +> “Here is the release. Here is the SBOM. Here is the vulnerability. Here is our VEX decision. Here is the evidence. Here is who approved it. Here is the customer-safe package. Here is how to verify it.” + +That is the target. + +[1]: https://github.com/aatuh/evydence "GitHub - aatuh/evydence: Self-hosted API-first evidence ledger for software release compliance readiness · GitHub" +[2]: https://github.com/aatuh/evydence/releases/tag/v0.1.0-rc.4 "Release Evydence v0.1.0-rc.4 · aatuh/evydence · GitHub" +[3]: https://www.cisa.gov/topics/information-communications-technology-supply-chain-security/sbom?utm_source=chatgpt.com "Software Bill of Materials (SBOM)" +[4]: https://cyclonedx.org/capabilities/vex/?utm_source=chatgpt.com "Vulnerability Exploitability eXchange (VEX)" +[5]: https://digital-strategy.ec.europa.eu/en/policies/cyber-resilience-act?utm_source=chatgpt.com "Cyber Resilience Act | Shaping Europe's digital future" From a38ffaf2d9b1ca24533ddc45e9bc95e5a6e6fb40 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:06:15 +0300 Subject: [PATCH 176/287] feat(decisions): add vulnerability decision history --- .productization_next_steps.md | 2 +- docs/api.md | 12 +++ docs/reference/api-contract-matrix.md | 3 +- docs/reference/vulnerability-decisions.md | 27 +++++- internal/adapters/httpapi/openapi.go | 1 + .../adapters/httpapi/openapi_operations.go | 11 +++ .../adapters/httpapi/route_registration.go | 1 + internal/adapters/httpapi/router.go | 30 ++++++ internal/adapters/httpapi/router_test.go | 13 ++- internal/app/ledger_test.go | 79 +++++++++++++++ internal/app/release_evidence_service.go | 4 + internal/app/vex.go | 97 +++++++++++++++++++ openapi.yaml | 2 +- 13 files changed, 274 insertions(+), 8 deletions(-) diff --git a/.productization_next_steps.md b/.productization_next_steps.md index d5b84b9..9a06e7e 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -353,7 +353,7 @@ Acceptance criteria: * Links are validated to refer to existing objects. * Customer package export can include public metadata for links without leaking raw payloads. -#### [ ] EVY-014 — Add decision history endpoint +#### [x] EVY-014 — Add decision history endpoint Priority: P1 diff --git a/docs/api.md b/docs/api.md index def5634..1534b83 100644 --- a/docs/api.md +++ b/docs/api.md @@ -181,6 +181,17 @@ supersession and replacement. `evidence_ids` may reference tenant-scoped supporting evidence from the same release; foreign-tenant or wrong-release evidence links are rejected. +Decision history: + +```http +GET /v1/vulnerability-decisions?release_id=rel_...&vulnerability=CVE-2026-0099&active=true +``` + +The history endpoint supports `product_id`, `release_id`, `vulnerability`, +`component`, `status`, and `active` filters. It returns append-only decision +records, including timestamps and supersession fields. It is tenant-scoped and +requires `evidence:read`. + ### 4. Readiness And Bundle Retrieval Create a release bundle: @@ -295,6 +306,7 @@ Current SSO endpoints model admin-managed provider, identity-link, trust-materia | `POST` | `/v1/vulnerability-scans` | Upload normalized vulnerability scan. | | `GET` | `/v1/vulnerability-scans/{id}` | Read vulnerability scan metadata. | | `POST` | `/v1/vulnerability-findings/{id}/decisions` | Superseding decision record. | +| `GET` | `/v1/vulnerability-decisions` | List decision history by product, release, vulnerability, component, status, and active state. | | `POST` | `/v1/vulnerability-findings/{id}/workflow` | Append workflow event. | | `GET` | `/v1/reports/vulnerability-posture` | Summarize findings for a release. | | `GET` | `/v1/reports/release-readiness` | Deterministic readiness report. | diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index dde446b..21d42a8 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 166 operations: 166 precise, 0 broad. +Generated from 167 operations: 167 precise, 0 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -167,6 +167,7 @@ Generated from 166 operations: 166 precise, 0 broad. | POST | /v1/vex | uploadVEX | Bearer | evidence:write | required | - | application/json:EvidenceUploadRequest | 201:application/json:VEXDocumentEnvelope | precise | | POST | /v1/vex/cyclonedx | uploadCycloneDXVEX | Bearer | evidence:write | required | - | application/json:EvidenceUploadRequest | 201:application/json:VEXDocumentEnvelope | precise | | GET | /v1/vex/{id} | getVEX | Bearer | evidence:read | - | path:id | - | 200:application/json:VEXDocumentEnvelope | precise | +| GET | /v1/vulnerability-decisions | listVulnerabilityDecisions | Bearer | evidence:read | - | query:active, query:component, query:product_id, query:release_id, query:status, query:vulnerability | - | 200:application/json:VulnerabilityDecisionListEnvelope | precise | | POST | /v1/vulnerability-findings/{id}/decisions | createVulnerabilityDecision | Bearer | evidence:write | required | path:id | application/json:CreateVulnerabilityDecisionRequest | 201:application/json:VulnerabilityDecisionEnvelope | precise | | POST | /v1/vulnerability-findings/{id}/workflow | recordVulnerabilityWorkflow | Bearer | security:write | required | path:id | application/json:RecordVulnerabilityWorkflowRequest | 201:application/json:VulnerabilityWorkflowRecordEnvelope | precise | | POST | /v1/vulnerability-scans | uploadVulnerabilityScan | Bearer | evidence:write | required | - | application/json:UploadVulnerabilityScanRequest | 201:application/json:VulnerabilityScanEnvelope | precise | diff --git a/docs/reference/vulnerability-decisions.md b/docs/reference/vulnerability-decisions.md index c0df1c5..4f765ec 100644 --- a/docs/reference/vulnerability-decisions.md +++ b/docs/reference/vulnerability-decisions.md @@ -65,15 +65,34 @@ decides whether they belong in decisions or in exceptions/waivers. Customer package manifests include only active decisions unless a future history-specific export is requested. +## Decision History API + +`GET /v1/vulnerability-decisions` returns the tenant-scoped append-only +decision history for operators with `evidence:read`. + +Supported filters: + +- `product_id` +- `release_id` +- `vulnerability` +- `component` +- `status` +- `active` + +The response uses the `VulnerabilityDecision` schema, including `created_at`, +`supersedes`, and `superseded_by` so clients can reconstruct the decision +chain. `status` must be one of the canonical statuses. `active=true` returns +decisions with no `superseded_by`; `active=false` returns superseded decisions. +Product and release filters are validated against tenant-owned resources and +the release must belong to the requested product when both filters are present. + ## Current Gaps The current model is enough to support release-readiness gating, but it is not yet the full buyer-facing VEX decision workflow: -- There is no first-class decision history endpoint. History exists in stored - decision records through `supersedes` and `superseded_by`, but clients cannot - query it directly by product, release, vulnerability, component, active - status, or supersession state. +- Decision history can now be queried directly, but it is still a read-only + operational API rather than a dedicated customer-facing export. - Customer package manifests can include active `customer_visible` decision summaries when the redaction profile explicitly allows `vulnerability_decision`. They exclude `internal_notes`, raw payload bytes, diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 51c1fb9..60b9bbd 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -325,6 +325,7 @@ func registerCriticalSchemas(registry *specs.Registry) { "created_at": map[string]any{"type": "string", "format": "date-time"}, }, "id", "tenant_id", "finding_id", "scan_id", "vulnerability", "status", "justification", "source", "schema_version", "created_at")) registry.RegisterSchema("VulnerabilityDecisionEnvelope", dataEnvelopeSchema("#/components/schemas/VulnerabilityDecision")) + registry.RegisterSchema("VulnerabilityDecisionListEnvelope", dataArrayEnvelopeSchema("#/components/schemas/VulnerabilityDecision")) registry.RegisterSchema("RecordVulnerabilityWorkflowRequest", objectSchema(map[string]any{ "action": map[string]any{"type": "string"}, "reason": map[string]any{"type": "string"}, diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index a927d74..059a263 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -353,6 +353,17 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Parameters = append(operation.Parameters, pathParam("id", "Vulnerability finding id.")) operation.RequestBody = jsonRequest("Vulnerability decision creation request.", "#/components/schemas/CreateVulnerabilityDecisionRequest") operation.Responses[http.StatusCreated] = jsonResponse("Created vulnerability decision envelope.", "#/components/schemas/VulnerabilityDecisionEnvelope") + case "listVulnerabilityDecisions": + operation.Description = "Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters." + operation.Parameters = append(operation.Parameters, + queryParam("product_id", "Filter by product id.", "string"), + queryParam("release_id", "Filter by release id.", "string"), + queryParam("vulnerability", "Filter by vulnerability identifier.", "string"), + queryParam("component", "Filter by affected component.", "string"), + queryParam("status", "Filter by decision status.", "string"), + queryParam("active", "When true returns active decisions; when false returns superseded decisions.", "boolean"), + ) + operation.Responses[http.StatusOK] = jsonResponse("Vulnerability decision list envelope.", "#/components/schemas/VulnerabilityDecisionListEnvelope") case "recordVulnerabilityWorkflow": operation.Description = "Records an append-only vulnerability workflow event for a tenant-scoped finding." operation.Parameters = append(operation.Parameters, pathParam("id", "Vulnerability finding id.")) diff --git a/internal/adapters/httpapi/route_registration.go b/internal/adapters/httpapi/route_registration.go index ff667d1..b493b76 100644 --- a/internal/adapters/httpapi/route_registration.go +++ b/internal/adapters/httpapi/route_registration.go @@ -210,6 +210,7 @@ func (s *Server) evidenceRiskPolicyRoutes() []routeDef { {http.MethodPost, "/v1/vulnerability-scans", op("uploadVulnerabilityScan", http.MethodPost, "/v1/vulnerability-scans", "Upload vulnerability scan", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.uploadVulnerabilityScan)}, {http.MethodGet, "/v1/vulnerability-scans/{id}", op("getVulnerabilityScan", http.MethodGet, "/v1/vulnerability-scans/{id}", "Get vulnerability scan", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.getVulnerabilityScan)}, {http.MethodPost, "/v1/vulnerability-findings/{id}/decisions", op("createVulnerabilityDecision", http.MethodPost, "/v1/vulnerability-findings/{id}/decisions", "Create vulnerability decision", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.createVulnerabilityDecision)}, + {http.MethodGet, "/v1/vulnerability-decisions", op("listVulnerabilityDecisions", http.MethodGet, "/v1/vulnerability-decisions", "List vulnerability decisions", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.listVulnerabilityDecisions)}, {http.MethodPost, "/v1/vulnerability-findings/{id}/workflow", op("recordVulnerabilityWorkflow", http.MethodPost, "/v1/vulnerability-findings/{id}/workflow", "Record vulnerability workflow event", []string{app.ScopeSecurityWrite}), http.HandlerFunc(s.recordVulnerabilityWorkflow)}, {http.MethodGet, "/v1/reports/vulnerability-posture", op("vulnerabilityPostureReport", http.MethodGet, "/v1/reports/vulnerability-posture", "Vulnerability posture report", []string{app.ScopeSecurityRead}), http.HandlerFunc(s.vulnerabilityPostureReport)}, {http.MethodPost, "/v1/openapi-contracts", op("uploadOpenAPIContract", http.MethodPost, "/v1/openapi-contracts", "Upload OpenAPI contract", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.uploadOpenAPIContract)}, diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index 284ada1..3cc90c1 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -1494,6 +1494,36 @@ func (s *Server) createVulnerabilityDecision(w http.ResponseWriter, r *http.Requ }) } +func (s *Server) listVulnerabilityDecisions(w http.ResponseWriter, r *http.Request) { + actor, ok := s.authenticate(w, r) + if !ok { + return + } + query := r.URL.Query() + var active *bool + if value := strings.TrimSpace(query.Get("active")); value != "" { + parsed, err := strconv.ParseBool(value) + if err != nil { + writeProblem(w, r, app.ErrValidation) + return + } + active = &parsed + } + decisions, err := s.ledger.ListVulnerabilityDecisions(r.Context(), actor, app.ListVulnerabilityDecisionsInput{ + ProductID: query.Get("product_id"), + ReleaseID: query.Get("release_id"), + Vulnerability: query.Get("vulnerability"), + Component: query.Get("component"), + Status: query.Get("status"), + Active: active, + }) + if err != nil { + writeProblem(w, r, err) + return + } + writeData(w, http.StatusOK, decisions) +} + func (s *Server) recordVulnerabilityWorkflow(w http.ResponseWriter, r *http.Request) { var req struct { Action string `json:"action"` diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 40cd412..7ef6e76 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -9,6 +9,7 @@ import ( "encoding/json" "net/http" "net/http/httptest" + "net/url" "strings" "testing" "time" @@ -85,7 +86,7 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { if _, ok := problemProps["request_id"]; !ok { t.Fatalf("Problem schema missing request_id: %#v", problemProps) } - for _, schemaName := range []string{"ReadinessStatusEnvelope", "BackupManifestEnvelope", "VerificationResultEnvelope", "ReadinessReportEnvelope", "CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "UpdateSSOProviderTrustMaterialRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "ExchangeSSOCredentialRequest", "SSOCredentialExchangeEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "DataEnvelope"} { + for _, schemaName := range []string{"ReadinessStatusEnvelope", "BackupManifestEnvelope", "VerificationResultEnvelope", "ReadinessReportEnvelope", "CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "VulnerabilityDecisionListEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "UpdateSSOProviderTrustMaterialRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "ExchangeSSOCredentialRequest", "SSOCredentialExchangeEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "DataEnvelope"} { if _, ok := schemas[schemaName]; !ok { t.Fatalf("schema %s missing from OpenAPI components", schemaName) } @@ -133,6 +134,9 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { uploadVulnerabilityScan := operationMap(t, paths, "/v1/vulnerability-scans", "post") assertRequestRef(t, uploadVulnerabilityScan, "#/components/schemas/UploadVulnerabilityScanRequest") assertResponseRef(t, uploadVulnerabilityScan, "201", "#/components/schemas/VulnerabilityScanEnvelope") + listVulnerabilityDecisions := operationMap(t, paths, "/v1/vulnerability-decisions", "get") + assertQueryParams(t, listVulnerabilityDecisions, "product_id", "release_id", "vulnerability", "component", "status", "active") + assertResponseRef(t, listVulnerabilityDecisions, "200", "#/components/schemas/VulnerabilityDecisionListEnvelope") uploadVEX := operationMap(t, paths, "/v1/vex", "post") assertRequestRef(t, uploadVEX, "#/components/schemas/EvidenceUploadRequest") assertResponseRef(t, uploadVEX, "201", "#/components/schemas/VEXDocumentEnvelope") @@ -636,6 +640,13 @@ func TestReleaseRiskDecisionHTTPFlow(t *testing.T) { if replayed != decisionBody { t.Fatalf("decision idempotency replay changed response\nfirst=%s\nsecond=%s", decisionBody, replayed) } + historyPath := "/v1/vulnerability-decisions?release_id=" + releaseID + "&product_id=" + productID + "&vulnerability=CVE-2026-0099&component=" + url.QueryEscape("pkg:apk/openssl@3.1.0") + "&status=not_affected&active=true" + history := getJSON(t, server, secret, historyPath, http.StatusOK) + if !strings.Contains(history, `"vulnerability":"CVE-2026-0099"`) || !strings.Contains(history, `"customer_visible":true`) { + t.Fatalf("decision history response missing decision fields: %s", history) + } + getJSON(t, server, secret, "/v1/vulnerability-decisions?active=maybe", http.StatusBadRequest) + getJSON(t, server, secret, "/v1/vulnerability-decisions?status=not_a_status", http.StatusBadRequest) report = getJSON(t, server, secret, "/v1/reports/release-readiness?release_id="+releaseID, http.StatusOK) if !strings.Contains(report, `"result":"passed"`) { t.Fatalf("expected passed readiness report after decision: %s", report) diff --git a/internal/app/ledger_test.go b/internal/app/ledger_test.go index 5471575..083633e 100644 --- a/internal/app/ledger_test.go +++ b/internal/app/ledger_test.go @@ -817,6 +817,85 @@ func TestVulnerabilityDecisionLifecycleSupersedesAndPackagesOnlyActive(t *testin } } +func TestListVulnerabilityDecisionsFiltersHistoryAndTenantScope(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, release, _ := setupReleaseRiskFixture(t, ledger) + scan, err := ledger.UploadVulnerabilityScan(ctx, actor, []byte(`{ + "scanner":"grype", + "target_ref":"pkg:oci/payments-api", + "release_id":"`+release.ID+`", + "findings":[{"vulnerability":"CVE-2026-0103","component":"pkg:apk/openssl@3.1.0","severity":"critical","state":"open"}] + }`)) + if err != nil { + t.Fatalf("scan: %v", err) + } + first, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{ + Status: decisionStatusUnderInvestigation, + Justification: "review started", + ImpactStatement: "The finding is under investigation.", + CustomerVisible: true, + }) + if err != nil { + t.Fatalf("first decision: %v", err) + } + second, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{ + Status: decisionStatusFixed, + Justification: "fixed in release artifact", + ImpactStatement: "The finding is fixed in this release artifact.", + CustomerVisible: true, + }) + if err != nil { + t.Fatalf("second decision: %v", err) + } + history, err := ledger.ListVulnerabilityDecisions(ctx, actor, ListVulnerabilityDecisionsInput{ + ProductID: release.ProductID, + ReleaseID: release.ID, + Vulnerability: "CVE-2026-0103", + Component: "pkg:apk/openssl@3.1.0", + }) + if err != nil { + t.Fatalf("list history: %v", err) + } + if len(history) != 2 { + t.Fatalf("history length=%d want 2 history=%#v", len(history), history) + } + active := true + activeOnly, err := ledger.ListVulnerabilityDecisions(ctx, actor, ListVulnerabilityDecisionsInput{ReleaseID: release.ID, Active: &active}) + if err != nil { + t.Fatalf("list active: %v", err) + } + if len(activeOnly) != 1 || activeOnly[0].ID != second.ID || activeOnly[0].Supersedes != first.ID { + t.Fatalf("active decisions=%#v, want second decision superseding first", activeOnly) + } + active = false + superseded, err := ledger.ListVulnerabilityDecisions(ctx, actor, ListVulnerabilityDecisionsInput{ReleaseID: release.ID, Status: decisionStatusUnderInvestigation, Active: &active}) + if err != nil { + t.Fatalf("list superseded: %v", err) + } + if len(superseded) != 1 || superseded[0].ID != first.ID || superseded[0].SupersededBy != second.ID { + t.Fatalf("superseded decisions=%#v, want first decision superseded by second", superseded) + } + if _, err := ledger.ListVulnerabilityDecisions(ctx, actor, ListVulnerabilityDecisionsInput{Status: "not_a_status"}); !errors.Is(err, ErrValidation) { + t.Fatalf("invalid status err=%v, want validation", err) + } + _, _, secretB, err := ledger.BootstrapTenant(ctx, "Tenant B", "admin-b", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap tenant B: %v", err) + } + actorB, err := ledger.Authenticate(ctx, secretB) + if err != nil { + t.Fatalf("authenticate tenant B: %v", err) + } + foreignHistory, err := ledger.ListVulnerabilityDecisions(ctx, actorB, ListVulnerabilityDecisionsInput{}) + if err != nil { + t.Fatalf("foreign list: %v", err) + } + if len(foreignHistory) != 0 { + t.Fatalf("foreign tenant saw decisions: %#v", foreignHistory) + } +} + func TestVulnerabilityDecisionEvidenceLinksAreTenantAndReleaseScoped(t *testing.T) { ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) ctx := context.Background() diff --git a/internal/app/release_evidence_service.go b/internal/app/release_evidence_service.go index 6a0b16f..9c83cf0 100644 --- a/internal/app/release_evidence_service.go +++ b/internal/app/release_evidence_service.go @@ -106,6 +106,10 @@ func (l *Ledger) CreateVulnerabilityDecision(ctx context.Context, actor domain.A return l.releaseEvidenceService().CreateVulnerabilityDecision(ctx, actor, findingID, in) } +func (l *Ledger) ListVulnerabilityDecisions(ctx context.Context, actor domain.Actor, in ListVulnerabilityDecisionsInput) ([]domain.VulnerabilityDecision, error) { + return l.releaseEvidenceService().ListVulnerabilityDecisions(ctx, actor, in) +} + func (l *Ledger) CreateException(ctx context.Context, actor domain.Actor, in CreateExceptionInput) (domain.Exception, error) { return l.releaseEvidenceService().CreateException(ctx, actor, in) } diff --git a/internal/app/vex.go b/internal/app/vex.go index 1f13dcf..bc39a57 100644 --- a/internal/app/vex.go +++ b/internal/app/vex.go @@ -37,6 +37,15 @@ type CreateVulnerabilityDecisionInput struct { EvidenceIDs []string } +type ListVulnerabilityDecisionsInput struct { + ProductID string + ReleaseID string + Vulnerability string + Component string + Status string + Active *bool +} + type CreateExceptionInput struct { ReleaseID string FindingID string @@ -261,6 +270,94 @@ func (s releaseEvidenceService) CreateVulnerabilityDecision(ctx context.Context, return decision, nil } +func (s releaseEvidenceService) ListVulnerabilityDecisions(ctx context.Context, actor domain.Actor, in ListVulnerabilityDecisionsInput) ([]domain.VulnerabilityDecision, error) { + l := s.ledger + if err := ctx.Err(); err != nil { + return nil, err + } + if err := require(actor, ScopeEvidenceRead); err != nil { + return nil, err + } + in.ProductID = strings.TrimSpace(in.ProductID) + in.ReleaseID = strings.TrimSpace(in.ReleaseID) + in.Vulnerability = strings.TrimSpace(in.Vulnerability) + in.Component = strings.TrimSpace(in.Component) + in.Status = strings.TrimSpace(in.Status) + if in.Status != "" && !validDecisionStatus(in.Status) { + return nil, ErrValidation + } + + l.mu.Lock() + defer l.mu.Unlock() + filterProductID := in.ProductID + if filterProductID != "" { + product, ok := l.products[filterProductID] + if !ok || product.TenantID != actor.TenantID { + return nil, ErrNotFound + } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceRead, resourceRefs{ProductID: product.ID}); err != nil { + return nil, err + } + } + if in.ReleaseID != "" { + release, ok := l.releases[in.ReleaseID] + if !ok || release.TenantID != actor.TenantID { + return nil, ErrNotFound + } + if filterProductID != "" && release.ProductID != filterProductID { + return nil, ErrNotFound + } + filterProductID = release.ProductID + if err := l.authorizeResourceLocked(actor, ScopeEvidenceRead, resourceRefs{ProductID: release.ProductID, ReleaseID: release.ID}); err != nil { + return nil, err + } + } + + out := []domain.VulnerabilityDecision{} + for _, decision := range l.decisions { + if decision.TenantID != actor.TenantID { + continue + } + if in.ReleaseID != "" && decision.ReleaseID != in.ReleaseID { + continue + } + releaseProductID := "" + if decision.ReleaseID != "" { + release, ok := l.releases[decision.ReleaseID] + if !ok || release.TenantID != actor.TenantID { + continue + } + releaseProductID = release.ProductID + } + if filterProductID != "" && releaseProductID != filterProductID { + continue + } + if in.Vulnerability != "" && decision.Vulnerability != in.Vulnerability { + continue + } + if in.Component != "" && decision.Component != in.Component { + continue + } + if in.Status != "" && decision.Status != in.Status { + continue + } + if in.Active != nil && (*in.Active) != (decision.SupersededBy == "") { + continue + } + if !l.resourceAllowedLocked(actor, ScopeEvidenceRead, resourceRefs{ProductID: releaseProductID, ReleaseID: decision.ReleaseID}) { + continue + } + out = append(out, decision) + } + sort.Slice(out, func(i, j int) bool { + if out[i].CreatedAt.Equal(out[j].CreatedAt) { + return out[i].ID < out[j].ID + } + return out[i].CreatedAt.Before(out[j].CreatedAt) + }) + return out, nil +} + func (s releaseEvidenceService) CreateException(ctx context.Context, actor domain.Actor, in CreateExceptionInput) (domain.Exception, error) { l := s.ledger if err := ctx.Err(); err != nil { diff --git a/openapi.yaml b/openapi.yaml index 4bc4966..d7c6d83 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From 6988a2fb1ee88b8ae8f8d52752f6332a976100e0 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:09:07 +0300 Subject: [PATCH 177/287] feat(decisions): add customer-safe decision summary --- .productization_next_steps.md | 2 +- docs/api.md | 12 +++ docs/reference/api-contract-matrix.md | 3 +- docs/reference/vulnerability-decisions.md | 15 +++- internal/adapters/httpapi/openapi.go | 28 +++++++ .../adapters/httpapi/openapi_operations.go | 4 + .../adapters/httpapi/route_registration.go | 1 + internal/adapters/httpapi/router.go | 13 ++++ internal/adapters/httpapi/router_test.go | 12 ++- internal/app/ledger_test.go | 75 +++++++++++++++++++ internal/app/release_evidence_service.go | 4 + internal/app/vex.go | 72 ++++++++++++++++++ internal/domain/domain.go | 29 +++++++ openapi.yaml | 2 +- 14 files changed, 266 insertions(+), 6 deletions(-) diff --git a/.productization_next_steps.md b/.productization_next_steps.md index 9a06e7e..5d7f95a 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -374,7 +374,7 @@ Acceptance criteria: * Respects tenant and scopes. * OpenAPI updated. -#### [ ] EVY-015 — Add customer-safe decision summary endpoint +#### [x] EVY-015 — Add customer-safe decision summary endpoint Priority: P1 diff --git a/docs/api.md b/docs/api.md index 1534b83..69b71d3 100644 --- a/docs/api.md +++ b/docs/api.md @@ -192,6 +192,17 @@ The history endpoint supports `product_id`, `release_id`, `vulnerability`, records, including timestamps and supersession fields. It is tenant-scoped and requires `evidence:read`. +Customer-safe decision summary: + +```http +GET /v1/reports/vulnerability-decision-summary?release_id=rel_... +``` + +The summary endpoint returns only active decisions marked `customer_visible`. +It excludes `internal_notes`, raw payload bytes, object-store references, bearer +tokens, and private review context. The response includes assumptions and +limitations and is intended for package viewers and exports. + ### 4. Readiness And Bundle Retrieval Create a release bundle: @@ -309,6 +320,7 @@ Current SSO endpoints model admin-managed provider, identity-link, trust-materia | `GET` | `/v1/vulnerability-decisions` | List decision history by product, release, vulnerability, component, status, and active state. | | `POST` | `/v1/vulnerability-findings/{id}/workflow` | Append workflow event. | | `GET` | `/v1/reports/vulnerability-posture` | Summarize findings for a release. | +| `GET` | `/v1/reports/vulnerability-decision-summary` | Customer-safe active vulnerability decision summary for a release. | | `GET` | `/v1/reports/release-readiness` | Deterministic readiness report. | | `GET` | `/v1/reports/missing-evidence` | Missing evidence report for review. | | `POST` | `/v1/reports/anomaly` | Generate deterministic evidence anomaly signals. | diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index 21d42a8..0b698dc 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 167 operations: 167 precise, 0 broad. +Generated from 168 operations: 168 precise, 0 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -129,6 +129,7 @@ Generated from 167 operations: 167 precise, 0 broad. | GET | /v1/reports/release-readiness | releaseReadinessReport | Bearer | verify:read | - | query:release_id | - | 200:application/json:ReadinessReportEnvelope | precise | | GET | /v1/reports/retention | retentionReport | Bearer | admin | - | query:scope_id, query:scope_type | - | 200:application/json:RetentionReportEnvelope | precise | | GET | /v1/reports/security-review-package | securityReviewPackageReport | Bearer | package:read | - | query:package_id | - | 200:application/json:SecurityReviewPackageReportEnvelope | precise | +| GET | /v1/reports/vulnerability-decision-summary | vulnerabilityDecisionSummaryReport | Bearer | report:read | - | query:release_id | - | 200:application/json:VulnerabilityDecisionSummaryReportEnvelope | precise | | GET | /v1/reports/vulnerability-posture | vulnerabilityPostureReport | Bearer | security:read | - | query:release_id | - | 200:application/json:VulnerabilityPostureReportEnvelope | precise | | POST | /v1/retention-overrides | createRetentionOverride | Bearer | admin | required | - | application/json:CreateRetentionOverrideRequest | 201:application/json:RetentionOverrideEnvelope | precise | | GET | /v1/role-bindings | listRoleBindings | Bearer | identity:admin | - | - | - | 200:application/json:RoleBindingListEnvelope | precise | diff --git a/docs/reference/vulnerability-decisions.md b/docs/reference/vulnerability-decisions.md index 4f765ec..46863ea 100644 --- a/docs/reference/vulnerability-decisions.md +++ b/docs/reference/vulnerability-decisions.md @@ -86,6 +86,16 @@ decisions with no `superseded_by`; `active=false` returns superseded decisions. Product and release filters are validated against tenant-owned resources and the release must belong to the requested product when both filters are present. +## Customer-Safe Summary API + +`GET /v1/reports/vulnerability-decision-summary?release_id=...` returns active +decisions that are explicitly marked `customer_visible`. The response excludes +`internal_notes`, raw evidence payload bytes, object-store references, bearer +tokens, and private review context. It includes assumptions and limitations so +package viewers and exports can present the decisions without implying +certification, legal compliance proof, complete SBOM coverage, or authoritative +scanner coverage. + ## Current Gaps The current model is enough to support release-readiness gating, but it is not @@ -97,6 +107,9 @@ yet the full buyer-facing VEX decision workflow: summaries when the redaction profile explicitly allows `vulnerability_decision`. They exclude `internal_notes`, raw payload bytes, and bearer secrets. +- The dedicated customer-safe summary endpoint is release-scoped JSON. HTML, + PDF, and package-specific rendering remain handled by package/report + resources. - There is no review date or expiry on a decision. Expiry behavior currently lives on exceptions and waivers, not decisions. - Supporting evidence links currently reference evidence-item records. Links to @@ -105,8 +118,6 @@ yet the full buyer-facing VEX decision workflow: modeling or evidence wrappers before they can be attached directly. - The source SBOM is indirect through release/artifact relationships rather than a direct `sbom_id` link. -- Customer package exports can include package-scoped decision metadata, but a - dedicated customer-safe decision-summary endpoint does not exist. ## Concrete Follow-Up Changes diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 60b9bbd..11faeed 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -326,6 +326,34 @@ func registerCriticalSchemas(registry *specs.Registry) { }, "id", "tenant_id", "finding_id", "scan_id", "vulnerability", "status", "justification", "source", "schema_version", "created_at")) registry.RegisterSchema("VulnerabilityDecisionEnvelope", dataEnvelopeSchema("#/components/schemas/VulnerabilityDecision")) registry.RegisterSchema("VulnerabilityDecisionListEnvelope", dataArrayEnvelopeSchema("#/components/schemas/VulnerabilityDecision")) + registry.RegisterSchema("VulnerabilityDecisionCustomerSummary", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "finding_id": map[string]any{"type": "string"}, + "scan_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "vulnerability": map[string]any{"type": "string"}, + "component": map[string]any{"type": "string"}, + "status": map[string]any{"type": "string"}, + "justification": map[string]any{"type": "string"}, + "impact_statement": map[string]any{"type": "string"}, + "action_statement": map[string]any{"type": "string"}, + "source": map[string]any{"type": "string"}, + "evidence_id": map[string]any{"type": "string"}, + "evidence_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "vex_document_id": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "finding_id", "scan_id", "release_id", "vulnerability", "status", "impact_statement", "source", "created_at")) + registry.RegisterSchema("VulnerabilityDecisionSummaryReport", objectSchema(map[string]any{ + "report_type": map[string]any{"type": "string"}, + "template_version": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "decisions": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/VulnerabilityDecisionCustomerSummary"}}, + "assumptions": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "generated_at": map[string]any{"type": "string", "format": "date-time"}, + }, "report_type", "template_version", "product_id", "release_id", "decisions", "assumptions", "limitations", "generated_at")) + registry.RegisterSchema("VulnerabilityDecisionSummaryReportEnvelope", dataEnvelopeSchema("#/components/schemas/VulnerabilityDecisionSummaryReport")) registry.RegisterSchema("RecordVulnerabilityWorkflowRequest", objectSchema(map[string]any{ "action": map[string]any{"type": "string"}, "reason": map[string]any{"type": "string"}, diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 059a263..6e31f4e 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -601,6 +601,10 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Description = "Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records." operation.Parameters = append(operation.Parameters, queryParam("release_id", "Release id.", "string")) operation.Responses[http.StatusOK] = jsonResponse("Vulnerability posture report envelope.", "#/components/schemas/VulnerabilityPostureReportEnvelope") + case "vulnerabilityDecisionSummaryReport": + operation.Description = "Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded." + operation.Parameters = append(operation.Parameters, queryParam("release_id", "Release id.", "string")) + operation.Responses[http.StatusOK] = jsonResponse("Vulnerability decision summary report envelope.", "#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope") case "generateAnomalyReport": operation.Description = "Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations." operation.RequestBody = jsonRequest("Anomaly report creation request.", "#/components/schemas/CreateAnomalyReportRequest") diff --git a/internal/adapters/httpapi/route_registration.go b/internal/adapters/httpapi/route_registration.go index b493b76..aa9a640 100644 --- a/internal/adapters/httpapi/route_registration.go +++ b/internal/adapters/httpapi/route_registration.go @@ -213,6 +213,7 @@ func (s *Server) evidenceRiskPolicyRoutes() []routeDef { {http.MethodGet, "/v1/vulnerability-decisions", op("listVulnerabilityDecisions", http.MethodGet, "/v1/vulnerability-decisions", "List vulnerability decisions", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.listVulnerabilityDecisions)}, {http.MethodPost, "/v1/vulnerability-findings/{id}/workflow", op("recordVulnerabilityWorkflow", http.MethodPost, "/v1/vulnerability-findings/{id}/workflow", "Record vulnerability workflow event", []string{app.ScopeSecurityWrite}), http.HandlerFunc(s.recordVulnerabilityWorkflow)}, {http.MethodGet, "/v1/reports/vulnerability-posture", op("vulnerabilityPostureReport", http.MethodGet, "/v1/reports/vulnerability-posture", "Vulnerability posture report", []string{app.ScopeSecurityRead}), http.HandlerFunc(s.vulnerabilityPostureReport)}, + {http.MethodGet, "/v1/reports/vulnerability-decision-summary", op("vulnerabilityDecisionSummaryReport", http.MethodGet, "/v1/reports/vulnerability-decision-summary", "Customer-safe vulnerability decision summary", []string{app.ScopeReportRead}), http.HandlerFunc(s.vulnerabilityDecisionSummaryReport)}, {http.MethodPost, "/v1/openapi-contracts", op("uploadOpenAPIContract", http.MethodPost, "/v1/openapi-contracts", "Upload OpenAPI contract", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.uploadOpenAPIContract)}, {http.MethodGet, "/v1/openapi-contracts/{id}", op("getOpenAPIContract", http.MethodGet, "/v1/openapi-contracts/{id}", "Get OpenAPI contract", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.getOpenAPIContract)}, {http.MethodPost, "/v1/openapi-diffs", op("createOpenAPIDiff", http.MethodPost, "/v1/openapi-diffs", "Create OpenAPI contract diff", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.createOpenAPIDiff)}, diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index 3cc90c1..7b2a6fa 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -1551,6 +1551,19 @@ func (s *Server) vulnerabilityPostureReport(w http.ResponseWriter, r *http.Reque writeData(w, http.StatusOK, report) } +func (s *Server) vulnerabilityDecisionSummaryReport(w http.ResponseWriter, r *http.Request) { + actor, ok := s.authenticate(w, r) + if !ok { + return + } + report, err := s.ledger.VulnerabilityDecisionSummaryReport(r.Context(), actor, r.URL.Query().Get("release_id")) + if err != nil { + writeProblem(w, r, err) + return + } + writeData(w, http.StatusOK, report) +} + func (s *Server) uploadOpenAPIContract(w http.ResponseWriter, r *http.Request) { var req struct { ProductID string `json:"product_id"` diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 7ef6e76..bd4c6ae 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -86,7 +86,7 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { if _, ok := problemProps["request_id"]; !ok { t.Fatalf("Problem schema missing request_id: %#v", problemProps) } - for _, schemaName := range []string{"ReadinessStatusEnvelope", "BackupManifestEnvelope", "VerificationResultEnvelope", "ReadinessReportEnvelope", "CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "VulnerabilityDecisionListEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "UpdateSSOProviderTrustMaterialRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "ExchangeSSOCredentialRequest", "SSOCredentialExchangeEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "DataEnvelope"} { + for _, schemaName := range []string{"ReadinessStatusEnvelope", "BackupManifestEnvelope", "VerificationResultEnvelope", "ReadinessReportEnvelope", "CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "VulnerabilityDecisionListEnvelope", "VulnerabilityDecisionSummaryReportEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "UpdateSSOProviderTrustMaterialRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "ExchangeSSOCredentialRequest", "SSOCredentialExchangeEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "DataEnvelope"} { if _, ok := schemas[schemaName]; !ok { t.Fatalf("schema %s missing from OpenAPI components", schemaName) } @@ -137,6 +137,9 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { listVulnerabilityDecisions := operationMap(t, paths, "/v1/vulnerability-decisions", "get") assertQueryParams(t, listVulnerabilityDecisions, "product_id", "release_id", "vulnerability", "component", "status", "active") assertResponseRef(t, listVulnerabilityDecisions, "200", "#/components/schemas/VulnerabilityDecisionListEnvelope") + decisionSummary := operationMap(t, paths, "/v1/reports/vulnerability-decision-summary", "get") + assertQueryParams(t, decisionSummary, "release_id") + assertResponseRef(t, decisionSummary, "200", "#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope") uploadVEX := operationMap(t, paths, "/v1/vex", "post") assertRequestRef(t, uploadVEX, "#/components/schemas/EvidenceUploadRequest") assertResponseRef(t, uploadVEX, "201", "#/components/schemas/VEXDocumentEnvelope") @@ -647,6 +650,13 @@ func TestReleaseRiskDecisionHTTPFlow(t *testing.T) { } getJSON(t, server, secret, "/v1/vulnerability-decisions?active=maybe", http.StatusBadRequest) getJSON(t, server, secret, "/v1/vulnerability-decisions?status=not_a_status", http.StatusBadRequest) + summary := getJSON(t, server, secret, "/v1/reports/vulnerability-decision-summary?release_id="+releaseID, http.StatusOK) + if !strings.Contains(summary, `"report_type":"vulnerability_decision_summary"`) || !strings.Contains(summary, `"The vulnerable code path is not present in this release."`) { + t.Fatalf("decision summary missing customer-safe content: %s", summary) + } + if strings.Contains(summary, "private note") || strings.Contains(summary, "payload_ref") { + t.Fatalf("decision summary leaked internal notes or raw payload metadata: %s", summary) + } report = getJSON(t, server, secret, "/v1/reports/release-readiness?release_id="+releaseID, http.StatusOK) if !strings.Contains(report, `"result":"passed"`) { t.Fatalf("expected passed readiness report after decision: %s", report) diff --git a/internal/app/ledger_test.go b/internal/app/ledger_test.go index 083633e..ee376ce 100644 --- a/internal/app/ledger_test.go +++ b/internal/app/ledger_test.go @@ -732,6 +732,81 @@ func TestCustomerVisibleDecisionRequiresImpactAndRedactsInternalNotes(t *testing } } +func TestVulnerabilityDecisionSummaryReportRedactsInternalAndOnlyIncludesActiveVisible(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, release, _ := setupReleaseRiskFixture(t, ledger) + supporting, err := ledger.CreateEvidence(ctx, actor, CreateEvidenceInput{ + ProductID: release.ProductID, ReleaseID: release.ID, Type: "security_review", Title: "Runtime review", PayloadHash: sampleDigest("summary-support"), + }) + if err != nil { + t.Fatalf("supporting evidence: %v", err) + } + scan, err := ledger.UploadVulnerabilityScan(ctx, actor, []byte(`{ + "scanner":"grype", + "target_ref":"pkg:oci/payments-api", + "release_id":"`+release.ID+`", + "findings":[ + {"vulnerability":"CVE-2026-0104","component":"pkg:apk/openssl@3.1.0","severity":"critical","state":"open"}, + {"vulnerability":"CVE-2026-0105","component":"pkg:apk/zlib@1.2.13","severity":"critical","state":"open"} + ] + }`)) + if err != nil { + t.Fatalf("scan: %v", err) + } + first, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{ + Status: decisionStatusUnderInvestigation, + Justification: "review started", + ImpactStatement: "Initial customer impact statement.", + CustomerVisible: true, + InternalNotes: "old private note", + }) + if err != nil { + t.Fatalf("first decision: %v", err) + } + second, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{ + Status: decisionStatusNotAffected, + Justification: "runtime path not present", + ImpactStatement: "This release is not affected because the vulnerable runtime path is not included.", + ActionStatement: "No customer action is required for this finding.", + CustomerVisible: true, + InternalNotes: "replacement private note", + EvidenceIDs: []string{supporting.ID}, + }) + if err != nil { + t.Fatalf("second decision: %v", err) + } + if _, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[1].ID, CreateVulnerabilityDecisionInput{ + Status: decisionStatusFixed, + Justification: "fixed but not customer-visible yet", + InternalNotes: "hidden private note", + }); err != nil { + t.Fatalf("hidden decision: %v", err) + } + report, err := ledger.VulnerabilityDecisionSummaryReport(ctx, actor, release.ID) + if err != nil { + t.Fatalf("summary: %v", err) + } + if report.ProductID != release.ProductID || report.ReleaseID != release.ID || len(report.Decisions) != 1 { + t.Fatalf("summary scope/decision count mismatch: %#v", report) + } + got := report.Decisions[0] + if got.ID != second.ID || got.ImpactStatement != second.ImpactStatement || len(got.EvidenceIDs) != 1 || got.EvidenceIDs[0] != supporting.ID { + t.Fatalf("summary decision=%#v, want active customer-visible decision", got) + } + body, err := json.Marshal(report) + if err != nil { + t.Fatalf("marshal summary: %v", err) + } + text := string(body) + if strings.Contains(text, first.ImpactStatement) || strings.Contains(text, "private note") || strings.Contains(text, "hidden private note") { + t.Fatalf("summary leaked superseded or internal decision data: %s", body) + } + if !strings.Contains(text, "not certification") || !strings.Contains(text, second.ImpactStatement) { + t.Fatalf("summary missing limitations or active impact statement: %s", body) + } +} + func TestVulnerabilityDecisionLifecycleSupersedesAndPackagesOnlyActive(t *testing.T) { ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) ctx := context.Background() diff --git a/internal/app/release_evidence_service.go b/internal/app/release_evidence_service.go index 9c83cf0..666548a 100644 --- a/internal/app/release_evidence_service.go +++ b/internal/app/release_evidence_service.go @@ -110,6 +110,10 @@ func (l *Ledger) ListVulnerabilityDecisions(ctx context.Context, actor domain.Ac return l.releaseEvidenceService().ListVulnerabilityDecisions(ctx, actor, in) } +func (l *Ledger) VulnerabilityDecisionSummaryReport(ctx context.Context, actor domain.Actor, releaseID string) (domain.VulnerabilityDecisionSummaryReport, error) { + return l.releaseEvidenceService().VulnerabilityDecisionSummaryReport(ctx, actor, releaseID) +} + func (l *Ledger) CreateException(ctx context.Context, actor domain.Actor, in CreateExceptionInput) (domain.Exception, error) { return l.releaseEvidenceService().CreateException(ctx, actor, in) } diff --git a/internal/app/vex.go b/internal/app/vex.go index bc39a57..82809bb 100644 --- a/internal/app/vex.go +++ b/internal/app/vex.go @@ -358,6 +358,78 @@ func (s releaseEvidenceService) ListVulnerabilityDecisions(ctx context.Context, return out, nil } +func (s releaseEvidenceService) VulnerabilityDecisionSummaryReport(ctx context.Context, actor domain.Actor, releaseID string) (domain.VulnerabilityDecisionSummaryReport, error) { + l := s.ledger + if err := ctx.Err(); err != nil { + return domain.VulnerabilityDecisionSummaryReport{}, err + } + if err := require(actor, ScopeReportRead); err != nil { + return domain.VulnerabilityDecisionSummaryReport{}, err + } + releaseID = strings.TrimSpace(releaseID) + if releaseID == "" { + return domain.VulnerabilityDecisionSummaryReport{}, ErrValidation + } + l.mu.Lock() + defer l.mu.Unlock() + release, ok := l.releases[releaseID] + if !ok || release.TenantID != actor.TenantID { + return domain.VulnerabilityDecisionSummaryReport{}, ErrNotFound + } + if err := l.authorizeResourceLocked(actor, ScopeReportRead, resourceRefs{ProductID: release.ProductID, ReleaseID: release.ID}); err != nil { + return domain.VulnerabilityDecisionSummaryReport{}, err + } + decisions := []domain.VulnerabilityDecisionCustomerSummary{} + for _, decision := range l.decisions { + if decision.TenantID != actor.TenantID || decision.ReleaseID != release.ID || decision.SupersededBy != "" || !decision.CustomerVisible { + continue + } + decisions = append(decisions, customerDecisionSummary(decision)) + } + sort.Slice(decisions, func(i, j int) bool { + if decisions[i].CreatedAt.Equal(decisions[j].CreatedAt) { + return decisions[i].ID < decisions[j].ID + } + return decisions[i].CreatedAt.Before(decisions[j].CreatedAt) + }) + return domain.VulnerabilityDecisionSummaryReport{ + ReportType: "vulnerability_decision_summary", + TemplateVersion: "vulnerability-decision-summary.v1.0.0", + ProductID: release.ProductID, + ReleaseID: release.ID, + Decisions: decisions, + Assumptions: []string{ + "Only active vulnerability decisions marked customer_visible are included.", + "Evidence identifiers point to records in this Evydence instance; raw evidence payload bytes are not included.", + }, + Limitations: []string{ + "This summary supports compliance-readiness review; it is not certification, legal advice, complete SBOM proof, or authoritative vulnerability coverage.", + "Decision accuracy depends on tenant-supplied evidence, scanner inputs, and review quality.", + }, + GeneratedAt: l.now(), + }, nil +} + +func customerDecisionSummary(decision domain.VulnerabilityDecision) domain.VulnerabilityDecisionCustomerSummary { + return domain.VulnerabilityDecisionCustomerSummary{ + ID: decision.ID, + FindingID: decision.FindingID, + ScanID: decision.ScanID, + ReleaseID: decision.ReleaseID, + Vulnerability: decision.Vulnerability, + Component: decision.Component, + Status: decision.Status, + Justification: decision.Justification, + ImpactStatement: decision.ImpactStatement, + ActionStatement: decision.ActionStatement, + Source: decision.Source, + EvidenceID: decision.EvidenceID, + EvidenceIDs: append([]string(nil), decision.EvidenceIDs...), + VEXDocumentID: decision.VEXDocumentID, + CreatedAt: decision.CreatedAt, + } +} + func (s releaseEvidenceService) CreateException(ctx context.Context, actor domain.Actor, in CreateExceptionInput) (domain.Exception, error) { l := s.ledger if err := ctx.Err(); err != nil { diff --git a/internal/domain/domain.go b/internal/domain/domain.go index 13a654d..e4fe196 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -1113,6 +1113,35 @@ type VulnerabilityDecision struct { CreatedAt time.Time `json:"created_at"` } +type VulnerabilityDecisionCustomerSummary struct { + ID string `json:"id"` + FindingID string `json:"finding_id"` + ScanID string `json:"scan_id"` + ReleaseID string `json:"release_id"` + Vulnerability string `json:"vulnerability"` + Component string `json:"component,omitempty"` + Status string `json:"status"` + Justification string `json:"justification,omitempty"` + ImpactStatement string `json:"impact_statement"` + ActionStatement string `json:"action_statement,omitempty"` + Source string `json:"source"` + EvidenceID string `json:"evidence_id,omitempty"` + EvidenceIDs []string `json:"evidence_ids,omitempty"` + VEXDocumentID string `json:"vex_document_id,omitempty"` + CreatedAt time.Time `json:"created_at"` +} + +type VulnerabilityDecisionSummaryReport struct { + ReportType string `json:"report_type"` + TemplateVersion string `json:"template_version"` + ProductID string `json:"product_id"` + ReleaseID string `json:"release_id"` + Decisions []VulnerabilityDecisionCustomerSummary `json:"decisions"` + Assumptions []string `json:"assumptions"` + Limitations []string `json:"limitations"` + GeneratedAt time.Time `json:"generated_at"` +} + type OpenAPIContract struct { ID string `json:"id"` TenantID string `json:"tenant_id"` diff --git a/openapi.yaml b/openapi.yaml index d7c6d83..308f08a 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From 822b5b0a6567cd788371ee2fa52db7d56041ccf1 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:10:29 +0300 Subject: [PATCH 178/287] chore(sdk): refresh OpenAPI route catalog --- sdk/openapi-route-catalog.json | 36 +++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/sdk/openapi-route-catalog.json b/sdk/openapi-route-catalog.json index 71bf057..ff3f979 100644 --- a/sdk/openapi-route-catalog.json +++ b/sdk/openapi-route-catalog.json @@ -1,5 +1,5 @@ { - "route_count": 166, + "route_count": 168, "routes": [ { "idempotency_key_required": false, @@ -2061,6 +2061,23 @@ "200" ] }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "vulnerabilityDecisionSummaryReport", + "path": "/v1/reports/vulnerability-decision-summary", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope" + ], + "scopes": [ + "report:read" + ], + "success_statuses": [ + "200" + ] + }, { "idempotency_key_required": false, "method": "GET", @@ -2701,6 +2718,23 @@ "200" ] }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "listVulnerabilityDecisions", + "path": "/v1/vulnerability-decisions", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/VulnerabilityDecisionListEnvelope" + ], + "scopes": [ + "evidence:read" + ], + "success_statuses": [ + "200" + ] + }, { "idempotency_key_required": true, "method": "POST", From cdf51753aeed1222eb53ddabf76aeb2baeb8b9d5 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:13:24 +0300 Subject: [PATCH 179/287] feat(vex): add import parser reports --- .productization_next_steps.md | 2 +- cmd/evydence-worker/main.go | 93 +++++++++++++++++-- cmd/evydence-worker/main_test.go | 9 ++ docs/api.md | 11 +++ docs/reference/api-contract-matrix.md | 3 +- docs/reference/vulnerability-decisions.md | 25 +++++ docs/reference/worker-outbox.md | 2 +- internal/adapters/httpapi/openapi.go | 26 ++++++ .../adapters/httpapi/openapi_operations.go | 4 + .../adapters/httpapi/route_registration.go | 1 + internal/adapters/httpapi/router.go | 13 +++ internal/adapters/httpapi/router_test.go | 9 +- internal/adapters/postgres/store.go | 91 ++++++++++++++++++ internal/adapters/postgres/store_test.go | 18 +++- internal/app/ledger.go | 2 + internal/app/ledger_test.go | 84 ++++++++++++++++- internal/app/ports.go | 2 + internal/app/release_evidence_service.go | 4 + internal/app/state.go | 8 ++ internal/app/vex.go | 74 ++++++++++++++- internal/domain/domain.go | 28 ++++++ ...20260601000300_vex_import_reports.down.sql | 3 + .../20260601000300_vex_import_reports.up.sql | 26 ++++++ openapi.yaml | 2 +- sdk/openapi-route-catalog.json | 19 +++- 25 files changed, 537 insertions(+), 22 deletions(-) create mode 100644 migrations/20260601000300_vex_import_reports.down.sql create mode 100644 migrations/20260601000300_vex_import_reports.up.sql diff --git a/.productization_next_steps.md b/.productization_next_steps.md index 5d7f95a..55226e4 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -414,7 +414,7 @@ Acceptance criteria: * Duplicate import does not create duplicate active decisions. * Parser failures are visible and actionable. -#### [ ] EVY-021 — Add import report for VEX parsing +#### [x] EVY-021 — Add import report for VEX parsing Priority: P1 diff --git a/cmd/evydence-worker/main.go b/cmd/evydence-worker/main.go index 9af1d2b..c661ee1 100644 --- a/cmd/evydence-worker/main.go +++ b/cmd/evydence-worker/main.go @@ -260,13 +260,16 @@ func processJobInternal(ctx context.Context, state jobStateLoader, objects jobOb stateChanged = true } if payloadBool(job, "worker_create_decisions") { - created, err := applyReplayedVEXDecisions(&snapshot, job, vex, parsed, replayed.Digest) + created, superseded, mappingFailures, err := applyReplayedVEXDecisions(&snapshot, job, vex, parsed, replayed.Digest) if err != nil { return err } if created > 0 { stateChanged = true } + if updateVEXImportReport(&snapshot, job, vex, parsed, created, superseded, mappingFailures) { + stateChanged = true + } } } if err := requirePayloadHash(job, ""); err != nil { @@ -759,7 +762,7 @@ func replayedVEXProductIDs(products []map[string]any) map[string]struct{} { return out } -func applyReplayedVEXDecisions(state *app.PersistedState, job postgres.ClaimedJob, vex domain.VEXDocument, parsed replayedVEX, payloadHash string) (int, error) { +func applyReplayedVEXDecisions(state *app.PersistedState, job postgres.ClaimedJob, vex domain.VEXDocument, parsed replayedVEX, payloadHash string) (int, int, []domain.VEXImportIssue, error) { if state.Decisions == nil { state.Decisions = map[string]domain.VulnerabilityDecision{} } @@ -768,6 +771,8 @@ func applyReplayedVEXDecisions(state *app.PersistedState, job postgres.ClaimedJo evidenceID := payloadString(job, "evidence_id") now := time.Now().UTC() created := 0 + superseded := 0 + mappingFailures := []domain.VEXImportIssue{} scanIDs := make([]string, 0, len(state.Scans)) for id, scan := range state.Scans { if scan.TenantID == job.TenantID && scan.ReleaseID == vex.ReleaseID { @@ -775,7 +780,8 @@ func applyReplayedVEXDecisions(state *app.PersistedState, job postgres.ClaimedJo } } sort.Strings(scanIDs) - for _, statement := range parsed.Statements { + for index, statement := range parsed.Statements { + statementMatched := false for _, scanID := range scanIDs { scan := state.Scans[scanID] for _, finding := range scan.Findings { @@ -787,6 +793,7 @@ func applyReplayedVEXDecisions(state *app.PersistedState, job postgres.ClaimedJo continue } } + statementMatched = true if replayedVEXDecisionExists(state.Decisions, job.TenantID, vex.ID, finding.ID) { continue } @@ -825,18 +832,26 @@ func applyReplayedVEXDecisions(state *app.PersistedState, job postgres.ClaimedJo CreatedAt: now, } if supersedes != "" { + superseded++ if _, err := app.AppendPersistedChainEntry(state, now, job.TenantID, "vulnerability_decision.superseded", "vulnerability_decision", supersedes, actorType, actorID, payloadHash, ""); err != nil { - return created, errors.New("append replayed vex decision supersession audit entry") + return created, superseded, mappingFailures, errors.New("append replayed vex decision supersession audit entry") } } if _, err := app.AppendPersistedChainEntry(state, now, job.TenantID, "vulnerability_decision.created", "vulnerability_finding", finding.ID, actorType, actorID, payloadHash, ""); err != nil { - return created, errors.New("append replayed vex decision audit entry") + return created, superseded, mappingFailures, errors.New("append replayed vex decision audit entry") } created++ } } + if !statementMatched { + mappingFailures = append(mappingFailures, domain.VEXImportIssue{ + StatementIndex: index + 1, + Code: "finding_not_found", + Detail: "No matching vulnerability scan finding was found for this VEX statement.", + }) + } } - return created, nil + return created, superseded, mappingFailures, nil } func replayedVEXDecisionExists(decisions map[string]domain.VulnerabilityDecision, tenantID, vexID, findingID string) bool { @@ -848,6 +863,72 @@ func replayedVEXDecisionExists(decisions map[string]domain.VulnerabilityDecision return false } +func updateVEXImportReport(state *app.PersistedState, job postgres.ClaimedJob, vex domain.VEXDocument, parsed replayedVEX, created, superseded int, mappingFailures []domain.VEXImportIssue) bool { + reportID := payloadString(job, "import_report_id") + if reportID == "" { + for id, report := range state.VEXImportReports { + if report.TenantID == job.TenantID && report.VEXDocumentID == vex.ID { + reportID = id + break + } + } + } + if reportID == "" { + return false + } + if state.VEXImportReports == nil { + state.VEXImportReports = map[string]domain.VEXImportReport{} + } + report, ok := state.VEXImportReports[reportID] + if !ok || report.TenantID != job.TenantID || report.VEXDocumentID != vex.ID { + return false + } + updated := report + changed := false + if updated.Status != "parsed" { + updated.Status = "parsed" + changed = true + } + if updated.StatementCount != parsed.StatementCount { + updated.StatementCount = parsed.StatementCount + changed = true + } + if created > updated.DecisionsCreated { + updated.DecisionsCreated = created + changed = true + } + if superseded > updated.DecisionsSuperseded { + updated.DecisionsSuperseded = superseded + changed = true + } + if !vexImportIssuesEqual(updated.MappingFailures, mappingFailures) { + updated.MappingFailures = append([]domain.VEXImportIssue(nil), mappingFailures...) + changed = true + } + if updated.SchemaVersion == "" { + updated.SchemaVersion = domain.VEXImportReportSchemaVersion + changed = true + } + if !changed { + return false + } + updated.UpdatedAt = time.Now().UTC() + state.VEXImportReports[reportID] = updated + return true +} + +func vexImportIssuesEqual(a, b []domain.VEXImportIssue) bool { + if len(a) != len(b) { + return false + } + for i := range a { + if a[i] != b[i] { + return false + } + } + return true +} + func replayedVEXDecisionID(vexID, findingID, status string) string { sum := strings.TrimPrefix(digestBytes([]byte(vexID+"\n"+findingID+"\n"+status)), "sha256:") if len(sum) > 32 { diff --git a/cmd/evydence-worker/main_test.go b/cmd/evydence-worker/main_test.go index 36d04f2..508849d 100644 --- a/cmd/evydence-worker/main_test.go +++ b/cmd/evydence-worker/main_test.go @@ -276,6 +276,7 @@ func TestProcessJobWithObjectsParsesPayloadAndChecksDurableState(t *testing.T) { } func TestProcessJobWithObjectsCreatesVEXDecisionsIdempotently(t *testing.T) { + now := time.Date(2026, 5, 28, 12, 0, 0, 0, time.UTC) body := []byte(`{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex","author":"security@example.test","timestamp":"2026-05-28T12:00:00Z","version":1,"statements":[{"vulnerability":{"name":"CVE-1"},"products":[{"@id":"pkg:oci/api"}],"status":"fixed","justification":"fixed","impact_statement":"patched","action_statement":"ship"}]}`) hash := digestBytes(body) job := postgres.ClaimedJob{ @@ -291,12 +292,16 @@ func TestProcessJobWithObjectsCreatesVEXDecisionsIdempotently(t *testing.T) { "actor_type": "api_key", "actor_id": "key_test", "evidence_id": "ev_vex", + "import_report_id": "vex_report", }, } store := &fakeStateStore{ok: true, state: app.PersistedState{ VEXDocuments: map[string]domain.VEXDocument{ "vex_test": {ID: "vex_test", TenantID: "ten_test", ReleaseID: "rel_test", EvidenceID: "ev_vex", Format: "openvex"}, }, + VEXImportReports: map[string]domain.VEXImportReport{ + "vex_report": {ID: "vex_report", TenantID: "ten_test", VEXDocumentID: "vex_test", EvidenceID: "ev_vex", Status: "accepted", SchemaVersion: domain.VEXImportReportSchemaVersion, CreatedAt: now, UpdatedAt: now}, + }, Scans: map[string]domain.VulnerabilityScan{ "scan_test": {ID: "scan_test", TenantID: "ten_test", ReleaseID: "rel_test", Findings: []domain.VulnerabilityFinding{{ID: "finding_1", Vulnerability: "CVE-1", Component: "pkg:oci/api", Severity: "critical", State: "open"}}}, }, @@ -318,6 +323,10 @@ func TestProcessJobWithObjectsCreatesVEXDecisionsIdempotently(t *testing.T) { if got := len(store.saved.Chain["ten_test"]); got != 1 { t.Fatalf("chain entries = %d, want 1", got) } + report := store.saved.VEXImportReports["vex_report"] + if report.Status != "parsed" || report.StatementCount != 1 || report.DecisionsCreated != 1 || report.DecisionsSuperseded != 0 { + t.Fatalf("import report = %#v", report) + } previous := store.saved store.state = previous diff --git a/docs/api.md b/docs/api.md index 69b71d3..0d9f69e 100644 --- a/docs/api.md +++ b/docs/api.md @@ -192,6 +192,16 @@ The history endpoint supports `product_id`, `release_id`, `vulnerability`, records, including timestamps and supersession fields. It is tenant-scoped and requires `evidence:read`. +VEX import parser report: + +```http +GET /v1/vex/{id}/import-report +``` + +The import report records parser version, statement counts, decision counts, +supersession counts, warnings, invalid statement issues, and mapping failures. +It does not include raw VEX payload bytes or object-store payload references. + Customer-safe decision summary: ```http @@ -454,6 +464,7 @@ Source snapshots capture submitted provider metadata. They do not call provider | `POST` | `/v1/vex` | Upload OpenVEX. | | `POST` | `/v1/vex/cyclonedx` | Upload CycloneDX VEX. | | `GET` | `/v1/vex/{id}` | Read VEX metadata. | +| `GET` | `/v1/vex/{id}/import-report` | Read VEX parser report with safe counts, warnings, and mapping failures. | | `POST` | `/v1/openapi-contracts` | Upload OpenAPI contract. | | `GET` | `/v1/openapi-contracts/{id}` | Read contract metadata. | | `POST` | `/v1/openapi-diffs` | Compare stored contracts. | diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index 0b698dc..445f39c 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 168 operations: 168 precise, 0 broad. +Generated from 169 operations: 169 precise, 0 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -168,6 +168,7 @@ Generated from 168 operations: 168 precise, 0 broad. | POST | /v1/vex | uploadVEX | Bearer | evidence:write | required | - | application/json:EvidenceUploadRequest | 201:application/json:VEXDocumentEnvelope | precise | | POST | /v1/vex/cyclonedx | uploadCycloneDXVEX | Bearer | evidence:write | required | - | application/json:EvidenceUploadRequest | 201:application/json:VEXDocumentEnvelope | precise | | GET | /v1/vex/{id} | getVEX | Bearer | evidence:read | - | path:id | - | 200:application/json:VEXDocumentEnvelope | precise | +| GET | /v1/vex/{id}/import-report | getVEXImportReport | Bearer | evidence:read | - | path:id | - | 200:application/json:VEXImportReportEnvelope | precise | | GET | /v1/vulnerability-decisions | listVulnerabilityDecisions | Bearer | evidence:read | - | query:active, query:component, query:product_id, query:release_id, query:status, query:vulnerability | - | 200:application/json:VulnerabilityDecisionListEnvelope | precise | | POST | /v1/vulnerability-findings/{id}/decisions | createVulnerabilityDecision | Bearer | evidence:write | required | path:id | application/json:CreateVulnerabilityDecisionRequest | 201:application/json:VulnerabilityDecisionEnvelope | precise | | POST | /v1/vulnerability-findings/{id}/workflow | recordVulnerabilityWorkflow | Bearer | security:write | required | path:id | application/json:RecordVulnerabilityWorkflowRequest | 201:application/json:VulnerabilityWorkflowRecordEnvelope | precise | diff --git a/docs/reference/vulnerability-decisions.md b/docs/reference/vulnerability-decisions.md index 46863ea..60a77fa 100644 --- a/docs/reference/vulnerability-decisions.md +++ b/docs/reference/vulnerability-decisions.md @@ -39,6 +39,7 @@ finding: | Scan finding link | `finding_id` and `scan_id` link the decision to the normalized finding. | | Supporting evidence links | `evidence_ids` can link tenant-scoped supporting evidence from the same release. | | Audit history | Decision creation appends an audit-chain entry. | +| Import report | `GET /v1/vex/{id}/import-report` exposes safe parser counts, warnings, and mapping failures for OpenVEX imports. | ## Canonical Lifecycle @@ -86,6 +87,27 @@ decisions with no `superseded_by`; `active=false` returns superseded decisions. Product and release filters are validated against tenant-owned resources and the release must belong to the requested product when both filters are present. +## VEX Import Reports + +OpenVEX upload creates a durable import report. The report captures: + +- parser version; +- number of statements parsed; +- number of decisions created; +- number of decisions superseded; +- unsupported field names when they can be reported safely; +- warnings; +- invalid statement issue codes; +- mapping failures such as no matching scan finding. + +`GET /v1/vex/{id}/import-report` returns the report for operators with +`evidence:read`. The report is intentionally safe to show in operational review: +it excludes raw VEX payload bytes, object-store payload references, bearer +tokens, internal triage notes, and private evidence content. Worker-owned parser +mode initially stores the report as `accepted`; the worker updates it to +`parsed` after replaying the tenant-prefixed payload and applying idempotent +decision side effects. + ## Customer-Safe Summary API `GET /v1/reports/vulnerability-decision-summary?release_id=...` returns active @@ -103,6 +125,9 @@ yet the full buyer-facing VEX decision workflow: - Decision history can now be queried directly, but it is still a read-only operational API rather than a dedicated customer-facing export. +- VEX import reports are available for OpenVEX imports. CycloneDX VEX reports + use the same VEX document metadata path but still need format-specific issue + detail in a later increment. - Customer package manifests can include active `customer_visible` decision summaries when the redaction profile explicitly allows `vulnerability_decision`. They exclude `internal_notes`, raw payload bytes, diff --git a/docs/reference/worker-outbox.md b/docs/reference/worker-outbox.md index 04361cb..d2d2a00 100644 --- a/docs/reference/worker-outbox.md +++ b/docs/reference/worker-outbox.md @@ -12,7 +12,7 @@ Configured job kinds: - `verify_subject` - `verify_attestation` -Current behavior is intentionally conservative. The API still records normalized signing and verification results before enqueueing jobs for the implemented paths. Parser jobs independently replay tenant-prefixed payload objects when `payload_ref` is present, verify object metadata and byte digests when `payload_hash` is present, parse SBOM, vulnerability-scan, OpenAPI, OpenVEX, and DSSE attestation payloads, and check that replayed payload summaries match the expected durable state. When `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, parser-backed uploads store accepted records first and workers write parser-derived document fields after replay. The `parse_vex` worker also creates OpenVEX-derived vulnerability decisions idempotently in that mode. Missing objects, wrong tenant prefixes, tenant mismatches, oversized payload objects, malformed replay payloads, durable-state mismatches, incomplete verification, missing signatures, hash mismatch, uninitialized storage, and unsupported job kinds fail the job safely. +Current behavior is intentionally conservative. The API still records normalized signing and verification results before enqueueing jobs for the implemented paths. Parser jobs independently replay tenant-prefixed payload objects when `payload_ref` is present, verify object metadata and byte digests when `payload_hash` is present, parse SBOM, vulnerability-scan, OpenAPI, OpenVEX, and DSSE attestation payloads, and check that replayed payload summaries match the expected durable state. When `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, parser-backed uploads store accepted records first and workers write parser-derived document fields after replay. The `parse_vex` worker also creates OpenVEX-derived vulnerability decisions idempotently in that mode and updates the VEX import report from `accepted` to `parsed` with safe decision and mapping-failure counts. Missing objects, wrong tenant prefixes, tenant mismatches, oversized payload objects, malformed replay payloads, durable-state mismatches, incomplete verification, missing signatures, hash mismatch, uninitialized storage, and unsupported job kinds fail the job safely. Parser and attestation jobs include a deterministic `parser_version` payload field for new uploads. Workers reject unsupported parser versions and accept diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 11faeed..8c5e890 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -1780,6 +1780,32 @@ func registerCriticalSchemas(registry *specs.Registry) { "created_at": map[string]any{"type": "string", "format": "date-time"}, }, "id", "tenant_id", "evidence_id", "release_id", "format", "statement_count", "schema_version", "created_at")) registry.RegisterSchema("VEXDocumentEnvelope", dataEnvelopeSchema("#/components/schemas/VEXDocument")) + registry.RegisterSchema("VEXImportIssue", objectSchema(map[string]any{ + "statement_index": map[string]any{"type": "integer"}, + "code": map[string]any{"type": "string"}, + "detail": map[string]any{"type": "string"}, + }, "code", "detail")) + registry.RegisterSchema("VEXImportReport", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "vex_document_id": map[string]any{"type": "string"}, + "evidence_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "artifact_id": map[string]any{"type": "string"}, + "parser_version": map[string]any{"type": "string"}, + "status": map[string]any{"type": "string", "enum": []string{"accepted", "parsed", "failed"}}, + "statement_count": map[string]any{"type": "integer"}, + "decisions_created": map[string]any{"type": "integer"}, + "decisions_superseded": map[string]any{"type": "integer"}, + "unsupported_fields": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "warnings": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "invalid_statements": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/VEXImportIssue"}}, + "mapping_failures": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/VEXImportIssue"}}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + "updated_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "vex_document_id", "evidence_id", "parser_version", "status", "statement_count", "decisions_created", "decisions_superseded", "schema_version", "created_at", "updated_at")) + registry.RegisterSchema("VEXImportReportEnvelope", dataEnvelopeSchema("#/components/schemas/VEXImportReport")) registry.RegisterSchema("VulnerabilityScan", objectSchema(map[string]any{ "id": map[string]any{"type": "string"}, "tenant_id": map[string]any{"type": "string"}, diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 6e31f4e..1e0ce74 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -210,6 +210,10 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Description = "Returns a tenant-scoped VEX document metadata record by id." operation.Parameters = append(operation.Parameters, pathParam("id", "VEX document id.")) operation.Responses[http.StatusOK] = jsonResponse("VEX document envelope.", "#/components/schemas/VEXDocumentEnvelope") + case "getVEXImportReport": + operation.Description = "Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes." + operation.Parameters = append(operation.Parameters, pathParam("id", "VEX document id.")) + operation.Responses[http.StatusOK] = jsonResponse("VEX import report envelope.", "#/components/schemas/VEXImportReportEnvelope") case "uploadVulnerabilityScan": operation.Description = "Uploads a generic vulnerability scan JSON payload and records normalized findings." operation.RequestBody = jsonRequest("Vulnerability scan upload payload.", "#/components/schemas/UploadVulnerabilityScanRequest") diff --git a/internal/adapters/httpapi/route_registration.go b/internal/adapters/httpapi/route_registration.go index aa9a640..6af1464 100644 --- a/internal/adapters/httpapi/route_registration.go +++ b/internal/adapters/httpapi/route_registration.go @@ -207,6 +207,7 @@ func (s *Server) evidenceRiskPolicyRoutes() []routeDef { {http.MethodPost, "/v1/vex", op("uploadVEX", http.MethodPost, "/v1/vex", "Upload OpenVEX document", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.uploadVEX)}, {http.MethodPost, "/v1/vex/cyclonedx", op("uploadCycloneDXVEX", http.MethodPost, "/v1/vex/cyclonedx", "Upload CycloneDX VEX document", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.uploadCycloneDXVEX)}, {http.MethodGet, "/v1/vex/{id}", op("getVEX", http.MethodGet, "/v1/vex/{id}", "Get VEX document", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.getVEX)}, + {http.MethodGet, "/v1/vex/{id}/import-report", op("getVEXImportReport", http.MethodGet, "/v1/vex/{id}/import-report", "Get VEX import report", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.getVEXImportReport)}, {http.MethodPost, "/v1/vulnerability-scans", op("uploadVulnerabilityScan", http.MethodPost, "/v1/vulnerability-scans", "Upload vulnerability scan", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.uploadVulnerabilityScan)}, {http.MethodGet, "/v1/vulnerability-scans/{id}", op("getVulnerabilityScan", http.MethodGet, "/v1/vulnerability-scans/{id}", "Get vulnerability scan", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.getVulnerabilityScan)}, {http.MethodPost, "/v1/vulnerability-findings/{id}/decisions", op("createVulnerabilityDecision", http.MethodPost, "/v1/vulnerability-findings/{id}/decisions", "Create vulnerability decision", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.createVulnerabilityDecision)}, diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index 7b2a6fa..c5552db 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -1432,6 +1432,19 @@ func (s *Server) getVEX(w http.ResponseWriter, r *http.Request) { writeData(w, http.StatusOK, vex) } +func (s *Server) getVEXImportReport(w http.ResponseWriter, r *http.Request) { + actor, ok := s.authenticate(w, r) + if !ok { + return + } + report, err := s.ledger.GetVEXImportReport(r.Context(), actor, r.PathValue("id")) + if err != nil { + writeProblem(w, r, err) + return + } + writeData(w, http.StatusOK, report) +} + func (s *Server) uploadCycloneDXVEX(w http.ResponseWriter, r *http.Request) { var req struct { ReleaseID string `json:"release_id"` diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index bd4c6ae..360d91a 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -86,7 +86,7 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { if _, ok := problemProps["request_id"]; !ok { t.Fatalf("Problem schema missing request_id: %#v", problemProps) } - for _, schemaName := range []string{"ReadinessStatusEnvelope", "BackupManifestEnvelope", "VerificationResultEnvelope", "ReadinessReportEnvelope", "CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "VulnerabilityDecisionListEnvelope", "VulnerabilityDecisionSummaryReportEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "UpdateSSOProviderTrustMaterialRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "ExchangeSSOCredentialRequest", "SSOCredentialExchangeEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "DataEnvelope"} { + for _, schemaName := range []string{"ReadinessStatusEnvelope", "BackupManifestEnvelope", "VerificationResultEnvelope", "ReadinessReportEnvelope", "CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "VEXImportReportEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "VulnerabilityDecisionListEnvelope", "VulnerabilityDecisionSummaryReportEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "UpdateSSOProviderTrustMaterialRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "ExchangeSSOCredentialRequest", "SSOCredentialExchangeEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "DataEnvelope"} { if _, ok := schemas[schemaName]; !ok { t.Fatalf("schema %s missing from OpenAPI components", schemaName) } @@ -143,6 +143,9 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { uploadVEX := operationMap(t, paths, "/v1/vex", "post") assertRequestRef(t, uploadVEX, "#/components/schemas/EvidenceUploadRequest") assertResponseRef(t, uploadVEX, "201", "#/components/schemas/VEXDocumentEnvelope") + getVEXImportReport := operationMap(t, paths, "/v1/vex/{id}/import-report", "get") + assertQueryParams(t, getVEXImportReport, "id") + assertResponseRef(t, getVEXImportReport, "200", "#/components/schemas/VEXImportReportEnvelope") createEvidence := operationMap(t, paths, "/v1/evidence", "post") assertRequestRef(t, createEvidence, "#/components/schemas/CreateEvidenceRequest") assertProblemResponseRef(t, createEvidence, "400") @@ -752,6 +755,10 @@ func TestVEXAndExceptionHTTPValidation(t *testing.T) { }, http.StatusCreated) vexID := dataField(t, vexBody, "id") getJSON(t, server, secret, "/v1/vex/"+vexID, http.StatusOK) + importReport := getJSON(t, server, secret, "/v1/vex/"+vexID+"/import-report", http.StatusOK) + if !strings.Contains(importReport, `"status":"parsed"`) || !strings.Contains(importReport, `"decisions_created":1`) || strings.Contains(importReport, "payload_ref") { + t.Fatalf("unsafe or incomplete VEX import report: %s", importReport) + } postJSON(t, server, secret, "/v1/vex", "vex-bad", map[string]any{"release_id": releaseID, "payload": map[string]any{"author": "a", "timestamp": "2026-05-27T12:00:00Z", "statements": []any{}, "extra": true}}, http.StatusBadRequest) exceptionBody := postJSON(t, server, secret, "/v1/exceptions", "exception-create", map[string]any{"release_id": releaseID, "reason": "temporary acceptance", "owner": "security", "expires_at": time.Now().UTC().Add(time.Hour).Format(time.RFC3339)}, http.StatusCreated) diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index 5fd0c3d..e00490b 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -280,6 +280,7 @@ func relationalEmptyState() app.PersistedState { SBOMs: map[string]domain.SBOM{}, Scans: map[string]domain.VulnerabilityScan{}, VEXDocuments: map[string]domain.VEXDocument{}, + VEXImportReports: map[string]domain.VEXImportReport{}, Decisions: map[string]domain.VulnerabilityDecision{}, Contracts: map[string]domain.OpenAPIContract{}, Policies: map[string]domain.PolicyEvaluation{}, @@ -1110,6 +1111,47 @@ func (s *Store) loadRelationalRiskDecisions(ctx context.Context, state *app.Pers return err } + reportRows, err := s.pool.Query(ctx, ` + SELECT id, tenant_id, vex_document_id, evidence_id, release_id, artifact_id, + parser_version, status, statement_count, decisions_created, + decisions_superseded, unsupported_fields, warnings, invalid_statements, + mapping_failures, schema_version, created_at, updated_at + FROM vex_import_reports + `) + if err != nil { + return fmt.Errorf("load relational vex import reports: %w", err) + } + defer reportRows.Close() + for reportRows.Next() { + var report domain.VEXImportReport + var releaseID, artifactID sql.NullString + var warnings, invalidStatements, mappingFailures []byte + if err := reportRows.Scan( + &report.ID, &report.TenantID, &report.VEXDocumentID, &report.EvidenceID, &releaseID, &artifactID, + &report.ParserVersion, &report.Status, &report.StatementCount, &report.DecisionsCreated, + &report.DecisionsSuperseded, &report.UnsupportedFields, &warnings, &invalidStatements, + &mappingFailures, &report.SchemaVersion, &report.CreatedAt, &report.UpdatedAt, + ); err != nil { + return fmt.Errorf("scan relational vex import report: %w", err) + } + report.ReleaseID = nullableSQLString(releaseID) + report.ArtifactID = nullableSQLString(artifactID) + if err := decodeJSON(warnings, &report.Warnings); err != nil { + return fmt.Errorf("decode relational vex import warnings: %w", err) + } + if err := decodeJSON(invalidStatements, &report.InvalidStatements); err != nil { + return fmt.Errorf("decode relational vex import invalid statements: %w", err) + } + if err := decodeJSON(mappingFailures, &report.MappingFailures); err != nil { + return fmt.Errorf("decode relational vex import mapping failures: %w", err) + } + state.VEXImportReports[report.ID] = report + *loaded = true + } + if err := reportRows.Err(); err != nil { + return err + } + decisionRows, err := s.pool.Query(ctx, ` SELECT id, tenant_id, finding_id, scan_id, release_id, vulnerability, component, status, justification, impact_statement, action_statement, @@ -2711,6 +2753,9 @@ func releaseLedgerMutationState(mutation app.ReleaseLedgerMutation) app.Persiste for _, vex := range mutation.VEXDocuments { state.VEXDocuments[vex.ID] = vex } + for _, report := range mutation.VEXImportReports { + state.VEXImportReports[report.ID] = report + } for _, decision := range mutation.VulnerabilityDecisions { state.Decisions[decision.ID] = decision } @@ -3172,6 +3217,52 @@ func syncRiskBuildControlRows(ctx context.Context, tx pgx.Tx, state app.Persiste return fmt.Errorf("upsert vex document row: %w", err) } } + for _, report := range state.VEXImportReports { + if report.ID == "" || report.TenantID == "" || report.VEXDocumentID == "" || report.EvidenceID == "" { + continue + } + warnings, err := json.Marshal(report.Warnings) + if err != nil { + return fmt.Errorf("encode vex import warnings: %w", err) + } + invalidStatements, err := json.Marshal(report.InvalidStatements) + if err != nil { + return fmt.Errorf("encode vex import invalid statements: %w", err) + } + mappingFailures, err := json.Marshal(report.MappingFailures) + if err != nil { + return fmt.Errorf("encode vex import mapping failures: %w", err) + } + if _, err := tx.Exec(ctx, ` + INSERT INTO vex_import_reports ( + id, tenant_id, vex_document_id, evidence_id, release_id, artifact_id, + parser_version, status, statement_count, decisions_created, + decisions_superseded, unsupported_fields, warnings, invalid_statements, + mapping_failures, schema_version, created_at, updated_at + ) + VALUES ( + $1, $2, $3, $4, $5, $6, + $7, $8, $9, $10, + $11, $12, $13, $14, + $15, $16, $17, $18 + ) + ON CONFLICT (id) DO UPDATE SET + status = EXCLUDED.status, + statement_count = EXCLUDED.statement_count, + decisions_created = EXCLUDED.decisions_created, + decisions_superseded = EXCLUDED.decisions_superseded, + unsupported_fields = EXCLUDED.unsupported_fields, + warnings = EXCLUDED.warnings, + invalid_statements = EXCLUDED.invalid_statements, + mapping_failures = EXCLUDED.mapping_failures, + updated_at = EXCLUDED.updated_at + `, report.ID, report.TenantID, report.VEXDocumentID, report.EvidenceID, nullableString(report.ReleaseID), nullableString(report.ArtifactID), + report.ParserVersion, report.Status, report.StatementCount, report.DecisionsCreated, + report.DecisionsSuperseded, report.UnsupportedFields, warnings, invalidStatements, + mappingFailures, report.SchemaVersion, nonZeroTime(report.CreatedAt), nonZeroTime(report.UpdatedAt)); err != nil { + return fmt.Errorf("upsert vex import report row: %w", err) + } + } for _, decision := range state.Decisions { if decision.ID == "" || decision.TenantID == "" || decision.FindingID == "" || decision.ScanID == "" { continue diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index ff6b205..cd37849 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -405,6 +405,9 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { VEXDocuments: map[string]domain.VEXDocument{ "vex_test": {ID: "vex_test", TenantID: "ten_test", EvidenceID: "ev_test", ReleaseID: "rel_test", ArtifactID: "art_test", Format: "openvex", Author: "tester", Version: "1", StatementCount: 1, StatusSummary: map[string]int{"not_affected": 1}, SchemaVersion: domain.VEXDocumentSchemaVersion, CreatedAt: time.Now().UTC()}, }, + VEXImportReports: map[string]domain.VEXImportReport{ + "vex_report_test": {ID: "vex_report_test", TenantID: "ten_test", VEXDocumentID: "vex_test", EvidenceID: "ev_test", ReleaseID: "rel_test", ArtifactID: "art_test", ParserVersion: app.ParserVersionOpenVEXJSON, Status: "parsed", StatementCount: 1, DecisionsCreated: 1, MappingFailures: []domain.VEXImportIssue{{StatementIndex: 2, Code: "finding_not_found", Detail: "No matching finding."}}, SchemaVersion: domain.VEXImportReportSchemaVersion, CreatedAt: time.Now().UTC(), UpdatedAt: time.Now().UTC()}, + }, Decisions: map[string]domain.VulnerabilityDecision{ "decision_test": {ID: "decision_test", TenantID: "ten_test", FindingID: "finding_test", ScanID: "scan_test", ReleaseID: "rel_test", Vulnerability: "CVE-0000-0001", Component: "lib", Status: "not_affected", Justification: "not_present", Source: "manual", EvidenceID: "ev_test", VEXDocumentID: "vex_test", SchemaVersion: domain.VulnerabilityDecisionVersion, CreatedAt: time.Now().UTC()}, }, @@ -631,6 +634,7 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { {name: "sbom", query: `SELECT count(*) FROM sboms WHERE tenant_id = 'ten_test' AND release_id = 'rel_test' AND component_count = 1`}, {name: "scan", query: `SELECT count(*) FROM vulnerability_scans WHERE tenant_id = 'ten_test' AND release_id = 'rel_test'`}, {name: "vex", query: `SELECT count(*) FROM vex_documents WHERE tenant_id = 'ten_test' AND id = 'vex_test' AND statement_count = 1`}, + {name: "vex report", query: `SELECT count(*) FROM vex_import_reports WHERE tenant_id = 'ten_test' AND id = 'vex_report_test' AND decisions_created = 1`}, {name: "decision", query: `SELECT count(*) FROM vulnerability_decisions WHERE tenant_id = 'ten_test' AND id = 'decision_test' AND status = 'not_affected'`}, {name: "exception", query: `SELECT count(*) FROM exceptions WHERE tenant_id = 'ten_test' AND id = 'exception_test' AND approved = true`}, {name: "contract", query: `SELECT count(*) FROM openapi_contracts WHERE tenant_id = 'ten_test' AND id = 'contract_test' AND operations <> '[]'::jsonb`}, @@ -748,8 +752,8 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { if relational.Products["prod_test"].Slug != "product" || relational.Evidence["ev_test"].ReleaseID != "rel_test" || relational.SBOMs["sbom_test"].ComponentCount != 1 { t.Fatalf("relational fallback missing core rows: product=%#v evidence=%#v sbom=%#v", relational.Products["prod_test"], relational.Evidence["ev_test"], relational.SBOMs["sbom_test"]) } - if relational.VEXDocuments["vex_test"].StatusSummary["not_affected"] != 1 || relational.Decisions["decision_test"].Status != "not_affected" || !relational.Exceptions["exception_test"].Approved { - t.Fatalf("relational risk rows missing: vex=%#v decision=%#v exception=%#v", relational.VEXDocuments["vex_test"], relational.Decisions["decision_test"], relational.Exceptions["exception_test"]) + if relational.VEXDocuments["vex_test"].StatusSummary["not_affected"] != 1 || relational.VEXImportReports["vex_report_test"].DecisionsCreated != 1 || relational.Decisions["decision_test"].Status != "not_affected" || !relational.Exceptions["exception_test"].Approved { + t.Fatalf("relational risk rows missing: vex=%#v report=%#v decision=%#v exception=%#v", relational.VEXDocuments["vex_test"], relational.VEXImportReports["vex_report_test"], relational.Decisions["decision_test"], relational.Exceptions["exception_test"]) } if relational.ControlFrameworks["framework_test"].Slug != "framework" || len(relational.SecurityControls["control_test"].EvidenceRequirements) != 1 || relational.ControlEvidence["control_evidence_test"].Confidence != "high" { t.Fatalf("relational control rows missing: framework=%#v control=%#v evidence=%#v", relational.ControlFrameworks["framework_test"], relational.SecurityControls["control_test"], relational.ControlEvidence["control_evidence_test"]) @@ -1112,6 +1116,11 @@ func TestApplyReleaseLedgerMutationWithPostgres(t *testing.T) { Format: "openvex", Author: "security", Version: "1", StatementCount: 1, StatusSummary: map[string]int{"not_affected": 1}, SchemaVersion: domain.VEXDocumentSchemaVersion, CreatedAt: now, }}, + VEXImportReports: []domain.VEXImportReport{{ + ID: "vex_report_focus", TenantID: "ten_release_focus", VEXDocumentID: "vex_focus", EvidenceID: "ev_focus", ReleaseID: "rel_focus", + ParserVersion: app.ParserVersionOpenVEXJSON, Status: "parsed", StatementCount: 1, DecisionsCreated: 1, + SchemaVersion: domain.VEXImportReportSchemaVersion, CreatedAt: now, UpdatedAt: now, + }}, VulnerabilityDecisions: []domain.VulnerabilityDecision{{ ID: "decision_release_focus", TenantID: "ten_release_focus", FindingID: "finding_focus", ScanID: "scan_focus", ReleaseID: "rel_focus", Vulnerability: "CVE-2099-0001", Component: "lib", Status: "not_affected", @@ -1157,6 +1166,7 @@ func TestApplyReleaseLedgerMutationWithPostgres(t *testing.T) { {name: "scan", query: `SELECT count(*) FROM vulnerability_scans WHERE id = 'scan_focus' AND release_id = 'rel_focus'`}, {name: "contract", query: `SELECT count(*) FROM openapi_contracts WHERE id = 'oas_focus' AND path_count = 1`}, {name: "vex", query: `SELECT count(*) FROM vex_documents WHERE id = 'vex_focus' AND statement_count = 1`}, + {name: "vex report", query: `SELECT count(*) FROM vex_import_reports WHERE id = 'vex_report_focus' AND decisions_created = 1`}, {name: "decision", query: `SELECT count(*) FROM vulnerability_decisions WHERE id = 'decision_release_focus' AND status = 'not_affected'`}, {name: "audit chain", query: `SELECT count(*) FROM audit_chain_entries WHERE id = 'chain_release_focus'`}, {name: "outbox", query: `SELECT count(*) FROM outbox_jobs WHERE id = 'job_release_focus' AND status = 'queued'`}, @@ -1185,8 +1195,8 @@ func TestApplyReleaseLedgerMutationWithPostgres(t *testing.T) { if loaded.Products["prod_focus"].Slug != "payments" || loaded.Evidence["ev_focus"].CanonicalHash == "" || len(loaded.EvidenceLifecycle) != 1 { t.Fatalf("loaded release ledger core missing: product=%#v evidence=%#v lifecycle=%#v", loaded.Products["prod_focus"], loaded.Evidence["ev_focus"], loaded.EvidenceLifecycle) } - if loaded.SBOMs["sbom_focus"].ComponentCount != 1 || loaded.Scans["scan_focus"].ReleaseID != "rel_focus" || loaded.Contracts["oas_focus"].PathCount != 1 || loaded.VEXDocuments["vex_focus"].StatementCount != 1 { - t.Fatalf("loaded parser metadata missing: sbom=%#v scan=%#v contract=%#v vex=%#v", loaded.SBOMs["sbom_focus"], loaded.Scans["scan_focus"], loaded.Contracts["oas_focus"], loaded.VEXDocuments["vex_focus"]) + if loaded.SBOMs["sbom_focus"].ComponentCount != 1 || loaded.Scans["scan_focus"].ReleaseID != "rel_focus" || loaded.Contracts["oas_focus"].PathCount != 1 || loaded.VEXDocuments["vex_focus"].StatementCount != 1 || loaded.VEXImportReports["vex_report_focus"].DecisionsCreated != 1 { + t.Fatalf("loaded parser metadata missing: sbom=%#v scan=%#v contract=%#v vex=%#v report=%#v", loaded.SBOMs["sbom_focus"], loaded.Scans["scan_focus"], loaded.Contracts["oas_focus"], loaded.VEXDocuments["vex_focus"], loaded.VEXImportReports["vex_report_focus"]) } if loaded.Decisions["decision_release_focus"].Status != "not_affected" || len(loaded.Chain["ten_release_focus"]) != 1 { t.Fatalf("loaded decision/chain missing: decision=%#v chain=%#v", loaded.Decisions["decision_release_focus"], loaded.Chain["ten_release_focus"]) diff --git a/internal/app/ledger.go b/internal/app/ledger.go index 10b3d9d..d4b0646 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -171,6 +171,7 @@ type Ledger struct { sboms map[string]domain.SBOM scans map[string]domain.VulnerabilityScan vexDocuments map[string]domain.VEXDocument + vexImportReports map[string]domain.VEXImportReport decisions map[string]domain.VulnerabilityDecision contracts map[string]domain.OpenAPIContract policies map[string]domain.PolicyEvaluation @@ -297,6 +298,7 @@ func NewLedgerWithError(cfg Config) (*Ledger, error) { sboms: map[string]domain.SBOM{}, scans: map[string]domain.VulnerabilityScan{}, vexDocuments: map[string]domain.VEXDocument{}, + vexImportReports: map[string]domain.VEXImportReport{}, decisions: map[string]domain.VulnerabilityDecision{}, contracts: map[string]domain.OpenAPIContract{}, policies: map[string]domain.PolicyEvaluation{}, diff --git a/internal/app/ledger_test.go b/internal/app/ledger_test.go index ee376ce..a9b0fbb 100644 --- a/internal/app/ledger_test.go +++ b/internal/app/ledger_test.go @@ -1082,7 +1082,7 @@ func TestOpenVEXIngestionCreatesDecisionAndRejectsMalformedInput(t *testing.T) { }`)); err != nil { t.Fatalf("scan: %v", err) } - if _, err := ledger.UploadVEX(ctx, actor, release.ID, artifact.ID, []byte(`{ + vex, err := ledger.UploadVEX(ctx, actor, release.ID, artifact.ID, []byte(`{ "@context":"https://openvex.dev/ns/v0.2.0", "@id":"https://example.test/vex/1", "author":"security@example.test", @@ -1096,9 +1096,17 @@ func TestOpenVEXIngestionCreatesDecisionAndRejectsMalformedInput(t *testing.T) { "impact_statement":"patched before release", "action_statement":"ship fixed artifact" }] - }`)); err != nil { + }`)) + if err != nil { t.Fatalf("vex: %v", err) } + importReport, err := ledger.GetVEXImportReport(ctx, actor, vex.ID) + if err != nil { + t.Fatalf("import report: %v", err) + } + if importReport.Status != "parsed" || importReport.StatementCount != 1 || importReport.DecisionsCreated != 1 || importReport.DecisionsSuperseded != 0 || len(importReport.MappingFailures) != 0 { + t.Fatalf("unexpected import report: %#v", importReport) + } report, err := ledger.ReleaseReadinessReport(ctx, actor, release.ID) if err != nil { t.Fatalf("readiness: %v", err) @@ -1111,6 +1119,69 @@ func TestOpenVEXIngestionCreatesDecisionAndRejectsMalformedInput(t *testing.T) { } } +func TestOpenVEXImportReportTracksSupersessionAndMappingFailures(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, release, artifact := setupReleaseRiskFixture(t, ledger) + scan, err := ledger.UploadVulnerabilityScan(ctx, actor, []byte(`{ + "scanner":"grype", + "target_ref":"pkg:oci/payments-api", + "release_id":"`+release.ID+`", + "findings":[{"vulnerability":"CVE-2026-0003","component":"pkg:apk/openssl@3.1.0","severity":"critical","state":"open"}] + }`)) + if err != nil { + t.Fatalf("scan: %v", err) + } + if _, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{ + Status: decisionStatusUnderInvestigation, + Justification: "manual triage started", + ImpactStatement: "The finding is under investigation.", + CustomerVisible: true, + }); err != nil { + t.Fatalf("manual decision: %v", err) + } + vex, err := ledger.UploadVEX(ctx, actor, release.ID, artifact.ID, []byte(`{ + "@context":"https://openvex.dev/ns/v0.2.0", + "@id":"https://example.test/vex/2", + "author":"security@example.test", + "timestamp":"2026-05-27T12:00:00Z", + "version":1, + "statements":[{ + "vulnerability":{"name":"CVE-2026-0003"}, + "products":[{"@id":"pkg:apk/openssl@3.1.0"}], + "status":"fixed", + "justification":"fixed in release candidate", + "impact_statement":"patched before release" + },{ + "vulnerability":{"name":"CVE-2026-9999"}, + "products":[{"@id":"pkg:apk/missing@1.0.0"}], + "status":"not_affected", + "justification":"component not present", + "impact_statement":"not present in this release" + }] + }`)) + if err != nil { + t.Fatalf("vex: %v", err) + } + report, err := ledger.GetVEXImportReport(ctx, actor, vex.ID) + if err != nil { + t.Fatalf("import report: %v", err) + } + if report.StatementCount != 2 || report.DecisionsCreated != 1 || report.DecisionsSuperseded != 1 { + t.Fatalf("report counts = %#v", report) + } + if len(report.MappingFailures) != 1 || report.MappingFailures[0].StatementIndex != 2 || report.MappingFailures[0].Code != "finding_not_found" { + t.Fatalf("mapping failures = %#v", report.MappingFailures) + } + body, err := json.Marshal(report) + if err != nil { + t.Fatalf("marshal report: %v", err) + } + if strings.Contains(string(body), "payload") || strings.Contains(string(body), "manual triage") { + t.Fatalf("import report leaked raw payload or internal triage details: %s", body) + } +} + func TestUploadVEXCanDeferDocumentParserSideEffectsToWorker(t *testing.T) { outbox := &recordingOutbox{} store := NewMemoryStore() @@ -1169,6 +1240,13 @@ func TestUploadVEXCanDeferDocumentParserSideEffectsToWorker(t *testing.T) { if persisted.Author != "" || persisted.StatementCount != 0 || persisted.StatusSummary != nil { t.Fatalf("persisted vex document should wait for worker parser side effects: %#v", persisted) } + importReport, err := ledger.GetVEXImportReport(ctx, actor, vex.ID) + if err != nil { + t.Fatalf("import report: %v", err) + } + if importReport.Status != "accepted" || importReport.StatementCount != 1 || importReport.DecisionsCreated != 0 || len(importReport.Warnings) == 0 { + t.Fatalf("worker-owned import report = %#v", importReport) + } decisionFound := false for _, decision := range state.Decisions { if decision.FindingID == scan.Findings[0].ID && decision.VEXDocumentID == vex.ID && decision.Status == decisionStatusFixed { @@ -1182,7 +1260,7 @@ func TestUploadVEXCanDeferDocumentParserSideEffectsToWorker(t *testing.T) { t.Fatalf("outbox jobs = %d, want 1", len(outbox.jobs)) } job := outbox.jobs[0] - if job.Kind != "parse_vex" || job.Payload["payload_ref"] == "" || job.Payload["payload_hash"] == "" || job.Payload["parser_version"] != ParserVersionOpenVEXJSON || job.Payload["worker_create_decisions"] != true { + if job.Kind != "parse_vex" || job.Payload["payload_ref"] == "" || job.Payload["payload_hash"] == "" || job.Payload["parser_version"] != ParserVersionOpenVEXJSON || job.Payload["worker_create_decisions"] != true || job.Payload["import_report_id"] == "" { t.Fatalf("outbox job missing replay metadata: %#v", job) } payloadRef, ok := job.Payload["payload_ref"].(string) diff --git a/internal/app/ports.go b/internal/app/ports.go index 470d980..71ba6a8 100644 --- a/internal/app/ports.go +++ b/internal/app/ports.go @@ -218,6 +218,7 @@ type PersistedState struct { SBOMs map[string]domain.SBOM `json:"sboms"` Scans map[string]domain.VulnerabilityScan `json:"scans"` VEXDocuments map[string]domain.VEXDocument `json:"vex_documents"` + VEXImportReports map[string]domain.VEXImportReport `json:"vex_import_reports"` Decisions map[string]domain.VulnerabilityDecision `json:"vulnerability_decisions"` Contracts map[string]domain.OpenAPIContract `json:"contracts"` Policies map[string]domain.PolicyEvaluation `json:"policies"` @@ -344,6 +345,7 @@ type ReleaseLedgerMutation struct { Scans []domain.VulnerabilityScan Contracts []domain.OpenAPIContract VEXDocuments []domain.VEXDocument + VEXImportReports []domain.VEXImportReport VulnerabilityDecisions []domain.VulnerabilityDecision AuditChainEntries []domain.AuditChainEntry OutboxJobs []OutboxJob diff --git a/internal/app/release_evidence_service.go b/internal/app/release_evidence_service.go index 666548a..a0ca187 100644 --- a/internal/app/release_evidence_service.go +++ b/internal/app/release_evidence_service.go @@ -102,6 +102,10 @@ func (l *Ledger) GetVEXDocument(ctx context.Context, actor domain.Actor, id stri return l.releaseEvidenceService().GetVEXDocument(ctx, actor, id) } +func (l *Ledger) GetVEXImportReport(ctx context.Context, actor domain.Actor, vexID string) (domain.VEXImportReport, error) { + return l.releaseEvidenceService().GetVEXImportReport(ctx, actor, vexID) +} + func (l *Ledger) CreateVulnerabilityDecision(ctx context.Context, actor domain.Actor, findingID string, in CreateVulnerabilityDecisionInput) (domain.VulnerabilityDecision, error) { return l.releaseEvidenceService().CreateVulnerabilityDecision(ctx, actor, findingID, in) } diff --git a/internal/app/state.go b/internal/app/state.go index d9007df..95fb188 100644 --- a/internal/app/state.go +++ b/internal/app/state.go @@ -108,6 +108,7 @@ func (l *Ledger) snapshotLocked() PersistedState { SBOMs: l.sboms, Scans: l.scans, VEXDocuments: l.vexDocuments, + VEXImportReports: l.vexImportReports, Decisions: l.decisions, Contracts: l.contracts, Policies: l.policies, @@ -264,6 +265,7 @@ func (l *Ledger) applyState(state PersistedState) { l.sboms = state.SBOMs l.scans = state.Scans l.vexDocuments = state.VEXDocuments + l.vexImportReports = state.VEXImportReports l.decisions = state.Decisions l.contracts = state.Contracts l.policies = state.Policies @@ -364,6 +366,9 @@ func releaseLedgerMutationFromState(state PersistedState) ReleaseLedgerMutation for _, vex := range state.VEXDocuments { mutation.VEXDocuments = append(mutation.VEXDocuments, vex) } + for _, report := range state.VEXImportReports { + mutation.VEXImportReports = append(mutation.VEXImportReports, report) + } for _, decision := range state.Decisions { mutation.VulnerabilityDecisions = append(mutation.VulnerabilityDecisions, decision) } @@ -740,6 +745,9 @@ func normalizeState(state PersistedState) PersistedState { if state.VEXDocuments == nil { state.VEXDocuments = map[string]domain.VEXDocument{} } + if state.VEXImportReports == nil { + state.VEXImportReports = map[string]domain.VEXImportReport{} + } if state.Decisions == nil { state.Decisions = map[string]domain.VulnerabilityDecision{} } diff --git a/internal/app/vex.go b/internal/app/vex.go index 82809bb..9caef90 100644 --- a/internal/app/vex.go +++ b/internal/app/vex.go @@ -176,9 +176,15 @@ func (s releaseEvidenceService) UploadVEX(ctx context.Context, actor domain.Acto } l.vexDocuments[vex.ID] = persistedVEX createdDecisions := 0 + supersededDecisions := 0 + mappingFailures := []domain.VEXImportIssue{} if !l.workerOwnedParsers { - for _, statement := range doc.Statements { - for _, matched := range l.findMatchingFindingsLocked(actor.TenantID, releaseID, statement) { + for index, statement := range doc.Statements { + matches := l.findMatchingFindingsLocked(actor.TenantID, releaseID, statement) + if len(matches) == 0 { + mappingFailures = append(mappingFailures, vexImportIssue(index+1, "finding_not_found", "No matching vulnerability scan finding was found for this VEX statement.")) + } + for _, matched := range matches { decision := l.createDecisionLocked(actor.TenantID, matched.scan, matched.finding, CreateVulnerabilityDecisionInput{ Status: statement.Status, Justification: statement.Justification, @@ -187,13 +193,46 @@ func (s releaseEvidenceService) UploadVEX(ctx context.Context, actor domain.Acto CustomerVisible: strings.TrimSpace(statement.ImpactStatement) != "", }, "vex", actorID(actor), item.ID, vex.ID) l.decisions[decision.ID] = decision + if decision.Supersedes != "" { + supersededDecisions++ + } l.appendDecisionLifecycleAuditLocked(actor.TenantID, decision, matched.finding.ID, actorType(actor), actorID(actor), payloadHash) createdDecisions++ } } + } else { + for index, statement := range doc.Statements { + if len(l.findMatchingFindingsLocked(actor.TenantID, releaseID, statement)) == 0 { + mappingFailures = append(mappingFailures, vexImportIssue(index+1, "finding_not_found", "No matching vulnerability scan finding was found for this VEX statement at upload time.")) + } + } } + warnings := []string{} + if l.workerOwnedParsers { + warnings = append(warnings, "Worker-owned parser side effects are enabled; decisions are created asynchronously after payload replay.") + } + report := domain.VEXImportReport{ + ID: newID("vexrep"), + TenantID: actor.TenantID, + VEXDocumentID: vex.ID, + EvidenceID: item.ID, + ReleaseID: releaseID, + ArtifactID: artifactID, + ParserVersion: ParserVersionOpenVEXJSON, + Status: ternary(l.workerOwnedParsers, "accepted", "parsed"), + StatementCount: len(doc.Statements), + DecisionsCreated: createdDecisions, + DecisionsSuperseded: supersededDecisions, + UnsupportedFields: []string{}, + Warnings: warnings, + MappingFailures: mappingFailures, + SchemaVersion: domain.VEXImportReportSchemaVersion, + CreatedAt: l.now(), + UpdatedAt: l.now(), + } + l.vexImportReports[report.ID] = report _, _ = l.appendChainLocked(actor.TenantID, chainAction, "vex_document", vex.ID, actorType(actor), actorID(actor), payloadHash, "") - jobPayload := map[string]any{"payload_ref": payloadRef, "payload_hash": payloadHash, "parser_version": ParserVersionOpenVEXJSON, "decisions_created": createdDecisions} + jobPayload := map[string]any{"payload_ref": payloadRef, "payload_hash": payloadHash, "parser_version": ParserVersionOpenVEXJSON, "decisions_created": createdDecisions, "import_report_id": report.ID} if l.workerOwnedParsers { jobPayload["worker_create_decisions"] = true jobPayload["actor_type"] = actorType(actor) @@ -207,6 +246,31 @@ func (s releaseEvidenceService) UploadVEX(ctx context.Context, actor domain.Acto return vex, nil } +func (s releaseEvidenceService) GetVEXImportReport(ctx context.Context, actor domain.Actor, vexID string) (domain.VEXImportReport, error) { + l := s.ledger + if err := ctx.Err(); err != nil { + return domain.VEXImportReport{}, err + } + if err := require(actor, ScopeEvidenceRead); err != nil { + return domain.VEXImportReport{}, err + } + l.mu.Lock() + defer l.mu.Unlock() + vex, ok := l.vexDocuments[strings.TrimSpace(vexID)] + if !ok || vex.TenantID != actor.TenantID { + return domain.VEXImportReport{}, ErrNotFound + } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceRead, resourceRefs{ReleaseID: vex.ReleaseID}); err != nil { + return domain.VEXImportReport{}, err + } + for _, report := range l.vexImportReports { + if report.TenantID == actor.TenantID && report.VEXDocumentID == vex.ID { + return report, nil + } + } + return domain.VEXImportReport{}, ErrNotFound +} + func (s releaseEvidenceService) GetVEXDocument(ctx context.Context, actor domain.Actor, id string) (domain.VEXDocument, error) { l := s.ledger if err := ctx.Err(); err != nil { @@ -763,6 +827,10 @@ func decisionEvidenceIDs(primary string, extra []string) []string { return sortedUniqueNonEmptyStrings(ids) } +func vexImportIssue(statementIndex int, code, detail string) domain.VEXImportIssue { + return domain.VEXImportIssue{StatementIndex: statementIndex, Code: code, Detail: detail} +} + func sortedUniqueNonEmptyStrings(in []string) []string { set := map[string]struct{}{} for _, value := range in { diff --git a/internal/domain/domain.go b/internal/domain/domain.go index e4fe196..27f9d24 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -9,6 +9,7 @@ const ( CanonicalizationProfileVersion = "canonicalization-profile.v1.0.0" PolicySetVersion = "policy-set.v1.0.0" VEXDocumentSchemaVersion = "vex-document.v1.0.0" + VEXImportReportSchemaVersion = "vex-import-report.v1.0.0" VulnerabilityDecisionVersion = "vulnerability-decision.v1.0.0" ReleaseReadinessTemplateVersion = "release-readiness.v1.0.0" CollectorSchemaVersion = "collector.v1.0.0" @@ -1088,6 +1089,33 @@ type VEXDocument struct { CreatedAt time.Time `json:"created_at"` } +type VEXImportIssue struct { + StatementIndex int `json:"statement_index,omitempty"` + Code string `json:"code"` + Detail string `json:"detail"` +} + +type VEXImportReport struct { + ID string `json:"id"` + TenantID string `json:"tenant_id"` + VEXDocumentID string `json:"vex_document_id"` + EvidenceID string `json:"evidence_id"` + ReleaseID string `json:"release_id,omitempty"` + ArtifactID string `json:"artifact_id,omitempty"` + ParserVersion string `json:"parser_version"` + Status string `json:"status"` + StatementCount int `json:"statement_count"` + DecisionsCreated int `json:"decisions_created"` + DecisionsSuperseded int `json:"decisions_superseded"` + UnsupportedFields []string `json:"unsupported_fields,omitempty"` + Warnings []string `json:"warnings,omitempty"` + InvalidStatements []VEXImportIssue `json:"invalid_statements,omitempty"` + MappingFailures []VEXImportIssue `json:"mapping_failures,omitempty"` + SchemaVersion string `json:"schema_version"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` +} + type VulnerabilityDecision struct { ID string `json:"id"` TenantID string `json:"tenant_id"` diff --git a/migrations/20260601000300_vex_import_reports.down.sql b/migrations/20260601000300_vex_import_reports.down.sql new file mode 100644 index 0000000..a7268b2 --- /dev/null +++ b/migrations/20260601000300_vex_import_reports.down.sql @@ -0,0 +1,3 @@ +DROP INDEX IF EXISTS vex_import_reports_tenant_release_idx; +DROP INDEX IF EXISTS vex_import_reports_tenant_vex_idx; +DROP TABLE IF EXISTS vex_import_reports; diff --git a/migrations/20260601000300_vex_import_reports.up.sql b/migrations/20260601000300_vex_import_reports.up.sql new file mode 100644 index 0000000..0666eeb --- /dev/null +++ b/migrations/20260601000300_vex_import_reports.up.sql @@ -0,0 +1,26 @@ +CREATE TABLE IF NOT EXISTS vex_import_reports ( + id text PRIMARY KEY, + tenant_id text NOT NULL, + vex_document_id text NOT NULL, + evidence_id text NOT NULL, + release_id text, + artifact_id text, + parser_version text NOT NULL, + status text NOT NULL, + statement_count integer NOT NULL DEFAULT 0, + decisions_created integer NOT NULL DEFAULT 0, + decisions_superseded integer NOT NULL DEFAULT 0, + unsupported_fields text[] NOT NULL DEFAULT ARRAY[]::text[], + warnings jsonb NOT NULL DEFAULT '[]'::jsonb, + invalid_statements jsonb NOT NULL DEFAULT '[]'::jsonb, + mapping_failures jsonb NOT NULL DEFAULT '[]'::jsonb, + schema_version text NOT NULL, + created_at timestamptz NOT NULL DEFAULT now(), + updated_at timestamptz NOT NULL DEFAULT now() +); + +CREATE INDEX IF NOT EXISTS vex_import_reports_tenant_vex_idx + ON vex_import_reports(tenant_id, vex_document_id); + +CREATE INDEX IF NOT EXISTS vex_import_reports_tenant_release_idx + ON vex_import_reports(tenant_id, release_id, created_at); diff --git a/openapi.yaml b/openapi.yaml index 308f08a..d43c41f 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/sdk/openapi-route-catalog.json b/sdk/openapi-route-catalog.json index ff3f979..3d1f9e9 100644 --- a/sdk/openapi-route-catalog.json +++ b/sdk/openapi-route-catalog.json @@ -1,5 +1,5 @@ { - "route_count": 168, + "route_count": 169, "routes": [ { "idempotency_key_required": false, @@ -2718,6 +2718,23 @@ "200" ] }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "getVEXImportReport", + "path": "/v1/vex/{id}/import-report", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/VEXImportReportEnvelope" + ], + "scopes": [ + "evidence:read" + ], + "success_statuses": [ + "200" + ] + }, { "idempotency_key_required": false, "method": "GET", From 6bbee3a1f291b9571b1c515b8cc92a045a0a2494 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:14:33 +0300 Subject: [PATCH 180/287] test(vex): cover OpenVEX decision mapping --- .productization_next_steps.md | 2 +- .../adapters/httpapi/openapi_operations.go | 41 ++- internal/adapters/httpapi/router_test.go | 17 + internal/app/vex.go | 78 ++++- internal/app/vex_mapping_test.go | 301 ++++++++++++++++++ openapi.yaml | 2 +- 6 files changed, 423 insertions(+), 18 deletions(-) create mode 100644 internal/app/vex_mapping_test.go diff --git a/.productization_next_steps.md b/.productization_next_steps.md index 55226e4..df290c5 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -437,7 +437,7 @@ Acceptance criteria: * Worker terminal failure contains useful problem details. * End-to-end example shows report. -#### [ ] EVY-022 — Add VEX mapping tests +#### [x] EVY-022 — Add VEX mapping tests Priority: P1 diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 1e0ce74..07485de 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -202,9 +202,22 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Description = "Returns a tenant-scoped SBOM metadata record by id." operation.Parameters = append(operation.Parameters, pathParam("id", "SBOM id.")) operation.Responses[http.StatusOK] = jsonResponse("SBOM envelope.", "#/components/schemas/SBOMEnvelope") - case "uploadVEX", "uploadCycloneDXVEX": + case "uploadVEX": operation.Description = "Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable." - operation.RequestBody = jsonRequest("VEX upload request.", "#/components/schemas/EvidenceUploadRequest") + operation.RequestBody = jsonRequest("OpenVEX upload request.", "#/components/schemas/EvidenceUploadRequest") + operation.RequestBody.Content["application/json"] = specs.MediaType{ + SchemaRef: "#/components/schemas/EvidenceUploadRequest", + Examples: map[string]any{ + "openvex-fixed-decision": specs.Example{ + Summary: "Imported OpenVEX fixed decision", + Value: openVEXUploadExample(), + }, + }, + } + operation.Responses[http.StatusCreated] = jsonResponse("Created VEX document envelope.", "#/components/schemas/VEXDocumentEnvelope") + case "uploadCycloneDXVEX": + operation.Description = "Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable." + operation.RequestBody = jsonRequest("CycloneDX VEX upload request.", "#/components/schemas/EvidenceUploadRequest") operation.Responses[http.StatusCreated] = jsonResponse("Created VEX document envelope.", "#/components/schemas/VEXDocumentEnvelope") case "getVEX": operation.Description = "Returns a tenant-scoped VEX document metadata record by id." @@ -787,6 +800,30 @@ func jsonRequest(description, schemaRef string) *specs.RequestBody { } } +func openVEXUploadExample() map[string]any { + return map[string]any{ + "release_id": "rel_20260527120000", + "artifact_id": "art_20260527120000", + "payload": map[string]any{ + "@context": "https://openvex.dev/ns/v0.2.0", + "@id": "https://example.test/vex/payments-api/1.0.0", + "author": "security@example.test", + "timestamp": "2026-05-27T12:00:00Z", + "version": 1, + "statements": []map[string]any{ + { + "vulnerability": map[string]any{"name": "CVE-2026-0002"}, + "products": []map[string]any{{"@id": "pkg:apk/openssl@3.1.0"}}, + "status": "fixed", + "justification": "fixed_in_release_candidate", + "impact_statement": "Patched before this release candidate.", + "action_statement": "Ship the fixed artifact after operator review.", + }, + }, + }, + } +} + func jsonResponse(description, schemaRef string) specs.Response { return specs.Response{ Description: description, diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 360d91a..6269fdd 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -142,6 +142,7 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { assertResponseRef(t, decisionSummary, "200", "#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope") uploadVEX := operationMap(t, paths, "/v1/vex", "post") assertRequestRef(t, uploadVEX, "#/components/schemas/EvidenceUploadRequest") + assertRequestExampleContains(t, uploadVEX, "openvex-fixed-decision", "CVE-2026-0002") assertResponseRef(t, uploadVEX, "201", "#/components/schemas/VEXDocumentEnvelope") getVEXImportReport := operationMap(t, paths, "/v1/vex/{id}/import-report", "get") assertQueryParams(t, getVEXImportReport, "id") @@ -1603,6 +1604,22 @@ func assertRequestRef(t *testing.T, operation map[string]any, wantRef string) { } } +func assertRequestExampleContains(t *testing.T, operation map[string]any, exampleName, want string) { + t.Helper() + body := asStringAnyMap(t, operation["requestBody"]) + content := asStringAnyMap(t, body["content"]) + media := asStringAnyMap(t, content["application/json"]) + examples := asStringAnyMap(t, media["examples"]) + example := asStringAnyMap(t, examples[exampleName]) + raw, err := json.Marshal(example["value"]) + if err != nil { + t.Fatalf("marshal example %s: %v", exampleName, err) + } + if !strings.Contains(string(raw), want) { + t.Fatalf("example %s does not contain %q: %s", exampleName, want, raw) + } +} + func assertProblemResponseRef(t *testing.T, operation map[string]any, status string) { t.Helper() assertMediaResponseRef(t, operation, status, "application/problem+json", "#/components/schemas/Problem") diff --git a/internal/app/vex.go b/internal/app/vex.go index 9caef90..b0e6b24 100644 --- a/internal/app/vex.go +++ b/internal/app/vex.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "encoding/json" + "fmt" "io" "sort" "strconv" @@ -178,13 +179,24 @@ func (s releaseEvidenceService) UploadVEX(ctx context.Context, actor domain.Acto createdDecisions := 0 supersededDecisions := 0 mappingFailures := []domain.VEXImportIssue{} + warnings := []string{} if !l.workerOwnedParsers { + createdForFinding := map[string]struct{}{} + duplicateWarningAdded := false for index, statement := range doc.Statements { matches := l.findMatchingFindingsLocked(actor.TenantID, releaseID, statement) if len(matches) == 0 { mappingFailures = append(mappingFailures, vexImportIssue(index+1, "finding_not_found", "No matching vulnerability scan finding was found for this VEX statement.")) } for _, matched := range matches { + if _, seen := createdForFinding[matched.finding.ID]; seen { + if !duplicateWarningAdded { + warnings = append(warnings, "Duplicate VEX statements for an already mapped finding were ignored.") + duplicateWarningAdded = true + } + continue + } + createdForFinding[matched.finding.ID] = struct{}{} decision := l.createDecisionLocked(actor.TenantID, matched.scan, matched.finding, CreateVulnerabilityDecisionInput{ Status: statement.Status, Justification: statement.Justification, @@ -207,7 +219,6 @@ func (s releaseEvidenceService) UploadVEX(ctx context.Context, actor domain.Acto } } } - warnings := []string{} if l.workerOwnedParsers { warnings = append(warnings, "Worker-owned parser side effects are enabled; decisions are created asynchronously after payload replay.") } @@ -647,33 +658,72 @@ func parseOpenVEX(raw []byte) (openVEXDocument, error) { dec := json.NewDecoder(bytes.NewReader(raw)) dec.DisallowUnknownFields() if err := dec.Decode(&doc); err != nil { - return openVEXDocument{}, ErrValidation + return openVEXDocument{}, vexValidationError("openvex JSON is malformed or contains unsupported fields") } if err := dec.Decode(&struct{}{}); err != io.EOF { - return openVEXDocument{}, ErrValidation + return openVEXDocument{}, vexValidationError("openvex JSON must contain a single document") + } + doc.Author = strings.TrimSpace(doc.Author) + doc.Timestamp = strings.TrimSpace(doc.Timestamp) + if doc.Author == "" { + return openVEXDocument{}, vexValidationError("openvex author is required") } - if strings.TrimSpace(doc.Author) == "" || strings.TrimSpace(doc.Timestamp) == "" || len(doc.Statements) == 0 { - return openVEXDocument{}, ErrValidation + if doc.Timestamp == "" { + return openVEXDocument{}, vexValidationError("openvex timestamp is required") + } + if len(doc.Statements) == 0 { + return openVEXDocument{}, vexValidationError("openvex must include at least one statement") } if _, err := time.Parse(time.RFC3339, doc.Timestamp); err != nil { - return openVEXDocument{}, ErrValidation + return openVEXDocument{}, vexValidationError("openvex timestamp must be RFC3339") } - for _, statement := range doc.Statements { - if strings.TrimSpace(statement.Vulnerability.Name) == "" || !validDecisionStatus(statement.Status) || strings.TrimSpace(statement.Justification) == "" { - return openVEXDocument{}, ErrValidation + for index := range doc.Statements { + statement := &doc.Statements[index] + statement.Vulnerability.Name = strings.TrimSpace(statement.Vulnerability.Name) + statement.Status = strings.TrimSpace(statement.Status) + statement.Justification = strings.TrimSpace(statement.Justification) + statement.ImpactStatement = strings.TrimSpace(statement.ImpactStatement) + statement.ActionStatement = strings.TrimSpace(statement.ActionStatement) + if statement.Vulnerability.Name == "" { + return openVEXDocument{}, vexStatementValidationError(index+1, "is missing a vulnerability name") + } + if !validDecisionStatus(statement.Status) { + return openVEXDocument{}, vexStatementValidationError(index+1, "has an unsupported status") + } + if statement.Justification == "" { + return openVEXDocument{}, vexStatementValidationError(index+1, "is missing a justification") } if len(statement.Products) == 0 { - return openVEXDocument{}, ErrValidation + return openVEXDocument{}, vexStatementValidationError(index+1, "is missing products") } - for _, product := range statement.Products { - if strings.TrimSpace(product.ID) == "" { - return openVEXDocument{}, ErrValidation - } + if err := validateOpenVEXProducts(index+1, statement.Products); err != nil { + return openVEXDocument{}, err } } return doc, nil } +func validateOpenVEXProducts(statementIndex int, products []openVEXProduct) error { + for index := range products { + products[index].ID = strings.TrimSpace(products[index].ID) + if products[index].ID == "" { + return vexValidationError(fmt.Sprintf("openvex statement %d product %d is missing an @id", statementIndex, index+1)) + } + if err := validateOpenVEXProducts(statementIndex, products[index].Subcomponents); err != nil { + return err + } + } + return nil +} + +func vexStatementValidationError(index int, detail string) error { + return vexValidationError(fmt.Sprintf("openvex statement %d %s", index, detail)) +} + +func vexValidationError(detail string) error { + return fmt.Errorf("%s: %w", detail, ErrValidation) +} + func validDecisionStatus(status string) bool { switch strings.TrimSpace(status) { case decisionStatusAffected, decisionStatusNotAffected, decisionStatusFixed, decisionStatusUnderInvestigation: diff --git a/internal/app/vex_mapping_test.go b/internal/app/vex_mapping_test.go new file mode 100644 index 0000000..6795a7f --- /dev/null +++ b/internal/app/vex_mapping_test.go @@ -0,0 +1,301 @@ +package app + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "strings" + "testing" + + "github.com/aatuh/evydence/internal/domain" +) + +func TestOpenVEXStatusMappingFixtures(t *testing.T) { + tests := []struct { + name string + status string + justification string + }{ + {name: "not affected", status: decisionStatusNotAffected, justification: "component_not_present"}, + {name: "affected", status: decisionStatusAffected, justification: "vulnerable_code_present"}, + {name: "fixed", status: decisionStatusFixed, justification: "fixed_in_release"}, + {name: "under investigation", status: decisionStatusUnderInvestigation, justification: "triage_in_progress"}, + } + + for index, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, release, artifact := setupReleaseRiskFixture(t, ledger) + vulnerability := fmt.Sprintf("CVE-2026-%04d", index+100) + component := fmt.Sprintf("pkg:apk/component-%d@1.0.0", index) + uploadVEXMappingScan(t, ctx, ledger, actor, release.ID, vulnerability, component) + + vex, err := ledger.UploadVEX(ctx, actor, release.ID, artifact.ID, openVEXFixture(t, []map[string]any{ + openVEXStatementFixture(vulnerability, []map[string]any{{"@id": component}}, tt.status, tt.justification), + })) + if err != nil { + t.Fatalf("upload vex: %v", err) + } + + active := true + decisions, err := ledger.ListVulnerabilityDecisions(ctx, actor, ListVulnerabilityDecisionsInput{ + ReleaseID: release.ID, + Vulnerability: vulnerability, + Active: &active, + }) + if err != nil { + t.Fatalf("list decisions: %v", err) + } + if len(decisions) != 1 { + t.Fatalf("decisions = %#v, want one", decisions) + } + decision := decisions[0] + if decision.Status != tt.status || decision.Source != "vex" || decision.VEXDocumentID != vex.ID || decision.Justification != tt.justification || !decision.CustomerVisible { + t.Fatalf("decision = %#v", decision) + } + report, err := ledger.GetVEXImportReport(ctx, actor, vex.ID) + if err != nil { + t.Fatalf("import report: %v", err) + } + if report.StatementCount != 1 || report.DecisionsCreated != 1 || len(report.MappingFailures) != 0 { + t.Fatalf("import report = %#v", report) + } + }) + } +} + +func TestOpenVEXMappingMultipleProductsAndReleaseScope(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, releaseA, artifact := setupReleaseRiskFixture(t, ledger) + releaseB, err := ledger.CreateRelease(ctx, actor, releaseA.ProductID, "2.0.0") + if err != nil { + t.Fatalf("release B: %v", err) + } + vulnerability := "CVE-2026-0200" + componentA := "pkg:oci/payments-api@sha256:a" + componentB := "pkg:oci/payments-api@sha256:b" + uploadVEXMappingScan(t, ctx, ledger, actor, releaseA.ID, vulnerability, componentA) + uploadVEXMappingScan(t, ctx, ledger, actor, releaseB.ID, vulnerability, componentB) + + vex, err := ledger.UploadVEX(ctx, actor, releaseA.ID, artifact.ID, openVEXFixture(t, []map[string]any{ + openVEXStatementFixture(vulnerability, []map[string]any{ + {"@id": "pkg:oci/aggregate", "subcomponents": []map[string]any{{"@id": componentA}}}, + {"@id": componentB}, + }, decisionStatusFixed, "fixed_in_release"), + })) + if err != nil { + t.Fatalf("upload vex: %v", err) + } + + active := true + releaseADecisions, err := ledger.ListVulnerabilityDecisions(ctx, actor, ListVulnerabilityDecisionsInput{ReleaseID: releaseA.ID, Vulnerability: vulnerability, Active: &active}) + if err != nil { + t.Fatalf("list release A decisions: %v", err) + } + releaseBDecisions, err := ledger.ListVulnerabilityDecisions(ctx, actor, ListVulnerabilityDecisionsInput{ReleaseID: releaseB.ID, Vulnerability: vulnerability, Active: &active}) + if err != nil { + t.Fatalf("list release B decisions: %v", err) + } + if len(releaseADecisions) != 1 || releaseADecisions[0].Component != componentA { + t.Fatalf("release A decisions = %#v", releaseADecisions) + } + if len(releaseBDecisions) != 0 { + t.Fatalf("VEX uploaded for release A created release B decisions: %#v", releaseBDecisions) + } + report, err := ledger.GetVEXImportReport(ctx, actor, vex.ID) + if err != nil { + t.Fatalf("import report: %v", err) + } + if report.DecisionsCreated != 1 || len(report.MappingFailures) != 0 { + t.Fatalf("import report = %#v", report) + } +} + +func TestOpenVEXDuplicateStatementIsIdempotentWithinImport(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, release, artifact := setupReleaseRiskFixture(t, ledger) + vulnerability := "CVE-2026-0300" + component := "pkg:apk/openssl@3.1.0" + uploadVEXMappingScan(t, ctx, ledger, actor, release.ID, vulnerability, component) + statement := openVEXStatementFixture(vulnerability, []map[string]any{{"@id": component}}, decisionStatusFixed, "fixed_in_release") + + vex, err := ledger.UploadVEX(ctx, actor, release.ID, artifact.ID, openVEXFixture(t, []map[string]any{statement, statement})) + if err != nil { + t.Fatalf("upload vex: %v", err) + } + active := true + decisions, err := ledger.ListVulnerabilityDecisions(ctx, actor, ListVulnerabilityDecisionsInput{ReleaseID: release.ID, Vulnerability: vulnerability, Active: &active}) + if err != nil { + t.Fatalf("list active decisions: %v", err) + } + if len(decisions) != 1 { + t.Fatalf("active decisions = %#v, want one", decisions) + } + inactive := false + superseded, err := ledger.ListVulnerabilityDecisions(ctx, actor, ListVulnerabilityDecisionsInput{ReleaseID: release.ID, Vulnerability: vulnerability, Active: &inactive}) + if err != nil { + t.Fatalf("list superseded decisions: %v", err) + } + if len(superseded) != 0 { + t.Fatalf("duplicate statement should not create superseded duplicate versions: %#v", superseded) + } + report, err := ledger.GetVEXImportReport(ctx, actor, vex.ID) + if err != nil { + t.Fatalf("import report: %v", err) + } + if report.DecisionsCreated != 1 || report.DecisionsSuperseded != 0 || !stringSliceContains(report.Warnings, "Duplicate VEX statements") { + t.Fatalf("import report = %#v", report) + } +} + +func TestOpenVEXMappingSupersedesExistingDecisionFixture(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, release, artifact := setupReleaseRiskFixture(t, ledger) + vulnerability := "CVE-2026-0400" + component := "pkg:apk/openssl@3.1.0" + scan := uploadVEXMappingScan(t, ctx, ledger, actor, release.ID, vulnerability, component) + if _, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{ + Status: decisionStatusUnderInvestigation, + Justification: "manual_triage", + ImpactStatement: "Manual triage is in progress.", + }); err != nil { + t.Fatalf("manual decision: %v", err) + } + + vex, err := ledger.UploadVEX(ctx, actor, release.ID, artifact.ID, openVEXFixture(t, []map[string]any{ + openVEXStatementFixture(vulnerability, []map[string]any{{"@id": component}}, decisionStatusFixed, "fixed_in_release"), + })) + if err != nil { + t.Fatalf("upload vex: %v", err) + } + active := true + activeDecisions, err := ledger.ListVulnerabilityDecisions(ctx, actor, ListVulnerabilityDecisionsInput{ReleaseID: release.ID, Vulnerability: vulnerability, Active: &active}) + if err != nil { + t.Fatalf("list active decisions: %v", err) + } + inactive := false + superseded, err := ledger.ListVulnerabilityDecisions(ctx, actor, ListVulnerabilityDecisionsInput{ReleaseID: release.ID, Vulnerability: vulnerability, Active: &inactive}) + if err != nil { + t.Fatalf("list superseded decisions: %v", err) + } + if len(activeDecisions) != 1 || activeDecisions[0].Status != decisionStatusFixed || len(superseded) != 1 || superseded[0].Status != decisionStatusUnderInvestigation { + t.Fatalf("active=%#v superseded=%#v", activeDecisions, superseded) + } + report, err := ledger.GetVEXImportReport(ctx, actor, vex.ID) + if err != nil { + t.Fatalf("import report: %v", err) + } + if report.DecisionsCreated != 1 || report.DecisionsSuperseded != 1 { + t.Fatalf("import report = %#v", report) + } +} + +func TestOpenVEXValidationFixturesReturnUsefulSafeErrors(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, release, artifact := setupReleaseRiskFixture(t, ledger) + tests := []struct { + name string + payload []byte + wantDetail string + notContain string + }{ + { + name: "unknown status", + payload: openVEXFixture(t, []map[string]any{ + openVEXStatementFixture("CVE-2026-0500", []map[string]any{{"@id": "pkg:apk/openssl@3.1.0"}}, "secret-token-status", "triage"), + }), + wantDetail: "openvex statement 1 has an unsupported status", + notContain: "secret-token-status", + }, + { + name: "component identity missing", + payload: openVEXFixture(t, []map[string]any{ + openVEXStatementFixture("CVE-2026-0501", []map[string]any{{"@id": ""}}, decisionStatusFixed, "fixed"), + }), + wantDetail: "openvex statement 1 product 1 is missing an @id", + }, + { + name: "malformed document", + payload: []byte(`{"author":"security@example.test"`), + wantDetail: "openvex JSON is malformed or contains unsupported fields", + }, + { + name: "missing vulnerability", + payload: openVEXFixture(t, []map[string]any{ + openVEXStatementFixture("", []map[string]any{{"@id": "pkg:apk/openssl@3.1.0"}}, decisionStatusFixed, "fixed"), + }), + wantDetail: "openvex statement 1 is missing a vulnerability name", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := ledger.UploadVEX(ctx, actor, release.ID, artifact.ID, tt.payload) + if !errors.Is(err, ErrValidation) { + t.Fatalf("err = %v, want validation", err) + } + if !strings.Contains(err.Error(), tt.wantDetail) { + t.Fatalf("err = %q, want detail %q", err, tt.wantDetail) + } + if tt.notContain != "" && strings.Contains(err.Error(), tt.notContain) { + t.Fatalf("error leaked raw invalid value %q: %v", tt.notContain, err) + } + }) + } +} + +func uploadVEXMappingScan(t *testing.T, ctx context.Context, ledger *Ledger, actor domain.Actor, releaseID, vulnerability, component string) domain.VulnerabilityScan { + t.Helper() + scan, err := ledger.UploadVulnerabilityScan(ctx, actor, []byte(`{ + "scanner":"grype", + "target_ref":"`+component+`", + "release_id":"`+releaseID+`", + "findings":[{"vulnerability":"`+vulnerability+`","component":"`+component+`","severity":"critical","state":"open"}] + }`)) + if err != nil { + t.Fatalf("upload scan: %v", err) + } + return scan +} + +func openVEXFixture(t *testing.T, statements []map[string]any) []byte { + t.Helper() + body, err := json.Marshal(map[string]any{ + "@context": "https://openvex.dev/ns/v0.2.0", + "@id": "https://example.test/vex/fixture", + "author": "security@example.test", + "timestamp": "2026-05-27T12:00:00Z", + "version": 1, + "statements": statements, + }) + if err != nil { + t.Fatalf("marshal VEX fixture: %v", err) + } + return body +} + +func openVEXStatementFixture(vulnerability string, products []map[string]any, status, justification string) map[string]any { + return map[string]any{ + "vulnerability": map[string]any{"name": vulnerability}, + "products": products, + "status": status, + "justification": justification, + "impact_statement": "Decision detail suitable for customer review.", + "action_statement": "Review the linked evidence before relying on this decision.", + } +} + +func stringSliceContains(values []string, needle string) bool { + for _, value := range values { + if strings.Contains(value, needle) { + return true + } + } + return false +} diff --git a/openapi.yaml b/openapi.yaml index d43c41f..40670c1 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From 6a08acd03f7a0cae7a5eec2707d3aafe73ebe537 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:17:06 +0300 Subject: [PATCH 181/287] feat(decisions): link manual decisions to VEX --- .productization_next_steps.md | 2 +- docs/api.md | 7 +- docs/reference/vulnerability-decisions.md | 10 +- internal/adapters/httpapi/openapi.go | 1 + internal/adapters/httpapi/router.go | 2 + internal/adapters/httpapi/router_test.go | 20 +++- internal/app/manual_decisions_test.go | 118 ++++++++++++++++++++++ internal/app/vex.go | 11 +- openapi.yaml | 2 +- 9 files changed, 166 insertions(+), 7 deletions(-) create mode 100644 internal/app/manual_decisions_test.go diff --git a/.productization_next_steps.md b/.productization_next_steps.md index df290c5..53d04a4 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -464,7 +464,7 @@ Acceptance criteria: * Error messages are useful. * OpenAPI examples include at least one imported VEX document. -#### [ ] EVY-023 — Add manual decision authoring fallback +#### [x] EVY-023 — Add manual decision authoring fallback Priority: P0 diff --git a/docs/api.md b/docs/api.md index 0d9f69e..4507e58 100644 --- a/docs/api.md +++ b/docs/api.md @@ -168,7 +168,8 @@ POST /v1/vulnerability-findings/{id}/decisions "action_statement": "No customer action is required for this finding.", "customer_visible": true, "internal_notes": "tenant-internal triage note", - "evidence_ids": ["ev_supporting_review"] + "evidence_ids": ["ev_supporting_review"], + "vex_document_id": "vex_imported_review" } ``` @@ -179,7 +180,9 @@ into customer-safe package summaries. A later decision for the same finding supersedes the previous active decision and records audit-chain entries for the supersession and replacement. `evidence_ids` may reference tenant-scoped supporting evidence from the same release; foreign-tenant or wrong-release -evidence links are rejected. +evidence links are rejected. `vex_document_id` can link a manual decision to an +imported VEX document from the same release, including cases where automated VEX +mapping did not create a decision. Decision history: diff --git a/docs/reference/vulnerability-decisions.md b/docs/reference/vulnerability-decisions.md index 60a77fa..e399356 100644 --- a/docs/reference/vulnerability-decisions.md +++ b/docs/reference/vulnerability-decisions.md @@ -35,7 +35,7 @@ finding: | Internal notes | `internal_notes` stores tenant-internal context separately from customer-safe impact text. | | Approver/actor | `approved_by` stores the actor id for API/OpenVEX-created decisions. | | Supersession | Creating a new decision for the same finding marks the prior active decision with `superseded_by` and sets `supersedes` on the new decision. | -| Source VEX/import | `vex_document_id` and `evidence_id` link imported decisions to the VEX document and evidence item. | +| Source VEX/import | `vex_document_id` and `evidence_id` link imported decisions to the VEX document and evidence item. Manual decisions may also set `vex_document_id` to link a same-release imported VEX document without changing the manual source. | | Scan finding link | `finding_id` and `scan_id` link the decision to the normalized finding. | | Supporting evidence links | `evidence_ids` can link tenant-scoped supporting evidence from the same release. | | Audit history | Decision creation appends an audit-chain entry. | @@ -66,6 +66,14 @@ decides whether they belong in decisions or in exceptions/waivers. Customer package manifests include only active decisions unless a future history-specific export is requested. +Manual decisions are the fallback when a VEX document is not available or when +automated VEX mapping does not create the required decision. They use the same +append-only lifecycle as imported decisions. If a VEX document is imported +later, create a new manual decision version with `vex_document_id` set to that +same-release VEX document; Evydence rejects foreign-tenant and wrong-release VEX +links. Customer-visible manual decisions require `impact_statement`, and +customer-safe package summaries omit `internal_notes`. + ## Decision History API `GET /v1/vulnerability-decisions` returns the tenant-scoped append-only diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 8c5e890..37a4c6a 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -299,6 +299,7 @@ func registerCriticalSchemas(registry *specs.Registry) { "customer_visible": map[string]any{"type": "boolean"}, "internal_notes": map[string]any{"type": "string", "description": "Tenant-internal notes; excluded from customer-safe package summaries."}, "evidence_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "vex_document_id": map[string]any{"type": "string", "description": "Optional tenant-scoped VEX document from the same release to link to this manual decision."}, }, "status", "justification")) registry.RegisterSchema("VulnerabilityDecision", objectSchema(map[string]any{ "id": map[string]any{"type": "string"}, diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index c5552db..0479bb4 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -1489,6 +1489,7 @@ func (s *Server) createVulnerabilityDecision(w http.ResponseWriter, r *http.Requ CustomerVisible bool `json:"customer_visible"` InternalNotes string `json:"internal_notes"` EvidenceIDs []string `json:"evidence_ids"` + VEXDocumentID string `json:"vex_document_id"` } s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { @@ -1502,6 +1503,7 @@ func (s *Server) createVulnerabilityDecision(w http.ResponseWriter, r *http.Requ CustomerVisible: req.CustomerVisible, InternalNotes: req.InternalNotes, EvidenceIDs: req.EvidenceIDs, + VEXDocumentID: req.VEXDocumentID, }) return http.StatusCreated, decision, err }) diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 6269fdd..0084767 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -86,6 +86,10 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { if _, ok := problemProps["request_id"]; !ok { t.Fatalf("Problem schema missing request_id: %#v", problemProps) } + decisionRequestProps := asStringAnyMap(t, asStringAnyMap(t, schemas["CreateVulnerabilityDecisionRequest"])["properties"]) + if _, ok := decisionRequestProps["vex_document_id"]; !ok { + t.Fatalf("manual decision request schema missing vex_document_id: %#v", decisionRequestProps) + } for _, schemaName := range []string{"ReadinessStatusEnvelope", "BackupManifestEnvelope", "VerificationResultEnvelope", "ReadinessReportEnvelope", "CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "VEXImportReportEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "VulnerabilityDecisionListEnvelope", "VulnerabilityDecisionSummaryReportEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "UpdateSSOProviderTrustMaterialRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "ExchangeSSOCredentialRequest", "SSOCredentialExchangeEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "DataEnvelope"} { if _, ok := schemas[schemaName]; !ok { t.Fatalf("schema %s missing from OpenAPI components", schemaName) @@ -731,10 +735,11 @@ func TestVEXAndExceptionHTTPValidation(t *testing.T) { releaseID := dataField(t, releaseBody, "id") artifactBody := postJSON(t, server, secret, "/v1/artifacts", "vex-artifact", map[string]any{"name": "api.tar.gz", "media_type": "application/gzip", "digest": "sha256:ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", "size": 42}, http.StatusCreated) artifactID := dataField(t, artifactBody, "id") - postJSON(t, server, secret, "/v1/vulnerability-scans", "vex-scan", map[string]any{ + scanBody := postJSON(t, server, secret, "/v1/vulnerability-scans", "vex-scan", map[string]any{ "scanner": "grype", "target_ref": "pkg:oci/payments-api", "release_id": releaseID, "findings": []map[string]any{{"vulnerability": "CVE-2026-0100", "component": "pkg:apk/openssl@3.1.0", "severity": "critical", "state": "open"}}, }, http.StatusCreated) + findingID := firstFindingID(t, scanBody) vexBody := postJSON(t, server, secret, "/v1/vex", "vex-upload", map[string]any{ "release_id": releaseID, "artifact_id": artifactID, @@ -760,6 +765,19 @@ func TestVEXAndExceptionHTTPValidation(t *testing.T) { if !strings.Contains(importReport, `"status":"parsed"`) || !strings.Contains(importReport, `"decisions_created":1`) || strings.Contains(importReport, "payload_ref") { t.Fatalf("unsafe or incomplete VEX import report: %s", importReport) } + postJSON(t, server, secret, "/v1/vulnerability-findings/"+findingID+"/decisions", "manual-vex-link-bad", map[string]any{ + "status": "not_affected", "justification": "manual review", "customer_visible": true, "vex_document_id": vexID, + }, http.StatusBadRequest) + manualDecision := postJSON(t, server, secret, "/v1/vulnerability-findings/"+findingID+"/decisions", "manual-vex-link", map[string]any{ + "status": "not_affected", + "justification": "manual review linked to imported VEX", + "impact_statement": "This release is not affected based on a manual review linked to the imported VEX document.", + "customer_visible": true, + "vex_document_id": vexID, + }, http.StatusCreated) + if !strings.Contains(manualDecision, `"vex_document_id":"`+vexID+`"`) || strings.Contains(manualDecision, "payload_ref") { + t.Fatalf("manual linked VEX decision response unsafe or incomplete: %s", manualDecision) + } postJSON(t, server, secret, "/v1/vex", "vex-bad", map[string]any{"release_id": releaseID, "payload": map[string]any{"author": "a", "timestamp": "2026-05-27T12:00:00Z", "statements": []any{}, "extra": true}}, http.StatusBadRequest) exceptionBody := postJSON(t, server, secret, "/v1/exceptions", "exception-create", map[string]any{"release_id": releaseID, "reason": "temporary acceptance", "owner": "security", "expires_at": time.Now().UTC().Add(time.Hour).Format(time.RFC3339)}, http.StatusCreated) diff --git a/internal/app/manual_decisions_test.go b/internal/app/manual_decisions_test.go new file mode 100644 index 0000000..1f50bca --- /dev/null +++ b/internal/app/manual_decisions_test.go @@ -0,0 +1,118 @@ +package app + +import ( + "context" + "encoding/json" + "errors" + "strings" + "testing" + "time" +) + +func TestManualDecisionCanLinkImportedVEXAndExportCustomerPackage(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, release, artifact := setupReleaseRiskFixture(t, ledger) + vulnerability := "CVE-2026-0600" + component := "pkg:apk/openssl@3.1.0" + scan := uploadVEXMappingScan(t, ctx, ledger, actor, release.ID, vulnerability, component) + vex, err := ledger.UploadVEX(ctx, actor, release.ID, artifact.ID, openVEXFixture(t, []map[string]any{ + openVEXStatementFixture("CVE-2026-9999", []map[string]any{{"@id": "pkg:apk/not-present@1.0.0"}}, decisionStatusFixed, "fixed_elsewhere"), + })) + if err != nil { + t.Fatalf("upload vex: %v", err) + } + report, err := ledger.GetVEXImportReport(ctx, actor, vex.ID) + if err != nil { + t.Fatalf("import report: %v", err) + } + if report.DecisionsCreated != 0 || len(report.MappingFailures) != 1 { + t.Fatalf("import report should show unmapped VEX statement: %#v", report) + } + + decision, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{ + Status: decisionStatusNotAffected, + Justification: "reviewed against imported VEX and release inventory", + ImpactStatement: "This release is not affected based on the linked VEX review and supporting release evidence.", + ActionStatement: "No customer action is required for this finding.", + CustomerVisible: true, + InternalNotes: "internal reviewer note", + VEXDocumentID: vex.ID, + }) + if err != nil { + t.Fatalf("manual decision: %v", err) + } + if decision.Source != "api" || decision.VEXDocumentID != vex.ID || decision.EvidenceID != "" { + t.Fatalf("manual linked decision = %#v", decision) + } + + profile, err := ledger.CreateRedactionProfile(ctx, actor, CreateRedactionProfileInput{Name: "linked VEX decisions", AllowedTypes: []string{"vulnerability_decision"}}) + if err != nil { + t.Fatalf("redaction profile: %v", err) + } + pkg, err := ledger.CreateCustomerSecurityPackage(ctx, actor, CreateCustomerPackageInput{ + ProductID: release.ProductID, + ReleaseID: release.ID, + RedactionProfileID: profile.ID, + Title: "Linked VEX decision package", + ExpiresAt: fixedNow().Add(time.Hour), + }) + if err != nil { + t.Fatalf("customer package: %v", err) + } + body, err := json.Marshal(pkg.Manifest) + if err != nil { + t.Fatalf("marshal package manifest: %v", err) + } + text := string(body) + if !strings.Contains(text, decision.ImpactStatement) || !strings.Contains(text, vex.ID) { + t.Fatalf("package manifest missing linked manual decision fields: %s", body) + } + if strings.Contains(text, "internal reviewer note") { + t.Fatalf("package manifest leaked internal notes: %s", body) + } +} + +func TestManualDecisionRejectsForeignReleaseVEXLink(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, releaseA, artifact := setupReleaseRiskFixture(t, ledger) + releaseB, err := ledger.CreateRelease(ctx, actor, releaseA.ProductID, "2.0.0") + if err != nil { + t.Fatalf("release B: %v", err) + } + scan := uploadVEXMappingScan(t, ctx, ledger, actor, releaseA.ID, "CVE-2026-0601", "pkg:apk/openssl@3.1.0") + vex, err := ledger.UploadVEX(ctx, actor, releaseB.ID, artifact.ID, openVEXFixture(t, []map[string]any{ + openVEXStatementFixture("CVE-2026-0601", []map[string]any{{"@id": "pkg:apk/openssl@3.1.0"}}, decisionStatusFixed, "fixed"), + })) + if err != nil { + t.Fatalf("upload release B vex: %v", err) + } + + _, err = ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{ + Status: decisionStatusNotAffected, + Justification: "manual review", + ImpactStatement: "Customer-safe review statement.", + CustomerVisible: true, + VEXDocumentID: vex.ID, + }) + if !errors.Is(err, ErrNotFound) { + t.Fatalf("foreign release VEX link err=%v, want not found", err) + } +} + +func TestManualCustomerVisibleDecisionRequiresCustomerStatement(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, release, _ := setupReleaseRiskFixture(t, ledger) + scan := uploadVEXMappingScan(t, ctx, ledger, actor, release.ID, "CVE-2026-0602", "pkg:apk/openssl@3.1.0") + + _, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{ + Status: decisionStatusNotAffected, + Justification: "manual review", + CustomerVisible: true, + }) + if !errors.Is(err, ErrValidation) { + t.Fatalf("customer-visible manual decision err=%v, want validation", err) + } +} diff --git a/internal/app/vex.go b/internal/app/vex.go index b0e6b24..03b308e 100644 --- a/internal/app/vex.go +++ b/internal/app/vex.go @@ -36,6 +36,7 @@ type CreateVulnerabilityDecisionInput struct { CustomerVisible bool InternalNotes string EvidenceIDs []string + VEXDocumentID string } type ListVulnerabilityDecisionsInput struct { @@ -331,12 +332,20 @@ func (s releaseEvidenceService) CreateVulnerabilityDecision(ctx context.Context, if latest, ok := l.latestDecisionForFindingLocked(actor.TenantID, finding.ID); ok && !validDecisionTransition(latest.Status, strings.TrimSpace(in.Status)) { return domain.VulnerabilityDecision{}, ErrValidation } + in.VEXDocumentID = strings.TrimSpace(in.VEXDocumentID) + if in.VEXDocumentID != "" { + vex, ok := l.vexDocuments[in.VEXDocumentID] + if !ok || vex.TenantID != actor.TenantID || vex.ReleaseID != scan.ReleaseID { + return domain.VulnerabilityDecision{}, ErrNotFound + } + in.VEXDocumentID = vex.ID + } evidenceIDs, err := l.validateDecisionEvidenceLinksLocked(actor.TenantID, scan.ReleaseID, in.EvidenceIDs) if err != nil { return domain.VulnerabilityDecision{}, err } in.EvidenceIDs = evidenceIDs - decision := l.createDecisionLocked(actor.TenantID, scan, finding, in, "api", actor.KeyID, "", "") + decision := l.createDecisionLocked(actor.TenantID, scan, finding, in, "api", actor.KeyID, "", in.VEXDocumentID) l.decisions[decision.ID] = decision l.appendDecisionLifecycleAuditLocked(actor.TenantID, decision, finding.ID, "api_key", actor.KeyID, "") if err := l.persistCriticalLocked(ctx, l.criticalMutationLocked()); err != nil { diff --git a/openapi.yaml b/openapi.yaml index 40670c1..8251207 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From ef3a8d6536e1aee0eac6a8695080426c71d9c1a3 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:19:06 +0300 Subject: [PATCH 182/287] feat(packages): define customer package v2 manifest --- .productization_next_steps.md | 2 +- docs/README.md | 1 + docs/api.md | 7 + docs/reference/customer-package-manifest.md | 50 ++ .../sample-customer-package-manifest.json | 198 +++++- internal/app/governance_packages.go | 579 +++++++++++++++++- internal/app/governance_packages_test.go | 106 ++++ internal/domain/domain.go | 2 +- site/package-viewer/index.html | 52 +- 9 files changed, 941 insertions(+), 56 deletions(-) create mode 100644 docs/reference/customer-package-manifest.md diff --git a/.productization_next_steps.md b/.productization_next_steps.md index 53d04a4..0c489d6 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -489,7 +489,7 @@ Goal: Backlog: -#### [ ] EVY-030 — Define package v2 manifest schema +#### [x] EVY-030 — Define package v2 manifest schema Priority: P0 diff --git a/docs/README.md b/docs/README.md index 9ff16ef..5137b98 100644 --- a/docs/README.md +++ b/docs/README.md @@ -28,6 +28,7 @@ This documentation is organized by reader task. Implementation claims should be - [API contract matrix](reference/api-contract-matrix.md): generated route-by-route contract precision inventory for production hardening. - [OpenAPI contract](reference/openapi.md): generation, drift checks, and review tips for `openapi.yaml`. - [Vulnerability decisions](reference/vulnerability-decisions.md): current VEX/decision model, buyer-facing gaps, and planned API changes. +- [Customer package manifest](reference/customer-package-manifest.md): v2 package schema, included metadata, exclusions, and local viewer compatibility. - [Observability](reference/observability.md): readiness, admin metrics, Prometheus rules, and dashboard starter assets. - [Capacity and failure modes](reference/capacity-and-failures.md): supported concurrency profile, sizing inputs, and failure behavior. - [Benchmark results](reference/benchmark-results.md): current local benchmark command and interpretation. diff --git a/docs/api.md b/docs/api.md index 4507e58..e601d56 100644 --- a/docs/api.md +++ b/docs/api.md @@ -419,6 +419,13 @@ Source snapshots capture submitted provider metadata. They do not call provider | `POST` | `/v1/incidents/{id}/webhook-receivers` | Create incident-scoped Ed25519 webhook receiver. | | `POST` | `/v1/incident-webhooks/{receiver_id}` | Receive signed incident timeline webhook without bearer authentication. | +Customer package manifests use the documented +[`customer-security-package.v2.0.0`](reference/customer-package-manifest.md) +schema. They include scoped release metadata, evidence summaries, redaction +profile details, readiness checks, verification material, limitations, and +non-claims while excluding raw payload bytes, object-store references, secrets, +token hashes, and internal decision notes. + ### Integrity, Verification, And Operations | Method | Path | Notes | diff --git a/docs/reference/customer-package-manifest.md b/docs/reference/customer-package-manifest.md new file mode 100644 index 0000000..ac997e9 --- /dev/null +++ b/docs/reference/customer-package-manifest.md @@ -0,0 +1,50 @@ +# Customer Package Manifest + +Customer packages use `customer-security-package.v2.0.0` manifests. The +manifest is a scoped, redacted JSON summary for technical evidence review. It is +not legal compliance proof, certification, complete SBOM proof, an authoritative +vulnerability result, or a secure-release guarantee. + +## Required Top-Level Fields + +| Field | Purpose | +| --- | --- | +| `schema_version` / `package_version` | Stable manifest schema version. | +| `package_id` / `id` | Package identifier used by API responses and ZIP exports. | +| `title` | Operator-provided package title. | +| `generated_at` | UTC generation timestamp. | +| `tenant`, `organization`, `product`, `release` | Scoped metadata for the package subject. | +| `redaction_profile` | Redaction profile id, allowed types, excluded fields, and schema version. | +| `evidence_ids` | Included evidence metadata identifiers after redaction profile filtering. | +| `artifact_digests` | Artifact IDs, names, media types, sizes, and digests linked to the release. | +| `readiness_summary` | Deterministic readiness checks, gaps, and limitations. | +| `verification_material` | Hash algorithm, canonicalization profile, release bundle hashes, and audit-chain summary. | +| `limitations`, `non_claims` | Required package limitations and conservative product-language boundaries. | + +## Optional Sections + +Sections appear only when the redaction profile allows the relevant type and +matching release-scoped records exist: + +- `sboms`: SBOM metadata such as format, spec version, component count, and evidence ID. +- `vulnerability_scans`: scanner metadata, target reference, summary counts, and finding count. +- `vex_documents`: VEX metadata, statement counts, status summary, and evidence ID. +- `vulnerability_decisions`: active customer-visible decision summaries only. +- `approvals`: release or product approval records. +- `exceptions`: approved, unexpired release exceptions. +- `waivers`: approved, unexpired product or release waivers. +- `provenance`: build runs and build attestation metadata. + +## Exclusions + +Customer package manifests exclude raw tenant evidence payload bytes, +object-store payload references, bearer tokens, private keys, API key hashes, +SSO/session token hashes, and tenant-internal vulnerability decision notes. +Customer-visible vulnerability decisions require `impact_statement`; internal +notes are not copied into `vulnerability_decisions`. + +## Viewer Compatibility + +The local package viewer at `site/package-viewer/index.html` loads v2 manifests +directly from disk. A non-sensitive sample is available at +`examples/end-to-end-release-evidence/sample-customer-package-manifest.json`. diff --git a/examples/end-to-end-release-evidence/sample-customer-package-manifest.json b/examples/end-to-end-release-evidence/sample-customer-package-manifest.json index 66abaad..54c4acf 100644 --- a/examples/end-to-end-release-evidence/sample-customer-package-manifest.json +++ b/examples/end-to-end-release-evidence/sample-customer-package-manifest.json @@ -1,23 +1,187 @@ { - "data": { - "id": "pkg_example", - "release_id": "rel_example", - "scope": "customer_review", - "expires_at": "2026-06-30T00:00:00Z", - "manifest_hash": "sha256:example", - "included_subjects": [ - "release_bundle", - "readiness_report", - "sbom_summary", - "vulnerability_decisions" + "schema_version": "customer-security-package.v2.0.0", + "package_version": "customer-security-package.v2.0.0", + "package_id": "csp_example", + "id": "csp_example", + "title": "Example customer review package", + "generated_at": "2026-05-27T12:00:00Z", + "tenant": { + "id": "ten_example", + "name": "Example Tenant" + }, + "organization": { + "records": [ + { + "id": "org_example", + "name": "Example Org", + "slug": "example-org", + "status": "active", + "created": "2026-05-27T12:00:00Z" + } ], - "redactions": [ - "raw evidence payload bytes are excluded", - "secrets and private keys are excluded" + "limitations": [ + "Organization records are included only as tenant metadata; product-to-organization ownership is not inferred by this package schema." + ] + }, + "product": { + "id": "prod_example", + "name": "Payments API", + "slug": "payments-api", + "created_at": "2026-05-27T12:00:00Z" + }, + "product_id": "prod_example", + "release": { + "id": "rel_example", + "product_id": "prod_example", + "version": "1.0.0", + "state": "approved", + "created_at": "2026-05-27T12:00:00Z" + }, + "release_id": "rel_example", + "redaction_profile_id": "rp_example", + "redaction_profile": { + "id": "rp_example", + "name": "customer review", + "allowed_types": [ + "artifact", + "sbom", + "vulnerability_scan", + "vex", + "vulnerability_decision", + "release_bundle" + ], + "excluded_fields": [ + "internal_notes" ], + "schema_version": "redaction-profile.v1.0.0" + }, + "evidence_ids": [ + "ev_sbom", + "ev_scan", + "ev_vex" + ], + "artifact_digests": [ + { + "id": "art_example", + "name": "payments-api.tar.gz", + "media_type": "application/gzip", + "size": 123, + "digest": "sha256:ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", + "created_at": "2026-05-27T12:00:00Z" + } + ], + "sboms": [ + { + "id": "sbom_example", + "evidence_id": "ev_sbom", + "release_id": "rel_example", + "artifact_id": "art_example", + "format": "cyclonedx", + "spec_version": "1.6", + "component_count": 42, + "created_at": "2026-05-27T12:00:00Z" + } + ], + "vulnerability_scans": [ + { + "id": "scan_example", + "evidence_id": "ev_scan", + "release_id": "rel_example", + "scanner": "example-scanner", + "target_ref": "pkg:oci/payments-api", + "summary": { + "critical": 0, + "high": 1 + }, + "finding_count": 1, + "created_at": "2026-05-27T12:00:00Z" + } + ], + "vex_documents": [ + { + "id": "vex_example", + "evidence_id": "ev_vex", + "release_id": "rel_example", + "artifact_id": "art_example", + "format": "openvex", + "author": "security@example.test", + "statement_count": 1, + "status_summary": { + "fixed": 1 + }, + "schema_version": "vex-document.v1.0.0", + "created_at": "2026-05-27T12:00:00Z" + } + ], + "vulnerability_decisions": [ + { + "id": "vd_example", + "finding_id": "finding_example", + "scan_id": "scan_example", + "release_id": "rel_example", + "vulnerability": "CVE-2026-0002", + "component": "pkg:apk/openssl@3.1.0", + "status": "fixed", + "justification": "fixed_in_release", + "impact_statement": "The finding is fixed in this release artifact.", + "action_statement": "Upgrade to this release after normal operator review.", + "source": "vex", + "evidence_id": "ev_vex", + "vex_document_id": "vex_example", + "created_at": "2026-05-27T12:00:00Z" + } + ], + "readiness_summary": { + "result": "passed", + "checks": [ + { + "name": "release_requires_sbom", + "result": "passed", + "severity": "high", + "missing": [], + "explanation": "sbom evidence exists" + } + ], + "gaps": [], "limitations": [ - "Customer package supports technical evidence review only.", - "It is not legal compliance proof, certification, or a secure-release guarantee." + "Readiness is derived from recorded package-scope evidence only.", + "Readiness output is not a compliance, certification, or secure-release conclusion." ] - } + }, + "verification_material": { + "hash_algorithm": "sha256", + "canonicalization": "canonicalization-profile.v1.0.0", + "manifest_hash_field": "manifest_hash", + "release_bundles": [ + { + "id": "rb_example", + "state": "generated", + "manifest_hash": "sha256:example", + "signature_refs": [ + "sig_example" + ], + "created_at": "2026-05-27T12:00:00Z" + } + ], + "audit_chain": { + "result": "passed", + "latest_sequence": 12, + "head_hash": "sha256:example", + "checks": [ + { + "name": "audit_chain", + "result": "passed" + } + ] + } + }, + "limitations": [ + "Package contents are scoped by product, release, redaction profile, and package expiry.", + "Raw tenant evidence payload bytes, object-store payload references, bearer tokens, private keys, API key hashes, SSO/session token hashes, and internal decision notes are not included.", + "Package data reflects records present in this Evydence instance at generation time." + ], + "non_claims": [ + "This package supports technical evidence review and compliance readiness only.", + "It is not legal compliance proof, certification, complete SBOM proof, an authoritative vulnerability result, regulator acceptance, or a secure-release guarantee." + ] } diff --git a/internal/app/governance_packages.go b/internal/app/governance_packages.go index 9eb7638..b75ee2c 100644 --- a/internal/app/governance_packages.go +++ b/internal/app/governance_packages.go @@ -257,23 +257,14 @@ func (s packageReportService) CreateCustomerSecurityPackage(ctx context.Context, return domain.CustomerSecurityPackage{}, ErrNotFound } evidenceIDs := l.packageEvidenceIDsLocked(actor.TenantID, in.ProductID, in.ReleaseID, profile) - manifest := map[string]any{ - "package_version": domain.CustomerPackageSchemaVersion, - "title": in.Title, - "product_id": in.ProductID, - "release_id": in.ReleaseID, - "redaction_profile_id": profile.ID, - "evidence_ids": evidenceIDs, - "limitations": []string{"Package contents are scoped and redacted; raw evidence payload bytes are not included in this manifest."}, - } - if decisions := l.packageDecisionSummariesLocked(actor.TenantID, in.ReleaseID, profile); len(decisions) > 0 { - manifest["vulnerability_decisions"] = decisions - } + packageID := newID("csp") + generatedAt := l.now() + manifest := l.customerPackageManifestLocked(packageID, generatedAt, actor.TenantID, in.Title, in.ProductID, in.ReleaseID, profile, evidenceIDs) hash, err := canonicalAnyHash(manifest) if err != nil { return domain.CustomerSecurityPackage{}, err } - pkg := domain.CustomerSecurityPackage{ID: newID("csp"), TenantID: actor.TenantID, ProductID: in.ProductID, ReleaseID: in.ReleaseID, RedactionProfileID: profile.ID, Title: in.Title, State: "generated", Manifest: manifest, ManifestHash: hash, ExpiresAt: in.ExpiresAt.UTC(), SchemaVersion: domain.CustomerPackageSchemaVersion, CreatedAt: l.now()} + pkg := domain.CustomerSecurityPackage{ID: packageID, TenantID: actor.TenantID, ProductID: in.ProductID, ReleaseID: in.ReleaseID, RedactionProfileID: profile.ID, Title: in.Title, State: "generated", Manifest: manifest, ManifestHash: hash, ExpiresAt: in.ExpiresAt.UTC(), SchemaVersion: domain.CustomerPackageSchemaVersion, CreatedAt: generatedAt} l.customerPackages[pkg.ID] = pkg _, _ = l.appendChainLocked(actor.TenantID, "customer_package.generated", "customer_security_package", pkg.ID, "api_key", actor.KeyID, hash, "") if err := l.persistLocked(ctx); err != nil { @@ -282,6 +273,559 @@ func (s packageReportService) CreateCustomerSecurityPackage(ctx context.Context, return pkg, nil } +func (l *Ledger) customerPackageManifestLocked(packageID string, generatedAt time.Time, tenantID, title, productID, releaseID string, profile domain.RedactionProfile, evidenceIDs []string) map[string]any { + product := l.products[productID] + var release domain.Release + if releaseID != "" { + release = l.releases[releaseID] + } + checks := l.packageReadinessChecksLocked(tenantID, releaseID) + gaps := []string{} + readinessResult := "not_applicable" + if releaseID != "" { + readinessResult = "passed" + for _, check := range checks { + gaps = append(gaps, check.Missing...) + if check.Result == "failed" { + readinessResult = "failed" + } + } + sort.Strings(gaps) + } + manifest := map[string]any{ + "schema_version": domain.CustomerPackageSchemaVersion, + "package_version": domain.CustomerPackageSchemaVersion, + "package_id": packageID, + "id": packageID, + "title": title, + "generated_at": generatedAt.UTC().Format(time.RFC3339Nano), + "tenant": l.packageTenantMetadataLocked(tenantID), + "organization": l.packageOrganizationMetadataLocked(tenantID), + "product": packageProductMetadata(product), + "product_id": productID, + "release": packageReleaseMetadata(release), + "release_id": releaseID, + "redaction_profile_id": profile.ID, + "redaction_profile": packageRedactionProfileMetadata(profile), + "evidence_ids": append([]string(nil), evidenceIDs...), + "artifact_digests": l.packageArtifactMetadataLocked(tenantID, releaseID), + "readiness_summary": packageReadinessSummary(readinessResult, checks, gaps), + "verification_material": l.packageVerificationMaterialLocked(tenantID, releaseID), + "limitations": []string{ + "Package contents are scoped by product, release, redaction profile, and package expiry.", + "Raw tenant evidence payload bytes, object-store payload references, bearer tokens, private keys, API key hashes, SSO/session token hashes, and internal decision notes are not included.", + "Package data reflects records present in this Evydence instance at generation time.", + }, + "non_claims": []string{ + "This package supports technical evidence review and compliance readiness only.", + "It is not legal compliance proof, certification, complete SBOM proof, an authoritative vulnerability result, regulator acceptance, or a secure-release guarantee.", + }, + } + if profileAllowsPackageType(profile, "sbom") { + manifest["sboms"] = l.packageSBOMMetadataLocked(tenantID, releaseID) + } + if profileAllowsPackageType(profile, "vulnerability_scan") { + manifest["vulnerability_scans"] = l.packageVulnerabilityScanMetadataLocked(tenantID, releaseID) + } + if profileAllowsPackageType(profile, "vex") { + manifest["vex_documents"] = l.packageVEXMetadataLocked(tenantID, releaseID) + } + if decisions := l.packageDecisionSummariesLocked(tenantID, releaseID, profile); len(decisions) > 0 { + manifest["vulnerability_decisions"] = decisions + } + if profileAllowsPackageType(profile, "approval") { + manifest["approvals"] = l.packageApprovalSummariesLocked(tenantID, productID, releaseID) + } + if profileAllowsPackageType(profile, "exception") { + manifest["exceptions"] = l.packageExceptionSummariesLocked(tenantID, releaseID) + } + if profileAllowsPackageType(profile, "waiver") { + manifest["waivers"] = l.packageWaiverSummariesLocked(tenantID, productID, releaseID) + } + if profileAllowsPackageType(profile, "build") || profileAllowsPackageType(profile, "build_attestation") { + manifest["provenance"] = l.packageProvenanceMetadataLocked(tenantID, releaseID, profile) + } + return manifest +} + +func (l *Ledger) packageTenantMetadataLocked(tenantID string) map[string]any { + tenant := l.tenants[tenantID] + return map[string]any{"id": tenant.ID, "name": tenant.Name} +} + +func (l *Ledger) packageOrganizationMetadataLocked(tenantID string) map[string]any { + organizations := []map[string]any{} + for _, organization := range l.organizations { + if organization.TenantID != tenantID { + continue + } + organizations = append(organizations, map[string]any{ + "id": organization.ID, + "name": organization.Name, + "slug": organization.Slug, + "status": organization.Status, + "created": organization.CreatedAt.UTC().Format(time.RFC3339), + }) + } + sort.Slice(organizations, func(i, j int) bool { return organizations[i]["id"].(string) < organizations[j]["id"].(string) }) + return map[string]any{ + "records": organizations, + "limitations": []string{ + "Organization records are included only as tenant metadata; product-to-organization ownership is not inferred by this package schema.", + }, + } +} + +func packageProductMetadata(product domain.Product) map[string]any { + if product.ID == "" { + return map[string]any{} + } + return map[string]any{ + "id": product.ID, + "name": product.Name, + "slug": product.Slug, + "created_at": product.CreatedAt.UTC().Format(time.RFC3339), + } +} + +func packageReleaseMetadata(release domain.Release) map[string]any { + if release.ID == "" { + return map[string]any{} + } + out := map[string]any{ + "id": release.ID, + "product_id": release.ProductID, + "version": release.Version, + "state": release.State, + "created_at": release.CreatedAt.UTC().Format(time.RFC3339), + } + if release.FrozenAt != nil { + out["frozen_at"] = release.FrozenAt.UTC().Format(time.RFC3339) + } + if release.ApprovedAt != nil { + out["approved_at"] = release.ApprovedAt.UTC().Format(time.RFC3339) + } + return out +} + +func packageRedactionProfileMetadata(profile domain.RedactionProfile) map[string]any { + return map[string]any{ + "id": profile.ID, + "name": profile.Name, + "description": profile.Description, + "allowed_types": append([]string(nil), profile.AllowedTypes...), + "excluded_fields": append([]string(nil), profile.ExcludedFields...), + "schema_version": profile.SchemaVersion, + } +} + +func (l *Ledger) packageArtifactMetadataLocked(tenantID, releaseID string) []map[string]any { + ids := l.packageReleaseArtifactIDsLocked(tenantID, releaseID) + out := []map[string]any{} + for _, id := range ids { + artifact := l.artifacts[id] + out = append(out, map[string]any{ + "id": artifact.ID, + "name": artifact.Name, + "media_type": artifact.MediaType, + "size": artifact.Size, + "digest": artifact.Digest, + "created_at": artifact.CreatedAt.UTC().Format(time.RFC3339), + }) + } + return out +} + +func (l *Ledger) packageReleaseArtifactIDsLocked(tenantID, releaseID string) []string { + ids := map[string]bool{} + if releaseID == "" { + return nil + } + for _, item := range l.evidence { + if item.TenantID != tenantID || item.ReleaseID != releaseID { + continue + } + for _, ref := range item.SubjectRefs { + if ref.Type == "artifact" && ref.ID != "" { + ids[ref.ID] = true + } + } + } + for _, sbom := range l.sboms { + if sbom.TenantID == tenantID && sbom.ReleaseID == releaseID && sbom.ArtifactID != "" { + ids[sbom.ArtifactID] = true + } + } + for _, vex := range l.vexDocuments { + if vex.TenantID == tenantID && vex.ReleaseID == releaseID && vex.ArtifactID != "" { + ids[vex.ArtifactID] = true + } + } + for _, build := range l.buildRuns { + if build.TenantID != tenantID || build.ReleaseID != releaseID { + continue + } + for _, output := range build.Outputs { + if output.ArtifactID != "" { + ids[output.ArtifactID] = true + } + } + } + return sortedStringSet(ids) +} + +func (l *Ledger) packageSBOMMetadataLocked(tenantID, releaseID string) []map[string]any { + out := []map[string]any{} + for _, sbom := range l.sboms { + if sbom.TenantID != tenantID || sbom.ReleaseID != releaseID { + continue + } + out = append(out, map[string]any{ + "id": sbom.ID, + "evidence_id": sbom.EvidenceID, + "release_id": sbom.ReleaseID, + "artifact_id": sbom.ArtifactID, + "format": sbom.Format, + "spec_version": sbom.SpecVersion, + "component_count": sbom.ComponentCount, + "created_at": sbom.CreatedAt.UTC().Format(time.RFC3339), + }) + } + sortManifestMapsByID(out) + return out +} + +func (l *Ledger) packageVulnerabilityScanMetadataLocked(tenantID, releaseID string) []map[string]any { + out := []map[string]any{} + for _, scan := range l.scans { + if scan.TenantID != tenantID || scan.ReleaseID != releaseID { + continue + } + out = append(out, map[string]any{ + "id": scan.ID, + "evidence_id": scan.EvidenceID, + "release_id": scan.ReleaseID, + "scanner": scan.Scanner, + "target_ref": scan.TargetRef, + "summary": cloneIntMap(scan.Summary), + "finding_count": len(scan.Findings), + "created_at": scan.CreatedAt.UTC().Format(time.RFC3339), + }) + } + sortManifestMapsByID(out) + return out +} + +func (l *Ledger) packageVEXMetadataLocked(tenantID, releaseID string) []map[string]any { + out := []map[string]any{} + for _, vex := range l.vexDocuments { + if vex.TenantID != tenantID || vex.ReleaseID != releaseID { + continue + } + out = append(out, map[string]any{ + "id": vex.ID, + "evidence_id": vex.EvidenceID, + "release_id": vex.ReleaseID, + "artifact_id": vex.ArtifactID, + "format": vex.Format, + "author": vex.Author, + "version": vex.Version, + "statement_count": vex.StatementCount, + "status_summary": cloneIntMap(vex.StatusSummary), + "schema_version": vex.SchemaVersion, + "created_at": vex.CreatedAt.UTC().Format(time.RFC3339), + }) + } + sortManifestMapsByID(out) + return out +} + +func (l *Ledger) packageApprovalSummariesLocked(tenantID, productID, releaseID string) []map[string]any { + out := []map[string]any{} + for _, approval := range l.approvals { + if approval.TenantID != tenantID || !approvalBelongsToPackage(approval, productID, releaseID) { + continue + } + out = append(out, map[string]any{ + "id": approval.ID, + "subject_type": approval.SubjectType, + "subject_id": approval.SubjectID, + "decision": approval.Decision, + "reason": approval.Reason, + "evidence_id": approval.EvidenceID, + "created_at": approval.CreatedAt.UTC().Format(time.RFC3339), + }) + } + sortManifestMapsByID(out) + return out +} + +func approvalBelongsToPackage(approval domain.ApprovalRecord, productID, releaseID string) bool { + switch approval.SubjectType { + case "release": + return releaseID != "" && approval.SubjectID == releaseID + case "product": + return approval.SubjectID == productID + default: + return false + } +} + +func (l *Ledger) packageExceptionSummariesLocked(tenantID, releaseID string) []map[string]any { + out := []map[string]any{} + now := l.now() + for _, exception := range l.exceptions { + if exception.TenantID != tenantID || exception.ReleaseID != releaseID || !exception.Approved || !exception.ExpiresAt.After(now) { + continue + } + summary := map[string]any{ + "id": exception.ID, + "release_id": exception.ReleaseID, + "finding_id": exception.FindingID, + "control_id": exception.ControlID, + "reason": exception.Reason, + "owner": exception.Owner, + "expires_at": exception.ExpiresAt.UTC().Format(time.RFC3339), + "approved": exception.Approved, + "created_at": exception.CreatedAt.UTC().Format(time.RFC3339), + } + if exception.ApprovedAt != nil { + summary["approved_at"] = exception.ApprovedAt.UTC().Format(time.RFC3339) + } + out = append(out, summary) + } + sortManifestMapsByID(out) + return out +} + +func (l *Ledger) packageWaiverSummariesLocked(tenantID, productID, releaseID string) []map[string]any { + out := []map[string]any{} + now := l.now() + for _, waiver := range l.waivers { + if waiver.TenantID != tenantID || !waiver.Approved || !waiver.ExpiresAt.After(now) || !waiverBelongsToPackage(waiver, productID, releaseID) { + continue + } + summary := map[string]any{ + "id": waiver.ID, + "scope_type": waiver.ScopeType, + "scope_id": waiver.ScopeID, + "control_id": waiver.ControlID, + "policy_id": waiver.PolicyID, + "owner": waiver.Owner, + "risk": waiver.Risk, + "reason": waiver.Reason, + "expires_at": waiver.ExpiresAt.UTC().Format(time.RFC3339), + "approved": waiver.Approved, + "created_at": waiver.CreatedAt.UTC().Format(time.RFC3339), + } + if waiver.ApprovedAt != nil { + summary["approved_at"] = waiver.ApprovedAt.UTC().Format(time.RFC3339) + } + out = append(out, summary) + } + sortManifestMapsByID(out) + return out +} + +func waiverBelongsToPackage(waiver domain.Waiver, productID, releaseID string) bool { + switch waiver.ScopeType { + case "release": + return releaseID != "" && waiver.ScopeID == releaseID + case "product": + return waiver.ScopeID == productID + default: + return false + } +} + +func (l *Ledger) packageProvenanceMetadataLocked(tenantID, releaseID string, profile domain.RedactionProfile) map[string]any { + builds := []map[string]any{} + buildIDs := map[string]bool{} + if profileAllowsPackageType(profile, "build") { + for _, build := range l.buildRuns { + if build.TenantID != tenantID || build.ReleaseID != releaseID { + continue + } + buildIDs[build.ID] = true + builds = append(builds, map[string]any{ + "id": build.ID, + "project_id": build.ProjectID, + "collector_id": build.CollectorID, + "provider": build.Provider, + "commit_sha": build.CommitSHA, + "repository": build.Repository, + "workflow_ref": build.WorkflowRef, + "run_id": build.RunID, + "run_attempt": build.RunAttempt, + "status": build.Status, + "started_at": build.StartedAt.UTC().Format(time.RFC3339), + "finished_at": packageOptionalTime(build.FinishedAt), + "parameters_hash": build.ParametersHash, + "environment_hash": build.EnvironmentHash, + "outputs": packageBuildOutputs(build.Outputs), + "schema_version": build.SchemaVersion, + "created_at": build.CreatedAt.UTC().Format(time.RFC3339), + }) + } + } + sortManifestMapsByID(builds) + attestations := []map[string]any{} + if profileAllowsPackageType(profile, "build_attestation") { + for _, attestation := range l.attestations { + if attestation.TenantID != tenantID || !buildIDs[attestation.BuildID] { + continue + } + attestations = append(attestations, map[string]any{ + "id": attestation.ID, + "build_id": attestation.BuildID, + "evidence_id": attestation.EvidenceID, + "payload_hash": attestation.PayloadHash, + "payload_size": attestation.PayloadSize, + "payload_type": attestation.PayloadType, + "predicate_type": attestation.PredicateType, + "subject_digests": append([]string(nil), attestation.SubjectDigests...), + "signature_count": attestation.SignatureCount, + "verification_status": attestation.VerificationStatus, + "schema_version": attestation.SchemaVersion, + "created_at": attestation.CreatedAt.UTC().Format(time.RFC3339), + }) + } + } + sortManifestMapsByID(attestations) + return map[string]any{"builds": builds, "build_attestations": attestations} +} + +func packageBuildOutputs(outputs []domain.BuildOutput) []map[string]any { + out := make([]map[string]any, 0, len(outputs)) + for _, output := range outputs { + out = append(out, map[string]any{"artifact_id": output.ArtifactID, "digest": output.Digest}) + } + sort.Slice(out, func(i, j int) bool { + return out[i]["artifact_id"].(string)+"\x00"+out[i]["digest"].(string) < out[j]["artifact_id"].(string)+"\x00"+out[j]["digest"].(string) + }) + return out +} + +func packageOptionalTime(value *time.Time) string { + if value == nil { + return "" + } + return value.UTC().Format(time.RFC3339) +} + +func (l *Ledger) packageReadinessChecksLocked(tenantID, releaseID string) []domain.PolicyCheck { + if releaseID == "" { + return nil + } + return []domain.PolicyCheck{ + l.checkReleaseHasEvidenceLocked(tenantID, releaseID, "sbom", "release_requires_sbom", "high"), + l.checkReleaseHasEvidenceLocked(tenantID, releaseID, "vulnerability_scan", "release_requires_vulnerability_scan", "high"), + l.checkReleaseHasArtifactDigestLocked(tenantID, releaseID), + l.checkReleaseHasSignedBundleLocked(tenantID, releaseID), + l.checkReleaseHasPassedBuildLocked(tenantID, releaseID), + l.checkReleaseHasBuildAttestationLocked(tenantID, releaseID), + l.checkNoOpenCriticalLocked(tenantID, releaseID), + } +} + +func packageReadinessSummary(result string, checks []domain.PolicyCheck, gaps []string) map[string]any { + checkSummaries := make([]map[string]any, 0, len(checks)) + for _, check := range checks { + checkSummaries = append(checkSummaries, map[string]any{ + "name": check.Name, + "result": check.Result, + "severity": check.Severity, + "missing": append([]string(nil), check.Missing...), + "explanation": check.Explanation, + }) + } + return map[string]any{ + "result": result, + "checks": checkSummaries, + "gaps": append([]string(nil), gaps...), + "limitations": []string{ + "Readiness is derived from recorded package-scope evidence only.", + "Readiness output is not a compliance, certification, or secure-release conclusion.", + }, + } +} + +func (l *Ledger) packageVerificationMaterialLocked(tenantID, releaseID string) map[string]any { + bundles := []map[string]any{} + for _, bundle := range l.bundles { + if bundle.TenantID != tenantID || bundle.ReleaseID != releaseID { + continue + } + bundles = append(bundles, map[string]any{ + "id": bundle.ID, + "state": bundle.State, + "manifest_hash": bundle.ManifestHash, + "signature_refs": append([]string(nil), bundle.SignatureRefs...), + "created_at": bundle.CreatedAt.UTC().Format(time.RFC3339), + }) + } + sortManifestMapsByID(bundles) + return map[string]any{ + "hash_algorithm": "sha256", + "canonicalization": domain.CanonicalizationProfileVersion, + "manifest_hash_field": "manifest_hash", + "release_bundles": bundles, + "audit_chain": l.packageAuditChainSummaryLocked(tenantID), + } +} + +func (l *Ledger) packageAuditChainSummaryLocked(tenantID string) map[string]any { + checks := l.verifyChainLocked(tenantID) + result := "passed" + for _, check := range checks { + if check.Result == "failed" { + result = "failed" + break + } + } + entries := l.chain[tenantID] + head := "" + if len(entries) > 0 { + head = entries[len(entries)-1].EntryHash + } + return map[string]any{ + "result": result, + "latest_sequence": len(entries), + "head_hash": head, + "checks": checks, + } +} + +func sortedStringSet(in map[string]bool) []string { + out := make([]string, 0, len(in)) + for value := range in { + if strings.TrimSpace(value) != "" { + out = append(out, value) + } + } + sort.Strings(out) + return out +} + +func cloneIntMap(in map[string]int) map[string]int { + if len(in) == 0 { + return map[string]int{} + } + out := make(map[string]int, len(in)) + for key, value := range in { + out[key] = value + } + return out +} + +func sortManifestMapsByID(items []map[string]any) { + sort.Slice(items, func(i, j int) bool { + left, _ := items[i]["id"].(string) + right, _ := items[j]["id"].(string) + return left < right + }) +} + func (s packageReportService) AccessCustomerSecurityPackage(ctx context.Context, actor domain.Actor, id string) (domain.CustomerSecurityPackage, error) { l := s.ledger if err := ctx.Err(); err != nil { @@ -737,7 +1281,14 @@ func (l *Ledger) packageEvidenceIDsLocked(tenantID, productID, releaseID string, } ids := []string{} for _, item := range l.evidence { - if item.TenantID != tenantID || (productID != "" && item.ProductID != productID) || (releaseID != "" && item.ReleaseID != releaseID) { + if item.TenantID != tenantID { + continue + } + if releaseID != "" { + if item.ReleaseID != releaseID { + continue + } + } else if productID != "" && item.ProductID != productID { continue } if len(allowed) > 0 { diff --git a/internal/app/governance_packages_test.go b/internal/app/governance_packages_test.go index d6c0385..34a4219 100644 --- a/internal/app/governance_packages_test.go +++ b/internal/app/governance_packages_test.go @@ -108,6 +108,112 @@ func TestWaiverApprovalAndCustomerPackageFlow(t *testing.T) { } } +func TestCustomerPackageV2ManifestSchemaAndSensitiveFieldExclusion(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, release, artifact := setupReleaseRiskFixture(t, ledger) + if _, err := ledger.CreateOrganization(ctx, actor, CreateOrganizationInput{Name: "Example Org", Slug: "example-org"}); err != nil { + t.Fatalf("organization: %v", err) + } + project, err := ledger.CreateProject(ctx, actor, release.ProductID, "api") + if err != nil { + t.Fatalf("project: %v", err) + } + if _, err := ledger.UploadSBOM(ctx, actor, release.ID, artifact.ID, []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","components":[{"name":"openssl","version":"3.1.0","purl":"pkg:apk/openssl@3.1.0"}]}`)); err != nil { + t.Fatalf("sbom: %v", err) + } + scan := uploadVEXMappingScan(t, ctx, ledger, actor, release.ID, "CVE-2026-0700", "pkg:apk/openssl@3.1.0") + vex, err := ledger.UploadVEX(ctx, actor, release.ID, artifact.ID, openVEXFixture(t, []map[string]any{ + openVEXStatementFixture("CVE-2026-0700", []map[string]any{{"@id": "pkg:apk/openssl@3.1.0"}}, decisionStatusFixed, "fixed_in_release"), + })) + if err != nil { + t.Fatalf("vex: %v", err) + } + decision, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{ + Status: decisionStatusNotAffected, + Justification: "manual customer-safe fallback", + ImpactStatement: "This release is not affected based on linked release evidence.", + ActionStatement: "No customer action is required for this finding.", + CustomerVisible: true, + InternalNotes: "private manual triage note", + VEXDocumentID: vex.ID, + }) + if err != nil { + t.Fatalf("decision: %v", err) + } + exception, err := ledger.CreateException(ctx, actor, CreateExceptionInput{ReleaseID: release.ID, FindingID: scan.Findings[0].ID, Reason: "temporary review exception", Owner: "security", ExpiresAt: fixedNow().Add(24 * time.Hour)}) + if err != nil { + t.Fatalf("exception: %v", err) + } + if _, err := ledger.ApproveException(ctx, actor, exception.ID); err != nil { + t.Fatalf("approve exception: %v", err) + } + waiver, err := ledger.CreateWaiver(ctx, actor, CreateWaiverInput{ScopeType: "release", ScopeID: release.ID, Owner: "security", Risk: "accepted temporarily", Reason: "customer-visible package waiver", ExpiresAt: fixedNow().Add(24 * time.Hour)}) + if err != nil { + t.Fatalf("waiver: %v", err) + } + if _, err := ledger.ApproveWaiver(ctx, actor, waiver.ID); err != nil { + t.Fatalf("approve waiver: %v", err) + } + if _, err := ledger.CreateApprovalRecord(ctx, actor, CreateApprovalInput{SubjectType: "release", SubjectID: release.ID, Decision: "approved", Reason: "release reviewed for package"}); err != nil { + t.Fatalf("approval: %v", err) + } + build, err := ledger.CreateBuildRun(ctx, actor, CreateBuildRunInput{ProjectID: project.ID, ReleaseID: release.ID, Provider: "generic_ci", CommitSHA: "0123456789abcdef0123456789abcdef01234567", Status: "passed", StartedAt: fixedNow(), Outputs: []domain.BuildOutput{{ArtifactID: artifact.ID, Digest: artifact.Digest}}}) + if err != nil { + t.Fatalf("build: %v", err) + } + if _, err := ledger.UploadBuildAttestation(ctx, actor, build.ID, dsseForDigest(t, artifact.Digest)); err != nil { + t.Fatalf("attestation: %v", err) + } + bundle, err := ledger.CreateReleaseBundle(ctx, actor, release.ID) + if err != nil { + t.Fatalf("bundle: %v", err) + } + profile, err := ledger.CreateRedactionProfile(ctx, actor, CreateRedactionProfileInput{ + Name: "customer v2", + AllowedTypes: []string{ + "artifact", "sbom", "vulnerability_scan", "vex", "vulnerability_decision", "approval", "exception", "waiver", "build", "build_attestation", "release_bundle", + }, + }) + if err != nil { + t.Fatalf("redaction profile: %v", err) + } + pkg, err := ledger.CreateCustomerSecurityPackage(ctx, actor, CreateCustomerPackageInput{ProductID: release.ProductID, ReleaseID: release.ID, RedactionProfileID: profile.ID, Title: "Customer v2 package", ExpiresAt: fixedNow().Add(time.Hour)}) + if err != nil { + t.Fatalf("package: %v", err) + } + manifest := pkg.Manifest + if manifest["schema_version"] != domain.CustomerPackageSchemaVersion || manifest["package_version"] != domain.CustomerPackageSchemaVersion || manifest["package_id"] != pkg.ID { + t.Fatalf("manifest version/id fields = %#v", manifest) + } + for _, key := range []string{"tenant", "organization", "product", "release", "artifact_digests", "sboms", "vulnerability_scans", "vex_documents", "vulnerability_decisions", "approvals", "exceptions", "waivers", "provenance", "readiness_summary", "verification_material", "redaction_profile", "limitations", "non_claims"} { + if _, ok := manifest[key]; !ok { + t.Fatalf("manifest missing %s: %#v", key, manifest) + } + } + textBytes, err := json.Marshal(manifest) + if err != nil { + t.Fatalf("marshal manifest: %v", err) + } + text := string(textBytes) + for _, want := range []string{artifact.Digest, "cyclonedx", "grype", vex.ID, decision.ImpactStatement, bundle.ManifestHash, "audit_chain"} { + if !strings.Contains(text, want) { + t.Fatalf("manifest missing %q: %s", want, text) + } + } + for _, forbidden := range []string{"private manual triage note", "payload_ref", "object://", "api_key_secret", "evy_", "private_key", "session_hash"} { + if strings.Contains(strings.ToLower(text), strings.ToLower(forbidden)) { + t.Fatalf("manifest leaked %q: %s", forbidden, text) + } + } + if !strings.Contains(text, "not legal compliance proof") || strings.Contains(text, "certified secure") { + t.Fatalf("manifest non-claims missing or unsafe: %s", text) + } + if _, err := customerPackageArchive(pkg); err != nil { + t.Fatalf("package viewer/archive should load v2 manifest JSON: %v", err) + } +} + func packageArchiveFiles(t *testing.T, body []byte) map[string]string { t.Helper() reader, err := zip.NewReader(bytes.NewReader(body), int64(len(body))) diff --git a/internal/domain/domain.go b/internal/domain/domain.go index 27f9d24..0176276 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -45,7 +45,7 @@ const ( WaiverSchemaVersion = "waiver.v1.0.0" ApprovalRecordSchemaVersion = "approval-record.v1.0.0" RedactionProfileSchemaVersion = "redaction-profile.v1.0.0" - CustomerPackageSchemaVersion = "customer-security-package.v1.0.0" + CustomerPackageSchemaVersion = "customer-security-package.v2.0.0" ReportTemplateSchemaVersion = "report-template.v1.0.0" EvidenceBundleSchemaVersion = "evidence-bundle.v1.0.0" EvidenceBundleImportVersion = "evidence-bundle-import.v1.0.0" diff --git a/site/package-viewer/index.html b/site/package-viewer/index.html index d617fbc..e5a05bd 100644 --- a/site/package-viewer/index.html +++ b/site/package-viewer/index.html @@ -139,27 +139,33 @@

Evydence Package Viewer

const jsonNode = document.getElementById("json"); const bundledDemo = { - data: { - id: "pkg_example", - release_id: "rel_example", - scope: "customer_review", - expires_at: "2026-06-30T00:00:00Z", - manifest_hash: "sha256:example", - included_subjects: [ - "release_bundle", - "readiness_report", - "sbom_summary", - "vulnerability_decisions" - ], - redactions: [ - "raw evidence payload bytes are excluded", - "secrets and private keys are excluded" - ], - limitations: [ - "Customer package supports technical evidence review only.", - "It is not legal compliance proof, certification, or a secure-release guarantee." - ] - } + schema_version: "customer-security-package.v2.0.0", + package_id: "csp_example", + title: "Example customer review package", + release_id: "rel_example", + generated_at: "2026-05-27T12:00:00Z", + readiness_summary: { + result: "passed", + checks: [{ name: "release_requires_sbom", result: "passed", severity: "high" }] + }, + artifact_digests: [ + { id: "art_example", name: "payments-api.tar.gz", digest: "sha256:example" } + ], + vulnerability_decisions: [ + { + id: "vd_example", + vulnerability: "CVE-2026-0002", + status: "fixed", + impact_statement: "The finding is fixed in this release artifact." + } + ], + limitations: [ + "Customer package supports technical evidence review only.", + "It is not legal compliance proof, certification, or a secure-release guarantee." + ], + non_claims: [ + "This package is not legal compliance proof, certification, complete SBOM proof, an authoritative vulnerability result, or a secure-release guarantee." + ] }; const pick = (obj, paths) => { @@ -194,8 +200,8 @@

Evydence Package Viewer

const data = parsed.data || parsed.manifest || parsed; summaryNode.textContent = ""; addPanel("File", fileName); - addPanel("Subject", pick(data, ["title", "id", "release_id", "subject_id", "manifest_hash"])); - addPanel("Result", pick(data, ["result", "status", "state"])); + addPanel("Subject", pick(data, ["title", "package_id", "id", "release_id", "subject_id", "manifest_hash"])); + addPanel("Result", pick(data, ["result", "readiness_summary.result", "status", "state"])); addPanel("Release", pick(data, ["release_id", "release.id", "subject.release_id"])); addPanel("Generated", pick(data, ["generated_at", "created_at", "checked_at"])); addPanel("Limitations", Array.isArray(data.limitations) ? data.limitations.length : "not present"); From 3c870e72f036cc3345d7b5678719ca15d732a788 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:21:00 +0300 Subject: [PATCH 183/287] feat(packages): add redaction profile presets --- .productization_next_steps.md | 2 +- docs/api.md | 4 +- docs/reference/customer-package-manifest.md | 15 +++ internal/adapters/httpapi/openapi.go | 3 +- internal/adapters/httpapi/router.go | 3 +- internal/adapters/httpapi/router_test.go | 9 ++ internal/app/governance_packages.go | 108 ++++++++++++++++++++ internal/app/governance_packages_test.go | 73 +++++++++++++ openapi.yaml | 2 +- 9 files changed, 214 insertions(+), 5 deletions(-) diff --git a/.productization_next_steps.md b/.productization_next_steps.md index 0c489d6..22b84e6 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -524,7 +524,7 @@ Acceptance criteria: * Manifest can be loaded by package viewer. * Tests verify sensitive fields are absent. -#### [ ] EVY-031 — Add package contents policy / redaction profile presets +#### [x] EVY-031 — Add package contents policy / redaction profile presets Priority: P0 diff --git a/docs/api.md b/docs/api.md index e601d56..ee7ecff 100644 --- a/docs/api.md +++ b/docs/api.md @@ -424,7 +424,9 @@ Customer package manifests use the documented schema. They include scoped release metadata, evidence summaries, redaction profile details, readiness checks, verification material, limitations, and non-claims while excluding raw payload bytes, object-store references, secrets, -token hashes, and internal decision notes. +token hashes, and internal decision notes. Redaction profiles can be created +from explicit `allowed_types` or the `customer_safe` / `security_review` +presets; preset policy fields cannot be overridden in the create request. ### Integrity, Verification, And Operations diff --git a/docs/reference/customer-package-manifest.md b/docs/reference/customer-package-manifest.md index ac997e9..9951051 100644 --- a/docs/reference/customer-package-manifest.md +++ b/docs/reference/customer-package-manifest.md @@ -43,6 +43,21 @@ SSO/session token hashes, and tenant-internal vulnerability decision notes. Customer-visible vulnerability decisions require `impact_statement`; internal notes are not copied into `vulnerability_decisions`. +## Presets + +`POST /v1/redaction-profiles` accepts either an explicit `allowed_types` list or +a server-defined `preset`. Presets reject caller-supplied `allowed_types` or +`excluded_fields` overrides so the package policy remains predictable. + +| Preset | Intended use | Default shape | +| --- | --- | --- | +| `customer_safe` | Customer release-evidence review. | Includes artifact, SBOM, vulnerability scan, VEX, active customer-visible decisions, release bundle, approval, exception, and waiver summaries. Excludes build provenance, internal URLs, raw payloads, token/key material, and internal notes. | +| `security_review` | Broader technical security review. | Includes the customer-safe families plus build provenance, build attestations, security-scan/manual-review categories, and API/security-review records where present. Still excludes raw payloads, object-store references, secrets, token material, and private keys. | + +Custom profiles must supply at least one `allowed_types` entry. An empty custom +profile is rejected because it would make package contents depend on implicit +defaults instead of explicit operator scope. + ## Viewer Compatibility The local package viewer at `site/package-viewer/index.html` loads v2 manifests diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 37a4c6a..f839a33 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -997,9 +997,10 @@ func registerCriticalSchemas(registry *specs.Registry) { registry.RegisterSchema("CreateRedactionProfileRequest", objectSchema(map[string]any{ "name": map[string]any{"type": "string"}, "description": map[string]any{"type": "string"}, + "preset": map[string]any{"type": "string", "enum": []string{"customer_safe", "security_review"}, "description": "Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted."}, "allowed_types": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, "excluded_fields": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, - }, "name")) + })) registry.RegisterSchema("RedactionProfile", objectSchema(map[string]any{ "id": map[string]any{"type": "string"}, "tenant_id": map[string]any{"type": "string"}, diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index 0479bb4..eb9ae0a 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -1009,6 +1009,7 @@ func (s *Server) createRedactionProfile(w http.ResponseWriter, r *http.Request) var req struct { Name string `json:"name"` Description string `json:"description"` + Preset string `json:"preset"` AllowedTypes []string `json:"allowed_types"` ExcludedFields []string `json:"excluded_fields"` } @@ -1016,7 +1017,7 @@ func (s *Server) createRedactionProfile(w http.ResponseWriter, r *http.Request) if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - profile, err := s.ledger.CreateRedactionProfile(ctx, actor, app.CreateRedactionProfileInput{Name: req.Name, Description: req.Description, AllowedTypes: req.AllowedTypes, ExcludedFields: req.ExcludedFields}) + profile, err := s.ledger.CreateRedactionProfile(ctx, actor, app.CreateRedactionProfileInput{Name: req.Name, Description: req.Description, Preset: req.Preset, AllowedTypes: req.AllowedTypes, ExcludedFields: req.ExcludedFields}) return http.StatusCreated, profile, err }) } diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 0084767..69b77ff 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -90,6 +90,10 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { if _, ok := decisionRequestProps["vex_document_id"]; !ok { t.Fatalf("manual decision request schema missing vex_document_id: %#v", decisionRequestProps) } + redactionRequestProps := asStringAnyMap(t, asStringAnyMap(t, schemas["CreateRedactionProfileRequest"])["properties"]) + if _, ok := redactionRequestProps["preset"]; !ok { + t.Fatalf("redaction profile request schema missing preset: %#v", redactionRequestProps) + } for _, schemaName := range []string{"ReadinessStatusEnvelope", "BackupManifestEnvelope", "VerificationResultEnvelope", "ReadinessReportEnvelope", "CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "VEXImportReportEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "VulnerabilityDecisionListEnvelope", "VulnerabilityDecisionSummaryReportEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "UpdateSSOProviderTrustMaterialRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "ExchangeSSOCredentialRequest", "SSOCredentialExchangeEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "DataEnvelope"} { if _, ok := schemas[schemaName]; !ok { t.Fatalf("schema %s missing from OpenAPI components", schemaName) @@ -1084,6 +1088,11 @@ func TestGovernancePackageAndBundleHTTPFlow(t *testing.T) { profileBody := postJSON(t, server, secret, "/v1/redaction-profiles", "gov-profile", map[string]any{"name": "customer", "allowed_types": []string{"security_review"}, "excluded_fields": []string{"payload_ref"}}, http.StatusCreated) profileID := dataField(t, profileBody, "id") + presetProfile := postJSON(t, server, secret, "/v1/redaction-profiles", "gov-profile-preset", map[string]any{"preset": "security_review"}, http.StatusCreated) + if !strings.Contains(presetProfile, `"name":"security_review"`) || !strings.Contains(presetProfile, "build_attestation") { + t.Fatalf("preset redaction profile response incomplete: %s", presetProfile) + } + postJSON(t, server, secret, "/v1/redaction-profiles", "gov-profile-preset-override", map[string]any{"preset": "customer_safe", "allowed_types": []string{"build"}}, http.StatusBadRequest) packageBody := postJSON(t, server, secret, "/v1/customer-packages", "gov-package", map[string]any{"product_id": productID, "release_id": releaseID, "redaction_profile_id": profileID, "title": "Customer package", "expires_at": time.Now().UTC().Add(time.Hour).Format(time.RFC3339)}, http.StatusCreated) packageID := dataField(t, packageBody, "id") getJSON(t, server, secret, "/v1/customer-packages/"+packageID, http.StatusOK) diff --git a/internal/app/governance_packages.go b/internal/app/governance_packages.go index b75ee2c..8f4406c 100644 --- a/internal/app/governance_packages.go +++ b/internal/app/governance_packages.go @@ -38,6 +38,7 @@ type CreateApprovalInput struct { type CreateRedactionProfileInput struct { Name string Description string + Preset string AllowedTypes []string ExcludedFields []string } @@ -80,6 +81,105 @@ type CreateDSSETrustRootInput struct { PublicKey string } +type redactionProfilePreset struct { + Name string + Description string + AllowedTypes []string + ExcludedFields []string +} + +var redactionProfilePresets = map[string]redactionProfilePreset{ + "customer_safe": { + Name: "customer_safe", + Description: "Customer-safe package profile for release evidence summaries without raw payloads, secrets, internal notes, or internal-only provenance fields.", + AllowedTypes: []string{ + "artifact", + "sbom", + "vulnerability_scan", + "vex", + "vulnerability_decision", + "release_bundle", + "approval", + "exception", + "waiver", + }, + ExcludedFields: []string{ + "action_internal_url", + "environment_hash", + "internal_notes", + "internal_url", + "object_key", + "oidc_subject", + "parameters_hash", + "payload", + "payload_bytes", + "payload_ref", + "private_key", + "repository", + "secret", + "source_identity", + "token", + "workflow_ref", + }, + }, + "security_review": { + Name: "security_review", + Description: "Security-review package profile for broader technical evidence review while still excluding raw payloads, secrets, token material, and private keys.", + AllowedTypes: []string{ + "api_security", + "approval", + "artifact", + "build", + "build_attestation", + "dast", + "exception", + "license_scan", + "manual_security_document", + "openapi_contract", + "pen_test_report", + "release_bundle", + "sast", + "sbom", + "secret_scan", + "security_review", + "threat_model", + "vex", + "vulnerability_decision", + "vulnerability_scan", + "waiver", + }, + ExcludedFields: []string{ + "internal_notes", + "object_key", + "payload", + "payload_bytes", + "payload_ref", + "private_key", + "secret", + "token", + }, + }, +} + +func applyRedactionProfilePreset(in CreateRedactionProfileInput) (CreateRedactionProfileInput, error) { + presetName := strings.TrimSpace(in.Preset) + if presetName == "" { + return in, nil + } + preset, ok := redactionProfilePresets[presetName] + if !ok { + return CreateRedactionProfileInput{}, ErrValidation + } + if len(in.AllowedTypes) > 0 || len(in.ExcludedFields) > 0 { + return CreateRedactionProfileInput{}, ErrValidation + } + in.Name = preset.Name + in.Description = preset.Description + in.AllowedTypes = append([]string(nil), preset.AllowedTypes...) + in.ExcludedFields = append([]string(nil), preset.ExcludedFields...) + return in, nil +} + func (l *Ledger) CreateWaiver(ctx context.Context, actor domain.Actor, in CreateWaiverInput) (domain.Waiver, error) { if err := ctx.Err(); err != nil { return domain.Waiver{}, err @@ -211,10 +311,18 @@ func (s packageReportService) CreateRedactionProfile(ctx context.Context, actor if err := require(actor, ScopePackageWrite); err != nil { return domain.RedactionProfile{}, err } + var err error + in, err = applyRedactionProfilePreset(in) + if err != nil { + return domain.RedactionProfile{}, err + } in.Name = strings.TrimSpace(in.Name) if in.Name == "" { return domain.RedactionProfile{}, ErrValidation } + if len(in.AllowedTypes) == 0 { + return domain.RedactionProfile{}, ErrValidation + } for _, typ := range in.AllowedTypes { if strings.TrimSpace(typ) == "" { return domain.RedactionProfile{}, ErrValidation diff --git a/internal/app/governance_packages_test.go b/internal/app/governance_packages_test.go index 34a4219..3991edc 100644 --- a/internal/app/governance_packages_test.go +++ b/internal/app/governance_packages_test.go @@ -214,6 +214,79 @@ func TestCustomerPackageV2ManifestSchemaAndSensitiveFieldExclusion(t *testing.T) } } +func TestRedactionProfilePresetsAreExplicitAndSafe(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, release, artifact := setupReleaseRiskFixture(t, ledger) + project, err := ledger.CreateProject(ctx, actor, release.ProductID, "api") + if err != nil { + t.Fatalf("project: %v", err) + } + if _, err := ledger.CreateBuildRun(ctx, actor, CreateBuildRunInput{ + ProjectID: project.ID, + ReleaseID: release.ID, + Provider: "github_actions", + CommitSHA: "0123456789abcdef0123456789abcdef01234567", + Repository: "github.internal.example/payments/api", + WorkflowRef: "github.internal.example/payments/api/.github/workflows/build.yml@refs/heads/main", + RunID: "123", + RunAttempt: 1, + Status: "passed", + StartedAt: fixedNow(), + Outputs: []domain.BuildOutput{{ArtifactID: artifact.ID, Digest: artifact.Digest}}, + }); err != nil { + t.Fatalf("build: %v", err) + } + customerSafe, err := ledger.CreateRedactionProfile(ctx, actor, CreateRedactionProfileInput{Preset: "customer_safe"}) + if err != nil { + t.Fatalf("customer-safe preset: %v", err) + } + if customerSafe.Name != "customer_safe" || !stringSliceContains(customerSafe.ExcludedFields, "internal_url") || stringSliceContains(customerSafe.AllowedTypes, "build") { + t.Fatalf("customer-safe profile = %#v", customerSafe) + } + pkg, err := ledger.CreateCustomerSecurityPackage(ctx, actor, CreateCustomerPackageInput{ProductID: release.ProductID, ReleaseID: release.ID, RedactionProfileID: customerSafe.ID, Title: "Customer safe package", ExpiresAt: fixedNow().Add(time.Hour)}) + if err != nil { + t.Fatalf("customer-safe package: %v", err) + } + body, err := json.Marshal(pkg.Manifest) + if err != nil { + t.Fatalf("marshal customer-safe manifest: %v", err) + } + text := string(body) + if !strings.Contains(text, `"name":"customer_safe"`) { + t.Fatalf("manifest does not name preset profile: %s", text) + } + if strings.Contains(text, "github.internal.example") || strings.Contains(text, `"provenance"`) { + t.Fatalf("customer-safe package leaked internal provenance: %s", text) + } + + securityReview, err := ledger.CreateRedactionProfile(ctx, actor, CreateRedactionProfileInput{Preset: "security_review"}) + if err != nil { + t.Fatalf("security-review preset: %v", err) + } + if !stringSliceContains(securityReview.AllowedTypes, "build") || !stringSliceContains(securityReview.AllowedTypes, "build_attestation") { + t.Fatalf("security-review profile missing provenance types: %#v", securityReview) + } + securityPkg, err := ledger.CreateCustomerSecurityPackage(ctx, actor, CreateCustomerPackageInput{ProductID: release.ProductID, ReleaseID: release.ID, RedactionProfileID: securityReview.ID, Title: "Security review package", ExpiresAt: fixedNow().Add(time.Hour)}) + if err != nil { + t.Fatalf("security-review package: %v", err) + } + securityBody, err := json.Marshal(securityPkg.Manifest) + if err != nil { + t.Fatalf("marshal security-review manifest: %v", err) + } + if !strings.Contains(string(securityBody), `"provenance"`) { + t.Fatalf("security-review package missing provenance: %s", securityBody) + } + + if _, err := ledger.CreateRedactionProfile(ctx, actor, CreateRedactionProfileInput{Preset: "customer_safe", AllowedTypes: []string{"build"}}); !errors.Is(err, ErrValidation) { + t.Fatalf("preset override err=%v, want validation", err) + } + if _, err := ledger.CreateRedactionProfile(ctx, actor, CreateRedactionProfileInput{Name: "unsafe"}); !errors.Is(err, ErrValidation) { + t.Fatalf("unsafe unscoped profile err=%v, want validation", err) + } +} + func packageArchiveFiles(t *testing.T, body []byte) map[string]string { t.Helper() reader, err := zip.NewReader(bytes.NewReader(body), int64(len(body))) diff --git a/openapi.yaml b/openapi.yaml index 8251207..922e7e3 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["name"],"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From 41cf6b5aecae076b2d12521cf7b7e71aa1dfdfb8 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:22:43 +0300 Subject: [PATCH 184/287] feat(cli): verify customer packages offline --- .productization_next_steps.md | 2 +- cmd/evydence/main.go | 558 ++++++++++++++++-- cmd/evydence/main_test.go | 179 ++++++ docs/how-to/view-packages.md | 8 + docs/reference/customer-package-manifest.md | 33 ++ .../end-to-end-release-evidence/README.md | 11 +- 6 files changed, 750 insertions(+), 41 deletions(-) diff --git a/.productization_next_steps.md b/.productization_next_steps.md index 22b84e6..2a55581 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -548,7 +548,7 @@ Acceptance criteria: * Package manifest names the profile used. * API refuses unsafe export without explicit scope/permission. -#### [ ] EVY-032 — Add customer package verification command +#### [x] EVY-032 — Add customer package verification command Priority: P1 diff --git a/cmd/evydence/main.go b/cmd/evydence/main.go index e0ee705..6da51c8 100644 --- a/cmd/evydence/main.go +++ b/cmd/evydence/main.go @@ -1,6 +1,7 @@ package main import ( + "archive/zip" "bytes" "context" "crypto/ed25519" @@ -58,6 +59,11 @@ func run(args []string) error { return usage() } return verifyAuditChain(args[1]) + case "package": + if len(args) < 2 || args[1] != "verify" { + return usage() + } + return verifyCustomerPackage(args[2:]) case "github-actions": if len(args) < 2 || args[1] != "upload-build" { return usage() @@ -95,7 +101,7 @@ func run(args []string) error { } func usage() error { - return errors.New("usage: evydence hash | evydence verify-manifest --hash sha256: | evydence verify-evidence-bundle | evydence verify-audit-chain | evydence github-actions upload-build ... | evydence import-bundle upload ... | evydence upload manifest ... | evydence release manifest|sign|verify|keygen") + return errors.New("usage: evydence hash | evydence verify-manifest --hash sha256: | evydence verify-evidence-bundle | evydence verify-audit-chain | evydence package verify ... | evydence github-actions upload-build ... | evydence import-bundle upload ... | evydence upload manifest ... | evydence release manifest|sign|verify|keygen") } func hashFile(path string) (string, error) { @@ -150,49 +156,15 @@ func verifyManifest(path, expected string) error { } func verifyEvidenceBundle(path string) error { - cleaned, err := cleanOperatorPath(path) - if err != nil { - return err - } - // #nosec G304,G703 -- this CLI command intentionally reads a local operator-specified bundle file. - body, err := os.ReadFile(cleaned) - if err != nil { - return err - } - var bundle struct { - Manifest map[string]any `json:"manifest"` - ManifestHash string `json:"manifest_hash"` - SignatureRefs []string `json:"signature_refs"` - Signatures []offlineSignature `json:"signatures"` - SigningKeys []offlineSigningKey `json:"signing_keys"` - } - if err := json.Unmarshal(body, &bundle); err != nil { - return errors.New("evidence bundle is not JSON") - } - if len(bundle.Manifest) == 0 || strings.TrimSpace(bundle.ManifestHash) == "" { - return errors.New("evidence bundle missing manifest or manifest_hash") - } - canonical, err := json.Marshal(bundle.Manifest) + bundle, err := readEvidenceBundle(path) if err != nil { return err } - var normalized any - if err := json.Unmarshal(canonical, &normalized); err != nil { - return err - } - canonical, err = json.Marshal(normalized) + verified, err := verifyEvidenceBundleStruct(bundle) if err != nil { return err } - sum := sha256.Sum256(canonical) - got := "sha256:" + hex.EncodeToString(sum[:]) - if got != bundle.ManifestHash { - return fmt.Errorf("evidence bundle hash mismatch: got %s want %s", got, bundle.ManifestHash) - } - if err := verifyOfflineSignatures(bundle.ManifestHash, bundle.SignatureRefs, bundle.Signatures, bundle.SigningKeys); err != nil { - return err - } - if len(bundle.Signatures) > 0 || len(bundle.SigningKeys) > 0 { + if verified.Signed { fmt.Println("evidence bundle manifest and signature verified") return nil } @@ -208,6 +180,20 @@ type offlineSignature struct { CreatedAt time.Time `json:"created_at,omitempty"` } +type offlineEvidenceBundle struct { + Manifest map[string]any `json:"manifest"` + ManifestHash string `json:"manifest_hash"` + SignatureRefs []string `json:"signature_refs"` + Signatures []offlineSignature `json:"signatures"` + SigningKeys []offlineSigningKey `json:"signing_keys"` +} + +type offlineEvidenceBundleVerification struct { + ManifestHash string + Signed bool + SigningKeyIDs []string +} + type offlineSigningKey struct { ID string `json:"id"` Algorithm string `json:"algorithm"` @@ -356,6 +342,502 @@ func verifyOfflineSignatures(payloadHash string, refs []string, signatures []off return errors.New("offline signature verification failed") } +func readEvidenceBundle(path string) (offlineEvidenceBundle, error) { + body, err := readFileStrict(path) + if err != nil { + return offlineEvidenceBundle{}, err + } + var bundle offlineEvidenceBundle + if err := json.Unmarshal(body, &bundle); err != nil { + return offlineEvidenceBundle{}, errors.New("evidence bundle is not JSON") + } + return bundle, nil +} + +func verifyEvidenceBundleStruct(bundle offlineEvidenceBundle) (offlineEvidenceBundleVerification, error) { + if len(bundle.Manifest) == 0 || strings.TrimSpace(bundle.ManifestHash) == "" { + return offlineEvidenceBundleVerification{}, errors.New("evidence bundle missing manifest or manifest_hash") + } + canonical, err := json.Marshal(bundle.Manifest) + if err != nil { + return offlineEvidenceBundleVerification{}, err + } + var normalized any + if err := json.Unmarshal(canonical, &normalized); err != nil { + return offlineEvidenceBundleVerification{}, err + } + canonical, err = json.Marshal(normalized) + if err != nil { + return offlineEvidenceBundleVerification{}, err + } + sum := sha256.Sum256(canonical) + got := "sha256:" + hex.EncodeToString(sum[:]) + if got != bundle.ManifestHash { + return offlineEvidenceBundleVerification{}, fmt.Errorf("evidence bundle hash mismatch: got %s want %s", got, bundle.ManifestHash) + } + keyIDs := evidenceBundleSigningKeyIDs(bundle) + if err := verifyOfflineSignatures(bundle.ManifestHash, bundle.SignatureRefs, bundle.Signatures, bundle.SigningKeys); err != nil { + return offlineEvidenceBundleVerification{}, err + } + return offlineEvidenceBundleVerification{ManifestHash: bundle.ManifestHash, Signed: len(bundle.Signatures) > 0 || len(bundle.SigningKeys) > 0, SigningKeyIDs: keyIDs}, nil +} + +func evidenceBundleSigningKeyIDs(bundle offlineEvidenceBundle) []string { + byID := map[string]offlineSignature{} + for _, signature := range bundle.Signatures { + if strings.TrimSpace(signature.ID) != "" { + byID[signature.ID] = signature + } + } + seen := map[string]bool{} + keyIDs := []string{} + for _, ref := range bundle.SignatureRefs { + signature, ok := byID[strings.TrimSpace(ref)] + if !ok || strings.TrimSpace(signature.KeyID) == "" || seen[signature.KeyID] { + continue + } + seen[signature.KeyID] = true + keyIDs = append(keyIDs, signature.KeyID) + } + return keyIDs +} + +const ( + customerPackageSchemaVersion = "customer-security-package.v2.0.0" + maxCustomerPackageFileBytes = int64(10 << 20) +) + +type customerPackageVerifyResult struct { + ManifestHash string + PackageID string + TenantID string + ProductID string + ReleaseID string + EvidenceIDs []string + ReleaseBundleHashes []string +} + +type customerPackageArchiveFiles struct { + Manifest []byte + Metadata map[string]any + Verification map[string]any +} + +func verifyCustomerPackage(args []string) error { + fs := flag.NewFlagSet("package verify", flag.ContinueOnError) + fs.SetOutput(io.Discard) + manifestPath := fs.String("manifest", "", "customer package manifest JSON path") + archivePath := fs.String("archive", "", "customer package ZIP path") + bundlePath := fs.String("bundle", "", "evidence bundle JSON path") + expectedHash := fs.String("hash", "", "expected canonical manifest hash sha256:") + expectedTenantID := fs.String("expected-tenant-id", "", "expected tenant id") + expectedProductID := fs.String("expected-product-id", "", "expected product id") + expectedReleaseID := fs.String("expected-release-id", "", "expected release id") + expectedPackageID := fs.String("expected-package-id", "", "expected package id") + expectedSigningKeyID := fs.String("expected-signing-key-id", "", "expected evidence-bundle signing key id") + if err := fs.Parse(args); err != nil { + return usage() + } + if fs.NArg() != 0 || (strings.TrimSpace(*manifestPath) == "" && strings.TrimSpace(*archivePath) == "") { + return usage() + } + + var archive customerPackageArchiveFiles + var manifestBody []byte + if strings.TrimSpace(*archivePath) != "" { + var err error + archive, err = readCustomerPackageArchive(*archivePath) + if err != nil { + return err + } + manifestBody = archive.Manifest + } + if strings.TrimSpace(*manifestPath) != "" { + body, err := readFileStrict(*manifestPath) + if err != nil { + return err + } + if len(manifestBody) > 0 { + archiveHash, err := canonicalJSONBytesHash(manifestBody) + if err != nil { + return err + } + fileHash, err := canonicalJSONBytesHash(body) + if err != nil { + return err + } + if archiveHash != fileHash { + return errors.New("manifest file and archive manifest do not match") + } + } + manifestBody = body + } + + result, err := verifyCustomerPackageManifestBytes(manifestBody) + if err != nil { + return err + } + if expected := strings.TrimSpace(*expectedHash); expected != "" && result.ManifestHash != expected { + return fmt.Errorf("customer package manifest hash mismatch: got %s want %s", result.ManifestHash, expected) + } + if err := verifyExpectedValue("tenant id", result.TenantID, *expectedTenantID); err != nil { + return err + } + if err := verifyExpectedValue("product id", result.ProductID, *expectedProductID); err != nil { + return err + } + if err := verifyExpectedValue("release id", result.ReleaseID, *expectedReleaseID); err != nil { + return err + } + if err := verifyExpectedValue("package id", result.PackageID, *expectedPackageID); err != nil { + return err + } + if len(archive.Manifest) > 0 { + if err := verifyCustomerPackageArchiveMetadata(archive, result); err != nil { + return err + } + } + bundleStatus := "not supplied" + if strings.TrimSpace(*bundlePath) != "" { + bundle, err := readEvidenceBundle(*bundlePath) + if err != nil { + return err + } + verified, err := verifyEvidenceBundleStruct(bundle) + if err != nil { + return err + } + if expected := strings.TrimSpace(*expectedSigningKeyID); expected != "" && !stringInSlice(verified.SigningKeyIDs, expected) { + return fmt.Errorf("expected signing key id %s was not used by evidence bundle signatures", expected) + } + if err := verifyCustomerPackageEvidenceCoverage(result.EvidenceIDs, bundle.Manifest); err != nil { + return err + } + bundleStatus = "verified" + if verified.Signed { + bundleStatus = "verified with signature" + } + } + fmt.Printf("customer package verified\npackage_id: %s\nproduct_id: %s\nrelease_id: %s\nmanifest_hash: %s\nevidence_bundle: %s\n", result.PackageID, result.ProductID, result.ReleaseID, result.ManifestHash, bundleStatus) + return nil +} + +func verifyCustomerPackageManifestBytes(body []byte) (customerPackageVerifyResult, error) { + if len(bytes.TrimSpace(body)) == 0 { + return customerPackageVerifyResult{}, errors.New("customer package manifest is empty") + } + var raw any + if err := json.Unmarshal(body, &raw); err != nil { + return customerPackageVerifyResult{}, errors.New("customer package manifest is not valid JSON") + } + if err := rejectCustomerPackageSensitiveKeys(raw); err != nil { + return customerPackageVerifyResult{}, err + } + hash, err := canonicalJSONBytesHash(body) + if err != nil { + return customerPackageVerifyResult{}, err + } + var manifest struct { + SchemaVersion string `json:"schema_version"` + PackageVersion string `json:"package_version"` + PackageID string `json:"package_id"` + ID string `json:"id"` + Title string `json:"title"` + GeneratedAt string `json:"generated_at"` + Tenant struct{ ID string } `json:"tenant"` + ProductID string `json:"product_id"` + Product struct{ ID string } `json:"product"` + ReleaseID string `json:"release_id"` + Release struct{ ID string } `json:"release"` + RedactionProfile struct { + ID string `json:"id"` + Name string `json:"name"` + AllowedTypes []string `json:"allowed_types"` + SchemaVersion string `json:"schema_version"` + } `json:"redaction_profile"` + EvidenceIDs []string `json:"evidence_ids"` + ArtifactDigests []struct { + ID string `json:"id"` + Digest string `json:"digest"` + } `json:"artifact_digests"` + ReadinessSummary map[string]any `json:"readiness_summary"` + VerificationMaterial struct { + HashAlgorithm string `json:"hash_algorithm"` + ReleaseBundles []struct { + ManifestHash string `json:"manifest_hash"` + } `json:"release_bundles"` + } `json:"verification_material"` + Limitations []string `json:"limitations"` + NonClaims []string `json:"non_claims"` + } + if err := json.Unmarshal(body, &manifest); err != nil { + return customerPackageVerifyResult{}, errors.New("customer package manifest structure is invalid") + } + if strings.TrimSpace(manifest.SchemaVersion) != customerPackageSchemaVersion || strings.TrimSpace(manifest.PackageVersion) != customerPackageSchemaVersion { + return customerPackageVerifyResult{}, errors.New("customer package manifest schema_version is unsupported") + } + packageID := strings.TrimSpace(manifest.PackageID) + if packageID == "" { + packageID = strings.TrimSpace(manifest.ID) + } + if packageID == "" || strings.TrimSpace(manifest.ID) == "" || packageID != strings.TrimSpace(manifest.ID) { + return customerPackageVerifyResult{}, errors.New("customer package manifest id/package_id mismatch") + } + if strings.TrimSpace(manifest.Title) == "" || strings.TrimSpace(manifest.Tenant.ID) == "" || strings.TrimSpace(manifest.ProductID) == "" || strings.TrimSpace(manifest.Product.ID) == "" { + return customerPackageVerifyResult{}, errors.New("customer package manifest missing required identity fields") + } + if strings.TrimSpace(manifest.ProductID) != strings.TrimSpace(manifest.Product.ID) { + return customerPackageVerifyResult{}, errors.New("customer package manifest product id mismatch") + } + if strings.TrimSpace(manifest.ReleaseID) != "" && strings.TrimSpace(manifest.Release.ID) != "" && strings.TrimSpace(manifest.ReleaseID) != strings.TrimSpace(manifest.Release.ID) { + return customerPackageVerifyResult{}, errors.New("customer package manifest release id mismatch") + } + if _, err := time.Parse(time.RFC3339Nano, strings.TrimSpace(manifest.GeneratedAt)); err != nil { + return customerPackageVerifyResult{}, errors.New("customer package manifest generated_at must be RFC3339") + } + if strings.TrimSpace(manifest.RedactionProfile.ID) == "" || strings.TrimSpace(manifest.RedactionProfile.Name) == "" || len(manifest.RedactionProfile.AllowedTypes) == 0 || strings.TrimSpace(manifest.RedactionProfile.SchemaVersion) == "" { + return customerPackageVerifyResult{}, errors.New("customer package manifest missing redaction profile details") + } + if len(manifest.ReadinessSummary) == 0 || len(manifest.Limitations) == 0 || len(manifest.NonClaims) == 0 { + return customerPackageVerifyResult{}, errors.New("customer package manifest missing readiness, limitations, or non-claims") + } + if algorithm := strings.TrimSpace(manifest.VerificationMaterial.HashAlgorithm); algorithm != "" && algorithm != "sha256" { + return customerPackageVerifyResult{}, errors.New("customer package manifest uses unsupported hash algorithm") + } + for _, artifact := range manifest.ArtifactDigests { + if strings.TrimSpace(artifact.ID) == "" || !validSHA256Digest(artifact.Digest) { + return customerPackageVerifyResult{}, errors.New("customer package manifest has invalid artifact digest") + } + } + releaseBundleHashes := []string{} + for _, bundle := range manifest.VerificationMaterial.ReleaseBundles { + if strings.TrimSpace(bundle.ManifestHash) != "" { + releaseBundleHashes = append(releaseBundleHashes, strings.TrimSpace(bundle.ManifestHash)) + } + } + return customerPackageVerifyResult{ + ManifestHash: hash, + PackageID: packageID, + TenantID: strings.TrimSpace(manifest.Tenant.ID), + ProductID: strings.TrimSpace(manifest.ProductID), + ReleaseID: strings.TrimSpace(manifest.ReleaseID), + EvidenceIDs: trimStringSlice(manifest.EvidenceIDs), + ReleaseBundleHashes: releaseBundleHashes, + }, nil +} + +func readCustomerPackageArchive(path string) (customerPackageArchiveFiles, error) { + cleaned, err := cleanOperatorPath(path) + if err != nil { + return customerPackageArchiveFiles{}, err + } + // #nosec G304 -- this CLI intentionally reads a local operator-specified ZIP archive and never extracts entries to disk. + reader, err := zip.OpenReader(cleaned) + if err != nil { + return customerPackageArchiveFiles{}, err + } + defer func() { + _ = reader.Close() + }() + files := customerPackageArchiveFiles{} + for _, file := range reader.File { + switch file.Name { + case "manifest.json": + files.Manifest, err = readZIPFileLimited(file) + case "package.json": + var body []byte + body, err = readZIPFileLimited(file) + if err == nil { + err = json.Unmarshal(body, &files.Metadata) + } + case "verification.json": + var body []byte + body, err = readZIPFileLimited(file) + if err == nil { + err = json.Unmarshal(body, &files.Verification) + } + } + if err != nil { + return customerPackageArchiveFiles{}, err + } + } + if len(files.Manifest) == 0 || len(files.Metadata) == 0 || len(files.Verification) == 0 { + return customerPackageArchiveFiles{}, errors.New("customer package archive missing manifest.json, package.json, or verification.json") + } + return files, nil +} + +func readZIPFileLimited(file *zip.File) ([]byte, error) { + if file.UncompressedSize64 > uint64(maxCustomerPackageFileBytes) { + return nil, fmt.Errorf("customer package archive entry %s is too large", file.Name) + } + rc, err := file.Open() + if err != nil { + return nil, err + } + defer func() { + _ = rc.Close() + }() + body, err := io.ReadAll(io.LimitReader(rc, maxCustomerPackageFileBytes+1)) + if err != nil { + return nil, err + } + if int64(len(body)) > maxCustomerPackageFileBytes { + return nil, fmt.Errorf("customer package archive entry %s is too large", file.Name) + } + return body, nil +} + +func verifyCustomerPackageArchiveMetadata(archive customerPackageArchiveFiles, result customerPackageVerifyResult) error { + for name, document := range map[string]map[string]any{"package.json": archive.Metadata, "verification.json": archive.Verification} { + if got := stringMapField(document, "manifest_hash"); got != result.ManifestHash { + return fmt.Errorf("%s manifest_hash mismatch", name) + } + if got := stringMapField(document, "package_id"); got != "" && got != result.PackageID { + return fmt.Errorf("%s package_id mismatch", name) + } + if name == "package.json" { + if got := stringMapField(document, "id"); got != "" && got != result.PackageID { + return fmt.Errorf("%s id mismatch", name) + } + } + } + return nil +} + +func verifyCustomerPackageEvidenceCoverage(packageEvidenceIDs []string, bundleManifest map[string]any) error { + if len(packageEvidenceIDs) == 0 { + return nil + } + bundleIDs := stringSliceFromAny(bundleManifest["evidence_ids"]) + if len(bundleIDs) == 0 { + return nil + } + for _, id := range packageEvidenceIDs { + if !stringInSlice(bundleIDs, id) { + return fmt.Errorf("evidence bundle does not include package evidence id %s", id) + } + } + return nil +} + +func canonicalJSONBytesHash(body []byte) (string, error) { + var normalized any + if err := json.Unmarshal(body, &normalized); err != nil { + return "", errors.New("manifest is not valid JSON") + } + canonical, err := json.Marshal(normalized) + if err != nil { + return "", err + } + return hashBytes(canonical), nil +} + +func validSHA256Digest(value string) bool { + value = strings.TrimSpace(value) + if !strings.HasPrefix(value, "sha256:") || len(value) != len("sha256:")+64 { + return false + } + _, err := hex.DecodeString(strings.TrimPrefix(value, "sha256:")) + return err == nil +} + +func verifyExpectedValue(label, got, expected string) error { + expected = strings.TrimSpace(expected) + if expected == "" { + return nil + } + if strings.TrimSpace(got) != expected { + return fmt.Errorf("customer package %s mismatch: got %s want %s", label, got, expected) + } + return nil +} + +func rejectCustomerPackageSensitiveKeys(value any) error { + return rejectCustomerPackageSensitiveKeysAt(value, "") +} + +func rejectCustomerPackageSensitiveKeysAt(value any, path string) error { + switch typed := value.(type) { + case map[string]any: + for key, child := range typed { + lower := strings.ToLower(strings.TrimSpace(key)) + if prohibitedCustomerPackageManifestKey(lower) { + if path == "" { + return fmt.Errorf("customer package manifest contains prohibited field %s", key) + } + return fmt.Errorf("customer package manifest contains prohibited field %s.%s", path, key) + } + childPath := key + if path != "" { + childPath = path + "." + key + } + if err := rejectCustomerPackageSensitiveKeysAt(child, childPath); err != nil { + return err + } + } + case []any: + for _, child := range typed { + if err := rejectCustomerPackageSensitiveKeysAt(child, path); err != nil { + return err + } + } + } + return nil +} + +func prohibitedCustomerPackageManifestKey(key string) bool { + switch key { + case "payload", "payload_bytes", "payload_ref", "object_key", "private_key", "token", "secret", "api_key_hash", "session_token_hash", "internal_notes": + return true + default: + return false + } +} + +func stringMapField(values map[string]any, key string) string { + if values == nil { + return "" + } + value, _ := values[key].(string) + return strings.TrimSpace(value) +} + +func stringSliceFromAny(value any) []string { + raw, ok := value.([]any) + if !ok { + return nil + } + out := make([]string, 0, len(raw)) + for _, item := range raw { + text, ok := item.(string) + if ok && strings.TrimSpace(text) != "" { + out = append(out, strings.TrimSpace(text)) + } + } + return out +} + +func trimStringSlice(values []string) []string { + out := make([]string, 0, len(values)) + for _, value := range values { + value = strings.TrimSpace(value) + if value != "" { + out = append(out, value) + } + } + return out +} + +func stringInSlice(values []string, expected string) bool { + for _, value := range values { + if value == expected { + return true + } + } + return false +} + func cleanOperatorPath(path string) (string, error) { path = strings.TrimSpace(path) if path == "" { diff --git a/cmd/evydence/main_test.go b/cmd/evydence/main_test.go index 07d08f2..312933c 100644 --- a/cmd/evydence/main_test.go +++ b/cmd/evydence/main_test.go @@ -1,6 +1,7 @@ package main import ( + "archive/zip" "crypto/ed25519" "crypto/rand" "crypto/sha256" @@ -167,6 +168,71 @@ func TestVerifyEvidenceBundleChecksIncludedSignature(t *testing.T) { } } +func TestVerifyCustomerPackageManifestArchiveAndBundle(t *testing.T) { + manifest := testCustomerPackageManifest() + body, err := json.Marshal(manifest) + if err != nil { + t.Fatalf("marshal manifest: %v", err) + } + hash, err := canonicalJSONBytesHash(body) + if err != nil { + t.Fatalf("manifest hash: %v", err) + } + dir := t.TempDir() + manifestPath := dir + "/manifest.json" + if err := os.WriteFile(manifestPath, body, 0o600); err != nil { + t.Fatalf("write manifest: %v", err) + } + archivePath := writeTestCustomerPackageArchive(t, dir+"/package.zip", body, hash, "csp_1") + bundlePath := writeSignedEvidenceBundle(t, dir+"/evidence-bundle.json", []any{"ev_1"}, "sk_1") + if err := verifyCustomerPackage([]string{ + "--manifest", manifestPath, + "--archive", archivePath, + "--bundle", bundlePath, + "--hash", hash, + "--expected-tenant-id", "ten_1", + "--expected-product-id", "prod_1", + "--expected-release-id", "rel_1", + "--expected-package-id", "csp_1", + "--expected-signing-key-id", "sk_1", + }); err != nil { + t.Fatalf("verify customer package: %v", err) + } + + badArchivePath := writeTestCustomerPackageArchive(t, dir+"/package-bad.zip", body, "sha256:"+strings.Repeat("0", 64), "csp_1") + if err := verifyCustomerPackage([]string{"--archive", badArchivePath}); err == nil || !strings.Contains(err.Error(), "manifest_hash mismatch") { + t.Fatalf("bad archive err=%v", err) + } +} + +func TestVerifyCustomerPackageRejectsSensitiveFieldsAndMismatches(t *testing.T) { + manifest := testCustomerPackageManifest() + manifest["payload_ref"] = "objects/ten_1/raw-secret.json" + body, err := json.Marshal(manifest) + if err != nil { + t.Fatalf("marshal manifest: %v", err) + } + path := t.TempDir() + "/manifest.json" + if err := os.WriteFile(path, body, 0o600); err != nil { + t.Fatalf("write manifest: %v", err) + } + if err := verifyCustomerPackage([]string{"--manifest", path}); err == nil || !strings.Contains(err.Error(), "prohibited field payload_ref") { + t.Fatalf("sensitive field err=%v", err) + } + + delete(manifest, "payload_ref") + body, err = json.Marshal(manifest) + if err != nil { + t.Fatalf("marshal safe manifest: %v", err) + } + if err := os.WriteFile(path, body, 0o600); err != nil { + t.Fatalf("write safe manifest: %v", err) + } + if err := verifyCustomerPackage([]string{"--manifest", path, "--expected-tenant-id", "ten_other"}); err == nil || !strings.Contains(err.Error(), "tenant id mismatch") { + t.Fatalf("tenant mismatch err=%v", err) + } +} + func TestVerifyAuditChainDetectsHashTampering(t *testing.T) { first := testAuditEntry(t, "", 1) second := testAuditEntry(t, first["entry_hash"].(string), 2) @@ -417,6 +483,17 @@ func TestRunCoversHashBundleAndReleaseCommands(t *testing.T) { if err := run([]string{"verify-evidence-bundle", bundlePath}); err != nil { t.Fatalf("run verify evidence bundle: %v", err) } + customerManifestBody, err := json.Marshal(testCustomerPackageManifest()) + if err != nil { + t.Fatalf("marshal customer package manifest: %v", err) + } + customerManifest := dir + "/customer-package.json" + if err := os.WriteFile(customerManifest, customerManifestBody, 0o600); err != nil { + t.Fatalf("write customer package manifest: %v", err) + } + if err := run([]string{"package", "verify", "--manifest", customerManifest}); err != nil { + t.Fatalf("run package verify: %v", err) + } chainPath := dir + "/chain.json" entry := testAuditEntry(t, "", 1) chainBody, err := json.Marshal([]map[string]any{entry}) @@ -495,3 +572,105 @@ func mustParseTime(t *testing.T, value string) time.Time { } return parsed } + +func testCustomerPackageManifest() map[string]any { + return map[string]any{ + "schema_version": "customer-security-package.v2.0.0", + "package_version": "customer-security-package.v2.0.0", + "package_id": "csp_1", + "id": "csp_1", + "title": "Customer package", + "generated_at": "2026-05-28T12:00:00Z", + "tenant": map[string]any{"id": "ten_1", "name": "Tenant"}, + "product": map[string]any{"id": "prod_1", "name": "Payments API"}, + "product_id": "prod_1", + "release": map[string]any{"id": "rel_1", "product_id": "prod_1", "version": "1.0.0", "state": "approved", "created_at": "2026-05-28T12:00:00Z"}, + "release_id": "rel_1", + "redaction_profile_id": "rp_1", + "redaction_profile": map[string]any{"id": "rp_1", "name": "customer_safe", "allowed_types": []any{"artifact", "release_bundle"}, "excluded_fields": []any{"payload_ref"}, "schema_version": "redaction-profile.v1.0.0"}, + "evidence_ids": []any{"ev_1"}, + "artifact_digests": []any{map[string]any{"id": "art_1", "name": "artifact.tar.gz", "media_type": "application/gzip", "size": 123, "digest": "sha256:ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", "created_at": "2026-05-28T12:00:00Z"}}, + "readiness_summary": map[string]any{"result": "passed", "checks": []any{}, "gaps": []any{}, "limitations": []any{"Readiness is derived from package-scoped evidence only."}}, + "verification_material": map[string]any{"hash_algorithm": "sha256", "canonicalization": "canonicalization-profile.v1.0.0", "manifest_hash_field": "manifest_hash", "release_bundles": []any{map[string]any{"id": "rb_1", "manifest_hash": "sha256:" + strings.Repeat("b", 64), "signature_refs": []any{"sig_1"}}}}, + "limitations": []any{"Package contents are scoped by product, release, redaction profile, and package expiry."}, + "non_claims": []any{"This package supports technical evidence review and compliance readiness only."}, + } +} + +func writeTestCustomerPackageArchive(t *testing.T, path string, manifest []byte, manifestHash, packageID string) string { + t.Helper() + file, err := os.Create(path) + if err != nil { + t.Fatalf("create archive: %v", err) + } + zw := zip.NewWriter(file) + for _, entry := range []struct { + name string + body []byte + }{ + {name: "manifest.json", body: manifest}, + {name: "package.json", body: mustMarshalJSON(t, map[string]any{"id": packageID, "manifest_hash": manifestHash})}, + {name: "verification.json", body: mustMarshalJSON(t, map[string]any{"package_id": packageID, "manifest_hash": manifestHash, "manifest_file": "manifest.json"})}, + } { + writer, err := zw.Create(entry.name) + if err != nil { + t.Fatalf("create archive entry: %v", err) + } + if _, err := writer.Write(entry.body); err != nil { + t.Fatalf("write archive entry: %v", err) + } + } + if err := zw.Close(); err != nil { + t.Fatalf("close archive writer: %v", err) + } + if err := file.Close(); err != nil { + t.Fatalf("close archive: %v", err) + } + return path +} + +func writeSignedEvidenceBundle(t *testing.T, path string, evidenceIDs []any, keyID string) string { + t.Helper() + manifest := map[string]any{"bundle_version": "evidence-bundle.v1.0.0", "evidence_ids": evidenceIDs} + canonical, err := json.Marshal(manifest) + if err != nil { + t.Fatalf("marshal bundle manifest: %v", err) + } + sum := sha256.Sum256(canonical) + manifestHash := "sha256:" + hex.EncodeToString(sum[:]) + pub, priv, err := ed25519.GenerateKey(rand.Reader) + if err != nil { + t.Fatalf("generate bundle key: %v", err) + } + body := mustMarshalJSON(t, map[string]any{ + "manifest": manifest, + "manifest_hash": manifestHash, + "signature_refs": []any{"sig_1"}, + "signatures": []any{map[string]any{ + "id": "sig_1", + "key_id": keyID, + "algorithm": "Ed25519", + "value": base64.RawStdEncoding.EncodeToString(ed25519.Sign(priv, []byte(manifestHash))), + "created_at": "2026-05-28T12:00:00Z", + }}, + "signing_keys": []any{map[string]any{ + "id": keyID, + "algorithm": "Ed25519", + "status": "active", + "public_key": base64.RawStdEncoding.EncodeToString(pub), + }}, + }) + if err := os.WriteFile(path, body, 0o600); err != nil { + t.Fatalf("write evidence bundle: %v", err) + } + return path +} + +func mustMarshalJSON(t *testing.T, value any) []byte { + t.Helper() + body, err := json.Marshal(value) + if err != nil { + t.Fatalf("marshal JSON: %v", err) + } + return body +} diff --git a/docs/how-to/view-packages.md b/docs/how-to/view-packages.md index 096b866..25aab0e 100644 --- a/docs/how-to/view-packages.md +++ b/docs/how-to/view-packages.md @@ -11,6 +11,14 @@ running the API, load `examples/end-to-end-release-evidence/sample-customer-package-manifest.json` or press **Load bundled demo** in the viewer. +Before sharing or reviewing a package, use the offline verifier for hash, +structure, archive metadata, and optional evidence-bundle signature checks: + +```sh +go run ./cmd/evydence package verify \ + --manifest examples/end-to-end-release-evidence/sample-customer-package-manifest.json +``` + ![Static package viewer preview](../assets/package-viewer-preview.svg) Use it for: diff --git a/docs/reference/customer-package-manifest.md b/docs/reference/customer-package-manifest.md index 9951051..d343f32 100644 --- a/docs/reference/customer-package-manifest.md +++ b/docs/reference/customer-package-manifest.md @@ -63,3 +63,36 @@ defaults instead of explicit operator scope. The local package viewer at `site/package-viewer/index.html` loads v2 manifests directly from disk. A non-sensitive sample is available at `examples/end-to-end-release-evidence/sample-customer-package-manifest.json`. + +## Offline Verification + +The CLI verifies a package manifest without contacting the API: + +```sh +go run ./cmd/evydence package verify \ + --manifest examples/end-to-end-release-evidence/sample-customer-package-manifest.json \ + --expected-product-id prod_example \ + --expected-release-id rel_example +``` + +For exported ZIP packages, verify archive metadata and the manifest hash: + +```sh +go run ./cmd/evydence package verify \ + --archive evydence-customer-package-csp_123.zip \ + --hash sha256: +``` + +When an evidence bundle is supplied, the verifier also checks the bundle +manifest hash, included signatures, and package evidence-id coverage: + +```sh +go run ./cmd/evydence package verify \ + --manifest package-manifest.json \ + --bundle evidence-bundle.json \ + --expected-signing-key-id sk_123 +``` + +Verification proves the local files match their recorded hashes and available +signatures. It does not prove legal compliance, certification, complete SBOM +coverage, vulnerability scanner authority, or release security status. diff --git a/examples/end-to-end-release-evidence/README.md b/examples/end-to-end-release-evidence/README.md index 9673645..1397350 100644 --- a/examples/end-to-end-release-evidence/README.md +++ b/examples/end-to-end-release-evidence/README.md @@ -93,8 +93,15 @@ question to concrete Evydence records: To visually inspect the customer-safe output, open `site/package-viewer/index.html` and load `customer-package.json` from the demo -output directory. To verify the release bundle through the API, read the bundle -id from `release-bundle.json` and call: +output directory. To verify the package manifest offline, run: + +```sh +go run ./cmd/evydence package verify \ + --manifest tmp/end-to-end-release-evidence/customer-package.json +``` + +To verify the release bundle through the API, read the bundle id from +`release-bundle.json` and call: ```sh bundle_id="$(jq -r '.data.id' tmp/end-to-end-release-evidence/release-bundle.json)" From 31df71925db231925766005836ed84d5751ca3db Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:24:27 +0300 Subject: [PATCH 185/287] feat(viewer): improve package review workflow --- .productization_next_steps.md | 2 +- Makefile | 3 + docs/how-to/view-packages.md | 8 +- site/package-viewer/index.html | 725 ++++++++++++++++++++++++++++----- 4 files changed, 628 insertions(+), 110 deletions(-) diff --git a/.productization_next_steps.md b/.productization_next_steps.md index 2a55581..11e6262 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -569,7 +569,7 @@ Acceptance criteria: * Exits non-zero on failure. * Example package verification is documented. -#### [ ] EVY-033 — Improve package viewer for reviewer workflow +#### [x] EVY-033 — Improve package viewer for reviewer workflow Priority: P1 diff --git a/Makefile b/Makefile index 79c3d39..7dc84e7 100644 --- a/Makefile +++ b/Makefile @@ -321,6 +321,9 @@ package-viewer-check: ## Validate local package viewer and walkthrough @grep -F 'Load bundled demo' site/package-viewer/index.html >/dev/null @grep -F 'textContent' site/package-viewer/index.html >/dev/null @! grep -F 'innerHTML' site/package-viewer/index.html >/dev/null + @grep -F 'Release Summary' site/package-viewer/index.html >/dev/null + @grep -F 'Vulnerability / VEX Decisions' site/package-viewer/index.html >/dev/null + @grep -F 'Verification Status' site/package-viewer/index.html >/dev/null @grep -F 'examples/end-to-end-release-evidence/sample-customer-package-manifest.json' docs/how-to/view-packages.md >/dev/null restore-rehearsal-check: ## Run repository-owned backup/restore rehearsal tests diff --git a/docs/how-to/view-packages.md b/docs/how-to/view-packages.md index 25aab0e..4041587 100644 --- a/docs/how-to/view-packages.md +++ b/docs/how-to/view-packages.md @@ -1,8 +1,8 @@ # View Release And Customer Packages Locally -Evydence is API-first, but the repository includes a minimal local package -viewer at `site/package-viewer/index.html` for customer-package and -release-evidence review. +Evydence is API-first, but the repository includes a local package viewer at +`site/package-viewer/index.html` for customer-package and release-evidence +review. Open the file in a browser, then select a JSON package, readiness report, evidence bundle, or package manifest from disk. The viewer runs entirely in the @@ -25,6 +25,8 @@ Use it for: - checking a release-readiness report before sending a customer package; - inspecting package manifests and limitations; +- reviewing artifact, SBOM, vulnerability, VEX, approval, exception, readiness, + contents, and verification sections; - reading evidence-bundle metadata during an offline review; - confirming that a shared package does not contain raw evidence payload bytes or secrets. diff --git a/site/package-viewer/index.html b/site/package-viewer/index.html index e5a05bd..ff3d496 100644 --- a/site/package-viewer/index.html +++ b/site/package-viewer/index.html @@ -7,128 +7,298 @@
-

Evydence Package Viewer

-

- Open a customer package, release-readiness report, evidence bundle, or - package manifest JSON file locally. This viewer never uploads data. -

- -
- - - No file loaded. -
- -
-

Boundary

-

- Viewer output supports technical evidence review only. It is not legal - compliance proof, certification, complete SBOM proof, an authoritative - vulnerability result, or a secure-release guarantee. -

-
- -
-
{}
+
+
+

Evydence Package Viewer

+

Local review surface for release evidence packages.

+
+
+ + + No file loaded +
+
+ +
+ +
+
+
+
+
+
+
+
+
+
+
+
From 476748fc6ec3ced6744eee51f20a466b3b221e6a Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:26:12 +0300 Subject: [PATCH 186/287] docs(examples): add sample customer package --- .productization_next_steps.md | 2 +- Makefile | 2 ++ README.md | 8 +++++--- docs/how-to/view-packages.md | 4 ++++ docs/reference/customer-package-manifest.md | 4 +++- .../end-to-end-release-evidence/README.md | 12 +++++++++++ .../sample-customer-package-manifest.json | 9 +++++++++ .../sample-customer-package.zip | Bin 0 -> 3032 bytes site/package-viewer/index.html | 19 +++++++++++++++++- 9 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 examples/end-to-end-release-evidence/sample-customer-package.zip diff --git a/.productization_next_steps.md b/.productization_next_steps.md index 11e6262..1a798d2 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -599,7 +599,7 @@ Acceptance criteria: * Viewer is usable from bundled demo. * No server-side authorization assumptions are introduced. -#### [ ] EVY-034 — Add downloadable sample customer package +#### [x] EVY-034 — Add downloadable sample customer package Priority: P1 diff --git a/Makefile b/Makefile index 7dc84e7..c132a05 100644 --- a/Makefile +++ b/Makefile @@ -300,8 +300,10 @@ demo-check: ## Validate checked end-to-end evidence demo fixtures @test -f examples/end-to-end-release-evidence/release-evidence-manifest.json @test -f examples/end-to-end-release-evidence/sample-readiness-report.json @test -f examples/end-to-end-release-evidence/sample-customer-package-manifest.json + @test -f examples/end-to-end-release-evidence/sample-customer-package.zip @test -f examples/end-to-end-release-evidence/sample-audit-chain-verification.json @python3 -c 'import json, pathlib; [json.loads(path.read_text()) for path in pathlib.Path("examples/end-to-end-release-evidence").glob("*.json")]' + @$(GO) run ./cmd/evydence package verify --archive examples/end-to-end-release-evidence/sample-customer-package.zip --expected-package-id csp_example --expected-product-id prod_example --expected-release-id rel_example >/dev/null @grep -F '/v1/reports/release-readiness' examples/end-to-end-release-evidence/run-local-demo.sh >/dev/null @grep -F '/v1/audit-chain/verify' examples/end-to-end-release-evidence/run-local-demo.sh >/dev/null @grep -F '/v1/customer-packages' examples/end-to-end-release-evidence/run-local-demo.sh >/dev/null diff --git a/README.md b/README.md index 90dfa0f..0a02b45 100644 --- a/README.md +++ b/README.md @@ -85,9 +85,11 @@ For durable local evaluation, run the production-like Compose rehearsal in For the release-evidence path to inspect first, use the [end-to-end release evidence example](examples/end-to-end-release-evidence/README.md). For concrete JSON outputs to inspect without running a full stack, open the -sample readiness report, customer-package manifest, and audit-chain -verification fixtures in that example or load the bundled package in the -[local package viewer](docs/how-to/view-packages.md). +sample readiness report, +[customer-package manifest](examples/end-to-end-release-evidence/sample-customer-package-manifest.json), +[downloadable customer package](examples/end-to-end-release-evidence/sample-customer-package.zip), +and audit-chain verification fixtures in that example or load the bundled +package in the [local package viewer](docs/how-to/view-packages.md). Release-candidate artifacts and their verification commands are indexed in [Release evidence index](docs/reference/release-evidence-index.md). Start with diff --git a/docs/how-to/view-packages.md b/docs/how-to/view-packages.md index 4041587..7bda9de 100644 --- a/docs/how-to/view-packages.md +++ b/docs/how-to/view-packages.md @@ -19,6 +19,10 @@ go run ./cmd/evydence package verify \ --manifest examples/end-to-end-release-evidence/sample-customer-package-manifest.json ``` +The same fixture is available as +`examples/end-to-end-release-evidence/sample-customer-package.zip` for archive +verification workflows. + ![Static package viewer preview](../assets/package-viewer-preview.svg) Use it for: diff --git a/docs/reference/customer-package-manifest.md b/docs/reference/customer-package-manifest.md index d343f32..07a006b 100644 --- a/docs/reference/customer-package-manifest.md +++ b/docs/reference/customer-package-manifest.md @@ -62,7 +62,9 @@ defaults instead of explicit operator scope. The local package viewer at `site/package-viewer/index.html` loads v2 manifests directly from disk. A non-sensitive sample is available at -`examples/end-to-end-release-evidence/sample-customer-package-manifest.json`. +`examples/end-to-end-release-evidence/sample-customer-package-manifest.json`; +the matching archive fixture is +`examples/end-to-end-release-evidence/sample-customer-package.zip`. ## Offline Verification diff --git a/examples/end-to-end-release-evidence/README.md b/examples/end-to-end-release-evidence/README.md index 1397350..db05381 100644 --- a/examples/end-to-end-release-evidence/README.md +++ b/examples/end-to-end-release-evidence/README.md @@ -36,6 +36,8 @@ you use source-checkout commands for local development. limitations. - `sample-customer-package-manifest.json`: representative customer package manifest without raw tenant payload bytes. +- `sample-customer-package.zip`: downloadable fixture with `manifest.json`, + `package.json`, `verification.json`, and `README.txt`. - `sample-audit-chain-verification.json`: representative audit-chain verification result. @@ -100,6 +102,16 @@ go run ./cmd/evydence package verify \ --manifest tmp/end-to-end-release-evidence/customer-package.json ``` +To inspect the checked sample without running the API, open +`sample-customer-package-manifest.json` in the viewer or verify the downloadable +fixture: + +```sh +go run ./cmd/evydence package verify \ + --archive examples/end-to-end-release-evidence/sample-customer-package.zip \ + --expected-package-id csp_example +``` + To verify the release bundle through the API, read the bundle id from `release-bundle.json` and call: diff --git a/examples/end-to-end-release-evidence/sample-customer-package-manifest.json b/examples/end-to-end-release-evidence/sample-customer-package-manifest.json index 54c4acf..fe1c1ca 100644 --- a/examples/end-to-end-release-evidence/sample-customer-package-manifest.json +++ b/examples/end-to-end-release-evidence/sample-customer-package-manifest.json @@ -94,6 +94,15 @@ "high": 1 }, "finding_count": 1, + "findings": [ + { + "id": "finding_example", + "vulnerability": "CVE-2026-0002", + "component": "pkg:apk/openssl@3.1.0", + "severity": "high", + "state": "fixed_by_decision" + } + ], "created_at": "2026-05-27T12:00:00Z" } ], diff --git a/examples/end-to-end-release-evidence/sample-customer-package.zip b/examples/end-to-end-release-evidence/sample-customer-package.zip new file mode 100644 index 0000000000000000000000000000000000000000..5b337bb16c3e1bf780fd59b1916cb338d7a47cfa GIT binary patch literal 3032 zcmZ`*XD}S<8s0^$#p)$WI666cZ;@yl(N|fbL|rw=!K#~(ST%?m(W69JHj8M{S&QhM zSR^D$v`xd&uY2x~b5G{p@0)L)nRn)y`Q~}%eV^CVfSiH_002;3K0d&+NefIeB>*tQ z3IISZD?U!Xo^FVMKuNCvKVPi1fge$sp<}~}L8Cu;xAaaQLOHh#@1MS3NoW4 zLB+HRAu$o-)Qb-7gi_HX#zP=Q9D#!__5(_e`#TZL$4sEE@TjA#Y_1Sda_zBsrF+F6 z6WNfqJyKt^^LSm_R?7Xydz8P|`rBIG!U1!&+X`Uy35-|~Gl^r??vqIdY7-jokf>)J z5F$8wzdTetV{ZKhS`?RBFJ5rx*708Hov=}xYt0N5ha+;iYI9Xs1!~J$ z6o!mNr%*R)h6S&B9IUR&JM3J9H=U(f*%3zwx!H@*R$<>aX#L;X+z`21`a1T$RFDzX4w;)-@l*lm1KpYxkPd&W5TnezB07-?Fojr-Ac%~#hSQ8SgCEoS!*SU zak?#s@7U4VL~;ndrE`Aa&1_#sGK7 zmMq^p<%}pZ>6He`yHm27IVBrWo)*E;OF)1bb+8 zq(0|Ro*31_VR_5(wcH^t=!bjuQfvlL_A1Lk(XbA6hw9M}lWU=al4fDZhv2(G?aj^3 z><=33+S>~p?Cm>?IJyY?UNg8LJK;b?t@dDK3pbSCk1>L zdE&?gPvD%48^Qpe(^3-<=qDAN(>P?0j`tYh>6*!{`h3R|p!NzZ5>oe*s%w}ckY7Xm z%ye8cVf`gDI2%FIek5@9CJ}a&)ZU1xSVUviUaoN7wOid(SM{PPV2|lJ*V`57-OiW` zy%j3+ycfyu%Sm=`xhH5_x^Kzj;@e@YCwt8iN@W_tcW7Hag3tDN3CEyyVX>$y4umYV)cX4CbT-!gNU)zVT$|8$3H%23ANFmodc58UWh8t zO|@0A$LjYpK311C>JZT_9&M%3W=j_OOFF4G zKN0)K9HSaduUr6IEq1$svhm!@|Bm@@Hi>2K^UoZ|lBOlVd-OQd9wpn-QN z5mqZ|ya&AVSawh*b7*Ubz>`i51Hrw!o4Qu;A!ro&q?-N@}jn*K21VJ zZGo}kVqOi z4!s|JGHyn6+%SJJ*{7){pqH3+UaWr_Z@iN<$xIz0q9-vh?t4lJSo8X3zviHYJ6aPP`gcNK$7rhJ;2fs9F=$DEH1F{)CH zKf9OrD^LxYQaG2^Xt%YIGx*3o7uB88Yv%#i=FeI-lN-$?!d?qoE4gDYxbr&?Yf_^) zvEO(ny0(&VaUzW7h9?DuCT$XcL z*hK%OM#p3T0OO@jK?r|OH%}L*Kup!Oo%@Cx2HJuhLuc$4VYg z7Fg>r#+`xZCoS2;XV&h>H#8MRx!GpGYwzNyxRYgzBKa1;*&p@Zw2gaHEvbn~GJ{f? z-kA=|DIFJS_SU{sdj#{mz{`h5-Q)o(a!wSVr3Ef=KI#WIC-JaO_oAquU_O zs^8Svt~f*%56n{CIjC-~*DHN=a(v8>i|6N|P)r&f@^jB$<4DtzGU-Y^$-~=4&a=H^ z6rQ;4l}KZlc9o#?{^Lg4D7alAqgi1Vmb?cKL78;pG+g}0FIFE4x6kfBy09?EZY2!t zVBC_7>~~w-h+m*nzO8tu4`#~~XZWU4(OWmO(vw)>+tgXdTmtQDeFB_;DV~~iHB8#% zpInDXJQVM9SXdoc!olMv~qo&V8+B*#%z2X!)U?zN5JjuHD*?D-4 z#sASP?_U4)gR{^-Y5wW@7l;99?$T|eOXsOC(M(rU$4FN)FeFenMaCa5O-m8pPDWpI z_LODMtW+PAdYg;!iWilhVuasdjv%WWT|l@p>b`^)`9R1$S<&is1XM`dx+ ziYgeXMgJ8&mw@?r=!4z4u{)evCl1vcCJyQc984LOU z-)k>5`0JEj3i8XA`z!U=$?_i}08k2id$}n8_ni5a`D?HJ&0GQfkIws*{;O$!)91kd XZK0{bmCKI+02G&Z=MrcC?J(e9LpWL2 literal 0 HcmV?d00001 diff --git a/site/package-viewer/index.html b/site/package-viewer/index.html index ff3d496..801d458 100644 --- a/site/package-viewer/index.html +++ b/site/package-viewer/index.html @@ -347,7 +347,14 @@

Evydence Package Viewer

{ id: "sbom_example", evidence_id: "ev_sbom", format: "cyclonedx", spec_version: "1.6", component_count: 42 } ], vulnerability_scans: [ - { id: "scan_example", scanner: "example-scanner", target_ref: "pkg:oci/payments-api", finding_count: 1, summary: { critical: 0, high: 1 } } + { + id: "scan_example", + scanner: "example-scanner", + target_ref: "pkg:oci/payments-api", + finding_count: 1, + summary: { critical: 0, high: 1 }, + findings: [{ id: "finding_example", vulnerability: "CVE-2026-0002", component: "pkg:apk/openssl@3.1.0", severity: "high", state: "fixed_by_decision" }] + } ], vex_documents: [ { id: "vex_example", format: "openvex", author: "security@example.test", statement_count: 1, status_summary: { fixed: 1 } } @@ -557,6 +564,7 @@

Evydence Package Viewer

const decisions = safeArray(data.vulnerability_decisions); const vexDocs = safeArray(data.vex_documents); const scans = safeArray(data.vulnerability_scans); + const findings = safeArray(data.vulnerability_findings).concat(scans.flatMap((scan) => safeArray(scan.findings))); sectionHead(nodes.risk, "Vulnerability / VEX Decisions", String(decisions.length) + " active decisions"); const split = document.createElement("div"); split.className = "split"; @@ -578,6 +586,15 @@

Evydence Package Viewer

], vexDocs, "No VEX document metadata is present."); split.append(scanNode, vexNode); nodes.risk.append(split); + appendText(nodes.risk, "h3", "", "Vulnerability findings"); + table(nodes.risk, [ + { label: "Finding", value: (row) => row.id || row.vulnerability }, + { label: "Vulnerability", value: "vulnerability" }, + { label: "Component", value: "component" }, + { label: "Severity", value: "severity", badge: true }, + { label: "State", value: "state", badge: true } + ], findings, "No customer-visible finding summaries are present."); + appendText(nodes.risk, "h3", "", "Active decisions"); table(nodes.risk, [ { label: "Vulnerability", value: "vulnerability" }, { label: "Component", value: "component" }, From a9ae7c66707095498bc35bbaf1c1b0fcf987d724 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:27:38 +0300 Subject: [PATCH 187/287] feat(reports): add readiness question sections --- .productization_next_steps.md | 2 +- docs/api.md | 5 +- docs/tutorials/getting-started.md | 6 +- .../sample-readiness-report.json | 115 +++++++++- internal/adapters/httpapi/openapi.go | 37 +++- internal/adapters/httpapi/router_test.go | 2 +- internal/app/ledger_test.go | 28 +++ internal/app/vex.go | 200 +++++++++++++++++- internal/domain/domain.go | 57 +++-- openapi.yaml | 2 +- 10 files changed, 421 insertions(+), 33 deletions(-) diff --git a/.productization_next_steps.md b/.productization_next_steps.md index 1a798d2..f6f657e 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -624,7 +624,7 @@ Goal: Backlog: -#### [ ] EVY-040 — Redesign release-readiness report around buyer questions +#### [x] EVY-040 — Redesign release-readiness report around buyer questions Priority: P1 diff --git a/docs/api.md b/docs/api.md index ee7ecff..17bea2e 100644 --- a/docs/api.md +++ b/docs/api.md @@ -250,7 +250,10 @@ Representative response shape: } ``` -Readiness is deterministic and evidence-scoped. It reports checks, blockers, gaps, assumptions, and limitations; it is not a legal compliance or release-security conclusion. +Readiness is deterministic and evidence-scoped. It reports checks, reviewer +question sections, missing evidence, failed policy checks, blockers, gaps, +assumptions, non-claims, and limitations; it is not a legal compliance or +release-security conclusion. ## Authentication And Scopes diff --git a/docs/tutorials/getting-started.md b/docs/tutorials/getting-started.md index a310d41..49cceb0 100644 --- a/docs/tutorials/getting-started.md +++ b/docs/tutorials/getting-started.md @@ -189,7 +189,11 @@ curl -sS "$EVYDENCE_URL/v1/reports/release-readiness?release_id=$RELEASE_ID" \ | jq . ``` -Expected status is `200`. In this minimal flow, `data.result` is expected to be `failed` because the release is missing some readiness inputs and has an unhandled open critical finding. The report should include checks, gaps, assumptions, limitations, and blocking findings. +Expected status is `200`. In this minimal flow, `data.result` is expected to be +`failed` because the release is missing some readiness inputs and has an +unhandled open critical finding. The report should include checks, reviewer +question sections, missing evidence, failed policy checks, gaps, assumptions, +limitations, non-claims, and blocking findings. Record a decision for the tutorial finding: diff --git a/examples/end-to-end-release-evidence/sample-readiness-report.json b/examples/end-to-end-release-evidence/sample-readiness-report.json index b0b62c8..4c49fb5 100644 --- a/examples/end-to-end-release-evidence/sample-readiness-report.json +++ b/examples/end-to-end-release-evidence/sample-readiness-report.json @@ -1,32 +1,131 @@ { "data": { + "report_type": "release_readiness", + "template_version": "release-readiness.v1.0.0", "release_id": "rel_example", "result": "failed", + "summary": { + "headline": "Recorded release evidence has readiness blockers or missing inputs.", + "result": "failed", + "human_summary": "The report found 1 failed policy check, 1 missing evidence input, and 1 blocking finding in the recorded release evidence.", + "policy_set": "policy-set.v1.0.0" + }, "checks": [ { - "name": "sbom_present", + "name": "release_requires_sbom", "result": "passed", - "detail": "At least one SBOM is linked to the release." + "severity": "high", + "explanation": "sbom evidence exists" }, { - "name": "critical_findings_handled", + "name": "critical_exploitable_blocks_release", "result": "failed", - "detail": "One critical finding remains open without a valid decision or approved unexpired exception." + "severity": "critical", + "missing": [ + "vulnerability_decision" + ], + "explanation": "open critical finding requires remediation, a valid VEX decision, or an approved unexpired exception" + } + ], + "sections": [ + { + "id": "release_evidence", + "title": "Release Evidence", + "status": "passed", + "summary": "Recorded evidence satisfies this section.", + "questions": [ + { + "id": "sbom", + "question": "Is there an SBOM for this release?", + "answer": "SBOM evidence is recorded for this release.", + "status": "passed", + "checks": [ + "release_requires_sbom" + ] + } + ] + }, + { + "id": "risk_decisions", + "title": "Vulnerability Decisions", + "status": "missing", + "summary": "One or more reviewer questions is missing evidence.", + "questions": [ + { + "id": "critical_findings_triaged", + "question": "Are open critical findings triaged?", + "answer": "One or more open critical findings require a valid decision, remediation, or approved unexpired exception.", + "status": "missing_evidence", + "checks": [ + "critical_exploitable_blocks_release" + ], + "missing_evidence": [ + "vulnerability_decision" + ], + "failed_policies": [ + "critical_exploitable_blocks_release" + ] + } + ] + }, + { + "id": "gaps_and_limitations", + "title": "Gaps And Limitations", + "status": "failed", + "summary": "One or more reviewer questions failed a policy check.", + "questions": [ + { + "id": "remaining_gaps", + "question": "What gaps remain?", + "answer": "The report lists missing evidence and failed policy checks that should be reviewed.", + "status": "failed_policy", + "missing_evidence": [ + "vulnerability_decision" + ], + "failed_policies": [ + "critical_exploitable_blocks_release" + ] + } + ] } ], "blocking_findings": [ { - "id": "finding_example", + "finding_id": "finding_example", + "scan_id": "scan_example", + "release_id": "rel_example", "vulnerability": "CVE-2026-0099", + "component": "pkg:apk/openssl@3.1.0", "severity": "critical", "state": "open" } ], + "gaps": [ + "vulnerability_decision" + ], + "missing_evidence": [ + "vulnerability_decision" + ], + "failed_policies": [ + "critical_exploitable_blocks_release" + ], + "known_limitations": [ + "Readiness is based only on evidence, decisions, exceptions, bundles, and build records stored in this Evydence instance.", + "SBOM presence does not prove component inventory completeness.", + "Scanner output is submitted evidence and is not treated as authoritative vulnerability truth." + ], + "non_claims": [ + "This report supports technical evidence review and compliance readiness only.", + "It is not legal compliance proof, certification, complete SBOM proof, an authoritative vulnerability result, regulator acceptance, or a secure-release guarantee." + ], "assumptions": [ - "Scanner output is treated as submitted evidence, not authoritative vulnerability truth." + "This report supports compliance readiness and technical evidence review; it is not a legal compliance conclusion." ], "limitations": [ - "Example report; run against real release evidence before relying on it." - ] + "Readiness is based only on evidence, decisions, exceptions, bundles, and build records stored in this Evydence instance.", + "SBOM presence does not prove component inventory completeness.", + "Scanner output is submitted evidence and is not treated as authoritative vulnerability truth." + ], + "generated_at": "2026-05-27T12:00:00Z" } } diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index f839a33..928d36b 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -1238,11 +1238,38 @@ func registerCriticalSchemas(registry *specs.Registry) { "product_id": map[string]any{"type": "string"}, "release_id": map[string]any{"type": "string"}, "result": map[string]any{"type": "string"}, - "checks": map[string]any{"type": "array", "items": map[string]any{"type": "object"}}, - "gaps": map[string]any{"type": "array", "items": map[string]any{"type": "object"}}, - "assumptions": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, - "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, - "generated_at": map[string]any{"type": "string", "format": "date-time"}, + "summary": map[string]any{"type": "object", "additionalProperties": false, "properties": map[string]any{ + "headline": map[string]any{"type": "string"}, + "result": map[string]any{"type": "string"}, + "human_summary": map[string]any{"type": "string"}, + "policy_set": map[string]any{"type": "string"}, + }}, + "checks": map[string]any{"type": "array", "items": map[string]any{"type": "object"}}, + "sections": map[string]any{"type": "array", "items": map[string]any{"type": "object", "additionalProperties": false, "properties": map[string]any{ + "id": map[string]any{"type": "string"}, + "title": map[string]any{"type": "string"}, + "status": map[string]any{"type": "string"}, + "summary": map[string]any{"type": "string"}, + "questions": map[string]any{"type": "array", "items": map[string]any{"type": "object", "additionalProperties": false, "properties": map[string]any{ + "id": map[string]any{"type": "string"}, + "question": map[string]any{"type": "string"}, + "answer": map[string]any{"type": "string"}, + "status": map[string]any{"type": "string"}, + "evidence": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "checks": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "missing_evidence": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "failed_policies": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "known_limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + }}}, + }}}, + "gaps": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "missing_evidence": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "failed_policies": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "known_limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "non_claims": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "assumptions": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "generated_at": map[string]any{"type": "string", "format": "date-time"}, }, "report_type", "template_version", "result", "assumptions", "limitations", "generated_at")) registry.RegisterSchema("ReadinessReportEnvelope", dataEnvelopeSchema("#/components/schemas/ReadinessReport")) registry.RegisterSchema("MissingEvidenceReport", objectSchema(map[string]any{ diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 69b77ff..116c95a 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -642,7 +642,7 @@ func TestReleaseRiskDecisionHTTPFlow(t *testing.T) { addHTTPBuildProvenance(t, server, secret, productID, releaseID, artifactID, "sha256:ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb") report := getJSON(t, server, secret, "/v1/reports/release-readiness?release_id="+releaseID, http.StatusOK) - if !strings.Contains(report, `"result":"failed"`) || !strings.Contains(report, `"blocking_findings"`) { + if !strings.Contains(report, `"result":"failed"`) || !strings.Contains(report, `"blocking_findings"`) || !strings.Contains(report, `"sections"`) || !strings.Contains(report, `"missing_evidence"`) { t.Fatalf("expected failed readiness report with blocking findings: %s", report) } postJSON(t, server, secret, "/v1/vulnerability-findings/"+findingID+"/decisions", "risk-decision-bad", map[string]any{"status": "not_affected", "justification": "vulnerable code is not present", "customer_visible": true}, http.StatusBadRequest) diff --git a/internal/app/ledger_test.go b/internal/app/ledger_test.go index a9b0fbb..fb28c2b 100644 --- a/internal/app/ledger_test.go +++ b/internal/app/ledger_test.go @@ -659,6 +659,17 @@ func TestReleaseReadinessRequiresHandledCriticalFinding(t *testing.T) { if report.Result != "failed" || len(report.BlockingFindings) != 1 { t.Fatalf("expected blocking critical finding, got %#v", report) } + if report.Summary.Headline == "" || len(report.Sections) < 5 || !hasMissing(report.MissingEvidence, "vulnerability_decision") || !hasMissing(report.FailedPolicies, "critical_exploitable_blocks_release") || len(report.KnownLimitations) == 0 || len(report.NonClaims) == 0 { + t.Fatalf("readiness v2 fields missing: %#v", report) + } + criticalQuestion := readinessQuestionByID(t, report, "critical_findings_triaged") + if criticalQuestion.Status != "missing_evidence" || !hasMissing(criticalQuestion.MissingEvidence, "vulnerability_decision") { + t.Fatalf("critical readiness question = %#v", criticalQuestion) + } + packageQuestion := readinessQuestionByID(t, report, "customer_package_safe_to_share") + if packageQuestion.Status != "limited" { + t.Fatalf("customer package question = %#v", packageQuestion) + } if _, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{Status: decisionStatusNotAffected, Justification: "vulnerable code is not present"}); err != nil { t.Fatalf("decision: %v", err) } @@ -669,6 +680,10 @@ func TestReleaseReadinessRequiresHandledCriticalFinding(t *testing.T) { if report.Result != "passed" || len(report.BlockingFindings) != 0 { t.Fatalf("expected readiness pass after decision, got %#v", report) } + decisionQuestion := readinessQuestionByID(t, report, "vex_decisions_for_blockers") + if decisionQuestion.Status != "passed" || !hasMissing(decisionQuestion.Evidence, "vulnerability_decision") { + t.Fatalf("decision readiness question = %#v", decisionQuestion) + } } func TestCustomerVisibleDecisionRequiresImpactAndRedactsInternalNotes(t *testing.T) { @@ -1497,6 +1512,19 @@ func hasMissing(items []string, want string) bool { return false } +func readinessQuestionByID(t *testing.T, report domain.ReleaseReadinessReport, id string) domain.ReadinessQuestion { + t.Helper() + for _, section := range report.Sections { + for _, question := range section.Questions { + if question.ID == id { + return question + } + } + } + t.Fatalf("readiness question %s not found in %#v", id, report.Sections) + return domain.ReadinessQuestion{} +} + func addBuildProvenance(t *testing.T, ledger *Ledger, actor domain.Actor, release domain.Release, artifact domain.Artifact) { t.Helper() ctx := context.Background() diff --git a/internal/app/vex.go b/internal/app/vex.go index 03b308e..4131d8e 100644 --- a/internal/app/vex.go +++ b/internal/app/vex.go @@ -646,22 +646,216 @@ func (s releaseEvidenceService) ReleaseReadinessReport(ctx context.Context, acto for _, check := range eval.Checks { gaps = append(gaps, check.Missing...) } - sort.Strings(gaps) + gaps = sortedUniqueNonEmptyStrings(gaps) + failedPolicies := failedPolicyNames(eval.Checks) + knownLimitations := releaseReadinessKnownLimitations() + nonClaims := releaseReadinessNonClaims() + sections := l.releaseReadinessSectionsLocked(actor.TenantID, eval.ReleaseID, eval, blocking, accepted, gaps, failedPolicies, knownLimitations) return domain.ReleaseReadinessReport{ ReportType: "release_readiness", TemplateVersion: domain.ReleaseReadinessTemplateVersion, ReleaseID: eval.ReleaseID, Result: eval.Result, + Summary: releaseReadinessSummary(eval, len(blocking), len(gaps), len(failedPolicies)), Checks: eval.Checks, + Sections: sections, BlockingFindings: blocking, AcceptedExceptions: accepted, Gaps: gaps, - Assumptions: []string{"This report supports compliance readiness and is not a legal compliance conclusion."}, - Limitations: []string{"Readiness is based only on evidence, decisions, exceptions, and bundles recorded in this Evydence instance."}, + MissingEvidence: gaps, + FailedPolicies: failedPolicies, + KnownLimitations: knownLimitations, + NonClaims: nonClaims, + Assumptions: []string{"This report supports compliance readiness and technical evidence review; it is not a legal compliance conclusion."}, + Limitations: knownLimitations, GeneratedAt: l.now(), }, nil } +func releaseReadinessSummary(eval domain.PolicyEvaluation, blockingCount, missingCount, failedCount int) domain.ReadinessSummary { + if eval.Result == "passed" { + return domain.ReadinessSummary{ + Headline: "Recorded release evidence satisfies the current built-in readiness checks.", + Result: eval.Result, + HumanSummary: "The report found no blocking policy failures in the recorded release evidence. Review the limitations and non-claims before sharing externally.", + PolicySet: eval.PolicySet, + } + } + return domain.ReadinessSummary{ + Headline: "Recorded release evidence has readiness blockers or missing inputs.", + Result: eval.Result, + HumanSummary: fmt.Sprintf("The report found %d failed policy checks, %d missing evidence inputs, and %d blocking findings in the recorded release evidence.", failedCount, missingCount, blockingCount), + PolicySet: eval.PolicySet, + } +} + +func releaseReadinessKnownLimitations() []string { + return []string{ + "Readiness is based only on evidence, decisions, exceptions, bundles, and build records stored in this Evydence instance.", + "SBOM presence does not prove component inventory completeness.", + "Scanner output is submitted evidence and is not treated as authoritative vulnerability truth.", + "Build provenance and attestations are evaluated from recorded metadata and configured trust material only.", + "Customer package shareability depends on the generated package redaction profile, expiry, and operator review.", + } +} + +func releaseReadinessNonClaims() []string { + return []string{ + "This report supports technical evidence review and compliance readiness only.", + "It is not legal compliance proof, certification, complete SBOM proof, an authoritative vulnerability result, regulator acceptance, or a secure-release guarantee.", + } +} + +func failedPolicyNames(checks []domain.PolicyCheck) []string { + out := []string{} + for _, check := range checks { + if check.Result == "failed" { + out = append(out, check.Name) + } + } + sort.Strings(out) + return out +} + +func (l *Ledger) releaseReadinessSectionsLocked(tenantID, releaseID string, eval domain.PolicyEvaluation, blocking []domain.BlockingFinding, accepted []domain.Exception, missingEvidence, failedPolicies, knownLimitations []string) []domain.ReadinessSection { + checks := readinessChecksByName(eval.Checks) + decisionCount := l.activeDecisionCountForReleaseLocked(tenantID, releaseID) + hasPackage := l.hasActiveCustomerPackageLocked(tenantID, releaseID) + sections := []domain.ReadinessSection{ + readinessSection("release_evidence", "Release Evidence", []domain.ReadinessQuestion{ + readinessQuestionForCheck(checks["release_requires_artifact_digest"], "artifact_digest", "Are artifact digests present?", "Artifact digest evidence is linked to the release.", "Release artifact digest evidence is missing."), + readinessQuestionForCheck(checks["release_requires_sbom"], "sbom", "Is there an SBOM for this release?", "SBOM evidence is recorded for this release.", "SBOM evidence is missing for this release."), + readinessQuestionForCheck(checks["release_requires_vulnerability_scan"], "vulnerability_scan", "Is there a vulnerability scan?", "Vulnerability scan evidence is recorded for this release.", "Vulnerability scan evidence is missing for this release."), + }), + readinessSection("risk_decisions", "Vulnerability Decisions", []domain.ReadinessQuestion{ + readinessQuestionForCheck(checks["critical_exploitable_blocks_release"], "critical_findings_triaged", "Are open critical findings triaged?", "No unhandled open critical findings are recorded.", "One or more open critical findings require a valid decision, remediation, or approved unexpired exception."), + readinessDecisionQuestion(decisionCount, len(blocking)), + readinessExceptionQuestion(accepted), + }), + readinessSection("provenance", "Build Provenance And Bundle", []domain.ReadinessQuestion{ + readinessQuestionForCheck(checks["release_requires_passed_build"], "passed_build", "Is passed build provenance attached?", "A passed build is linked to a release artifact digest.", "No passed build with output digest linked to the release was found."), + readinessQuestionForCheck(checks["release_requires_build_attestation"], "build_attestation", "Is there a build attestation for a release artifact?", "A build attestation subject matches a release artifact digest.", "No build attestation subject matches a release artifact digest."), + readinessQuestionForCheck(checks["release_requires_signed_bundle"], "signed_bundle", "Is there a signed release bundle?", "A signed release bundle exists for this release.", "A signed release bundle is missing for this release."), + }), + readinessSection("customer_review", "Customer Package Review", []domain.ReadinessQuestion{ + readinessCustomerPackageQuestion(hasPackage), + }), + readinessSection("gaps_and_limitations", "Gaps And Limitations", []domain.ReadinessQuestion{ + readinessGapQuestion(missingEvidence, failedPolicies), + {ID: "known_limitations", Question: "What limitations apply?", Answer: "Read the known_limitations and non_claims fields before using this report.", Status: "limited", KnownLimitations: append([]string(nil), knownLimitations...)}, + }), + } + return sections +} + +func readinessChecksByName(checks []domain.PolicyCheck) map[string]domain.PolicyCheck { + out := map[string]domain.PolicyCheck{} + for _, check := range checks { + out[check.Name] = check + } + return out +} + +func readinessSection(id, title string, questions []domain.ReadinessQuestion) domain.ReadinessSection { + status := "passed" + for _, question := range questions { + switch question.Status { + case "failed_policy": + status = "failed" + case "missing_evidence": + if status != "failed" { + status = "missing" + } + case "limited": + if status == "passed" { + status = "limited" + } + } + } + return domain.ReadinessSection{ID: id, Title: title, Status: status, Summary: readinessSectionSummary(status), Questions: questions} +} + +func readinessSectionSummary(status string) string { + switch status { + case "failed": + return "One or more reviewer questions failed a policy check." + case "missing": + return "One or more reviewer questions is missing evidence." + case "limited": + return "This section has recorded limitations or non-blocking missing context." + default: + return "Recorded evidence satisfies this section." + } +} + +func readinessQuestionForCheck(check domain.PolicyCheck, id, question, passedAnswer, failedAnswer string) domain.ReadinessQuestion { + if check.Name == "" { + return domain.ReadinessQuestion{ID: id, Question: question, Answer: "No policy check was recorded for this question.", Status: "limited", KnownLimitations: []string{"Policy coverage for this question is not configured."}} + } + if check.Result == "passed" { + return domain.ReadinessQuestion{ID: id, Question: question, Answer: passedAnswer, Status: "passed", Checks: []string{check.Name}} + } + status := "failed_policy" + if len(check.Missing) > 0 { + status = "missing_evidence" + } + return domain.ReadinessQuestion{ID: id, Question: question, Answer: failedAnswer, Status: status, Checks: []string{check.Name}, MissingEvidence: append([]string(nil), check.Missing...), FailedPolicies: []string{check.Name}} +} + +func readinessDecisionQuestion(decisionCount, blockingCount int) domain.ReadinessQuestion { + if blockingCount > 0 { + return domain.ReadinessQuestion{ID: "vex_decisions_for_blockers", Question: "Are VEX or vulnerability decisions present for blocking findings?", Answer: fmt.Sprintf("%d blocking finding(s) still need a valid decision, remediation, or approved exception.", blockingCount), Status: "failed_policy", MissingEvidence: []string{"vulnerability_decision"}, FailedPolicies: []string{"critical_exploitable_blocks_release"}} + } + if decisionCount > 0 { + return domain.ReadinessQuestion{ID: "vex_decisions_for_blockers", Question: "Are VEX or vulnerability decisions present for blocking findings?", Answer: fmt.Sprintf("%d active vulnerability decision(s) are recorded for this release.", decisionCount), Status: "passed", Evidence: []string{"vulnerability_decision"}} + } + return domain.ReadinessQuestion{ID: "vex_decisions_for_blockers", Question: "Are VEX or vulnerability decisions present for blocking findings?", Answer: "No active vulnerability decisions are recorded; no blocking findings currently require one.", Status: "limited", KnownLimitations: []string{"Decision evidence is only expected when findings require triage or customer-visible explanation."}} +} + +func readinessExceptionQuestion(accepted []domain.Exception) domain.ReadinessQuestion { + if len(accepted) > 0 { + return domain.ReadinessQuestion{ID: "approved_exceptions", Question: "Are exceptions approved and unexpired?", Answer: fmt.Sprintf("%d approved unexpired exception(s) are accepted for this release.", len(accepted)), Status: "passed", Evidence: []string{"exception"}} + } + return domain.ReadinessQuestion{ID: "approved_exceptions", Question: "Are exceptions approved and unexpired?", Answer: "No approved unexpired release exceptions are used by this report.", Status: "limited", KnownLimitations: []string{"No exception is needed when policy checks pass without an accepted exception."}} +} + +func readinessCustomerPackageQuestion(hasPackage bool) domain.ReadinessQuestion { + if hasPackage { + return domain.ReadinessQuestion{ID: "customer_package_safe_to_share", Question: "Is a customer package available for review?", Answer: "A non-expired customer package is recorded for this release; review its redaction profile before sharing.", Status: "passed", Evidence: []string{"customer_package"}} + } + return domain.ReadinessQuestion{ID: "customer_package_safe_to_share", Question: "Is a customer package available for review?", Answer: "No customer package was evaluated by this release readiness report.", Status: "limited", KnownLimitations: []string{"Package shareability is evaluated when a scoped customer package is generated."}} +} + +func readinessGapQuestion(missingEvidence, failedPolicies []string) domain.ReadinessQuestion { + if len(missingEvidence) == 0 && len(failedPolicies) == 0 { + return domain.ReadinessQuestion{ID: "remaining_gaps", Question: "What gaps remain?", Answer: "No blocking readiness gaps are recorded by the current policy checks.", Status: "passed"} + } + status := "failed_policy" + if len(failedPolicies) == 0 { + status = "missing_evidence" + } + return domain.ReadinessQuestion{ID: "remaining_gaps", Question: "What gaps remain?", Answer: "The report lists missing evidence and failed policy checks that should be reviewed.", Status: status, MissingEvidence: append([]string(nil), missingEvidence...), FailedPolicies: append([]string(nil), failedPolicies...)} +} + +func (l *Ledger) activeDecisionCountForReleaseLocked(tenantID, releaseID string) int { + count := 0 + for _, decision := range l.decisions { + if decision.TenantID == tenantID && decision.ReleaseID == releaseID && decision.SupersededBy == "" { + count++ + } + } + return count +} + +func (l *Ledger) hasActiveCustomerPackageLocked(tenantID, releaseID string) bool { + for _, pkg := range l.customerPackages { + if pkg.TenantID == tenantID && pkg.ReleaseID == releaseID && pkg.State == "generated" && pkg.ExpiresAt.After(l.now()) { + return true + } + } + return false +} + func parseOpenVEX(raw []byte) (openVEXDocument, error) { var doc openVEXDocument dec := json.NewDecoder(bytes.NewReader(raw)) diff --git a/internal/domain/domain.go b/internal/domain/domain.go index 0176276..a2c5f55 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -1256,18 +1256,51 @@ type VerifyCheck struct { } type ReleaseReadinessReport struct { - ReportType string `json:"report_type"` - TemplateVersion string `json:"template_version"` - ReleaseID string `json:"release_id"` - Result string `json:"result"` - Checks []PolicyCheck `json:"checks"` - BlockingFindings []BlockingFinding `json:"blocking_findings,omitempty"` - AcceptedExceptions []Exception `json:"accepted_exceptions,omitempty"` - Gaps []string `json:"gaps,omitempty"` - Assumptions []string `json:"assumptions"` - Limitations []string `json:"limitations"` - Metadata map[string]any `json:"metadata,omitempty"` - GeneratedAt time.Time `json:"generated_at"` + ReportType string `json:"report_type"` + TemplateVersion string `json:"template_version"` + ReleaseID string `json:"release_id"` + Result string `json:"result"` + Summary ReadinessSummary `json:"summary,omitempty"` + Checks []PolicyCheck `json:"checks"` + Sections []ReadinessSection `json:"sections,omitempty"` + BlockingFindings []BlockingFinding `json:"blocking_findings,omitempty"` + AcceptedExceptions []Exception `json:"accepted_exceptions,omitempty"` + Gaps []string `json:"gaps,omitempty"` + MissingEvidence []string `json:"missing_evidence,omitempty"` + FailedPolicies []string `json:"failed_policies,omitempty"` + KnownLimitations []string `json:"known_limitations,omitempty"` + NonClaims []string `json:"non_claims,omitempty"` + Assumptions []string `json:"assumptions"` + Limitations []string `json:"limitations"` + Metadata map[string]any `json:"metadata,omitempty"` + GeneratedAt time.Time `json:"generated_at"` +} + +type ReadinessSummary struct { + Headline string `json:"headline"` + Result string `json:"result"` + HumanSummary string `json:"human_summary"` + PolicySet string `json:"policy_set,omitempty"` +} + +type ReadinessSection struct { + ID string `json:"id"` + Title string `json:"title"` + Status string `json:"status"` + Summary string `json:"summary"` + Questions []ReadinessQuestion `json:"questions"` +} + +type ReadinessQuestion struct { + ID string `json:"id"` + Question string `json:"question"` + Answer string `json:"answer"` + Status string `json:"status"` + Evidence []string `json:"evidence,omitempty"` + Checks []string `json:"checks,omitempty"` + MissingEvidence []string `json:"missing_evidence,omitempty"` + FailedPolicies []string `json:"failed_policies,omitempty"` + KnownLimitations []string `json:"known_limitations,omitempty"` } type BlockingFinding struct { diff --git a/openapi.yaml b/openapi.yaml index 922e7e3..18bf6b0 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"gaps":{"items":{"type":"object"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From fa2b46c973a3ba07b2c74c6c5dfb537e73d249a3 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:28:20 +0300 Subject: [PATCH 188/287] feat(policy): expand release readiness checks --- .productization_next_steps.md | 2 +- docs/api.md | 8 ++ .../sample-readiness-report.json | 4 +- internal/adapters/httpapi/openapi.go | 2 + internal/app/builds.go | 4 +- internal/app/ledger.go | 32 +++++- internal/app/ledger_test.go | 59 +++++++++- internal/app/vex.go | 103 +++++++++++++++++- internal/domain/domain.go | 2 + openapi.yaml | 2 +- 10 files changed, 207 insertions(+), 11 deletions(-) diff --git a/.productization_next_steps.md b/.productization_next_steps.md index f6f657e..d980328 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -651,7 +651,7 @@ Acceptance criteria: * Report includes non-claim language. * Example report updated. -#### [ ] EVY-041 — Add policy-based readiness checks +#### [x] EVY-041 — Add policy-based readiness checks Priority: P1 diff --git a/docs/api.md b/docs/api.md index 17bea2e..afe9125 100644 --- a/docs/api.md +++ b/docs/api.md @@ -255,6 +255,14 @@ question sections, missing evidence, failed policy checks, blockers, gaps, assumptions, non-claims, and limitations; it is not a legal compliance or release-security conclusion. +The default `policy-set.v1.0.0` release checks require release-linked artifact +and digest evidence, SBOM evidence, vulnerability-scan evidence, handled open +critical/high findings, review-safe customer-visible decisions, justifications +for `not_affected` decisions, complete exception metadata, passed build +provenance, build-attestation subject coverage, a signed release bundle, and +valid redaction profiles for generated customer packages. Failed checks include +`remediation` text with the next evidence action to take. + ## Authentication And Scopes API keys and collector keys are tenant-scoped bearer secrets. Human SSO session actors derive scopes from role bindings and enforce resource constraints where those resources are part of the request. diff --git a/examples/end-to-end-release-evidence/sample-readiness-report.json b/examples/end-to-end-release-evidence/sample-readiness-report.json index 4c49fb5..e31fa4b 100644 --- a/examples/end-to-end-release-evidence/sample-readiness-report.json +++ b/examples/end-to-end-release-evidence/sample-readiness-report.json @@ -4,6 +4,7 @@ "template_version": "release-readiness.v1.0.0", "release_id": "rel_example", "result": "failed", + "policy_set": "policy-set.v1.0.0", "summary": { "headline": "Recorded release evidence has readiness blockers or missing inputs.", "result": "failed", @@ -24,7 +25,8 @@ "missing": [ "vulnerability_decision" ], - "explanation": "open critical finding requires remediation, a valid VEX decision, or an approved unexpired exception" + "explanation": "open critical finding requires remediation, a valid VEX decision, or an approved unexpired exception", + "remediation": "Record a fixed or not_affected vulnerability decision, upload VEX evidence, remediate the finding, or approve an unexpired scoped exception." } ], "sections": [ diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 928d36b..f616a01 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -277,6 +277,7 @@ func registerCriticalSchemas(registry *specs.Registry) { "severity": map[string]any{"type": "string"}, "missing": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, "explanation": map[string]any{"type": "string"}, + "remediation": map[string]any{"type": "string"}, }, "name", "result", "severity", "explanation")) registry.RegisterSchema("PolicyEvaluation", objectSchema(map[string]any{ "id": map[string]any{"type": "string"}, @@ -1238,6 +1239,7 @@ func registerCriticalSchemas(registry *specs.Registry) { "product_id": map[string]any{"type": "string"}, "release_id": map[string]any{"type": "string"}, "result": map[string]any{"type": "string"}, + "policy_set": map[string]any{"type": "string"}, "summary": map[string]any{"type": "object", "additionalProperties": false, "properties": map[string]any{ "headline": map[string]any{"type": "string"}, "result": map[string]any{"type": "string"}, diff --git a/internal/app/builds.go b/internal/app/builds.go index 9100f62..d9409bd 100644 --- a/internal/app/builds.go +++ b/internal/app/builds.go @@ -764,7 +764,7 @@ func (l *Ledger) checkReleaseHasPassedBuildLocked(tenantID, releaseID string) do } } } - return domain.PolicyCheck{Name: "release_requires_passed_build", Result: "failed", Severity: "high", Missing: []string{"passed_build"}, Explanation: "no passed build with output digest linked to the release was found"} + return domain.PolicyCheck{Name: "release_requires_passed_build", Result: "failed", Severity: "high", Missing: []string{"passed_build"}, Explanation: "no passed build with output digest linked to the release was found", Remediation: "Upload a passed build run whose output digest matches a release artifact digest."} } func (l *Ledger) checkReleaseHasBuildAttestationLocked(tenantID, releaseID string) domain.PolicyCheck { @@ -783,7 +783,7 @@ func (l *Ledger) checkReleaseHasBuildAttestationLocked(tenantID, releaseID strin } } } - return domain.PolicyCheck{Name: "release_requires_build_attestation", Result: "failed", Severity: "high", Missing: []string{"build_attestation"}, Explanation: "no build attestation subject matches a release artifact digest"} + return domain.PolicyCheck{Name: "release_requires_build_attestation", Result: "failed", Severity: "high", Missing: []string{"build_attestation"}, Explanation: "no build attestation subject matches a release artifact digest", Remediation: "Upload a DSSE/in-toto attestation whose subject digest matches a release artifact digest."} } func (l *Ledger) releaseArtifactDigestsLocked(tenantID, releaseID string) map[string]struct{} { diff --git a/internal/app/ledger.go b/internal/app/ledger.go index d4b0646..cc9a2ae 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -1173,6 +1173,7 @@ func (l *Ledger) EvaluateRelease(ctx context.Context, actor domain.Actor, releas return domain.PolicyEvaluation{}, err } checks := []domain.PolicyCheck{ + l.checkReleaseHasArtifactLocked(actor.TenantID, release.ID), l.checkReleaseHasEvidenceLocked(actor.TenantID, release.ID, "sbom", "release_requires_sbom", "high"), l.checkReleaseHasEvidenceLocked(actor.TenantID, release.ID, "vulnerability_scan", "release_requires_vulnerability_scan", "high"), l.checkReleaseHasArtifactDigestLocked(actor.TenantID, release.ID), @@ -1180,6 +1181,11 @@ func (l *Ledger) EvaluateRelease(ctx context.Context, actor domain.Actor, releas l.checkReleaseHasPassedBuildLocked(actor.TenantID, release.ID), l.checkReleaseHasBuildAttestationLocked(actor.TenantID, release.ID), l.checkNoOpenCriticalLocked(actor.TenantID, release.ID), + l.checkNoOpenHighLocked(actor.TenantID, release.ID), + l.checkCustomerVisibleDecisionsHaveStatementsLocked(actor.TenantID, release.ID), + l.checkNotAffectedDecisionsHaveJustificationLocked(actor.TenantID, release.ID), + l.checkExceptionsCompleteLocked(actor.TenantID, release.ID), + l.checkPackageRedactionProfilesValidLocked(actor.TenantID, release.ID), } result := "passed" for _, check := range checks { @@ -1869,19 +1875,41 @@ func (l *Ledger) verifySignatureLocked(tenantID string, signatureRefs []string, return false } +func (l *Ledger) checkReleaseHasArtifactLocked(tenantID, releaseID string) domain.PolicyCheck { + for _, item := range l.evidence { + if item.TenantID != tenantID || item.ReleaseID != releaseID { + continue + } + for _, ref := range item.SubjectRefs { + if ref.Type == "artifact" && ref.ID != "" { + return domain.PolicyCheck{Name: "release_has_artifact", Result: "passed", Severity: "high", Explanation: "artifact evidence is linked to the release"} + } + } + } + return domain.PolicyCheck{Name: "release_has_artifact", Result: "failed", Severity: "high", Missing: []string{"artifact"}, Explanation: "release artifact evidence is missing", Remediation: "Register an artifact digest and link it to release evidence such as SBOM, scan, build output, or artifact digest evidence."} +} + func (l *Ledger) checkReleaseHasEvidenceLocked(tenantID, releaseID, typ, name, severity string) domain.PolicyCheck { for _, item := range l.evidence { if item.TenantID == tenantID && item.ReleaseID == releaseID && item.Type == typ { return domain.PolicyCheck{Name: name, Result: "passed", Severity: severity, Explanation: typ + " evidence exists"} } } - return domain.PolicyCheck{Name: name, Result: "failed", Severity: severity, Missing: []string{typ}, Explanation: typ + " evidence is missing"} + return domain.PolicyCheck{Name: name, Result: "failed", Severity: severity, Missing: []string{typ}, Explanation: typ + " evidence is missing", Remediation: "Upload " + typ + " evidence for this release."} } func (l *Ledger) checkNoOpenCriticalLocked(tenantID, releaseID string) domain.PolicyCheck { blocking := l.unhandledCriticalFindingsLocked(tenantID, releaseID) if len(blocking) > 0 { - return domain.PolicyCheck{Name: "critical_exploitable_blocks_release", Result: "failed", Severity: "critical", Missing: []string{"vulnerability_decision"}, Explanation: "open critical finding requires remediation, a valid VEX decision, or an approved unexpired exception"} + return domain.PolicyCheck{Name: "critical_exploitable_blocks_release", Result: "failed", Severity: "critical", Missing: []string{"vulnerability_decision"}, Explanation: "open critical finding requires remediation, a valid VEX decision, or an approved unexpired exception", Remediation: "Record a fixed or not_affected vulnerability decision, upload VEX evidence, remediate the finding, or approve an unexpired scoped exception."} } return domain.PolicyCheck{Name: "critical_exploitable_blocks_release", Result: "passed", Severity: "critical", Explanation: "no open critical findings recorded"} } + +func (l *Ledger) checkNoOpenHighLocked(tenantID, releaseID string) domain.PolicyCheck { + blocking := l.unhandledFindingsBySeverityLocked(tenantID, releaseID, "high") + if len(blocking) > 0 { + return domain.PolicyCheck{Name: "high_findings_require_triage", Result: "failed", Severity: "high", Missing: []string{"vulnerability_decision"}, Explanation: "open high finding requires a valid decision, remediation, or an approved unexpired exception", Remediation: "Record a fixed or not_affected vulnerability decision, upload VEX evidence, remediate the finding, or approve an unexpired scoped exception."} + } + return domain.PolicyCheck{Name: "high_findings_require_triage", Result: "passed", Severity: "high", Explanation: "no unhandled open high findings recorded"} +} diff --git a/internal/app/ledger_test.go b/internal/app/ledger_test.go index fb28c2b..7c4a037 100644 --- a/internal/app/ledger_test.go +++ b/internal/app/ledger_test.go @@ -659,9 +659,13 @@ func TestReleaseReadinessRequiresHandledCriticalFinding(t *testing.T) { if report.Result != "failed" || len(report.BlockingFindings) != 1 { t.Fatalf("expected blocking critical finding, got %#v", report) } - if report.Summary.Headline == "" || len(report.Sections) < 5 || !hasMissing(report.MissingEvidence, "vulnerability_decision") || !hasMissing(report.FailedPolicies, "critical_exploitable_blocks_release") || len(report.KnownLimitations) == 0 || len(report.NonClaims) == 0 { + if report.PolicySet == "" || report.Summary.Headline == "" || len(report.Sections) < 5 || !hasMissing(report.MissingEvidence, "vulnerability_decision") || !hasMissing(report.FailedPolicies, "critical_exploitable_blocks_release") || len(report.KnownLimitations) == 0 || len(report.NonClaims) == 0 { t.Fatalf("readiness v2 fields missing: %#v", report) } + criticalCheck := policyCheckByName(t, report.Checks, "critical_exploitable_blocks_release") + if criticalCheck.Remediation == "" { + t.Fatalf("critical check missing remediation: %#v", criticalCheck) + } criticalQuestion := readinessQuestionByID(t, report, "critical_findings_triaged") if criticalQuestion.Status != "missing_evidence" || !hasMissing(criticalQuestion.MissingEvidence, "vulnerability_decision") { t.Fatalf("critical readiness question = %#v", criticalQuestion) @@ -684,6 +688,48 @@ func TestReleaseReadinessRequiresHandledCriticalFinding(t *testing.T) { if decisionQuestion.Status != "passed" || !hasMissing(decisionQuestion.Evidence, "vulnerability_decision") { t.Fatalf("decision readiness question = %#v", decisionQuestion) } + highScan, err := ledger.UploadVulnerabilityScan(ctx, actor, []byte(`{ + "scanner":"grype", + "target_ref":"pkg:oci/payments-api", + "release_id":"`+release.ID+`", + "findings":[{"vulnerability":"CVE-2026-0002","component":"pkg:apk/curl@8.0.0","severity":"high","state":"open"}] + }`)) + if err != nil { + t.Fatalf("high scan: %v", err) + } + report, err = ledger.ReleaseReadinessReport(ctx, actor, release.ID) + if err != nil { + t.Fatalf("readiness after high finding: %v", err) + } + highCheck := policyCheckByName(t, report.Checks, "high_findings_require_triage") + if report.Result != "failed" || highCheck.Result != "failed" || highCheck.Remediation == "" { + t.Fatalf("expected high finding triage failure, report=%#v check=%#v", report, highCheck) + } + if _, err := ledger.CreateVulnerabilityDecision(ctx, actor, highScan.Findings[0].ID, CreateVulnerabilityDecisionInput{Status: decisionStatusFixed, Justification: "fixed in release"}); err != nil { + t.Fatalf("high decision: %v", err) + } + report, err = ledger.ReleaseReadinessReport(ctx, actor, release.ID) + if err != nil { + t.Fatalf("readiness after high decision: %v", err) + } + if report.Result != "passed" { + t.Fatalf("expected readiness pass after high decision, got %#v", report) + } + profile, err := ledger.CreateRedactionProfile(ctx, actor, CreateRedactionProfileInput{Name: "unsafe package profile", AllowedTypes: []string{"vulnerability_decision"}}) + if err != nil { + t.Fatalf("redaction profile: %v", err) + } + if _, err := ledger.CreateCustomerSecurityPackage(ctx, actor, CreateCustomerPackageInput{ProductID: release.ProductID, ReleaseID: release.ID, RedactionProfileID: profile.ID, Title: "Unsafe package", ExpiresAt: fixedNow().Add(time.Hour)}); err != nil { + t.Fatalf("customer package: %v", err) + } + report, err = ledger.ReleaseReadinessReport(ctx, actor, release.ID) + if err != nil { + t.Fatalf("readiness after unsafe package: %v", err) + } + packageCheck := policyCheckByName(t, report.Checks, "package_redaction_profile_valid") + if report.Result != "failed" || packageCheck.Result != "failed" || packageCheck.Remediation == "" { + t.Fatalf("expected package redaction failure, report=%#v check=%#v", report, packageCheck) + } } func TestCustomerVisibleDecisionRequiresImpactAndRedactsInternalNotes(t *testing.T) { @@ -1512,6 +1558,17 @@ func hasMissing(items []string, want string) bool { return false } +func policyCheckByName(t *testing.T, checks []domain.PolicyCheck, name string) domain.PolicyCheck { + t.Helper() + for _, check := range checks { + if check.Name == name { + return check + } + } + t.Fatalf("policy check %s not found in %#v", name, checks) + return domain.PolicyCheck{} +} + func readinessQuestionByID(t *testing.T, report domain.ReleaseReadinessReport, id string) domain.ReadinessQuestion { t.Helper() for _, section := range report.Sections { diff --git a/internal/app/vex.go b/internal/app/vex.go index 4131d8e..d878629 100644 --- a/internal/app/vex.go +++ b/internal/app/vex.go @@ -656,6 +656,7 @@ func (s releaseEvidenceService) ReleaseReadinessReport(ctx context.Context, acto TemplateVersion: domain.ReleaseReadinessTemplateVersion, ReleaseID: eval.ReleaseID, Result: eval.Result, + PolicySet: eval.PolicySet, Summary: releaseReadinessSummary(eval, len(blocking), len(gaps), len(failedPolicies)), Checks: eval.Checks, Sections: sections, @@ -723,14 +724,19 @@ func (l *Ledger) releaseReadinessSectionsLocked(tenantID, releaseID string, eval hasPackage := l.hasActiveCustomerPackageLocked(tenantID, releaseID) sections := []domain.ReadinessSection{ readinessSection("release_evidence", "Release Evidence", []domain.ReadinessQuestion{ + readinessQuestionForCheck(checks["release_has_artifact"], "release_has_artifact", "Is a release artifact linked?", "Artifact evidence is linked to the release.", "Release artifact evidence is missing."), readinessQuestionForCheck(checks["release_requires_artifact_digest"], "artifact_digest", "Are artifact digests present?", "Artifact digest evidence is linked to the release.", "Release artifact digest evidence is missing."), readinessQuestionForCheck(checks["release_requires_sbom"], "sbom", "Is there an SBOM for this release?", "SBOM evidence is recorded for this release.", "SBOM evidence is missing for this release."), readinessQuestionForCheck(checks["release_requires_vulnerability_scan"], "vulnerability_scan", "Is there a vulnerability scan?", "Vulnerability scan evidence is recorded for this release.", "Vulnerability scan evidence is missing for this release."), }), readinessSection("risk_decisions", "Vulnerability Decisions", []domain.ReadinessQuestion{ readinessQuestionForCheck(checks["critical_exploitable_blocks_release"], "critical_findings_triaged", "Are open critical findings triaged?", "No unhandled open critical findings are recorded.", "One or more open critical findings require a valid decision, remediation, or approved unexpired exception."), + readinessQuestionForCheck(checks["high_findings_require_triage"], "high_findings_triaged", "Are open high findings triaged?", "No unhandled open high findings are recorded.", "One or more open high findings require a valid decision, remediation, or approved unexpired exception."), readinessDecisionQuestion(decisionCount, len(blocking)), + readinessQuestionForCheck(checks["customer_visible_decisions_require_statements"], "customer_visible_decision_statements", "Do customer-visible decisions have review-safe statements?", "Customer-visible decisions have required impact statements.", "One or more customer-visible decisions is missing an impact statement."), + readinessQuestionForCheck(checks["not_affected_decisions_require_justification"], "not_affected_justifications", "Do not_affected decisions include justifications?", "not_affected decisions include recorded justifications.", "One or more not_affected decisions is missing a justification."), readinessExceptionQuestion(accepted), + readinessQuestionForCheck(checks["exceptions_require_owner_reason_expiry_and_approval"], "exception_completeness", "Are exceptions complete?", "Release exceptions have required owner, reason, expiry, and approval metadata.", "One or more exceptions is incomplete."), }), readinessSection("provenance", "Build Provenance And Bundle", []domain.ReadinessQuestion{ readinessQuestionForCheck(checks["release_requires_passed_build"], "passed_build", "Is passed build provenance attached?", "A passed build is linked to a release artifact digest.", "No passed build with output digest linked to the release was found."), @@ -739,6 +745,7 @@ func (l *Ledger) releaseReadinessSectionsLocked(tenantID, releaseID string, eval }), readinessSection("customer_review", "Customer Package Review", []domain.ReadinessQuestion{ readinessCustomerPackageQuestion(hasPackage), + readinessQuestionForCheck(checks["package_redaction_profile_valid"], "package_redaction_profile_valid", "Is the customer package redaction profile valid?", "Recorded package redaction profiles are explicit and exclude sensitive fields, or no package exists yet.", "One or more packages has an expired or incomplete redaction profile."), }), readinessSection("gaps_and_limitations", "Gaps And Limitations", []domain.ReadinessQuestion{ readinessGapQuestion(missingEvidence, failedPolicies), @@ -856,6 +863,88 @@ func (l *Ledger) hasActiveCustomerPackageLocked(tenantID, releaseID string) bool return false } +func (l *Ledger) checkCustomerVisibleDecisionsHaveStatementsLocked(tenantID, releaseID string) domain.PolicyCheck { + missing := []string{} + for _, decision := range l.decisions { + if decision.TenantID != tenantID || decision.ReleaseID != releaseID || decision.SupersededBy != "" || !decision.CustomerVisible { + continue + } + if strings.TrimSpace(decision.ImpactStatement) == "" { + missing = append(missing, decision.ID) + } + } + if len(missing) > 0 { + sort.Strings(missing) + return domain.PolicyCheck{Name: "customer_visible_decisions_require_statements", Result: "failed", Severity: "high", Missing: missing, Explanation: "customer-visible decisions require an impact statement suitable for package summaries", Remediation: "Create a superseding customer-visible decision with a clear impact statement and no internal-only notes in customer-facing fields."} + } + return domain.PolicyCheck{Name: "customer_visible_decisions_require_statements", Result: "passed", Severity: "high", Explanation: "customer-visible decisions have required impact statements"} +} + +func (l *Ledger) checkNotAffectedDecisionsHaveJustificationLocked(tenantID, releaseID string) domain.PolicyCheck { + missing := []string{} + for _, decision := range l.decisions { + if decision.TenantID != tenantID || decision.ReleaseID != releaseID || decision.SupersededBy != "" || decision.Status != decisionStatusNotAffected { + continue + } + if strings.TrimSpace(decision.Justification) == "" { + missing = append(missing, decision.ID) + } + } + if len(missing) > 0 { + sort.Strings(missing) + return domain.PolicyCheck{Name: "not_affected_decisions_require_justification", Result: "failed", Severity: "high", Missing: missing, Explanation: "not_affected decisions require a recorded justification", Remediation: "Create a superseding not_affected decision with a specific technical justification."} + } + return domain.PolicyCheck{Name: "not_affected_decisions_require_justification", Result: "passed", Severity: "high", Explanation: "not_affected decisions have recorded justifications"} +} + +func (l *Ledger) checkExceptionsCompleteLocked(tenantID, releaseID string) domain.PolicyCheck { + missing := []string{} + for _, exception := range l.exceptions { + if exception.TenantID != tenantID || exception.ReleaseID != releaseID { + continue + } + if strings.TrimSpace(exception.Owner) == "" || strings.TrimSpace(exception.Reason) == "" || exception.ExpiresAt.IsZero() || (exception.Approved && (strings.TrimSpace(exception.ApprovedBy) == "" || exception.ApprovedAt == nil)) { + missing = append(missing, exception.ID) + } + } + if len(missing) > 0 { + sort.Strings(missing) + return domain.PolicyCheck{Name: "exceptions_require_owner_reason_expiry_and_approval", Result: "failed", Severity: "high", Missing: missing, Explanation: "exceptions must include owner, reason, expiry, and approval metadata when approved", Remediation: "Create a complete exception with owner, reason, future expiry, and an audited approval transition."} + } + return domain.PolicyCheck{Name: "exceptions_require_owner_reason_expiry_and_approval", Result: "passed", Severity: "high", Explanation: "release exceptions have required completeness fields"} +} + +func (l *Ledger) checkPackageRedactionProfilesValidLocked(tenantID, releaseID string) domain.PolicyCheck { + missing := []string{} + sawPackage := false + for _, pkg := range l.customerPackages { + if pkg.TenantID != tenantID || pkg.ReleaseID != releaseID { + continue + } + sawPackage = true + profile, ok := l.redactions[pkg.RedactionProfileID] + if !ok || profile.TenantID != tenantID || len(profile.AllowedTypes) == 0 || !redactionProfileExcludesPackageSensitiveFields(profile) || !pkg.ExpiresAt.After(l.now()) { + missing = append(missing, pkg.ID) + } + } + if len(missing) > 0 { + sort.Strings(missing) + return domain.PolicyCheck{Name: "package_redaction_profile_valid", Result: "failed", Severity: "high", Missing: missing, Explanation: "one or more customer packages has an expired package or redaction profile that does not explicitly exclude sensitive fields", Remediation: "Create a new package with the customer_safe or security_review preset, or configure explicit allowed types and sensitive-field exclusions."} + } + if !sawPackage { + return domain.PolicyCheck{Name: "package_redaction_profile_valid", Result: "passed", Severity: "medium", Explanation: "no customer package is recorded for this release; redaction profile validation applies when a package exists"} + } + return domain.PolicyCheck{Name: "package_redaction_profile_valid", Result: "passed", Severity: "high", Explanation: "customer package redaction profiles are explicit and exclude sensitive fields"} +} + +func redactionProfileExcludesPackageSensitiveFields(profile domain.RedactionProfile) bool { + required := map[string]struct{}{"payload_ref": {}, "object_key": {}, "private_key": {}, "token": {}, "secret": {}, "internal_notes": {}} + for _, field := range profile.ExcludedFields { + delete(required, strings.ToLower(strings.TrimSpace(field))) + } + return len(required) == 0 +} + func parseOpenVEX(raw []byte) (openVEXDocument, error) { var doc openVEXDocument dec := json.NewDecoder(bytes.NewReader(raw)) @@ -1153,13 +1242,21 @@ func (l *Ledger) findingHandledLocked(tenantID string, scan domain.Vulnerability } func (l *Ledger) unhandledCriticalFindingsLocked(tenantID, releaseID string) []domain.BlockingFinding { + return l.unhandledFindingsBySeverityLocked(tenantID, releaseID, "critical") +} + +func (l *Ledger) unhandledFindingsBySeverityLocked(tenantID, releaseID string, severities ...string) []domain.BlockingFinding { + allowed := map[string]struct{}{} + for _, severity := range severities { + allowed[strings.ToLower(strings.TrimSpace(severity))] = struct{}{} + } blocking := []domain.BlockingFinding{} for _, scan := range l.scans { if scan.TenantID != tenantID || scan.ReleaseID != releaseID { continue } for _, finding := range scan.Findings { - if strings.ToLower(finding.Severity) != "critical" || strings.ToLower(nonEmpty(finding.State, "open")) != "open" { + if _, ok := allowed[strings.ToLower(finding.Severity)]; !ok || strings.ToLower(nonEmpty(finding.State, "open")) != "open" { continue } if l.findingHandledLocked(tenantID, scan, finding) { @@ -1202,7 +1299,7 @@ func (l *Ledger) checkReleaseHasArtifactDigestLocked(tenantID, releaseID string) } } } - return domain.PolicyCheck{Name: "release_requires_artifact_digest", Result: "failed", Severity: "high", Missing: []string{"artifact_digest"}, Explanation: "release artifact digest evidence is missing"} + return domain.PolicyCheck{Name: "release_requires_artifact_digest", Result: "failed", Severity: "high", Missing: []string{"artifact_digest"}, Explanation: "release artifact digest evidence is missing", Remediation: "Register an artifact digest and link it to release evidence."} } func (l *Ledger) checkReleaseHasSignedBundleLocked(tenantID, releaseID string) domain.PolicyCheck { @@ -1214,5 +1311,5 @@ func (l *Ledger) checkReleaseHasSignedBundleLocked(tenantID, releaseID string) d return domain.PolicyCheck{Name: "release_requires_signed_bundle", Result: "passed", Severity: "high", Explanation: "signed release bundle exists"} } } - return domain.PolicyCheck{Name: "release_requires_signed_bundle", Result: "failed", Severity: "high", Missing: []string{"signed_release_bundle"}, Explanation: "signed release bundle is missing"} + return domain.PolicyCheck{Name: "release_requires_signed_bundle", Result: "failed", Severity: "high", Missing: []string{"signed_release_bundle"}, Explanation: "signed release bundle is missing", Remediation: "Generate a release bundle after required evidence is recorded."} } diff --git a/internal/domain/domain.go b/internal/domain/domain.go index a2c5f55..f882736 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -1209,6 +1209,7 @@ type PolicyCheck struct { Severity string `json:"severity"` Missing []string `json:"missing,omitempty"` Explanation string `json:"explanation"` + Remediation string `json:"remediation,omitempty"` } type Exception struct { @@ -1260,6 +1261,7 @@ type ReleaseReadinessReport struct { TemplateVersion string `json:"template_version"` ReleaseID string `json:"release_id"` Result string `json:"result"` + PolicySet string `json:"policy_set,omitempty"` Summary ReadinessSummary `json:"summary,omitempty"` Checks []PolicyCheck `json:"checks"` Sections []ReadinessSection `json:"sections,omitempty"` diff --git a/openapi.yaml b/openapi.yaml index 18bf6b0..0540985 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"remediation":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"policy_set":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From 2ec346f0dc5a000df8826ad87d5af69d53346de2 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:31:12 +0300 Subject: [PATCH 189/287] feat(packages): add customer safe gaps --- .productization_next_steps.md | 2 +- docs/reference/customer-package-manifest.md | 10 ++++ internal/app/governance_packages.go | 58 +++++++++++++++++++++ internal/app/governance_packages_test.go | 37 +++++++++++++ site/package-viewer/index.html | 7 +++ 5 files changed, 113 insertions(+), 1 deletion(-) diff --git a/.productization_next_steps.md b/.productization_next_steps.md index d980328..38581d9 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -680,7 +680,7 @@ Acceptance criteria: * Tests cover pass/fail examples. * Readiness report includes policy version. -#### [ ] EVY-042 — Add “customer-safe gaps” section +#### [x] EVY-042 — Add “customer-safe gaps” section Priority: P2 diff --git a/docs/reference/customer-package-manifest.md b/docs/reference/customer-package-manifest.md index 07a006b..7efd875 100644 --- a/docs/reference/customer-package-manifest.md +++ b/docs/reference/customer-package-manifest.md @@ -18,6 +18,7 @@ vulnerability result, or a secure-release guarantee. | `evidence_ids` | Included evidence metadata identifiers after redaction profile filtering. | | `artifact_digests` | Artifact IDs, names, media types, sizes, and digests linked to the release. | | `readiness_summary` | Deterministic readiness checks, gaps, and limitations. | +| `customer_safe_gaps` | Optional customer-visible gap records filtered through the package redaction profile. | | `verification_material` | Hash algorithm, canonicalization profile, release bundle hashes, and audit-chain summary. | | `limitations`, `non_claims` | Required package limitations and conservative product-language boundaries. | @@ -43,6 +44,15 @@ SSO/session token hashes, and tenant-internal vulnerability decision notes. Customer-visible vulnerability decisions require `impact_statement`; internal notes are not copied into `vulnerability_decisions`. +## Customer-Safe Gaps + +`customer_safe_gaps` contains factual missing-evidence records only when the +missing evidence type is allowed by the package redaction profile. For example, +an SBOM gap can appear in a `customer_safe` package because `sbom` is included, +while build-attestation or internal provenance gaps are omitted unless the +profile explicitly includes `build` or `build_attestation`. Internal-only gaps +remain outside the package manifest. + ## Presets `POST /v1/redaction-profiles` accepts either an explicit `allowed_types` list or diff --git a/internal/app/governance_packages.go b/internal/app/governance_packages.go index 8f4406c..446cf50 100644 --- a/internal/app/governance_packages.go +++ b/internal/app/governance_packages.go @@ -429,6 +429,9 @@ func (l *Ledger) customerPackageManifestLocked(packageID string, generatedAt tim "It is not legal compliance proof, certification, complete SBOM proof, an authoritative vulnerability result, regulator acceptance, or a secure-release guarantee.", }, } + if customerSafeGaps := packageCustomerSafeGaps(checks, profile); len(customerSafeGaps) > 0 { + manifest["customer_safe_gaps"] = customerSafeGaps + } if profileAllowsPackageType(profile, "sbom") { manifest["sboms"] = l.packageSBOMMetadataLocked(tenantID, releaseID) } @@ -845,6 +848,7 @@ func packageReadinessSummary(result string, checks []domain.PolicyCheck, gaps [] "severity": check.Severity, "missing": append([]string(nil), check.Missing...), "explanation": check.Explanation, + "remediation": check.Remediation, }) } return map[string]any{ @@ -858,6 +862,60 @@ func packageReadinessSummary(result string, checks []domain.PolicyCheck, gaps [] } } +func packageCustomerSafeGaps(checks []domain.PolicyCheck, profile domain.RedactionProfile) []map[string]any { + out := []map[string]any{} + for _, check := range checks { + if check.Result == "passed" { + continue + } + for _, missing := range check.Missing { + if !packageGapVisibleForProfile(missing, profile) { + continue + } + out = append(out, map[string]any{ + "id": "gap_" + check.Name + "_" + missing, + "category": "missing_evidence", + "evidence_type": missing, + "source_check": check.Name, + "severity": check.Severity, + "summary": check.Explanation, + "remediation": check.Remediation, + "customer_visible": true, + "limitations": []string{ + "Gap is based only on evidence metadata included by this package redaction profile.", + }, + }) + } + } + sort.Slice(out, func(i, j int) bool { + left, _ := out[i]["id"].(string) + right, _ := out[j]["id"].(string) + return left < right + }) + return out +} + +func packageGapVisibleForProfile(missing string, profile domain.RedactionProfile) bool { + switch strings.TrimSpace(missing) { + case "artifact", "artifact_digest": + return profileAllowsPackageType(profile, "artifact") + case "sbom": + return profileAllowsPackageType(profile, "sbom") + case "vulnerability_scan": + return profileAllowsPackageType(profile, "vulnerability_scan") + case "vulnerability_decision": + return profileAllowsPackageType(profile, "vulnerability_decision") + case "signed_release_bundle": + return profileAllowsPackageType(profile, "release_bundle") + case "passed_build": + return profileAllowsPackageType(profile, "build") + case "build_attestation": + return profileAllowsPackageType(profile, "build_attestation") + default: + return false + } +} + func (l *Ledger) packageVerificationMaterialLocked(tenantID, releaseID string) map[string]any { bundles := []map[string]any{} for _, bundle := range l.bundles { diff --git a/internal/app/governance_packages_test.go b/internal/app/governance_packages_test.go index 3991edc..48081ed 100644 --- a/internal/app/governance_packages_test.go +++ b/internal/app/governance_packages_test.go @@ -287,6 +287,43 @@ func TestRedactionProfilePresetsAreExplicitAndSafe(t *testing.T) { } } +func TestCustomerPackageGapsRespectRedactionProfile(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, release, _ := setupReleaseRiskFixture(t, ledger) + customerSafe, err := ledger.CreateRedactionProfile(ctx, actor, CreateRedactionProfileInput{Preset: "customer_safe"}) + if err != nil { + t.Fatalf("customer-safe profile: %v", err) + } + pkg, err := ledger.CreateCustomerSecurityPackage(ctx, actor, CreateCustomerPackageInput{ProductID: release.ProductID, ReleaseID: release.ID, RedactionProfileID: customerSafe.ID, Title: "Gap package", ExpiresAt: fixedNow().Add(time.Hour)}) + if err != nil { + t.Fatalf("customer-safe package: %v", err) + } + body, err := json.Marshal(pkg.Manifest) + if err != nil { + t.Fatalf("marshal package: %v", err) + } + text := string(body) + if !strings.Contains(text, `"customer_safe_gaps"`) || !strings.Contains(text, `"evidence_type":"sbom"`) || !strings.Contains(text, `"customer_visible":true`) { + t.Fatalf("customer-safe gaps missing: %s", text) + } + internalOnly, err := ledger.CreateRedactionProfile(ctx, actor, CreateRedactionProfileInput{Name: "decision-only", AllowedTypes: []string{"vulnerability_decision"}}) + if err != nil { + t.Fatalf("decision-only profile: %v", err) + } + internalPkg, err := ledger.CreateCustomerSecurityPackage(ctx, actor, CreateCustomerPackageInput{ProductID: release.ProductID, ReleaseID: release.ID, RedactionProfileID: internalOnly.ID, Title: "Decision-only package", ExpiresAt: fixedNow().Add(time.Hour)}) + if err != nil { + t.Fatalf("decision-only package: %v", err) + } + body, err = json.Marshal(internalPkg.Manifest) + if err != nil { + t.Fatalf("marshal decision-only package: %v", err) + } + if strings.Contains(string(body), `"customer_safe_gaps"`) || strings.Contains(string(body), `"evidence_type":"sbom"`) { + t.Fatalf("internal-only profile leaked excluded gaps: %s", body) + } +} + func packageArchiveFiles(t *testing.T, body []byte) map[string]string { t.Helper() reader, err := zip.NewReader(bytes.NewReader(body), int64(len(body))) diff --git a/site/package-viewer/index.html b/site/package-viewer/index.html index 801d458..835b221 100644 --- a/site/package-viewer/index.html +++ b/site/package-viewer/index.html @@ -642,6 +642,13 @@

Evydence Package Viewer

const gaps = safeArray(summary.gaps); appendText(nodes.readiness, "h3", "", "Gaps"); tagList(nodes.readiness, gaps); + appendText(nodes.readiness, "h3", "", "Customer-safe gaps"); + table(nodes.readiness, [ + { label: "Evidence", value: "evidence_type" }, + { label: "Severity", value: "severity", badge: true }, + { label: "Summary", value: "summary" }, + { label: "Remediation", value: "remediation" } + ], data.customer_safe_gaps, "No customer-safe package gaps are present."); }; const renderContents = (data) => { From 13eaa986147d7f56aac8d34ee44909d90b4a710d Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:32:14 +0300 Subject: [PATCH 190/287] docs(ci): add github actions quickstart --- .productization_next_steps.md | 2 +- Makefile | 5 + README.md | 4 + docs/README.md | 5 +- .../quickstart-release-evidence.yml | 110 ++++++++++++++++++ docs/how-to/integrate-ci.md | 43 +++++-- 6 files changed, 154 insertions(+), 15 deletions(-) create mode 100644 docs/github-actions/quickstart-release-evidence.yml diff --git a/.productization_next_steps.md b/.productization_next_steps.md index 38581d9..f550ff4 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -705,7 +705,7 @@ Goal: Backlog: -#### [ ] EVY-050 — Create GitHub Actions quickstart workflow +#### [x] EVY-050 — Create GitHub Actions quickstart workflow Priority: P0 diff --git a/Makefile b/Makefile index c132a05..f3f924b 100644 --- a/Makefile +++ b/Makefile @@ -152,6 +152,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @test -f docs/explanation/trust-model.md @test -f docs/collectors/source-snapshots.md @test -f docs/collectors/supply-chain.md + @test -f docs/github-actions/quickstart-release-evidence.yml @test -f docs/github-actions/release-evidence-workflow.yml @test -f docs/github-actions/upload-build/action.yml @test -f docs/gitlab/evydence-release-evidence.gitlab-ci.yml @@ -189,6 +190,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod "reference/release-validation.md" \ "collectors/source-snapshots.md" \ "collectors/supply-chain.md" \ + "github-actions/quickstart-release-evidence.yml" \ "github-actions/release-evidence-workflow.yml" \ "github-actions/upload-build/action.yml" \ "gitlab/evydence-release-evidence.gitlab-ci.yml" \ @@ -219,6 +221,9 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'package-viewer-preview.svg' docs/how-to/view-packages.md >/dev/null @grep -F 'v0.1.0-rc.4 - 2026-05-31' CHANGELOG.md >/dev/null @grep -F 'make restore-rehearsal-check' docs/runbooks/backup-restore.md >/dev/null + @grep -F 'dist/evydence github-actions upload-build' docs/github-actions/quickstart-release-evidence.yml >/dev/null + @grep -F 'scripts/github_release_evidence_manifest.py' docs/github-actions/quickstart-release-evidence.yml >/dev/null + @grep -F '/v1/reports/release-readiness' docs/github-actions/quickstart-release-evidence.yml >/dev/null @grep -F 'dist/evydence github-actions upload-build' docs/github-actions/release-evidence-workflow.yml >/dev/null @grep -F 'go run ./cmd/evydence "$${args[@]}"' docs/github-actions/upload-build/action.yml >/dev/null @grep -F 'cat > evydence-upload-manifest.json' docs/gitlab/evydence-release-evidence.gitlab-ci.yml >/dev/null diff --git a/README.md b/README.md index 0a02b45..7b5369c 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,10 @@ For durable local evaluation, run the production-like Compose rehearsal in [Install and operate](docs/how-to/install-and-operate.md). For the release-evidence path to inspect first, use the [end-to-end release evidence example](examples/end-to-end-release-evidence/README.md). +For the first CI wiring example, start with the +[GitHub Actions quickstart release evidence workflow](docs/github-actions/quickstart-release-evidence.yml), +then move to the scanner-oriented workflow once your runner has pinned scanner +versions. For concrete JSON outputs to inspect without running a full stack, open the sample readiness report, [customer-package manifest](examples/end-to-end-release-evidence/sample-customer-package-manifest.json), diff --git a/docs/README.md b/docs/README.md index 5137b98..5a415d7 100644 --- a/docs/README.md +++ b/docs/README.md @@ -11,7 +11,7 @@ This documentation is organized by reader task. Implementation claims should be ## How-To Guides -- [Integrate CI collectors](how-to/integrate-ci.md): connect GitHub Actions, the composite upload action, GitLab CI, source snapshots, and collector supply-chain records. +- [Integrate CI collectors](how-to/integrate-ci.md): connect the GitHub Actions quickstart, the scanner workflow, the composite upload action, GitLab CI, source snapshots, and collector supply-chain records. - [Kubernetes deployment](kubernetes.md): install the Helm chart and verify a self-hosted cluster deployment. - [Air-gapped installation](air-gapped.md): build, sign, transfer, verify, and import an offline package. - [Release signing](release-signing.md): create and verify local release artifact manifests. @@ -62,7 +62,8 @@ This documentation is organized by reader task. Implementation claims should be ## Workflow Examples -- [GitHub Actions release evidence workflow](github-actions/release-evidence-workflow.yml) +- [GitHub Actions quickstart release evidence workflow](github-actions/quickstart-release-evidence.yml) +- [GitHub Actions scanner release evidence workflow](github-actions/release-evidence-workflow.yml) - [GitHub Actions upload-build composite action](github-actions/upload-build/action.yml) - [GitHub release evidence manifest generator](../scripts/github_release_evidence_manifest.py) - [GitLab release evidence CI template](gitlab/evydence-release-evidence.gitlab-ci.yml) diff --git a/docs/github-actions/quickstart-release-evidence.yml b/docs/github-actions/quickstart-release-evidence.yml new file mode 100644 index 0000000..415decd --- /dev/null +++ b/docs/github-actions/quickstart-release-evidence.yml @@ -0,0 +1,110 @@ +name: evydence-quickstart-release-evidence + +on: + workflow_dispatch: + +jobs: + evydence-release-evidence: + runs-on: ubuntu-latest + permissions: + contents: read + env: + EVYDENCE_API_URL: ${{ secrets.EVYDENCE_API_URL }} + EVYDENCE_API_KEY: ${{ secrets.EVYDENCE_API_KEY }} + EVYDENCE_PROJECT_ID: ${{ vars.EVYDENCE_PROJECT_ID }} + EVYDENCE_RELEASE_ID: ${{ vars.EVYDENCE_RELEASE_ID }} + EVYDENCE_ARTIFACT_ID: ${{ vars.EVYDENCE_ARTIFACT_ID }} + EVYDENCE_OPENVEX_PATH: ${{ vars.EVYDENCE_OPENVEX_PATH }} + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version-file: go.mod + + - name: Build CLI artifact + run: | + set -euo pipefail + mkdir -p dist .evydence + go build -o dist/evydence ./cmd/evydence + + - id: artifact + name: Compute artifact digest + run: | + set -euo pipefail + dist/evydence hash dist/evydence > .evydence/artifact.digest + printf 'digest=%s\n' "$(cat .evydence/artifact.digest)" >> "$GITHUB_OUTPUT" + + - name: Write quickstart SBOM and vulnerability scan evidence + run: | + set -euo pipefail + cat > .evydence/sbom.cdx.json < .evydence/grype.json < Date: Sun, 31 May 2026 22:34:03 +0300 Subject: [PATCH 191/287] feat(cli): add one-shot release evidence upload --- .productization_next_steps.md | 2 +- Makefile | 2 + README.md | 2 +- cmd/evydence/main.go | 359 +++++++++++++++++++++++++++++++++- cmd/evydence/main_test.go | 166 ++++++++++++++++ docs/how-to/integrate-ci.md | 50 +++++ 6 files changed, 578 insertions(+), 3 deletions(-) diff --git a/.productization_next_steps.md b/.productization_next_steps.md index f550ff4..45993f9 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -729,7 +729,7 @@ Acceptance criteria: * Produces output visible in release bundle/readiness report. * README points to this as the first CI example. -#### [ ] EVY-051 — Add CLI command for one-shot release evidence upload +#### [x] EVY-051 — Add CLI command for one-shot release evidence upload Priority: P1 diff --git a/Makefile b/Makefile index f3f924b..503251c 100644 --- a/Makefile +++ b/Makefile @@ -221,6 +221,8 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'package-viewer-preview.svg' docs/how-to/view-packages.md >/dev/null @grep -F 'v0.1.0-rc.4 - 2026-05-31' CHANGELOG.md >/dev/null @grep -F 'make restore-rehearsal-check' docs/runbooks/backup-restore.md >/dev/null + @grep -F 'release upload-evidence' docs/how-to/integrate-ci.md >/dev/null + @grep -F -- '--dry-run' docs/how-to/integrate-ci.md >/dev/null @grep -F 'dist/evydence github-actions upload-build' docs/github-actions/quickstart-release-evidence.yml >/dev/null @grep -F 'scripts/github_release_evidence_manifest.py' docs/github-actions/quickstart-release-evidence.yml >/dev/null @grep -F '/v1/reports/release-readiness' docs/github-actions/quickstart-release-evidence.yml >/dev/null diff --git a/README.md b/README.md index 7b5369c..205a44f 100644 --- a/README.md +++ b/README.md @@ -162,7 +162,7 @@ non-sensitive sample data and does not upload files. ### Tooling, Deployment, And Examples -- `cmd/evydence` helper for hashing, manifest verification, GitHub Actions build provenance upload, release artifact manifest signing/verification, bulk upload manifests, and air-gapped evidence bundle import. +- `cmd/evydence` helper for hashing, one-shot release evidence upload, manifest verification, GitHub Actions build provenance upload, release artifact manifest signing/verification, bulk upload manifests, and air-gapped evidence bundle import. - Docker Compose dependencies for PostgreSQL and MinIO. - Production-like Docker Compose rehearsal with API, worker, migrations, PostgreSQL, and MinIO. diff --git a/cmd/evydence/main.go b/cmd/evydence/main.go index 6da51c8..dfec805 100644 --- a/cmd/evydence/main.go +++ b/cmd/evydence/main.go @@ -84,6 +84,8 @@ func run(args []string) error { return usage() } switch args[1] { + case "upload-evidence": + return uploadReleaseEvidence(context.Background(), http.DefaultClient, args[2:]) case "manifest": return createReleaseArtifactManifest(args[2:]) case "sign": @@ -101,7 +103,7 @@ func run(args []string) error { } func usage() error { - return errors.New("usage: evydence hash | evydence verify-manifest --hash sha256: | evydence verify-evidence-bundle | evydence verify-audit-chain | evydence package verify ... | evydence github-actions upload-build ... | evydence import-bundle upload ... | evydence upload manifest ... | evydence release manifest|sign|verify|keygen") + return errors.New("usage: evydence hash | evydence verify-manifest --hash sha256: | evydence verify-evidence-bundle | evydence verify-audit-chain | evydence package verify ... | evydence github-actions upload-build ... | evydence import-bundle upload ... | evydence upload manifest ... | evydence release upload-evidence|manifest|sign|verify|keygen") } func hashFile(path string) (string, error) { @@ -838,6 +840,15 @@ func stringInSlice(values []string, expected string) bool { return false } +func firstNonEmpty(values ...string) string { + for _, value := range values { + if trimmed := strings.TrimSpace(value); trimmed != "" { + return trimmed + } + } + return "" +} + func cleanOperatorPath(path string) (string, error) { path = strings.TrimSpace(path) if path == "" { @@ -1061,6 +1072,352 @@ func uploadManifestRequests(ctx context.Context, client *http.Client, args []str return nil } +type releaseUploadConfig struct { + APIURL string + APIKey string + ProductID string + ProductName string + ProductSlug string + CreateProduct bool + ReleaseID string + ReleaseVersion string + CreateRelease bool + ArtifactID string + ArtifactPath string + ArtifactName string + ArtifactMediaType string + CreateArtifact bool + SBOMPath string + ScanPath string + ScanScanner string + TargetRef string + VEXPath string + CreateBundle bool + DryRun bool + IdempotencyPrefix string +} + +func uploadReleaseEvidence(ctx context.Context, client *http.Client, args []string) error { + cfg, err := parseReleaseUploadConfig(args) + if err != nil { + return err + } + artifact, err := releaseUploadArtifactMetadata(cfg.ArtifactPath, cfg.ArtifactName, cfg.ArtifactMediaType) + if err != nil { + return err + } + sbomPayload, err := readOptionalJSONPayload(cfg.SBOMPath, "SBOM") + if err != nil { + return err + } + scanPayload, err := readOptionalJSONPayload(cfg.ScanPath, "vulnerability scan") + if err != nil { + return err + } + vexPayload, err := readOptionalJSONPayload(cfg.VEXPath, "VEX") + if err != nil { + return err + } + if len(sbomPayload) == 0 && len(scanPayload) == 0 && len(vexPayload) == 0 && !cfg.CreateBundle { + return errors.New("provide at least one evidence file or leave --create-bundle enabled") + } + if cfg.ArtifactPath != "" && cfg.ArtifactID == "" && !cfg.CreateArtifact { + return errors.New("--artifact-id is required when --artifact is supplied unless --create-artifact is set") + } + if cfg.ReleaseID == "" && !cfg.CreateRelease { + return errors.New("--release-id is required unless --create-release is set") + } + if cfg.ProductID == "" && (cfg.CreateRelease || cfg.CreateProduct) && !cfg.CreateProduct { + return errors.New("--product-id is required unless --create-product is set") + } + if cfg.CreateProduct && (cfg.ProductName == "" || cfg.ProductSlug == "") { + return errors.New("--product-name and --product-slug are required with --create-product") + } + if cfg.CreateRelease && cfg.ReleaseVersion == "" { + return errors.New("--release-version is required with --create-release") + } + if cfg.CreateArtifact && cfg.ArtifactPath == "" { + return errors.New("--artifact is required with --create-artifact") + } + if !cfg.DryRun && (cfg.APIURL == "" || cfg.APIKey == "") { + return usage() + } + if cfg.IdempotencyPrefix == "" { + cfg.IdempotencyPrefix = releaseUploadIdempotencyPrefix(cfg, artifact, sbomPayload, scanPayload, vexPayload) + } + productID := cfg.ProductID + if cfg.CreateProduct { + id, err := postReleaseUploadJSON(ctx, client, cfg, "/v1/products", cfg.IdempotencyPrefix+"-product", map[string]any{ + "name": cfg.ProductName, + "slug": cfg.ProductSlug, + }, "") + if err != nil { + return err + } + productID = id + } + releaseID := cfg.ReleaseID + if cfg.CreateRelease { + if productID == "" { + return errors.New("product id is required before creating a release") + } + id, err := postReleaseUploadJSON(ctx, client, cfg, "/v1/releases", cfg.IdempotencyPrefix+"-release", map[string]any{ + "product_id": productID, + "version": cfg.ReleaseVersion, + }, "") + if err != nil { + return err + } + releaseID = id + } + if releaseID == "" { + return errors.New("release id is required") + } + artifactID := cfg.ArtifactID + if cfg.CreateArtifact { + id, err := postReleaseUploadJSON(ctx, client, cfg, "/v1/artifacts", cfg.IdempotencyPrefix+"-artifact", map[string]any{ + "name": artifact.Name, + "media_type": artifact.MediaType, + "digest": artifact.Digest, + "size": artifact.Size, + }, "") + if err != nil { + return err + } + artifactID = id + } + if len(sbomPayload) > 0 { + if _, err := postReleaseUploadJSON(ctx, client, cfg, "/v1/sboms", cfg.IdempotencyPrefix+"-sbom", map[string]any{ + "release_id": releaseID, + "artifact_id": artifactID, + "payload": json.RawMessage(sbomPayload), + }, ""); err != nil { + return err + } + } + if len(scanPayload) > 0 { + payload, err := buildReleaseUploadScanPayload(scanPayload, releaseID, cfg.TargetRef, cfg.ScanScanner, artifact) + if err != nil { + return err + } + if _, err := postReleaseUploadRaw(ctx, client, cfg, "/v1/vulnerability-scans", cfg.IdempotencyPrefix+"-scan", payload, ""); err != nil { + return err + } + } + if len(vexPayload) > 0 { + if _, err := postReleaseUploadJSON(ctx, client, cfg, "/v1/vex", cfg.IdempotencyPrefix+"-vex", map[string]any{ + "release_id": releaseID, + "artifact_id": artifactID, + "payload": json.RawMessage(vexPayload), + }, ""); err != nil { + return err + } + } + if cfg.CreateBundle { + if _, err := postReleaseUploadJSON(ctx, client, cfg, "/v1/release-bundles", cfg.IdempotencyPrefix+"-release-bundle", map[string]any{ + "release_id": releaseID, + }, ""); err != nil { + return err + } + } + printReleaseUploadNextSteps(cfg.APIURL, releaseID) + return nil +} + +func parseReleaseUploadConfig(args []string) (releaseUploadConfig, error) { + fs := flag.NewFlagSet("release upload-evidence", flag.ContinueOnError) + fs.SetOutput(io.Discard) + cfg := releaseUploadConfig{CreateBundle: true, ArtifactMediaType: "application/octet-stream", ScanScanner: "generic"} + productAlias := "" + releaseAlias := "" + fs.StringVar(&cfg.APIURL, "url", strings.TrimSpace(os.Getenv("EVYDENCE_API_URL")), "Evydence API URL") + fs.StringVar(&cfg.APIKey, "api-key", strings.TrimSpace(os.Getenv("EVYDENCE_API_KEY")), "Evydence API key") + fs.StringVar(&cfg.ProductID, "product-id", "", "existing product id") + fs.StringVar(&productAlias, "product", "", "existing product id alias") + fs.StringVar(&cfg.ProductName, "product-name", "", "product name used with --create-product") + fs.StringVar(&cfg.ProductSlug, "product-slug", "", "product slug used with --create-product") + fs.BoolVar(&cfg.CreateProduct, "create-product", false, "create product before uploading evidence") + fs.StringVar(&cfg.ReleaseID, "release-id", "", "existing release id") + fs.StringVar(&releaseAlias, "release", "", "existing release id alias") + fs.StringVar(&cfg.ReleaseVersion, "release-version", "", "release version used with --create-release") + fs.BoolVar(&cfg.CreateRelease, "create-release", false, "create release before uploading evidence") + fs.StringVar(&cfg.ArtifactID, "artifact-id", "", "existing artifact id") + fs.StringVar(&cfg.ArtifactPath, "artifact", "", "artifact file path used for digest and optional registration") + fs.StringVar(&cfg.ArtifactName, "artifact-name", "", "artifact name; defaults to artifact file basename") + fs.StringVar(&cfg.ArtifactMediaType, "artifact-media-type", "application/octet-stream", "artifact media type used with --create-artifact") + fs.BoolVar(&cfg.CreateArtifact, "create-artifact", false, "register artifact before uploading evidence") + fs.StringVar(&cfg.SBOMPath, "sbom", "", "CycloneDX SBOM JSON path") + fs.StringVar(&cfg.ScanPath, "scan", "", "Evydence generic vulnerability scan JSON path") + fs.StringVar(&cfg.ScanScanner, "scan-scanner", "generic", "scanner name to use when the scan JSON omits scanner") + fs.StringVar(&cfg.TargetRef, "target-ref", "", "scan target reference; defaults to artifact digest when available") + fs.StringVar(&cfg.VEXPath, "vex", "", "OpenVEX JSON path") + fs.BoolVar(&cfg.CreateBundle, "create-bundle", true, "create a release bundle after uploads") + fs.BoolVar(&cfg.DryRun, "dry-run", false, "validate inputs and print planned requests without network calls") + fs.StringVar(&cfg.IdempotencyPrefix, "idempotency-prefix", "", "stable idempotency prefix") + if err := fs.Parse(args); err != nil { + return releaseUploadConfig{}, usage() + } + if fs.NArg() != 0 { + return releaseUploadConfig{}, usage() + } + cfg.APIURL = strings.TrimSpace(cfg.APIURL) + cfg.APIKey = strings.TrimSpace(cfg.APIKey) + cfg.ProductID = firstNonEmpty(cfg.ProductID, productAlias) + cfg.ReleaseID = firstNonEmpty(cfg.ReleaseID, releaseAlias) + cfg.ProductName = strings.TrimSpace(cfg.ProductName) + cfg.ProductSlug = strings.TrimSpace(cfg.ProductSlug) + cfg.ReleaseVersion = strings.TrimSpace(cfg.ReleaseVersion) + cfg.ArtifactID = strings.TrimSpace(cfg.ArtifactID) + cfg.ArtifactName = strings.TrimSpace(cfg.ArtifactName) + cfg.ArtifactMediaType = firstNonEmpty(cfg.ArtifactMediaType, "application/octet-stream") + cfg.ScanScanner = firstNonEmpty(cfg.ScanScanner, "generic") + cfg.TargetRef = strings.TrimSpace(cfg.TargetRef) + cfg.IdempotencyPrefix = strings.TrimSpace(cfg.IdempotencyPrefix) + return cfg, nil +} + +type releaseUploadArtifact struct { + Name string + MediaType string + Digest string + Size int64 +} + +func releaseUploadArtifactMetadata(path, name, mediaType string) (releaseUploadArtifact, error) { + if strings.TrimSpace(path) == "" { + return releaseUploadArtifact{Name: strings.TrimSpace(name), MediaType: firstNonEmpty(mediaType, "application/octet-stream")}, nil + } + cleaned, err := cleanOperatorPath(path) + if err != nil { + return releaseUploadArtifact{}, err + } + info, err := os.Stat(cleaned) + if err != nil { + return releaseUploadArtifact{}, err + } + if info.IsDir() { + return releaseUploadArtifact{}, errors.New("--artifact must point to a file") + } + digest, err := hashFile(cleaned) + if err != nil { + return releaseUploadArtifact{}, err + } + if strings.TrimSpace(name) == "" { + name = filepath.Base(cleaned) + } + return releaseUploadArtifact{Name: strings.TrimSpace(name), MediaType: firstNonEmpty(mediaType, "application/octet-stream"), Digest: digest, Size: info.Size()}, nil +} + +func readOptionalJSONPayload(path, label string) (json.RawMessage, error) { + if strings.TrimSpace(path) == "" { + return nil, nil + } + body, err := readFileStrict(path) + if err != nil { + return nil, err + } + if len(body) > 20<<20 { + return nil, fmt.Errorf("%s payload exceeds 20 MiB", label) + } + var normalized any + dec := json.NewDecoder(bytes.NewReader(body)) + dec.DisallowUnknownFields() + if err := dec.Decode(&normalized); err != nil { + return nil, fmt.Errorf("%s payload is not valid JSON", label) + } + if err := dec.Decode(&struct{}{}); err != io.EOF { + return nil, fmt.Errorf("%s payload must contain one JSON document", label) + } + canonical, err := json.Marshal(normalized) + if err != nil { + return nil, err + } + return canonical, nil +} + +func buildReleaseUploadScanPayload(raw json.RawMessage, releaseID, targetRef, scanner string, artifact releaseUploadArtifact) ([]byte, error) { + var doc struct { + Scanner string `json:"scanner"` + TargetRef string `json:"target_ref"` + ReleaseID string `json:"release_id"` + Findings []struct { + Vulnerability string `json:"vulnerability"` + Component string `json:"component"` + Severity string `json:"severity"` + State string `json:"state"` + } `json:"findings"` + } + dec := json.NewDecoder(bytes.NewReader(raw)) + dec.DisallowUnknownFields() + if err := dec.Decode(&doc); err != nil { + return nil, errors.New("scan payload must use Evydence generic vulnerability scan JSON") + } + doc.Scanner = firstNonEmpty(doc.Scanner, scanner) + doc.TargetRef = firstNonEmpty(doc.TargetRef, targetRef) + if doc.TargetRef == "" && artifact.Digest != "" { + doc.TargetRef = "artifact-digest:" + artifact.Digest + } + doc.ReleaseID = releaseID + if strings.TrimSpace(doc.Scanner) == "" || strings.TrimSpace(doc.TargetRef) == "" { + return nil, errors.New("scan payload requires scanner and target_ref; use --scan-scanner and --target-ref when the file omits them") + } + if doc.Findings == nil { + return nil, errors.New("scan payload requires findings") + } + body, err := json.Marshal(doc) + if err != nil { + return nil, err + } + return body, nil +} + +func releaseUploadIdempotencyPrefix(cfg releaseUploadConfig, artifact releaseUploadArtifact, sbom, scan, vex json.RawMessage) string { + parts := []string{ + cfg.ProductID, cfg.ProductName, cfg.ProductSlug, + cfg.ReleaseID, cfg.ReleaseVersion, + cfg.ArtifactID, artifact.Name, artifact.Digest, + hashBytes(sbom), hashBytes(scan), hashBytes(vex), + } + sum := sha256.Sum256([]byte(strings.Join(parts, "\x00"))) + return "release-evidence-" + hex.EncodeToString(sum[:8]) +} + +func postReleaseUploadJSON(ctx context.Context, client *http.Client, cfg releaseUploadConfig, path, idem string, payload any, placeholderID string) (string, error) { + body, err := json.Marshal(payload) + if err != nil { + return "", err + } + return postReleaseUploadRaw(ctx, client, cfg, path, idem, body, placeholderID) +} + +func postReleaseUploadRaw(ctx context.Context, client *http.Client, cfg releaseUploadConfig, path, idem string, body []byte, placeholderID string) (string, error) { + if cfg.DryRun { + fmt.Printf("dry-run: would POST %s idempotency=%s payload_hash=%s\n", path, idem, hashBytes(body)) + return placeholderID, nil + } + response, err := postRawEvydence(ctx, client, cfg.APIURL, cfg.APIKey, path, idem, body) + if err != nil { + return "", err + } + id, err := responseDataID(response) + if err != nil { + return "", err + } + fmt.Println("uploaded " + path + ": " + id) + return id, nil +} + +func printReleaseUploadNextSteps(apiURL, releaseID string) { + reference := "/v1/reports/release-readiness?release_id=" + releaseID + if strings.TrimSpace(apiURL) != "" { + if base, err := cleanAPIURL(apiURL); err == nil { + reference = base + "/v1/reports/release-readiness?release_id=" + url.QueryEscape(releaseID) + } + } + fmt.Println("next: read release readiness at " + reference) + fmt.Println("next: verify release bundle with GET /v1/release-bundles/{id}/verify after bundle creation") +} + func createReleaseArtifactManifest(args []string) error { fs := flag.NewFlagSet("release manifest", flag.ContinueOnError) fs.SetOutput(io.Discard) diff --git a/cmd/evydence/main_test.go b/cmd/evydence/main_test.go index 312933c..93ce59e 100644 --- a/cmd/evydence/main_test.go +++ b/cmd/evydence/main_test.go @@ -8,6 +8,7 @@ import ( "encoding/base64" "encoding/hex" "encoding/json" + "io" "net/http" "net/http/httptest" "os" @@ -343,6 +344,140 @@ func TestGitHubActionsUploadBuildPostsBuildAndAttestationSafely(t *testing.T) { } } +func TestReleaseUploadEvidenceDryRunValidatesFilesAndPrintsNextSteps(t *testing.T) { + dir := t.TempDir() + artifactPath := writeTestFile(t, dir+"/api.tar.gz", []byte("artifact")) + sbomPath := writeTestFile(t, dir+"/sbom.json", []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","components":[{"name":"api","purl":"pkg:github/acme/api@abc"}]}`)) + scanPath := writeTestFile(t, dir+"/scan.json", []byte(`{"findings":[]}`)) + vexPath := writeTestFile(t, dir+"/vex.json", []byte(`{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex","author":"security@example.test","timestamp":"2026-05-27T12:00:00Z","version":1,"statements":[{"vulnerability":{"name":"CVE-2026-0001"},"products":[{"@id":"pkg:github/acme/api@abc"}],"status":"not_affected","justification":"component_not_present","impact_statement":"not shipped","action_statement":"none"}]}`)) + t.Setenv("EVYDENCE_API_KEY", "evy_secret_should_not_print") + + out, err := captureStdout(t, func() error { + return uploadReleaseEvidence(t.Context(), http.DefaultClient, []string{ + "--dry-run", + "--product-id", "prod_1", + "--release-id", "rel_1", + "--artifact-id", "art_1", + "--artifact", artifactPath, + "--sbom", sbomPath, + "--scan", scanPath, + "--scan-scanner", "generic", + "--target-ref", "pkg:github/acme/api@abc", + "--vex", vexPath, + }) + }) + if err != nil { + t.Fatalf("dry-run upload: %v", err) + } + for _, expected := range []string{"/v1/sboms", "/v1/vulnerability-scans", "/v1/vex", "/v1/release-bundles", "/v1/reports/release-readiness?release_id=rel_1"} { + if !strings.Contains(out, expected) { + t.Fatalf("dry-run output missing %q:\n%s", expected, out) + } + } + if strings.Contains(out, "evy_secret_should_not_print") { + t.Fatalf("dry-run output leaked API key: %s", out) + } +} + +func TestReleaseUploadEvidenceCreatesMissingResourcesAndUploads(t *testing.T) { + dir := t.TempDir() + artifactPath := writeTestFile(t, dir+"/api.tar.gz", []byte("artifact")) + sbomPath := writeTestFile(t, dir+"/sbom.json", []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","components":[{"name":"api","purl":"pkg:github/acme/api@abc"}]}`)) + scanPath := writeTestFile(t, dir+"/scan.json", []byte(`{"scanner":"generic","findings":[]}`)) + vexPath := writeTestFile(t, dir+"/vex.json", []byte(`{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex","author":"security@example.test","timestamp":"2026-05-27T12:00:00Z","version":1,"statements":[{"vulnerability":{"name":"CVE-2026-0001"},"products":[{"@id":"pkg:github/acme/api@abc"}],"status":"fixed","justification":"fixed","impact_statement":"patched","action_statement":"upgrade"}]}`)) + seen := []string{} + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if got := r.Header.Get("Authorization"); got != "Bearer evy_secret" { + t.Fatalf("authorization header=%q", got) + } + if !strings.HasPrefix(r.Header.Get("Idempotency-Key"), "one-shot-") { + t.Fatalf("idempotency key=%q", r.Header.Get("Idempotency-Key")) + } + seen = append(seen, r.URL.Path) + var payload map[string]any + if err := json.NewDecoder(r.Body).Decode(&payload); err != nil { + t.Fatalf("decode payload for %s: %v", r.URL.Path, err) + } + switch r.URL.Path { + case "/v1/products": + if payload["name"] != "Payments" || payload["slug"] != "payments" { + t.Fatalf("product payload=%#v", payload) + } + _, _ = w.Write([]byte(`{"data":{"id":"prod_1"},"meta":{"api_version":"v1"}}`)) + case "/v1/releases": + if payload["product_id"] != "prod_1" || payload["version"] != "1.0.0" { + t.Fatalf("release payload=%#v", payload) + } + _, _ = w.Write([]byte(`{"data":{"id":"rel_1"},"meta":{"api_version":"v1"}}`)) + case "/v1/artifacts": + if payload["name"] != "api.tar.gz" || !strings.HasPrefix(payload["digest"].(string), "sha256:") { + t.Fatalf("artifact payload=%#v", payload) + } + _, _ = w.Write([]byte(`{"data":{"id":"art_1"},"meta":{"api_version":"v1"}}`)) + case "/v1/sboms": + if payload["release_id"] != "rel_1" || payload["artifact_id"] != "art_1" { + t.Fatalf("sbom payload=%#v", payload) + } + _, _ = w.Write([]byte(`{"data":{"id":"sbom_1"},"meta":{"api_version":"v1"}}`)) + case "/v1/vulnerability-scans": + if payload["release_id"] != "rel_1" || payload["target_ref"] != "pkg:github/acme/api@abc" { + t.Fatalf("scan payload=%#v", payload) + } + _, _ = w.Write([]byte(`{"data":{"id":"scan_1"},"meta":{"api_version":"v1"}}`)) + case "/v1/vex": + if payload["release_id"] != "rel_1" || payload["artifact_id"] != "art_1" { + t.Fatalf("vex payload=%#v", payload) + } + _, _ = w.Write([]byte(`{"data":{"id":"vex_1"},"meta":{"api_version":"v1"}}`)) + case "/v1/release-bundles": + if payload["release_id"] != "rel_1" { + t.Fatalf("bundle payload=%#v", payload) + } + _, _ = w.Write([]byte(`{"data":{"id":"bundle_1"},"meta":{"api_version":"v1"}}`)) + default: + t.Fatalf("unexpected path %s", r.URL.Path) + } + })) + defer server.Close() + + if err := uploadReleaseEvidence(t.Context(), server.Client(), []string{ + "--url", server.URL, + "--api-key", "evy_secret", + "--create-product", + "--product-name", "Payments", + "--product-slug", "payments", + "--create-release", + "--release-version", "1.0.0", + "--create-artifact", + "--artifact", artifactPath, + "--sbom", sbomPath, + "--scan", scanPath, + "--target-ref", "pkg:github/acme/api@abc", + "--vex", vexPath, + "--idempotency-prefix", "one-shot", + }); err != nil { + t.Fatalf("upload evidence: %v", err) + } + want := []string{"/v1/products", "/v1/releases", "/v1/artifacts", "/v1/sboms", "/v1/vulnerability-scans", "/v1/vex", "/v1/release-bundles"} + if strings.Join(seen, ",") != strings.Join(want, ",") { + t.Fatalf("paths=%v want=%v", seen, want) + } +} + +func TestReleaseUploadEvidenceRequiresExplicitCreateFlags(t *testing.T) { + dir := t.TempDir() + sbomPath := writeTestFile(t, dir+"/sbom.json", []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","components":[{"name":"api"}]}`)) + err := uploadReleaseEvidence(t.Context(), http.DefaultClient, []string{"--dry-run", "--sbom", sbomPath}) + if err == nil || !strings.Contains(err.Error(), "--release-id") { + t.Fatalf("missing release err=%v", err) + } + artifactPath := writeTestFile(t, dir+"/api.tar.gz", []byte("artifact")) + err = uploadReleaseEvidence(t.Context(), http.DefaultClient, []string{"--dry-run", "--release-id", "rel_1", "--artifact", artifactPath, "--sbom", sbomPath}) + if err == nil || !strings.Contains(err.Error(), "--artifact-id") { + t.Fatalf("missing artifact err=%v", err) + } +} + func TestUsageRunAndManifestVerificationHelpers(t *testing.T) { if err := usage(); err == nil || !strings.Contains(err.Error(), "evydence hash") { t.Fatalf("usage err=%v", err) @@ -375,6 +510,37 @@ func TestUsageRunAndManifestVerificationHelpers(t *testing.T) { } } +func writeTestFile(t *testing.T, path string, body []byte) string { + t.Helper() + if err := os.WriteFile(path, body, 0o600); err != nil { + t.Fatalf("write %s: %v", path, err) + } + return path +} + +func captureStdout(t *testing.T, fn func() error) (string, error) { + t.Helper() + old := os.Stdout + reader, writer, err := os.Pipe() + if err != nil { + t.Fatalf("pipe: %v", err) + } + os.Stdout = writer + runErr := fn() + if err := writer.Close(); err != nil { + t.Fatalf("close writer: %v", err) + } + os.Stdout = old + out, err := io.ReadAll(reader) + if err != nil { + t.Fatalf("read stdout: %v", err) + } + if err := reader.Close(); err != nil { + t.Fatalf("close reader: %v", err) + } + return string(out), runErr +} + func TestGenerateReleaseSigningKeyWritesBase64Keys(t *testing.T) { dir := t.TempDir() privatePath := dir + "/private.key" diff --git a/docs/how-to/integrate-ci.md b/docs/how-to/integrate-ci.md index b71af06..c6466fd 100644 --- a/docs/how-to/integrate-ci.md +++ b/docs/how-to/integrate-ci.md @@ -61,6 +61,56 @@ and record GitHub OIDC metadata, grant `id-token: write` in the workflow and pas the value as evidence metadata; it does not request or verify a GitHub OIDC token. +## One-Shot CLI Upload + +For a local or CI path that already has files on disk, use the one-shot release +evidence uploader: + +```sh +go run ./cmd/evydence release upload-evidence \ + --url "$EVYDENCE_API_URL" \ + --api-key "$EVYDENCE_API_KEY" \ + --product-id "$EVYDENCE_PRODUCT_ID" \ + --release-id "$EVYDENCE_RELEASE_ID" \ + --artifact-id "$EVYDENCE_ARTIFACT_ID" \ + --artifact dist/api.tar.gz \ + --sbom .evydence/sbom.cdx.json \ + --scan .evydence/scan.evydence.json \ + --target-ref "pkg:github/${GITHUB_REPOSITORY}@${GITHUB_SHA}" \ + --vex .evydence/review.openvex.json +``` + +The command computes the artifact digest locally, validates JSON inputs, uploads +the SBOM, generic vulnerability scan, optional OpenVEX document, and release +bundle through existing `/v1` endpoints, then prints the release-readiness API +reference to check next. It never prints the API key. + +Use explicit create flags when the product, release, or artifact should be +created by the command: + +```sh +go run ./cmd/evydence release upload-evidence \ + --url "$EVYDENCE_API_URL" \ + --api-key "$EVYDENCE_API_KEY" \ + --create-product \ + --product-name "Payments API" \ + --product-slug payments-api \ + --create-release \ + --release-version 1.0.0 \ + --create-artifact \ + --artifact dist/api.tar.gz \ + --sbom .evydence/sbom.cdx.json \ + --scan .evydence/scan.evydence.json \ + --target-ref "pkg:github/acme/payments-api@${GITHUB_SHA}" \ + --idempotency-prefix "release-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" +``` + +Without the matching `--create-*` flag, missing product, release, or artifact +IDs fail before side effects. Add `--dry-run` to validate paths and JSON and +print planned requests without requiring an API URL or key. The `--scan` file is +Evydence generic vulnerability scan JSON with `findings`; use the full +scanner-oriented workflow when you need Grype or Trivy normalization. + The full workflow also shows a scanner handoff path: - produce CycloneDX JSON with `syft`; From 1b6ca83394c0f9e46071cf060eb46b7c742dd69f Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:35:23 +0300 Subject: [PATCH 192/287] feat(cli): formalize upload manifest validation --- .productization_next_steps.md | 2 +- Makefile | 7 + cmd/evydence/main.go | 220 ++++++++++++++---- cmd/evydence/main_test.go | 79 +++++++ docs/README.md | 1 + .../quickstart-release-evidence.yml | 2 + .../release-evidence-workflow.yml | 2 + .../evydence-release-evidence.gitlab-ci.yml | 1 + docs/how-to/integrate-ci.md | 10 + docs/reference/upload-manifest.md | 87 +++++++ schemas/upload-manifest.v1.schema.json | 78 +++++++ scripts/github_release_evidence_manifest.py | 18 +- 12 files changed, 457 insertions(+), 50 deletions(-) create mode 100644 docs/reference/upload-manifest.md create mode 100644 schemas/upload-manifest.v1.schema.json diff --git a/.productization_next_steps.md b/.productization_next_steps.md index 45993f9..04e48d5 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -748,7 +748,7 @@ Acceptance criteria: * Command supports dry-run. * Command has examples. -#### [ ] EVY-052 — Add manifest schema for bulk upload +#### [x] EVY-052 — Add manifest schema for bulk upload Priority: P1 diff --git a/Makefile b/Makefile index 503251c..dc27b1e 100644 --- a/Makefile +++ b/Makefile @@ -149,6 +149,8 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @test -f docs/reference/roadmap.md @test -f docs/reference/worker-outbox.md @test -f docs/reference/release-validation.md + @test -f docs/reference/upload-manifest.md + @test -f schemas/upload-manifest.v1.schema.json @test -f docs/explanation/trust-model.md @test -f docs/collectors/source-snapshots.md @test -f docs/collectors/supply-chain.md @@ -188,6 +190,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod "reference/roadmap.md" \ "reference/worker-outbox.md" \ "reference/release-validation.md" \ + "reference/upload-manifest.md" \ "collectors/source-snapshots.md" \ "collectors/supply-chain.md" \ "github-actions/quickstart-release-evidence.yml" \ @@ -223,13 +226,17 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'make restore-rehearsal-check' docs/runbooks/backup-restore.md >/dev/null @grep -F 'release upload-evidence' docs/how-to/integrate-ci.md >/dev/null @grep -F -- '--dry-run' docs/how-to/integrate-ci.md >/dev/null + @grep -F 'upload validate-manifest' docs/how-to/integrate-ci.md >/dev/null + @grep -F 'evydence-upload-manifest.v1.0.0' docs/reference/upload-manifest.md schemas/upload-manifest.v1.schema.json >/dev/null @grep -F 'dist/evydence github-actions upload-build' docs/github-actions/quickstart-release-evidence.yml >/dev/null + @grep -F 'upload validate-manifest' docs/github-actions/quickstart-release-evidence.yml >/dev/null @grep -F 'scripts/github_release_evidence_manifest.py' docs/github-actions/quickstart-release-evidence.yml >/dev/null @grep -F '/v1/reports/release-readiness' docs/github-actions/quickstart-release-evidence.yml >/dev/null @grep -F 'dist/evydence github-actions upload-build' docs/github-actions/release-evidence-workflow.yml >/dev/null @grep -F 'go run ./cmd/evydence "$${args[@]}"' docs/github-actions/upload-build/action.yml >/dev/null @grep -F 'cat > evydence-upload-manifest.json' docs/gitlab/evydence-release-evidence.gitlab-ci.yml >/dev/null @grep -F 'artifact.digest' docs/gitlab/evydence-release-evidence.gitlab-ci.yml >/dev/null + @grep -F 'upload validate-manifest' docs/gitlab/evydence-release-evidence.gitlab-ci.yml >/dev/null @grep -F -- '--manifest evydence-upload-manifest.json' docs/gitlab/evydence-release-evidence.gitlab-ci.yml >/dev/null @grep -F 'make production-check' .github/workflows/ci.yml >/dev/null @grep -F 'make production-check' .github/workflows/release-artifacts.yml >/dev/null diff --git a/cmd/evydence/main.go b/cmd/evydence/main.go index dfec805..c127c07 100644 --- a/cmd/evydence/main.go +++ b/cmd/evydence/main.go @@ -75,10 +75,17 @@ func run(args []string) error { } return uploadEvidenceBundleImport(context.Background(), http.DefaultClient, args[2:]) case "upload": - if len(args) < 2 || args[1] != "manifest" { + if len(args) < 2 { + return usage() + } + switch args[1] { + case "manifest": + return uploadManifestRequests(context.Background(), http.DefaultClient, args[2:]) + case "validate-manifest": + return validateUploadManifestCommand(args[2:]) + default: return usage() } - return uploadManifestRequests(context.Background(), http.DefaultClient, args[2:]) case "release": if len(args) < 2 { return usage() @@ -103,7 +110,7 @@ func run(args []string) error { } func usage() error { - return errors.New("usage: evydence hash | evydence verify-manifest --hash sha256: | evydence verify-evidence-bundle | evydence verify-audit-chain | evydence package verify ... | evydence github-actions upload-build ... | evydence import-bundle upload ... | evydence upload manifest ... | evydence release upload-evidence|manifest|sign|verify|keygen") + return errors.New("usage: evydence hash | evydence verify-manifest --hash sha256: | evydence verify-evidence-bundle | evydence verify-audit-chain | evydence package verify ... | evydence github-actions upload-build ... | evydence import-bundle upload ... | evydence upload manifest|validate-manifest ... | evydence release upload-evidence|manifest|sign|verify|keygen") } func hashFile(path string) (string, error) { @@ -1014,64 +1021,197 @@ func uploadManifestRequests(ctx context.Context, client *http.Client, args []str if strings.TrimSpace(*apiURL) == "" || strings.TrimSpace(*apiKey) == "" || strings.TrimSpace(*manifestPath) == "" { return usage() } - cleaned, err := cleanOperatorPath(*manifestPath) + manifest, err := readAndValidateUploadManifest(*manifestPath) if err != nil { return err } + for _, req := range manifest.Requests { + payload, err := req.PayloadBytes() + if err != nil { + return err + } + response, err := postRawEvydence(ctx, client, *apiURL, *apiKey, req.Path, req.IdempotencyKey, payload) + if err != nil { + return err + } + id, err := responseDataID(response) + if err != nil { + return err + } + fmt.Println("uploaded " + req.Path + ": " + id) + } + return nil +} + +func validateUploadManifestCommand(args []string) error { + fs := flag.NewFlagSet("upload validate-manifest", flag.ContinueOnError) + fs.SetOutput(io.Discard) + manifestPath := fs.String("manifest", "", "upload manifest JSON path") + if err := fs.Parse(args); err != nil { + return usage() + } + if strings.TrimSpace(*manifestPath) == "" || fs.NArg() != 0 { + return usage() + } + manifest, err := readAndValidateUploadManifest(*manifestPath) + if err != nil { + return err + } + fmt.Printf("upload manifest valid: %d requests\n", len(manifest.Requests)) + return nil +} + +const uploadManifestSchemaVersion = "evydence-upload-manifest.v1.0.0" + +type uploadManifestFile struct { + SchemaVersion string `json:"schema_version"` + Requests []uploadManifestRequest `json:"requests"` +} + +type uploadManifestRequest struct { + Kind string `json:"kind"` + Path string `json:"path"` + IdempotencyKey string `json:"idempotency_key"` + Payload json.RawMessage `json:"payload"` + PayloadFile string `json:"payload_file"` + payloadPath string +} + +func readAndValidateUploadManifest(path string) (uploadManifestFile, error) { + cleaned, err := cleanOperatorPath(path) + if err != nil { + return uploadManifestFile{}, err + } // #nosec G304,G703 -- this CLI command intentionally reads a local operator-specified upload manifest. body, err := os.ReadFile(cleaned) if err != nil { - return err + return uploadManifestFile{}, err } - var manifest struct { - Requests []struct { - Path string `json:"path"` - IdempotencyKey string `json:"idempotency_key"` - Payload json.RawMessage `json:"payload"` - PayloadFile string `json:"payload_file"` - } `json:"requests"` + var manifest uploadManifestFile + dec := json.NewDecoder(bytes.NewReader(body)) + dec.DisallowUnknownFields() + if err := dec.Decode(&manifest); err != nil { + return uploadManifestFile{}, errors.New("upload manifest is not valid JSON or contains unknown fields") } - if err := json.Unmarshal(body, &manifest); err != nil { - return errors.New("upload manifest is not valid JSON") + if err := dec.Decode(&struct{}{}); err != io.EOF { + return uploadManifestFile{}, errors.New("upload manifest must contain one JSON document") + } + if manifest.SchemaVersion != "" && manifest.SchemaVersion != uploadManifestSchemaVersion { + return uploadManifestFile{}, fmt.Errorf("upload manifest schema_version must be %s", uploadManifestSchemaVersion) } if len(manifest.Requests) == 0 || len(manifest.Requests) > 100 { - return errors.New("upload manifest must contain 1-100 requests") + return uploadManifestFile{}, errors.New("upload manifest must contain 1-100 requests") } baseDir := filepath.Dir(cleaned) - for i, req := range manifest.Requests { - path := strings.TrimSpace(req.Path) - idem := strings.TrimSpace(req.IdempotencyKey) - if !strings.HasPrefix(path, "/v1/") || idem == "" { - return fmt.Errorf("upload request %d missing /v1 path or idempotency key", i) - } - payload := req.Payload - if strings.TrimSpace(req.PayloadFile) != "" { - payloadPath, err := cleanOperatorPath(filepath.Join(baseDir, req.PayloadFile)) - if err != nil { - return err - } - // #nosec G304,G703 -- payload files are local operator-selected files referenced by the manifest. - payload, err = os.ReadFile(payloadPath) - if err != nil { - return err - } + for i := range manifest.Requests { + if err := manifest.Requests[i].Validate(i, baseDir); err != nil { + return uploadManifestFile{}, err } - if len(bytes.TrimSpace(payload)) == 0 { - return fmt.Errorf("upload request %d has empty payload", i) - } - response, err := postRawEvydence(ctx, client, *apiURL, *apiKey, path, idem, payload) + } + return manifest, nil +} + +func (r *uploadManifestRequest) Validate(index int, baseDir string) error { + r.Kind = strings.TrimSpace(r.Kind) + r.Path = strings.TrimSpace(r.Path) + r.IdempotencyKey = strings.TrimSpace(r.IdempotencyKey) + r.PayloadFile = strings.TrimSpace(r.PayloadFile) + if !strings.HasPrefix(r.Path, "/v1/") || r.IdempotencyKey == "" { + return fmt.Errorf("upload request %d missing /v1 path or idempotency key", index) + } + if r.Kind != "" && !uploadManifestKindAllowsPath(r.Kind, r.Path) { + return fmt.Errorf("upload request %d kind %q does not allow path %q", index, r.Kind, r.Path) + } + hasInlinePayload := len(bytes.TrimSpace(r.Payload)) > 0 + hasPayloadFile := r.PayloadFile != "" + if hasInlinePayload == hasPayloadFile { + return fmt.Errorf("upload request %d must set exactly one of payload or payload_file", index) + } + if hasInlinePayload && !json.Valid(r.Payload) { + return fmt.Errorf("upload request %d payload is not valid JSON", index) + } + if hasPayloadFile { + payloadPath, err := cleanManifestPayloadPath(baseDir, r.PayloadFile) if err != nil { - return err + return fmt.Errorf("upload request %d: %w", index, err) } - id, err := responseDataID(response) + r.payloadPath = payloadPath + // #nosec G304,G703 -- payload files are local operator-selected files constrained to the manifest directory. + payload, err := os.ReadFile(payloadPath) if err != nil { - return err + return fmt.Errorf("upload request %d payload_file cannot be read", index) + } + if len(bytes.TrimSpace(payload)) == 0 || !json.Valid(payload) { + return fmt.Errorf("upload request %d payload_file is not valid JSON", index) } - fmt.Println("uploaded " + path + ": " + id) } return nil } +func (r uploadManifestRequest) PayloadBytes() ([]byte, error) { + if r.payloadPath == "" { + return r.Payload, nil + } + // #nosec G304,G703 -- payload files were already validated and constrained to the manifest directory. + return os.ReadFile(r.payloadPath) +} + +func cleanManifestPayloadPath(baseDir, rel string) (string, error) { + rel = strings.TrimSpace(rel) + if rel == "" { + return "", errors.New("payload_file is required") + } + if strings.Contains(rel, "\x00") { + return "", errors.New("payload_file contains a NUL byte") + } + if filepath.IsAbs(rel) { + return "", errors.New("payload_file must be relative to the manifest directory") + } + cleanRel := filepath.Clean(rel) + if cleanRel == "." || cleanRel == ".." || strings.HasPrefix(cleanRel, ".."+string(filepath.Separator)) { + return "", errors.New("payload_file must stay inside the manifest directory") + } + baseEval, err := filepath.EvalSymlinks(baseDir) + if err != nil { + return "", errors.New("manifest directory cannot be resolved") + } + full := filepath.Join(baseEval, cleanRel) + fullEval, err := filepath.EvalSymlinks(full) + if err != nil { + return "", errors.New("payload_file cannot be resolved") + } + relative, err := filepath.Rel(baseEval, fullEval) + if err != nil || relative == ".." || strings.HasPrefix(relative, ".."+string(filepath.Separator)) { + return "", errors.New("payload_file must stay inside the manifest directory") + } + return fullEval, nil +} + +func uploadManifestKindAllowsPath(kind, path string) bool { + switch strings.TrimSpace(kind) { + case "artifact": + return path == "/v1/artifacts" + case "sbom": + return path == "/v1/sboms" || path == "/v1/sboms/spdx" + case "scan", "vulnerability_scan": + return path == "/v1/vulnerability-scans" + case "vex": + return path == "/v1/vex" || path == "/v1/vex/cyclonedx" + case "provenance", "build", "build_attestation": + return path == "/v1/builds" || strings.HasPrefix(path, "/v1/builds/") + case "approval": + return path == "/v1/approvals" || strings.HasPrefix(path, "/v1/releases/") + case "package_export", "customer_package": + return path == "/v1/customer-packages" + case "release_bundle": + return path == "/v1/release-bundles" + case "evidence": + return path == "/v1/evidence" + default: + return false + } +} + type releaseUploadConfig struct { APIURL string APIKey string diff --git a/cmd/evydence/main_test.go b/cmd/evydence/main_test.go index 93ce59e..041decf 100644 --- a/cmd/evydence/main_test.go +++ b/cmd/evydence/main_test.go @@ -78,6 +78,85 @@ func TestUploadManifestPostsRequests(t *testing.T) { } } +func TestValidateUploadManifestCommand(t *testing.T) { + dir := t.TempDir() + payloadPath := writeTestFile(t, dir+"/artifact.json", []byte(`{"name":"api","digest":"sha256:ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb","size":1}`)) + _ = payloadPath + manifestPath := dir + "/upload.json" + body, err := json.Marshal(map[string]any{ + "schema_version": uploadManifestSchemaVersion, + "requests": []map[string]any{{ + "kind": "artifact", + "path": "/v1/artifacts", + "idempotency_key": "artifact-1", + "payload_file": "artifact.json", + }}, + }) + if err != nil { + t.Fatalf("marshal manifest: %v", err) + } + if err := os.WriteFile(manifestPath, body, 0o600); err != nil { + t.Fatalf("write manifest: %v", err) + } + out, err := captureStdout(t, func() error { + return validateUploadManifestCommand([]string{"--manifest", manifestPath}) + }) + if err != nil { + t.Fatalf("validate manifest: %v", err) + } + if !strings.Contains(out, "upload manifest valid: 1 requests") { + t.Fatalf("unexpected validate output: %s", out) + } +} + +func TestUploadManifestValidationRejectsUnsafeInputs(t *testing.T) { + dir := t.TempDir() + writeTestFile(t, dir+"/payload.json", []byte(`{"release_id":"rel_1"}`)) + tests := []struct { + name string + body string + want string + }{ + { + name: "unknown schema", + body: `{"schema_version":"other","requests":[{"path":"/v1/release-bundles","idempotency_key":"k","payload":{"release_id":"rel_1"}}]}`, + want: "schema_version", + }, + { + name: "unknown field", + body: `{"schema_version":"evydence-upload-manifest.v1.0.0","unexpected":true,"requests":[{"path":"/v1/release-bundles","idempotency_key":"k","payload":{"release_id":"rel_1"}}]}`, + want: "unknown fields", + }, + { + name: "both payload sources", + body: `{"requests":[{"path":"/v1/release-bundles","idempotency_key":"k","payload":{"release_id":"rel_1"},"payload_file":"payload.json"}]}`, + want: "exactly one", + }, + { + name: "payload traversal", + body: `{"requests":[{"path":"/v1/release-bundles","idempotency_key":"k","payload_file":"../payload.json"}]}`, + want: "inside the manifest directory", + }, + { + name: "kind mismatch", + body: `{"requests":[{"kind":"sbom","path":"/v1/vex","idempotency_key":"k","payload":{"release_id":"rel_1"}}]}`, + want: "does not allow path", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + manifestPath := dir + "/" + strings.ReplaceAll(tt.name, " ", "-") + ".json" + if err := os.WriteFile(manifestPath, []byte(tt.body), 0o600); err != nil { + t.Fatalf("write manifest: %v", err) + } + err := validateUploadManifestCommand([]string{"--manifest", manifestPath}) + if err == nil || !strings.Contains(err.Error(), tt.want) { + t.Fatalf("err=%v want %q", err, tt.want) + } + }) + } +} + func TestImportBundleUploadPostsImport(t *testing.T) { dir := t.TempDir() bundlePath := dir + "/bundle.json" diff --git a/docs/README.md b/docs/README.md index 5a415d7..662d339 100644 --- a/docs/README.md +++ b/docs/README.md @@ -42,6 +42,7 @@ This documentation is organized by reader task. Implementation claims should be - [Roadmap and release cadence](reference/roadmap.md): current release-line focus, external trust controls, and cadence expectations. - [Worker outbox contract](reference/worker-outbox.md): durable job kinds, idempotency, and safe logging rules. - [Release validation](reference/release-validation.md): canonical `make release-check` behavior and summary evidence. +- [Upload manifest](reference/upload-manifest.md): schema, validation command, supported evidence request kinds, and safe payload-file handling. - [SDK workflow](sdk/README.md): current Go, TypeScript, and Python wrapper usage and limitations. - [Collector supply chain](collectors/supply-chain.md): collector release evidence and health checks. - [Source snapshot collectors](collectors/source-snapshots.md): GitHub and GitLab source metadata upload examples. diff --git a/docs/github-actions/quickstart-release-evidence.yml b/docs/github-actions/quickstart-release-evidence.yml index 415decd..78ff592 100644 --- a/docs/github-actions/quickstart-release-evidence.yml +++ b/docs/github-actions/quickstart-release-evidence.yml @@ -91,6 +91,8 @@ jobs: - name: Upload release evidence and create release bundle run: | set -euo pipefail + dist/evydence upload validate-manifest \ + --manifest .evydence/upload-manifest.json dist/evydence upload manifest \ --url "$EVYDENCE_API_URL" \ --api-key "$EVYDENCE_API_KEY" \ diff --git a/docs/github-actions/release-evidence-workflow.yml b/docs/github-actions/release-evidence-workflow.yml index 91a1bcd..24bdb14 100644 --- a/docs/github-actions/release-evidence-workflow.yml +++ b/docs/github-actions/release-evidence-workflow.yml @@ -82,6 +82,8 @@ jobs: EVYDENCE_API_URL: ${{ secrets.EVYDENCE_API_URL }} EVYDENCE_API_KEY: ${{ secrets.EVYDENCE_API_KEY }} run: | + dist/evydence upload validate-manifest \ + --manifest .evydence/upload-manifest.json dist/evydence upload manifest \ --url "$EVYDENCE_API_URL" \ --api-key "$EVYDENCE_API_KEY" \ diff --git a/docs/gitlab/evydence-release-evidence.gitlab-ci.yml b/docs/gitlab/evydence-release-evidence.gitlab-ci.yml index c0d942b..bcac33b 100644 --- a/docs/gitlab/evydence-release-evidence.gitlab-ci.yml +++ b/docs/gitlab/evydence-release-evidence.gitlab-ci.yml @@ -55,6 +55,7 @@ evydence:evidence: ] } EOF + - go run ./cmd/evydence upload validate-manifest --manifest evydence-upload-manifest.json - go run ./cmd/evydence upload manifest --url "$EVYDENCE_API_URL" --api-key "$EVYDENCE_API_KEY" --manifest evydence-upload-manifest.json rules: - if: $EVYDENCE_API_URL && $EVYDENCE_API_KEY diff --git a/docs/how-to/integrate-ci.md b/docs/how-to/integrate-ci.md index c6466fd..2eee8ee 100644 --- a/docs/how-to/integrate-ci.md +++ b/docs/how-to/integrate-ci.md @@ -111,6 +111,16 @@ print planned requests without requiring an API URL or key. The `--scan` file is Evydence generic vulnerability scan JSON with `findings`; use the full scanner-oriented workflow when you need Grype or Trivy normalization. +For bulk uploads, validate the manifest before upload: + +```sh +go run ./cmd/evydence upload validate-manifest \ + --manifest .evydence/upload-manifest.json +``` + +The manifest schema and supported request kinds are documented in +[Upload manifest](../reference/upload-manifest.md). + The full workflow also shows a scanner handoff path: - produce CycloneDX JSON with `syft`; diff --git a/docs/reference/upload-manifest.md b/docs/reference/upload-manifest.md new file mode 100644 index 0000000..b37ad4a --- /dev/null +++ b/docs/reference/upload-manifest.md @@ -0,0 +1,87 @@ +# Upload Manifest + +The upload manifest is a local CLI file for batching existing `/v1` create +requests. It is useful in CI when scanner, SBOM, VEX, provenance, approval, and +package-export payloads are produced as files before upload. + +The schema file is [schemas/upload-manifest.v1.schema.json](../../schemas/upload-manifest.v1.schema.json). +The current schema version is `evydence-upload-manifest.v1.0.0`. + +## Shape + +```json +{ + "schema_version": "evydence-upload-manifest.v1.0.0", + "requests": [ + { + "kind": "sbom", + "path": "/v1/sboms", + "idempotency_key": "release-123-sbom", + "payload_file": "sbom-cyclonedx-upload.json" + } + ] +} +``` + +Each request must include: + +- `path`: a `/v1` create/action endpoint. +- `idempotency_key`: the exact idempotency key sent to the API. +- exactly one of `payload` or `payload_file`. + +`payload_file` is resolved relative to the manifest directory and must stay +inside that directory after symlink resolution. The CLI validates JSON before it +sends any request. + +`kind` is optional for backward compatibility, but recommended. It documents the +request intent and lets the CLI reject obvious path mistakes: + +| Kind | Supported paths | +| --- | --- | +| `artifact` | `/v1/artifacts` | +| `sbom` | `/v1/sboms`, `/v1/sboms/spdx` | +| `scan`, `vulnerability_scan` | `/v1/vulnerability-scans` | +| `vex` | `/v1/vex`, `/v1/vex/cyclonedx` | +| `provenance`, `build`, `build_attestation` | `/v1/builds`, `/v1/builds/{id}/attestations` | +| `approval` | `/v1/approvals`, release approval paths | +| `package_export`, `customer_package` | `/v1/customer-packages` | +| `release_bundle` | `/v1/release-bundles` | +| `evidence` | `/v1/evidence` | + +## Commands + +Validate without network access: + +```sh +go run ./cmd/evydence upload validate-manifest \ + --manifest .evydence/upload-manifest.json +``` + +Upload after validation: + +```sh +go run ./cmd/evydence upload manifest \ + --url "$EVYDENCE_API_URL" \ + --api-key "$EVYDENCE_API_KEY" \ + --manifest .evydence/upload-manifest.json +``` + +The upload command validates the manifest again before sending requests. It does +not print the API key or raw payload bodies. + +## Supported Evidence Flow + +The manifest supports the release evidence path used by the GitHub and GitLab +examples: + +- artifact registration through `/v1/artifacts`; +- CycloneDX or SPDX SBOM upload; +- generic vulnerability scan upload; +- OpenVEX or CycloneDX VEX upload; +- build provenance or attestation upload; +- approval records; +- release bundle creation; +- customer package export. + +Scanner output remains evidence for review. It is not complete or authoritative +vulnerability coverage by itself. diff --git a/schemas/upload-manifest.v1.schema.json b/schemas/upload-manifest.v1.schema.json new file mode 100644 index 0000000..b0c2712 --- /dev/null +++ b/schemas/upload-manifest.v1.schema.json @@ -0,0 +1,78 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://evydence.local/schemas/upload-manifest.v1.schema.json", + "title": "Evydence Upload Manifest v1", + "type": "object", + "additionalProperties": false, + "properties": { + "schema_version": { + "type": "string", + "const": "evydence-upload-manifest.v1.0.0" + }, + "requests": { + "type": "array", + "minItems": 1, + "maxItems": 100, + "items": { + "$ref": "#/$defs/request" + } + } + }, + "required": ["requests"], + "$defs": { + "request": { + "type": "object", + "additionalProperties": false, + "properties": { + "kind": { + "type": "string", + "enum": [ + "artifact", + "sbom", + "scan", + "vulnerability_scan", + "vex", + "provenance", + "build", + "build_attestation", + "approval", + "package_export", + "customer_package", + "release_bundle", + "evidence" + ] + }, + "path": { + "type": "string", + "pattern": "^/v1/" + }, + "idempotency_key": { + "type": "string", + "minLength": 1 + }, + "payload": { + "type": "object" + }, + "payload_file": { + "type": "string", + "minLength": 1 + } + }, + "required": ["path", "idempotency_key"], + "oneOf": [ + { + "required": ["payload"], + "not": { + "required": ["payload_file"] + } + }, + { + "required": ["payload_file"], + "not": { + "required": ["payload"] + } + } + ] + } + } +} diff --git a/scripts/github_release_evidence_manifest.py b/scripts/github_release_evidence_manifest.py index b1774e6..f7ee98e 100755 --- a/scripts/github_release_evidence_manifest.py +++ b/scripts/github_release_evidence_manifest.py @@ -66,8 +66,8 @@ def trivy_findings(doc: dict[str, Any]) -> list[dict[str, str]]: return findings -def request(path: str, idempotency_key: str, payload_file: str) -> dict[str, str]: - return {"path": path, "idempotency_key": idempotency_key, "payload_file": payload_file} +def request(path: str, idempotency_key: str, payload_file: str, kind: str) -> dict[str, str]: + return {"kind": kind, "path": path, "idempotency_key": idempotency_key, "payload_file": payload_file} def parse_args() -> argparse.Namespace: @@ -99,7 +99,7 @@ def main() -> None: payload = {"release_id": args.release_id, "artifact_id": args.artifact_id, "payload": load_json(args.cyclonedx_sbom)} payload_path = base / "sbom-cyclonedx-upload.json" write_json(payload_path, payload) - requests.append(request("/v1/sboms", f"{args.idempotency_prefix}-sbom-cyclonedx", payload_path.name)) + requests.append(request("/v1/sboms", f"{args.idempotency_prefix}-sbom-cyclonedx", payload_path.name, "sbom")) if args.grype_json: payload = { @@ -110,7 +110,7 @@ def main() -> None: } payload_path = base / "scan-grype-upload.json" write_json(payload_path, payload) - requests.append(request("/v1/vulnerability-scans", f"{args.idempotency_prefix}-scan-grype", payload_path.name)) + requests.append(request("/v1/vulnerability-scans", f"{args.idempotency_prefix}-scan-grype", payload_path.name, "scan")) if args.trivy_json: payload = { @@ -121,18 +121,18 @@ def main() -> None: } payload_path = base / "scan-trivy-upload.json" write_json(payload_path, payload) - requests.append(request("/v1/vulnerability-scans", f"{args.idempotency_prefix}-scan-trivy", payload_path.name)) + requests.append(request("/v1/vulnerability-scans", f"{args.idempotency_prefix}-scan-trivy", payload_path.name, "scan")) if args.openvex_json: payload = {"release_id": args.release_id, "artifact_id": args.artifact_id, "payload": load_json(args.openvex_json)} payload_path = base / "vex-openvex-upload.json" write_json(payload_path, payload) - requests.append(request("/v1/vex", f"{args.idempotency_prefix}-vex-openvex", payload_path.name)) + requests.append(request("/v1/vex", f"{args.idempotency_prefix}-vex-openvex", payload_path.name, "vex")) if args.include_release_bundle: payload_path = base / "release-bundle-upload.json" write_json(payload_path, {"release_id": args.release_id}) - requests.append(request("/v1/release-bundles", f"{args.idempotency_prefix}-release-bundle", payload_path.name)) + requests.append(request("/v1/release-bundles", f"{args.idempotency_prefix}-release-bundle", payload_path.name, "release_bundle")) package_fields = [ args.customer_package_product_id, @@ -158,11 +158,11 @@ def main() -> None: "expires_at": args.customer_package_expires_at, }, ) - requests.append(request("/v1/customer-packages", f"{args.idempotency_prefix}-customer-package", payload_path.name)) + requests.append(request("/v1/customer-packages", f"{args.idempotency_prefix}-customer-package", payload_path.name, "package_export")) if not requests: raise SystemExit("no evidence inputs were supplied") - write_json(out, {"requests": requests}) + write_json(out, {"schema_version": "evydence-upload-manifest.v1.0.0", "requests": requests}) if __name__ == "__main__": From 3164a0a009445c2fd36bba7e54de9c0d508645e9 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:37:18 +0300 Subject: [PATCH 193/287] feat(api): add release evidence workflow endpoint --- .productization_next_steps.md | 2 +- README.md | 2 +- docs/api.md | 7 + docs/reference/api-contract-matrix.md | 3 +- docs/reference/production-exit-review.md | 2 +- internal/adapters/httpapi/openapi.go | 24 +++ .../adapters/httpapi/openapi_operations.go | 5 + .../adapters/httpapi/route_registration.go | 1 + internal/adapters/httpapi/router.go | 13 ++ internal/adapters/httpapi/router_test.go | 35 +++- internal/app/workflows.go | 162 ++++++++++++++++++ internal/domain/domain.go | 26 +++ openapi.yaml | 2 +- sdk/openapi-route-catalog.json | 19 +- 14 files changed, 296 insertions(+), 7 deletions(-) create mode 100644 internal/app/workflows.go diff --git a/.productization_next_steps.md b/.productization_next_steps.md index 04e48d5..5a40f74 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -773,7 +773,7 @@ Goal: Backlog: -#### [ ] EVY-060 — Add high-level workflow endpoints if current API is too low-level +#### [x] EVY-060 — Add high-level workflow endpoints if current API is too low-level Priority: P1 diff --git a/README.md b/README.md index 205a44f..400c989 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![OpenSSF Scorecard](https://github.com/aatuh/evydence/actions/workflows/scorecard.yml/badge.svg)](https://github.com/aatuh/evydence/actions/workflows/scorecard.yml) [![License: AGPL-3.0-only](https://img.shields.io/badge/license-AGPL--3.0--only-blue.svg)](LICENSE) ![Go Version](https://img.shields.io/badge/go-1.25+-00ADD8.svg) -![OpenAPI](https://img.shields.io/badge/OpenAPI-166%20precise%20operations-brightgreen.svg) +![OpenAPI](https://img.shields.io/badge/OpenAPI-170%20precise%20operations-brightgreen.svg) ![Coverage Gate](https://img.shields.io/badge/coverage%20gate-80%25+-brightgreen.svg) Evydence is a self-hosted, API-first release evidence ledger for product diff --git a/docs/api.md b/docs/api.md index afe9125..7c065ed 100644 --- a/docs/api.md +++ b/docs/api.md @@ -65,6 +65,7 @@ Then create: ```http POST /v1/projects POST /v1/releases +POST /v1/releases/{id}/evidence-flow/start ``` Representative request bodies: @@ -77,6 +78,11 @@ Representative request bodies: {"product_id":"prod_...","version":"1.0.0"} ``` +`POST /v1/releases/{id}/evidence-flow/start` returns a read-only workflow plan +with current evidence counts, required endpoints, scopes, idempotency guidance, +assumptions, and limitations. It does not create evidence or replace the +resource-specific endpoints. + ### 2. Register Artifact And Upload Evidence Register an artifact: @@ -320,6 +326,7 @@ Current SSO endpoints model admin-managed provider, identity-link, trust-materia | `POST` | `/v1/projects` | Create project under product. | | `POST` | `/v1/releases` | Create release. | | `GET` | `/v1/releases/{id}` | Read release. | +| `POST` | `/v1/releases/{id}/evidence-flow/start` | Read high-level release evidence workflow plan. | | `POST` | `/v1/releases/{id}/freeze` | Append freeze transition. | | `POST` | `/v1/releases/{id}/approve` | Append approval transition. | | `POST` | `/v1/artifacts` | Register artifact digest metadata. | diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index 445f39c..2e03b75 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 169 operations: 169 precise, 0 broad. +Generated from 170 operations: 170 precise, 0 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -115,6 +115,7 @@ Generated from 169 operations: 169 precise, 0 broad. | POST | /v1/releases | createRelease | Bearer | release:write | required | - | application/json:CreateReleaseRequest | 201:application/json:ReleaseEnvelope | precise | | GET | /v1/releases/{id} | getRelease | Bearer | release:read | - | path:id | - | 200:application/json:ReleaseEnvelope | precise | | POST | /v1/releases/{id}/approve | approveRelease | Bearer | release:write | required | path:id | application/json:EmptyObject | 200:application/json:ReleaseEnvelope | precise | +| POST | /v1/releases/{id}/evidence-flow/start | startReleaseEvidenceFlow | Bearer | release:read | required | path:id | - | 200:application/json:ReleaseEvidenceFlowEnvelope | precise | | POST | /v1/releases/{id}/freeze | freezeRelease | Bearer | release:write | required | path:id | application/json:EmptyObject | 200:application/json:ReleaseEnvelope | precise | | POST | /v1/remediation-tasks | createRemediationTask | Bearer | incident:write | required | - | application/json:CreateRemediationTaskRequest | 201:application/json:RemediationTaskEnvelope | precise | | POST | /v1/report-templates | createReportTemplate | Bearer | report:read | required | - | application/json:CreateReportTemplateRequest | 201:application/json:CustomReportTemplateEnvelope | precise | diff --git a/docs/reference/production-exit-review.md b/docs/reference/production-exit-review.md index 0f290a0..293b084 100644 --- a/docs/reference/production-exit-review.md +++ b/docs/reference/production-exit-review.md @@ -12,7 +12,7 @@ SaaS-ready, legally compliant, certified, or secure-release-guaranteed. ## Repo-Verified Strengths -- API contract has 166 precise `/v1` operations and zero broad operations. +- API contract has 170 precise `/v1` operations and zero broad operations. - `make production-check` is available and requires live PostgreSQL, coverage, migration compatibility, release validation, race tests, security scans, and release-signing smoke checks. diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index f616a01..42dfcb8 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -1575,6 +1575,30 @@ func registerCriticalSchemas(registry *specs.Registry) { "approved_at": map[string]any{"type": "string", "format": "date-time"}, }, "id", "tenant_id", "product_id", "version", "status", "schema_version", "created_at")) registry.RegisterSchema("ReleaseEnvelope", dataEnvelopeSchema("#/components/schemas/Release")) + registry.RegisterSchema("ReleaseEvidenceFlowStep", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "title": map[string]any{"type": "string"}, + "status": map[string]any{"type": "string", "enum": []string{"present", "missing", "optional"}}, + "required": map[string]any{"type": "boolean"}, + "method": map[string]any{"type": "string"}, + "path": map[string]any{"type": "string"}, + "required_scopes": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "idempotency_required": map[string]any{"type": "boolean"}, + "description": map[string]any{"type": "string"}, + "next_reference": map[string]any{"type": "string"}, + }, "id", "title", "status", "required", "method", "path", "required_scopes", "idempotency_required", "description")) + registry.RegisterSchema("ReleaseEvidenceFlow", objectSchema(map[string]any{ + "release_id": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "status": map[string]any{"type": "string", "enum": []string{"needs_evidence", "ready_for_review"}}, + "counts": map[string]any{"type": "object", "additionalProperties": map[string]any{"type": "integer"}}, + "steps": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/ReleaseEvidenceFlowStep"}}, + "assumptions": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "schema_version": map[string]any{"type": "string"}, + "generated_at": map[string]any{"type": "string", "format": "date-time"}, + }, "release_id", "product_id", "status", "counts", "steps", "assumptions", "limitations", "schema_version", "generated_at")) + registry.RegisterSchema("ReleaseEvidenceFlowEnvelope", dataEnvelopeSchema("#/components/schemas/ReleaseEvidenceFlow")) registry.RegisterSchema("RegisterArtifactRequest", objectSchema(map[string]any{ "release_id": map[string]any{"type": "string"}, "name": map[string]any{"type": "string"}, diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 07485de..1bdc342 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -164,6 +164,11 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Description = "Returns a tenant-scoped release by id." operation.Parameters = append(operation.Parameters, pathParam("id", "Release id.")) operation.Responses[http.StatusOK] = jsonResponse("Release envelope.", "#/components/schemas/ReleaseEnvelope") + case "startReleaseEvidenceFlow": + operation.Description = "Returns a high-level release evidence workflow plan, current evidence counts, required scopes, assumptions, and limitations. This read-only convenience operation does not create evidence." + operation.Parameters = append(operation.Parameters, pathParam("id", "Release id.")) + delete(operation.Responses, http.StatusCreated) + operation.Responses[http.StatusOK] = jsonResponse("Release evidence flow envelope.", "#/components/schemas/ReleaseEvidenceFlowEnvelope") case "freezeRelease": operation.Description = "Freezes a release as an append-only transition." operation.Parameters = append(operation.Parameters, pathParam("id", "Release id.")) diff --git a/internal/adapters/httpapi/route_registration.go b/internal/adapters/httpapi/route_registration.go index 6af1464..3e98b8e 100644 --- a/internal/adapters/httpapi/route_registration.go +++ b/internal/adapters/httpapi/route_registration.go @@ -111,6 +111,7 @@ func (s *Server) productReleaseRoutes() []routeDef { {http.MethodPost, "/v1/projects", op("createProject", http.MethodPost, "/v1/projects", "Create project", []string{app.ScopeProjectWrite}), http.HandlerFunc(s.createProject)}, {http.MethodPost, "/v1/releases", op("createRelease", http.MethodPost, "/v1/releases", "Create release", []string{app.ScopeReleaseWrite}), http.HandlerFunc(s.createRelease)}, {http.MethodGet, "/v1/releases/{id}", op("getRelease", http.MethodGet, "/v1/releases/{id}", "Get release", []string{app.ScopeReleaseRead}), http.HandlerFunc(s.getRelease)}, + {http.MethodPost, "/v1/releases/{id}/evidence-flow/start", op("startReleaseEvidenceFlow", http.MethodPost, "/v1/releases/{id}/evidence-flow/start", "Start release evidence flow", []string{app.ScopeReleaseRead}), http.HandlerFunc(s.startReleaseEvidenceFlow)}, {http.MethodPost, "/v1/releases/{id}/freeze", op("freezeRelease", http.MethodPost, "/v1/releases/{id}/freeze", "Freeze release", []string{app.ScopeReleaseWrite}), http.HandlerFunc(s.freezeRelease)}, {http.MethodPost, "/v1/releases/{id}/approve", op("approveRelease", http.MethodPost, "/v1/releases/{id}/approve", "Approve release", []string{app.ScopeReleaseWrite}), http.HandlerFunc(s.approveRelease)}, {http.MethodPost, "/v1/release-candidates", op("createReleaseCandidate", http.MethodPost, "/v1/release-candidates", "Create release candidate", []string{app.ScopeReleaseWrite}), http.HandlerFunc(s.createReleaseCandidate)}, diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index eb9ae0a..33f1a75 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -344,6 +344,19 @@ func (s *Server) getRelease(w http.ResponseWriter, r *http.Request) { writeData(w, http.StatusOK, release) } +func (s *Server) startReleaseEvidenceFlow(w http.ResponseWriter, r *http.Request) { + actor, ok := s.authenticate(w, r) + if !ok { + return + } + flow, err := s.ledger.ReleaseEvidenceFlowPlan(r.Context(), actor, r.PathValue("id")) + if err != nil { + writeProblem(w, r, err) + return + } + writeData(w, http.StatusOK, flow) +} + func (s *Server) freezeRelease(w http.ResponseWriter, r *http.Request) { s.create(w, r, func(ctx requestContext, actor domain.Actor, _ []byte) (int, any, error) { release, err := s.ledger.FreezeRelease(ctx, actor, r.PathValue("id")) diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 116c95a..e74d7e1 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -94,7 +94,7 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { if _, ok := redactionRequestProps["preset"]; !ok { t.Fatalf("redaction profile request schema missing preset: %#v", redactionRequestProps) } - for _, schemaName := range []string{"ReadinessStatusEnvelope", "BackupManifestEnvelope", "VerificationResultEnvelope", "ReadinessReportEnvelope", "CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "VEXImportReportEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "VulnerabilityDecisionListEnvelope", "VulnerabilityDecisionSummaryReportEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "UpdateSSOProviderTrustMaterialRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "ExchangeSSOCredentialRequest", "SSOCredentialExchangeEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "DataEnvelope"} { + for _, schemaName := range []string{"ReadinessStatusEnvelope", "BackupManifestEnvelope", "VerificationResultEnvelope", "ReadinessReportEnvelope", "CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "ReleaseEvidenceFlowEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "VEXImportReportEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "VulnerabilityDecisionListEnvelope", "VulnerabilityDecisionSummaryReportEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "UpdateSSOProviderTrustMaterialRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "ExchangeSSOCredentialRequest", "SSOCredentialExchangeEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "DataEnvelope"} { if _, ok := schemas[schemaName]; !ok { t.Fatalf("schema %s missing from OpenAPI components", schemaName) } @@ -127,6 +127,8 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { assertResponseRef(t, createRelease, "201", "#/components/schemas/ReleaseEnvelope") getRelease := operationMap(t, paths, "/v1/releases/{id}", "get") assertResponseRef(t, getRelease, "200", "#/components/schemas/ReleaseEnvelope") + startFlow := operationMap(t, paths, "/v1/releases/{id}/evidence-flow/start", "post") + assertResponseRef(t, startFlow, "200", "#/components/schemas/ReleaseEvidenceFlowEnvelope") freezeRelease := operationMap(t, paths, "/v1/releases/{id}/freeze", "post") assertRequestRef(t, freezeRelease, "#/components/schemas/EmptyObject") assertResponseRef(t, freezeRelease, "200", "#/components/schemas/ReleaseEnvelope") @@ -612,6 +614,37 @@ func TestReleaseBundleVerifyFlow(t *testing.T) { } } +func TestReleaseEvidenceFlowStartHTTPFlow(t *testing.T) { + server, secret := testServer(t) + productBody := postJSON(t, server, secret, "/v1/products", "flow-prod", map[string]any{"name": "Flow Product", "slug": "flow-product"}, http.StatusCreated) + productID := dataField(t, productBody, "id") + releaseBody := postJSON(t, server, secret, "/v1/releases", "flow-rel", map[string]any{"product_id": productID, "version": "1.0.0"}, http.StatusCreated) + releaseID := dataField(t, releaseBody, "id") + artifactDigest := "sha256:ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb" + artifactBody := postJSON(t, server, secret, "/v1/artifacts", "flow-artifact", map[string]any{"name": "api.tar.gz", "media_type": "application/gzip", "digest": artifactDigest, "size": 42}, http.StatusCreated) + artifactID := dataField(t, artifactBody, "id") + postJSON(t, server, secret, "/v1/sboms", "flow-sbom", map[string]any{ + "release_id": releaseID, + "artifact_id": artifactID, + "payload": map[string]any{ + "bomFormat": "CycloneDX", "specVersion": "1.6", + "components": []map[string]any{{"name": "api", "purl": "pkg:github/acme/api@abc"}}, + }, + }, http.StatusCreated) + postJSON(t, server, secret, "/v1/vulnerability-scans", "flow-scan", map[string]any{"scanner": "generic", "target_ref": "pkg:github/acme/api@abc", "release_id": releaseID, "findings": []map[string]any{}}, http.StatusCreated) + addHTTPBuildProvenance(t, server, secret, productID, releaseID, artifactID, artifactDigest) + postJSON(t, server, secret, "/v1/release-bundles", "flow-bundle", map[string]any{"release_id": releaseID}, http.StatusCreated) + flow := postJSON(t, server, secret, "/v1/releases/"+releaseID+"/evidence-flow/start", "flow-start", map[string]any{}, http.StatusOK) + for _, expected := range []string{`"schema_version":"release-evidence-flow.v1.0.0"`, `"status":"ready_for_review"`, `"artifact_refs":1`, `"sboms":1`, `"vulnerability_scans":1`, `"release_bundles":1`, `"path":"/v1/sboms"`} { + if !strings.Contains(flow, expected) { + t.Fatalf("flow response missing %s: %s", expected, flow) + } + } + if strings.Contains(flow, "certified secure") || strings.Contains(flow, "legally compliant") { + t.Fatalf("flow response uses prohibited claim wording: %s", flow) + } +} + func TestReleaseRiskDecisionHTTPFlow(t *testing.T) { server, secret := testServer(t) productBody := postJSON(t, server, secret, "/v1/products", "risk-prod", map[string]any{"name": "Payments", "slug": "risk-payments"}, http.StatusCreated) diff --git a/internal/app/workflows.go b/internal/app/workflows.go new file mode 100644 index 0000000..a88c1f2 --- /dev/null +++ b/internal/app/workflows.go @@ -0,0 +1,162 @@ +package app + +import ( + "context" + "strings" + + "github.com/aatuh/evydence/internal/domain" +) + +func (l *Ledger) ReleaseEvidenceFlowPlan(ctx context.Context, actor domain.Actor, releaseID string) (domain.ReleaseEvidenceFlow, error) { + return l.releaseEvidenceService().ReleaseEvidenceFlowPlan(ctx, actor, releaseID) +} + +func (s releaseEvidenceService) ReleaseEvidenceFlowPlan(ctx context.Context, actor domain.Actor, releaseID string) (domain.ReleaseEvidenceFlow, error) { + l := s.ledger + if err := ctx.Err(); err != nil { + return domain.ReleaseEvidenceFlow{}, err + } + if err := require(actor, ScopeReleaseRead); err != nil { + return domain.ReleaseEvidenceFlow{}, err + } + releaseID = strings.TrimSpace(releaseID) + if releaseID == "" { + return domain.ReleaseEvidenceFlow{}, ErrValidation + } + l.mu.Lock() + defer l.mu.Unlock() + release, ok := l.releases[releaseID] + if !ok || release.TenantID != actor.TenantID { + return domain.ReleaseEvidenceFlow{}, ErrNotFound + } + if err := l.authorizeResourceLocked(actor, ScopeReleaseRead, resourceRefs{ProductID: release.ProductID, ReleaseID: release.ID}); err != nil { + return domain.ReleaseEvidenceFlow{}, err + } + counts := releaseEvidenceFlowCountsLocked(l, actor.TenantID, release.ID) + steps := []domain.ReleaseEvidenceFlowStep{ + releaseEvidenceFlowStep("artifact_digest", "Register artifact digest", counts["artifact_refs"] > 0, true, "POST", "/v1/artifacts", []string{ScopeEvidenceWrite}, "Register the release artifact digest or upload build output metadata that references the artifact."), + releaseEvidenceFlowStep("build_provenance", "Record build provenance", counts["passed_builds"] > 0, true, "POST", "/v1/builds", []string{ScopeBuildWrite}, "Record CI build metadata, commit identity, and output digests for the release."), + releaseEvidenceFlowStep("sbom", "Upload SBOM", counts["sboms"] > 0, true, "POST", "/v1/sboms", []string{ScopeEvidenceWrite}, "Upload CycloneDX or SPDX SBOM evidence linked to the release and artifact where available."), + releaseEvidenceFlowStep("vulnerability_scan", "Upload vulnerability scan", counts["vulnerability_scans"] > 0, true, "POST", "/v1/vulnerability-scans", []string{ScopeEvidenceWrite}, "Upload generic vulnerability scan evidence for review and decision workflows."), + releaseEvidenceFlowStep("vex_or_decisions", "Record VEX or decisions", counts["vex_documents"]+counts["vulnerability_decisions"] > 0, false, "POST", "/v1/vex", []string{ScopeEvidenceWrite}, "Upload OpenVEX/CycloneDX VEX or create manual vulnerability decisions for relevant findings."), + releaseEvidenceFlowStep("release_bundle", "Create release bundle", counts["release_bundles"] > 0, true, "POST", "/v1/release-bundles", []string{ScopeBundleWrite}, "Create an immutable release bundle after the required evidence is present."), + releaseEvidenceFlowStep("readiness", "Read release readiness", true, true, "GET", "/v1/reports/release-readiness?release_id="+release.ID, []string{ScopeVerifyRead}, "Review deterministic policy checks, gaps, assumptions, exceptions, and limitations."), + releaseEvidenceFlowStep("customer_package", "Create customer package", counts["customer_packages"] > 0, false, "POST", "/v1/customer-packages", []string{ScopePackageWrite}, "Create a scoped customer-safe package only after redaction profile review."), + } + status := "ready_for_review" + for _, step := range steps { + if step.Required && step.Status != "present" { + status = "needs_evidence" + break + } + } + return domain.ReleaseEvidenceFlow{ + ReleaseID: release.ID, + ProductID: release.ProductID, + Status: status, + Counts: counts, + Steps: steps, + Assumptions: []string{ + "Workflow steps describe Evydence API evidence collection and do not replace CI provider, scanner, or operator review.", + "Scanner and SBOM uploads are recorded as evidence with limitations, not as complete or authoritative coverage.", + }, + Limitations: []string{ + "This workflow plan does not make legal compliance conclusions, grant certification, or guarantee release security.", + "Artifact-to-release association is inferred from release-linked SBOMs, build outputs, attestations, and uploaded evidence references.", + }, + SchemaVersion: domain.ReleaseEvidenceFlowVersion, + GeneratedAt: l.now(), + }, nil +} + +func releaseEvidenceFlowCountsLocked(l *Ledger, tenantID, releaseID string) map[string]int { + counts := map[string]int{ + "artifact_refs": 0, + "passed_builds": 0, + "build_attestations": 0, + "sboms": 0, + "vulnerability_scans": 0, + "vex_documents": 0, + "vulnerability_decisions": 0, + "release_bundles": 0, + "customer_packages": 0, + } + artifactRefs := map[string]struct{}{} + for _, sbom := range l.sboms { + if sbom.TenantID == tenantID && sbom.ReleaseID == releaseID { + counts["sboms"]++ + if sbom.ArtifactID != "" { + artifactRefs[sbom.ArtifactID] = struct{}{} + } + } + } + for _, scan := range l.scans { + if scan.TenantID == tenantID && scan.ReleaseID == releaseID { + counts["vulnerability_scans"]++ + } + } + for _, vex := range l.vexDocuments { + if vex.TenantID == tenantID && vex.ReleaseID == releaseID { + counts["vex_documents"]++ + if vex.ArtifactID != "" { + artifactRefs[vex.ArtifactID] = struct{}{} + } + } + } + for _, decision := range l.decisions { + if decision.TenantID == tenantID && decision.ReleaseID == releaseID && decision.SupersededBy == "" { + counts["vulnerability_decisions"]++ + } + } + for _, build := range l.buildRuns { + if build.TenantID == tenantID && build.ReleaseID == releaseID { + if build.Status == "passed" { + counts["passed_builds"]++ + } + for _, output := range build.Outputs { + if output.ArtifactID != "" { + artifactRefs[output.ArtifactID] = struct{}{} + } + } + } + } + for _, attestation := range l.attestations { + build, ok := l.buildRuns[attestation.BuildID] + if ok && attestation.TenantID == tenantID && build.ReleaseID == releaseID { + counts["build_attestations"]++ + } + } + for _, bundle := range l.bundles { + if bundle.TenantID == tenantID && bundle.ReleaseID == releaseID { + counts["release_bundles"]++ + } + } + for _, pkg := range l.customerPackages { + if pkg.TenantID == tenantID && pkg.ReleaseID == releaseID { + counts["customer_packages"]++ + } + } + counts["artifact_refs"] = len(artifactRefs) + return counts +} + +func releaseEvidenceFlowStep(id, title string, present, required bool, method, path string, scopes []string, description string) domain.ReleaseEvidenceFlowStep { + status := "missing" + if present { + status = "present" + } else if !required { + status = "optional" + } + return domain.ReleaseEvidenceFlowStep{ + ID: id, + Title: title, + Status: status, + Required: required, + Method: method, + Path: path, + RequiredScopes: scopes, + IdempotencyRequired: method == "POST", + Description: description, + NextReference: path, + } +} diff --git a/internal/domain/domain.go b/internal/domain/domain.go index f882736..84fb35e 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -6,6 +6,7 @@ const ( EvidenceItemSchemaVersion = "evidence-item.v1.0.0" AuditChainEntrySchemaVersion = "audit-chain-entry.v1.0.0" ReleaseBundleSchemaVersion = "release-bundle.v1.0.0" + ReleaseEvidenceFlowVersion = "release-evidence-flow.v1.0.0" CanonicalizationProfileVersion = "canonicalization-profile.v1.0.0" PolicySetVersion = "policy-set.v1.0.0" VEXDocumentSchemaVersion = "vex-document.v1.0.0" @@ -276,6 +277,31 @@ type Release struct { ApprovedAt *time.Time `json:"approved_at,omitempty"` } +type ReleaseEvidenceFlow struct { + ReleaseID string `json:"release_id"` + ProductID string `json:"product_id"` + Status string `json:"status"` + Counts map[string]int `json:"counts"` + Steps []ReleaseEvidenceFlowStep `json:"steps"` + Assumptions []string `json:"assumptions"` + Limitations []string `json:"limitations"` + SchemaVersion string `json:"schema_version"` + GeneratedAt time.Time `json:"generated_at"` +} + +type ReleaseEvidenceFlowStep struct { + ID string `json:"id"` + Title string `json:"title"` + Status string `json:"status"` + Required bool `json:"required"` + Method string `json:"method"` + Path string `json:"path"` + RequiredScopes []string `json:"required_scopes"` + IdempotencyRequired bool `json:"idempotency_required"` + Description string `json:"description"` + NextReference string `json:"next_reference,omitempty"` +} + type Artifact struct { ID string `json:"id"` TenantID string `json:"tenant_id"` diff --git a/openapi.yaml b/openapi.yaml index 0540985..77a7dd1 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"remediation":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"policy_set":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"remediation":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"policy_set":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlow":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["needs_evidence","ready_for_review"],"type":"string"},"steps":{"items":{"$ref":"#/components/schemas/ReleaseEvidenceFlowStep"},"type":"array"}},"required":["release_id","product_id","status","counts","steps","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseEvidenceFlowEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseEvidenceFlow"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlowStep":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"idempotency_required":{"type":"boolean"},"method":{"type":"string"},"next_reference":{"type":"string"},"path":{"type":"string"},"required":{"type":"boolean"},"required_scopes":{"items":{"type":"string"},"type":"array"},"status":{"enum":["present","missing","optional"],"type":"string"},"title":{"type":"string"}},"required":["id","title","status","required","method","path","required_scopes","idempotency_required","description"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/evidence-flow/start":{"post":{"description":"Returns a high-level release evidence workflow plan, current evidence counts, required scopes, assumptions, and limitations. This read-only convenience operation does not create evidence.","operationId":"startReleaseEvidenceFlow","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEvidenceFlowEnvelope"}}},"description":"Release evidence flow envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Start release evidence flow","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:read"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/sdk/openapi-route-catalog.json b/sdk/openapi-route-catalog.json index 3d1f9e9..1765f60 100644 --- a/sdk/openapi-route-catalog.json +++ b/sdk/openapi-route-catalog.json @@ -1,5 +1,5 @@ { - "route_count": 169, + "route_count": 170, "routes": [ { "idempotency_key_required": false, @@ -1823,6 +1823,23 @@ "200" ] }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "startReleaseEvidenceFlow", + "path": "/v1/releases/{id}/evidence-flow/start", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/ReleaseEvidenceFlowEnvelope" + ], + "scopes": [ + "release:read" + ], + "success_statuses": [ + "200" + ] + }, { "idempotency_key_required": true, "method": "POST", From 51a1e86c184d66352c434378845ba471367c438e Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:38:12 +0300 Subject: [PATCH 194/287] feat(api): add release security summary --- .productization_next_steps.md | 2 +- Makefile | 2 + README.md | 2 +- docs/api.md | 7 + docs/reference/api-contract-matrix.md | 3 +- docs/reference/production-exit-review.md | 2 +- .../end-to-end-release-evidence/README.md | 4 + .../run-local-demo.sh | 3 + .../sample-security-summary.json | 56 +++++++ internal/adapters/httpapi/openapi.go | 48 ++++++ .../adapters/httpapi/openapi_operations.go | 4 + .../adapters/httpapi/route_registration.go | 1 + internal/adapters/httpapi/router.go | 13 ++ internal/adapters/httpapi/router_test.go | 47 +++++- internal/app/ledger.go | 51 ++++--- internal/app/ledger_test.go | 77 ++++++++++ internal/app/workflows.go | 143 ++++++++++++++++++ internal/domain/domain.go | 54 +++++++ openapi.yaml | 2 +- sdk/openapi-route-catalog.json | 19 ++- 20 files changed, 511 insertions(+), 29 deletions(-) create mode 100644 examples/end-to-end-release-evidence/sample-security-summary.json diff --git a/.productization_next_steps.md b/.productization_next_steps.md index 5a40f74..a79fbcc 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -796,7 +796,7 @@ Acceptance criteria: * They are optional convenience APIs. * OpenAPI examples are included. -#### [ ] EVY-061 — Add release security summary endpoint +#### [x] EVY-061 — Add release security summary endpoint Priority: P0 diff --git a/Makefile b/Makefile index dc27b1e..0972768 100644 --- a/Makefile +++ b/Makefile @@ -313,12 +313,14 @@ demo-check: ## Validate checked end-to-end evidence demo fixtures @test -f examples/end-to-end-release-evidence/README.md @test -f examples/end-to-end-release-evidence/release-evidence-manifest.json @test -f examples/end-to-end-release-evidence/sample-readiness-report.json + @test -f examples/end-to-end-release-evidence/sample-security-summary.json @test -f examples/end-to-end-release-evidence/sample-customer-package-manifest.json @test -f examples/end-to-end-release-evidence/sample-customer-package.zip @test -f examples/end-to-end-release-evidence/sample-audit-chain-verification.json @python3 -c 'import json, pathlib; [json.loads(path.read_text()) for path in pathlib.Path("examples/end-to-end-release-evidence").glob("*.json")]' @$(GO) run ./cmd/evydence package verify --archive examples/end-to-end-release-evidence/sample-customer-package.zip --expected-package-id csp_example --expected-product-id prod_example --expected-release-id rel_example >/dev/null @grep -F '/v1/reports/release-readiness' examples/end-to-end-release-evidence/run-local-demo.sh >/dev/null + @grep -F '/security-summary' examples/end-to-end-release-evidence/run-local-demo.sh >/dev/null @grep -F '/v1/audit-chain/verify' examples/end-to-end-release-evidence/run-local-demo.sh >/dev/null @grep -F '/v1/customer-packages' examples/end-to-end-release-evidence/run-local-demo.sh >/dev/null @grep -F 'not legal' examples/end-to-end-release-evidence/README.md >/dev/null diff --git a/README.md b/README.md index 400c989..fa10f35 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![OpenSSF Scorecard](https://github.com/aatuh/evydence/actions/workflows/scorecard.yml/badge.svg)](https://github.com/aatuh/evydence/actions/workflows/scorecard.yml) [![License: AGPL-3.0-only](https://img.shields.io/badge/license-AGPL--3.0--only-blue.svg)](LICENSE) ![Go Version](https://img.shields.io/badge/go-1.25+-00ADD8.svg) -![OpenAPI](https://img.shields.io/badge/OpenAPI-170%20precise%20operations-brightgreen.svg) +![OpenAPI](https://img.shields.io/badge/OpenAPI-171%20precise%20operations-brightgreen.svg) ![Coverage Gate](https://img.shields.io/badge/coverage%20gate-80%25+-brightgreen.svg) Evydence is a self-hosted, API-first release evidence ledger for product diff --git a/docs/api.md b/docs/api.md index 7c065ed..0371678 100644 --- a/docs/api.md +++ b/docs/api.md @@ -66,6 +66,7 @@ Then create: POST /v1/projects POST /v1/releases POST /v1/releases/{id}/evidence-flow/start +GET /v1/releases/{id}/security-summary ``` Representative request bodies: @@ -83,6 +84,11 @@ with current evidence counts, required endpoints, scopes, idempotency guidance, assumptions, and limitations. It does not create evidence or replace the resource-specific endpoints. +`GET /v1/releases/{id}/security-summary` returns a tenant-scoped quick-check +summary for review surfaces. It includes artifact, SBOM, scan, finding, +decision, approval, exception, readiness, and package-generation status, but it +does not include raw evidence payload bytes or private decision notes. + ### 2. Register Artifact And Upload Evidence Register an artifact: @@ -327,6 +333,7 @@ Current SSO endpoints model admin-managed provider, identity-link, trust-materia | `POST` | `/v1/releases` | Create release. | | `GET` | `/v1/releases/{id}` | Read release. | | `POST` | `/v1/releases/{id}/evidence-flow/start` | Read high-level release evidence workflow plan. | +| `GET` | `/v1/releases/{id}/security-summary` | Read customer-safe release security summary status. | | `POST` | `/v1/releases/{id}/freeze` | Append freeze transition. | | `POST` | `/v1/releases/{id}/approve` | Append approval transition. | | `POST` | `/v1/artifacts` | Register artifact digest metadata. | diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index 2e03b75..b7d2e77 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 170 operations: 170 precise, 0 broad. +Generated from 171 operations: 171 precise, 0 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -117,6 +117,7 @@ Generated from 170 operations: 170 precise, 0 broad. | POST | /v1/releases/{id}/approve | approveRelease | Bearer | release:write | required | path:id | application/json:EmptyObject | 200:application/json:ReleaseEnvelope | precise | | POST | /v1/releases/{id}/evidence-flow/start | startReleaseEvidenceFlow | Bearer | release:read | required | path:id | - | 200:application/json:ReleaseEvidenceFlowEnvelope | precise | | POST | /v1/releases/{id}/freeze | freezeRelease | Bearer | release:write | required | path:id | application/json:EmptyObject | 200:application/json:ReleaseEnvelope | precise | +| GET | /v1/releases/{id}/security-summary | releaseSecuritySummary | Bearer | report:read | - | path:id | - | 200:application/json:ReleaseSecuritySummaryEnvelope | precise | | POST | /v1/remediation-tasks | createRemediationTask | Bearer | incident:write | required | - | application/json:CreateRemediationTaskRequest | 201:application/json:RemediationTaskEnvelope | precise | | POST | /v1/report-templates | createReportTemplate | Bearer | report:read | required | - | application/json:CreateReportTemplateRequest | 201:application/json:CustomReportTemplateEnvelope | precise | | POST | /v1/report-templates/{id}/render | renderReportTemplate | Bearer | report:read | required | path:id | application/json:RenderReportTemplateRequest | 201:application/json:RenderedCustomReportEnvelope | precise | diff --git a/docs/reference/production-exit-review.md b/docs/reference/production-exit-review.md index 293b084..4ad91ab 100644 --- a/docs/reference/production-exit-review.md +++ b/docs/reference/production-exit-review.md @@ -12,7 +12,7 @@ SaaS-ready, legally compliant, certified, or secure-release-guaranteed. ## Repo-Verified Strengths -- API contract has 170 precise `/v1` operations and zero broad operations. +- API contract has 171 precise `/v1` operations and zero broad operations. - `make production-check` is available and requires live PostgreSQL, coverage, migration compatibility, release validation, race tests, security scans, and release-signing smoke checks. diff --git a/examples/end-to-end-release-evidence/README.md b/examples/end-to-end-release-evidence/README.md index db05381..01b8165 100644 --- a/examples/end-to-end-release-evidence/README.md +++ b/examples/end-to-end-release-evidence/README.md @@ -34,6 +34,8 @@ you use source-checkout commands for local development. - `release-evidence-manifest.json`: example CLI bulk-upload manifest. - `sample-readiness-report.json`: representative readiness output with gaps and limitations. +- `sample-security-summary.json`: representative release security quick-check + output without raw tenant payload bytes. - `sample-customer-package-manifest.json`: representative customer package manifest without raw tenant payload bytes. - `sample-customer-package.zip`: downloadable fixture with `manifest.json`, @@ -89,6 +91,8 @@ question to concrete Evydence records: this demo. - `release-readiness.json`: the readiness result, gaps, assumptions, and limitations. +- `release-security-summary.json`: the compact release security status for + review surfaces. - `release-bundle.json`: the signed release bundle metadata. - `customer-package.json`: the customer-safe package manifest. - `audit-chain-verification.json`: audit-chain continuity verification. diff --git a/examples/end-to-end-release-evidence/run-local-demo.sh b/examples/end-to-end-release-evidence/run-local-demo.sh index 05d9348..2bda029 100755 --- a/examples/end-to-end-release-evidence/run-local-demo.sh +++ b/examples/end-to-end-release-evidence/run-local-demo.sh @@ -59,6 +59,9 @@ printf '%s\n' "$package" > "$outdir/customer-package.json" readiness="$(api GET "/v1/reports/release-readiness?release_id=${release_id}" "" "")" printf '%s\n' "$readiness" > "$outdir/release-readiness.json" +security_summary="$(api GET "/v1/releases/${release_id}/security-summary" "" "")" +printf '%s\n' "$security_summary" > "$outdir/release-security-summary.json" + audit="$(api GET /v1/audit-chain/verify "" "")" printf '%s\n' "$audit" > "$outdir/audit-chain-verification.json" diff --git a/examples/end-to-end-release-evidence/sample-security-summary.json b/examples/end-to-end-release-evidence/sample-security-summary.json new file mode 100644 index 0000000..cf9d960 --- /dev/null +++ b/examples/end-to-end-release-evidence/sample-security-summary.json @@ -0,0 +1,56 @@ +{ + "data": { + "product": { + "id": "prod_example", + "name": "Demo Payments API", + "slug": "demo-payments-api" + }, + "release": { + "id": "rel_example", + "version": "1.0.0", + "state": "draft" + }, + "artifact_count": 1, + "sbom_status": "present", + "vulnerability_scan_status": "present", + "open_findings_by_severity": { + "critical": 1 + }, + "decisions_by_status": { + "not_affected": 1 + }, + "approval_summary": { + "total": 0, + "approved": 0 + }, + "exception_summary": { + "total": 0, + "approved_unexpired": 0, + "unapproved": 0, + "expired": 0 + }, + "readiness_status": "passed", + "package_status": "generated", + "counts": { + "artifact_refs": 1, + "build_attestations": 1, + "customer_packages": 1, + "passed_builds": 1, + "release_bundles": 1, + "sboms": 1, + "vex_documents": 0, + "vulnerability_decisions": 1, + "vulnerability_scans": 1 + }, + "assumptions": [ + "Summary values are derived only from evidence, decisions, exceptions, approvals, bundles, packages, and build records in this Evydence tenant.", + "Open finding counts reflect uploaded scanner evidence and recorded decisions or exceptions; scanner results are not treated as complete or authoritative coverage." + ], + "limitations": [ + "This summary supports technical review and compliance readiness, not legal compliance conclusions, certification, or release security guarantees.", + "Raw SBOM, scanner, VEX, build, and package payload bytes are intentionally excluded from the summary." + ], + "schema_version": "release-security-summary.v1.0.0", + "generated_at": "2026-05-27T12:00:00Z" + } +} diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 42dfcb8..4528ec6 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -1599,6 +1599,54 @@ func registerCriticalSchemas(registry *specs.Registry) { "generated_at": map[string]any{"type": "string", "format": "date-time"}, }, "release_id", "product_id", "status", "counts", "steps", "assumptions", "limitations", "schema_version", "generated_at")) registry.RegisterSchema("ReleaseEvidenceFlowEnvelope", dataEnvelopeSchema("#/components/schemas/ReleaseEvidenceFlow")) + registry.RegisterSchema("ReleaseSecurityProductSummary", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "name": map[string]any{"type": "string"}, + "slug": map[string]any{"type": "string"}, + }, "id", "name", "slug")) + registry.RegisterSchema("ReleaseSecurityReleaseSummary", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "version": map[string]any{"type": "string"}, + "state": map[string]any{"type": "string"}, + }, "id", "version", "state")) + registry.RegisterSchema("ReleaseSecurityMissingDecision", objectSchema(map[string]any{ + "finding_id": map[string]any{"type": "string"}, + "scan_id": map[string]any{"type": "string"}, + "vulnerability": map[string]any{"type": "string"}, + "component": map[string]any{"type": "string"}, + "severity": map[string]any{"type": "string"}, + "state": map[string]any{"type": "string"}, + }, "finding_id", "scan_id", "vulnerability", "severity", "state")) + registry.RegisterSchema("ReleaseSecurityApprovalSummary", objectSchema(map[string]any{ + "total": map[string]any{"type": "integer"}, + "approved": map[string]any{"type": "integer"}, + }, "total", "approved")) + registry.RegisterSchema("ReleaseSecurityExceptionSummary", objectSchema(map[string]any{ + "total": map[string]any{"type": "integer"}, + "approved_unexpired": map[string]any{"type": "integer"}, + "unapproved": map[string]any{"type": "integer"}, + "expired": map[string]any{"type": "integer"}, + }, "total", "approved_unexpired", "unapproved", "expired")) + registry.RegisterSchema("ReleaseSecuritySummary", objectSchema(map[string]any{ + "product": map[string]any{"$ref": "#/components/schemas/ReleaseSecurityProductSummary"}, + "release": map[string]any{"$ref": "#/components/schemas/ReleaseSecurityReleaseSummary"}, + "artifact_count": map[string]any{"type": "integer"}, + "sbom_status": map[string]any{"type": "string", "enum": []string{"present", "missing"}}, + "vulnerability_scan_status": map[string]any{"type": "string", "enum": []string{"present", "missing"}}, + "open_findings_by_severity": map[string]any{"type": "object", "additionalProperties": map[string]any{"type": "integer"}}, + "decisions_by_status": map[string]any{"type": "object", "additionalProperties": map[string]any{"type": "integer"}}, + "missing_required_decisions": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/ReleaseSecurityMissingDecision"}}, + "approval_summary": map[string]any{"$ref": "#/components/schemas/ReleaseSecurityApprovalSummary"}, + "exception_summary": map[string]any{"$ref": "#/components/schemas/ReleaseSecurityExceptionSummary"}, + "readiness_status": map[string]any{"type": "string", "enum": []string{"passed", "failed"}}, + "package_status": map[string]any{"type": "string", "enum": []string{"generated", "not_generated"}}, + "counts": map[string]any{"type": "object", "additionalProperties": map[string]any{"type": "integer"}}, + "assumptions": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "schema_version": map[string]any{"type": "string"}, + "generated_at": map[string]any{"type": "string", "format": "date-time"}, + }, "product", "release", "artifact_count", "sbom_status", "vulnerability_scan_status", "open_findings_by_severity", "decisions_by_status", "approval_summary", "exception_summary", "readiness_status", "package_status", "counts", "assumptions", "limitations", "schema_version", "generated_at")) + registry.RegisterSchema("ReleaseSecuritySummaryEnvelope", dataEnvelopeSchema("#/components/schemas/ReleaseSecuritySummary")) registry.RegisterSchema("RegisterArtifactRequest", objectSchema(map[string]any{ "release_id": map[string]any{"type": "string"}, "name": map[string]any{"type": "string"}, diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 1bdc342..6bb248e 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -169,6 +169,10 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Parameters = append(operation.Parameters, pathParam("id", "Release id.")) delete(operation.Responses, http.StatusCreated) operation.Responses[http.StatusOK] = jsonResponse("Release evidence flow envelope.", "#/components/schemas/ReleaseEvidenceFlowEnvelope") + case "releaseSecuritySummary": + operation.Description = "Returns a tenant-scoped release security summary for review surfaces without raw evidence payload bytes." + operation.Parameters = append(operation.Parameters, pathParam("id", "Release id.")) + operation.Responses[http.StatusOK] = jsonResponse("Release security summary envelope.", "#/components/schemas/ReleaseSecuritySummaryEnvelope") case "freezeRelease": operation.Description = "Freezes a release as an append-only transition." operation.Parameters = append(operation.Parameters, pathParam("id", "Release id.")) diff --git a/internal/adapters/httpapi/route_registration.go b/internal/adapters/httpapi/route_registration.go index 3e98b8e..5d9693b 100644 --- a/internal/adapters/httpapi/route_registration.go +++ b/internal/adapters/httpapi/route_registration.go @@ -112,6 +112,7 @@ func (s *Server) productReleaseRoutes() []routeDef { {http.MethodPost, "/v1/releases", op("createRelease", http.MethodPost, "/v1/releases", "Create release", []string{app.ScopeReleaseWrite}), http.HandlerFunc(s.createRelease)}, {http.MethodGet, "/v1/releases/{id}", op("getRelease", http.MethodGet, "/v1/releases/{id}", "Get release", []string{app.ScopeReleaseRead}), http.HandlerFunc(s.getRelease)}, {http.MethodPost, "/v1/releases/{id}/evidence-flow/start", op("startReleaseEvidenceFlow", http.MethodPost, "/v1/releases/{id}/evidence-flow/start", "Start release evidence flow", []string{app.ScopeReleaseRead}), http.HandlerFunc(s.startReleaseEvidenceFlow)}, + {http.MethodGet, "/v1/releases/{id}/security-summary", op("releaseSecuritySummary", http.MethodGet, "/v1/releases/{id}/security-summary", "Release security summary", []string{app.ScopeReportRead}), http.HandlerFunc(s.releaseSecuritySummary)}, {http.MethodPost, "/v1/releases/{id}/freeze", op("freezeRelease", http.MethodPost, "/v1/releases/{id}/freeze", "Freeze release", []string{app.ScopeReleaseWrite}), http.HandlerFunc(s.freezeRelease)}, {http.MethodPost, "/v1/releases/{id}/approve", op("approveRelease", http.MethodPost, "/v1/releases/{id}/approve", "Approve release", []string{app.ScopeReleaseWrite}), http.HandlerFunc(s.approveRelease)}, {http.MethodPost, "/v1/release-candidates", op("createReleaseCandidate", http.MethodPost, "/v1/release-candidates", "Create release candidate", []string{app.ScopeReleaseWrite}), http.HandlerFunc(s.createReleaseCandidate)}, diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index 33f1a75..40ed8cd 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -357,6 +357,19 @@ func (s *Server) startReleaseEvidenceFlow(w http.ResponseWriter, r *http.Request writeData(w, http.StatusOK, flow) } +func (s *Server) releaseSecuritySummary(w http.ResponseWriter, r *http.Request) { + actor, ok := s.authenticate(w, r) + if !ok { + return + } + summary, err := s.ledger.ReleaseSecuritySummary(r.Context(), actor, r.PathValue("id")) + if err != nil { + writeProblem(w, r, err) + return + } + writeData(w, http.StatusOK, summary) +} + func (s *Server) freezeRelease(w http.ResponseWriter, r *http.Request) { s.create(w, r, func(ctx requestContext, actor domain.Actor, _ []byte) (int, any, error) { release, err := s.ledger.FreezeRelease(ctx, actor, r.PathValue("id")) diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index e74d7e1..4d7d963 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -94,7 +94,7 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { if _, ok := redactionRequestProps["preset"]; !ok { t.Fatalf("redaction profile request schema missing preset: %#v", redactionRequestProps) } - for _, schemaName := range []string{"ReadinessStatusEnvelope", "BackupManifestEnvelope", "VerificationResultEnvelope", "ReadinessReportEnvelope", "CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "ReleaseEvidenceFlowEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "VEXImportReportEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "VulnerabilityDecisionListEnvelope", "VulnerabilityDecisionSummaryReportEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "UpdateSSOProviderTrustMaterialRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "ExchangeSSOCredentialRequest", "SSOCredentialExchangeEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "DataEnvelope"} { + for _, schemaName := range []string{"ReadinessStatusEnvelope", "BackupManifestEnvelope", "VerificationResultEnvelope", "ReadinessReportEnvelope", "CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "ReleaseEvidenceFlowEnvelope", "ReleaseSecuritySummaryEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "VEXImportReportEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "VulnerabilityDecisionListEnvelope", "VulnerabilityDecisionSummaryReportEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "UpdateSSOProviderTrustMaterialRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "ExchangeSSOCredentialRequest", "SSOCredentialExchangeEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "DataEnvelope"} { if _, ok := schemas[schemaName]; !ok { t.Fatalf("schema %s missing from OpenAPI components", schemaName) } @@ -129,6 +129,8 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { assertResponseRef(t, getRelease, "200", "#/components/schemas/ReleaseEnvelope") startFlow := operationMap(t, paths, "/v1/releases/{id}/evidence-flow/start", "post") assertResponseRef(t, startFlow, "200", "#/components/schemas/ReleaseEvidenceFlowEnvelope") + securitySummary := operationMap(t, paths, "/v1/releases/{id}/security-summary", "get") + assertResponseRef(t, securitySummary, "200", "#/components/schemas/ReleaseSecuritySummaryEnvelope") freezeRelease := operationMap(t, paths, "/v1/releases/{id}/freeze", "post") assertRequestRef(t, freezeRelease, "#/components/schemas/EmptyObject") assertResponseRef(t, freezeRelease, "200", "#/components/schemas/ReleaseEnvelope") @@ -645,6 +647,49 @@ func TestReleaseEvidenceFlowStartHTTPFlow(t *testing.T) { } } +func TestReleaseSecuritySummaryHTTPFlow(t *testing.T) { + server, secret := testServer(t) + productBody := postJSON(t, server, secret, "/v1/products", "security-summary-prod", map[string]any{"name": "Summary Product", "slug": "summary-product"}, http.StatusCreated) + productID := dataField(t, productBody, "id") + releaseBody := postJSON(t, server, secret, "/v1/releases", "security-summary-rel", map[string]any{"product_id": productID, "version": "1.0.0"}, http.StatusCreated) + releaseID := dataField(t, releaseBody, "id") + artifactBody := postJSON(t, server, secret, "/v1/artifacts", "security-summary-artifact", map[string]any{"name": "api.tar.gz", "media_type": "application/gzip", "digest": "sha256:ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", "size": 42}, http.StatusCreated) + artifactID := dataField(t, artifactBody, "id") + postJSON(t, server, secret, "/v1/sboms", "security-summary-sbom", map[string]any{ + "release_id": releaseID, + "artifact_id": artifactID, + "payload": map[string]any{ + "bomFormat": "CycloneDX", "specVersion": "1.6", + "components": []map[string]any{{"name": "openssl", "purl": "pkg:apk/openssl@3.1.0"}}, + }, + }, http.StatusCreated) + scanBody := postJSON(t, server, secret, "/v1/vulnerability-scans", "security-summary-scan", map[string]any{ + "scanner": "grype", "target_ref": "pkg:oci/summary-api", "release_id": releaseID, + "findings": []map[string]any{{"vulnerability": "CVE-2026-0099", "component": "pkg:apk/openssl@3.1.0", "severity": "critical", "state": "open"}}, + }, http.StatusCreated) + findingID := firstFindingID(t, scanBody) + + summary := getJSON(t, server, secret, "/v1/releases/"+releaseID+"/security-summary", http.StatusOK) + for _, expected := range []string{`"schema_version":"release-security-summary.v1.0.0"`, `"sbom_status":"present"`, `"vulnerability_scan_status":"present"`, `"critical":1`, `"missing_required_decisions"`, `"readiness_status":"failed"`, `"package_status":"not_generated"`} { + if !strings.Contains(summary, expected) { + t.Fatalf("security summary missing %s: %s", expected, summary) + } + } + for _, forbidden := range []string{"payload_ref", "payload_hash", "internal_notes", "certified secure", "legally compliant"} { + if strings.Contains(summary, forbidden) { + t.Fatalf("security summary leaked or overclaimed %q: %s", forbidden, summary) + } + } + keyBody := postJSON(t, server, secret, "/v1/api-keys", "security-summary-release-reader", map[string]any{"name": "release reader", "scopes": []string{"release:read"}}, http.StatusCreated) + getJSON(t, server, nestedDataField(t, keyBody, "secret"), "/v1/releases/"+releaseID+"/security-summary", http.StatusForbidden) + + postJSON(t, server, secret, "/v1/vulnerability-findings/"+findingID+"/decisions", "security-summary-decision", map[string]any{"status": "not_affected", "justification": "vulnerable code is not present"}, http.StatusCreated) + summary = getJSON(t, server, secret, "/v1/releases/"+releaseID+"/security-summary", http.StatusOK) + if !strings.Contains(summary, `"not_affected":1`) || strings.Contains(summary, `"missing_required_decisions":[{`) { + t.Fatalf("security summary did not reflect decision: %s", summary) + } +} + func TestReleaseRiskDecisionHTTPFlow(t *testing.T) { server, secret := testServer(t) productBody := postJSON(t, server, secret, "/v1/products", "risk-prod", map[string]any{"name": "Payments", "slug": "risk-payments"}, http.StatusCreated) diff --git a/internal/app/ledger.go b/internal/app/ledger.go index cc9a2ae..a349e1c 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -1172,28 +1172,8 @@ func (l *Ledger) EvaluateRelease(ctx context.Context, actor domain.Actor, releas if err := l.authorizeResourceLocked(actor, ScopeVerifyRead, resourceRefs{ReleaseID: release.ID}); err != nil { return domain.PolicyEvaluation{}, err } - checks := []domain.PolicyCheck{ - l.checkReleaseHasArtifactLocked(actor.TenantID, release.ID), - l.checkReleaseHasEvidenceLocked(actor.TenantID, release.ID, "sbom", "release_requires_sbom", "high"), - l.checkReleaseHasEvidenceLocked(actor.TenantID, release.ID, "vulnerability_scan", "release_requires_vulnerability_scan", "high"), - l.checkReleaseHasArtifactDigestLocked(actor.TenantID, release.ID), - l.checkReleaseHasSignedBundleLocked(actor.TenantID, release.ID), - l.checkReleaseHasPassedBuildLocked(actor.TenantID, release.ID), - l.checkReleaseHasBuildAttestationLocked(actor.TenantID, release.ID), - l.checkNoOpenCriticalLocked(actor.TenantID, release.ID), - l.checkNoOpenHighLocked(actor.TenantID, release.ID), - l.checkCustomerVisibleDecisionsHaveStatementsLocked(actor.TenantID, release.ID), - l.checkNotAffectedDecisionsHaveJustificationLocked(actor.TenantID, release.ID), - l.checkExceptionsCompleteLocked(actor.TenantID, release.ID), - l.checkPackageRedactionProfilesValidLocked(actor.TenantID, release.ID), - } - result := "passed" - for _, check := range checks { - if check.Result == "failed" { - result = "failed" - break - } - } + checks := l.releasePolicyChecksLocked(actor.TenantID, release.ID) + result := releasePolicyResult(checks) eval := domain.PolicyEvaluation{ID: newID("pe"), TenantID: actor.TenantID, ReleaseID: release.ID, Result: result, PolicySet: domain.PolicySetVersion, Checks: checks, CreatedAt: l.now()} l.policies[eval.ID] = eval _, _ = l.appendChainLocked(actor.TenantID, "policy.evaluated", "policy_evaluation", eval.ID, "api_key", actor.KeyID, "", "") @@ -1203,6 +1183,33 @@ func (l *Ledger) EvaluateRelease(ctx context.Context, actor domain.Actor, releas return eval, nil } +func (l *Ledger) releasePolicyChecksLocked(tenantID, releaseID string) []domain.PolicyCheck { + return []domain.PolicyCheck{ + l.checkReleaseHasArtifactLocked(tenantID, releaseID), + l.checkReleaseHasEvidenceLocked(tenantID, releaseID, "sbom", "release_requires_sbom", "high"), + l.checkReleaseHasEvidenceLocked(tenantID, releaseID, "vulnerability_scan", "release_requires_vulnerability_scan", "high"), + l.checkReleaseHasArtifactDigestLocked(tenantID, releaseID), + l.checkReleaseHasSignedBundleLocked(tenantID, releaseID), + l.checkReleaseHasPassedBuildLocked(tenantID, releaseID), + l.checkReleaseHasBuildAttestationLocked(tenantID, releaseID), + l.checkNoOpenCriticalLocked(tenantID, releaseID), + l.checkNoOpenHighLocked(tenantID, releaseID), + l.checkCustomerVisibleDecisionsHaveStatementsLocked(tenantID, releaseID), + l.checkNotAffectedDecisionsHaveJustificationLocked(tenantID, releaseID), + l.checkExceptionsCompleteLocked(tenantID, releaseID), + l.checkPackageRedactionProfilesValidLocked(tenantID, releaseID), + } +} + +func releasePolicyResult(checks []domain.PolicyCheck) string { + for _, check := range checks { + if check.Result == "failed" { + return "failed" + } + } + return "passed" +} + func (l *Ledger) CreateReleaseBundle(ctx context.Context, actor domain.Actor, releaseID string) (domain.ReleaseBundle, error) { if err := ctx.Err(); err != nil { return domain.ReleaseBundle{}, err diff --git a/internal/app/ledger_test.go b/internal/app/ledger_test.go index 7c4a037..7518873 100644 --- a/internal/app/ledger_test.go +++ b/internal/app/ledger_test.go @@ -136,6 +136,83 @@ func TestUploadSBOMEnqueuesParserVersion(t *testing.T) { } } +func TestReleaseSecuritySummaryIsTenantScopedAndRedacted(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, release, artifact := setupReleaseRiskFixture(t, ledger) + if _, err := ledger.UploadSBOM(ctx, actor, release.ID, artifact.ID, []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","components":[{"name":"openssl","purl":"pkg:apk/openssl@3.1.0"}]}`)); err != nil { + t.Fatalf("sbom: %v", err) + } + scan, err := ledger.UploadVulnerabilityScan(ctx, actor, []byte(`{ + "scanner":"grype", + "target_ref":"pkg:oci/payments-api", + "release_id":"`+release.ID+`", + "findings":[{"vulnerability":"CVE-2026-0099","component":"pkg:apk/openssl@3.1.0","severity":"critical","state":"open"}] + }`)) + if err != nil { + t.Fatalf("scan: %v", err) + } + addBuildProvenance(t, ledger, actor, release, artifact) + if _, err := ledger.CreateReleaseBundle(ctx, actor, release.ID); err != nil { + t.Fatalf("bundle: %v", err) + } + + summary, err := ledger.ReleaseSecuritySummary(ctx, actor, release.ID) + if err != nil { + t.Fatalf("summary: %v", err) + } + if summary.SchemaVersion != domain.ReleaseSecuritySummaryVersion || summary.SBOMStatus != "present" || summary.VulnerabilityScanStatus != "present" { + t.Fatalf("summary basics missing: %#v", summary) + } + if summary.OpenFindingsBySeverity["critical"] != 1 || len(summary.MissingRequiredDecisions) != 1 || summary.ReadinessStatus != "failed" { + t.Fatalf("summary should show unhandled critical finding: %#v", summary) + } + body, err := json.Marshal(summary) + if err != nil { + t.Fatalf("marshal summary: %v", err) + } + for _, forbidden := range []string{"payload_ref", "payload_hash", "internal_notes", "secret", "token"} { + if strings.Contains(string(body), forbidden) { + t.Fatalf("summary leaked %q: %s", forbidden, body) + } + } + + if _, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{Status: decisionStatusNotAffected, Justification: "vulnerable code is not present"}); err != nil { + t.Fatalf("decision: %v", err) + } + summary, err = ledger.ReleaseSecuritySummary(ctx, actor, release.ID) + if err != nil { + t.Fatalf("summary after decision: %v", err) + } + if len(summary.MissingRequiredDecisions) != 0 || summary.DecisionsByStatus[decisionStatusNotAffected] != 1 || summary.ReadinessStatus != "passed" { + t.Fatalf("summary should reflect accepted decision: %#v", summary) + } + + _, readerSecret, err := ledger.CreateAPIKey(ctx, actor, "release-reader", []string{ScopeReleaseRead}, nil) + if err != nil { + t.Fatalf("reader key: %v", err) + } + reader, err := ledger.Authenticate(ctx, readerSecret) + if err != nil { + t.Fatalf("reader auth: %v", err) + } + if _, err := ledger.ReleaseSecuritySummary(ctx, reader, release.ID); !errors.Is(err, ErrForbidden) { + t.Fatalf("wrong-scope summary err = %v, want forbidden", err) + } + + _, _, otherSecret, err := ledger.BootstrapTenant(ctx, "Other Tenant", "admin", []string{"*"}) + if err != nil { + t.Fatalf("other bootstrap: %v", err) + } + other, err := ledger.Authenticate(ctx, otherSecret) + if err != nil { + t.Fatalf("other auth: %v", err) + } + if _, err := ledger.ReleaseSecuritySummary(ctx, other, release.ID); !errors.Is(err, ErrNotFound) { + t.Fatalf("cross-tenant summary err = %v, want not found", err) + } +} + func TestUploadSBOMCanDeferParserSideEffectsToWorker(t *testing.T) { outbox := &recordingOutbox{} store := NewMemoryStore() diff --git a/internal/app/workflows.go b/internal/app/workflows.go index a88c1f2..1d12a42 100644 --- a/internal/app/workflows.go +++ b/internal/app/workflows.go @@ -11,6 +11,10 @@ func (l *Ledger) ReleaseEvidenceFlowPlan(ctx context.Context, actor domain.Actor return l.releaseEvidenceService().ReleaseEvidenceFlowPlan(ctx, actor, releaseID) } +func (l *Ledger) ReleaseSecuritySummary(ctx context.Context, actor domain.Actor, releaseID string) (domain.ReleaseSecuritySummary, error) { + return l.releaseEvidenceService().ReleaseSecuritySummary(ctx, actor, releaseID) +} + func (s releaseEvidenceService) ReleaseEvidenceFlowPlan(ctx context.Context, actor domain.Actor, releaseID string) (domain.ReleaseEvidenceFlow, error) { l := s.ledger if err := ctx.Err(); err != nil { @@ -160,3 +164,142 @@ func releaseEvidenceFlowStep(id, title string, present, required bool, method, p NextReference: path, } } + +func (s releaseEvidenceService) ReleaseSecuritySummary(ctx context.Context, actor domain.Actor, releaseID string) (domain.ReleaseSecuritySummary, error) { + l := s.ledger + if err := ctx.Err(); err != nil { + return domain.ReleaseSecuritySummary{}, err + } + if err := require(actor, ScopeReportRead); err != nil { + return domain.ReleaseSecuritySummary{}, err + } + releaseID = strings.TrimSpace(releaseID) + if releaseID == "" { + return domain.ReleaseSecuritySummary{}, ErrValidation + } + l.mu.Lock() + defer l.mu.Unlock() + release, ok := l.releases[releaseID] + if !ok || release.TenantID != actor.TenantID { + return domain.ReleaseSecuritySummary{}, ErrNotFound + } + product, ok := l.products[release.ProductID] + if !ok || product.TenantID != actor.TenantID { + return domain.ReleaseSecuritySummary{}, ErrNotFound + } + if err := l.authorizeResourceLocked(actor, ScopeReportRead, resourceRefs{ProductID: release.ProductID, ReleaseID: release.ID}); err != nil { + return domain.ReleaseSecuritySummary{}, err + } + counts := releaseEvidenceFlowCountsLocked(l, actor.TenantID, release.ID) + openBySeverity, decisionsByStatus := releaseSecurityFindingDecisionCountsLocked(l, actor.TenantID, release.ID) + missing := []domain.ReleaseSecurityMissingDecision{} + for _, finding := range l.unhandledFindingsBySeverityLocked(actor.TenantID, release.ID, "critical", "high") { + missing = append(missing, domain.ReleaseSecurityMissingDecision{ + FindingID: finding.FindingID, + ScanID: finding.ScanID, + Vulnerability: finding.Vulnerability, + Component: finding.Component, + Severity: finding.Severity, + State: nonEmpty(finding.State, "open"), + }) + } + checks := l.releasePolicyChecksLocked(actor.TenantID, release.ID) + readiness := releasePolicyResult(checks) + packageStatus := "not_generated" + if counts["customer_packages"] > 0 { + packageStatus = "generated" + } + return domain.ReleaseSecuritySummary{ + Product: domain.ReleaseSecurityProductSummary{ + ID: product.ID, Name: product.Name, Slug: product.Slug, + }, + Release: domain.ReleaseSecurityReleaseSummary{ + ID: release.ID, Version: release.Version, State: release.State, + }, + ArtifactCount: counts["artifact_refs"], + SBOMStatus: presentMissingStatus(counts["sboms"] > 0), + VulnerabilityScanStatus: presentMissingStatus(counts["vulnerability_scans"] > 0), + OpenFindingsBySeverity: openBySeverity, + DecisionsByStatus: decisionsByStatus, + MissingRequiredDecisions: missing, + ApprovalSummary: releaseSecurityApprovalSummaryLocked(l, actor.TenantID, release.ID), + ExceptionSummary: releaseSecurityExceptionSummaryLocked(l, actor.TenantID, release.ID), + ReadinessStatus: readiness, + PackageStatus: packageStatus, + Counts: counts, + Assumptions: []string{ + "Summary values are derived only from evidence, decisions, exceptions, approvals, bundles, packages, and build records in this Evydence tenant.", + "Open finding counts reflect uploaded scanner evidence and recorded decisions or exceptions; scanner results are not treated as complete or authoritative coverage.", + }, + Limitations: []string{ + "This summary supports technical review and compliance readiness, not legal compliance conclusions, certification, or release security guarantees.", + "Raw SBOM, scanner, VEX, build, and package payload bytes are intentionally excluded from the summary.", + }, + SchemaVersion: domain.ReleaseSecuritySummaryVersion, + GeneratedAt: l.now(), + }, nil +} + +func releaseSecurityFindingDecisionCountsLocked(l *Ledger, tenantID, releaseID string) (map[string]int, map[string]int) { + openBySeverity := map[string]int{} + for _, scan := range l.scans { + if scan.TenantID != tenantID || scan.ReleaseID != releaseID { + continue + } + for _, finding := range scan.Findings { + if strings.ToLower(nonEmpty(finding.State, "open")) != "open" { + continue + } + openBySeverity[strings.ToLower(nonEmpty(finding.Severity, "unknown"))]++ + } + } + decisionsByStatus := map[string]int{} + for _, decision := range l.decisions { + if decision.TenantID == tenantID && decision.ReleaseID == releaseID && decision.SupersededBy == "" { + decisionsByStatus[decision.Status]++ + } + } + return openBySeverity, decisionsByStatus +} + +func releaseSecurityApprovalSummaryLocked(l *Ledger, tenantID, releaseID string) domain.ReleaseSecurityApprovalSummary { + summary := domain.ReleaseSecurityApprovalSummary{} + for _, approval := range l.approvals { + if approval.TenantID != tenantID || approval.SubjectType != "release" || approval.SubjectID != releaseID { + continue + } + summary.Total++ + if approval.Decision == "approved" { + summary.Approved++ + } + } + return summary +} + +func releaseSecurityExceptionSummaryLocked(l *Ledger, tenantID, releaseID string) domain.ReleaseSecurityExceptionSummary { + summary := domain.ReleaseSecurityExceptionSummary{} + now := l.now() + for _, exception := range l.exceptions { + if exception.TenantID != tenantID || exception.ReleaseID != releaseID { + continue + } + summary.Total++ + if !exception.ExpiresAt.After(now) { + summary.Expired++ + continue + } + if exception.Approved { + summary.ApprovedUnexpired++ + } else { + summary.Unapproved++ + } + } + return summary +} + +func presentMissingStatus(present bool) string { + if present { + return "present" + } + return "missing" +} diff --git a/internal/domain/domain.go b/internal/domain/domain.go index 84fb35e..018af87 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -7,6 +7,7 @@ const ( AuditChainEntrySchemaVersion = "audit-chain-entry.v1.0.0" ReleaseBundleSchemaVersion = "release-bundle.v1.0.0" ReleaseEvidenceFlowVersion = "release-evidence-flow.v1.0.0" + ReleaseSecuritySummaryVersion = "release-security-summary.v1.0.0" CanonicalizationProfileVersion = "canonicalization-profile.v1.0.0" PolicySetVersion = "policy-set.v1.0.0" VEXDocumentSchemaVersion = "vex-document.v1.0.0" @@ -302,6 +303,59 @@ type ReleaseEvidenceFlowStep struct { NextReference string `json:"next_reference,omitempty"` } +type ReleaseSecuritySummary struct { + Product ReleaseSecurityProductSummary `json:"product"` + Release ReleaseSecurityReleaseSummary `json:"release"` + ArtifactCount int `json:"artifact_count"` + SBOMStatus string `json:"sbom_status"` + VulnerabilityScanStatus string `json:"vulnerability_scan_status"` + OpenFindingsBySeverity map[string]int `json:"open_findings_by_severity"` + DecisionsByStatus map[string]int `json:"decisions_by_status"` + MissingRequiredDecisions []ReleaseSecurityMissingDecision `json:"missing_required_decisions,omitempty"` + ApprovalSummary ReleaseSecurityApprovalSummary `json:"approval_summary"` + ExceptionSummary ReleaseSecurityExceptionSummary `json:"exception_summary"` + ReadinessStatus string `json:"readiness_status"` + PackageStatus string `json:"package_status"` + Counts map[string]int `json:"counts"` + Assumptions []string `json:"assumptions"` + Limitations []string `json:"limitations"` + SchemaVersion string `json:"schema_version"` + GeneratedAt time.Time `json:"generated_at"` +} + +type ReleaseSecurityProductSummary struct { + ID string `json:"id"` + Name string `json:"name"` + Slug string `json:"slug"` +} + +type ReleaseSecurityReleaseSummary struct { + ID string `json:"id"` + Version string `json:"version"` + State string `json:"state"` +} + +type ReleaseSecurityMissingDecision struct { + FindingID string `json:"finding_id"` + ScanID string `json:"scan_id"` + Vulnerability string `json:"vulnerability"` + Component string `json:"component,omitempty"` + Severity string `json:"severity"` + State string `json:"state"` +} + +type ReleaseSecurityApprovalSummary struct { + Total int `json:"total"` + Approved int `json:"approved"` +} + +type ReleaseSecurityExceptionSummary struct { + Total int `json:"total"` + ApprovedUnexpired int `json:"approved_unexpired"` + Unapproved int `json:"unapproved"` + Expired int `json:"expired"` +} + type Artifact struct { ID string `json:"id"` TenantID string `json:"tenant_id"` diff --git a/openapi.yaml b/openapi.yaml index 77a7dd1..a856114 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"remediation":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"policy_set":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlow":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["needs_evidence","ready_for_review"],"type":"string"},"steps":{"items":{"$ref":"#/components/schemas/ReleaseEvidenceFlowStep"},"type":"array"}},"required":["release_id","product_id","status","counts","steps","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseEvidenceFlowEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseEvidenceFlow"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlowStep":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"idempotency_required":{"type":"boolean"},"method":{"type":"string"},"next_reference":{"type":"string"},"path":{"type":"string"},"required":{"type":"boolean"},"required_scopes":{"items":{"type":"string"},"type":"array"},"status":{"enum":["present","missing","optional"],"type":"string"},"title":{"type":"string"}},"required":["id","title","status","required","method","path","required_scopes","idempotency_required","description"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/evidence-flow/start":{"post":{"description":"Returns a high-level release evidence workflow plan, current evidence counts, required scopes, assumptions, and limitations. This read-only convenience operation does not create evidence.","operationId":"startReleaseEvidenceFlow","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEvidenceFlowEnvelope"}}},"description":"Release evidence flow envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Start release evidence flow","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:read"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"remediation":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"policy_set":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlow":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["needs_evidence","ready_for_review"],"type":"string"},"steps":{"items":{"$ref":"#/components/schemas/ReleaseEvidenceFlowStep"},"type":"array"}},"required":["release_id","product_id","status","counts","steps","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseEvidenceFlowEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseEvidenceFlow"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlowStep":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"idempotency_required":{"type":"boolean"},"method":{"type":"string"},"next_reference":{"type":"string"},"path":{"type":"string"},"required":{"type":"boolean"},"required_scopes":{"items":{"type":"string"},"type":"array"},"status":{"enum":["present","missing","optional"],"type":"string"},"title":{"type":"string"}},"required":["id","title","status","required","method","path","required_scopes","idempotency_required","description"],"type":"object"},"ReleaseSecurityApprovalSummary":{"additionalProperties":false,"properties":{"approved":{"type":"integer"},"total":{"type":"integer"}},"required":["total","approved"],"type":"object"},"ReleaseSecurityExceptionSummary":{"additionalProperties":false,"properties":{"approved_unexpired":{"type":"integer"},"expired":{"type":"integer"},"total":{"type":"integer"},"unapproved":{"type":"integer"}},"required":["total","approved_unexpired","unapproved","expired"],"type":"object"},"ReleaseSecurityMissingDecision":{"additionalProperties":false,"properties":{"component":{"type":"string"},"finding_id":{"type":"string"},"scan_id":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["finding_id","scan_id","vulnerability","severity","state"],"type":"object"},"ReleaseSecurityProductSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"],"type":"object"},"ReleaseSecurityReleaseSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"state":{"type":"string"},"version":{"type":"string"}},"required":["id","version","state"],"type":"object"},"ReleaseSecuritySummary":{"additionalProperties":false,"properties":{"approval_summary":{"$ref":"#/components/schemas/ReleaseSecurityApprovalSummary"},"artifact_count":{"type":"integer"},"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"decisions_by_status":{"additionalProperties":{"type":"integer"},"type":"object"},"exception_summary":{"$ref":"#/components/schemas/ReleaseSecurityExceptionSummary"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_required_decisions":{"items":{"$ref":"#/components/schemas/ReleaseSecurityMissingDecision"},"type":"array"},"open_findings_by_severity":{"additionalProperties":{"type":"integer"},"type":"object"},"package_status":{"enum":["generated","not_generated"],"type":"string"},"product":{"$ref":"#/components/schemas/ReleaseSecurityProductSummary"},"readiness_status":{"enum":["passed","failed"],"type":"string"},"release":{"$ref":"#/components/schemas/ReleaseSecurityReleaseSummary"},"sbom_status":{"enum":["present","missing"],"type":"string"},"schema_version":{"type":"string"},"vulnerability_scan_status":{"enum":["present","missing"],"type":"string"}},"required":["product","release","artifact_count","sbom_status","vulnerability_scan_status","open_findings_by_severity","decisions_by_status","approval_summary","exception_summary","readiness_status","package_status","counts","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseSecuritySummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseSecuritySummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/evidence-flow/start":{"post":{"description":"Returns a high-level release evidence workflow plan, current evidence counts, required scopes, assumptions, and limitations. This read-only convenience operation does not create evidence.","operationId":"startReleaseEvidenceFlow","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEvidenceFlowEnvelope"}}},"description":"Release evidence flow envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Start release evidence flow","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:read"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/security-summary":{"get":{"description":"Returns a tenant-scoped release security summary for review surfaces without raw evidence payload bytes.","operationId":"releaseSecuritySummary","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseSecuritySummaryEnvelope"}}},"description":"Release security summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release security summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/sdk/openapi-route-catalog.json b/sdk/openapi-route-catalog.json index 1765f60..4557b74 100644 --- a/sdk/openapi-route-catalog.json +++ b/sdk/openapi-route-catalog.json @@ -1,5 +1,5 @@ { - "route_count": 170, + "route_count": 171, "routes": [ { "idempotency_key_required": false, @@ -1857,6 +1857,23 @@ "200" ] }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "releaseSecuritySummary", + "path": "/v1/releases/{id}/security-summary", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/ReleaseSecuritySummaryEnvelope" + ], + "scopes": [ + "report:read" + ], + "success_statuses": [ + "200" + ] + }, { "idempotency_key_required": true, "method": "POST", From 6dc1e2a3978406a5361e5ce722afd383d8450c9b Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:40:57 +0300 Subject: [PATCH 195/287] docs(api): add release flow openapi examples --- .productization_next_steps.md | 2 +- docs/api.md | 1 + .../adapters/httpapi/openapi_operations.go | 171 ++++++++++++++++++ internal/adapters/httpapi/router_test.go | 26 +++ openapi.yaml | 2 +- 5 files changed, 200 insertions(+), 2 deletions(-) diff --git a/.productization_next_steps.md b/.productization_next_steps.md index a79fbcc..cb5cb86 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -824,7 +824,7 @@ Acceptance criteria: * Does not expose raw evidence payloads. * Used by example/demo. -#### [ ] EVY-062 — Add API examples for VEX-first flow +#### [x] EVY-062 — Add API examples for VEX-first flow Priority: P1 diff --git a/docs/api.md b/docs/api.md index 0371678..89e43ef 100644 --- a/docs/api.md +++ b/docs/api.md @@ -3,6 +3,7 @@ The public API base path is `/v1`. The generated contract is committed at [`../openapi.yaml`](../openapi.yaml) and served by the API at `/v1/openapi.json`. Use this page for common integration workflows and route lookup. The endpoint catalog is expected to list every path in `openapi.yaml`; the generated contract remains the source of truth for operation details, schemas, status codes, security metadata, and route drift checks. +The OpenAPI contract also includes non-sensitive examples for the main release evidence flow: create release, upload SBOM, upload vulnerability scan, record a vulnerability decision, read release readiness, and create a customer package. ## Request Contract diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 6bb248e..a31194e 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -159,7 +159,35 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { case "createRelease": operation.Description = "Creates an append-only release record under a product and optional project." operation.RequestBody = jsonRequest("Release creation request.", "#/components/schemas/CreateReleaseRequest") + addJSONRequestExamples(operation.RequestBody, map[string]any{ + "release-candidate": specs.Example{ + Summary: "Create a release for evidence collection", + Value: map[string]any{ + "product_id": "prod_20260527120000", + "project_id": "proj_20260527120000", + "version": "1.0.0-rc.1", + }, + }, + }) operation.Responses[http.StatusCreated] = jsonResponse("Created release envelope.", "#/components/schemas/ReleaseEnvelope") + addJSONResponseExamples(&operation, http.StatusCreated, map[string]any{ + "created-release": specs.Example{ + Summary: "Created release response", + Value: map[string]any{ + "data": map[string]any{ + "id": "rel_20260527120000", + "tenant_id": "ten_20260527120000", + "product_id": "prod_20260527120000", + "project_id": "proj_20260527120000", + "version": "1.0.0-rc.1", + "status": "draft", + "schema_version": "release.v1.0.0", + "created_at": "2026-05-27T12:00:00Z", + }, + "meta": map[string]any{"api_version": "v1"}, + }, + }, + }) case "getRelease": operation.Description = "Returns a tenant-scoped release by id." operation.Parameters = append(operation.Parameters, pathParam("id", "Release id.")) @@ -206,6 +234,12 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { case "uploadSBOM": operation.Description = "Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata." operation.RequestBody = jsonRequest("CycloneDX SBOM upload request.", "#/components/schemas/EvidenceUploadRequest") + addJSONRequestExamples(operation.RequestBody, map[string]any{ + "cyclonedx-release-sbom": specs.Example{ + Summary: "Upload a CycloneDX SBOM linked to the release artifact", + Value: cyclonedxSBOMUploadExample(), + }, + }) operation.Responses[http.StatusCreated] = jsonResponse("Created SBOM envelope.", "#/components/schemas/SBOMEnvelope") case "getSBOM": operation.Description = "Returns a tenant-scoped SBOM metadata record by id." @@ -239,6 +273,12 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { case "uploadVulnerabilityScan": operation.Description = "Uploads a generic vulnerability scan JSON payload and records normalized findings." operation.RequestBody = jsonRequest("Vulnerability scan upload payload.", "#/components/schemas/UploadVulnerabilityScanRequest") + addJSONRequestExamples(operation.RequestBody, map[string]any{ + "generic-critical-finding": specs.Example{ + Summary: "Upload a generic scanner finding for release triage", + Value: vulnerabilityScanUploadExample(), + }, + }) operation.Responses[http.StatusCreated] = jsonResponse("Created vulnerability scan envelope.", "#/components/schemas/VulnerabilityScanEnvelope") case "getVulnerabilityScan": operation.Description = "Returns a tenant-scoped vulnerability scan by id." @@ -366,6 +406,12 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Description = "Returns a deterministic release-readiness report with gaps, assumptions, and limitations." operation.Parameters = append(operation.Parameters, queryParam("release_id", "Release id.", "string")) operation.Responses[http.StatusOK] = jsonResponse("Release readiness report envelope.", "#/components/schemas/ReadinessReportEnvelope") + addJSONResponseExamples(&operation, http.StatusOK, map[string]any{ + "failed-readiness-with-gap": specs.Example{ + Summary: "Readiness report with a vulnerability decision gap", + Value: releaseReadinessReportExample(), + }, + }) case "missingEvidenceReport": operation.Description = "Returns a deterministic missing-evidence report for a release with assumptions and limitations." operation.Parameters = append(operation.Parameters, queryParam("release_id", "Release id.", "string")) @@ -378,6 +424,12 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Description = "Creates an append-only vulnerability decision for a tenant-scoped scan finding." operation.Parameters = append(operation.Parameters, pathParam("id", "Vulnerability finding id.")) operation.RequestBody = jsonRequest("Vulnerability decision creation request.", "#/components/schemas/CreateVulnerabilityDecisionRequest") + addJSONRequestExamples(operation.RequestBody, map[string]any{ + "not-affected-decision": specs.Example{ + Summary: "Record a customer-visible not-affected decision", + Value: vulnerabilityDecisionExample(), + }, + }) operation.Responses[http.StatusCreated] = jsonResponse("Created vulnerability decision envelope.", "#/components/schemas/VulnerabilityDecisionEnvelope") case "listVulnerabilityDecisions": operation.Description = "Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters." @@ -715,6 +767,12 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { case "createCustomerPackage": operation.Description = "Creates a scoped customer security package manifest using an explicit redaction profile." operation.RequestBody = jsonRequest("Customer package creation request.", "#/components/schemas/CreateCustomerPackageRequest") + addJSONRequestExamples(operation.RequestBody, map[string]any{ + "release-evidence-package": specs.Example{ + Summary: "Create a scoped release evidence package", + Value: customerPackageRequestExample(), + }, + }) operation.Responses[http.StatusCreated] = jsonResponse("Created customer security package envelope.", "#/components/schemas/CustomerSecurityPackageEnvelope") case "getCustomerPackage": operation.Description = "Returns a tenant-scoped customer security package manifest by id." @@ -809,6 +867,41 @@ func jsonRequest(description, schemaRef string) *specs.RequestBody { } } +func addJSONRequestExamples(body *specs.RequestBody, examples map[string]any) { + if body == nil || len(examples) == 0 { + return + } + media := body.Content["application/json"] + media.Examples = examples + body.Content["application/json"] = media +} + +func addJSONResponseExamples(operation *specs.Operation, status int, examples map[string]any) { + if operation == nil || len(examples) == 0 { + return + } + response := operation.Responses[status] + media := response.Content["application/json"] + media.Examples = examples + response.Content["application/json"] = media + operation.Responses[status] = response +} + +func cyclonedxSBOMUploadExample() map[string]any { + return map[string]any{ + "release_id": "rel_20260527120000", + "artifact_id": "art_20260527120000", + "payload": map[string]any{ + "bomFormat": "CycloneDX", + "specVersion": "1.6", + "components": []map[string]any{ + {"name": "payments-api", "version": "1.0.0-rc.1", "purl": "pkg:oci/payments-api@sha256-ca978112"}, + {"name": "openssl", "version": "3.1.0-r0", "purl": "pkg:apk/openssl@3.1.0-r0"}, + }, + }, + } +} + func openVEXUploadExample() map[string]any { return map[string]any{ "release_id": "rel_20260527120000", @@ -833,6 +926,84 @@ func openVEXUploadExample() map[string]any { } } +func vulnerabilityScanUploadExample() map[string]any { + return map[string]any{ + "scanner": "generic-json", + "target_ref": "pkg:oci/payments-api@sha256-ca978112", + "release_id": "rel_20260527120000", + "findings": []map[string]any{ + { + "vulnerability": "CVE-2026-0099", + "component": "pkg:apk/openssl@3.1.0-r0", + "severity": "critical", + "state": "open", + }, + }, + } +} + +func vulnerabilityDecisionExample() map[string]any { + return map[string]any{ + "status": "not_affected", + "justification": "The vulnerable code path is not reachable in this release.", + "impact_statement": "The shipped artifact does not include the affected runtime path.", + "customer_visible": true, + "evidence_ids": []string{"ev_20260527120000"}, + } +} + +func releaseReadinessReportExample() map[string]any { + return map[string]any{ + "data": map[string]any{ + "report_type": "release_readiness", + "template_version": "release-readiness.v1.0.0", + "product_id": "prod_20260527120000", + "release_id": "rel_20260527120000", + "result": "failed", + "policy_set": "policy-set.v1.0.0", + "summary": map[string]any{ + "headline": "Release evidence has one blocking vulnerability decision gap.", + "result": "failed", + "human_summary": "Required artifact, SBOM, scan, build, and bundle evidence is present, but one critical finding still needs a valid decision or approved exception.", + "policy_set": "policy-set.v1.0.0", + }, + "blocking_findings": []map[string]any{ + { + "finding_id": "scan_20260527120000:finding:1", + "scan_id": "scan_20260527120000", + "release_id": "rel_20260527120000", + "vulnerability": "CVE-2026-0099", + "component": "pkg:apk/openssl@3.1.0-r0", + "severity": "critical", + "state": "open", + "decision_state": "missing", + }, + }, + "missing_evidence": []string{"vulnerability_decision"}, + "accepted_exceptions": []map[string]any{}, + "assumptions": []string{ + "Readiness is based on tenant evidence recorded in Evydence.", + }, + "limitations": []string{ + "Readiness supports technical review and does not prove legal compliance, certification, complete vulnerability coverage, or release security.", + }, + "schema_version": "release-readiness.v1.0.0", + "generated_at": "2026-05-27T12:00:00Z", + }, + "meta": map[string]any{"api_version": "v1"}, + } +} + +func customerPackageRequestExample() map[string]any { + return map[string]any{ + "product_id": "prod_20260527120000", + "release_id": "rel_20260527120000", + "redaction_profile_id": "rp_20260527120000", + "title": "Payments API 1.0.0 release evidence package", + "expires_at": "2026-06-30T00:00:00Z", + } +} + func jsonResponse(description, schemaRef string) specs.Response { return specs.Response{ Description: description, diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 4d7d963..81e8246 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -111,6 +111,7 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { releaseReadiness := operationMap(t, paths, "/v1/reports/release-readiness", "get") assertQueryParams(t, releaseReadiness, "release_id") assertResponseRef(t, releaseReadiness, "200", "#/components/schemas/ReadinessReportEnvelope") + assertResponseExampleContains(t, releaseReadiness, "200", "failed-readiness-with-gap", "blocking_findings") craReadiness := operationMap(t, paths, "/v1/reports/cra-readiness", "get") assertQueryParams(t, craReadiness, "product_id", "release_id") assertResponseRef(t, craReadiness, "200", "#/components/schemas/ReadinessReportEnvelope") @@ -124,7 +125,9 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { assertResponseRef(t, createProject, "201", "#/components/schemas/ProjectEnvelope") createRelease := operationMap(t, paths, "/v1/releases", "post") assertRequestRef(t, createRelease, "#/components/schemas/CreateReleaseRequest") + assertRequestExampleContains(t, createRelease, "release-candidate", "1.0.0-rc.1") assertResponseRef(t, createRelease, "201", "#/components/schemas/ReleaseEnvelope") + assertResponseExampleContains(t, createRelease, "201", "created-release", "rel_20260527120000") getRelease := operationMap(t, paths, "/v1/releases/{id}", "get") assertResponseRef(t, getRelease, "200", "#/components/schemas/ReleaseEnvelope") startFlow := operationMap(t, paths, "/v1/releases/{id}/evidence-flow/start", "post") @@ -142,13 +145,17 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { assertResponseRef(t, createBuild, "201", "#/components/schemas/BuildRunEnvelope") uploadSBOM := operationMap(t, paths, "/v1/sboms", "post") assertRequestRef(t, uploadSBOM, "#/components/schemas/EvidenceUploadRequest") + assertRequestExampleContains(t, uploadSBOM, "cyclonedx-release-sbom", "pkg:apk/openssl") assertResponseRef(t, uploadSBOM, "201", "#/components/schemas/SBOMEnvelope") uploadVulnerabilityScan := operationMap(t, paths, "/v1/vulnerability-scans", "post") assertRequestRef(t, uploadVulnerabilityScan, "#/components/schemas/UploadVulnerabilityScanRequest") + assertRequestExampleContains(t, uploadVulnerabilityScan, "generic-critical-finding", "CVE-2026-0099") assertResponseRef(t, uploadVulnerabilityScan, "201", "#/components/schemas/VulnerabilityScanEnvelope") listVulnerabilityDecisions := operationMap(t, paths, "/v1/vulnerability-decisions", "get") assertQueryParams(t, listVulnerabilityDecisions, "product_id", "release_id", "vulnerability", "component", "status", "active") assertResponseRef(t, listVulnerabilityDecisions, "200", "#/components/schemas/VulnerabilityDecisionListEnvelope") + createVulnerabilityDecision := operationMap(t, paths, "/v1/vulnerability-findings/{id}/decisions", "post") + assertRequestExampleContains(t, createVulnerabilityDecision, "not-affected-decision", "customer_visible") decisionSummary := operationMap(t, paths, "/v1/reports/vulnerability-decision-summary", "get") assertQueryParams(t, decisionSummary, "release_id") assertResponseRef(t, decisionSummary, "200", "#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope") @@ -172,6 +179,8 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { if _, ok := portalPackage["security"]; ok { t.Fatalf("public portal token exchange should not advertise bearer security: %#v", portalPackage["security"]) } + createCustomerPackage := operationMap(t, paths, "/v1/customer-packages", "post") + assertRequestExampleContains(t, createCustomerPackage, "release-evidence-package", "redaction_profile_id") downloadPackage := operationMap(t, paths, "/v1/customer-packages/{id}/download", "get") assertMediaResponseType(t, downloadPackage, "200", "application/zip") portalDownload := operationMap(t, paths, "/v1/customer-portal/package/download", "post") @@ -1725,6 +1734,23 @@ func assertRequestExampleContains(t *testing.T, operation map[string]any, exampl } } +func assertResponseExampleContains(t *testing.T, operation map[string]any, status, exampleName, want string) { + t.Helper() + responses := asStringAnyMap(t, operation["responses"]) + response := asStringAnyMap(t, responses[status]) + content := asStringAnyMap(t, response["content"]) + media := asStringAnyMap(t, content["application/json"]) + examples := asStringAnyMap(t, media["examples"]) + example := asStringAnyMap(t, examples[exampleName]) + raw, err := json.Marshal(example["value"]) + if err != nil { + t.Fatalf("marshal response example %s: %v", exampleName, err) + } + if !strings.Contains(string(raw), want) { + t.Fatalf("response example %s does not contain %q: %s", exampleName, want, raw) + } +} + func assertProblemResponseRef(t *testing.T, operation map[string]any, status string) { t.Helper() assertMediaResponseRef(t, operation, status, "application/problem+json", "#/components/schemas/Problem") diff --git a/openapi.yaml b/openapi.yaml index a856114..4368507 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"remediation":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"policy_set":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlow":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["needs_evidence","ready_for_review"],"type":"string"},"steps":{"items":{"$ref":"#/components/schemas/ReleaseEvidenceFlowStep"},"type":"array"}},"required":["release_id","product_id","status","counts","steps","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseEvidenceFlowEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseEvidenceFlow"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlowStep":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"idempotency_required":{"type":"boolean"},"method":{"type":"string"},"next_reference":{"type":"string"},"path":{"type":"string"},"required":{"type":"boolean"},"required_scopes":{"items":{"type":"string"},"type":"array"},"status":{"enum":["present","missing","optional"],"type":"string"},"title":{"type":"string"}},"required":["id","title","status","required","method","path","required_scopes","idempotency_required","description"],"type":"object"},"ReleaseSecurityApprovalSummary":{"additionalProperties":false,"properties":{"approved":{"type":"integer"},"total":{"type":"integer"}},"required":["total","approved"],"type":"object"},"ReleaseSecurityExceptionSummary":{"additionalProperties":false,"properties":{"approved_unexpired":{"type":"integer"},"expired":{"type":"integer"},"total":{"type":"integer"},"unapproved":{"type":"integer"}},"required":["total","approved_unexpired","unapproved","expired"],"type":"object"},"ReleaseSecurityMissingDecision":{"additionalProperties":false,"properties":{"component":{"type":"string"},"finding_id":{"type":"string"},"scan_id":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["finding_id","scan_id","vulnerability","severity","state"],"type":"object"},"ReleaseSecurityProductSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"],"type":"object"},"ReleaseSecurityReleaseSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"state":{"type":"string"},"version":{"type":"string"}},"required":["id","version","state"],"type":"object"},"ReleaseSecuritySummary":{"additionalProperties":false,"properties":{"approval_summary":{"$ref":"#/components/schemas/ReleaseSecurityApprovalSummary"},"artifact_count":{"type":"integer"},"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"decisions_by_status":{"additionalProperties":{"type":"integer"},"type":"object"},"exception_summary":{"$ref":"#/components/schemas/ReleaseSecurityExceptionSummary"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_required_decisions":{"items":{"$ref":"#/components/schemas/ReleaseSecurityMissingDecision"},"type":"array"},"open_findings_by_severity":{"additionalProperties":{"type":"integer"},"type":"object"},"package_status":{"enum":["generated","not_generated"],"type":"string"},"product":{"$ref":"#/components/schemas/ReleaseSecurityProductSummary"},"readiness_status":{"enum":["passed","failed"],"type":"string"},"release":{"$ref":"#/components/schemas/ReleaseSecurityReleaseSummary"},"sbom_status":{"enum":["present","missing"],"type":"string"},"schema_version":{"type":"string"},"vulnerability_scan_status":{"enum":["present","missing"],"type":"string"}},"required":["product","release","artifact_count","sbom_status","vulnerability_scan_status","open_findings_by_severity","decisions_by_status","approval_summary","exception_summary","readiness_status","package_status","counts","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseSecuritySummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseSecuritySummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/evidence-flow/start":{"post":{"description":"Returns a high-level release evidence workflow plan, current evidence counts, required scopes, assumptions, and limitations. This read-only convenience operation does not create evidence.","operationId":"startReleaseEvidenceFlow","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEvidenceFlowEnvelope"}}},"description":"Release evidence flow envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Start release evidence flow","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:read"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/security-summary":{"get":{"description":"Returns a tenant-scoped release security summary for review surfaces without raw evidence payload bytes.","operationId":"releaseSecuritySummary","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseSecuritySummaryEnvelope"}}},"description":"Release security summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release security summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"remediation":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"policy_set":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlow":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["needs_evidence","ready_for_review"],"type":"string"},"steps":{"items":{"$ref":"#/components/schemas/ReleaseEvidenceFlowStep"},"type":"array"}},"required":["release_id","product_id","status","counts","steps","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseEvidenceFlowEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseEvidenceFlow"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlowStep":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"idempotency_required":{"type":"boolean"},"method":{"type":"string"},"next_reference":{"type":"string"},"path":{"type":"string"},"required":{"type":"boolean"},"required_scopes":{"items":{"type":"string"},"type":"array"},"status":{"enum":["present","missing","optional"],"type":"string"},"title":{"type":"string"}},"required":["id","title","status","required","method","path","required_scopes","idempotency_required","description"],"type":"object"},"ReleaseSecurityApprovalSummary":{"additionalProperties":false,"properties":{"approved":{"type":"integer"},"total":{"type":"integer"}},"required":["total","approved"],"type":"object"},"ReleaseSecurityExceptionSummary":{"additionalProperties":false,"properties":{"approved_unexpired":{"type":"integer"},"expired":{"type":"integer"},"total":{"type":"integer"},"unapproved":{"type":"integer"}},"required":["total","approved_unexpired","unapproved","expired"],"type":"object"},"ReleaseSecurityMissingDecision":{"additionalProperties":false,"properties":{"component":{"type":"string"},"finding_id":{"type":"string"},"scan_id":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["finding_id","scan_id","vulnerability","severity","state"],"type":"object"},"ReleaseSecurityProductSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"],"type":"object"},"ReleaseSecurityReleaseSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"state":{"type":"string"},"version":{"type":"string"}},"required":["id","version","state"],"type":"object"},"ReleaseSecuritySummary":{"additionalProperties":false,"properties":{"approval_summary":{"$ref":"#/components/schemas/ReleaseSecurityApprovalSummary"},"artifact_count":{"type":"integer"},"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"decisions_by_status":{"additionalProperties":{"type":"integer"},"type":"object"},"exception_summary":{"$ref":"#/components/schemas/ReleaseSecurityExceptionSummary"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_required_decisions":{"items":{"$ref":"#/components/schemas/ReleaseSecurityMissingDecision"},"type":"array"},"open_findings_by_severity":{"additionalProperties":{"type":"integer"},"type":"object"},"package_status":{"enum":["generated","not_generated"],"type":"string"},"product":{"$ref":"#/components/schemas/ReleaseSecurityProductSummary"},"readiness_status":{"enum":["passed","failed"],"type":"string"},"release":{"$ref":"#/components/schemas/ReleaseSecurityReleaseSummary"},"sbom_status":{"enum":["present","missing"],"type":"string"},"schema_version":{"type":"string"},"vulnerability_scan_status":{"enum":["present","missing"],"type":"string"}},"required":["product","release","artifact_count","sbom_status","vulnerability_scan_status","open_findings_by_severity","decisions_by_status","approval_summary","exception_summary","readiness_status","package_status","counts","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseSecuritySummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseSecuritySummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"examples":{"release-evidence-package":{"summary":"Create a scoped release evidence package","value":{"expires_at":"2026-06-30T00:00:00Z","product_id":"prod_20260527120000","redaction_profile_id":"rp_20260527120000","release_id":"rel_20260527120000","title":"Payments API 1.0.0 release evidence package"}}},"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"examples":{"release-candidate":{"summary":"Create a release for evidence collection","value":{"product_id":"prod_20260527120000","project_id":"proj_20260527120000","version":"1.0.0-rc.1"}}},"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"examples":{"created-release":{"summary":"Created release response","value":{"data":{"created_at":"2026-05-27T12:00:00Z","id":"rel_20260527120000","product_id":"prod_20260527120000","project_id":"proj_20260527120000","schema_version":"release.v1.0.0","status":"draft","tenant_id":"ten_20260527120000","version":"1.0.0-rc.1"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/evidence-flow/start":{"post":{"description":"Returns a high-level release evidence workflow plan, current evidence counts, required scopes, assumptions, and limitations. This read-only convenience operation does not create evidence.","operationId":"startReleaseEvidenceFlow","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEvidenceFlowEnvelope"}}},"description":"Release evidence flow envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Start release evidence flow","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:read"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/security-summary":{"get":{"description":"Returns a tenant-scoped release security summary for review surfaces without raw evidence payload bytes.","operationId":"releaseSecuritySummary","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseSecuritySummaryEnvelope"}}},"description":"Release security summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release security summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"examples":{"failed-readiness-with-gap":{"summary":"Readiness report with a vulnerability decision gap","value":{"data":{"accepted_exceptions":[],"assumptions":["Readiness is based on tenant evidence recorded in Evydence."],"blocking_findings":[{"component":"pkg:apk/openssl@3.1.0-r0","decision_state":"missing","finding_id":"scan_20260527120000:finding:1","release_id":"rel_20260527120000","scan_id":"scan_20260527120000","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"generated_at":"2026-05-27T12:00:00Z","limitations":["Readiness supports technical review and does not prove legal compliance, certification, complete vulnerability coverage, or release security."],"missing_evidence":["vulnerability_decision"],"policy_set":"policy-set.v1.0.0","product_id":"prod_20260527120000","release_id":"rel_20260527120000","report_type":"release_readiness","result":"failed","schema_version":"release-readiness.v1.0.0","summary":{"headline":"Release evidence has one blocking vulnerability decision gap.","human_summary":"Required artifact, SBOM, scan, build, and bundle evidence is present, but one critical finding still needs a valid decision or approved exception.","policy_set":"policy-set.v1.0.0","result":"failed"},"template_version":"release-readiness.v1.0.0"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"examples":{"cyclonedx-release-sbom":{"summary":"Upload a CycloneDX SBOM linked to the release artifact","value":{"artifact_id":"art_20260527120000","payload":{"bomFormat":"CycloneDX","components":[{"name":"payments-api","purl":"pkg:oci/payments-api@sha256-ca978112","version":"1.0.0-rc.1"},{"name":"openssl","purl":"pkg:apk/openssl@3.1.0-r0","version":"3.1.0-r0"}],"specVersion":"1.6"},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"examples":{"not-affected-decision":{"summary":"Record a customer-visible not-affected decision","value":{"customer_visible":true,"evidence_ids":["ev_20260527120000"],"impact_statement":"The shipped artifact does not include the affected runtime path.","justification":"The vulnerable code path is not reachable in this release.","status":"not_affected"}}},"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"examples":{"generic-critical-finding":{"summary":"Upload a generic scanner finding for release triage","value":{"findings":[{"component":"pkg:apk/openssl@3.1.0-r0","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"release_id":"rel_20260527120000","scanner":"generic-json","target_ref":"pkg:oci/payments-api@sha256-ca978112"}}},"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From 471ef3c6eb7bf5a6d38f2cd51a302e7410c73d6d Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:43:08 +0300 Subject: [PATCH 196/287] feat(package): add static customer package html report --- .productization_next_steps.md | 2 +- Makefile | 1 + docs/how-to/view-packages.md | 5 + docs/reference/customer-package-manifest.md | 8 + .../end-to-end-release-evidence/README.md | 3 + internal/app/governance_packages.go | 201 ++++++++++++++++++ internal/app/governance_packages_test.go | 10 +- internal/app/manual_decisions_test.go | 13 +- 8 files changed, 239 insertions(+), 4 deletions(-) diff --git a/.productization_next_steps.md b/.productization_next_steps.md index cb5cb86..700452b 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -871,7 +871,7 @@ Acceptance criteria: * Document chosen UI boundary. * Avoid starting a broad frontend unless necessary. -#### [ ] EVY-071 — Add generated HTML customer package report +#### [x] EVY-071 — Add generated HTML customer package report Priority: P1 diff --git a/Makefile b/Makefile index 0972768..49a6f6d 100644 --- a/Makefile +++ b/Makefile @@ -222,6 +222,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'make public-release-verify TAG=v0.1.0-rc.4' examples/end-to-end-release-evidence/README.md >/dev/null @test -f docs/assets/package-viewer-preview.svg @grep -F 'package-viewer-preview.svg' docs/how-to/view-packages.md >/dev/null + @grep -F 'report.html' docs/reference/customer-package-manifest.md docs/how-to/view-packages.md >/dev/null @grep -F 'v0.1.0-rc.4 - 2026-05-31' CHANGELOG.md >/dev/null @grep -F 'make restore-rehearsal-check' docs/runbooks/backup-restore.md >/dev/null @grep -F 'release upload-evidence' docs/how-to/integrate-ci.md >/dev/null diff --git a/docs/how-to/view-packages.md b/docs/how-to/view-packages.md index 7bda9de..8d5f9a5 100644 --- a/docs/how-to/view-packages.md +++ b/docs/how-to/view-packages.md @@ -23,6 +23,11 @@ The same fixture is available as `examples/end-to-end-release-evidence/sample-customer-package.zip` for archive verification workflows. +Customer package ZIP exports generated by the API include a self-contained +`report.html` file. Open it directly from the unpacked archive when a static +release summary is easier to review than raw JSON. The report uses only the +redacted package manifest and local inline styles. + ![Static package viewer preview](../assets/package-viewer-preview.svg) Use it for: diff --git a/docs/reference/customer-package-manifest.md b/docs/reference/customer-package-manifest.md index 7efd875..0626b56 100644 --- a/docs/reference/customer-package-manifest.md +++ b/docs/reference/customer-package-manifest.md @@ -76,6 +76,14 @@ directly from disk. A non-sensitive sample is available at the matching archive fixture is `examples/end-to-end-release-evidence/sample-customer-package.zip`. +Runtime ZIP exports also include `report.html`, a self-contained static HTML +rendering of the redacted manifest. It shows release summary, VEX and +vulnerability-decision tables, readiness checks, verification material, +limitations, and non-claims without requiring a server or loading remote assets. +The HTML report is generated from package-scoped data only and excludes raw +evidence payload bytes, object-store references, token material, private keys, +and internal decision notes. + ## Offline Verification The CLI verifies a package manifest without contacting the API: diff --git a/examples/end-to-end-release-evidence/README.md b/examples/end-to-end-release-evidence/README.md index 01b8165..72b27d9 100644 --- a/examples/end-to-end-release-evidence/README.md +++ b/examples/end-to-end-release-evidence/README.md @@ -43,6 +43,9 @@ you use source-checkout commands for local development. - `sample-audit-chain-verification.json`: representative audit-chain verification result. +Customer package ZIP exports generated by the API also include `report.html`, +a self-contained static report rendered from the redacted manifest. + ## Run Against A Local API Start Evydence with the getting-started tutorial or the production-like Compose diff --git a/internal/app/governance_packages.go b/internal/app/governance_packages.go index 446cf50..cdfca6d 100644 --- a/internal/app/governance_packages.go +++ b/internal/app/governance_packages.go @@ -9,6 +9,7 @@ import ( "encoding/json" "html" "sort" + "strconv" "strings" "time" @@ -1070,6 +1071,7 @@ func customerPackageArchive(pkg domain.CustomerSecurityPackage) (CustomerPackage "title": pkg.Title, "state": pkg.State, "manifest_hash": pkg.ManifestHash, + "html_report_file": "report.html", "expires_at": pkg.ExpiresAt.UTC().Format(time.RFC3339), "schema_version": pkg.SchemaVersion, "created_at": pkg.CreatedAt.UTC().Format(time.RFC3339), @@ -1079,6 +1081,7 @@ func customerPackageArchive(pkg domain.CustomerSecurityPackage) (CustomerPackage "manifest_hash": pkg.ManifestHash, "manifest_file": "manifest.json", "metadata_file": "package.json", + "html_report_file": "report.html", "hash_algorithm": "sha256", "verification_note": "Verify the package manifest hash against the Evydence API or a signed bundle before relying on contents.", "limitations": []string{ @@ -1114,6 +1117,10 @@ func customerPackageArchive(pkg domain.CustomerSecurityPackage) (CustomerPackage _ = zw.Close() return CustomerPackageArchive{}, err } + if err := addZIPFile(zw, "report.html", customerPackageHTMLReport(pkg, metadata, verification)); err != nil { + _ = zw.Close() + return CustomerPackageArchive{}, err + } if err := zw.Close(); err != nil { return CustomerPackageArchive{}, err } @@ -1121,6 +1128,200 @@ func customerPackageArchive(pkg domain.CustomerSecurityPackage) (CustomerPackage return CustomerPackageArchive{PackageID: pkg.ID, Filename: "evydence-customer-package-" + pkg.ID + ".zip", MediaType: "application/zip", Bytes: body, Hash: hashBytes(body), Size: int64(len(body))}, nil } +func customerPackageHTMLReport(pkg domain.CustomerSecurityPackage, metadata, verification map[string]any) []byte { + manifest := pkg.Manifest + product := packageHTMLMap(manifest["product"]) + release := packageHTMLMap(manifest["release"]) + readiness := packageHTMLMap(manifest["readiness_summary"]) + vexDocuments := packageHTMLRecords(manifest["vex_documents"]) + decisions := packageHTMLRecords(manifest["vulnerability_decisions"]) + limitations := packageHTMLStrings(manifest["limitations"]) + nonClaims := packageHTMLStrings(manifest["non_claims"]) + + var b strings.Builder + b.WriteString("") + b.WriteString(packageHTMLEscape(pkg.Title)) + b.WriteString("
") + b.WriteString("

") + b.WriteString(packageHTMLEscape(pkg.Title)) + b.WriteString("

This static report is generated from the redacted customer package manifest. It supports technical evidence review and compliance readiness only; it is not legal compliance proof, certification, complete SBOM proof, an authoritative vulnerability result, regulator acceptance, or a secure-release guarantee.

") + + b.WriteString("

Release Summary

") + packageHTMLRow(&b, "Package ID", pkg.ID) + packageHTMLRow(&b, "Product", packageHTMLFirst(product, "name", "id")) + packageHTMLRow(&b, "Release", packageHTMLFirst(release, "version", "id")) + packageHTMLRow(&b, "Package State", pkg.State) + packageHTMLRow(&b, "Readiness", packageHTMLString(readiness["result"])) + packageHTMLRow(&b, "Manifest Hash", packageHTMLString(metadata["manifest_hash"])) + b.WriteString("
") + + b.WriteString("

VEX And Vulnerability Decisions

") + if len(vexDocuments) == 0 && len(decisions) == 0 { + b.WriteString("

No customer-visible VEX documents or vulnerability decisions are included by this package profile.

") + } else { + if len(vexDocuments) > 0 { + b.WriteString("

VEX Documents

") + for _, record := range vexDocuments { + b.WriteString("") + } + b.WriteString("
IDFormatAuthorStatementsStatus Summary
" + packageHTMLEscape(packageHTMLString(record["id"])) + "" + packageHTMLEscape(packageHTMLString(record["format"])) + "" + packageHTMLEscape(packageHTMLString(record["author"])) + "" + packageHTMLEscape(packageHTMLString(record["statement_count"])) + "" + packageHTMLEscape(packageHTMLJSON(record["status_summary"])) + "
") + } + if len(decisions) > 0 { + b.WriteString("

Vulnerability Decisions

") + for _, record := range decisions { + b.WriteString("") + } + b.WriteString("
VulnerabilityComponentStatusImpact StatementSource
" + packageHTMLEscape(packageHTMLString(record["vulnerability"])) + "" + packageHTMLEscape(packageHTMLString(record["component"])) + "" + packageHTMLEscape(packageHTMLString(record["status"])) + "" + packageHTMLEscape(packageHTMLString(record["impact_statement"])) + "" + packageHTMLEscape(packageHTMLString(record["source"])) + "
") + } + } + + b.WriteString("

Readiness

") + packageHTMLReadiness(&b, readiness) + b.WriteString("

Verification

") + packageHTMLRow(&b, "Manifest File", packageHTMLString(verification["manifest_file"])) + packageHTMLRow(&b, "Manifest Hash", packageHTMLString(verification["manifest_hash"])) + packageHTMLRow(&b, "Hash Algorithm", packageHTMLString(verification["hash_algorithm"])) + packageHTMLRow(&b, "Verification Note", packageHTMLString(verification["verification_note"])) + b.WriteString("
") + b.WriteString("

Limitations

") + packageHTMLList(&b, limitations) + b.WriteString("

Non-Claims

") + packageHTMLList(&b, nonClaims) + b.WriteString("
") + return []byte(b.String()) +} + +func packageHTMLReadiness(b *strings.Builder, readiness map[string]any) { + result := packageHTMLString(readiness["result"]) + if result == "" { + b.WriteString("

No release readiness summary is included in this package.

") + return + } + b.WriteString("

Result: " + packageHTMLEscape(result) + "

") + checks := packageHTMLRecords(readiness["checks"]) + if len(checks) > 0 { + b.WriteString("") + for _, check := range checks { + b.WriteString("") + } + b.WriteString("
CheckResultSeverityMissingExplanation
" + packageHTMLEscape(packageHTMLString(check["name"])) + "" + packageHTMLEscape(packageHTMLString(check["result"])) + "" + packageHTMLEscape(packageHTMLString(check["severity"])) + "" + packageHTMLEscape(packageHTMLJSON(check["missing"])) + "" + packageHTMLEscape(packageHTMLString(check["explanation"])) + "
") + } + if gaps := packageHTMLStrings(readiness["gaps"]); len(gaps) > 0 { + b.WriteString("

Gaps

") + packageHTMLList(b, gaps) + } +} + +func packageHTMLRow(b *strings.Builder, label, value string) { + b.WriteString("") + b.WriteString(packageHTMLEscape(label)) + b.WriteString("") + b.WriteString(packageHTMLEscape(value)) + b.WriteString("") +} + +func packageHTMLList(b *strings.Builder, items []string) { + if len(items) == 0 { + b.WriteString("

None included.

") + return + } + b.WriteString("
    ") + for _, item := range items { + b.WriteString("
  • ") + b.WriteString(packageHTMLEscape(item)) + b.WriteString("
  • ") + } + b.WriteString("
") +} + +func packageHTMLMap(value any) map[string]any { + if value == nil { + return map[string]any{} + } + if record, ok := value.(map[string]any); ok { + return record + } + return map[string]any{} +} + +func packageHTMLRecords(value any) []map[string]any { + switch records := value.(type) { + case []map[string]any: + return records + case []any: + out := make([]map[string]any, 0, len(records)) + for _, record := range records { + if mapped, ok := record.(map[string]any); ok { + out = append(out, mapped) + } + } + return out + default: + return nil + } +} + +func packageHTMLStrings(value any) []string { + switch records := value.(type) { + case []string: + return append([]string(nil), records...) + case []any: + out := make([]string, 0, len(records)) + for _, record := range records { + if s := packageHTMLString(record); s != "" { + out = append(out, s) + } + } + return out + default: + return nil + } +} + +func packageHTMLFirst(record map[string]any, keys ...string) string { + for _, key := range keys { + if value := packageHTMLString(record[key]); value != "" { + return value + } + } + return "" +} + +func packageHTMLString(value any) string { + switch v := value.(type) { + case string: + return v + case int: + return strconv.Itoa(v) + case int64: + return strconv.FormatInt(v, 10) + case float64: + return strconv.FormatFloat(v, 'f', -1, 64) + case bool: + if v { + return "true" + } + return "false" + default: + return "" + } +} + +func packageHTMLJSON(value any) string { + if value == nil { + return "" + } + body, err := json.Marshal(value) + if err != nil { + return "" + } + return string(body) +} + +func packageHTMLEscape(value string) string { + return html.EscapeString(value) +} + func addZIPFile(zw *zip.Writer, name string, body []byte) error { header := &zip.FileHeader{Name: name, Method: zip.Deflate} header.SetMode(0o644) diff --git a/internal/app/governance_packages_test.go b/internal/app/governance_packages_test.go index 48081ed..6f585e4 100644 --- a/internal/app/governance_packages_test.go +++ b/internal/app/governance_packages_test.go @@ -69,12 +69,18 @@ func TestWaiverApprovalAndCustomerPackageFlow(t *testing.T) { t.Fatalf("archive metadata invalid: %#v", archive) } files := packageArchiveFiles(t, archive.Bytes) - for _, name := range []string{"manifest.json", "package.json", "verification.json", "README.txt"} { + for _, name := range []string{"manifest.json", "package.json", "verification.json", "README.txt", "report.html"} { if files[name] == "" { t.Fatalf("archive missing %s: %#v", name, files) } } - archiveText := strings.Join([]string{files["manifest.json"], files["package.json"], files["verification.json"], files["README.txt"]}, "\n") + if report := files["report.html"]; !strings.Contains(report, "Release Summary") || !strings.Contains(report, "VEX And Vulnerability Decisions") || !strings.Contains(report, "Readiness") || !strings.Contains(report, "Verification") || !strings.Contains(report, "Limitations") || !strings.Contains(report, "not legal compliance proof") { + t.Fatalf("HTML report missing expected sections or non-claim: %s", report) + } + if strings.Contains(files["report.html"], " Date: Sun, 31 May 2026 22:46:04 +0300 Subject: [PATCH 197/287] docs(ui): defer internal demo dashboard --- .productization_next_steps.md | 10 +++++++++- docs/reference/roadmap.md | 3 +++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.productization_next_steps.md b/.productization_next_steps.md index 700452b..324b370 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -887,7 +887,7 @@ Acceptance criteria: * Can be attached to package export. * Clearly says it is not certification/legal proof. -#### [ ] EVY-072 — Add internal demo dashboard only if needed +#### [x] EVY-072 — Add internal demo dashboard only if needed Priority: P2 @@ -910,6 +910,14 @@ Acceptance criteria: * Uses existing API. * Demo-focused, not enterprise UI. +Decision: + +The internal demo dashboard is not needed for the current VEX-first product +path. The repository now has API examples, an end-to-end release evidence demo, +a local package viewer, and generated `report.html` package exports. Keep the +demo surface static/offline until a pilot proves a server-backed dashboard is +necessary. + --- ### Milestone 9: Production/Pilot Hardening diff --git a/docs/reference/roadmap.md b/docs/reference/roadmap.md index 83dadde..2d34d85 100644 --- a/docs/reference/roadmap.md +++ b/docs/reference/roadmap.md @@ -23,6 +23,9 @@ is not part of the current supported profile. vulnerability reporting; - keep the first evaluation path tied to release artifacts, the end-to-end release evidence example, the package viewer, and the release evidence index; +- keep the demo surface static/offline for now: the package viewer and generated + `report.html` exports are the supported reviewer view, and a server-backed + internal dashboard remains deferred until a pilot proves it is necessary; - continue reducing large service surfaces while preserving tenant isolation, append-only evidence behavior, and safe error handling. From e7812dacdc66876d213a06ddffccd91c5329fdb7 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:48:06 +0300 Subject: [PATCH 198/287] docs(ops): add pilot deployment checklist --- .productization_next_steps.md | 2 +- Makefile | 4 + docs/README.md | 1 + docs/how-to/pilot-deployment-checklist.md | 140 ++++++++++++++++++++++ docs/operations.md | 1 + docs/reference/source-of-truth.md | 1 + 6 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 docs/how-to/pilot-deployment-checklist.md diff --git a/.productization_next_steps.md b/.productization_next_steps.md index 324b370..90e9671 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -1000,7 +1000,7 @@ Acceptance criteria: * Production-like Compose or Helm exposes enough signals. * Alerts suggested but not vendor-specific unless already wired. -#### [ ] EVY-083 — Add pilot deployment checklist +#### [x] EVY-083 — Add pilot deployment checklist Priority: P0 diff --git a/Makefile b/Makefile index 49a6f6d..847e793 100644 --- a/Makefile +++ b/Makefile @@ -225,6 +225,10 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'report.html' docs/reference/customer-package-manifest.md docs/how-to/view-packages.md >/dev/null @grep -F 'v0.1.0-rc.4 - 2026-05-31' CHANGELOG.md >/dev/null @grep -F 'make restore-rehearsal-check' docs/runbooks/backup-restore.md >/dev/null + @test -f docs/how-to/pilot-deployment-checklist.md + @grep -F 'Required: external PostgreSQL' docs/how-to/pilot-deployment-checklist.md >/dev/null + @grep -F 'Required: object paths are tenant-prefixed' docs/how-to/pilot-deployment-checklist.md >/dev/null + @grep -F 'Required: public API access is behind TLS' docs/how-to/pilot-deployment-checklist.md >/dev/null @grep -F 'release upload-evidence' docs/how-to/integrate-ci.md >/dev/null @grep -F -- '--dry-run' docs/how-to/integrate-ci.md >/dev/null @grep -F 'upload validate-manifest' docs/how-to/integrate-ci.md >/dev/null diff --git a/docs/README.md b/docs/README.md index 662d339..26125ae 100644 --- a/docs/README.md +++ b/docs/README.md @@ -17,6 +17,7 @@ This documentation is organized by reader task. Implementation claims should be - [Release signing](release-signing.md): create and verify local release artifact manifests. - [View packages locally](how-to/view-packages.md): inspect package, readiness, and evidence-bundle JSON without uploading it. - [Production hardening review](production-hardening.md): review production configuration, backups, ingress, diagnostics, and customer package controls. +- [Pilot deployment checklist](how-to/pilot-deployment-checklist.md): copy-paste checklist for the narrow design-partner pilot profile. - [Backup and restore runbook](runbooks/backup-restore.md): rehearse paired database/object-store restore and verification. - [Upgrade runbook](runbooks/upgrade.md): verify release artifacts, migrations, and post-upgrade checks. - [Incident response runbook](runbooks/incident-response.md): handle operator incidents without leaking secrets or raw evidence. diff --git a/docs/how-to/pilot-deployment-checklist.md b/docs/how-to/pilot-deployment-checklist.md new file mode 100644 index 0000000..106a413 --- /dev/null +++ b/docs/how-to/pilot-deployment-checklist.md @@ -0,0 +1,140 @@ +# Pilot Deployment Checklist + +This how-to is a copy-paste checklist for one narrow design-partner pilot +profile: a single self-hosted Evydence tenant, one API writer replica, scalable +worker replicas, external PostgreSQL, external S3/MinIO-compatible object +storage, reverse-proxy TLS, and operator-managed signing material. + +Use it before a pilot starts and keep the completed copy with the deployment +record. The checklist supports deployment readiness review only. It is not legal +compliance proof, certification, complete SBOM proof, authoritative scanner +coverage, auditor acceptance, or a secure-release guarantee. + +## Required Before Pilot Traffic + +### Environment + +- [ ] Required: deployment owner named: +- [ ] Required: pilot tenant name and expected products/releases recorded: +- [ ] Required: `ENV=production` configured for the API and workers. +- [ ] Required: one API writer replica configured. +- [ ] Required: worker replicas configured and sized for the expected evidence + upload volume. +- [ ] Required: `GET /v1/ready` returns ready after migrations and worker + startup. +- [ ] Recommended: capacity assumptions recorded from + `docs/reference/capacity-and-failures.md`. + +### Database + +- [ ] Required: external PostgreSQL is provisioned outside the application + container. +- [ ] Required: `EVYDENCE_DATABASE_URL` is supplied from deployment secrets, not + source control or logs. +- [ ] Required: migrations have been applied with the release artifact being + deployed. +- [ ] Required: database backups are enabled and the backup location is known. +- [ ] Recommended: database restore rehearsal completed before pilot traffic. + +### Object Storage + +- [ ] Required: external S3/MinIO-compatible object storage is configured for + raw payloads and package artifacts. +- [ ] Required: object paths are tenant-prefixed. +- [ ] Required: object storage credentials are supplied from deployment secrets. +- [ ] Required: object encryption and lifecycle policy are reviewed. +- [ ] Recommended: retention or object-lock policy is verified where the pilot + requires WORM-style controls. + +### API Keys And Access + +- [ ] Required: bootstrap/admin API key is generated once, stored in a secret + manager, and not retained in shell history. +- [ ] Required: collector API keys use least-privilege scopes. +- [ ] Required: revoked or unused pilot keys are removed before traffic starts. +- [ ] Required: support/debug access uses scoped keys and expires after the + pilot window. +- [ ] Recommended: key rotation date recorded: + +### Signing Mode + +- [ ] Required: signing mode is documented: +- [ ] Required: production deployments do not use plaintext local signing-key + storage. +- [ ] Required: signing verification command has been run against a generated + release bundle or package manifest. +- [ ] Recommended: external KMS/HSM/gateway limitations are recorded if used. + +### TLS And Reverse Proxy + +- [ ] Required: public API access is behind TLS. +- [ ] Required: reverse proxy or ingress request body limits match the intended + upload sizes. +- [ ] Required: rate limiting is configured for unauthenticated and token-heavy + endpoints. +- [ ] Required: `/v1/metrics`, `/v1/audit-log`, and `/v1/admin/instance` are not + publicly exposed without scoped authentication. +- [ ] Recommended: ingress logs redact authorization headers and cookies. + +### Image Digest And Release Evidence + +- [ ] Required: release artifact manifest and signatures were verified. +- [ ] Required: image digest or binary checksum is recorded: +- [ ] Required: OpenAPI checksum and migration checksum from the release + evidence match the deployed artifact. +- [ ] Required: release notes and known limitations were reviewed with the pilot + owner. + +### Backups And Restore Rehearsal + +- [ ] Required: PostgreSQL backup schedule recorded: +- [ ] Required: object-store backup or replication policy recorded: +- [ ] Required: signing material backup or recovery policy recorded: +- [ ] Required: restore owner and escalation path recorded: +- [ ] Recommended: restore rehearsal completed with audit-chain, bundle, and + package verification after restore. + +### Migrations And Upgrade + +- [ ] Required: current migration version recorded before deployment: +- [ ] Required: target migration version recorded: +- [ ] Required: upgrade runbook reviewed from `docs/runbooks/upgrade.md`. +- [ ] Recommended: rollback or forward-fix decision policy recorded: + +### Package Retention And Redaction + +- [ ] Required: customer package expiry defaults are set. +- [ ] Required: redaction profile reviewed against the pilot's sharing scope. +- [ ] Required: raw evidence payload bytes, private keys, bearer tokens, + database URLs, and provider credentials are excluded from shared packages. +- [ ] Required: package access scope and intended recipients are recorded. +- [ ] Recommended: sample package inspected in the local viewer before sharing. + +### Support Contact + +- [ ] Required: pilot support contact: +- [ ] Required: security reporting path from `SECURITY.md` shared with the + pilot owner. +- [ ] Required: sanitized bug-report rules from `SUPPORT.md` shared with the + pilot owner. +- [ ] Recommended: support response expectations documented for the pilot + window. + +## Final Pilot Go/No-Go + +- [ ] Required: `make production-check` passed for the deployment evidence + environment, or every failing check has a documented pilot-blocking + decision. +- [ ] Required: `make release-acceptance` passed for the release artifact. +- [ ] Required: backup and restore responsibilities are accepted by the + operator. +- [ ] Required: unsupported production profiles are understood: broad regulated + production, hosted SaaS operation, and multi-writer API high availability + remain outside this narrow pilot profile. + +Record final decision: + +- [ ] Go +- [ ] No-go +- [ ] Go with documented limitations: + diff --git a/docs/operations.md b/docs/operations.md index 090a36b..d16b7bb 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -17,6 +17,7 @@ This operator index points to the canonical references for running Evydence. Kee | View packages locally | [View packages locally](how-to/view-packages.md) | Customer package and readiness JSON can be inspected without uploading data. | | Deploy on Kubernetes | [Kubernetes deployment](kubernetes.md) | API and worker deploy with external PostgreSQL, object storage, and external signing mode. | | Build an offline package | [Air-gapped installation](air-gapped.md) | Package manifests and signatures are verified before import. | +| Prepare a design-partner pilot | [Pilot deployment checklist](how-to/pilot-deployment-checklist.md) | One narrow pilot profile is reviewed for environment, database, object storage, access, signing, TLS, backups, migrations, redaction, and support. | | Review production hardening | [Production hardening review](production-hardening.md) | Unsafe defaults, backup gaps, diagnostics exposure, and customer package handling are reviewed. | | Rehearse backup and restore | [Backup and restore runbook](runbooks/backup-restore.md) | Database/object-store pairing and post-restore verification are recorded. | | Upgrade a deployment | [Upgrade runbook](runbooks/upgrade.md) | Release artifacts, migrations, and post-upgrade verification are checked. | diff --git a/docs/reference/source-of-truth.md b/docs/reference/source-of-truth.md index 11e4c5a..726b3e0 100644 --- a/docs/reference/source-of-truth.md +++ b/docs/reference/source-of-truth.md @@ -15,6 +15,7 @@ product-boundary language across the docs. | Release-candidate evidence | `docs/reference/release-candidate.md` | Canonical release-candidate artifact checklist. | | Release evidence artifact map | `docs/reference/release-evidence-index.md` | Maps each release artifact to generation and verification commands. | | Production profiles and exit criteria | `docs/reference/production-readiness.md` and `docs/reference/production-exit-review.md` | Do not broaden status elsewhere without updating these. | +| Design-partner pilot checklist | `docs/how-to/pilot-deployment-checklist.md` | Narrow copy-paste checklist for one controlled self-hosted pilot profile. | | Maintainer review ownership | `CODEOWNERS` and `docs/reference/maintainer-review-policy.md` | Branch protection or repository rules must enforce this before it is a merge gate. | | Roadmap and cadence | `docs/reference/roadmap.md` | Public roadmap, supported release line, and cadence expectations. | | Backup/restore | `docs/runbooks/backup-restore.md` | Operator rehearsal steps and evidence to keep. | From 139f7c9252f0f3609ddaf86bb6c4fe40dd09ac09 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:49:13 +0300 Subject: [PATCH 199/287] docs(commercial): add design partner pilot offer --- .productization_next_steps.md | 2 +- Makefile | 3 + docs/README.md | 1 + docs/commercial/design-partner-pilot.md | 96 +++++++++++++++++++++++++ docs/reference/source-of-truth.md | 1 + 5 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 docs/commercial/design-partner-pilot.md diff --git a/.productization_next_steps.md b/.productization_next_steps.md index 90e9671..43d0ef2 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -1042,7 +1042,7 @@ Goal: Backlog: -#### [ ] EVY-090 — Add “Design Partner Pilot” offer doc +#### [x] EVY-090 — Add “Design Partner Pilot” offer doc Priority: P1 diff --git a/Makefile b/Makefile index 847e793..6c69d05 100644 --- a/Makefile +++ b/Makefile @@ -229,6 +229,9 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'Required: external PostgreSQL' docs/how-to/pilot-deployment-checklist.md >/dev/null @grep -F 'Required: object paths are tenant-prefixed' docs/how-to/pilot-deployment-checklist.md >/dev/null @grep -F 'Required: public API access is behind TLS' docs/how-to/pilot-deployment-checklist.md >/dev/null + @test -f docs/commercial/design-partner-pilot.md + @grep -F 'AGPL-3.0-only' docs/commercial/design-partner-pilot.md >/dev/null + @grep -F 'Non-Deliverables' docs/commercial/design-partner-pilot.md >/dev/null @grep -F 'release upload-evidence' docs/how-to/integrate-ci.md >/dev/null @grep -F -- '--dry-run' docs/how-to/integrate-ci.md >/dev/null @grep -F 'upload validate-manifest' docs/how-to/integrate-ci.md >/dev/null diff --git a/docs/README.md b/docs/README.md index 26125ae..d74848d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -52,6 +52,7 @@ This documentation is organized by reader task. Implementation claims should be - [License](../LICENSE): `AGPL-3.0-only` public license text. - [Commercial licensing](../COMMERCIAL.md): commercial license exceptions, self-hosted support, release evidence packages, deployment review, and custom integration support. +- [Design partner pilot](commercial/design-partner-pilot.md): narrow paid pilot shape for one self-hosted release evidence workflow. - [Security policy](../SECURITY.md): vulnerability reporting guidance for tenant isolation, evidence integrity, credentials, collectors, object storage, signing, reports, exports, and raw evidence payloads. - [Support](../SUPPORT.md): community support expectations, commercial support boundaries, and sanitized bug-report requirements. - [Governance](../GOVERNANCE.md): maintainer-led decision process, contribution acceptance, release evidence expectations, and conservative product-language policy. diff --git a/docs/commercial/design-partner-pilot.md b/docs/commercial/design-partner-pilot.md new file mode 100644 index 0000000..f753304 --- /dev/null +++ b/docs/commercial/design-partner-pilot.md @@ -0,0 +1,96 @@ +# Design Partner Pilot + +This page describes a narrow paid pilot shape for teams evaluating Evydence as a +self-hosted release evidence ledger. It is commercial positioning, not a legal +compliance statement, certification, audit opinion, complete SBOM claim, +authoritative vulnerability assessment, or secure-release guarantee. + +## Pilot Offer + +We wire one software product release into Evydence, ingest SBOM, +vulnerability-scan, VEX/provenance, and artifact evidence, produce one signed +customer-safe evidence bundle or package, and review the self-hosted deployment +profile with the operator. + +The goal is to prove whether Evydence can organize, verify, and present the +technical evidence a release team already has, while making gaps, assumptions, +exceptions, and limitations explicit. + +## Ideal Customer Profile + +This pilot is a fit when the team: + +- ships software products where release evidence is requested by customers, + procurement, internal security, or engineering leadership; +- can run a self-hosted service with PostgreSQL, object storage, TLS, backups, + and operator-owned secrets; +- already generates at least one SBOM and one vulnerability scan result in CI or + release tooling; +- wants VEX-style vulnerability decisions and customer-safe package outputs; +- accepts a controlled self-hosted candidate profile with one API writer replica + and scalable worker replicas. + +It is not a fit when the team needs a hosted SaaS service, broad GRC workflow, +legal compliance determination, certification, scanner replacement, or +regulator/auditor-ready evidence without independent review. + +## Deliverables + +- One agreed product and release modeled in Evydence. +- One SBOM upload path and one vulnerability-scan upload path connected to the + release. +- One VEX document, manual vulnerability decision, or approved exception path + for an intentionally reviewed finding. +- One artifact digest and release bundle generated through Evydence. +- One customer-safe package or evidence bundle with manifest, verification + material, limitations, and non-claims. +- One deployment-profile review using the + [pilot deployment checklist](../how-to/pilot-deployment-checklist.md). +- One short findings summary covering implemented evidence, gaps, assumptions, + and next steps. + +## Non-Deliverables + +- Legal compliance advice or certification. +- A guarantee that the release is secure. +- A completeness guarantee for SBOM contents. +- A completeness or authority guarantee for scanner output. +- Hosted SaaS operation by default. +- Replacement of customer security review, external audit, or legal review. +- Unlimited integration work, custom UI, or provider-specific development beyond + the agreed pilot scope. +- Public disclosure of customer data, secrets, raw evidence payloads, private + keys, bearer tokens, database URLs, provider credentials, or unreleased + product details. + +## License And Commercial Path + +Evydence is available under `AGPL-3.0-only`. Teams that can comply with AGPL +obligations may evaluate and operate the public code under that license. + +Commercial license exceptions and paid self-hosted support are available when +AGPL obligations are not suitable for a proprietary deployment, private +distribution model, or internal commercial use. See +[Commercial licensing](../../COMMERCIAL.md) for the current license boundary. + +## Support Boundary + +Pilot support focuses on the agreed deployment, evidence workflow, package +verification, and documentation. Operators remain responsible for infrastructure +controls such as TLS, network policy, backup tooling, secret storage, object +storage retention, KMS/HSM configuration, identity-provider configuration, and +incident response. + +Bug reports and security reports must be sanitized. Do not send raw customer +evidence, tokens, private keys, database URLs, object-store credentials, or +unredacted vulnerability reports through public channels. + +## Pilot Exit Criteria + +- The agreed release evidence flow runs end to end. +- The customer-safe package verifies offline and states its limitations. +- The deployment checklist is completed or has explicit accepted gaps. +- The operator can explain backup, restore, signing, redaction, and scoped + access responsibilities. +- Follow-up work is separated into repo-local product gaps, deployment + responsibilities, and external provider dependencies. diff --git a/docs/reference/source-of-truth.md b/docs/reference/source-of-truth.md index 726b3e0..f1e081c 100644 --- a/docs/reference/source-of-truth.md +++ b/docs/reference/source-of-truth.md @@ -24,6 +24,7 @@ product-boundary language across the docs. | Capacity and failure modes | `docs/reference/capacity-and-failures.md` and `docs/reference/benchmark-results.md` | Benchmark results are narrow and local. | | Security reporting | `SECURITY.md` | Repository settings for private reporting must be verified on GitHub. | | Support expectations | `SUPPORT.md` | Public support boundaries and sanitized-report rules. | +| Commercial pilot positioning | `docs/commercial/design-partner-pilot.md` and `COMMERCIAL.md` | Pilot docs must not imply legal compliance, certification, scanner authority, SBOM completeness, or secure releases. | ## Repetition Policy From fb68e2527591d5e475a143f20695da8c6a7902ca Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:50:24 +0300 Subject: [PATCH 200/287] docs(marketing): add conservative product landing copy --- .productization_next_steps.md | 2 +- Makefile | 4 ++ docs/README.md | 1 + docs/commercial/product-landing-copy.md | 74 +++++++++++++++++++++++++ docs/reference/source-of-truth.md | 1 + 5 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 docs/commercial/product-landing-copy.md diff --git a/.productization_next_steps.md b/.productization_next_steps.md index 43d0ef2..a34b8ee 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -1063,7 +1063,7 @@ Acceptance criteria: * Mentions support boundaries. * Includes ideal customer profile. -#### [ ] EVY-091 — Add product landing copy +#### [x] EVY-091 — Add product landing copy Priority: P1 diff --git a/Makefile b/Makefile index 6c69d05..30d7b34 100644 --- a/Makefile +++ b/Makefile @@ -232,6 +232,10 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @test -f docs/commercial/design-partner-pilot.md @grep -F 'AGPL-3.0-only' docs/commercial/design-partner-pilot.md >/dev/null @grep -F 'Non-Deliverables' docs/commercial/design-partner-pilot.md >/dev/null + @test -f docs/commercial/product-landing-copy.md + @grep -F 'One-Sentence Pitch' docs/commercial/product-landing-copy.md >/dev/null + @grep -F 'Why Self-Hosted' docs/commercial/product-landing-copy.md >/dev/null + @grep -F 'Pilot CTA' docs/commercial/product-landing-copy.md >/dev/null @grep -F 'release upload-evidence' docs/how-to/integrate-ci.md >/dev/null @grep -F -- '--dry-run' docs/how-to/integrate-ci.md >/dev/null @grep -F 'upload validate-manifest' docs/how-to/integrate-ci.md >/dev/null diff --git a/docs/README.md b/docs/README.md index d74848d..c59b35a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -53,6 +53,7 @@ This documentation is organized by reader task. Implementation claims should be - [License](../LICENSE): `AGPL-3.0-only` public license text. - [Commercial licensing](../COMMERCIAL.md): commercial license exceptions, self-hosted support, release evidence packages, deployment review, and custom integration support. - [Design partner pilot](commercial/design-partner-pilot.md): narrow paid pilot shape for one self-hosted release evidence workflow. +- [Product landing copy](commercial/product-landing-copy.md): conservative reusable positioning for README, website, outreach, or pilot materials. - [Security policy](../SECURITY.md): vulnerability reporting guidance for tenant isolation, evidence integrity, credentials, collectors, object storage, signing, reports, exports, and raw evidence payloads. - [Support](../SUPPORT.md): community support expectations, commercial support boundaries, and sanitized bug-report requirements. - [Governance](../GOVERNANCE.md): maintainer-led decision process, contribution acceptance, release evidence expectations, and conservative product-language policy. diff --git a/docs/commercial/product-landing-copy.md b/docs/commercial/product-landing-copy.md new file mode 100644 index 0000000..3c0fca5 --- /dev/null +++ b/docs/commercial/product-landing-copy.md @@ -0,0 +1,74 @@ +# Product Landing Copy + +This page is reusable copy for README sections, a website, outreach, or pilot +materials. Keep the wording aligned with repository evidence and avoid legal +compliance, certification, complete SBOM, scanner-authority, or release-security +guarantees. + +## Headline + +Release evidence customers can verify without handing control to another SaaS. + +## One-Sentence Pitch + +Evydence is a self-hosted API evidence ledger that organizes release artifacts, +SBOMs, vulnerability decisions, VEX, build provenance, controls, exceptions, and +customer-safe packages into reproducible, tamper-evident records. + +## Problem + +Software teams are asked for release evidence by customers, procurement, +security review, and internal leadership. The evidence usually lives across CI, +artifact stores, scanners, spreadsheets, tickets, GRC tools, and ad hoc folders. + +That makes it hard to answer practical questions: + +- what shipped in this release; +- which SBOM, scan, build, VEX, exception, and approval records support it; +- what is missing or explicitly assumed; +- what can be shared with a customer without exposing raw internal evidence; +- how a reviewer can verify the package later. + +## How It Works + +1. Model products, releases, artifacts, collectors, and controls. +2. Ingest evidence from APIs, CI workflows, SBOMs, scans, OpenVEX, source + snapshots, and build attestations. +3. Preserve raw payload hashes and tenant-scoped object references while + normalizing reviewer-safe summaries. +4. Record decisions, exceptions, approvals, lifecycle events, and audit-chain + entries append-only. +5. Generate release-readiness reports, signed bundles, evidence bundles, and + customer-safe packages with limitations and verification material. + +## Why Self-Hosted + +Evydence is designed for teams that need evidence custody, tenant-local storage, +operator-controlled secrets, private package workflows, and deployment-specific +trust decisions. + +Self-hosting lets the operator choose PostgreSQL, object storage, signing mode, +backup strategy, network boundaries, and customer-sharing policy. It also keeps +Evydence out of the path of claiming legal or audit conclusions on the +operator's behalf. + +## What It Is Not + +- Not a vulnerability scanner. +- Not an SBOM generator. +- Not a broad SaaS GRC platform. +- Not a public trust center. +- Not a legal compliance determination. +- Not a certification service. +- Not a guarantee that a release is secure. +- Not a substitute for customer review, external audit, or legal advice. + +## Pilot CTA + +Design-partner pilot: connect one product release, ingest SBOM plus vulnerability +scan plus VEX/provenance evidence, produce one signed customer-safe evidence +bundle, and review the self-hosted deployment profile. + +See [Design Partner Pilot](design-partner-pilot.md) for scope, deliverables, +non-deliverables, support boundaries, and the AGPL/commercial license path. + diff --git a/docs/reference/source-of-truth.md b/docs/reference/source-of-truth.md index f1e081c..1dc351f 100644 --- a/docs/reference/source-of-truth.md +++ b/docs/reference/source-of-truth.md @@ -25,6 +25,7 @@ product-boundary language across the docs. | Security reporting | `SECURITY.md` | Repository settings for private reporting must be verified on GitHub. | | Support expectations | `SUPPORT.md` | Public support boundaries and sanitized-report rules. | | Commercial pilot positioning | `docs/commercial/design-partner-pilot.md` and `COMMERCIAL.md` | Pilot docs must not imply legal compliance, certification, scanner authority, SBOM completeness, or secure releases. | +| Reusable product copy | `docs/commercial/product-landing-copy.md` | Website, outreach, and README excerpts should start from this conservative copy. | ## Repetition Policy From a3e9807fe85b9b776a0c753321b03ffb7fb08699 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:52:47 +0300 Subject: [PATCH 201/287] docs(marketing): add category comparison --- .productization_next_steps.md | 2 +- Makefile | 4 ++ docs/README.md | 1 + docs/commercial/category-comparison.md | 60 ++++++++++++++++++++++++++ docs/reference/source-of-truth.md | 1 + 5 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 docs/commercial/category-comparison.md diff --git a/.productization_next_steps.md b/.productization_next_steps.md index a34b8ee..96fb777 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -1082,7 +1082,7 @@ Acceptance criteria: * Pilot CTA. * No unsupported claims. -#### [ ] EVY-092 — Add comparison page: Evydence vs scanners/GRC/trust centers +#### [x] EVY-092 — Add comparison page: Evydence vs scanners/GRC/trust centers Priority: P2 diff --git a/Makefile b/Makefile index 30d7b34..b22a243 100644 --- a/Makefile +++ b/Makefile @@ -236,6 +236,10 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'One-Sentence Pitch' docs/commercial/product-landing-copy.md >/dev/null @grep -F 'Why Self-Hosted' docs/commercial/product-landing-copy.md >/dev/null @grep -F 'Pilot CTA' docs/commercial/product-landing-copy.md >/dev/null + @test -f docs/commercial/category-comparison.md + @grep -F 'Vulnerability scanners' docs/commercial/category-comparison.md >/dev/null + @grep -F 'SBOM inventory tools' docs/commercial/category-comparison.md >/dev/null + @grep -F 'Trust centers' docs/commercial/category-comparison.md >/dev/null @grep -F 'release upload-evidence' docs/how-to/integrate-ci.md >/dev/null @grep -F -- '--dry-run' docs/how-to/integrate-ci.md >/dev/null @grep -F 'upload validate-manifest' docs/how-to/integrate-ci.md >/dev/null diff --git a/docs/README.md b/docs/README.md index c59b35a..342196b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -54,6 +54,7 @@ This documentation is organized by reader task. Implementation claims should be - [Commercial licensing](../COMMERCIAL.md): commercial license exceptions, self-hosted support, release evidence packages, deployment review, and custom integration support. - [Design partner pilot](commercial/design-partner-pilot.md): narrow paid pilot shape for one self-hosted release evidence workflow. - [Product landing copy](commercial/product-landing-copy.md): conservative reusable positioning for README, website, outreach, or pilot materials. +- [Category comparison](commercial/category-comparison.md): fair positioning against scanners, SBOM inventory tools, broad GRC, trust centers, and scripts. - [Security policy](../SECURITY.md): vulnerability reporting guidance for tenant isolation, evidence integrity, credentials, collectors, object storage, signing, reports, exports, and raw evidence payloads. - [Support](../SUPPORT.md): community support expectations, commercial support boundaries, and sanitized bug-report requirements. - [Governance](../GOVERNANCE.md): maintainer-led decision process, contribution acceptance, release evidence expectations, and conservative product-language policy. diff --git a/docs/commercial/category-comparison.md b/docs/commercial/category-comparison.md new file mode 100644 index 0000000..8c4a788 --- /dev/null +++ b/docs/commercial/category-comparison.md @@ -0,0 +1,60 @@ +# Category Comparison + +This page explains where Evydence fits next to scanners, SBOM inventory tools, +GRC platforms, trust centers, and scripts. It is intended to help buyers choose +the right tool for the job. The categories below solve real problems; Evydence +exists because release-level evidence packaging and verification is usually a +separate workflow. + +## Short Version + +Evydence is a self-hosted release evidence ledger. It organizes technical +evidence, decisions, exceptions, bundles, audit chains, controls, and +customer-safe packages around a product release. + +It complements tools that generate findings, inventories, questionnaires, or +customer portals. It does not replace them. + +## Comparison + +| Category | Strong At | Common Boundary | Where Evydence Fits | +| --- | --- | --- | --- | +| Vulnerability scanners | Finding known issues in source, containers, dependencies, or deployed surfaces. | Scanner output often needs release context, VEX decisions, exceptions, and customer-safe explanation. | Stores scanner output as evidence, links findings to releases and artifacts, records decisions and exceptions, and reports unresolved release blockers. | +| SBOM inventory tools | Tracking components, dependency inventories, and vulnerability exposure over time. | Inventory views do not always answer which evidence package supports a specific customer release. | Links SBOMs to artifacts/releases, preserves hashes, and exports release-scoped package material. | +| Broad GRC tools | Managing controls, tasks, vendor questionnaires, policies, and organization-wide compliance workflows. | Broad workflow can be too high level for reproducible release evidence and raw technical artifact verification. | Provides release-level technical evidence and control coverage inputs that can support GRC workflows without claiming to replace review. | +| Trust centers | Publishing selected security documents and package material to customers. | Public portals usually depend on curated upstream evidence and redaction decisions. | Generates scoped, verifiable package manifests and static reports that can feed a trust center or be shared offline. | +| DIY scripts and spreadsheets | Fast local coordination for one team or one release. | Harder to keep append-only history, tenant scope, signatures, audit chains, and repeatable package structure. | Provides a repeatable API, manifest schema, verification commands, and release evidence workflow. | + +## Why Evydence Exists + +Release review commonly needs a single answer to a concrete question: + +> What technical evidence supports this release, what decisions were made, what +> gaps remain, and what can be shared safely? + +Evydence focuses on that release-level answer: + +- release-scoped artifacts, SBOMs, scans, VEX, provenance, controls, decisions, + exceptions, and approvals; +- append-only evidence lifecycle and audit-chain records; +- signed release bundles and verification receipts; +- customer-safe packages with redaction, limitations, and non-claims; +- self-hosted storage and operator-controlled trust boundaries. + +## When Another Tool Should Lead + +- Use scanners to discover findings. +- Use SBOM generators to produce component lists. +- Use dependency-inventory tools for component management at scale. +- Use GRC platforms for broad organizational compliance workflow. +- Use trust centers for public or customer-facing distribution workflows. +- Use Evydence when the release team needs a reproducible evidence ledger and + package for a specific product release. + +## Boundaries + +Evydence supports compliance readiness and technical evidence organization. It +does not make legal compliance conclusions, grant certification, prove SBOM +completeness, treat scanner output as authoritative, or guarantee release +security. + diff --git a/docs/reference/source-of-truth.md b/docs/reference/source-of-truth.md index 1dc351f..34b6040 100644 --- a/docs/reference/source-of-truth.md +++ b/docs/reference/source-of-truth.md @@ -26,6 +26,7 @@ product-boundary language across the docs. | Support expectations | `SUPPORT.md` | Public support boundaries and sanitized-report rules. | | Commercial pilot positioning | `docs/commercial/design-partner-pilot.md` and `COMMERCIAL.md` | Pilot docs must not imply legal compliance, certification, scanner authority, SBOM completeness, or secure releases. | | Reusable product copy | `docs/commercial/product-landing-copy.md` | Website, outreach, and README excerpts should start from this conservative copy. | +| Category comparison | `docs/commercial/category-comparison.md` | Keep comparisons fair, non-hostile, and focused on category boundaries. | ## Repetition Policy From 8f928f78b94d92613d19fd496887d9cf0b6249af Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:54:28 +0300 Subject: [PATCH 202/287] test(app): add vex-first release evidence flow --- .productization_next_steps.md | 2 +- internal/app/productization_flow_test.go | 216 +++++++++++++++++++++++ 2 files changed, 217 insertions(+), 1 deletion(-) create mode 100644 internal/app/productization_flow_test.go diff --git a/.productization_next_steps.md b/.productization_next_steps.md index 96fb777..fd12b9c 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -1115,7 +1115,7 @@ Goal: Backlog: -#### [ ] EVY-100 — Add end-to-end VEX-first integration test +#### [x] EVY-100 — Add end-to-end VEX-first integration test Priority: P0 diff --git a/internal/app/productization_flow_test.go b/internal/app/productization_flow_test.go new file mode 100644 index 0000000..4852438 --- /dev/null +++ b/internal/app/productization_flow_test.go @@ -0,0 +1,216 @@ +package app + +import ( + "context" + "encoding/json" + "strings" + "testing" + "time" + + "github.com/aatuh/evydence/internal/domain" +) + +func TestVEXFirstReleaseEvidenceFlowEndToEnd(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + _, _, secret, err := ledger.BootstrapTenant(ctx, "Design Partner", "admin", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap: %v", err) + } + actor, err := ledger.Authenticate(ctx, secret) + if err != nil { + t.Fatalf("auth: %v", err) + } + + product, err := ledger.CreateProduct(ctx, actor, "Demo Payments API", "demo-payments-api") + if err != nil { + t.Fatalf("product: %v", err) + } + release, err := ledger.CreateRelease(ctx, actor, product.ID, "2026.05.0") + if err != nil { + t.Fatalf("release: %v", err) + } + project, err := ledger.CreateProject(ctx, actor, product.ID, "payments-api") + if err != nil { + t.Fatalf("project: %v", err) + } + artifact, err := ledger.RegisterArtifact(ctx, actor, "payments-api-linux-amd64.tar.gz", "application/gzip", sampleDigest("artifact"), 123456) + if err != nil { + t.Fatalf("artifact: %v", err) + } + + sbom, err := ledger.UploadSBOM(ctx, actor, release.ID, artifact.ID, []byte(`{ + "bomFormat":"CycloneDX", + "specVersion":"1.6", + "components":[ + {"name":"openssl","version":"3.1.0","purl":"pkg:apk/openssl@3.1.0"}, + {"name":"curl","version":"8.0.0","purl":"pkg:apk/curl@8.0.0"} + ] + }`)) + if err != nil { + t.Fatalf("sbom: %v", err) + } + if sbom.ComponentCount != 2 || sbom.EvidenceID == "" { + t.Fatalf("sbom parsed metadata = %#v", sbom) + } + + scan, err := ledger.UploadVulnerabilityScan(ctx, actor, []byte(`{ + "scanner":"grype", + "target_ref":"pkg:oci/demo-payments-api@sha256:example", + "release_id":"`+release.ID+`", + "findings":[ + {"vulnerability":"CVE-2026-1000","component":"pkg:apk/openssl@3.1.0","severity":"critical","state":"open"}, + {"vulnerability":"CVE-2026-1001","component":"pkg:apk/curl@8.0.0","severity":"high","state":"open"} + ] + }`)) + if err != nil { + t.Fatalf("scan: %v", err) + } + if len(scan.Findings) != 2 { + t.Fatalf("scan findings = %#v", scan.Findings) + } + + vex, err := ledger.UploadVEX(ctx, actor, release.ID, artifact.ID, openVEXFixture(t, []map[string]any{ + openVEXStatementFixture("CVE-2026-1000", []map[string]any{{"@id": "pkg:apk/openssl@3.1.0"}}, decisionStatusNotAffected, "component_not_present"), + })) + if err != nil { + t.Fatalf("vex: %v", err) + } + importReport, err := ledger.GetVEXImportReport(ctx, actor, vex.ID) + if err != nil { + t.Fatalf("vex import report: %v", err) + } + if importReport.DecisionsCreated != 1 || len(importReport.MappingFailures) != 0 { + t.Fatalf("vex import report = %#v", importReport) + } + active := true + decisions, err := ledger.ListVulnerabilityDecisions(ctx, actor, ListVulnerabilityDecisionsInput{ReleaseID: release.ID, Vulnerability: "CVE-2026-1000", Active: &active}) + if err != nil { + t.Fatalf("list decisions: %v", err) + } + if len(decisions) != 1 || decisions[0].Source != "vex" || decisions[0].VEXDocumentID != vex.ID || !decisions[0].CustomerVisible { + t.Fatalf("vex decisions = %#v", decisions) + } + + exception, err := ledger.CreateException(ctx, actor, CreateExceptionInput{ + ReleaseID: release.ID, + FindingID: scan.Findings[1].ID, + Reason: "accepted for the pilot release while vendor update is scheduled", + Owner: "security", + ExpiresAt: fixedNow().Add(24 * time.Hour), + }) + if err != nil { + t.Fatalf("exception: %v", err) + } + if _, err := ledger.ApproveException(ctx, actor, exception.ID); err != nil { + t.Fatalf("approve exception: %v", err) + } + + build, err := ledger.CreateBuildRun(ctx, actor, CreateBuildRunInput{ + ProjectID: project.ID, + ReleaseID: release.ID, + Provider: "github_actions", + CommitSHA: "0123456789abcdef0123456789abcdef01234567", + Repository: "aatuh/evydence", + WorkflowRef: "aatuh/evydence/.github/workflows/release.yml@refs/heads/main", + RunID: "123456789", + RunAttempt: 1, + Status: "passed", + StartedAt: fixedNow(), + Outputs: []domain.BuildOutput{{ArtifactID: artifact.ID, Digest: artifact.Digest}}, + }) + if err != nil { + t.Fatalf("build: %v", err) + } + if _, err := ledger.UploadBuildAttestation(ctx, actor, build.ID, dsseForDigest(t, artifact.Digest)); err != nil { + t.Fatalf("attestation: %v", err) + } + + bundle, err := ledger.CreateReleaseBundle(ctx, actor, release.ID) + if err != nil { + t.Fatalf("bundle: %v", err) + } + bundleVerification, err := ledger.VerifySubject(ctx, actor, "release_bundle", bundle.ID) + if err != nil { + t.Fatalf("verify bundle: %v", err) + } + if bundleVerification.Result != "passed" { + t.Fatalf("bundle verification = %#v", bundleVerification) + } + + readiness, err := ledger.ReleaseReadinessReport(ctx, actor, release.ID) + if err != nil { + t.Fatalf("readiness: %v", err) + } + if readiness.Result != "passed" || len(readiness.BlockingFindings) != 0 || len(readiness.AcceptedExceptions) != 1 { + t.Fatalf("readiness = %#v", readiness) + } + if policyCheckByName(t, readiness.Checks, "critical_exploitable_blocks_release").Result != "passed" { + t.Fatalf("critical policy should pass: %#v", readiness.Checks) + } + + profile, err := ledger.CreateRedactionProfile(ctx, actor, CreateRedactionProfileInput{ + Name: "customer release evidence", + AllowedTypes: []string{ + "artifact", "sbom", "vulnerability_scan", "vex", "vulnerability_decision", "exception", "build", "build_attestation", "release_bundle", + }, + }) + if err != nil { + t.Fatalf("redaction profile: %v", err) + } + pkg, err := ledger.CreateCustomerSecurityPackage(ctx, actor, CreateCustomerPackageInput{ + ProductID: product.ID, + ReleaseID: release.ID, + RedactionProfileID: profile.ID, + Title: "Demo Payments API release evidence", + ExpiresAt: fixedNow().Add(7 * 24 * time.Hour), + }) + if err != nil { + t.Fatalf("customer package: %v", err) + } + if pkg.ManifestHash == "" || pkg.SchemaVersion != domain.CustomerPackageSchemaVersion { + t.Fatalf("package metadata = %#v", pkg) + } + manifestHash, err := canonicalAnyHash(pkg.Manifest) + if err != nil { + t.Fatalf("hash manifest: %v", err) + } + if manifestHash != pkg.ManifestHash { + t.Fatalf("manifest hash = %s, want %s", manifestHash, pkg.ManifestHash) + } + + archive, err := ledger.ExportCustomerSecurityPackageArchive(ctx, actor, pkg.ID) + if err != nil { + t.Fatalf("export archive: %v", err) + } + files := packageArchiveFiles(t, archive.Bytes) + for _, name := range []string{"manifest.json", "package.json", "verification.json", "README.txt", "report.html"} { + if strings.TrimSpace(files[name]) == "" { + t.Fatalf("archive missing %s: %#v", name, files) + } + } + manifestText := files["manifest.json"] + for _, want := range []string{product.ID, release.ID, artifact.Digest, sbom.ID, scan.ID, vex.ID, decisions[0].ID, exception.ID, bundle.ManifestHash, "audit_chain", "passed"} { + if !strings.Contains(manifestText, want) { + t.Fatalf("manifest missing %q: %s", want, manifestText) + } + } + for _, forbidden := range []string{"payload_ref", "object://", "api_key_secret", "private_key_value", "bearer_secret_value", "database_url"} { + if strings.Contains(strings.ToLower(manifestText), forbidden) { + t.Fatalf("manifest leaked %q: %s", forbidden, manifestText) + } + } + reportHTML := files["report.html"] + if !strings.Contains(reportHTML, "Release Summary") || !strings.Contains(reportHTML, "Verification") || strings.Contains(reportHTML, " Date: Sun, 31 May 2026 22:56:30 +0300 Subject: [PATCH 203/287] test(package): add redaction leakage guards --- .productization_next_steps.md | 2 +- Makefile | 1 + docs/reference/customer-package-manifest.md | 9 + internal/app/redaction_leakage_test.go | 172 ++++++++++++++++++++ 4 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 internal/app/redaction_leakage_test.go diff --git a/.productization_next_steps.md b/.productization_next_steps.md index fd12b9c..b95f051 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -1142,7 +1142,7 @@ Acceptance criteria: * Output fixtures are stable or regenerated intentionally. * Catches regressions in main product path. -#### [ ] EVY-101 — Add redaction leakage tests +#### [x] EVY-101 — Add redaction leakage tests Priority: P0 diff --git a/Makefile b/Makefile index b22a243..a9b1e4a 100644 --- a/Makefile +++ b/Makefile @@ -223,6 +223,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @test -f docs/assets/package-viewer-preview.svg @grep -F 'package-viewer-preview.svg' docs/how-to/view-packages.md >/dev/null @grep -F 'report.html' docs/reference/customer-package-manifest.md docs/how-to/view-packages.md >/dev/null + @grep -F 'Redaction Leakage Guard' docs/reference/customer-package-manifest.md >/dev/null @grep -F 'v0.1.0-rc.4 - 2026-05-31' CHANGELOG.md >/dev/null @grep -F 'make restore-rehearsal-check' docs/runbooks/backup-restore.md >/dev/null @test -f docs/how-to/pilot-deployment-checklist.md diff --git a/docs/reference/customer-package-manifest.md b/docs/reference/customer-package-manifest.md index 0626b56..b348ca3 100644 --- a/docs/reference/customer-package-manifest.md +++ b/docs/reference/customer-package-manifest.md @@ -84,6 +84,15 @@ The HTML report is generated from package-scoped data only and excludes raw evidence payload bytes, object-store references, token material, private keys, and internal decision notes. +## Redaction Leakage Guard + +Customer package generation is tested with canary values for API key secrets, +internal decision notes, raw scanner payload bytes, internal URLs, object-store +paths, signing private material, tenant secrets, and internal-only evidence +fields. Runtime package archives and the checked sample fixture must not contain +those canaries, raw payload references, object-store URLs, source identity +metadata, uploader identifiers, or canonical evidence hashes. + ## Offline Verification The CLI verifies a package manifest without contacting the API: diff --git a/internal/app/redaction_leakage_test.go b/internal/app/redaction_leakage_test.go new file mode 100644 index 0000000..076584b --- /dev/null +++ b/internal/app/redaction_leakage_test.go @@ -0,0 +1,172 @@ +package app + +import ( + "context" + "encoding/base64" + "os" + "strings" + "testing" + "time" +) + +func TestCustomerPackageRedactionLeakageMatrix(t *testing.T) { + objects := newTestObjectStore() + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow, ObjectStore: objects}) + ctx := context.Background() + actor, release, artifact := setupReleaseRiskFixture(t, ledger) + + _, apiSecret, err := ledger.CreateAPIKey(ctx, actor, "leakage-test-key", []string{ScopeEvidenceRead}, nil) + if err != nil { + t.Fatalf("api key: %v", err) + } + internalNote := "INTERNAL-TRIAGE-NOTE-EVY-101" + internalURL := "https://internal.example.test/runbooks/evy-101" + rawScannerPayload := "RAW-SCANNER-PAYLOAD-EVY-101" + tenantSecret := "TENANT-SECRET-EVY-101" + privateMaterialCanary := "PRIVATE-SIGNING-MATERIAL-EVY-101" + + if _, err := ledger.UploadSBOM(ctx, actor, release.ID, artifact.ID, []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","components":[{"name":"openssl","version":"3.1.0","purl":"pkg:apk/openssl@3.1.0"}]}`)); err != nil { + t.Fatalf("sbom: %v", err) + } + scan, err := ledger.UploadVulnerabilityScan(ctx, actor, []byte(`{ + "scanner":"grype", + "target_ref":"pkg:oci/payments-api", + "release_id":"`+release.ID+`", + "findings":[{"vulnerability":"CVE-2026-1100","component":"pkg:apk/openssl@3.1.0","severity":"critical","state":"open"}] + }`)) + if err != nil { + t.Fatalf("vulnerability scan: %v", err) + } + decision, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{ + Status: decisionStatusNotAffected, + Justification: "internal review references " + internalURL, + ImpactStatement: "This release is not affected based on the customer-visible release evidence.", + ActionStatement: "Internal runbook: " + internalURL, + CustomerVisible: true, + InternalNotes: internalNote, + }) + if err != nil { + t.Fatalf("decision: %v", err) + } + if _, err := ledger.CreateEvidence(ctx, actor, CreateEvidenceInput{ + ProductID: release.ProductID, + ReleaseID: release.ID, + Type: "security_review", + Title: "Internal review", + PayloadRef: "object://tenants/" + actor.TenantID + "/payloads/manual/" + privateMaterialCanary, + PayloadHash: sampleDigest("review"), + Metadata: map[string]any{ + "tenant_secret": tenantSecret, + "internal_url": internalURL, + "private_key": privateMaterialCanary, + }, + SourceIdentity: map[string]any{"internal_url": internalURL}, + }); err != nil { + t.Fatalf("internal evidence: %v", err) + } + securityScan, err := ledger.UploadSecurityScan(ctx, actor, UploadSecurityScanInput{ + ProductID: release.ProductID, + ReleaseID: release.ID, + ArtifactID: artifact.ID, + Category: "secret_scan", + Format: "generic", + Scanner: "internal-secret-scanner", + TargetRef: "pkg:oci/payments-api", + Raw: []byte(`{"findings":[{"severity":"` + rawScannerPayload + `"}]}`), + }) + if err != nil { + t.Fatalf("security scan: %v", err) + } + addBuildProvenance(t, ledger, actor, release, artifact) + bundle, err := ledger.CreateReleaseBundle(ctx, actor, release.ID) + if err != nil { + t.Fatalf("bundle: %v", err) + } + + var privateKeyMaterial string + ledger.mu.Lock() + for _, key := range ledger.signingKeys { + if key.TenantID == actor.TenantID && len(key.Private) > 0 { + privateKeyMaterial = base64.RawStdEncoding.EncodeToString(key.Private) + break + } + } + ledger.mu.Unlock() + if privateKeyMaterial == "" { + t.Fatal("test setup did not create signing key material") + } + + profile, err := ledger.CreateRedactionProfile(ctx, actor, CreateRedactionProfileInput{ + Name: "customer leakage guard", + AllowedTypes: []string{ + "artifact", "sbom", "vulnerability_scan", "vulnerability_decision", "security_review", "secret_scan", "build", "build_attestation", "release_bundle", + }, + ExcludedFields: []string{"action_statement", "justification", "evidence_id", "evidence_ids", "internal_url"}, + }) + if err != nil { + t.Fatalf("redaction profile: %v", err) + } + pkg, err := ledger.CreateCustomerSecurityPackage(ctx, actor, CreateCustomerPackageInput{ + ProductID: release.ProductID, + ReleaseID: release.ID, + RedactionProfileID: profile.ID, + Title: "Customer leakage guard", + ExpiresAt: fixedNow().Add(24 * time.Hour), + }) + if err != nil { + t.Fatalf("package: %v", err) + } + archive, err := ledger.ExportCustomerSecurityPackageArchive(ctx, actor, pkg.ID) + if err != nil { + t.Fatalf("archive: %v", err) + } + files := packageArchiveFiles(t, archive.Bytes) + packageText := strings.Join(mapValues(files), "\n") + if !strings.Contains(packageText, decision.ImpactStatement) || !strings.Contains(packageText, bundle.ManifestHash) { + t.Fatalf("package missing expected customer-safe evidence: %s", packageText) + } + for _, forbidden := range []string{ + apiSecret, + internalNote, + internalURL, + rawScannerPayload, + tenantSecret, + privateMaterialCanary, + privateKeyMaterial, + securityScan.PayloadRef, + "payload_ref", + "object://", + "source_identity", + "uploaded_by", + "canonical_hash", + } { + if forbidden == "" { + continue + } + if strings.Contains(strings.ToLower(packageText), strings.ToLower(forbidden)) { + t.Fatalf("customer package leaked %q: %s", forbidden, packageText) + } + } +} + +func TestSampleCustomerPackageFixtureHasNoRedactionLeakage(t *testing.T) { + body, err := os.ReadFile("../../examples/end-to-end-release-evidence/sample-customer-package-manifest.json") + if err != nil { + t.Fatalf("read fixture: %v", err) + } + text := strings.ToLower(string(body)) + for _, forbidden := range []string{ + "payload_ref", + "object://", + "source_identity", + "uploaded_by", + "api_key_secret", + "private_key", + "database_url", + "raw_payload", + } { + if strings.Contains(text, forbidden) { + t.Fatalf("sample customer package fixture leaked %q: %s", forbidden, body) + } + } +} From a62e499e8282d1ba25a4406e4ba021592e1aa5bf Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 22:58:05 +0300 Subject: [PATCH 204/287] test(package): add customer package manifest golden --- .productization_next_steps.md | 2 +- Makefile | 2 + docs/reference/customer-package-manifest.md | 6 +++ .../sample-customer-package-manifest.sha256 | 1 + internal/app/customer_package_golden_test.go | 52 +++++++++++++++++++ 5 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 examples/end-to-end-release-evidence/sample-customer-package-manifest.sha256 create mode 100644 internal/app/customer_package_golden_test.go diff --git a/.productization_next_steps.md b/.productization_next_steps.md index b95f051..e91fa47 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -1182,7 +1182,7 @@ Acceptance criteria: * Changes require committed contract update. * Breaking changes are noted in changelog or release notes. -#### [ ] EVY-103 — Add fixture golden tests for package manifest +#### [x] EVY-103 — Add fixture golden tests for package manifest Priority: P1 diff --git a/Makefile b/Makefile index a9b1e4a..8b9b5f6 100644 --- a/Makefile +++ b/Makefile @@ -332,9 +332,11 @@ demo-check: ## Validate checked end-to-end evidence demo fixtures @test -f examples/end-to-end-release-evidence/sample-readiness-report.json @test -f examples/end-to-end-release-evidence/sample-security-summary.json @test -f examples/end-to-end-release-evidence/sample-customer-package-manifest.json + @test -f examples/end-to-end-release-evidence/sample-customer-package-manifest.sha256 @test -f examples/end-to-end-release-evidence/sample-customer-package.zip @test -f examples/end-to-end-release-evidence/sample-audit-chain-verification.json @python3 -c 'import json, pathlib; [json.loads(path.read_text()) for path in pathlib.Path("examples/end-to-end-release-evidence").glob("*.json")]' + @cd examples/end-to-end-release-evidence && sha256sum -c sample-customer-package-manifest.sha256 >/dev/null @$(GO) run ./cmd/evydence package verify --archive examples/end-to-end-release-evidence/sample-customer-package.zip --expected-package-id csp_example --expected-product-id prod_example --expected-release-id rel_example >/dev/null @grep -F '/v1/reports/release-readiness' examples/end-to-end-release-evidence/run-local-demo.sh >/dev/null @grep -F '/security-summary' examples/end-to-end-release-evidence/run-local-demo.sh >/dev/null diff --git a/docs/reference/customer-package-manifest.md b/docs/reference/customer-package-manifest.md index b348ca3..5021eb0 100644 --- a/docs/reference/customer-package-manifest.md +++ b/docs/reference/customer-package-manifest.md @@ -93,6 +93,12 @@ fields. Runtime package archives and the checked sample fixture must not contain those canaries, raw payload references, object-store URLs, source identity metadata, uploader identifiers, or canonical evidence hashes. +The sample manifest is also protected by +`examples/end-to-end-release-evidence/sample-customer-package-manifest.sha256`. +Intentional fixture or manifest-shape changes must update the JSON fixture and +checksum together, and the fixture schema version must match the current +`customer-security-package.v2.0.0` domain version. + ## Offline Verification The CLI verifies a package manifest without contacting the API: diff --git a/examples/end-to-end-release-evidence/sample-customer-package-manifest.sha256 b/examples/end-to-end-release-evidence/sample-customer-package-manifest.sha256 new file mode 100644 index 0000000..b12608b --- /dev/null +++ b/examples/end-to-end-release-evidence/sample-customer-package-manifest.sha256 @@ -0,0 +1 @@ +5079f1f386f7266a82c3d706b87db04f8c53fb4e65d53c1a6dbe3d9cb2e263e5 sample-customer-package-manifest.json diff --git a/internal/app/customer_package_golden_test.go b/internal/app/customer_package_golden_test.go new file mode 100644 index 0000000..ebfcffb --- /dev/null +++ b/internal/app/customer_package_golden_test.go @@ -0,0 +1,52 @@ +package app + +import ( + "crypto/sha256" + "encoding/hex" + "encoding/json" + "os" + "strings" + "testing" + + "github.com/aatuh/evydence/internal/domain" +) + +func TestSampleCustomerPackageManifestGolden(t *testing.T) { + body, err := os.ReadFile("../../examples/end-to-end-release-evidence/sample-customer-package-manifest.json") + if err != nil { + t.Fatalf("read manifest fixture: %v", err) + } + expectedBody, err := os.ReadFile("../../examples/end-to-end-release-evidence/sample-customer-package-manifest.sha256") + if err != nil { + t.Fatalf("read manifest checksum fixture: %v", err) + } + expectedHash := strings.Fields(string(expectedBody))[0] + sum := sha256.Sum256(body) + if got := hex.EncodeToString(sum[:]); got != expectedHash { + t.Fatalf("sample customer package manifest drifted: got sha256 %s want %s; update the fixture and checksum intentionally", got, expectedHash) + } + + var manifest map[string]any + if err := json.Unmarshal(body, &manifest); err != nil { + t.Fatalf("decode manifest fixture: %v", err) + } + for _, key := range []string{ + "schema_version", + "package_version", + "package_id", + "product", + "release", + "redaction_profile", + "readiness_summary", + "verification_material", + "limitations", + "non_claims", + } { + if _, ok := manifest[key]; !ok { + t.Fatalf("manifest fixture missing required key %q", key) + } + } + if manifest["schema_version"] != domain.CustomerPackageSchemaVersion || manifest["package_version"] != domain.CustomerPackageSchemaVersion { + t.Fatalf("manifest fixture schema version = schema:%v package:%v want %s", manifest["schema_version"], manifest["package_version"], domain.CustomerPackageSchemaVersion) + } +} From 7a7c8939ce603592649769147477f876cf47f466 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 23:01:00 +0300 Subject: [PATCH 205/287] docs(productization): add future backlog checkboxes --- .productization_next_steps.md | 58 +++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/.productization_next_steps.md b/.productization_next_steps.md index e91fa47..3c43f5b 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -1201,18 +1201,22 @@ Acceptance criteria: ### Milestone 12: Future Expansion Backlog These are valid later, but should not block the VEX-first product. +Parent items in this section stay unchecked until every listed sub-item is +implemented, documented, and covered by tests or release checks. Checked +sub-items record existing repository evidence so future work does not repeat +already-built surfaces. #### [ ] EVY-200 — Artifact exchange / trust package portal Potential later expansion: -* NDA-gated customer access -* package access logs -* time-limited links -* watermarking -* customer-specific packages -* answer library -* security questionnaire drafts +* [ ] NDA-gated customer access +* [x] package access counters and failed-attempt tracking +* [x] time-limited package links through expiring portal tokens +* [ ] watermarking +* [x] customer-specific packages through scoped customer package records +* [ ] answer library +* [x] security questionnaire drafts Only do this after customer-safe packages are strong. @@ -1220,9 +1224,11 @@ Only do this after customer-safe packages are strong. Potential later expansion: -* ingest OpenAPI diffs -* attach API breaking-change evidence to releases -* export API contract evidence into release package +* [x] ingest OpenAPI contracts and deterministic OpenAPI diffs +* [x] attach API breaking-change evidence to releases through `ContractDiff` + release links and audit-chain entries +* [ ] export API contract evidence into the customer/release package manifest + as a first-class package section Do not turn Evydence into the OpenAPI governance product itself. @@ -1230,10 +1236,11 @@ Do not turn Evydence into the OpenAPI governance product itself. Potential later expansion: -* CRA evidence mapping templates -* vulnerability handling report -* security update evidence report -* incident package template +* [x] CRA evidence mapping template pack +* [x] vulnerability posture report +* [ ] CRA-specific vulnerability handling report template +* [ ] security update evidence report +* [x] incident package report Keep language as readiness support, not legal conclusion. @@ -1241,10 +1248,14 @@ Keep language as readiness support, not legal conclusion. Potential later expansion: -* stronger HSM profiles -* object-lock proof packages -* transparency proof integrations -* deployment-specific custody review tooling +* [x] external signing provider records and operation receipts +* [x] HTTPS signing gateway executor +* [x] AWS KMS, GCP Cloud KMS, and Azure Key Vault signing executors +* [ ] native PKCS#11/HSM module profile beyond gateway-backed `pkcs11-hsm` +* [x] object-retention policy records and configured object-store verification +* [ ] object-lock proof packages for customer/release export +* [x] public transparency proof records, verification, and optional proof fetcher +* [ ] deployment-specific custody review tooling Do this when a real pilot requires it. @@ -1252,11 +1263,12 @@ Do this when a real pilot requires it. Potential later expansion: -* external reviewer accounts -* package tokens -* access logs -* expiry -* package download history +* [ ] external reviewer accounts +* [x] package tokens +* [x] access counters and failed-attempt counters +* [x] expiry +* [x] package ZIP download endpoint +* [ ] detailed package download history events Do this only after static/offline package flow is excellent. From 0bc68ae4f73c090fd7002b29ecb0cf70916d23a7 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 23:02:14 +0300 Subject: [PATCH 206/287] feat(package): export api contract evidence --- .productization_next_steps.md | 4 +- docs/reference/customer-package-manifest.md | 22 ++++- internal/app/governance_packages.go | 103 ++++++++++++++++++++ internal/app/governance_packages_test.go | 65 +++++++++++- 4 files changed, 183 insertions(+), 11 deletions(-) diff --git a/.productization_next_steps.md b/.productization_next_steps.md index 3c43f5b..366137d 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -1220,14 +1220,14 @@ Potential later expansion: Only do this after customer-safe packages are strong. -#### [ ] EVY-201 — OpenAPI governance integration +#### [x] EVY-201 — OpenAPI governance integration Potential later expansion: * [x] ingest OpenAPI contracts and deterministic OpenAPI diffs * [x] attach API breaking-change evidence to releases through `ContractDiff` release links and audit-chain entries -* [ ] export API contract evidence into the customer/release package manifest +* [x] export API contract evidence into the customer/release package manifest as a first-class package section Do not turn Evydence into the OpenAPI governance product itself. diff --git a/docs/reference/customer-package-manifest.md b/docs/reference/customer-package-manifest.md index 5021eb0..82f5b50 100644 --- a/docs/reference/customer-package-manifest.md +++ b/docs/reference/customer-package-manifest.md @@ -31,11 +31,23 @@ matching release-scoped records exist: - `vulnerability_scans`: scanner metadata, target reference, summary counts, and finding count. - `vex_documents`: VEX metadata, statement counts, status summary, and evidence ID. - `vulnerability_decisions`: active customer-visible decision summaries only. +- `api_contracts`: OpenAPI contract metadata, normalized operation summaries, + deterministic contract diff results, and API-contract limitations. - `approvals`: release or product approval records. - `exceptions`: approved, unexpired release exceptions. - `waivers`: approved, unexpired product or release waivers. - `provenance`: build runs and build attestation metadata. +The `api_contracts` section contains `openapi_contracts` and `contract_diffs`. +OpenAPI contract entries include IDs, evidence IDs, product/release scope, +version, SHA-256 hash, path and operation counts, and normalized operation +labels, methods, paths, operation IDs, required-request indicators, required +request fields, and response statuses. Contract diff entries include the base +and target contract IDs, result, breaking and non-breaking change summaries, +schema version, and timestamp. The section deliberately omits raw OpenAPI +document bytes, object-store references, and private/internal document +extensions. + ## Exclusions Customer package manifests exclude raw tenant evidence payload bytes, @@ -78,11 +90,11 @@ the matching archive fixture is Runtime ZIP exports also include `report.html`, a self-contained static HTML rendering of the redacted manifest. It shows release summary, VEX and -vulnerability-decision tables, readiness checks, verification material, -limitations, and non-claims without requiring a server or loading remote assets. -The HTML report is generated from package-scoped data only and excludes raw -evidence payload bytes, object-store references, token material, private keys, -and internal decision notes. +vulnerability-decision tables, API contract evidence when included, readiness +checks, verification material, limitations, and non-claims without requiring a +server or loading remote assets. The HTML report is generated from +package-scoped data only and excludes raw evidence payload bytes, object-store +references, token material, private keys, and internal decision notes. ## Redaction Leakage Guard diff --git a/internal/app/governance_packages.go b/internal/app/governance_packages.go index cdfca6d..0ee6fc9 100644 --- a/internal/app/governance_packages.go +++ b/internal/app/governance_packages.go @@ -442,6 +442,9 @@ func (l *Ledger) customerPackageManifestLocked(packageID string, generatedAt tim if profileAllowsPackageType(profile, "vex") { manifest["vex_documents"] = l.packageVEXMetadataLocked(tenantID, releaseID) } + if profileAllowsPackageType(profile, "openapi_contract") { + manifest["api_contracts"] = l.packageAPIContractMetadataLocked(tenantID, releaseID) + } if decisions := l.packageDecisionSummariesLocked(tenantID, releaseID, profile); len(decisions) > 0 { manifest["vulnerability_decisions"] = decisions } @@ -652,6 +655,83 @@ func (l *Ledger) packageVEXMetadataLocked(tenantID, releaseID string) []map[stri return out } +func (l *Ledger) packageAPIContractMetadataLocked(tenantID, releaseID string) map[string]any { + contracts := []map[string]any{} + for _, contract := range l.contracts { + if contract.TenantID != tenantID || contract.ReleaseID != releaseID { + continue + } + contracts = append(contracts, map[string]any{ + "id": contract.ID, + "evidence_id": contract.EvidenceID, + "product_id": contract.ProductID, + "release_id": contract.ReleaseID, + "version": contract.Version, + "hash": contract.Hash, + "path_count": contract.PathCount, + "operation_count": len(contract.Operations), + "operations": packageOpenAPIOperations(contract.Operations), + "created_at": contract.CreatedAt.UTC().Format(time.RFC3339), + }) + } + sortManifestMapsByID(contracts) + diffs := []map[string]any{} + for _, diff := range l.contractDiffs { + if diff.TenantID != tenantID || diff.ReleaseID != releaseID { + continue + } + diffs = append(diffs, map[string]any{ + "id": diff.ID, + "base_contract_id": diff.BaseContractID, + "target_contract_id": diff.TargetContractID, + "product_id": diff.ProductID, + "release_id": diff.ReleaseID, + "result": diff.Result, + "breaking_changes": append([]string(nil), diff.BreakingChanges...), + "non_breaking_changes": append([]string(nil), diff.NonBreakingChanges...), + "schema_version": diff.SchemaVersion, + "created_at": diff.CreatedAt.UTC().Format(time.RFC3339), + }) + } + sortManifestMapsByID(diffs) + return map[string]any{ + "openapi_contracts": contracts, + "contract_diffs": diffs, + "limitations": []string{ + "OpenAPI contract evidence includes stored metadata, hashes, and normalized operation summaries only.", + "Raw OpenAPI document bytes, object-store payload references, and private/internal extensions are not included.", + "Diff results summarize recorded contract evidence and do not make this package an API governance approval.", + }, + } +} + +func packageOpenAPIOperations(operations []domain.OpenAPIOperation) []map[string]any { + out := make([]map[string]any, 0, len(operations)) + for _, operation := range operations { + method := strings.ToUpper(strings.TrimSpace(operation.Method)) + path := strings.TrimSpace(operation.Path) + if method == "" || path == "" { + continue + } + out = append(out, map[string]any{ + "label": method + " " + path, + "path": path, + "method": method, + "operation_id": operation.OperationID, + "deprecated": operation.Deprecated, + "request_body_required": operation.RequestBodyRequired, + "required_request_fields": append([]string(nil), operation.RequiredRequestFields...), + "response_statuses": append([]string(nil), operation.ResponseStatuses...), + }) + } + sort.Slice(out, func(i, j int) bool { + left, _ := out[i]["label"].(string) + right, _ := out[j]["label"].(string) + return left < right + }) + return out +} + func (l *Ledger) packageApprovalSummariesLocked(tenantID, productID, releaseID string) []map[string]any { out := []map[string]any{} for _, approval := range l.approvals { @@ -1133,6 +1213,7 @@ func customerPackageHTMLReport(pkg domain.CustomerSecurityPackage, metadata, ver product := packageHTMLMap(manifest["product"]) release := packageHTMLMap(manifest["release"]) readiness := packageHTMLMap(manifest["readiness_summary"]) + apiContracts := packageHTMLMap(manifest["api_contracts"]) vexDocuments := packageHTMLRecords(manifest["vex_documents"]) decisions := packageHTMLRecords(manifest["vulnerability_decisions"]) limitations := packageHTMLStrings(manifest["limitations"]) @@ -1175,6 +1256,28 @@ func customerPackageHTMLReport(pkg domain.CustomerSecurityPackage, metadata, ver } } + b.WriteString("

API Contract Evidence

") + contractRecords := packageHTMLRecords(apiContracts["openapi_contracts"]) + diffRecords := packageHTMLRecords(apiContracts["contract_diffs"]) + if len(contractRecords) == 0 && len(diffRecords) == 0 { + b.WriteString("

No customer-visible OpenAPI contract evidence is included by this package profile.

") + } else { + if len(contractRecords) > 0 { + b.WriteString("

OpenAPI Contracts

") + for _, record := range contractRecords { + b.WriteString("") + } + b.WriteString("
IDVersionHashPathsOperations
" + packageHTMLEscape(packageHTMLString(record["id"])) + "" + packageHTMLEscape(packageHTMLString(record["version"])) + "" + packageHTMLEscape(packageHTMLString(record["hash"])) + "" + packageHTMLEscape(packageHTMLString(record["path_count"])) + "" + packageHTMLEscape(packageHTMLString(record["operation_count"])) + "
") + } + if len(diffRecords) > 0 { + b.WriteString("

Contract Diffs

") + for _, record := range diffRecords { + b.WriteString("") + } + b.WriteString("
IDResultBreaking ChangesNon-breaking Changes
" + packageHTMLEscape(packageHTMLString(record["id"])) + "" + packageHTMLEscape(packageHTMLString(record["result"])) + "" + packageHTMLEscape(packageHTMLJSON(record["breaking_changes"])) + "" + packageHTMLEscape(packageHTMLJSON(record["non_breaking_changes"])) + "
") + } + } + b.WriteString("

Readiness

") packageHTMLReadiness(&b, readiness) b.WriteString("

Verification

") diff --git a/internal/app/governance_packages_test.go b/internal/app/governance_packages_test.go index 6f585e4..549b9e8 100644 --- a/internal/app/governance_packages_test.go +++ b/internal/app/governance_packages_test.go @@ -125,6 +125,51 @@ func TestCustomerPackageV2ManifestSchemaAndSensitiveFieldExclusion(t *testing.T) if err != nil { t.Fatalf("project: %v", err) } + openAPIRawCanary := "RAW-OPENAPI-PAYLOAD-CANARY-EVY-201" + baseContract, err := ledger.UploadOpenAPIContract(ctx, actor, release.ProductID, release.ID, "v1", []byte(`{ + "openapi":"3.1.0", + "info":{"title":"Payments API","version":"1","description":"`+openAPIRawCanary+`"}, + "paths":{"/v1/payments":{"get":{"operationId":"listPayments","responses":{"200":{"description":"ok"}}}}} + }`)) + if err != nil { + t.Fatalf("base OpenAPI contract: %v", err) + } + targetContract, err := ledger.UploadOpenAPIContract(ctx, actor, release.ProductID, release.ID, "v2", []byte(`{ + "openapi":"3.1.0", + "info":{"title":"Payments API","version":"2"}, + "paths":{} + }`)) + if err != nil { + t.Fatalf("target OpenAPI contract: %v", err) + } + contractDiff, err := ledger.CreateContractDiff(ctx, actor, CreateContractDiffInput{BaseContractID: baseContract.ID, TargetContractID: targetContract.ID, ReleaseID: release.ID}) + if err != nil { + t.Fatalf("contract diff: %v", err) + } + _, _, foreignSecret, err := ledger.BootstrapTenant(ctx, "Foreign Tenant", "foreign", []string{"*"}) + if err != nil { + t.Fatalf("foreign bootstrap: %v", err) + } + foreignActor, err := ledger.Authenticate(ctx, foreignSecret) + if err != nil { + t.Fatalf("foreign auth: %v", err) + } + foreignProduct, err := ledger.CreateProduct(ctx, foreignActor, "Foreign API", "foreign-api") + if err != nil { + t.Fatalf("foreign product: %v", err) + } + foreignRelease, err := ledger.CreateRelease(ctx, foreignActor, foreignProduct.ID, "9.9.9") + if err != nil { + t.Fatalf("foreign release: %v", err) + } + foreignContract, err := ledger.UploadOpenAPIContract(ctx, foreignActor, foreignProduct.ID, foreignRelease.ID, "foreign", []byte(`{ + "openapi":"3.1.0", + "info":{"title":"Foreign API","version":"1"}, + "paths":{"/foreign-only":{"get":{"responses":{"200":{"description":"ok"}}}}} + }`)) + if err != nil { + t.Fatalf("foreign OpenAPI contract: %v", err) + } if _, err := ledger.UploadSBOM(ctx, actor, release.ID, artifact.ID, []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","components":[{"name":"openssl","version":"3.1.0","purl":"pkg:apk/openssl@3.1.0"}]}`)); err != nil { t.Fatalf("sbom: %v", err) } @@ -178,7 +223,7 @@ func TestCustomerPackageV2ManifestSchemaAndSensitiveFieldExclusion(t *testing.T) profile, err := ledger.CreateRedactionProfile(ctx, actor, CreateRedactionProfileInput{ Name: "customer v2", AllowedTypes: []string{ - "artifact", "sbom", "vulnerability_scan", "vex", "vulnerability_decision", "approval", "exception", "waiver", "build", "build_attestation", "release_bundle", + "artifact", "sbom", "vulnerability_scan", "vex", "vulnerability_decision", "approval", "exception", "waiver", "build", "build_attestation", "openapi_contract", "release_bundle", }, }) if err != nil { @@ -192,22 +237,34 @@ func TestCustomerPackageV2ManifestSchemaAndSensitiveFieldExclusion(t *testing.T) if manifest["schema_version"] != domain.CustomerPackageSchemaVersion || manifest["package_version"] != domain.CustomerPackageSchemaVersion || manifest["package_id"] != pkg.ID { t.Fatalf("manifest version/id fields = %#v", manifest) } - for _, key := range []string{"tenant", "organization", "product", "release", "artifact_digests", "sboms", "vulnerability_scans", "vex_documents", "vulnerability_decisions", "approvals", "exceptions", "waivers", "provenance", "readiness_summary", "verification_material", "redaction_profile", "limitations", "non_claims"} { + for _, key := range []string{"tenant", "organization", "product", "release", "artifact_digests", "sboms", "vulnerability_scans", "vex_documents", "vulnerability_decisions", "approvals", "exceptions", "waivers", "provenance", "api_contracts", "readiness_summary", "verification_material", "redaction_profile", "limitations", "non_claims"} { if _, ok := manifest[key]; !ok { t.Fatalf("manifest missing %s: %#v", key, manifest) } } + apiContracts, ok := manifest["api_contracts"].(map[string]any) + if !ok { + t.Fatalf("api_contracts section has unexpected shape: %#v", manifest["api_contracts"]) + } + contracts, ok := apiContracts["openapi_contracts"].([]map[string]any) + if !ok || len(contracts) != 2 { + t.Fatalf("openapi contract summaries = %#v, want two scoped contracts", apiContracts["openapi_contracts"]) + } + diffs, ok := apiContracts["contract_diffs"].([]map[string]any) + if !ok || len(diffs) != 1 || diffs[0]["id"] != contractDiff.ID || diffs[0]["result"] != "breaking" { + t.Fatalf("contract diff summaries = %#v, want scoped breaking diff", apiContracts["contract_diffs"]) + } textBytes, err := json.Marshal(manifest) if err != nil { t.Fatalf("marshal manifest: %v", err) } text := string(textBytes) - for _, want := range []string{artifact.Digest, "cyclonedx", "grype", vex.ID, decision.ImpactStatement, bundle.ManifestHash, "audit_chain"} { + for _, want := range []string{artifact.Digest, "cyclonedx", "grype", vex.ID, decision.ImpactStatement, bundle.ManifestHash, "audit_chain", baseContract.Hash, targetContract.Hash, "GET /v1/payments", "target contract has fewer paths than base contract"} { if !strings.Contains(text, want) { t.Fatalf("manifest missing %q: %s", want, text) } } - for _, forbidden := range []string{"private manual triage note", "payload_ref", "object://", "api_key_secret", "evy_", "private_key", "session_hash"} { + for _, forbidden := range []string{"private manual triage note", openAPIRawCanary, foreignContract.ID, "foreign-only", "payload_ref", "object://", "api_key_secret", "evy_", "private_key", "session_hash"} { if strings.Contains(strings.ToLower(text), strings.ToLower(forbidden)) { t.Fatalf("manifest leaked %q: %s", forbidden, text) } From b0cfb8b1d16ad14d8f7d0d5f8fe143bf3c1f19db Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 23:03:21 +0300 Subject: [PATCH 207/287] feat(portal): audit customer package downloads --- .productization_next_steps.md | 4 ++-- docs/api.md | 2 +- docs/operations.md | 2 +- internal/app/enterprise.go | 11 ++++++++++- internal/app/enterprise_test.go | 26 ++++++++++++++++++++++++-- internal/app/governance_packages.go | 2 +- 6 files changed, 39 insertions(+), 8 deletions(-) diff --git a/.productization_next_steps.md b/.productization_next_steps.md index 366137d..272d6a9 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -1211,7 +1211,7 @@ already-built surfaces. Potential later expansion: * [ ] NDA-gated customer access -* [x] package access counters and failed-attempt tracking +* [x] package access logs, counters, and failed-attempt tracking * [x] time-limited package links through expiring portal tokens * [ ] watermarking * [x] customer-specific packages through scoped customer package records @@ -1268,7 +1268,7 @@ Potential later expansion: * [x] access counters and failed-attempt counters * [x] expiry * [x] package ZIP download endpoint -* [ ] detailed package download history events +* [x] detailed package download history events Do this only after static/offline package flow is excellent. diff --git a/docs/api.md b/docs/api.md index 89e43ef..59f923c 100644 --- a/docs/api.md +++ b/docs/api.md @@ -287,7 +287,7 @@ Important scope boundaries: | Tenant data | Cross-tenant reads return `404` where applicable. | | Collector identity | Build attribution is derived from the authenticated collector key; clients must not submit `collector_id` for build attribution. | | Instance admin | `GET /v1/admin/instance` requires explicit `instance:admin`; tenant admin and ordinary wildcard tenant keys are insufficient. | -| Customer portal | `POST /v1/customer-portal/package` is a public token exchange endpoint and intentionally does not use bearer authentication. | +| Customer portal | `POST /v1/customer-portal/package` and `/v1/customer-portal/package/download` are public token exchange endpoints and intentionally do not use bearer authentication. Successful exchanges and downloads are visible through the tenant audit log without storing the supplied token. | ## Endpoint Catalog diff --git a/docs/operations.md b/docs/operations.md index d16b7bb..629b0fc 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -38,7 +38,7 @@ This operator index points to the canonical references for running Evydence. Kee ## Token And Trust Boundaries - API keys, collector keys, SSO session tokens, and customer portal access tokens are bearer secrets. Do not place them in logs, documentation, long-lived build output, or customer packages. -- Customer portal access tokens are returned once by `POST /v1/customer-portal/access`, expire, and are stored as hashes. Deployments should still use reverse-proxy or API-gateway throttling for the unauthenticated portal endpoint. +- Customer portal access tokens are returned once by `POST /v1/customer-portal/access`, expire, and are stored as hashes. Successful manifest exchanges and ZIP downloads write audit-chain entries under both the portal access record and package record; failed known-prefix attempts are recorded as unverified access events. Supplied portal tokens are never stored in those entries. Deployments should still use reverse-proxy or API-gateway throttling for the unauthenticated portal endpoint. - Human SSO session records are admin-managed, authenticated SSO sessions can revoke themselves through API-first logout, and SSO credential exchange can set an HttpOnly session cookie after locally verifying an OIDC ID token or SAML assertion against tenant-configured trust material. OIDC group claim values can be captured on the session and mapped to configured roles without creating permanent role bindings from token claims. Current endpoints can refresh OIDC public JWKS from discovery metadata and can call a configured OIDC UserInfo endpoint or provider validation gateway for verification checks, but they do not implement direct provider-specific management API clients or external group synchronization. - Object-retention APIs record and verify retention intent for tenant-prefixed object paths. S3/MinIO verification can check bucket defaults plus sample-object retention and legal hold where configured. Enforcing WORM or object-lock settings remains the responsibility of the configured object store and deployment policy. diff --git a/internal/app/enterprise.go b/internal/app/enterprise.go index 4d3fa32..5297bfb 100644 --- a/internal/app/enterprise.go +++ b/internal/app/enterprise.go @@ -784,6 +784,10 @@ func (s identityService) CreateCustomerPortalAccess(ctx context.Context, actor d } func (s identityService) AccessCustomerPortalPackage(ctx context.Context, token string) (domain.CustomerSecurityPackage, error) { + return s.accessCustomerPortalPackage(ctx, token, "customer_portal_package.accessed") +} + +func (s identityService) accessCustomerPortalPackage(ctx context.Context, token, successEntryType string) (domain.CustomerSecurityPackage, error) { l := s.ledger if err := ctx.Err(); err != nil { return domain.CustomerSecurityPackage{}, err @@ -822,7 +826,7 @@ func (s identityService) AccessCustomerPortalPackage(ctx context.Context, token now := l.now() access.LastAccessedAt = &now l.portalAccess[id] = access - _, _ = l.appendChainLocked(access.TenantID, "customer_portal_package.accessed", "customer_security_package", pkg.ID, "customer_portal", access.ID, pkg.ManifestHash, "") + l.appendCustomerPortalAccessEventLocked(successEntryType, access, pkg) if err := l.persistCriticalLocked(ctx, l.criticalMutationLocked()); err != nil { return domain.CustomerSecurityPackage{}, err } @@ -831,6 +835,11 @@ func (s identityService) AccessCustomerPortalPackage(ctx context.Context, token return domain.CustomerSecurityPackage{}, ErrUnauthorized } +func (l *Ledger) appendCustomerPortalAccessEventLocked(entryType string, access domain.CustomerPortalAccess, pkg domain.CustomerSecurityPackage) { + _, _ = l.appendChainLocked(access.TenantID, entryType, "customer_portal_access", access.ID, "customer_portal", access.ID, pkg.ManifestHash, "") + _, _ = l.appendChainLocked(access.TenantID, entryType, "customer_security_package", pkg.ID, "customer_portal", access.ID, pkg.ManifestHash, "") +} + func (s packageReportService) CreateQuestionnaireTemplate(ctx context.Context, actor domain.Actor, in CreateQuestionnaireTemplateInput) (domain.QuestionnaireTemplate, error) { l := s.ledger if err := ctx.Err(); err != nil { diff --git a/internal/app/enterprise_test.go b/internal/app/enterprise_test.go index 65635ed..fa0c077 100644 --- a/internal/app/enterprise_test.go +++ b/internal/app/enterprise_test.go @@ -546,6 +546,13 @@ func TestCustomerPortalRetentionQuestionnairesAndCommercialCollectors(t *testing if portalPkg.ID != pkg.ID { t.Fatalf("portal package id = %s want %s", portalPkg.ID, pkg.ID) } + portalArchive, err := ledger.ExportCustomerPortalPackageArchive(ctx, token) + if err != nil { + t.Fatalf("portal package download: %v", err) + } + if portalArchive.PackageID != pkg.ID || portalArchive.MediaType != "application/zip" { + t.Fatalf("portal archive metadata = %#v", portalArchive) + } badToken := mutateTokenSuffix(token) if _, err := ledger.AccessCustomerPortalPackage(ctx, badToken); !errors.Is(err, ErrUnauthorized) { t.Fatalf("bad portal token err=%v, want unauthorized", err) @@ -554,15 +561,30 @@ func TestCustomerPortalRetentionQuestionnairesAndCommercialCollectors(t *testing if err != nil { t.Fatalf("portal audit log: %v", err) } - foundFailedAccess := false + foundAccess, foundDownload, foundFailedAccess := false, false, false for _, entry := range entries { - if entry.EntryType == "customer_portal_package.access_failed" && entry.ActorID == "unverified" { + switch entry.EntryType { + case "customer_portal_package.accessed": + if entry.ActorID == access.ID && entry.PayloadHash == pkg.ManifestHash { + foundAccess = true + } + case "customer_portal_package.downloaded": + if entry.ActorID == access.ID && entry.PayloadHash == pkg.ManifestHash { + foundDownload = true + } + case "customer_portal_package.access_failed": foundFailedAccess = true + if entry.ActorID != "unverified" { + t.Fatalf("failed portal access actor = %q, want unverified", entry.ActorID) + } } if entry.ActorID == badToken || entry.PayloadHash == badToken { t.Fatalf("portal audit leaked token: %#v", entry) } } + if !foundAccess || !foundDownload { + t.Fatalf("missing portal access/download audit entries access=%v download=%v entries=%#v", foundAccess, foundDownload, entries) + } if !foundFailedAccess { t.Fatalf("missing failed portal access audit entry: %#v", entries) } diff --git a/internal/app/governance_packages.go b/internal/app/governance_packages.go index 0ee6fc9..5982921 100644 --- a/internal/app/governance_packages.go +++ b/internal/app/governance_packages.go @@ -1113,7 +1113,7 @@ func (s packageReportService) ExportCustomerSecurityPackageArchive(ctx context.C func (s packageReportService) ExportCustomerPortalPackageArchive(ctx context.Context, token string) (CustomerPackageArchive, error) { l := s.ledger - pkg, err := l.AccessCustomerPortalPackage(ctx, token) + pkg, err := l.identityService().accessCustomerPortalPackage(ctx, token, "customer_portal_package.downloaded") if err != nil { return CustomerPackageArchive{}, err } From c89b59681d39b4c2c2159948d35ce34eae45fb2d Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 23:05:30 +0300 Subject: [PATCH 208/287] feat(reports): add CRA evidence templates --- .productization_next_steps.md | 6 +- docs/api.md | 2 + docs/reference/api-contract-matrix.md | 4 +- internal/adapters/httpapi/openapi.go | 29 +++ .../adapters/httpapi/openapi_operations.go | 14 ++ .../adapters/httpapi/route_registration.go | 2 + internal/adapters/httpapi/router.go | 26 +++ internal/adapters/httpapi/router_test.go | 18 +- internal/app/authz_inventory_test.go | 2 + internal/app/context_cancellation_test.go | 16 ++ internal/app/controls.go | 169 ++++++++++++++++++ internal/app/controls_test.go | 86 +++++++++ internal/app/package_report_service.go | 8 + internal/domain/domain.go | 29 +++ openapi.yaml | 2 +- sdk/openapi-route-catalog.json | 36 +++- 16 files changed, 442 insertions(+), 7 deletions(-) diff --git a/.productization_next_steps.md b/.productization_next_steps.md index 272d6a9..6463630 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -1232,14 +1232,14 @@ Potential later expansion: Do not turn Evydence into the OpenAPI governance product itself. -#### [ ] EVY-202 — CRA-readiness templates +#### [x] EVY-202 — CRA-readiness templates Potential later expansion: * [x] CRA evidence mapping template pack * [x] vulnerability posture report -* [ ] CRA-specific vulnerability handling report template -* [ ] security update evidence report +* [x] CRA-specific vulnerability handling report template +* [x] security update evidence report * [x] incident package report Keep language as readiness support, not legal conclusion. diff --git a/docs/api.md b/docs/api.md index 59f923c..64f85a2 100644 --- a/docs/api.md +++ b/docs/api.md @@ -418,6 +418,8 @@ Source snapshots capture submitted provider metadata. They do not call provider | `GET` | `/v1/control-evidence` | List links. | | `GET` | `/v1/reports/control-coverage` | Deterministic control coverage. | | `GET` | `/v1/reports/cra-readiness` | Technical evidence readiness report with limitations. | +| `GET` | `/v1/reports/cra-vulnerability-handling` | CRA-oriented vulnerability handling evidence report with limitations. | +| `GET` | `/v1/reports/security-update-evidence` | Release-scoped security update evidence report with limitations. | | `POST` | `/v1/exceptions` | Create exception. | | `POST` | `/v1/exceptions/{id}/approve` | Approve exception. | | `GET` | `/v1/exceptions` | List exceptions. | diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index b7d2e77..b4b95ec 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 171 operations: 171 precise, 0 broad. +Generated from 173 operations: 173 precise, 0 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -125,12 +125,14 @@ Generated from 171 operations: 171 precise, 0 broad. | GET | /v1/reports/control-coverage | controlCoverageReport | Bearer | report:read | - | query:framework_id, query:product_id, query:release_id | - | 200:application/json:ReadinessReportEnvelope | precise | | GET | /v1/reports/cra-readiness | craReadinessReport | Bearer | report:read | - | query:product_id, query:release_id | - | 200:application/json:ReadinessReportEnvelope | precise | | GET | /v1/reports/cra-readiness-html | craReadinessHTMLPackage | Bearer | report:read | - | query:product_id, query:release_id | - | 200:application/json:HTMLReportPackageEnvelope | precise | +| GET | /v1/reports/cra-vulnerability-handling | craVulnerabilityHandlingReport | Bearer | report:read | - | query:product_id, query:release_id | - | 200:application/json:CRAVulnerabilityHandlingReportEnvelope | precise | | GET | /v1/reports/incident-package | incidentReport | Bearer | incident:read | - | query:incident_id | - | 200:application/json:IncidentReportEnvelope | precise | | GET | /v1/reports/missing-evidence | missingEvidenceReport | Bearer | verify:read | - | query:release_id | - | 200:application/json:MissingEvidenceReportEnvelope | precise | | POST | /v1/reports/pdf | createPDFReportPackage | Bearer | report:read | required | - | application/json:CreatePDFReportPackageRequest | 201:application/json:PDFReportPackageEnvelope | precise | | GET | /v1/reports/release-readiness | releaseReadinessReport | Bearer | verify:read | - | query:release_id | - | 200:application/json:ReadinessReportEnvelope | precise | | GET | /v1/reports/retention | retentionReport | Bearer | admin | - | query:scope_id, query:scope_type | - | 200:application/json:RetentionReportEnvelope | precise | | GET | /v1/reports/security-review-package | securityReviewPackageReport | Bearer | package:read | - | query:package_id | - | 200:application/json:SecurityReviewPackageReportEnvelope | precise | +| GET | /v1/reports/security-update-evidence | securityUpdateEvidenceReport | Bearer | report:read | - | query:product_id, query:release_id | - | 200:application/json:SecurityUpdateEvidenceReportEnvelope | precise | | GET | /v1/reports/vulnerability-decision-summary | vulnerabilityDecisionSummaryReport | Bearer | report:read | - | query:release_id | - | 200:application/json:VulnerabilityDecisionSummaryReportEnvelope | precise | | GET | /v1/reports/vulnerability-posture | vulnerabilityPostureReport | Bearer | security:read | - | query:release_id | - | 200:application/json:VulnerabilityPostureReportEnvelope | precise | | POST | /v1/retention-overrides | createRetentionOverride | Bearer | admin | required | - | application/json:CreateRetentionOverrideRequest | 201:application/json:RetentionOverrideEnvelope | precise | diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 4528ec6..6c60a71 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -2113,6 +2113,35 @@ func registerCriticalSchemas(registry *specs.Registry) { "generated_at": map[string]any{"type": "string", "format": "date-time"}, }, "report_type", "template_version", "summary", "open_critical", "assumptions", "limitations", "generated_at")) registry.RegisterSchema("VulnerabilityPostureReportEnvelope", dataEnvelopeSchema("#/components/schemas/VulnerabilityPostureReport")) + registry.RegisterSchema("CRAVulnerabilityHandlingReport", objectSchema(map[string]any{ + "report_type": map[string]any{"type": "string"}, + "template_version": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "summary": map[string]any{"type": "object", "additionalProperties": map[string]any{"type": "integer"}}, + "decisions": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/VulnerabilityDecisionCustomerSummary"}}, + "accepted_exceptions": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/Exception"}}, + "evidence_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "assumptions": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "generated_at": map[string]any{"type": "string", "format": "date-time"}, + }, "report_type", "template_version", "product_id", "release_id", "summary", "assumptions", "limitations", "generated_at")) + registry.RegisterSchema("CRAVulnerabilityHandlingReportEnvelope", dataEnvelopeSchema("#/components/schemas/CRAVulnerabilityHandlingReport")) + registry.RegisterSchema("SecurityUpdateEvidenceReport", objectSchema(map[string]any{ + "report_type": map[string]any{"type": "string"}, + "template_version": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "summary": map[string]any{"type": "object", "additionalProperties": map[string]any{"type": "integer"}}, + "fixed_decisions": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/VulnerabilityDecisionCustomerSummary"}}, + "incidents": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/Incident"}}, + "remediation_tasks": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/RemediationTask"}}, + "evidence_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "assumptions": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "generated_at": map[string]any{"type": "string", "format": "date-time"}, + }, "report_type", "template_version", "product_id", "release_id", "summary", "assumptions", "limitations", "generated_at")) + registry.RegisterSchema("SecurityUpdateEvidenceReportEnvelope", dataEnvelopeSchema("#/components/schemas/SecurityUpdateEvidenceReport")) registry.RegisterSchema("CreateAnomalyReportRequest", objectSchema(map[string]any{ "subject_type": map[string]any{"type": "string"}, "subject_id": map[string]any{"type": "string"}, diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index a31194e..8d4a22f 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -752,6 +752,20 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { queryParam("release_id", "Release id.", "string"), ) operation.Responses[http.StatusOK] = jsonResponse("CRA readiness report envelope.", "#/components/schemas/ReadinessReportEnvelope") + case "craVulnerabilityHandlingReport": + operation.Description = "Returns a CRA-oriented vulnerability handling evidence report without legal compliance, certification, scanner-authority, or release-security conclusions." + operation.Parameters = append(operation.Parameters, + queryParam("product_id", "Product id.", "string"), + queryParam("release_id", "Release id.", "string"), + ) + operation.Responses[http.StatusOK] = jsonResponse("CRA vulnerability handling report envelope.", "#/components/schemas/CRAVulnerabilityHandlingReportEnvelope") + case "securityUpdateEvidenceReport": + operation.Description = "Returns a security update evidence report for release-scoped fixed decisions, incidents, remediation tasks, and linked evidence without legal or security conclusions." + operation.Parameters = append(operation.Parameters, + queryParam("product_id", "Product id.", "string"), + queryParam("release_id", "Release id.", "string"), + ) + operation.Responses[http.StatusOK] = jsonResponse("Security update evidence report envelope.", "#/components/schemas/SecurityUpdateEvidenceReportEnvelope") case "controlCoverageReport": operation.Description = "Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations." operation.Parameters = append(operation.Parameters, diff --git a/internal/adapters/httpapi/route_registration.go b/internal/adapters/httpapi/route_registration.go index 5d9693b..c2f2791 100644 --- a/internal/adapters/httpapi/route_registration.go +++ b/internal/adapters/httpapi/route_registration.go @@ -101,6 +101,8 @@ func (s *Server) controlRoutes() []routeDef { {http.MethodGet, "/v1/control-evidence", op("listControlEvidence", http.MethodGet, "/v1/control-evidence", "List control evidence", []string{app.ScopeControlsRead}), http.HandlerFunc(s.listControlEvidence)}, {http.MethodGet, "/v1/reports/control-coverage", op("controlCoverageReport", http.MethodGet, "/v1/reports/control-coverage", "Control coverage report", []string{app.ScopeReportRead}), http.HandlerFunc(s.controlCoverageReport)}, {http.MethodGet, "/v1/reports/cra-readiness", op("craReadinessReport", http.MethodGet, "/v1/reports/cra-readiness", "CRA readiness report", []string{app.ScopeReportRead}), http.HandlerFunc(s.craReadinessReport)}, + {http.MethodGet, "/v1/reports/cra-vulnerability-handling", op("craVulnerabilityHandlingReport", http.MethodGet, "/v1/reports/cra-vulnerability-handling", "CRA vulnerability handling report", []string{app.ScopeReportRead}), http.HandlerFunc(s.craVulnerabilityHandlingReport)}, + {http.MethodGet, "/v1/reports/security-update-evidence", op("securityUpdateEvidenceReport", http.MethodGet, "/v1/reports/security-update-evidence", "Security update evidence report", []string{app.ScopeReportRead}), http.HandlerFunc(s.securityUpdateEvidenceReport)}, } } diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index 40ed8cd..d94851f 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -1796,6 +1796,32 @@ func (s *Server) craReadinessReport(w http.ResponseWriter, r *http.Request) { writeData(w, http.StatusOK, report) } +func (s *Server) craVulnerabilityHandlingReport(w http.ResponseWriter, r *http.Request) { + actor, ok := s.authenticate(w, r) + if !ok { + return + } + report, err := s.ledger.CRAVulnerabilityHandlingReport(r.Context(), actor, r.URL.Query().Get("product_id"), r.URL.Query().Get("release_id")) + if err != nil { + writeProblem(w, r, err) + return + } + writeData(w, http.StatusOK, report) +} + +func (s *Server) securityUpdateEvidenceReport(w http.ResponseWriter, r *http.Request) { + actor, ok := s.authenticate(w, r) + if !ok { + return + } + report, err := s.ledger.SecurityUpdateEvidenceReport(r.Context(), actor, r.URL.Query().Get("product_id"), r.URL.Query().Get("release_id")) + if err != nil { + writeProblem(w, r, err) + return + } + writeData(w, http.StatusOK, report) +} + func (s *Server) createReleaseBundle(w http.ResponseWriter, r *http.Request) { var req struct { ReleaseID string `json:"release_id"` diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 81e8246..573bc6e 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -94,7 +94,7 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { if _, ok := redactionRequestProps["preset"]; !ok { t.Fatalf("redaction profile request schema missing preset: %#v", redactionRequestProps) } - for _, schemaName := range []string{"ReadinessStatusEnvelope", "BackupManifestEnvelope", "VerificationResultEnvelope", "ReadinessReportEnvelope", "CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "ReleaseEvidenceFlowEnvelope", "ReleaseSecuritySummaryEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "VEXImportReportEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "VulnerabilityDecisionListEnvelope", "VulnerabilityDecisionSummaryReportEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "UpdateSSOProviderTrustMaterialRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "ExchangeSSOCredentialRequest", "SSOCredentialExchangeEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "DataEnvelope"} { + for _, schemaName := range []string{"ReadinessStatusEnvelope", "BackupManifestEnvelope", "VerificationResultEnvelope", "ReadinessReportEnvelope", "CRAVulnerabilityHandlingReportEnvelope", "SecurityUpdateEvidenceReportEnvelope", "CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "ReleaseEvidenceFlowEnvelope", "ReleaseSecuritySummaryEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "VEXImportReportEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "VulnerabilityDecisionListEnvelope", "VulnerabilityDecisionSummaryReportEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "UpdateSSOProviderTrustMaterialRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "ExchangeSSOCredentialRequest", "SSOCredentialExchangeEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "DataEnvelope"} { if _, ok := schemas[schemaName]; !ok { t.Fatalf("schema %s missing from OpenAPI components", schemaName) } @@ -115,6 +115,12 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { craReadiness := operationMap(t, paths, "/v1/reports/cra-readiness", "get") assertQueryParams(t, craReadiness, "product_id", "release_id") assertResponseRef(t, craReadiness, "200", "#/components/schemas/ReadinessReportEnvelope") + craVulnerabilityHandling := operationMap(t, paths, "/v1/reports/cra-vulnerability-handling", "get") + assertQueryParams(t, craVulnerabilityHandling, "product_id", "release_id") + assertResponseRef(t, craVulnerabilityHandling, "200", "#/components/schemas/CRAVulnerabilityHandlingReportEnvelope") + securityUpdateEvidence := operationMap(t, paths, "/v1/reports/security-update-evidence", "get") + assertQueryParams(t, securityUpdateEvidence, "product_id", "release_id") + assertResponseRef(t, securityUpdateEvidence, "200", "#/components/schemas/SecurityUpdateEvidenceReportEnvelope") createProduct := operationMap(t, paths, "/v1/products", "post") assertRequestRef(t, createProduct, "#/components/schemas/CreateProductRequest") assertResponseRef(t, createProduct, "201", "#/components/schemas/ProductEnvelope") @@ -504,10 +510,12 @@ func TestAuthenticatedReadRoutesRejectMissingBearerToken(t *testing.T) { "/v1/reports/control-coverage", "/v1/reports/cra-readiness", "/v1/reports/cra-readiness-html", + "/v1/reports/cra-vulnerability-handling", "/v1/reports/incident-package", "/v1/reports/missing-evidence", "/v1/reports/retention", "/v1/reports/security-review-package", + "/v1/reports/security-update-evidence", "/v1/reports/vulnerability-posture", "/v1/role-bindings", "/v1/sboms/sbom_missing", @@ -1024,6 +1032,14 @@ func TestControlsAndReportsHTTPFlow(t *testing.T) { if strings.Contains(strings.ToLower(cra), "automatically compliant") || strings.Contains(strings.ToLower(cra), "certified secure") { t.Fatalf("CRA report contains forbidden claim: %s", cra) } + handling := getJSON(t, server, secret, "/v1/reports/cra-vulnerability-handling?product_id="+productID+"&release_id="+releaseID, http.StatusOK) + if !strings.Contains(handling, `"report_type":"cra_vulnerability_handling"`) || strings.Contains(strings.ToLower(handling), "certified secure") { + t.Fatalf("CRA vulnerability handling report response: %s", handling) + } + update := getJSON(t, server, secret, "/v1/reports/security-update-evidence?product_id="+productID+"&release_id="+releaseID, http.StatusOK) + if !strings.Contains(update, `"report_type":"security_update_evidence"`) || strings.Contains(strings.ToLower(update), "automatically compliant") { + t.Fatalf("security update evidence report response: %s", update) + } } func TestEvidenceLifecycleSourceDeploymentHTTPFlow(t *testing.T) { diff --git a/internal/app/authz_inventory_test.go b/internal/app/authz_inventory_test.go index 97d7f40..779a3f9 100644 --- a/internal/app/authz_inventory_test.go +++ b/internal/app/authz_inventory_test.go @@ -18,6 +18,8 @@ func TestResourceScopedAuthorizationCoverageInventory(t *testing.T) { "ListControlEvidence", "ControlCoverageReport", "CRAReadinessReport", + "CRAVulnerabilityHandlingReport", + "SecurityUpdateEvidenceReport", }, "risk_workflows.go": { "CreateIncident", diff --git a/internal/app/context_cancellation_test.go b/internal/app/context_cancellation_test.go index 556f8ae..886d25f 100644 --- a/internal/app/context_cancellation_test.go +++ b/internal/app/context_cancellation_test.go @@ -149,6 +149,14 @@ func TestLedgerOperationsHonorCanceledContextBeforeWork(t *testing.T) { _, err := ledger.CRAReadinessReport(ctx, actor, CRAReadinessReportInput{ProductID: "prod", ReleaseID: "rel"}) return err }}, + {"CRAVulnerabilityHandlingReport", func() error { + _, err := ledger.CRAVulnerabilityHandlingReport(ctx, actor, "prod", "rel") + return err + }}, + {"SecurityUpdateEvidenceReport", func() error { + _, err := ledger.SecurityUpdateEvidenceReport(ctx, actor, "prod", "rel") + return err + }}, {"CreateCollector", func() error { _, _, _, err := ledger.CreateCollector(ctx, actor, CreateCollectorInput{Name: "collector", Type: "github_actions", Version: "1"}) return err @@ -514,6 +522,14 @@ func TestLedgerOperationsRejectActorsWithoutRequiredScopesBeforeResourceWork(t * _, err := ledger.CRAReadinessReport(ctx, actor, CRAReadinessReportInput{ProductID: "prod", ReleaseID: "rel"}) return err }}, + {"CRAVulnerabilityHandlingReport", func() error { + _, err := ledger.CRAVulnerabilityHandlingReport(ctx, actor, "prod", "rel") + return err + }}, + {"SecurityUpdateEvidenceReport", func() error { + _, err := ledger.SecurityUpdateEvidenceReport(ctx, actor, "prod", "rel") + return err + }}, {"CreateCollector", func() error { _, _, _, err := ledger.CreateCollector(ctx, actor, CreateCollectorInput{Name: "collector", Type: "github_actions", Version: "1"}) return err diff --git a/internal/app/controls.go b/internal/app/controls.go index f936613..5b7ad69 100644 --- a/internal/app/controls.go +++ b/internal/app/controls.go @@ -344,6 +344,175 @@ func (s packageReportService) CRAReadinessReport(ctx context.Context, actor doma }, nil } +func (s packageReportService) CRAVulnerabilityHandlingReport(ctx context.Context, actor domain.Actor, productID, releaseID string) (domain.CRAVulnerabilityHandlingReport, error) { + l := s.ledger + if err := ctx.Err(); err != nil { + return domain.CRAVulnerabilityHandlingReport{}, err + } + if err := require(actor, ScopeReportRead); err != nil { + return domain.CRAVulnerabilityHandlingReport{}, err + } + productID, releaseID = strings.TrimSpace(productID), strings.TrimSpace(releaseID) + if productID == "" || releaseID == "" { + return domain.CRAVulnerabilityHandlingReport{}, ErrValidation + } + l.mu.Lock() + defer l.mu.Unlock() + if err := l.ensureScopeLocked(actor.TenantID, productID, "", releaseID); err != nil { + return domain.CRAVulnerabilityHandlingReport{}, err + } + if err := l.authorizeResourceLocked(actor, ScopeReportRead, resourceRefs{ProductID: productID, ReleaseID: releaseID}); err != nil { + return domain.CRAVulnerabilityHandlingReport{}, err + } + summary := map[string]int{ + "findings_total": 0, + "open_critical_total": 0, + "decisions_total": 0, + "approved_exceptions_total": 0, + } + evidenceIDs := []string{} + for _, scan := range l.scans { + if scan.TenantID != actor.TenantID || scan.ReleaseID != releaseID { + continue + } + evidenceIDs = append(evidenceIDs, scan.EvidenceID) + summary["findings_total"] += len(scan.Findings) + for _, finding := range scan.Findings { + if strings.EqualFold(finding.Severity, "critical") && strings.EqualFold(finding.State, "open") { + summary["open_critical_total"]++ + } + } + } + decisions := []domain.VulnerabilityDecisionCustomerSummary{} + for _, decision := range l.decisions { + if decision.TenantID != actor.TenantID || decision.ReleaseID != releaseID || decision.SupersededBy != "" { + continue + } + decisions = append(decisions, customerDecisionSummary(decision)) + evidenceIDs = append(evidenceIDs, decisionEvidenceIDs(decision.EvidenceID, decision.EvidenceIDs)...) + if decision.VEXDocumentID != "" { + if vex, ok := l.vexDocuments[decision.VEXDocumentID]; ok && vex.TenantID == actor.TenantID { + evidenceIDs = append(evidenceIDs, vex.EvidenceID) + } + } + } + sort.Slice(decisions, func(i, j int) bool { return decisions[i].ID < decisions[j].ID }) + summary["decisions_total"] = len(decisions) + exceptions := []domain.Exception{} + now := l.now() + for _, exception := range l.exceptions { + if exception.TenantID == actor.TenantID && exception.ReleaseID == releaseID && exception.Approved && exception.ExpiresAt.After(now) { + exceptions = append(exceptions, exception) + } + } + sort.Slice(exceptions, func(i, j int) bool { return exceptions[i].ID < exceptions[j].ID }) + summary["approved_exceptions_total"] = len(exceptions) + evidenceIDs = sortedUniqueNonEmptyStrings(evidenceIDs) + summary["evidence_total"] = len(evidenceIDs) + return domain.CRAVulnerabilityHandlingReport{ + ReportType: "cra_vulnerability_handling", + TemplateVersion: "cra-vulnerability-handling.v1.0.0", + ProductID: productID, + ReleaseID: releaseID, + Summary: summary, + Decisions: decisions, + AcceptedExceptions: exceptions, + EvidenceIDs: evidenceIDs, + Assumptions: []string{"This report summarizes vulnerability handling records for CRA readiness review using evidence stored in this tenant."}, + Limitations: []string{"Report contents do not prove legal compliance, certification, complete vulnerability detection, scanner authority, or release security status."}, + GeneratedAt: l.now(), + }, nil +} + +func (s packageReportService) SecurityUpdateEvidenceReport(ctx context.Context, actor domain.Actor, productID, releaseID string) (domain.SecurityUpdateEvidenceReport, error) { + l := s.ledger + if err := ctx.Err(); err != nil { + return domain.SecurityUpdateEvidenceReport{}, err + } + if err := require(actor, ScopeReportRead); err != nil { + return domain.SecurityUpdateEvidenceReport{}, err + } + productID, releaseID = strings.TrimSpace(productID), strings.TrimSpace(releaseID) + if productID == "" || releaseID == "" { + return domain.SecurityUpdateEvidenceReport{}, ErrValidation + } + l.mu.Lock() + defer l.mu.Unlock() + if err := l.ensureScopeLocked(actor.TenantID, productID, "", releaseID); err != nil { + return domain.SecurityUpdateEvidenceReport{}, err + } + if err := l.authorizeResourceLocked(actor, ScopeReportRead, resourceRefs{ProductID: productID, ReleaseID: releaseID}); err != nil { + return domain.SecurityUpdateEvidenceReport{}, err + } + evidenceIDs := []string{} + for _, scan := range l.scans { + if scan.TenantID == actor.TenantID && scan.ReleaseID == releaseID { + evidenceIDs = append(evidenceIDs, scan.EvidenceID) + } + } + fixedDecisions := []domain.VulnerabilityDecisionCustomerSummary{} + for _, decision := range l.decisions { + if decision.TenantID != actor.TenantID || decision.ReleaseID != releaseID || decision.SupersededBy != "" || decision.Status != decisionStatusFixed { + continue + } + fixedDecisions = append(fixedDecisions, customerDecisionSummary(decision)) + evidenceIDs = append(evidenceIDs, decisionEvidenceIDs(decision.EvidenceID, decision.EvidenceIDs)...) + if decision.VEXDocumentID != "" { + if vex, ok := l.vexDocuments[decision.VEXDocumentID]; ok && vex.TenantID == actor.TenantID { + evidenceIDs = append(evidenceIDs, vex.EvidenceID) + } + } + } + sort.Slice(fixedDecisions, func(i, j int) bool { return fixedDecisions[i].ID < fixedDecisions[j].ID }) + incidents := []domain.Incident{} + for _, incident := range l.incidents { + if incident.TenantID == actor.TenantID && incident.ProductID == productID && incident.ReleaseID == releaseID { + incidents = append(incidents, incident) + } + } + sort.Slice(incidents, func(i, j int) bool { return incidents[i].ID < incidents[j].ID }) + tasks := []domain.RemediationTask{} + for _, task := range l.tasks { + if task.TenantID != actor.TenantID { + continue + } + if task.ReleaseID == releaseID { + tasks = append(tasks, task) + evidenceIDs = append(evidenceIDs, task.EvidenceID) + continue + } + if task.IncidentID != "" { + if incident, ok := l.incidents[task.IncidentID]; ok && incident.TenantID == actor.TenantID && incident.ReleaseID == releaseID { + tasks = append(tasks, task) + evidenceIDs = append(evidenceIDs, task.EvidenceID) + } + } + } + sort.Slice(tasks, func(i, j int) bool { return tasks[i].ID < tasks[j].ID }) + evidenceIDs = sortedUniqueNonEmptyStrings(evidenceIDs) + summary := map[string]int{ + "fixed_decisions_total": len(fixedDecisions), + "incidents_total": len(incidents), + "remediation_tasks_total": len(tasks), + "linked_evidence_total": len(evidenceIDs), + "security_update_subjects": len(fixedDecisions) + len(incidents) + len(tasks), + } + return domain.SecurityUpdateEvidenceReport{ + ReportType: "security_update_evidence", + TemplateVersion: "security-update-evidence.v1.0.0", + ProductID: productID, + ReleaseID: releaseID, + Summary: summary, + FixedDecisions: fixedDecisions, + Incidents: incidents, + RemediationTasks: tasks, + EvidenceIDs: evidenceIDs, + Assumptions: []string{"This report summarizes recorded release evidence that may support security update review."}, + Limitations: []string{"Security update evidence is scoped to records in this Evydence tenant and does not prove legal sufficiency, customer notification completeness, or release security status."}, + GeneratedAt: l.now(), + }, nil +} + func (l *Ledger) controlCoverageReportLocked(tenantID string, in ControlCoverageReportInput) (domain.ControlCoverageReport, error) { if strings.TrimSpace(in.ProductID) != "" || strings.TrimSpace(in.ReleaseID) != "" { if err := l.ensureScopeLocked(tenantID, in.ProductID, "", in.ReleaseID); err != nil { diff --git a/internal/app/controls_test.go b/internal/app/controls_test.go index 7378633..c74d752 100644 --- a/internal/app/controls_test.go +++ b/internal/app/controls_test.go @@ -96,6 +96,92 @@ func TestControlFrameworkControlEvidenceAndCoverageFlow(t *testing.T) { } } +func TestCRATemplateReportsForVulnerabilityHandlingAndSecurityUpdates(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, release, _ := setupReleaseRiskFixture(t, ledger) + scan, err := ledger.UploadVulnerabilityScan(ctx, actor, []byte(`{ + "scanner":"grype", + "target_ref":"pkg:oci/payments-api", + "release_id":"`+release.ID+`", + "findings":[{"vulnerability":"CVE-2026-2020","component":"pkg:apk/openssl@3.1.0","severity":"critical","state":"open"}] + }`)) + if err != nil { + t.Fatalf("scan: %v", err) + } + decision, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{ + Status: decisionStatusFixed, + Justification: "patched in the release build", + ImpactStatement: "The release contains the patched component version.", + ActionStatement: "Customers should deploy this release when they next update.", + CustomerVisible: true, + InternalNotes: "private triage details must not appear in CRA reports", + }) + if err != nil { + t.Fatalf("decision: %v", err) + } + exception, err := ledger.CreateException(ctx, actor, CreateExceptionInput{ReleaseID: release.ID, FindingID: scan.Findings[0].ID, Reason: "temporary customer rollout window", Owner: "security", ExpiresAt: fixedNow().Add(48 * time.Hour)}) + if err != nil { + t.Fatalf("exception: %v", err) + } + if _, err := ledger.ApproveException(ctx, actor, exception.ID); err != nil { + t.Fatalf("approve exception: %v", err) + } + supportingEvidence, err := ledger.CreateEvidence(ctx, actor, CreateEvidenceInput{ProductID: release.ProductID, ReleaseID: release.ID, Type: "security_review", Title: "Security update review", PayloadHash: sampleDigest("security-update")}) + if err != nil { + t.Fatalf("supporting evidence: %v", err) + } + incident, err := ledger.CreateIncident(ctx, actor, CreateIncidentInput{ProductID: release.ProductID, ReleaseID: release.ID, Title: "Security update coordination", Severity: "medium", OpenedAt: fixedNow()}) + if err != nil { + t.Fatalf("incident: %v", err) + } + task, err := ledger.CreateRemediationTask(ctx, actor, CreateRemediationTaskInput{IncidentID: incident.ID, ReleaseID: release.ID, Title: "Publish security update note", Owner: "security", EvidenceID: supportingEvidence.ID}) + if err != nil { + t.Fatalf("remediation task: %v", err) + } + + handling, err := ledger.CRAVulnerabilityHandlingReport(ctx, actor, release.ProductID, release.ID) + if err != nil { + t.Fatalf("CRA vulnerability handling report: %v", err) + } + if handling.ReportType != "cra_vulnerability_handling" || handling.Summary["findings_total"] != 1 || handling.Summary["decisions_total"] != 1 || handling.Summary["approved_exceptions_total"] != 1 { + t.Fatalf("unexpected vulnerability handling report: %#v", handling) + } + if len(handling.Decisions) != 1 || handling.Decisions[0].ID != decision.ID || len(handling.AcceptedExceptions) != 1 { + t.Fatalf("handling decisions/exceptions = %#v", handling) + } + if !stringSliceContains(handling.EvidenceIDs, scan.EvidenceID) { + t.Fatalf("handling evidence ids missing scan evidence %s: %#v", scan.EvidenceID, handling.EvidenceIDs) + } + updateReport, err := ledger.SecurityUpdateEvidenceReport(ctx, actor, release.ProductID, release.ID) + if err != nil { + t.Fatalf("security update evidence report: %v", err) + } + if updateReport.ReportType != "security_update_evidence" || updateReport.Summary["incidents_total"] != 1 || updateReport.Summary["remediation_tasks_total"] != 1 || updateReport.Summary["fixed_decisions_total"] != 1 { + t.Fatalf("unexpected security update report: %#v", updateReport) + } + if len(updateReport.Incidents) != 1 || updateReport.Incidents[0].ID != incident.ID || len(updateReport.RemediationTasks) != 1 || updateReport.RemediationTasks[0].ID != task.ID { + t.Fatalf("security update incident/task details = %#v", updateReport) + } + if !stringSliceContains(updateReport.EvidenceIDs, supportingEvidence.ID) || !stringSliceContains(updateReport.EvidenceIDs, scan.EvidenceID) { + t.Fatalf("security update evidence ids missing expected ids: %#v", updateReport.EvidenceIDs) + } + reportText := strings.ToLower(strings.Join(append(append(handling.Assumptions, handling.Limitations...), append(updateReport.Assumptions, updateReport.Limitations...)...), " ")) + for _, forbidden := range []string{"private triage details", "legally sufficient", "certified secure", "automatically compliant"} { + if strings.Contains(reportText, forbidden) { + t.Fatalf("CRA report text leaked forbidden phrase %q: handling=%#v update=%#v", forbidden, handling, updateReport) + } + } + + actorB, _, _ := setupReleaseRiskFixture(t, ledger) + if _, err := ledger.CRAVulnerabilityHandlingReport(ctx, actorB, release.ProductID, release.ID); !errors.Is(err, ErrNotFound) { + t.Fatalf("cross-tenant CRA vulnerability handling err=%v, want not found", err) + } + if _, err := ledger.SecurityUpdateEvidenceReport(ctx, actorB, release.ProductID, release.ID); !errors.Is(err, ErrNotFound) { + t.Fatalf("cross-tenant security update err=%v, want not found", err) + } +} + func TestControlValidationScopeAndWaivedCoverage(t *testing.T) { ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) ctx := context.Background() diff --git a/internal/app/package_report_service.go b/internal/app/package_report_service.go index 185199f..6365011 100644 --- a/internal/app/package_report_service.go +++ b/internal/app/package_report_service.go @@ -26,6 +26,14 @@ func (l *Ledger) CRAReadinessReport(ctx context.Context, actor domain.Actor, in return l.packageReportService().CRAReadinessReport(ctx, actor, in) } +func (l *Ledger) CRAVulnerabilityHandlingReport(ctx context.Context, actor domain.Actor, productID, releaseID string) (domain.CRAVulnerabilityHandlingReport, error) { + return l.packageReportService().CRAVulnerabilityHandlingReport(ctx, actor, productID, releaseID) +} + +func (l *Ledger) SecurityUpdateEvidenceReport(ctx context.Context, actor domain.Actor, productID, releaseID string) (domain.SecurityUpdateEvidenceReport, error) { + return l.packageReportService().SecurityUpdateEvidenceReport(ctx, actor, productID, releaseID) +} + func (l *Ledger) IncidentReport(ctx context.Context, actor domain.Actor, incidentID string) (domain.IncidentReport, error) { return l.packageReportService().IncidentReport(ctx, actor, incidentID) } diff --git a/internal/domain/domain.go b/internal/domain/domain.go index 018af87..e78a0c7 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -674,6 +674,35 @@ type CRAReadinessReport struct { GeneratedAt time.Time `json:"generated_at"` } +type CRAVulnerabilityHandlingReport struct { + ReportType string `json:"report_type"` + TemplateVersion string `json:"template_version"` + ProductID string `json:"product_id"` + ReleaseID string `json:"release_id"` + Summary map[string]int `json:"summary"` + Decisions []VulnerabilityDecisionCustomerSummary `json:"decisions,omitempty"` + AcceptedExceptions []Exception `json:"accepted_exceptions,omitempty"` + EvidenceIDs []string `json:"evidence_ids,omitempty"` + Assumptions []string `json:"assumptions"` + Limitations []string `json:"limitations"` + GeneratedAt time.Time `json:"generated_at"` +} + +type SecurityUpdateEvidenceReport struct { + ReportType string `json:"report_type"` + TemplateVersion string `json:"template_version"` + ProductID string `json:"product_id"` + ReleaseID string `json:"release_id"` + Summary map[string]int `json:"summary"` + FixedDecisions []VulnerabilityDecisionCustomerSummary `json:"fixed_decisions,omitempty"` + Incidents []Incident `json:"incidents,omitempty"` + RemediationTasks []RemediationTask `json:"remediation_tasks,omitempty"` + EvidenceIDs []string `json:"evidence_ids,omitempty"` + Assumptions []string `json:"assumptions"` + Limitations []string `json:"limitations"` + GeneratedAt time.Time `json:"generated_at"` +} + type AuditChainEntry struct { ID string `json:"id"` TenantID string `json:"tenant_id"` diff --git a/openapi.yaml b/openapi.yaml index 4368507..3b21809 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"remediation":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"policy_set":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlow":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["needs_evidence","ready_for_review"],"type":"string"},"steps":{"items":{"$ref":"#/components/schemas/ReleaseEvidenceFlowStep"},"type":"array"}},"required":["release_id","product_id","status","counts","steps","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseEvidenceFlowEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseEvidenceFlow"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlowStep":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"idempotency_required":{"type":"boolean"},"method":{"type":"string"},"next_reference":{"type":"string"},"path":{"type":"string"},"required":{"type":"boolean"},"required_scopes":{"items":{"type":"string"},"type":"array"},"status":{"enum":["present","missing","optional"],"type":"string"},"title":{"type":"string"}},"required":["id","title","status","required","method","path","required_scopes","idempotency_required","description"],"type":"object"},"ReleaseSecurityApprovalSummary":{"additionalProperties":false,"properties":{"approved":{"type":"integer"},"total":{"type":"integer"}},"required":["total","approved"],"type":"object"},"ReleaseSecurityExceptionSummary":{"additionalProperties":false,"properties":{"approved_unexpired":{"type":"integer"},"expired":{"type":"integer"},"total":{"type":"integer"},"unapproved":{"type":"integer"}},"required":["total","approved_unexpired","unapproved","expired"],"type":"object"},"ReleaseSecurityMissingDecision":{"additionalProperties":false,"properties":{"component":{"type":"string"},"finding_id":{"type":"string"},"scan_id":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["finding_id","scan_id","vulnerability","severity","state"],"type":"object"},"ReleaseSecurityProductSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"],"type":"object"},"ReleaseSecurityReleaseSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"state":{"type":"string"},"version":{"type":"string"}},"required":["id","version","state"],"type":"object"},"ReleaseSecuritySummary":{"additionalProperties":false,"properties":{"approval_summary":{"$ref":"#/components/schemas/ReleaseSecurityApprovalSummary"},"artifact_count":{"type":"integer"},"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"decisions_by_status":{"additionalProperties":{"type":"integer"},"type":"object"},"exception_summary":{"$ref":"#/components/schemas/ReleaseSecurityExceptionSummary"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_required_decisions":{"items":{"$ref":"#/components/schemas/ReleaseSecurityMissingDecision"},"type":"array"},"open_findings_by_severity":{"additionalProperties":{"type":"integer"},"type":"object"},"package_status":{"enum":["generated","not_generated"],"type":"string"},"product":{"$ref":"#/components/schemas/ReleaseSecurityProductSummary"},"readiness_status":{"enum":["passed","failed"],"type":"string"},"release":{"$ref":"#/components/schemas/ReleaseSecurityReleaseSummary"},"sbom_status":{"enum":["present","missing"],"type":"string"},"schema_version":{"type":"string"},"vulnerability_scan_status":{"enum":["present","missing"],"type":"string"}},"required":["product","release","artifact_count","sbom_status","vulnerability_scan_status","open_findings_by_severity","decisions_by_status","approval_summary","exception_summary","readiness_status","package_status","counts","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseSecuritySummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseSecuritySummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"examples":{"release-evidence-package":{"summary":"Create a scoped release evidence package","value":{"expires_at":"2026-06-30T00:00:00Z","product_id":"prod_20260527120000","redaction_profile_id":"rp_20260527120000","release_id":"rel_20260527120000","title":"Payments API 1.0.0 release evidence package"}}},"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"examples":{"release-candidate":{"summary":"Create a release for evidence collection","value":{"product_id":"prod_20260527120000","project_id":"proj_20260527120000","version":"1.0.0-rc.1"}}},"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"examples":{"created-release":{"summary":"Created release response","value":{"data":{"created_at":"2026-05-27T12:00:00Z","id":"rel_20260527120000","product_id":"prod_20260527120000","project_id":"proj_20260527120000","schema_version":"release.v1.0.0","status":"draft","tenant_id":"ten_20260527120000","version":"1.0.0-rc.1"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/evidence-flow/start":{"post":{"description":"Returns a high-level release evidence workflow plan, current evidence counts, required scopes, assumptions, and limitations. This read-only convenience operation does not create evidence.","operationId":"startReleaseEvidenceFlow","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEvidenceFlowEnvelope"}}},"description":"Release evidence flow envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Start release evidence flow","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:read"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/security-summary":{"get":{"description":"Returns a tenant-scoped release security summary for review surfaces without raw evidence payload bytes.","operationId":"releaseSecuritySummary","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseSecuritySummaryEnvelope"}}},"description":"Release security summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release security summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"examples":{"failed-readiness-with-gap":{"summary":"Readiness report with a vulnerability decision gap","value":{"data":{"accepted_exceptions":[],"assumptions":["Readiness is based on tenant evidence recorded in Evydence."],"blocking_findings":[{"component":"pkg:apk/openssl@3.1.0-r0","decision_state":"missing","finding_id":"scan_20260527120000:finding:1","release_id":"rel_20260527120000","scan_id":"scan_20260527120000","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"generated_at":"2026-05-27T12:00:00Z","limitations":["Readiness supports technical review and does not prove legal compliance, certification, complete vulnerability coverage, or release security."],"missing_evidence":["vulnerability_decision"],"policy_set":"policy-set.v1.0.0","product_id":"prod_20260527120000","release_id":"rel_20260527120000","report_type":"release_readiness","result":"failed","schema_version":"release-readiness.v1.0.0","summary":{"headline":"Release evidence has one blocking vulnerability decision gap.","human_summary":"Required artifact, SBOM, scan, build, and bundle evidence is present, but one critical finding still needs a valid decision or approved exception.","policy_set":"policy-set.v1.0.0","result":"failed"},"template_version":"release-readiness.v1.0.0"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"examples":{"cyclonedx-release-sbom":{"summary":"Upload a CycloneDX SBOM linked to the release artifact","value":{"artifact_id":"art_20260527120000","payload":{"bomFormat":"CycloneDX","components":[{"name":"payments-api","purl":"pkg:oci/payments-api@sha256-ca978112","version":"1.0.0-rc.1"},{"name":"openssl","purl":"pkg:apk/openssl@3.1.0-r0","version":"3.1.0-r0"}],"specVersion":"1.6"},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"examples":{"not-affected-decision":{"summary":"Record a customer-visible not-affected decision","value":{"customer_visible":true,"evidence_ids":["ev_20260527120000"],"impact_statement":"The shipped artifact does not include the affected runtime path.","justification":"The vulnerable code path is not reachable in this release.","status":"not_affected"}}},"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"examples":{"generic-critical-finding":{"summary":"Upload a generic scanner finding for release triage","value":{"findings":[{"component":"pkg:apk/openssl@3.1.0-r0","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"release_id":"rel_20260527120000","scanner":"generic-json","target_ref":"pkg:oci/payments-api@sha256-ca978112"}}},"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CRAVulnerabilityHandlingReport":{"additionalProperties":false,"properties":{"accepted_exceptions":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"CRAVulnerabilityHandlingReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"remediation":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"policy_set":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlow":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["needs_evidence","ready_for_review"],"type":"string"},"steps":{"items":{"$ref":"#/components/schemas/ReleaseEvidenceFlowStep"},"type":"array"}},"required":["release_id","product_id","status","counts","steps","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseEvidenceFlowEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseEvidenceFlow"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlowStep":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"idempotency_required":{"type":"boolean"},"method":{"type":"string"},"next_reference":{"type":"string"},"path":{"type":"string"},"required":{"type":"boolean"},"required_scopes":{"items":{"type":"string"},"type":"array"},"status":{"enum":["present","missing","optional"],"type":"string"},"title":{"type":"string"}},"required":["id","title","status","required","method","path","required_scopes","idempotency_required","description"],"type":"object"},"ReleaseSecurityApprovalSummary":{"additionalProperties":false,"properties":{"approved":{"type":"integer"},"total":{"type":"integer"}},"required":["total","approved"],"type":"object"},"ReleaseSecurityExceptionSummary":{"additionalProperties":false,"properties":{"approved_unexpired":{"type":"integer"},"expired":{"type":"integer"},"total":{"type":"integer"},"unapproved":{"type":"integer"}},"required":["total","approved_unexpired","unapproved","expired"],"type":"object"},"ReleaseSecurityMissingDecision":{"additionalProperties":false,"properties":{"component":{"type":"string"},"finding_id":{"type":"string"},"scan_id":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["finding_id","scan_id","vulnerability","severity","state"],"type":"object"},"ReleaseSecurityProductSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"],"type":"object"},"ReleaseSecurityReleaseSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"state":{"type":"string"},"version":{"type":"string"}},"required":["id","version","state"],"type":"object"},"ReleaseSecuritySummary":{"additionalProperties":false,"properties":{"approval_summary":{"$ref":"#/components/schemas/ReleaseSecurityApprovalSummary"},"artifact_count":{"type":"integer"},"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"decisions_by_status":{"additionalProperties":{"type":"integer"},"type":"object"},"exception_summary":{"$ref":"#/components/schemas/ReleaseSecurityExceptionSummary"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_required_decisions":{"items":{"$ref":"#/components/schemas/ReleaseSecurityMissingDecision"},"type":"array"},"open_findings_by_severity":{"additionalProperties":{"type":"integer"},"type":"object"},"package_status":{"enum":["generated","not_generated"],"type":"string"},"product":{"$ref":"#/components/schemas/ReleaseSecurityProductSummary"},"readiness_status":{"enum":["passed","failed"],"type":"string"},"release":{"$ref":"#/components/schemas/ReleaseSecurityReleaseSummary"},"sbom_status":{"enum":["present","missing"],"type":"string"},"schema_version":{"type":"string"},"vulnerability_scan_status":{"enum":["present","missing"],"type":"string"}},"required":["product","release","artifact_count","sbom_status","vulnerability_scan_status","open_findings_by_severity","decisions_by_status","approval_summary","exception_summary","readiness_status","package_status","counts","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseSecuritySummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseSecuritySummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityUpdateEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"fixed_decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incidents":{"items":{"$ref":"#/components/schemas/Incident"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"remediation_tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"SecurityUpdateEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"examples":{"release-evidence-package":{"summary":"Create a scoped release evidence package","value":{"expires_at":"2026-06-30T00:00:00Z","product_id":"prod_20260527120000","redaction_profile_id":"rp_20260527120000","release_id":"rel_20260527120000","title":"Payments API 1.0.0 release evidence package"}}},"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"examples":{"release-candidate":{"summary":"Create a release for evidence collection","value":{"product_id":"prod_20260527120000","project_id":"proj_20260527120000","version":"1.0.0-rc.1"}}},"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"examples":{"created-release":{"summary":"Created release response","value":{"data":{"created_at":"2026-05-27T12:00:00Z","id":"rel_20260527120000","product_id":"prod_20260527120000","project_id":"proj_20260527120000","schema_version":"release.v1.0.0","status":"draft","tenant_id":"ten_20260527120000","version":"1.0.0-rc.1"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/evidence-flow/start":{"post":{"description":"Returns a high-level release evidence workflow plan, current evidence counts, required scopes, assumptions, and limitations. This read-only convenience operation does not create evidence.","operationId":"startReleaseEvidenceFlow","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEvidenceFlowEnvelope"}}},"description":"Release evidence flow envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Start release evidence flow","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:read"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/security-summary":{"get":{"description":"Returns a tenant-scoped release security summary for review surfaces without raw evidence payload bytes.","operationId":"releaseSecuritySummary","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseSecuritySummaryEnvelope"}}},"description":"Release security summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release security summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-vulnerability-handling":{"get":{"description":"Returns a CRA-oriented vulnerability handling evidence report without legal compliance, certification, scanner-authority, or release-security conclusions.","operationId":"craVulnerabilityHandlingReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReportEnvelope"}}},"description":"CRA vulnerability handling report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA vulnerability handling report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"examples":{"failed-readiness-with-gap":{"summary":"Readiness report with a vulnerability decision gap","value":{"data":{"accepted_exceptions":[],"assumptions":["Readiness is based on tenant evidence recorded in Evydence."],"blocking_findings":[{"component":"pkg:apk/openssl@3.1.0-r0","decision_state":"missing","finding_id":"scan_20260527120000:finding:1","release_id":"rel_20260527120000","scan_id":"scan_20260527120000","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"generated_at":"2026-05-27T12:00:00Z","limitations":["Readiness supports technical review and does not prove legal compliance, certification, complete vulnerability coverage, or release security."],"missing_evidence":["vulnerability_decision"],"policy_set":"policy-set.v1.0.0","product_id":"prod_20260527120000","release_id":"rel_20260527120000","report_type":"release_readiness","result":"failed","schema_version":"release-readiness.v1.0.0","summary":{"headline":"Release evidence has one blocking vulnerability decision gap.","human_summary":"Required artifact, SBOM, scan, build, and bundle evidence is present, but one critical finding still needs a valid decision or approved exception.","policy_set":"policy-set.v1.0.0","result":"failed"},"template_version":"release-readiness.v1.0.0"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/security-update-evidence":{"get":{"description":"Returns a security update evidence report for release-scoped fixed decisions, incidents, remediation tasks, and linked evidence without legal or security conclusions.","operationId":"securityUpdateEvidenceReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReportEnvelope"}}},"description":"Security update evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security update evidence report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"examples":{"cyclonedx-release-sbom":{"summary":"Upload a CycloneDX SBOM linked to the release artifact","value":{"artifact_id":"art_20260527120000","payload":{"bomFormat":"CycloneDX","components":[{"name":"payments-api","purl":"pkg:oci/payments-api@sha256-ca978112","version":"1.0.0-rc.1"},{"name":"openssl","purl":"pkg:apk/openssl@3.1.0-r0","version":"3.1.0-r0"}],"specVersion":"1.6"},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"examples":{"not-affected-decision":{"summary":"Record a customer-visible not-affected decision","value":{"customer_visible":true,"evidence_ids":["ev_20260527120000"],"impact_statement":"The shipped artifact does not include the affected runtime path.","justification":"The vulnerable code path is not reachable in this release.","status":"not_affected"}}},"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"examples":{"generic-critical-finding":{"summary":"Upload a generic scanner finding for release triage","value":{"findings":[{"component":"pkg:apk/openssl@3.1.0-r0","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"release_id":"rel_20260527120000","scanner":"generic-json","target_ref":"pkg:oci/payments-api@sha256-ca978112"}}},"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/sdk/openapi-route-catalog.json b/sdk/openapi-route-catalog.json index 4557b74..bc5fe59 100644 --- a/sdk/openapi-route-catalog.json +++ b/sdk/openapi-route-catalog.json @@ -1,5 +1,5 @@ { - "route_count": 171, + "route_count": 173, "routes": [ { "idempotency_key_required": false, @@ -1993,6 +1993,23 @@ "200" ] }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "craVulnerabilityHandlingReport", + "path": "/v1/reports/cra-vulnerability-handling", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/CRAVulnerabilityHandlingReportEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "report:read" + ], + "success_statuses": [ + "200" + ] + }, { "idempotency_key_required": false, "method": "GET", @@ -2095,6 +2112,23 @@ "200" ] }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "securityUpdateEvidenceReport", + "path": "/v1/reports/security-update-evidence", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SecurityUpdateEvidenceReportEnvelope" + ], + "scopes": [ + "report:read" + ], + "success_statuses": [ + "200" + ] + }, { "idempotency_key_required": false, "method": "GET", From 91206f1adabd21c53eefea1d6ed99e7630bb7b24 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 23:06:32 +0300 Subject: [PATCH 209/287] feat(portal): add gated customer package exchange --- .productization_next_steps.md | 8 +- docs/api.md | 4 +- docs/operations.md | 2 +- docs/reference/api-contract-matrix.md | 4 +- docs/reference/customer-package-manifest.md | 14 +- internal/adapters/httpapi/openapi.go | 59 +++- .../adapters/httpapi/openapi_operations.go | 12 + internal/adapters/httpapi/portal_handlers.go | 49 +++- .../adapters/httpapi/route_registration.go | 2 + internal/adapters/httpapi/router_test.go | 25 +- internal/adapters/postgres/store.go | 269 +++++++++++------- internal/app/authz_inventory_test.go | 4 + internal/app/context_cancellation_test.go | 24 ++ internal/app/enterprise.go | 171 +++++++++-- internal/app/enterprise_test.go | 38 ++- internal/app/future_extensions.go | 91 +++++- internal/app/governance_packages.go | 101 ++++++- internal/app/identity_service.go | 4 + internal/app/ledger.go | 2 + internal/app/package_report_service.go | 12 + internal/app/ports.go | 189 ++++++------ internal/app/state.go | 193 +++++++------ internal/domain/domain.go | 203 +++++++------ ...ustomer_portal_nda_answer_library.down.sql | 7 + ..._customer_portal_nda_answer_library.up.sql | 26 ++ openapi.yaml | 2 +- sdk/openapi-route-catalog.json | 36 ++- 27 files changed, 1092 insertions(+), 459 deletions(-) create mode 100644 migrations/20260601000400_customer_portal_nda_answer_library.down.sql create mode 100644 migrations/20260601000400_customer_portal_nda_answer_library.up.sql diff --git a/.productization_next_steps.md b/.productization_next_steps.md index 6463630..fa97467 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -1206,16 +1206,16 @@ implemented, documented, and covered by tests or release checks. Checked sub-items record existing repository evidence so future work does not repeat already-built surfaces. -#### [ ] EVY-200 — Artifact exchange / trust package portal +#### [x] EVY-200 — Artifact exchange / trust package portal Potential later expansion: -* [ ] NDA-gated customer access +* [x] NDA-gated customer access * [x] package access logs, counters, and failed-attempt tracking * [x] time-limited package links through expiring portal tokens -* [ ] watermarking +* [x] watermarking * [x] customer-specific packages through scoped customer package records -* [ ] answer library +* [x] answer library * [x] security questionnaire drafts Only do this after customer-safe packages are strong. diff --git a/docs/api.md b/docs/api.md index 64f85a2..3f51eb7 100644 --- a/docs/api.md +++ b/docs/api.md @@ -287,7 +287,7 @@ Important scope boundaries: | Tenant data | Cross-tenant reads return `404` where applicable. | | Collector identity | Build attribution is derived from the authenticated collector key; clients must not submit `collector_id` for build attribution. | | Instance admin | `GET /v1/admin/instance` requires explicit `instance:admin`; tenant admin and ordinary wildcard tenant keys are insufficient. | -| Customer portal | `POST /v1/customer-portal/package` and `/v1/customer-portal/package/download` are public token exchange endpoints and intentionally do not use bearer authentication. Successful exchanges and downloads are visible through the tenant audit log without storing the supplied token. | +| Customer portal | `POST /v1/customer-portal/package` and `/v1/customer-portal/package/download` are public token exchange endpoints and intentionally do not use bearer authentication. Optional NDA acceptance and distribution watermarks are recorded without storing supplied tokens. Successful exchanges and downloads are visible through the tenant audit log without storing the supplied token. | ## Endpoint Catalog @@ -436,6 +436,8 @@ Source snapshots capture submitted provider metadata. They do not call provider | `POST` | `/v1/questionnaire-templates` | Create questionnaire template. | | `POST` | `/v1/questionnaire-packages` | Generate evidence-backed responses. | | `POST` | `/v1/questionnaire-drafts` | Create evidence-backed draft answers for review. | +| `GET` | `/v1/questionnaire-answer-library` | List reusable questionnaire answer drafts. | +| `POST` | `/v1/questionnaire-answer-library` | Create reusable questionnaire answer draft. | | `GET` | `/v1/reports/security-review-package` | Redaction-aware package report. | | `GET` | `/v1/reports/cra-readiness-html` | HTML CRA-readiness review content. | | `POST` | `/v1/reports/pdf` | Create reproducible PDF report package metadata and payload hash. | diff --git a/docs/operations.md b/docs/operations.md index 629b0fc..83bf5b8 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -38,7 +38,7 @@ This operator index points to the canonical references for running Evydence. Kee ## Token And Trust Boundaries - API keys, collector keys, SSO session tokens, and customer portal access tokens are bearer secrets. Do not place them in logs, documentation, long-lived build output, or customer packages. -- Customer portal access tokens are returned once by `POST /v1/customer-portal/access`, expire, and are stored as hashes. Successful manifest exchanges and ZIP downloads write audit-chain entries under both the portal access record and package record; failed known-prefix attempts are recorded as unverified access events. Supplied portal tokens are never stored in those entries. Deployments should still use reverse-proxy or API-gateway throttling for the unauthenticated portal endpoint. +- Customer portal access tokens are returned once by `POST /v1/customer-portal/access`, expire, and are stored as hashes. Access can require explicit NDA acceptance, and portal ZIP downloads can include non-secret distribution watermarks. Successful manifest exchanges, ZIP downloads, NDA acceptance events, and failed known-prefix attempts write audit-chain entries under the portal access record and relevant package record without storing the supplied token. Deployments should still use reverse-proxy or API-gateway throttling for the unauthenticated portal endpoint. - Human SSO session records are admin-managed, authenticated SSO sessions can revoke themselves through API-first logout, and SSO credential exchange can set an HttpOnly session cookie after locally verifying an OIDC ID token or SAML assertion against tenant-configured trust material. OIDC group claim values can be captured on the session and mapped to configured roles without creating permanent role bindings from token claims. Current endpoints can refresh OIDC public JWKS from discovery metadata and can call a configured OIDC UserInfo endpoint or provider validation gateway for verification checks, but they do not implement direct provider-specific management API clients or external group synchronization. - Object-retention APIs record and verify retention intent for tenant-prefixed object paths. S3/MinIO verification can check bucket defaults plus sample-object retention and legal hold where configured. Enforcing WORM or object-lock settings remains the responsibility of the configured object store and deployment policy. diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index b4b95ec..081eee5 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 173 operations: 173 precise, 0 broad. +Generated from 175 operations: 175 precise, 0 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -98,6 +98,8 @@ Generated from 173 operations: 173 precise, 0 broad. | POST | /v1/public-transparency-log-entries/{id}/fetch-proof | fetchPublicTransparencyLogEntryProof | Bearer | keys:admin | required | path:id | application/json:EmptyObject | 200:application/json:PublicTransparencyLogEntryEnvelope | precise | | POST | /v1/public-transparency-log-entries/{id}/verify | verifyPublicTransparencyLogEntry | Bearer | keys:admin | required | path:id | application/json:VerifyPublicTransparencyLogEntryRequest | 200:application/json:PublicTransparencyLogEntryEnvelope | precise | | POST | /v1/public-transparency-logs | createPublicTransparencyLog | Bearer | keys:admin | required | - | application/json:CreatePublicTransparencyLogRequest | 201:application/json:PublicTransparencyLogEnvelope | precise | +| GET | /v1/questionnaire-answer-library | listQuestionnaireAnswerLibrary | Bearer | package:read | - | query:product_id, query:question_id, query:release_id | - | 200:application/json:QuestionnaireAnswerLibraryEntryListEnvelope | precise | +| POST | /v1/questionnaire-answer-library | createQuestionnaireAnswerLibraryEntry | Bearer | package:write | required | - | application/json:CreateQuestionnaireAnswerLibraryEntryRequest | 201:application/json:QuestionnaireAnswerLibraryEntryEnvelope | precise | | POST | /v1/questionnaire-drafts | createQuestionnaireDraft | Bearer | package:read | required | - | application/json:CreateQuestionnaireDraftRequest | 201:application/json:QuestionnaireDraftEnvelope | precise | | POST | /v1/questionnaire-packages | createQuestionnairePackage | Bearer | package:write | required | - | application/json:CreateQuestionnairePackageRequest | 201:application/json:QuestionnairePackageEnvelope | precise | | POST | /v1/questionnaire-templates | createQuestionnaireTemplate | Bearer | package:write | required | - | application/json:CreateQuestionnaireTemplateRequest | 201:application/json:QuestionnaireTemplateEnvelope | precise | diff --git a/docs/reference/customer-package-manifest.md b/docs/reference/customer-package-manifest.md index 82f5b50..bf2660b 100644 --- a/docs/reference/customer-package-manifest.md +++ b/docs/reference/customer-package-manifest.md @@ -90,11 +90,15 @@ the matching archive fixture is Runtime ZIP exports also include `report.html`, a self-contained static HTML rendering of the redacted manifest. It shows release summary, VEX and -vulnerability-decision tables, API contract evidence when included, readiness -checks, verification material, limitations, and non-claims without requiring a -server or loading remote assets. The HTML report is generated from -package-scoped data only and excludes raw evidence payload bytes, object-store -references, token material, private keys, and internal decision notes. +vulnerability-decision tables, questionnaire answer-library entries when +included, API contract evidence when included, readiness checks, verification +material, limitations, and non-claims without requiring a server or loading +remote assets. Portal ZIP downloads can also include `WATERMARK.txt` and a +visible report watermark for customer-specific distribution. The watermark is +not a secret and does not change the canonical package manifest hash. The HTML +report is generated from package-scoped data only and excludes raw evidence +payload bytes, object-store references, token material, private keys, and +internal decision notes. ## Redaction Leakage Guard diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 6c60a71..96afdf5 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -1021,19 +1021,20 @@ func registerCriticalSchemas(registry *specs.Registry) { "expires_at": map[string]any{"type": "string", "format": "date-time"}, }, "product_id", "redaction_profile_id", "title", "expires_at")) registry.RegisterSchema("CustomerSecurityPackage", objectSchema(map[string]any{ - "id": map[string]any{"type": "string"}, - "tenant_id": map[string]any{"type": "string"}, - "product_id": map[string]any{"type": "string"}, - "release_id": map[string]any{"type": "string"}, - "redaction_profile_id": map[string]any{"type": "string"}, - "title": map[string]any{"type": "string"}, - "state": map[string]any{"type": "string"}, - "manifest": map[string]any{"type": "object", "additionalProperties": true}, - "manifest_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, - "expires_at": map[string]any{"type": "string", "format": "date-time"}, - "access_count": map[string]any{"type": "integer"}, - "schema_version": map[string]any{"type": "string"}, - "created_at": map[string]any{"type": "string", "format": "date-time"}, + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "redaction_profile_id": map[string]any{"type": "string"}, + "title": map[string]any{"type": "string"}, + "state": map[string]any{"type": "string"}, + "manifest": map[string]any{"type": "object", "additionalProperties": true}, + "manifest_hash": map[string]any{"type": "string", "pattern": "^sha256:"}, + "distribution_watermark": map[string]any{"type": "string"}, + "expires_at": map[string]any{"type": "string", "format": "date-time"}, + "access_count": map[string]any{"type": "integer"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, }, "id", "tenant_id", "product_id", "redaction_profile_id", "title", "state", "manifest", "manifest_hash", "expires_at", "access_count", "schema_version", "created_at")) registry.RegisterSchema("CustomerSecurityPackageEnvelope", dataEnvelopeSchema("#/components/schemas/CustomerSecurityPackage")) registry.RegisterSchema("SecurityReviewPackageReport", objectSchema(map[string]any{ @@ -1212,6 +1213,32 @@ func registerCriticalSchemas(registry *specs.Registry) { "created_at": map[string]any{"type": "string", "format": "date-time"}, }, "id", "tenant_id", "template_id", "responses", "manifest_hash", "limitations", "schema_version", "created_at")) registry.RegisterSchema("QuestionnaireDraftEnvelope", dataEnvelopeSchema("#/components/schemas/QuestionnaireDraft")) + registry.RegisterSchema("CreateQuestionnaireAnswerLibraryEntryRequest", objectSchema(map[string]any{ + "question_id": map[string]any{"type": "string"}, + "evidence_type": map[string]any{"type": "string"}, + "control_id": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "answer": map[string]any{"type": "string"}, + "evidence_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + }, "answer")) + registry.RegisterSchema("QuestionnaireAnswerLibraryEntry", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "question_id": map[string]any{"type": "string"}, + "evidence_type": map[string]any{"type": "string"}, + "control_id": map[string]any{"type": "string"}, + "product_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "answer": map[string]any{"type": "string"}, + "evidence_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "answer", "schema_version", "created_at")) + registry.RegisterSchema("QuestionnaireAnswerLibraryEntryEnvelope", dataEnvelopeSchema("#/components/schemas/QuestionnaireAnswerLibraryEntry")) + registry.RegisterSchema("QuestionnaireAnswerLibraryEntryListEnvelope", dataArrayEnvelopeSchema("#/components/schemas/QuestionnaireAnswerLibraryEntry")) registry.RegisterSchema("CreatePDFReportPackageRequest", objectSchema(map[string]any{ "report_type": map[string]any{"type": "string"}, "product_id": map[string]any{"type": "string"}, @@ -2352,6 +2379,8 @@ func registerCriticalSchemas(registry *specs.Registry) { registry.RegisterSchema("CreateCustomerPortalAccessRequest", objectSchema(map[string]any{ "package_id": map[string]any{"type": "string"}, "customer_name": map[string]any{"type": "string"}, + "require_nda": map[string]any{"type": "boolean"}, + "watermark": map[string]any{"type": "string", "description": "Optional customer-visible distribution watermark. It is not a token or secret."}, "expires_at": map[string]any{"type": "string", "format": "date-time"}, }, "package_id", "customer_name", "expires_at")) registry.RegisterSchema("CustomerPortalAccessCreateResponse", objectSchema(map[string]any{ @@ -2360,7 +2389,9 @@ func registerCriticalSchemas(registry *specs.Registry) { }, "access", "secret")) registry.RegisterSchema("CustomerPortalAccessCreateEnvelope", dataEnvelopeSchema("#/components/schemas/CustomerPortalAccessCreateResponse")) registry.RegisterSchema("CustomerPortalPackageRequest", objectSchema(map[string]any{ - "token": map[string]any{"type": "string", "description": "Customer portal access token issued by createCustomerPortalAccess."}, + "token": map[string]any{"type": "string", "description": "Customer portal access token issued by createCustomerPortalAccess."}, + "nda_accepted": map[string]any{"type": "boolean", "description": "Set true to record acceptance for NDA-gated portal access."}, + "nda_accepted_by": map[string]any{"type": "string", "description": "Reviewer label recorded when NDA acceptance is required. Do not include secrets."}, }, "token")) } diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 8d4a22f..bfb9f34 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -856,6 +856,18 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Description = "Creates an evidence-backed questionnaire draft with limitations." operation.RequestBody = jsonRequest("Questionnaire draft creation request.", "#/components/schemas/CreateQuestionnaireDraftRequest") operation.Responses[http.StatusCreated] = jsonResponse("Created questionnaire draft envelope.", "#/components/schemas/QuestionnaireDraftEnvelope") + case "createQuestionnaireAnswerLibraryEntry": + operation.Description = "Creates a tenant-scoped reusable questionnaire answer draft linked to optional evidence, product, release, or control scope." + operation.RequestBody = jsonRequest("Questionnaire answer library entry creation request.", "#/components/schemas/CreateQuestionnaireAnswerLibraryEntryRequest") + operation.Responses[http.StatusCreated] = jsonResponse("Created questionnaire answer library entry envelope.", "#/components/schemas/QuestionnaireAnswerLibraryEntryEnvelope") + case "listQuestionnaireAnswerLibrary": + operation.Description = "Lists tenant-scoped questionnaire answer library entries with optional question, product, and release filters." + operation.Parameters = append(operation.Parameters, + queryParam("question_id", "Filter by questionnaire question id.", "string"), + queryParam("product_id", "Filter by product id.", "string"), + queryParam("release_id", "Filter by release id.", "string"), + ) + operation.Responses[http.StatusOK] = jsonResponse("Questionnaire answer library entry list envelope.", "#/components/schemas/QuestionnaireAnswerLibraryEntryListEnvelope") case "createPDFReportPackage": operation.Description = "Creates a deterministic PDF report package record and payload metadata." operation.RequestBody = jsonRequest("PDF report package creation request.", "#/components/schemas/CreatePDFReportPackageRequest") diff --git a/internal/adapters/httpapi/portal_handlers.go b/internal/adapters/httpapi/portal_handlers.go index 3d3c7cf..8adc8a1 100644 --- a/internal/adapters/httpapi/portal_handlers.go +++ b/internal/adapters/httpapi/portal_handlers.go @@ -12,20 +12,24 @@ func (s *Server) createCustomerPortalAccess(w http.ResponseWriter, r *http.Reque var req struct { PackageID string `json:"package_id"` CustomerName string `json:"customer_name"` + RequireNDA bool `json:"require_nda"` + Watermark string `json:"watermark"` ExpiresAt time.Time `json:"expires_at"` } s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - access, secret, err := s.ledger.CreateCustomerPortalAccess(ctx, actor, app.CreateCustomerPortalAccessInput{PackageID: req.PackageID, CustomerName: req.CustomerName, ExpiresAt: req.ExpiresAt}) + access, secret, err := s.ledger.CreateCustomerPortalAccess(ctx, actor, app.CreateCustomerPortalAccessInput{PackageID: req.PackageID, CustomerName: req.CustomerName, RequireNDA: req.RequireNDA, Watermark: req.Watermark, ExpiresAt: req.ExpiresAt}) return http.StatusCreated, map[string]any{"access": access, "secret": secret}, err }) } func (s *Server) accessCustomerPortalPackage(w http.ResponseWriter, r *http.Request) { var req struct { - Token string `json:"token"` + Token string `json:"token"` + NDAAccepted bool `json:"nda_accepted"` + NDAAcceptedBy string `json:"nda_accepted_by"` } body, err := readBody(r) if err != nil { @@ -36,7 +40,7 @@ func (s *Server) accessCustomerPortalPackage(w http.ResponseWriter, r *http.Requ writeProblem(w, r, err) return } - pkg, err := s.ledger.AccessCustomerPortalPackage(r.Context(), req.Token) + pkg, err := s.ledger.AccessCustomerPortalPackageWithAcceptance(r.Context(), req.Token, app.CustomerPortalAcceptanceInput{NDAAccepted: req.NDAAccepted, NDAAcceptedBy: req.NDAAcceptedBy}) if err != nil { writeProblem(w, r, err) return @@ -46,7 +50,9 @@ func (s *Server) accessCustomerPortalPackage(w http.ResponseWriter, r *http.Requ func (s *Server) downloadCustomerPortalPackage(w http.ResponseWriter, r *http.Request) { var req struct { - Token string `json:"token"` + Token string `json:"token"` + NDAAccepted bool `json:"nda_accepted"` + NDAAcceptedBy string `json:"nda_accepted_by"` } body, err := readBody(r) if err != nil { @@ -57,7 +63,7 @@ func (s *Server) downloadCustomerPortalPackage(w http.ResponseWriter, r *http.Re writeProblem(w, r, err) return } - archive, err := s.ledger.ExportCustomerPortalPackageArchive(r.Context(), req.Token) + archive, err := s.ledger.ExportCustomerPortalPackageArchiveWithAcceptance(r.Context(), req.Token, app.CustomerPortalAcceptanceInput{NDAAccepted: req.NDAAccepted, NDAAcceptedBy: req.NDAAcceptedBy}) if err != nil { writeProblem(w, r, err) return @@ -95,3 +101,36 @@ func (s *Server) createQuestionnairePackage(w http.ResponseWriter, r *http.Reque return http.StatusCreated, pkg, err }) } + +func (s *Server) createQuestionnaireAnswerLibraryEntry(w http.ResponseWriter, r *http.Request) { + var req struct { + QuestionID string `json:"question_id"` + EvidenceType string `json:"evidence_type"` + ControlID string `json:"control_id"` + ProductID string `json:"product_id"` + ReleaseID string `json:"release_id"` + Answer string `json:"answer"` + EvidenceIDs []string `json:"evidence_ids"` + Limitations []string `json:"limitations"` + } + s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { + if err := decodeJSON(body, &req); err != nil { + return 0, nil, err + } + entry, err := s.ledger.CreateQuestionnaireAnswerLibraryEntry(ctx, actor, app.CreateQuestionnaireAnswerLibraryEntryInput{QuestionID: req.QuestionID, EvidenceType: req.EvidenceType, ControlID: req.ControlID, ProductID: req.ProductID, ReleaseID: req.ReleaseID, Answer: req.Answer, EvidenceIDs: req.EvidenceIDs, Limitations: req.Limitations}) + return http.StatusCreated, entry, err + }) +} + +func (s *Server) listQuestionnaireAnswerLibrary(w http.ResponseWriter, r *http.Request) { + actor, ok := s.authenticate(w, r) + if !ok { + return + } + entries, err := s.ledger.ListQuestionnaireAnswerLibrary(r.Context(), actor, app.ListQuestionnaireAnswerLibraryInput{QuestionID: r.URL.Query().Get("question_id"), ProductID: r.URL.Query().Get("product_id"), ReleaseID: r.URL.Query().Get("release_id")}) + if err != nil { + writeProblem(w, r, err) + return + } + writeData(w, http.StatusOK, entries) +} diff --git a/internal/adapters/httpapi/route_registration.go b/internal/adapters/httpapi/route_registration.go index c2f2791..4311ffa 100644 --- a/internal/adapters/httpapi/route_registration.go +++ b/internal/adapters/httpapi/route_registration.go @@ -181,6 +181,8 @@ func (s *Server) packagePortalRoutes() []routeDef { {http.MethodPost, "/v1/questionnaire-templates", op("createQuestionnaireTemplate", http.MethodPost, "/v1/questionnaire-templates", "Create questionnaire template", []string{app.ScopePackageWrite}), http.HandlerFunc(s.createQuestionnaireTemplate)}, {http.MethodPost, "/v1/questionnaire-packages", op("createQuestionnairePackage", http.MethodPost, "/v1/questionnaire-packages", "Create questionnaire package", []string{app.ScopePackageWrite}), http.HandlerFunc(s.createQuestionnairePackage)}, {http.MethodPost, "/v1/questionnaire-drafts", op("createQuestionnaireDraft", http.MethodPost, "/v1/questionnaire-drafts", "Create evidence-backed questionnaire draft", []string{app.ScopePackageRead}), http.HandlerFunc(s.createQuestionnaireDraft)}, + {http.MethodPost, "/v1/questionnaire-answer-library", op("createQuestionnaireAnswerLibraryEntry", http.MethodPost, "/v1/questionnaire-answer-library", "Create questionnaire answer library entry", []string{app.ScopePackageWrite}), http.HandlerFunc(s.createQuestionnaireAnswerLibraryEntry)}, + {http.MethodGet, "/v1/questionnaire-answer-library", op("listQuestionnaireAnswerLibrary", http.MethodGet, "/v1/questionnaire-answer-library", "List questionnaire answer library entries", []string{app.ScopePackageRead}), http.HandlerFunc(s.listQuestionnaireAnswerLibrary)}, {http.MethodGet, "/v1/reports/security-review-package", op("securityReviewPackageReport", http.MethodGet, "/v1/reports/security-review-package", "Security review package report", []string{app.ScopePackageRead}), http.HandlerFunc(s.securityReviewPackageReport)}, {http.MethodGet, "/v1/reports/cra-readiness-html", op("craReadinessHTMLPackage", http.MethodGet, "/v1/reports/cra-readiness-html", "CRA readiness HTML package", []string{app.ScopeReportRead}), http.HandlerFunc(s.craReadinessHTMLPackage)}, {http.MethodPost, "/v1/reports/pdf", op("createPDFReportPackage", http.MethodPost, "/v1/reports/pdf", "Create reproducible PDF report package", []string{app.ScopeReportRead}), http.HandlerFunc(s.createPDFReportPackage)}, diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 573bc6e..e9269b3 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -94,7 +94,7 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { if _, ok := redactionRequestProps["preset"]; !ok { t.Fatalf("redaction profile request schema missing preset: %#v", redactionRequestProps) } - for _, schemaName := range []string{"ReadinessStatusEnvelope", "BackupManifestEnvelope", "VerificationResultEnvelope", "ReadinessReportEnvelope", "CRAVulnerabilityHandlingReportEnvelope", "SecurityUpdateEvidenceReportEnvelope", "CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "ReleaseEvidenceFlowEnvelope", "ReleaseSecuritySummaryEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "VEXImportReportEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "VulnerabilityDecisionListEnvelope", "VulnerabilityDecisionSummaryReportEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "UpdateSSOProviderTrustMaterialRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "ExchangeSSOCredentialRequest", "SSOCredentialExchangeEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "DataEnvelope"} { + for _, schemaName := range []string{"ReadinessStatusEnvelope", "BackupManifestEnvelope", "VerificationResultEnvelope", "ReadinessReportEnvelope", "CRAVulnerabilityHandlingReportEnvelope", "SecurityUpdateEvidenceReportEnvelope", "CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "ReleaseEvidenceFlowEnvelope", "ReleaseSecuritySummaryEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "VEXImportReportEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "VulnerabilityDecisionListEnvelope", "VulnerabilityDecisionSummaryReportEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "UpdateSSOProviderTrustMaterialRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "ExchangeSSOCredentialRequest", "SSOCredentialExchangeEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "QuestionnaireAnswerLibraryEntryEnvelope", "QuestionnaireAnswerLibraryEntryListEnvelope", "DataEnvelope"} { if _, ok := schemas[schemaName]; !ok { t.Fatalf("schema %s missing from OpenAPI components", schemaName) } @@ -195,6 +195,12 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { if _, ok := portalDownload["security"]; ok { t.Fatalf("public portal download should not advertise bearer security: %#v", portalDownload["security"]) } + createAnswerLibrary := operationMap(t, paths, "/v1/questionnaire-answer-library", "post") + assertRequestRef(t, createAnswerLibrary, "#/components/schemas/CreateQuestionnaireAnswerLibraryEntryRequest") + assertResponseRef(t, createAnswerLibrary, "201", "#/components/schemas/QuestionnaireAnswerLibraryEntryEnvelope") + listAnswerLibrary := operationMap(t, paths, "/v1/questionnaire-answer-library", "get") + assertQueryParams(t, listAnswerLibrary, "question_id", "product_id", "release_id") + assertResponseRef(t, listAnswerLibrary, "200", "#/components/schemas/QuestionnaireAnswerLibraryEntryListEnvelope") incidentWebhook := operationMap(t, paths, "/v1/incident-webhooks/{receiver_id}", "post") assertQueryParams(t, incidentWebhook, "receiver_id", "X-Evydence-Webhook-Event-ID", "X-Evydence-Webhook-Timestamp", "X-Evydence-Webhook-Signature") if _, ok := incidentWebhook["security"]; ok { @@ -501,6 +507,7 @@ func TestAuthenticatedReadRoutesRejectMissingBearerToken(t *testing.T) { "/v1/marketplace-collectors/collector_missing/health", "/v1/openapi-contracts/contract_missing", "/v1/products", + "/v1/questionnaire-answer-library", "/v1/release-bundles/bundle_missing", "/v1/release-bundles/bundle_missing/manifest", "/v1/release-bundles/bundle_missing/verify", @@ -1248,14 +1255,15 @@ func TestEnterprisePortalRetentionAndCommercialCollectorHTTPFlow(t *testing.T) { profileID := dataField(t, profileBody, "id") packageBody := postJSON(t, server, sessionSecret, "/v1/customer-packages", "ent-package", map[string]any{"product_id": productID, "release_id": releaseID, "redaction_profile_id": profileID, "title": "Customer package", "expires_at": time.Now().UTC().Add(time.Hour).Format(time.RFC3339)}, http.StatusCreated) packageID := dataField(t, packageBody, "id") - accessBody := postJSON(t, server, sessionSecret, "/v1/customer-portal/access", "ent-access", map[string]any{"package_id": packageID, "customer_name": "ACME", "expires_at": time.Now().UTC().Add(time.Hour).Format(time.RFC3339)}, http.StatusCreated) + accessBody := postJSON(t, server, sessionSecret, "/v1/customer-portal/access", "ent-access", map[string]any{"package_id": packageID, "customer_name": "ACME", "require_nda": true, "watermark": "ACME confidential review copy", "expires_at": time.Now().UTC().Add(time.Hour).Format(time.RFC3339)}, http.StatusCreated) portalSecret := nestedDataField(t, accessBody, "secret") - portalBody := postJSONNoAuth(t, server, "/v1/customer-portal/package", map[string]any{"token": portalSecret}, http.StatusOK) - if !strings.Contains(portalBody, packageID) || strings.Contains(portalBody, portalSecret) { + postJSONNoAuth(t, server, "/v1/customer-portal/package", map[string]any{"token": portalSecret}, http.StatusForbidden) + portalBody := postJSONNoAuth(t, server, "/v1/customer-portal/package", map[string]any{"token": portalSecret, "nda_accepted": true, "nda_accepted_by": "reviewer@example.test"}, http.StatusOK) + if !strings.Contains(portalBody, packageID) || !strings.Contains(portalBody, "ACME confidential review copy") || strings.Contains(portalBody, portalSecret) { t.Fatalf("portal package response invalid: %s", portalBody) } portalArchive := postJSONNoAuthRaw(t, server, "/v1/customer-portal/package/download", map[string]any{"token": portalSecret}, http.StatusOK) - if portalArchive.Header().Get("Content-Type") != "application/zip" || !bytes.HasPrefix(portalArchive.Body.Bytes(), []byte("PK")) || bytes.Contains(portalArchive.Body.Bytes(), []byte(portalSecret)) { + if portalArchive.Header().Get("Content-Type") != "application/zip" || !bytes.HasPrefix(portalArchive.Body.Bytes(), []byte("PK")) || bytes.Contains(portalArchive.Body.Bytes(), []byte(portalSecret)) || !bytes.Contains(portalArchive.Body.Bytes(), []byte("WATERMARK.txt")) { t.Fatalf("portal archive response invalid headers=%v len=%d", portalArchive.Header(), portalArchive.Body.Len()) } postJSON(t, server, sessionSecret, "/v1/legal-holds", "ent-hold", map[string]any{"scope_type": "release", "scope_id": releaseID, "reason": "extended review", "owner": "legal"}, http.StatusCreated) @@ -1266,8 +1274,13 @@ func TestEnterprisePortalRetentionAndCommercialCollectorHTTPFlow(t *testing.T) { } templateBody := postJSON(t, server, sessionSecret, "/v1/questionnaire-templates", "ent-question-template", map[string]any{"name": "customer", "version": "1", "questions": []map[string]any{{"id": "q1", "prompt": "Is review evidence available?", "evidence_type": "security_review"}}}, http.StatusCreated) templateID := dataField(t, templateBody, "id") + postJSON(t, server, sessionSecret, "/v1/questionnaire-answer-library", "ent-answer-library", map[string]any{"question_id": "q1", "evidence_type": "security_review", "product_id": productID, "release_id": releaseID, "answer": "A scoped security review evidence record is available in the package evidence.", "evidence_ids": []string{evidenceID}}, http.StatusCreated) + answerLibrary := getJSON(t, server, sessionSecret, "/v1/questionnaire-answer-library?product_id="+productID+"&release_id="+releaseID, http.StatusOK) + if !strings.Contains(answerLibrary, evidenceID) { + t.Fatalf("answer library missing evidence: %s", answerLibrary) + } questionnaire := postJSON(t, server, sessionSecret, "/v1/questionnaire-packages", "ent-question-package", map[string]any{"template_id": templateID, "package_id": packageID, "product_id": productID, "release_id": releaseID}, http.StatusCreated) - if !strings.Contains(questionnaire, evidenceID) { + if !strings.Contains(questionnaire, evidenceID) || !strings.Contains(questionnaire, "scoped security review evidence") { t.Fatalf("questionnaire package missing evidence id: %s", questionnaire) } collectorBody := postJSON(t, server, sessionSecret, "/v1/commercial-collectors", "ent-commercial-collector", map[string]any{"name": "jira", "provider": "jira", "version": "1.0.0", "manifest_hash": "sha256:2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae", "allowed_scopes": []string{"evidence:write"}}, http.StatusCreated) diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index e00490b..cec8272 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -198,100 +198,101 @@ func (s *Store) loadRelationalState(ctx context.Context) (app.PersistedState, bo func relationalEmptyState() app.PersistedState { return app.PersistedState{ - Tenants: map[string]domain.Tenant{}, - Organizations: map[string]domain.Organization{}, - Users: map[string]domain.HumanUser{}, - RoleBindings: map[string]domain.RoleBinding{}, - SSOProviders: map[string]domain.SSOProvider{}, - IdentityLinks: map[string]domain.UserIdentityLink{}, - SSOSessions: map[string]domain.SSOSession{}, - SSOSessionHashes: map[string]string{}, - APIKeys: map[string]domain.APIKey{}, - APIKeyHashes: map[string]string{}, - Collectors: map[string]domain.Collector{}, - CollectorReleases: map[string]domain.CollectorRelease{}, - BuildRuns: map[string]domain.BuildRun{}, - BuildAttestations: map[string]domain.BuildAttestation{}, - EvidenceLifecycle: map[string]domain.EvidenceLifecycleEvent{}, - ReleaseCandidates: map[string]domain.ReleaseCandidate{}, - ContainerImages: map[string]domain.ContainerImage{}, - ArtifactSignatures: map[string]domain.ArtifactSignature{}, - Repositories: map[string]domain.SourceRepository{}, - Commits: map[string]domain.SourceCommit{}, - Branches: map[string]domain.SourceBranch{}, - PullRequests: map[string]domain.PullRequest{}, - Environments: map[string]domain.DeploymentEnvironment{}, - Deployments: map[string]domain.DeploymentEvent{}, - Incidents: map[string]domain.Incident{}, - TimelineEvents: map[string]domain.IncidentTimelineEvent{}, - IncidentWebhookReceivers: map[string]domain.IncidentWebhookReceiver{}, - IncidentWebhookEvents: map[string]domain.IncidentWebhookEvent{}, - RemediationTasks: map[string]domain.RemediationTask{}, - SecurityScans: map[string]domain.SecurityScan{}, - ManualSecurityDocs: map[string]domain.ManualSecurityDocument{}, - SBOMDiffs: map[string]domain.SBOMDiff{}, - DependencyChanges: map[string]domain.DependencyChange{}, - VulnerabilityWorkflow: map[string]domain.VulnerabilityWorkflowRecord{}, - ContractDiffs: map[string]domain.ContractDiff{}, - CustomPolicies: map[string]domain.CustomPolicy{}, - CustomPolicyEvaluations: map[string]domain.CustomPolicyEvaluation{}, - Waivers: map[string]domain.Waiver{}, - Approvals: map[string]domain.ApprovalRecord{}, - DSSETrustRoots: map[string]domain.DSSETrustRoot{}, - CosignVerifications: map[string]domain.CosignVerification{}, - SigningProviders: map[string]domain.SigningProvider{}, - MerkleBatches: map[string]domain.MerkleBatch{}, - TransparencyCheckpoints: map[string]domain.TransparencyCheckpoint{}, - CustomerPortalAccess: map[string]domain.CustomerPortalAccess{}, - CustomerPortalHashes: map[string]string{}, - RedactionProfiles: map[string]domain.RedactionProfile{}, - CustomerPackages: map[string]domain.CustomerSecurityPackage{}, - HTMLReports: map[string]domain.HTMLReportPackage{}, - ReportTemplates: map[string]domain.CustomReportTemplate{}, - RenderedReports: map[string]domain.RenderedCustomReport{}, - EvidenceBundles: map[string]domain.EvidenceBundle{}, - BundleImports: map[string]domain.EvidenceBundleImport{}, - ObjectRetentionPolicies: map[string]domain.ObjectRetentionPolicy{}, - BackupManifests: map[string]domain.BackupManifest{}, - LegalHolds: map[string]domain.LegalHold{}, - RetentionOverrides: map[string]domain.RetentionOverride{}, - QuestionnaireTemplates: map[string]domain.QuestionnaireTemplate{}, - QuestionnairePackages: map[string]domain.QuestionnairePackage{}, - CommercialCollectors: map[string]domain.CommercialCollectorDefinition{}, - EvidenceSummaries: map[string]domain.EvidenceSummary{}, - QuestionnaireDrafts: map[string]domain.QuestionnaireDraft{}, - GraphSnapshots: map[string]domain.EvidenceGraphSnapshot{}, - SaaSProfiles: map[string]domain.SaaSEditionProfile{}, - PublicTransparencyLogs: map[string]domain.PublicTransparencyLog{}, - PublicTransparencyItems: map[string]domain.PublicTransparencyLogEntry{}, - MarketplaceCollectors: map[string]domain.MarketplaceCollector{}, - PDFReports: map[string]domain.PDFReportPackage{}, - AnomalyReports: map[string]domain.AnomalyReport{}, - ProviderVerifications: map[string]domain.ProviderVerification{}, - SigningOperations: map[string]domain.SigningOperation{}, - ControlFrameworks: map[string]domain.ControlFramework{}, - SecurityControls: map[string]domain.SecurityControl{}, - ControlEvidence: map[string]domain.ControlEvidence{}, - Products: map[string]domain.Product{}, - Projects: map[string]domain.Project{}, - Releases: map[string]domain.Release{}, - Artifacts: map[string]domain.Artifact{}, - Evidence: map[string]domain.EvidenceItem{}, - SBOMs: map[string]domain.SBOM{}, - Scans: map[string]domain.VulnerabilityScan{}, - VEXDocuments: map[string]domain.VEXDocument{}, - VEXImportReports: map[string]domain.VEXImportReport{}, - Decisions: map[string]domain.VulnerabilityDecision{}, - Contracts: map[string]domain.OpenAPIContract{}, - Policies: map[string]domain.PolicyEvaluation{}, - Exceptions: map[string]domain.Exception{}, - Bundles: map[string]domain.ReleaseBundle{}, - SigningKeys: map[string]domain.SigningKey{}, - SigningKeyPrivate: map[string][]byte{}, - Signatures: map[string]domain.Signature{}, - Verifications: map[string]domain.VerificationResult{}, - Chain: map[string][]domain.AuditChainEntry{}, - Idempotency: map[string]app.IdempotencyRecord{}, + Tenants: map[string]domain.Tenant{}, + Organizations: map[string]domain.Organization{}, + Users: map[string]domain.HumanUser{}, + RoleBindings: map[string]domain.RoleBinding{}, + SSOProviders: map[string]domain.SSOProvider{}, + IdentityLinks: map[string]domain.UserIdentityLink{}, + SSOSessions: map[string]domain.SSOSession{}, + SSOSessionHashes: map[string]string{}, + APIKeys: map[string]domain.APIKey{}, + APIKeyHashes: map[string]string{}, + Collectors: map[string]domain.Collector{}, + CollectorReleases: map[string]domain.CollectorRelease{}, + BuildRuns: map[string]domain.BuildRun{}, + BuildAttestations: map[string]domain.BuildAttestation{}, + EvidenceLifecycle: map[string]domain.EvidenceLifecycleEvent{}, + ReleaseCandidates: map[string]domain.ReleaseCandidate{}, + ContainerImages: map[string]domain.ContainerImage{}, + ArtifactSignatures: map[string]domain.ArtifactSignature{}, + Repositories: map[string]domain.SourceRepository{}, + Commits: map[string]domain.SourceCommit{}, + Branches: map[string]domain.SourceBranch{}, + PullRequests: map[string]domain.PullRequest{}, + Environments: map[string]domain.DeploymentEnvironment{}, + Deployments: map[string]domain.DeploymentEvent{}, + Incidents: map[string]domain.Incident{}, + TimelineEvents: map[string]domain.IncidentTimelineEvent{}, + IncidentWebhookReceivers: map[string]domain.IncidentWebhookReceiver{}, + IncidentWebhookEvents: map[string]domain.IncidentWebhookEvent{}, + RemediationTasks: map[string]domain.RemediationTask{}, + SecurityScans: map[string]domain.SecurityScan{}, + ManualSecurityDocs: map[string]domain.ManualSecurityDocument{}, + SBOMDiffs: map[string]domain.SBOMDiff{}, + DependencyChanges: map[string]domain.DependencyChange{}, + VulnerabilityWorkflow: map[string]domain.VulnerabilityWorkflowRecord{}, + ContractDiffs: map[string]domain.ContractDiff{}, + CustomPolicies: map[string]domain.CustomPolicy{}, + CustomPolicyEvaluations: map[string]domain.CustomPolicyEvaluation{}, + Waivers: map[string]domain.Waiver{}, + Approvals: map[string]domain.ApprovalRecord{}, + DSSETrustRoots: map[string]domain.DSSETrustRoot{}, + CosignVerifications: map[string]domain.CosignVerification{}, + SigningProviders: map[string]domain.SigningProvider{}, + MerkleBatches: map[string]domain.MerkleBatch{}, + TransparencyCheckpoints: map[string]domain.TransparencyCheckpoint{}, + CustomerPortalAccess: map[string]domain.CustomerPortalAccess{}, + CustomerPortalHashes: map[string]string{}, + RedactionProfiles: map[string]domain.RedactionProfile{}, + CustomerPackages: map[string]domain.CustomerSecurityPackage{}, + HTMLReports: map[string]domain.HTMLReportPackage{}, + ReportTemplates: map[string]domain.CustomReportTemplate{}, + RenderedReports: map[string]domain.RenderedCustomReport{}, + EvidenceBundles: map[string]domain.EvidenceBundle{}, + BundleImports: map[string]domain.EvidenceBundleImport{}, + ObjectRetentionPolicies: map[string]domain.ObjectRetentionPolicy{}, + BackupManifests: map[string]domain.BackupManifest{}, + LegalHolds: map[string]domain.LegalHold{}, + RetentionOverrides: map[string]domain.RetentionOverride{}, + QuestionnaireTemplates: map[string]domain.QuestionnaireTemplate{}, + QuestionnairePackages: map[string]domain.QuestionnairePackage{}, + QuestionnaireAnswerLibrary: map[string]domain.QuestionnaireAnswerLibraryEntry{}, + CommercialCollectors: map[string]domain.CommercialCollectorDefinition{}, + EvidenceSummaries: map[string]domain.EvidenceSummary{}, + QuestionnaireDrafts: map[string]domain.QuestionnaireDraft{}, + GraphSnapshots: map[string]domain.EvidenceGraphSnapshot{}, + SaaSProfiles: map[string]domain.SaaSEditionProfile{}, + PublicTransparencyLogs: map[string]domain.PublicTransparencyLog{}, + PublicTransparencyItems: map[string]domain.PublicTransparencyLogEntry{}, + MarketplaceCollectors: map[string]domain.MarketplaceCollector{}, + PDFReports: map[string]domain.PDFReportPackage{}, + AnomalyReports: map[string]domain.AnomalyReport{}, + ProviderVerifications: map[string]domain.ProviderVerification{}, + SigningOperations: map[string]domain.SigningOperation{}, + ControlFrameworks: map[string]domain.ControlFramework{}, + SecurityControls: map[string]domain.SecurityControl{}, + ControlEvidence: map[string]domain.ControlEvidence{}, + Products: map[string]domain.Product{}, + Projects: map[string]domain.Project{}, + Releases: map[string]domain.Release{}, + Artifacts: map[string]domain.Artifact{}, + Evidence: map[string]domain.EvidenceItem{}, + SBOMs: map[string]domain.SBOM{}, + Scans: map[string]domain.VulnerabilityScan{}, + VEXDocuments: map[string]domain.VEXDocument{}, + VEXImportReports: map[string]domain.VEXImportReport{}, + Decisions: map[string]domain.VulnerabilityDecision{}, + Contracts: map[string]domain.OpenAPIContract{}, + Policies: map[string]domain.PolicyEvaluation{}, + Exceptions: map[string]domain.Exception{}, + Bundles: map[string]domain.ReleaseBundle{}, + SigningKeys: map[string]domain.SigningKey{}, + SigningKeyPrivate: map[string][]byte{}, + Signatures: map[string]domain.Signature{}, + Verifications: map[string]domain.VerificationResult{}, + Chain: map[string][]domain.AuditChainEntry{}, + Idempotency: map[string]app.IdempotencyRecord{}, } } @@ -511,7 +512,8 @@ func (s *Store) loadRelationalCustomerPortalAccess(ctx context.Context, state *a rows, err := s.pool.Query(ctx, ` SELECT id, tenant_id, package_id, customer_name, prefix, hash, expires_at, revoked_at, access_count, failed_access_count, - last_accessed_at, last_failed_at, schema_version, created_at + last_accessed_at, last_failed_at, require_nda, nda_accepted_at, + nda_accepted_by, watermark, schema_version, created_at FROM customer_portal_access `) if err != nil { @@ -521,17 +523,21 @@ func (s *Store) loadRelationalCustomerPortalAccess(ctx context.Context, state *a for rows.Next() { var access domain.CustomerPortalAccess var hash string - var revokedAt, lastAccessedAt, lastFailedAt sql.NullTime + var revokedAt, lastAccessedAt, lastFailedAt, ndaAcceptedAt sql.NullTime + var ndaAcceptedBy, watermark sql.NullString if err := rows.Scan( &access.ID, &access.TenantID, &access.PackageID, &access.CustomerName, &access.Prefix, &hash, &access.ExpiresAt, &revokedAt, &access.AccessCount, &access.FailedAccessCount, - &lastAccessedAt, &lastFailedAt, &access.SchemaVersion, &access.CreatedAt, + &lastAccessedAt, &lastFailedAt, &access.RequireNDA, &ndaAcceptedAt, &ndaAcceptedBy, &watermark, &access.SchemaVersion, &access.CreatedAt, ); err != nil { return fmt.Errorf("scan relational customer portal access: %w", err) } access.RevokedAt = nullableSQLTime(revokedAt) access.LastAccessedAt = nullableSQLTime(lastAccessedAt) access.LastFailedAt = nullableSQLTime(lastFailedAt) + access.NDAAcceptedAt = nullableSQLTime(ndaAcceptedAt) + access.NDAAcceptedBy = nullableSQLString(ndaAcceptedBy) + access.Watermark = nullableSQLString(watermark) state.CustomerPortalAccess[access.ID] = access state.CustomerPortalHashes[access.ID] = hash *loaded = true @@ -2301,7 +2307,30 @@ func (s *Store) loadRelationalRetention(ctx context.Context, state *app.Persiste state.QuestionnairePackages[pkg.ID] = pkg *loaded = true } - return qpRows.Err() + if err := qpRows.Err(); err != nil { + return err + } + + answerRows, err := s.pool.Query(ctx, `SELECT id, tenant_id, question_id, evidence_type, control_id, product_id, release_id, answer, evidence_ids, limitations, schema_version, created_at FROM questionnaire_answer_library`) + if err != nil { + return fmt.Errorf("load relational questionnaire answer library: %w", err) + } + defer answerRows.Close() + for answerRows.Next() { + var entry domain.QuestionnaireAnswerLibraryEntry + var questionID, evidenceType, controlID, productID, releaseID sql.NullString + if err := answerRows.Scan(&entry.ID, &entry.TenantID, &questionID, &evidenceType, &controlID, &productID, &releaseID, &entry.Answer, &entry.EvidenceIDs, &entry.Limitations, &entry.SchemaVersion, &entry.CreatedAt); err != nil { + return fmt.Errorf("scan relational questionnaire answer library: %w", err) + } + entry.QuestionID = nullableSQLString(questionID) + entry.EvidenceType = nullableSQLString(evidenceType) + entry.ControlID = nullableSQLString(controlID) + entry.ProductID = nullableSQLString(productID) + entry.ReleaseID = nullableSQLString(releaseID) + state.QuestionnaireAnswerLibrary[entry.ID] = entry + *loaded = true + } + return answerRows.Err() } func (s *Store) loadRelationalFutureExtensionRows(ctx context.Context, state *app.PersistedState, loaded *bool) error { @@ -4251,6 +4280,25 @@ func syncPackageReportRetentionRows(ctx context.Context, tx pgx.Tx, state app.Pe return fmt.Errorf("upsert questionnaire package row: %w", err) } } + for _, entry := range state.QuestionnaireAnswerLibrary { + if entry.ID == "" || entry.TenantID == "" { + continue + } + if _, err := tx.Exec(ctx, ` + INSERT INTO questionnaire_answer_library ( + id, tenant_id, question_id, evidence_type, control_id, product_id, + release_id, answer, evidence_ids, limitations, schema_version, created_at + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) + ON CONFLICT (id) DO UPDATE SET + answer = EXCLUDED.answer, + evidence_ids = EXCLUDED.evidence_ids, + limitations = EXCLUDED.limitations, + schema_version = EXCLUDED.schema_version + `, entry.ID, entry.TenantID, nullableString(entry.QuestionID), nullableString(entry.EvidenceType), nullableString(entry.ControlID), nullableString(entry.ProductID), nullableString(entry.ReleaseID), entry.Answer, entry.EvidenceIDs, entry.Limitations, entry.SchemaVersion, nonZeroTime(entry.CreatedAt)); err != nil { + return fmt.Errorf("upsert questionnaire answer library row: %w", err) + } + } for _, report := range state.PDFReports { if report.ID == "" || report.TenantID == "" { continue @@ -4701,9 +4749,10 @@ func syncIdentityAndIdempotency(ctx context.Context, tx pgx.Tx, state app.Persis INSERT INTO customer_portal_access ( id, tenant_id, package_id, customer_name, prefix, hash, expires_at, revoked_at, access_count, failed_access_count, - last_accessed_at, last_failed_at, schema_version, created_at + last_accessed_at, last_failed_at, require_nda, nda_accepted_at, + nda_accepted_by, watermark, schema_version, created_at ) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18) ON CONFLICT (id) DO UPDATE SET customer_name = EXCLUDED.customer_name, prefix = EXCLUDED.prefix, @@ -4714,8 +4763,12 @@ func syncIdentityAndIdempotency(ctx context.Context, tx pgx.Tx, state app.Persis failed_access_count = EXCLUDED.failed_access_count, last_accessed_at = EXCLUDED.last_accessed_at, last_failed_at = EXCLUDED.last_failed_at, + require_nda = EXCLUDED.require_nda, + nda_accepted_at = EXCLUDED.nda_accepted_at, + nda_accepted_by = EXCLUDED.nda_accepted_by, + watermark = EXCLUDED.watermark, schema_version = EXCLUDED.schema_version - `, access.ID, access.TenantID, access.PackageID, access.CustomerName, access.Prefix, hash, access.ExpiresAt, nullableTime(access.RevokedAt), access.AccessCount, access.FailedAccessCount, nullableTime(access.LastAccessedAt), nullableTime(access.LastFailedAt), access.SchemaVersion, nonZeroTime(access.CreatedAt)); err != nil { + `, access.ID, access.TenantID, access.PackageID, access.CustomerName, access.Prefix, hash, access.ExpiresAt, nullableTime(access.RevokedAt), access.AccessCount, access.FailedAccessCount, nullableTime(access.LastAccessedAt), nullableTime(access.LastFailedAt), access.RequireNDA, nullableTime(access.NDAAcceptedAt), nullableString(access.NDAAcceptedBy), nullableString(access.Watermark), access.SchemaVersion, nonZeroTime(access.CreatedAt)); err != nil { return fmt.Errorf("upsert customer portal access row: %w", err) } } @@ -4828,9 +4881,10 @@ func syncCriticalIdentityAndIdempotency(ctx context.Context, tx pgx.Tx, mutation INSERT INTO customer_portal_access ( id, tenant_id, package_id, customer_name, prefix, hash, expires_at, revoked_at, access_count, failed_access_count, - last_accessed_at, last_failed_at, schema_version, created_at + last_accessed_at, last_failed_at, require_nda, nda_accepted_at, + nda_accepted_by, watermark, schema_version, created_at ) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18) ON CONFLICT (id) DO UPDATE SET customer_name = EXCLUDED.customer_name, prefix = EXCLUDED.prefix, @@ -4841,8 +4895,12 @@ func syncCriticalIdentityAndIdempotency(ctx context.Context, tx pgx.Tx, mutation failed_access_count = EXCLUDED.failed_access_count, last_accessed_at = EXCLUDED.last_accessed_at, last_failed_at = EXCLUDED.last_failed_at, + require_nda = EXCLUDED.require_nda, + nda_accepted_at = EXCLUDED.nda_accepted_at, + nda_accepted_by = EXCLUDED.nda_accepted_by, + watermark = EXCLUDED.watermark, schema_version = EXCLUDED.schema_version - `, access.ID, access.TenantID, access.PackageID, access.CustomerName, access.Prefix, hash, access.ExpiresAt, nullableTime(access.RevokedAt), access.AccessCount, access.FailedAccessCount, nullableTime(access.LastAccessedAt), nullableTime(access.LastFailedAt), access.SchemaVersion, nonZeroTime(access.CreatedAt)); err != nil { + `, access.ID, access.TenantID, access.PackageID, access.CustomerName, access.Prefix, hash, access.ExpiresAt, nullableTime(access.RevokedAt), access.AccessCount, access.FailedAccessCount, nullableTime(access.LastAccessedAt), nullableTime(access.LastFailedAt), access.RequireNDA, nullableTime(access.NDAAcceptedAt), nullableString(access.NDAAcceptedBy), nullableString(access.Watermark), access.SchemaVersion, nonZeroTime(access.CreatedAt)); err != nil { return fmt.Errorf("upsert critical customer portal access row: %w", err) } } @@ -5134,6 +5192,9 @@ func resourceProjections(state app.PersistedState) []resourceProjection { for _, v := range state.QuestionnairePackages { out = append(out, resourceProjection{TenantID: v.TenantID, ResourceType: "questionnaire_package", ResourceID: v.ID, ProductID: v.ProductID, ReleaseID: v.ReleaseID, CreatedAt: v.CreatedAt}) } + for _, v := range state.QuestionnaireAnswerLibrary { + out = append(out, resourceProjection{TenantID: v.TenantID, ResourceType: "questionnaire_answer_library", ResourceID: v.ID, ProductID: v.ProductID, ReleaseID: v.ReleaseID, CreatedAt: v.CreatedAt}) + } for _, v := range state.CommercialCollectors { out = append(out, resourceProjection{TenantID: v.TenantID, ResourceType: "commercial_collector", ResourceID: v.ID, CreatedAt: v.CreatedAt}) } diff --git a/internal/app/authz_inventory_test.go b/internal/app/authz_inventory_test.go index 779a3f9..1a0eedf 100644 --- a/internal/app/authz_inventory_test.go +++ b/internal/app/authz_inventory_test.go @@ -21,6 +21,10 @@ func TestResourceScopedAuthorizationCoverageInventory(t *testing.T) { "CRAVulnerabilityHandlingReport", "SecurityUpdateEvidenceReport", }, + "enterprise.go": { + "CreateQuestionnaireAnswerLibraryEntry", + "ListQuestionnaireAnswerLibrary", + }, "risk_workflows.go": { "CreateIncident", "RecordIncidentTimelineEvent", diff --git a/internal/app/context_cancellation_test.go b/internal/app/context_cancellation_test.go index 886d25f..b363b57 100644 --- a/internal/app/context_cancellation_test.go +++ b/internal/app/context_cancellation_test.go @@ -187,6 +187,10 @@ func TestLedgerOperationsHonorCanceledContextBeforeWork(t *testing.T) { {"AccessCustomerSecurityPackage", func() error { _, err := ledger.AccessCustomerSecurityPackage(ctx, actor, "pkg"); return err }}, {"ExportCustomerSecurityPackageArchive", func() error { _, err := ledger.ExportCustomerSecurityPackageArchive(ctx, actor, "pkg"); return err }}, {"ExportCustomerPortalPackageArchive", func() error { _, err := ledger.ExportCustomerPortalPackageArchive(ctx, "token"); return err }}, + {"ExportCustomerPortalPackageArchiveWithAcceptance", func() error { + _, err := ledger.ExportCustomerPortalPackageArchiveWithAcceptance(ctx, "token", CustomerPortalAcceptanceInput{NDAAccepted: true, NDAAcceptedBy: "reviewer"}) + return err + }}, {"SecurityReviewPackageReport", func() error { _, err := ledger.SecurityReviewPackageReport(ctx, actor, "pkg"); return err }}, {"CRAReadinessHTMLPackage", func() error { _, err := ledger.CRAReadinessHTMLPackage(ctx, actor, "prod", "rel"); return err }}, {"ListControlFrameworkTemplatePacks", func() error { _, err := ledger.ListControlFrameworkTemplatePacks(ctx, actor); return err }}, @@ -289,6 +293,10 @@ func TestLedgerOperationsHonorCanceledContextBeforeWork(t *testing.T) { return err }}, {"AccessCustomerPortalPackage", func() error { _, err := ledger.AccessCustomerPortalPackage(ctx, "token"); return err }}, + {"AccessCustomerPortalPackageWithAcceptance", func() error { + _, err := ledger.AccessCustomerPortalPackageWithAcceptance(ctx, "token", CustomerPortalAcceptanceInput{NDAAccepted: true, NDAAcceptedBy: "reviewer"}) + return err + }}, {"CreateQuestionnaireTemplate", func() error { _, err := ledger.CreateQuestionnaireTemplate(ctx, actor, CreateQuestionnaireTemplateInput{Name: "template", Version: "1"}) return err @@ -297,6 +305,14 @@ func TestLedgerOperationsHonorCanceledContextBeforeWork(t *testing.T) { _, err := ledger.CreateQuestionnairePackage(ctx, actor, CreateQuestionnairePackageInput{TemplateID: "template", PackageID: "pkg", ProductID: "prod", ReleaseID: "rel"}) return err }}, + {"CreateQuestionnaireAnswerLibraryEntry", func() error { + _, err := ledger.CreateQuestionnaireAnswerLibraryEntry(ctx, actor, CreateQuestionnaireAnswerLibraryEntryInput{QuestionID: "q1", Answer: "answer"}) + return err + }}, + {"ListQuestionnaireAnswerLibrary", func() error { + _, err := ledger.ListQuestionnaireAnswerLibrary(ctx, actor, ListQuestionnaireAnswerLibraryInput{QuestionID: "q1"}) + return err + }}, {"CreateCommercialCollectorDefinition", func() error { _, err := ledger.CreateCommercialCollectorDefinition(ctx, actor, CreateCommercialCollectorInput{Name: "collector", Provider: "jira", Version: "1", ManifestHash: sampleDigest("collector")}) return err @@ -630,6 +646,14 @@ func TestLedgerOperationsRejectActorsWithoutRequiredScopesBeforeResourceWork(t * _, err := ledger.CreateQuestionnairePackage(ctx, actor, CreateQuestionnairePackageInput{TemplateID: "template", PackageID: "pkg", ProductID: "prod", ReleaseID: "rel"}) return err }}, + {"CreateQuestionnaireAnswerLibraryEntry", func() error { + _, err := ledger.CreateQuestionnaireAnswerLibraryEntry(ctx, actor, CreateQuestionnaireAnswerLibraryEntryInput{QuestionID: "q1", Answer: "answer"}) + return err + }}, + {"ListQuestionnaireAnswerLibrary", func() error { + _, err := ledger.ListQuestionnaireAnswerLibrary(ctx, actor, ListQuestionnaireAnswerLibraryInput{QuestionID: "q1"}) + return err + }}, {"CreateCommercialCollectorDefinition", func() error { _, err := ledger.CreateCommercialCollectorDefinition(ctx, actor, CreateCommercialCollectorInput{Name: "collector", Provider: "jira", Version: "1", ManifestHash: sampleDigest("collector")}) return err diff --git a/internal/app/enterprise.go b/internal/app/enterprise.go index 5297bfb..41c89b4 100644 --- a/internal/app/enterprise.go +++ b/internal/app/enterprise.go @@ -8,6 +8,7 @@ import ( "encoding/json" "encoding/pem" "fmt" + "sort" "strings" "time" @@ -89,9 +90,16 @@ type CreateRetentionOverrideInput struct { type CreateCustomerPortalAccessInput struct { PackageID string CustomerName string + RequireNDA bool + Watermark string ExpiresAt time.Time } +type CustomerPortalAcceptanceInput struct { + NDAAccepted bool + NDAAcceptedBy string +} + type CreateQuestionnaireTemplateInput struct { Name string Version string @@ -105,6 +113,23 @@ type CreateQuestionnairePackageInput struct { ReleaseID string } +type CreateQuestionnaireAnswerLibraryEntryInput struct { + QuestionID string + EvidenceType string + ControlID string + ProductID string + ReleaseID string + Answer string + EvidenceIDs []string + Limitations []string +} + +type ListQuestionnaireAnswerLibraryInput struct { + QuestionID string + ProductID string + ReleaseID string +} + type CreateCommercialCollectorInput struct { Name string Provider string @@ -762,7 +787,8 @@ func (s identityService) CreateCustomerPortalAccess(ctx context.Context, actor d if err := require(actor, ScopePackageWrite); err != nil { return domain.CustomerPortalAccess{}, "", err } - in.PackageID, in.CustomerName = strings.TrimSpace(in.PackageID), strings.TrimSpace(in.CustomerName) + in.PackageID, in.CustomerName = strings.TrimSpace(in.PackageID), cleanExternalLabel(in.CustomerName) + in.Watermark = cleanExternalLabel(in.Watermark) if in.PackageID == "" || in.CustomerName == "" || !in.ExpiresAt.After(l.now()) { return domain.CustomerPortalAccess{}, "", ErrValidation } @@ -773,7 +799,12 @@ func (s identityService) CreateCustomerPortalAccess(ctx context.Context, actor d return domain.CustomerPortalAccess{}, "", ErrNotFound } secret := "evycp_" + randomToken(32) - access := domain.CustomerPortalAccess{ID: newID("cpa"), TenantID: actor.TenantID, PackageID: pkg.ID, CustomerName: in.CustomerName, Prefix: secretPrefix(secret), ExpiresAt: in.ExpiresAt.UTC(), SchemaVersion: domain.CustomerPortalAccessVersion, CreatedAt: l.now(), Hash: l.hashSecret(secret)} + accessID := newID("cpa") + watermark := in.Watermark + if watermark == "" { + watermark = packageDistributionWatermark(pkg, in.CustomerName, accessID) + } + access := domain.CustomerPortalAccess{ID: accessID, TenantID: actor.TenantID, PackageID: pkg.ID, CustomerName: in.CustomerName, RequireNDA: in.RequireNDA, Watermark: watermark, Prefix: secretPrefix(secret), ExpiresAt: in.ExpiresAt.UTC(), SchemaVersion: domain.CustomerPortalAccessVersion, CreatedAt: l.now(), Hash: l.hashSecret(secret)} l.portalAccess[access.ID] = access _, _ = l.appendChainLocked(actor.TenantID, "customer_portal_access.created", "customer_security_package", pkg.ID, actorType(actor), actorID(actor), "", "") if err := l.persistCriticalLocked(ctx, l.criticalMutationLocked()); err != nil { @@ -784,10 +815,14 @@ func (s identityService) CreateCustomerPortalAccess(ctx context.Context, actor d } func (s identityService) AccessCustomerPortalPackage(ctx context.Context, token string) (domain.CustomerSecurityPackage, error) { - return s.accessCustomerPortalPackage(ctx, token, "customer_portal_package.accessed") + return s.AccessCustomerPortalPackageWithAcceptance(ctx, token, CustomerPortalAcceptanceInput{}) } -func (s identityService) accessCustomerPortalPackage(ctx context.Context, token, successEntryType string) (domain.CustomerSecurityPackage, error) { +func (s identityService) AccessCustomerPortalPackageWithAcceptance(ctx context.Context, token string, in CustomerPortalAcceptanceInput) (domain.CustomerSecurityPackage, error) { + return s.accessCustomerPortalPackage(ctx, token, in, "customer_portal_package.accessed") +} + +func (s identityService) accessCustomerPortalPackage(ctx context.Context, token string, in CustomerPortalAcceptanceInput, successEntryType string) (domain.CustomerSecurityPackage, error) { l := s.ledger if err := ctx.Err(); err != nil { return domain.CustomerSecurityPackage{}, err @@ -822,6 +857,19 @@ func (s identityService) accessCustomerPortalPackage(ctx context.Context, token, if !ok || pkg.TenantID != access.TenantID || !pkg.ExpiresAt.After(l.now()) { return domain.CustomerSecurityPackage{}, ErrNotFound } + if access.RequireNDA && access.NDAAcceptedAt == nil { + acceptedBy := cleanExternalLabel(in.NDAAcceptedBy) + if !in.NDAAccepted || acceptedBy == "" { + _, _ = l.appendChainLocked(access.TenantID, "customer_portal_package.nda_required", "customer_portal_access", access.ID, "customer_portal", access.ID, pkg.ManifestHash, "") + _ = l.persistCriticalLocked(ctx, l.criticalMutationLocked()) + return domain.CustomerSecurityPackage{}, ErrForbidden + } + now := l.now() + access.NDAAcceptedAt = &now + access.NDAAcceptedBy = acceptedBy + l.portalAccess[id] = access + _, _ = l.appendChainLocked(access.TenantID, "customer_portal_package.nda_accepted", "customer_portal_access", access.ID, "customer_portal", access.ID, pkg.ManifestHash, "") + } access.AccessCount++ now := l.now() access.LastAccessedAt = &now @@ -830,7 +878,7 @@ func (s identityService) accessCustomerPortalPackage(ctx context.Context, token, if err := l.persistCriticalLocked(ctx, l.criticalMutationLocked()); err != nil { return domain.CustomerSecurityPackage{}, err } - return pkg, nil + return packageWithDistributionWatermark(pkg, access), nil } return domain.CustomerSecurityPackage{}, ErrUnauthorized } @@ -902,17 +950,7 @@ func (s packageReportService) CreateQuestionnairePackage(ctx context.Context, ac } responses := []domain.QuestionnaireResponse{} for _, question := range tpl.Questions { - evidenceIDs := []string{} - for _, item := range l.evidence { - if item.TenantID == actor.TenantID && (in.ProductID == "" || item.ProductID == in.ProductID) && (in.ReleaseID == "" || item.ReleaseID == in.ReleaseID) && (question.EvidenceType == "" || item.Type == question.EvidenceType) { - evidenceIDs = append(evidenceIDs, item.ID) - } - } - answer := "No matching evidence was linked for this question." - if len(evidenceIDs) > 0 { - answer = "Evidence is available for review in the linked evidence records." - } - responses = append(responses, domain.QuestionnaireResponse{QuestionID: question.ID, Answer: answer, EvidenceIDs: sortedStrings(evidenceIDs), Limitations: []string{"Questionnaire responses summarize recorded evidence and require human review."}}) + responses = append(responses, l.questionnaireResponseForQuestionLocked(actor.TenantID, question, in.ProductID, in.ReleaseID)) } hash, err := canonicalAnyHash(responses) if err != nil { @@ -927,6 +965,107 @@ func (s packageReportService) CreateQuestionnairePackage(ctx context.Context, ac return pkg, nil } +func (s packageReportService) CreateQuestionnaireAnswerLibraryEntry(ctx context.Context, actor domain.Actor, in CreateQuestionnaireAnswerLibraryEntryInput) (domain.QuestionnaireAnswerLibraryEntry, error) { + l := s.ledger + if err := ctx.Err(); err != nil { + return domain.QuestionnaireAnswerLibraryEntry{}, err + } + if err := require(actor, ScopePackageWrite); err != nil { + return domain.QuestionnaireAnswerLibraryEntry{}, err + } + in.QuestionID, in.EvidenceType, in.ControlID = strings.TrimSpace(in.QuestionID), strings.TrimSpace(in.EvidenceType), strings.TrimSpace(in.ControlID) + in.ProductID, in.ReleaseID = strings.TrimSpace(in.ProductID), strings.TrimSpace(in.ReleaseID) + in.Answer = strings.TrimSpace(in.Answer) + if in.Answer == "" || (in.QuestionID == "" && in.EvidenceType == "" && in.ControlID == "") { + return domain.QuestionnaireAnswerLibraryEntry{}, ErrValidation + } + l.mu.Lock() + defer l.mu.Unlock() + if in.ProductID != "" || in.ReleaseID != "" { + if err := l.ensureScopeLocked(actor.TenantID, in.ProductID, "", in.ReleaseID); err != nil { + return domain.QuestionnaireAnswerLibraryEntry{}, err + } + if err := l.authorizeResourceLocked(actor, ScopePackageWrite, resourceRefs{ProductID: in.ProductID, ReleaseID: in.ReleaseID}); err != nil { + return domain.QuestionnaireAnswerLibraryEntry{}, err + } + } + if in.ControlID != "" { + control, ok := l.controls[in.ControlID] + if !ok || control.TenantID != actor.TenantID { + return domain.QuestionnaireAnswerLibraryEntry{}, ErrNotFound + } + } + evidenceIDs := sortedStrings(in.EvidenceIDs) + for _, id := range evidenceIDs { + item, ok := l.evidence[id] + if !ok || item.TenantID != actor.TenantID || !evidenceMatchesRefs(item, resourceRefs{ProductID: in.ProductID, ReleaseID: in.ReleaseID}) { + return domain.QuestionnaireAnswerLibraryEntry{}, ErrNotFound + } + } + entry := domain.QuestionnaireAnswerLibraryEntry{ + ID: newID("qal"), + TenantID: actor.TenantID, + QuestionID: in.QuestionID, + EvidenceType: in.EvidenceType, + ControlID: in.ControlID, + ProductID: in.ProductID, + ReleaseID: in.ReleaseID, + Answer: in.Answer, + EvidenceIDs: evidenceIDs, + Limitations: sortedStrings(in.Limitations), + SchemaVersion: domain.QuestionnaireAnswerLibraryVersion, + CreatedAt: l.now(), + } + if len(entry.Limitations) == 0 { + entry.Limitations = []string{"Answer library entries are reusable drafts and require human review before external use."} + } + l.answerLibrary[entry.ID] = entry + _, _ = l.appendChainLocked(actor.TenantID, "questionnaire_answer_library.created", "questionnaire_answer_library", entry.ID, actorType(actor), actorID(actor), "", "") + if err := l.persistLocked(ctx); err != nil { + return domain.QuestionnaireAnswerLibraryEntry{}, err + } + return entry, nil +} + +func (s packageReportService) ListQuestionnaireAnswerLibrary(ctx context.Context, actor domain.Actor, in ListQuestionnaireAnswerLibraryInput) ([]domain.QuestionnaireAnswerLibraryEntry, error) { + l := s.ledger + if err := ctx.Err(); err != nil { + return nil, err + } + if err := require(actor, ScopePackageRead); err != nil { + return nil, err + } + in.QuestionID, in.ProductID, in.ReleaseID = strings.TrimSpace(in.QuestionID), strings.TrimSpace(in.ProductID), strings.TrimSpace(in.ReleaseID) + l.mu.Lock() + defer l.mu.Unlock() + if in.ProductID != "" || in.ReleaseID != "" { + if err := l.ensureScopeLocked(actor.TenantID, in.ProductID, "", in.ReleaseID); err != nil { + return nil, err + } + if err := l.authorizeResourceLocked(actor, ScopePackageRead, resourceRefs{ProductID: in.ProductID, ReleaseID: in.ReleaseID}); err != nil { + return nil, err + } + } + out := []domain.QuestionnaireAnswerLibraryEntry{} + for _, entry := range l.answerLibrary { + if entry.TenantID != actor.TenantID { + continue + } + if in.QuestionID != "" && entry.QuestionID != in.QuestionID { + continue + } + if in.ProductID != "" && entry.ProductID != "" && entry.ProductID != in.ProductID { + continue + } + if in.ReleaseID != "" && entry.ReleaseID != "" && entry.ReleaseID != in.ReleaseID { + continue + } + out = append(out, entry) + } + sort.Slice(out, func(i, j int) bool { return out[i].ID < out[j].ID }) + return out, nil +} + func (l *Ledger) CreateCommercialCollectorDefinition(ctx context.Context, actor domain.Actor, in CreateCommercialCollectorInput) (domain.CommercialCollectorDefinition, error) { if err := ctx.Err(); err != nil { return domain.CommercialCollectorDefinition{}, err diff --git a/internal/app/enterprise_test.go b/internal/app/enterprise_test.go index fa0c077..2f3c81d 100644 --- a/internal/app/enterprise_test.go +++ b/internal/app/enterprise_test.go @@ -532,19 +532,22 @@ func TestCustomerPortalRetentionQuestionnairesAndCommercialCollectors(t *testing if err != nil { t.Fatalf("customer package: %v", err) } - access, token, err := ledger.CreateCustomerPortalAccess(ctx, actor, CreateCustomerPortalAccessInput{PackageID: pkg.ID, CustomerName: "ACME", ExpiresAt: fixedNow().Add(time.Hour)}) + access, token, err := ledger.CreateCustomerPortalAccess(ctx, actor, CreateCustomerPortalAccessInput{PackageID: pkg.ID, CustomerName: "ACME", RequireNDA: true, Watermark: "ACME confidential review copy", ExpiresAt: fixedNow().Add(time.Hour)}) if err != nil { t.Fatalf("portal access: %v", err) } - if token == "" || access.Hash != "" { + if token == "" || access.Hash != "" || !access.RequireNDA || access.Watermark == "" { t.Fatalf("portal token/hash leakage access=%#v token=%q", access, token) } - portalPkg, err := ledger.AccessCustomerPortalPackage(ctx, token) + if _, err := ledger.AccessCustomerPortalPackage(ctx, token); !errors.Is(err, ErrForbidden) { + t.Fatalf("NDA-gated portal package without acceptance err=%v, want forbidden", err) + } + portalPkg, err := ledger.AccessCustomerPortalPackageWithAcceptance(ctx, token, CustomerPortalAcceptanceInput{NDAAccepted: true, NDAAcceptedBy: "reviewer@example.test"}) if err != nil { t.Fatalf("portal package: %v", err) } - if portalPkg.ID != pkg.ID { - t.Fatalf("portal package id = %s want %s", portalPkg.ID, pkg.ID) + if portalPkg.ID != pkg.ID || portalPkg.DistributionWatermark != "ACME confidential review copy" { + t.Fatalf("portal package = %#v, want id %s with watermark", portalPkg, pkg.ID) } portalArchive, err := ledger.ExportCustomerPortalPackageArchive(ctx, token) if err != nil { @@ -561,13 +564,19 @@ func TestCustomerPortalRetentionQuestionnairesAndCommercialCollectors(t *testing if err != nil { t.Fatalf("portal audit log: %v", err) } - foundAccess, foundDownload, foundFailedAccess := false, false, false + portalFiles := packageArchiveFiles(t, portalArchive.Bytes) + if !strings.Contains(portalFiles["WATERMARK.txt"], "ACME confidential review copy") || !strings.Contains(portalFiles["report.html"], "ACME confidential review copy") || strings.Contains(portalFiles["package.json"], token) { + t.Fatalf("portal archive watermark/token handling invalid: files=%#v", portalFiles) + } + foundAccess, foundDownload, foundFailedAccess, foundNDAAccepted := false, false, false, false for _, entry := range entries { switch entry.EntryType { case "customer_portal_package.accessed": if entry.ActorID == access.ID && entry.PayloadHash == pkg.ManifestHash { foundAccess = true } + case "customer_portal_package.nda_accepted": + foundNDAAccepted = true case "customer_portal_package.downloaded": if entry.ActorID == access.ID && entry.PayloadHash == pkg.ManifestHash { foundDownload = true @@ -582,8 +591,8 @@ func TestCustomerPortalRetentionQuestionnairesAndCommercialCollectors(t *testing t.Fatalf("portal audit leaked token: %#v", entry) } } - if !foundAccess || !foundDownload { - t.Fatalf("missing portal access/download audit entries access=%v download=%v entries=%#v", foundAccess, foundDownload, entries) + if !foundAccess || !foundDownload || !foundNDAAccepted { + t.Fatalf("missing portal access/download/NDA audit entries access=%v download=%v nda=%v entries=%#v", foundAccess, foundDownload, foundNDAAccepted, entries) } if !foundFailedAccess { t.Fatalf("missing failed portal access audit entry: %#v", entries) @@ -612,11 +621,19 @@ func TestCustomerPortalRetentionQuestionnairesAndCommercialCollectors(t *testing if err != nil { t.Fatalf("questionnaire template: %v", err) } + answer, err := ledger.CreateQuestionnaireAnswerLibraryEntry(ctx, actor, CreateQuestionnaireAnswerLibraryEntryInput{QuestionID: "q1", EvidenceType: "sbom", ProductID: release.ProductID, ReleaseID: release.ID, Answer: "A scoped SBOM evidence record is available in the linked package evidence.", EvidenceIDs: []string{item.ID}}) + if err != nil { + t.Fatalf("answer library: %v", err) + } + answers, err := ledger.ListQuestionnaireAnswerLibrary(ctx, actor, ListQuestionnaireAnswerLibraryInput{ProductID: release.ProductID, ReleaseID: release.ID}) + if err != nil || len(answers) != 1 || answers[0].ID != answer.ID { + t.Fatalf("answer library list=%#v err=%v", answers, err) + } qpkg, err := ledger.CreateQuestionnairePackage(ctx, actor, CreateQuestionnairePackageInput{TemplateID: template.ID, PackageID: pkg.ID, ProductID: release.ProductID, ReleaseID: release.ID}) if err != nil { t.Fatalf("questionnaire package: %v", err) } - if len(qpkg.Responses) != 1 || len(qpkg.Responses[0].EvidenceIDs) != 1 { + if len(qpkg.Responses) != 1 || len(qpkg.Responses[0].EvidenceIDs) != 1 || qpkg.Responses[0].Answer != answer.Answer { t.Fatalf("questionnaire package = %#v", qpkg) } def, err := ledger.CreateCommercialCollectorDefinition(ctx, actor, CreateCommercialCollectorInput{Name: "jira", Provider: "jira", Version: "1.0.0", ManifestHash: sampleDigest("manifest"), AllowedScopes: []string{ScopeEvidenceWrite}}) @@ -637,6 +654,9 @@ func TestCustomerPortalRetentionQuestionnairesAndCommercialCollectors(t *testing if _, _, err := ledger.CreateCustomerPortalAccess(ctx, other, CreateCustomerPortalAccessInput{PackageID: pkg.ID, CustomerName: "bad", ExpiresAt: fixedNow().Add(time.Hour)}); !errors.Is(err, ErrNotFound) { t.Fatalf("cross tenant portal err=%v, want not found", err) } + if _, err := ledger.CreateQuestionnaireAnswerLibraryEntry(ctx, other, CreateQuestionnaireAnswerLibraryEntryInput{QuestionID: "q1", ProductID: release.ProductID, ReleaseID: release.ID, Answer: "bad"}); !errors.Is(err, ErrNotFound) { + t.Fatalf("cross tenant answer library err=%v, want not found", err) + } } func TestCustomerPortalAccessRevokesAfterRepeatedFailedAttempts(t *testing.T) { diff --git a/internal/app/future_extensions.go b/internal/app/future_extensions.go index 1ef6b85..f62b59e 100644 --- a/internal/app/future_extensions.go +++ b/internal/app/future_extensions.go @@ -16,6 +16,7 @@ import ( "errors" "fmt" "math/big" + "sort" "strings" "time" @@ -195,17 +196,7 @@ func (s packageReportService) CreateQuestionnaireDraft(ctx context.Context, acto } responses := make([]domain.QuestionnaireResponse, 0, len(template.Questions)) for _, question := range template.Questions { - ids := l.evidenceIDsForQuestionLocked(actor.TenantID, question, in.ProductID, in.ReleaseID) - answer := "No matching evidence is recorded for this question." - if len(ids) > 0 { - answer = "Evidence is available for this question in " + strings.Join(ids, ", ") + "." - } - responses = append(responses, domain.QuestionnaireResponse{ - QuestionID: question.ID, - Answer: answer, - EvidenceIDs: ids, - Limitations: []string{"Draft response is evidence-backed but requires human review before external use."}, - }) + responses = append(responses, l.questionnaireResponseForQuestionLocked(actor.TenantID, question, in.ProductID, in.ReleaseID)) } hash, err := canonicalAnyHash(responses) if err != nil { @@ -1400,6 +1391,84 @@ func (l *Ledger) evidenceIDsForQuestionLocked(tenantID string, question domain.Q return l.evidenceIDsForRefsLocked(tenantID, resourceRefs{ProductID: strings.TrimSpace(productID), ReleaseID: strings.TrimSpace(releaseID)}, strings.TrimSpace(question.EvidenceType)) } +func (l *Ledger) questionnaireResponseForQuestionLocked(tenantID string, question domain.QuestionnaireQuestion, productID, releaseID string) domain.QuestionnaireResponse { + if entry, ok := l.questionnaireAnswerLibraryMatchLocked(tenantID, question, productID, releaseID); ok { + return domain.QuestionnaireResponse{ + QuestionID: question.ID, + Answer: entry.Answer, + EvidenceIDs: append([]string(nil), entry.EvidenceIDs...), + Limitations: append([]string(nil), entry.Limitations...), + } + } + ids := l.evidenceIDsForQuestionLocked(tenantID, question, productID, releaseID) + answer := "No matching evidence is recorded for this question." + if len(ids) > 0 { + answer = "Evidence is available for review in the linked evidence records." + } + return domain.QuestionnaireResponse{QuestionID: question.ID, Answer: answer, EvidenceIDs: ids, Limitations: []string{"Questionnaire responses summarize recorded evidence and require human review."}} +} + +func (l *Ledger) questionnaireAnswerLibraryMatchLocked(tenantID string, question domain.QuestionnaireQuestion, productID, releaseID string) (domain.QuestionnaireAnswerLibraryEntry, bool) { + productID, releaseID = strings.TrimSpace(productID), strings.TrimSpace(releaseID) + candidates := []domain.QuestionnaireAnswerLibraryEntry{} + for _, entry := range l.answerLibrary { + if entry.TenantID != tenantID || !questionnaireAnswerMatchesQuestion(entry, question) { + continue + } + if entry.ProductID != "" && entry.ProductID != productID { + continue + } + if entry.ReleaseID != "" && entry.ReleaseID != releaseID { + continue + } + candidates = append(candidates, entry) + } + if len(candidates) == 0 { + return domain.QuestionnaireAnswerLibraryEntry{}, false + } + sort.Slice(candidates, func(i, j int) bool { + left, right := questionnaireAnswerSpecificity(candidates[i], question), questionnaireAnswerSpecificity(candidates[j], question) + if left != right { + return left > right + } + if !candidates[i].CreatedAt.Equal(candidates[j].CreatedAt) { + return candidates[i].CreatedAt.After(candidates[j].CreatedAt) + } + return candidates[i].ID < candidates[j].ID + }) + return candidates[0], true +} + +func questionnaireAnswerMatchesQuestion(entry domain.QuestionnaireAnswerLibraryEntry, question domain.QuestionnaireQuestion) bool { + if entry.QuestionID != "" && entry.QuestionID == question.ID { + return true + } + if entry.ControlID != "" && entry.ControlID == question.ControlID { + return true + } + return entry.EvidenceType != "" && entry.EvidenceType == question.EvidenceType +} + +func questionnaireAnswerSpecificity(entry domain.QuestionnaireAnswerLibraryEntry, question domain.QuestionnaireQuestion) int { + score := 0 + if entry.QuestionID != "" && entry.QuestionID == question.ID { + score += 8 + } + if entry.ControlID != "" && entry.ControlID == question.ControlID { + score += 4 + } + if entry.EvidenceType != "" && entry.EvidenceType == question.EvidenceType { + score += 2 + } + if entry.ReleaseID != "" { + score++ + } + if entry.ProductID != "" { + score++ + } + return score +} + func (l *Ledger) evidenceIDsForRefsLocked(tenantID string, refs resourceRefs, evidenceType string) []string { ids := []string{} for _, item := range l.evidence { diff --git a/internal/app/governance_packages.go b/internal/app/governance_packages.go index 5982921..ae64331 100644 --- a/internal/app/governance_packages.go +++ b/internal/app/governance_packages.go @@ -95,6 +95,7 @@ var redactionProfilePresets = map[string]redactionProfilePreset{ Description: "Customer-safe package profile for release evidence summaries without raw payloads, secrets, internal notes, or internal-only provenance fields.", AllowedTypes: []string{ "artifact", + "answer_library", "sbom", "vulnerability_scan", "vex", @@ -129,6 +130,7 @@ var redactionProfilePresets = map[string]redactionProfilePreset{ AllowedTypes: []string{ "api_security", "approval", + "answer_library", "artifact", "build", "build_attestation", @@ -457,6 +459,9 @@ func (l *Ledger) customerPackageManifestLocked(packageID string, generatedAt tim if profileAllowsPackageType(profile, "waiver") { manifest["waivers"] = l.packageWaiverSummariesLocked(tenantID, productID, releaseID) } + if profileAllowsPackageType(profile, "answer_library") { + manifest["answer_library"] = l.packageAnswerLibraryMetadataLocked(tenantID, productID, releaseID) + } if profileAllowsPackageType(profile, "build") || profileAllowsPackageType(profile, "build_attestation") { manifest["provenance"] = l.packageProvenanceMetadataLocked(tenantID, releaseID, profile) } @@ -830,6 +835,35 @@ func waiverBelongsToPackage(waiver domain.Waiver, productID, releaseID string) b } } +func (l *Ledger) packageAnswerLibraryMetadataLocked(tenantID, productID, releaseID string) []map[string]any { + out := []map[string]any{} + for _, entry := range l.answerLibrary { + if entry.TenantID != tenantID { + continue + } + if entry.ProductID != "" && entry.ProductID != productID { + continue + } + if entry.ReleaseID != "" && entry.ReleaseID != releaseID { + continue + } + out = append(out, map[string]any{ + "id": entry.ID, + "question_id": entry.QuestionID, + "evidence_type": entry.EvidenceType, + "control_id": entry.ControlID, + "product_id": entry.ProductID, + "release_id": entry.ReleaseID, + "answer": entry.Answer, + "evidence_ids": append([]string(nil), entry.EvidenceIDs...), + "limitations": append([]string(nil), entry.Limitations...), + "created_at": entry.CreatedAt.UTC().Format(time.RFC3339), + }) + } + sortManifestMapsByID(out) + return out +} + func (l *Ledger) packageProvenanceMetadataLocked(tenantID, releaseID string, profile domain.RedactionProfile) map[string]any { builds := []map[string]any{} buildIDs := map[string]bool{} @@ -1112,8 +1146,12 @@ func (s packageReportService) ExportCustomerSecurityPackageArchive(ctx context.C } func (s packageReportService) ExportCustomerPortalPackageArchive(ctx context.Context, token string) (CustomerPackageArchive, error) { + return s.ExportCustomerPortalPackageArchiveWithAcceptance(ctx, token, CustomerPortalAcceptanceInput{}) +} + +func (s packageReportService) ExportCustomerPortalPackageArchiveWithAcceptance(ctx context.Context, token string, in CustomerPortalAcceptanceInput) (CustomerPackageArchive, error) { l := s.ledger - pkg, err := l.identityService().accessCustomerPortalPackage(ctx, token, "customer_portal_package.downloaded") + pkg, err := l.identityService().accessCustomerPortalPackage(ctx, token, in, "customer_portal_package.downloaded") if err != nil { return CustomerPackageArchive{}, err } @@ -1140,6 +1178,41 @@ func (s packageReportService) SecurityReviewPackageReport(ctx context.Context, a return domain.SecurityReviewPackageReport{ReportType: "security_review_package", TemplateVersion: "security-review-package.v1.0.0", PackageID: pkg.ID, ProductID: pkg.ProductID, ReleaseID: pkg.ReleaseID, EvidenceIDs: ids, Assumptions: []string{"Report includes only package-scoped evidence metadata."}, Limitations: []string{"This report supports customer review but is not a compliance, legal, or secure-release conclusion."}, GeneratedAt: l.now()}, nil } +func packageWithDistributionWatermark(pkg domain.CustomerSecurityPackage, access domain.CustomerPortalAccess) domain.CustomerSecurityPackage { + pkg.DistributionWatermark = packageDistributionWatermark(pkg, access.CustomerName, access.ID) + if access.Watermark != "" { + pkg.DistributionWatermark = access.Watermark + } + return pkg +} + +func packageDistributionWatermark(pkg domain.CustomerSecurityPackage, customerName, accessID string) string { + customerName = cleanExternalLabel(customerName) + accessID = strings.TrimSpace(accessID) + if customerName == "" && accessID == "" { + return "Evydence package " + pkg.ID + " exported for scoped review." + } + return cleanExternalLabel("Evydence package " + pkg.ID + " for " + customerName + " via access " + accessID + ".") +} + +func cleanExternalLabel(value string) string { + value = strings.TrimSpace(value) + if value == "" { + return "" + } + runes := make([]rune, 0, len(value)) + for _, r := range value { + if r < 32 || r == 127 { + continue + } + runes = append(runes, r) + if len(runes) >= 160 { + break + } + } + return strings.TrimSpace(string(runes)) +} + func customerPackageArchive(pkg domain.CustomerSecurityPackage) (CustomerPackageArchive, error) { var buf bytes.Buffer zw := zip.NewWriter(&buf) @@ -1156,6 +1229,9 @@ func customerPackageArchive(pkg domain.CustomerSecurityPackage) (CustomerPackage "schema_version": pkg.SchemaVersion, "created_at": pkg.CreatedAt.UTC().Format(time.RFC3339), } + if pkg.DistributionWatermark != "" { + metadata["distribution_watermark"] = pkg.DistributionWatermark + } verification := map[string]any{ "package_id": pkg.ID, "manifest_hash": pkg.ManifestHash, @@ -1197,6 +1273,12 @@ func customerPackageArchive(pkg domain.CustomerSecurityPackage) (CustomerPackage _ = zw.Close() return CustomerPackageArchive{}, err } + if pkg.DistributionWatermark != "" { + if err := addZIPFile(zw, "WATERMARK.txt", []byte(pkg.DistributionWatermark+"\n")); err != nil { + _ = zw.Close() + return CustomerPackageArchive{}, err + } + } if err := addZIPFile(zw, "report.html", customerPackageHTMLReport(pkg, metadata, verification)); err != nil { _ = zw.Close() return CustomerPackageArchive{}, err @@ -1216,6 +1298,7 @@ func customerPackageHTMLReport(pkg domain.CustomerSecurityPackage, metadata, ver apiContracts := packageHTMLMap(manifest["api_contracts"]) vexDocuments := packageHTMLRecords(manifest["vex_documents"]) decisions := packageHTMLRecords(manifest["vulnerability_decisions"]) + answerLibrary := packageHTMLRecords(manifest["answer_library"]) limitations := packageHTMLStrings(manifest["limitations"]) nonClaims := packageHTMLStrings(manifest["non_claims"]) @@ -1226,6 +1309,11 @@ func customerPackageHTMLReport(pkg domain.CustomerSecurityPackage, metadata, ver b.WriteString("

") b.WriteString(packageHTMLEscape(pkg.Title)) b.WriteString("

This static report is generated from the redacted customer package manifest. It supports technical evidence review and compliance readiness only; it is not legal compliance proof, certification, complete SBOM proof, an authoritative vulnerability result, regulator acceptance, or a secure-release guarantee.

") + if watermark := packageHTMLString(metadata["distribution_watermark"]); watermark != "" { + b.WriteString("

Distribution watermark: ") + b.WriteString(packageHTMLEscape(watermark)) + b.WriteString("

") + } b.WriteString("

Release Summary

") packageHTMLRow(&b, "Package ID", pkg.ID) @@ -1256,6 +1344,17 @@ func customerPackageHTMLReport(pkg domain.CustomerSecurityPackage, metadata, ver } } + b.WriteString("

Questionnaire Answer Library

") + if len(answerLibrary) == 0 { + b.WriteString("

No customer-visible questionnaire answer library entries are included by this package profile.

") + } else { + b.WriteString("
") + for _, record := range answerLibrary { + b.WriteString("") + } + b.WriteString("
QuestionEvidence TypeAnswerEvidence IDs
" + packageHTMLEscape(packageHTMLString(record["question_id"])) + "" + packageHTMLEscape(packageHTMLString(record["evidence_type"])) + "" + packageHTMLEscape(packageHTMLString(record["answer"])) + "" + packageHTMLEscape(packageHTMLJSON(record["evidence_ids"])) + "
") + } + b.WriteString("

API Contract Evidence

") contractRecords := packageHTMLRecords(apiContracts["openapi_contracts"]) diffRecords := packageHTMLRecords(apiContracts["contract_diffs"]) diff --git a/internal/app/identity_service.go b/internal/app/identity_service.go index 34791ac..d77e24c 100644 --- a/internal/app/identity_service.go +++ b/internal/app/identity_service.go @@ -218,3 +218,7 @@ func (l *Ledger) CreateCustomerPortalAccess(ctx context.Context, actor domain.Ac func (l *Ledger) AccessCustomerPortalPackage(ctx context.Context, token string) (domain.CustomerSecurityPackage, error) { return l.identityService().AccessCustomerPortalPackage(ctx, token) } + +func (l *Ledger) AccessCustomerPortalPackageWithAcceptance(ctx context.Context, token string, in CustomerPortalAcceptanceInput) (domain.CustomerSecurityPackage, error) { + return l.identityService().AccessCustomerPortalPackageWithAcceptance(ctx, token, in) +} diff --git a/internal/app/ledger.go b/internal/app/ledger.go index a349e1c..638904b 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -153,6 +153,7 @@ type Ledger struct { portalAccess map[string]domain.CustomerPortalAccess questionTemplates map[string]domain.QuestionnaireTemplate questionPackages map[string]domain.QuestionnairePackage + answerLibrary map[string]domain.QuestionnaireAnswerLibraryEntry commercialCollectors map[string]domain.CommercialCollectorDefinition evidenceSummaries map[string]domain.EvidenceSummary questionDrafts map[string]domain.QuestionnaireDraft @@ -280,6 +281,7 @@ func NewLedgerWithError(cfg Config) (*Ledger, error) { portalAccess: map[string]domain.CustomerPortalAccess{}, questionTemplates: map[string]domain.QuestionnaireTemplate{}, questionPackages: map[string]domain.QuestionnairePackage{}, + answerLibrary: map[string]domain.QuestionnaireAnswerLibraryEntry{}, commercialCollectors: map[string]domain.CommercialCollectorDefinition{}, evidenceSummaries: map[string]domain.EvidenceSummary{}, questionDrafts: map[string]domain.QuestionnaireDraft{}, diff --git a/internal/app/package_report_service.go b/internal/app/package_report_service.go index 6365011..c449451 100644 --- a/internal/app/package_report_service.go +++ b/internal/app/package_report_service.go @@ -54,6 +54,14 @@ func (l *Ledger) CreateQuestionnairePackage(ctx context.Context, actor domain.Ac return l.packageReportService().CreateQuestionnairePackage(ctx, actor, in) } +func (l *Ledger) CreateQuestionnaireAnswerLibraryEntry(ctx context.Context, actor domain.Actor, in CreateQuestionnaireAnswerLibraryEntryInput) (domain.QuestionnaireAnswerLibraryEntry, error) { + return l.packageReportService().CreateQuestionnaireAnswerLibraryEntry(ctx, actor, in) +} + +func (l *Ledger) ListQuestionnaireAnswerLibrary(ctx context.Context, actor domain.Actor, in ListQuestionnaireAnswerLibraryInput) ([]domain.QuestionnaireAnswerLibraryEntry, error) { + return l.packageReportService().ListQuestionnaireAnswerLibrary(ctx, actor, in) +} + func (l *Ledger) CreateRedactionProfile(ctx context.Context, actor domain.Actor, in CreateRedactionProfileInput) (domain.RedactionProfile, error) { return l.packageReportService().CreateRedactionProfile(ctx, actor, in) } @@ -74,6 +82,10 @@ func (l *Ledger) ExportCustomerPortalPackageArchive(ctx context.Context, token s return l.packageReportService().ExportCustomerPortalPackageArchive(ctx, token) } +func (l *Ledger) ExportCustomerPortalPackageArchiveWithAcceptance(ctx context.Context, token string, in CustomerPortalAcceptanceInput) (CustomerPackageArchive, error) { + return l.packageReportService().ExportCustomerPortalPackageArchiveWithAcceptance(ctx, token, in) +} + func (l *Ledger) SecurityReviewPackageReport(ctx context.Context, actor domain.Actor, packageID string) (domain.SecurityReviewPackageReport, error) { return l.packageReportService().SecurityReviewPackageReport(ctx, actor, packageID) } diff --git a/internal/app/ports.go b/internal/app/ports.go index 71ba6a8..ef9e1bf 100644 --- a/internal/app/ports.go +++ b/internal/app/ports.go @@ -136,100 +136,101 @@ type ObjectRetentionResult struct { } type PersistedState struct { - Tenants map[string]domain.Tenant `json:"tenants"` - Organizations map[string]domain.Organization `json:"organizations"` - Users map[string]domain.HumanUser `json:"users"` - RoleBindings map[string]domain.RoleBinding `json:"role_bindings"` - SSOProviders map[string]domain.SSOProvider `json:"sso_providers"` - IdentityLinks map[string]domain.UserIdentityLink `json:"identity_links"` - SSOSessions map[string]domain.SSOSession `json:"sso_sessions"` - SSOSessionHashes map[string]string `json:"sso_session_hashes,omitempty"` - APIKeys map[string]domain.APIKey `json:"api_keys"` - APIKeyHashes map[string]string `json:"api_key_hashes,omitempty"` - Collectors map[string]domain.Collector `json:"collectors"` - CollectorReleases map[string]domain.CollectorRelease `json:"collector_releases"` - Products map[string]domain.Product `json:"products"` - Projects map[string]domain.Project `json:"projects"` - Releases map[string]domain.Release `json:"releases"` - Artifacts map[string]domain.Artifact `json:"artifacts"` - BuildRuns map[string]domain.BuildRun `json:"build_runs"` - BuildAttestations map[string]domain.BuildAttestation `json:"build_attestations"` - Evidence map[string]domain.EvidenceItem `json:"evidence"` - EvidenceLifecycle map[string]domain.EvidenceLifecycleEvent `json:"evidence_lifecycle"` - ReleaseCandidates map[string]domain.ReleaseCandidate `json:"release_candidates"` - ContainerImages map[string]domain.ContainerImage `json:"container_images"` - ArtifactSignatures map[string]domain.ArtifactSignature `json:"artifact_signatures"` - Repositories map[string]domain.SourceRepository `json:"repositories"` - Commits map[string]domain.SourceCommit `json:"commits"` - Branches map[string]domain.SourceBranch `json:"branches"` - PullRequests map[string]domain.PullRequest `json:"pull_requests"` - Environments map[string]domain.DeploymentEnvironment `json:"environments"` - Deployments map[string]domain.DeploymentEvent `json:"deployments"` - Incidents map[string]domain.Incident `json:"incidents"` - TimelineEvents map[string]domain.IncidentTimelineEvent `json:"timeline_events"` - IncidentWebhookReceivers map[string]domain.IncidentWebhookReceiver `json:"incident_webhook_receivers"` - IncidentWebhookEvents map[string]domain.IncidentWebhookEvent `json:"incident_webhook_events"` - RemediationTasks map[string]domain.RemediationTask `json:"remediation_tasks"` - SecurityScans map[string]domain.SecurityScan `json:"security_scans"` - ManualSecurityDocs map[string]domain.ManualSecurityDocument `json:"manual_security_docs"` - SBOMDiffs map[string]domain.SBOMDiff `json:"sbom_diffs"` - DependencyChanges map[string]domain.DependencyChange `json:"dependency_changes"` - VulnerabilityWorkflow map[string]domain.VulnerabilityWorkflowRecord `json:"vulnerability_workflow"` - ContractDiffs map[string]domain.ContractDiff `json:"contract_diffs"` - CustomPolicies map[string]domain.CustomPolicy `json:"custom_policies"` - CustomPolicyEvaluations map[string]domain.CustomPolicyEvaluation `json:"custom_policy_evaluations"` - Waivers map[string]domain.Waiver `json:"waivers"` - Approvals map[string]domain.ApprovalRecord `json:"approvals"` - RedactionProfiles map[string]domain.RedactionProfile `json:"redaction_profiles"` - CustomerPackages map[string]domain.CustomerSecurityPackage `json:"customer_packages"` - HTMLReports map[string]domain.HTMLReportPackage `json:"html_reports"` - ReportTemplates map[string]domain.CustomReportTemplate `json:"report_templates"` - RenderedReports map[string]domain.RenderedCustomReport `json:"rendered_reports"` - EvidenceBundles map[string]domain.EvidenceBundle `json:"evidence_bundles"` - BundleImports map[string]domain.EvidenceBundleImport `json:"bundle_imports"` - DSSETrustRoots map[string]domain.DSSETrustRoot `json:"dsse_trust_roots"` - CosignVerifications map[string]domain.CosignVerification `json:"cosign_verifications"` - SigningProviders map[string]domain.SigningProvider `json:"signing_providers"` - MerkleBatches map[string]domain.MerkleBatch `json:"merkle_batches"` - TransparencyCheckpoints map[string]domain.TransparencyCheckpoint `json:"transparency_checkpoints"` - ObjectRetentionPolicies map[string]domain.ObjectRetentionPolicy `json:"object_retention_policies"` - BackupManifests map[string]domain.BackupManifest `json:"backup_manifests"` - LegalHolds map[string]domain.LegalHold `json:"legal_holds"` - RetentionOverrides map[string]domain.RetentionOverride `json:"retention_overrides"` - CustomerPortalAccess map[string]domain.CustomerPortalAccess `json:"customer_portal_access"` - CustomerPortalHashes map[string]string `json:"customer_portal_hashes,omitempty"` - QuestionnaireTemplates map[string]domain.QuestionnaireTemplate `json:"questionnaire_templates"` - QuestionnairePackages map[string]domain.QuestionnairePackage `json:"questionnaire_packages"` - CommercialCollectors map[string]domain.CommercialCollectorDefinition `json:"commercial_collectors"` - EvidenceSummaries map[string]domain.EvidenceSummary `json:"evidence_summaries"` - QuestionnaireDrafts map[string]domain.QuestionnaireDraft `json:"questionnaire_drafts"` - GraphSnapshots map[string]domain.EvidenceGraphSnapshot `json:"graph_snapshots"` - SaaSProfiles map[string]domain.SaaSEditionProfile `json:"saas_profiles"` - PublicTransparencyLogs map[string]domain.PublicTransparencyLog `json:"public_transparency_logs"` - PublicTransparencyItems map[string]domain.PublicTransparencyLogEntry `json:"public_transparency_items"` - MarketplaceCollectors map[string]domain.MarketplaceCollector `json:"marketplace_collectors"` - PDFReports map[string]domain.PDFReportPackage `json:"pdf_reports"` - AnomalyReports map[string]domain.AnomalyReport `json:"anomaly_reports"` - ProviderVerifications map[string]domain.ProviderVerification `json:"provider_verifications"` - SigningOperations map[string]domain.SigningOperation `json:"signing_operations"` - ControlFrameworks map[string]domain.ControlFramework `json:"control_frameworks"` - SecurityControls map[string]domain.SecurityControl `json:"security_controls"` - ControlEvidence map[string]domain.ControlEvidence `json:"control_evidence"` - SBOMs map[string]domain.SBOM `json:"sboms"` - Scans map[string]domain.VulnerabilityScan `json:"scans"` - VEXDocuments map[string]domain.VEXDocument `json:"vex_documents"` - VEXImportReports map[string]domain.VEXImportReport `json:"vex_import_reports"` - Decisions map[string]domain.VulnerabilityDecision `json:"vulnerability_decisions"` - Contracts map[string]domain.OpenAPIContract `json:"contracts"` - Policies map[string]domain.PolicyEvaluation `json:"policies"` - Exceptions map[string]domain.Exception `json:"exceptions"` - Bundles map[string]domain.ReleaseBundle `json:"bundles"` - SigningKeys map[string]domain.SigningKey `json:"signing_keys"` - SigningKeyPrivate map[string][]byte `json:"signing_key_private,omitempty"` - Signatures map[string]domain.Signature `json:"signatures"` - Verifications map[string]domain.VerificationResult `json:"verifications"` - Chain map[string][]domain.AuditChainEntry `json:"chain"` - Idempotency map[string]IdempotencyRecord `json:"idempotency"` + Tenants map[string]domain.Tenant `json:"tenants"` + Organizations map[string]domain.Organization `json:"organizations"` + Users map[string]domain.HumanUser `json:"users"` + RoleBindings map[string]domain.RoleBinding `json:"role_bindings"` + SSOProviders map[string]domain.SSOProvider `json:"sso_providers"` + IdentityLinks map[string]domain.UserIdentityLink `json:"identity_links"` + SSOSessions map[string]domain.SSOSession `json:"sso_sessions"` + SSOSessionHashes map[string]string `json:"sso_session_hashes,omitempty"` + APIKeys map[string]domain.APIKey `json:"api_keys"` + APIKeyHashes map[string]string `json:"api_key_hashes,omitempty"` + Collectors map[string]domain.Collector `json:"collectors"` + CollectorReleases map[string]domain.CollectorRelease `json:"collector_releases"` + Products map[string]domain.Product `json:"products"` + Projects map[string]domain.Project `json:"projects"` + Releases map[string]domain.Release `json:"releases"` + Artifacts map[string]domain.Artifact `json:"artifacts"` + BuildRuns map[string]domain.BuildRun `json:"build_runs"` + BuildAttestations map[string]domain.BuildAttestation `json:"build_attestations"` + Evidence map[string]domain.EvidenceItem `json:"evidence"` + EvidenceLifecycle map[string]domain.EvidenceLifecycleEvent `json:"evidence_lifecycle"` + ReleaseCandidates map[string]domain.ReleaseCandidate `json:"release_candidates"` + ContainerImages map[string]domain.ContainerImage `json:"container_images"` + ArtifactSignatures map[string]domain.ArtifactSignature `json:"artifact_signatures"` + Repositories map[string]domain.SourceRepository `json:"repositories"` + Commits map[string]domain.SourceCommit `json:"commits"` + Branches map[string]domain.SourceBranch `json:"branches"` + PullRequests map[string]domain.PullRequest `json:"pull_requests"` + Environments map[string]domain.DeploymentEnvironment `json:"environments"` + Deployments map[string]domain.DeploymentEvent `json:"deployments"` + Incidents map[string]domain.Incident `json:"incidents"` + TimelineEvents map[string]domain.IncidentTimelineEvent `json:"timeline_events"` + IncidentWebhookReceivers map[string]domain.IncidentWebhookReceiver `json:"incident_webhook_receivers"` + IncidentWebhookEvents map[string]domain.IncidentWebhookEvent `json:"incident_webhook_events"` + RemediationTasks map[string]domain.RemediationTask `json:"remediation_tasks"` + SecurityScans map[string]domain.SecurityScan `json:"security_scans"` + ManualSecurityDocs map[string]domain.ManualSecurityDocument `json:"manual_security_docs"` + SBOMDiffs map[string]domain.SBOMDiff `json:"sbom_diffs"` + DependencyChanges map[string]domain.DependencyChange `json:"dependency_changes"` + VulnerabilityWorkflow map[string]domain.VulnerabilityWorkflowRecord `json:"vulnerability_workflow"` + ContractDiffs map[string]domain.ContractDiff `json:"contract_diffs"` + CustomPolicies map[string]domain.CustomPolicy `json:"custom_policies"` + CustomPolicyEvaluations map[string]domain.CustomPolicyEvaluation `json:"custom_policy_evaluations"` + Waivers map[string]domain.Waiver `json:"waivers"` + Approvals map[string]domain.ApprovalRecord `json:"approvals"` + RedactionProfiles map[string]domain.RedactionProfile `json:"redaction_profiles"` + CustomerPackages map[string]domain.CustomerSecurityPackage `json:"customer_packages"` + HTMLReports map[string]domain.HTMLReportPackage `json:"html_reports"` + ReportTemplates map[string]domain.CustomReportTemplate `json:"report_templates"` + RenderedReports map[string]domain.RenderedCustomReport `json:"rendered_reports"` + EvidenceBundles map[string]domain.EvidenceBundle `json:"evidence_bundles"` + BundleImports map[string]domain.EvidenceBundleImport `json:"bundle_imports"` + DSSETrustRoots map[string]domain.DSSETrustRoot `json:"dsse_trust_roots"` + CosignVerifications map[string]domain.CosignVerification `json:"cosign_verifications"` + SigningProviders map[string]domain.SigningProvider `json:"signing_providers"` + MerkleBatches map[string]domain.MerkleBatch `json:"merkle_batches"` + TransparencyCheckpoints map[string]domain.TransparencyCheckpoint `json:"transparency_checkpoints"` + ObjectRetentionPolicies map[string]domain.ObjectRetentionPolicy `json:"object_retention_policies"` + BackupManifests map[string]domain.BackupManifest `json:"backup_manifests"` + LegalHolds map[string]domain.LegalHold `json:"legal_holds"` + RetentionOverrides map[string]domain.RetentionOverride `json:"retention_overrides"` + CustomerPortalAccess map[string]domain.CustomerPortalAccess `json:"customer_portal_access"` + CustomerPortalHashes map[string]string `json:"customer_portal_hashes,omitempty"` + QuestionnaireTemplates map[string]domain.QuestionnaireTemplate `json:"questionnaire_templates"` + QuestionnairePackages map[string]domain.QuestionnairePackage `json:"questionnaire_packages"` + QuestionnaireAnswerLibrary map[string]domain.QuestionnaireAnswerLibraryEntry `json:"questionnaire_answer_library"` + CommercialCollectors map[string]domain.CommercialCollectorDefinition `json:"commercial_collectors"` + EvidenceSummaries map[string]domain.EvidenceSummary `json:"evidence_summaries"` + QuestionnaireDrafts map[string]domain.QuestionnaireDraft `json:"questionnaire_drafts"` + GraphSnapshots map[string]domain.EvidenceGraphSnapshot `json:"graph_snapshots"` + SaaSProfiles map[string]domain.SaaSEditionProfile `json:"saas_profiles"` + PublicTransparencyLogs map[string]domain.PublicTransparencyLog `json:"public_transparency_logs"` + PublicTransparencyItems map[string]domain.PublicTransparencyLogEntry `json:"public_transparency_items"` + MarketplaceCollectors map[string]domain.MarketplaceCollector `json:"marketplace_collectors"` + PDFReports map[string]domain.PDFReportPackage `json:"pdf_reports"` + AnomalyReports map[string]domain.AnomalyReport `json:"anomaly_reports"` + ProviderVerifications map[string]domain.ProviderVerification `json:"provider_verifications"` + SigningOperations map[string]domain.SigningOperation `json:"signing_operations"` + ControlFrameworks map[string]domain.ControlFramework `json:"control_frameworks"` + SecurityControls map[string]domain.SecurityControl `json:"security_controls"` + ControlEvidence map[string]domain.ControlEvidence `json:"control_evidence"` + SBOMs map[string]domain.SBOM `json:"sboms"` + Scans map[string]domain.VulnerabilityScan `json:"scans"` + VEXDocuments map[string]domain.VEXDocument `json:"vex_documents"` + VEXImportReports map[string]domain.VEXImportReport `json:"vex_import_reports"` + Decisions map[string]domain.VulnerabilityDecision `json:"vulnerability_decisions"` + Contracts map[string]domain.OpenAPIContract `json:"contracts"` + Policies map[string]domain.PolicyEvaluation `json:"policies"` + Exceptions map[string]domain.Exception `json:"exceptions"` + Bundles map[string]domain.ReleaseBundle `json:"bundles"` + SigningKeys map[string]domain.SigningKey `json:"signing_keys"` + SigningKeyPrivate map[string][]byte `json:"signing_key_private,omitempty"` + Signatures map[string]domain.Signature `json:"signatures"` + Verifications map[string]domain.VerificationResult `json:"verifications"` + Chain map[string][]domain.AuditChainEntry `json:"chain"` + Idempotency map[string]IdempotencyRecord `json:"idempotency"` } func AppendPersistedChainEntry(state *PersistedState, now time.Time, tenantID, entryType, subjectType, subjectID, actorType, actorID, payloadHash, signatureRef string) (domain.AuditChainEntry, error) { diff --git a/internal/app/state.go b/internal/app/state.go index 95fb188..8ace9bc 100644 --- a/internal/app/state.go +++ b/internal/app/state.go @@ -26,100 +26,101 @@ func (l *Ledger) snapshotLocked() PersistedState { signingKeys[id] = key } state := PersistedState{ - Tenants: l.tenants, - Organizations: l.organizations, - Users: l.users, - RoleBindings: l.roleBindings, - SSOProviders: l.ssoProviders, - IdentityLinks: l.identityLinks, - SSOSessions: ssoSessions, - SSOSessionHashes: map[string]string{}, - APIKeys: apiKeys, - APIKeyHashes: map[string]string{}, - Collectors: l.collectors, - CollectorReleases: l.collectorReleases, - Products: l.products, - Projects: l.projects, - Releases: l.releases, - Artifacts: l.artifacts, - BuildRuns: l.buildRuns, - BuildAttestations: l.attestations, - Evidence: l.evidence, - EvidenceLifecycle: l.lifecycle, - ReleaseCandidates: l.candidates, - ContainerImages: l.images, - ArtifactSignatures: l.artifactSigs, - Repositories: l.repositories, - Commits: l.commits, - Branches: l.branches, - PullRequests: l.pullRequests, - Environments: l.environments, - Deployments: l.deployments, - Incidents: l.incidents, - TimelineEvents: l.timeline, - IncidentWebhookReceivers: l.webhookReceivers, - IncidentWebhookEvents: l.webhookEvents, - RemediationTasks: l.tasks, - SecurityScans: l.securityScans, - ManualSecurityDocs: l.manualDocs, - SBOMDiffs: l.sbomDiffs, - DependencyChanges: l.depChanges, - VulnerabilityWorkflow: l.vulnWorkflow, - ContractDiffs: l.contractDiffs, - CustomPolicies: l.customPolicies, - CustomPolicyEvaluations: l.customPolicyEvals, - Waivers: l.waivers, - Approvals: l.approvals, - RedactionProfiles: l.redactions, - CustomerPackages: l.customerPackages, - HTMLReports: l.htmlReports, - ReportTemplates: l.reportTemplates, - RenderedReports: l.renderedReports, - EvidenceBundles: l.evidenceBundles, - BundleImports: l.bundleImports, - DSSETrustRoots: l.dsseTrustRoots, - CosignVerifications: l.cosignVerifs, - SigningProviders: l.signingProviders, - MerkleBatches: l.merkleBatches, - TransparencyCheckpoints: l.transparency, - ObjectRetentionPolicies: l.retentionPolicies, - BackupManifests: l.backupManifests, - LegalHolds: l.legalHolds, - RetentionOverrides: l.retentionOverrides, - CustomerPortalAccess: portalAccess, - CustomerPortalHashes: map[string]string{}, - QuestionnaireTemplates: l.questionTemplates, - QuestionnairePackages: l.questionPackages, - CommercialCollectors: l.commercialCollectors, - EvidenceSummaries: l.evidenceSummaries, - QuestionnaireDrafts: l.questionDrafts, - GraphSnapshots: l.graphSnapshots, - SaaSProfiles: l.saasProfiles, - PublicTransparencyLogs: l.publicLogs, - PublicTransparencyItems: l.publicLogEntries, - MarketplaceCollectors: l.marketplaceCollectors, - PDFReports: l.pdfReports, - AnomalyReports: l.anomalyReports, - ProviderVerifications: l.providerVerifications, - SigningOperations: l.signingOperations, - ControlFrameworks: l.frameworks, - SecurityControls: l.controls, - ControlEvidence: l.controlLinks, - SBOMs: l.sboms, - Scans: l.scans, - VEXDocuments: l.vexDocuments, - VEXImportReports: l.vexImportReports, - Decisions: l.decisions, - Contracts: l.contracts, - Policies: l.policies, - Exceptions: l.exceptions, - Bundles: l.bundles, - SigningKeys: signingKeys, - SigningKeyPrivate: map[string][]byte{}, - Signatures: l.signatures, - Verifications: l.verifications, - Chain: l.chain, - Idempotency: l.idempotency, + Tenants: l.tenants, + Organizations: l.organizations, + Users: l.users, + RoleBindings: l.roleBindings, + SSOProviders: l.ssoProviders, + IdentityLinks: l.identityLinks, + SSOSessions: ssoSessions, + SSOSessionHashes: map[string]string{}, + APIKeys: apiKeys, + APIKeyHashes: map[string]string{}, + Collectors: l.collectors, + CollectorReleases: l.collectorReleases, + Products: l.products, + Projects: l.projects, + Releases: l.releases, + Artifacts: l.artifacts, + BuildRuns: l.buildRuns, + BuildAttestations: l.attestations, + Evidence: l.evidence, + EvidenceLifecycle: l.lifecycle, + ReleaseCandidates: l.candidates, + ContainerImages: l.images, + ArtifactSignatures: l.artifactSigs, + Repositories: l.repositories, + Commits: l.commits, + Branches: l.branches, + PullRequests: l.pullRequests, + Environments: l.environments, + Deployments: l.deployments, + Incidents: l.incidents, + TimelineEvents: l.timeline, + IncidentWebhookReceivers: l.webhookReceivers, + IncidentWebhookEvents: l.webhookEvents, + RemediationTasks: l.tasks, + SecurityScans: l.securityScans, + ManualSecurityDocs: l.manualDocs, + SBOMDiffs: l.sbomDiffs, + DependencyChanges: l.depChanges, + VulnerabilityWorkflow: l.vulnWorkflow, + ContractDiffs: l.contractDiffs, + CustomPolicies: l.customPolicies, + CustomPolicyEvaluations: l.customPolicyEvals, + Waivers: l.waivers, + Approvals: l.approvals, + RedactionProfiles: l.redactions, + CustomerPackages: l.customerPackages, + HTMLReports: l.htmlReports, + ReportTemplates: l.reportTemplates, + RenderedReports: l.renderedReports, + EvidenceBundles: l.evidenceBundles, + BundleImports: l.bundleImports, + DSSETrustRoots: l.dsseTrustRoots, + CosignVerifications: l.cosignVerifs, + SigningProviders: l.signingProviders, + MerkleBatches: l.merkleBatches, + TransparencyCheckpoints: l.transparency, + ObjectRetentionPolicies: l.retentionPolicies, + BackupManifests: l.backupManifests, + LegalHolds: l.legalHolds, + RetentionOverrides: l.retentionOverrides, + CustomerPortalAccess: portalAccess, + CustomerPortalHashes: map[string]string{}, + QuestionnaireTemplates: l.questionTemplates, + QuestionnairePackages: l.questionPackages, + QuestionnaireAnswerLibrary: l.answerLibrary, + CommercialCollectors: l.commercialCollectors, + EvidenceSummaries: l.evidenceSummaries, + QuestionnaireDrafts: l.questionDrafts, + GraphSnapshots: l.graphSnapshots, + SaaSProfiles: l.saasProfiles, + PublicTransparencyLogs: l.publicLogs, + PublicTransparencyItems: l.publicLogEntries, + MarketplaceCollectors: l.marketplaceCollectors, + PDFReports: l.pdfReports, + AnomalyReports: l.anomalyReports, + ProviderVerifications: l.providerVerifications, + SigningOperations: l.signingOperations, + ControlFrameworks: l.frameworks, + SecurityControls: l.controls, + ControlEvidence: l.controlLinks, + SBOMs: l.sboms, + Scans: l.scans, + VEXDocuments: l.vexDocuments, + VEXImportReports: l.vexImportReports, + Decisions: l.decisions, + Contracts: l.contracts, + Policies: l.policies, + Exceptions: l.exceptions, + Bundles: l.bundles, + SigningKeys: signingKeys, + SigningKeyPrivate: map[string][]byte{}, + Signatures: l.signatures, + Verifications: l.verifications, + Chain: l.chain, + Idempotency: l.idempotency, } for id, key := range state.APIKeys { if key.Hash != "" { @@ -247,6 +248,7 @@ func (l *Ledger) applyState(state PersistedState) { l.portalAccess = state.CustomerPortalAccess l.questionTemplates = state.QuestionnaireTemplates l.questionPackages = state.QuestionnairePackages + l.answerLibrary = state.QuestionnaireAnswerLibrary l.commercialCollectors = state.CommercialCollectors l.evidenceSummaries = state.EvidenceSummaries l.questionDrafts = state.QuestionnaireDrafts @@ -691,6 +693,9 @@ func normalizeState(state PersistedState) PersistedState { if state.QuestionnairePackages == nil { state.QuestionnairePackages = map[string]domain.QuestionnairePackage{} } + if state.QuestionnaireAnswerLibrary == nil { + state.QuestionnaireAnswerLibrary = map[string]domain.QuestionnaireAnswerLibraryEntry{} + } if state.CommercialCollectors == nil { state.CommercialCollectors = map[string]domain.CommercialCollectorDefinition{} } diff --git a/internal/domain/domain.go b/internal/domain/domain.go index e78a0c7..457fb19 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -3,84 +3,85 @@ package domain import "time" const ( - EvidenceItemSchemaVersion = "evidence-item.v1.0.0" - AuditChainEntrySchemaVersion = "audit-chain-entry.v1.0.0" - ReleaseBundleSchemaVersion = "release-bundle.v1.0.0" - ReleaseEvidenceFlowVersion = "release-evidence-flow.v1.0.0" - ReleaseSecuritySummaryVersion = "release-security-summary.v1.0.0" - CanonicalizationProfileVersion = "canonicalization-profile.v1.0.0" - PolicySetVersion = "policy-set.v1.0.0" - VEXDocumentSchemaVersion = "vex-document.v1.0.0" - VEXImportReportSchemaVersion = "vex-import-report.v1.0.0" - VulnerabilityDecisionVersion = "vulnerability-decision.v1.0.0" - ReleaseReadinessTemplateVersion = "release-readiness.v1.0.0" - CollectorSchemaVersion = "collector.v1.0.0" - BuildRunSchemaVersion = "build-run.v1.0.0" - BuildAttestationSchemaVersion = "build-attestation.v1.0.0" - ControlFrameworkSchemaVersion = "control-framework.v1.0.0" - SecurityControlSchemaVersion = "security-control.v1.0.0" - ControlEvidenceSchemaVersion = "control-evidence.v1.0.0" - ControlCoverageTemplateVersion = "control-coverage.v1.0.0" - CRAReadinessTemplateVersion = "cra-readiness.v1.0.0" - EvidenceLifecycleSchemaVersion = "evidence-lifecycle-event.v1.0.0" - ReleaseCandidateSchemaVersion = "release-candidate.v1.0.0" - ContainerImageSchemaVersion = "container-image.v1.0.0" - ArtifactSignatureSchemaVersion = "artifact-signature.v1.0.0" - SourceRepositorySchemaVersion = "source-repository.v1.0.0" - SourceCommitSchemaVersion = "source-commit.v1.0.0" - SourceBranchSchemaVersion = "source-branch.v1.0.0" - PullRequestSchemaVersion = "pull-request.v1.0.0" - DeploymentEnvironmentVersion = "deployment-environment.v1.0.0" - DeploymentEventSchemaVersion = "deployment-event.v1.0.0" - IncidentSchemaVersion = "incident.v1.0.0" - IncidentTimelineSchemaVersion = "incident-timeline-event.v1.0.0" - IncidentWebhookReceiverVersion = "incident-webhook-receiver.v1.0.0" - IncidentWebhookEventVersion = "incident-webhook-event.v1.0.0" - RemediationTaskSchemaVersion = "remediation-task.v1.0.0" - SecurityScanSchemaVersion = "security-scan.v1.0.0" - ManualSecurityDocSchemaVersion = "manual-security-document.v1.0.0" - SBOMDiffSchemaVersion = "sbom-diff.v1.0.0" - DependencyChangeSchemaVersion = "dependency-change.v1.0.0" - ContractDiffSchemaVersion = "contract-diff.v1.0.0" - CustomPolicySchemaVersion = "custom-policy.v1.0.0" - CustomPolicyEvalSchemaVersion = "custom-policy-evaluation.v1.0.0" - WaiverSchemaVersion = "waiver.v1.0.0" - ApprovalRecordSchemaVersion = "approval-record.v1.0.0" - RedactionProfileSchemaVersion = "redaction-profile.v1.0.0" - CustomerPackageSchemaVersion = "customer-security-package.v2.0.0" - ReportTemplateSchemaVersion = "report-template.v1.0.0" - EvidenceBundleSchemaVersion = "evidence-bundle.v1.0.0" - EvidenceBundleImportVersion = "evidence-bundle-import.v1.0.0" - DSSETrustRootSchemaVersion = "dsse-trust-root.v1.0.0" - CosignVerificationSchemaVersion = "cosign-verification.v1.0.0" - SigningProviderSchemaVersion = "signing-provider.v1.0.0" - MerkleBatchSchemaVersion = "merkle-batch.v1.0.0" - TransparencyCheckpointVersion = "transparency-checkpoint.v1.0.0" - ObjectRetentionPolicyVersion = "object-retention-policy.v1.0.0" - BackupManifestSchemaVersion = "backup-manifest.v1.0.0" - CollectorReleaseSchemaVersion = "collector-release.v1.0.0" - OrganizationSchemaVersion = "organization.v1.0.0" - HumanUserSchemaVersion = "human-user.v1.0.0" - RoleBindingSchemaVersion = "role-binding.v1.0.0" - SSOProviderSchemaVersion = "sso-provider.v1.0.0" - SSOSessionSchemaVersion = "sso-session.v1.0.0" - LegalHoldSchemaVersion = "legal-hold.v1.0.0" - RetentionOverrideSchemaVersion = "retention-override.v1.0.0" - CustomerPortalAccessVersion = "customer-portal-access.v1.0.0" - QuestionnaireTemplateVersion = "questionnaire-template.v1.0.0" - QuestionnairePackageVersion = "questionnaire-package.v1.0.0" - CommercialCollectorVersion = "commercial-collector.v1.0.0" - EvidenceSummaryVersion = "evidence-summary.v1.0.0" - QuestionnaireDraftVersion = "questionnaire-draft.v1.0.0" - EvidenceGraphSnapshotVersion = "evidence-graph-snapshot.v1.0.0" - SaaSEditionProfileVersion = "saas-edition-profile.v1.0.0" - PublicTransparencyLogVersion = "public-transparency-log.v1.0.0" - PublicTransparencyEntryVersion = "public-transparency-entry.v1.0.0" - MarketplaceCollectorVersion = "marketplace-collector.v1.0.0" - PDFReportPackageVersion = "pdf-report-package.v1.0.0" - AnomalyReportVersion = "anomaly-report.v1.0.0" - ProviderVerificationVersion = "provider-verification.v1.0.0" - SigningOperationVersion = "signing-operation.v1.0.0" + EvidenceItemSchemaVersion = "evidence-item.v1.0.0" + AuditChainEntrySchemaVersion = "audit-chain-entry.v1.0.0" + ReleaseBundleSchemaVersion = "release-bundle.v1.0.0" + ReleaseEvidenceFlowVersion = "release-evidence-flow.v1.0.0" + ReleaseSecuritySummaryVersion = "release-security-summary.v1.0.0" + CanonicalizationProfileVersion = "canonicalization-profile.v1.0.0" + PolicySetVersion = "policy-set.v1.0.0" + VEXDocumentSchemaVersion = "vex-document.v1.0.0" + VEXImportReportSchemaVersion = "vex-import-report.v1.0.0" + VulnerabilityDecisionVersion = "vulnerability-decision.v1.0.0" + ReleaseReadinessTemplateVersion = "release-readiness.v1.0.0" + CollectorSchemaVersion = "collector.v1.0.0" + BuildRunSchemaVersion = "build-run.v1.0.0" + BuildAttestationSchemaVersion = "build-attestation.v1.0.0" + ControlFrameworkSchemaVersion = "control-framework.v1.0.0" + SecurityControlSchemaVersion = "security-control.v1.0.0" + ControlEvidenceSchemaVersion = "control-evidence.v1.0.0" + ControlCoverageTemplateVersion = "control-coverage.v1.0.0" + CRAReadinessTemplateVersion = "cra-readiness.v1.0.0" + EvidenceLifecycleSchemaVersion = "evidence-lifecycle-event.v1.0.0" + ReleaseCandidateSchemaVersion = "release-candidate.v1.0.0" + ContainerImageSchemaVersion = "container-image.v1.0.0" + ArtifactSignatureSchemaVersion = "artifact-signature.v1.0.0" + SourceRepositorySchemaVersion = "source-repository.v1.0.0" + SourceCommitSchemaVersion = "source-commit.v1.0.0" + SourceBranchSchemaVersion = "source-branch.v1.0.0" + PullRequestSchemaVersion = "pull-request.v1.0.0" + DeploymentEnvironmentVersion = "deployment-environment.v1.0.0" + DeploymentEventSchemaVersion = "deployment-event.v1.0.0" + IncidentSchemaVersion = "incident.v1.0.0" + IncidentTimelineSchemaVersion = "incident-timeline-event.v1.0.0" + IncidentWebhookReceiverVersion = "incident-webhook-receiver.v1.0.0" + IncidentWebhookEventVersion = "incident-webhook-event.v1.0.0" + RemediationTaskSchemaVersion = "remediation-task.v1.0.0" + SecurityScanSchemaVersion = "security-scan.v1.0.0" + ManualSecurityDocSchemaVersion = "manual-security-document.v1.0.0" + SBOMDiffSchemaVersion = "sbom-diff.v1.0.0" + DependencyChangeSchemaVersion = "dependency-change.v1.0.0" + ContractDiffSchemaVersion = "contract-diff.v1.0.0" + CustomPolicySchemaVersion = "custom-policy.v1.0.0" + CustomPolicyEvalSchemaVersion = "custom-policy-evaluation.v1.0.0" + WaiverSchemaVersion = "waiver.v1.0.0" + ApprovalRecordSchemaVersion = "approval-record.v1.0.0" + RedactionProfileSchemaVersion = "redaction-profile.v1.0.0" + CustomerPackageSchemaVersion = "customer-security-package.v2.0.0" + ReportTemplateSchemaVersion = "report-template.v1.0.0" + EvidenceBundleSchemaVersion = "evidence-bundle.v1.0.0" + EvidenceBundleImportVersion = "evidence-bundle-import.v1.0.0" + DSSETrustRootSchemaVersion = "dsse-trust-root.v1.0.0" + CosignVerificationSchemaVersion = "cosign-verification.v1.0.0" + SigningProviderSchemaVersion = "signing-provider.v1.0.0" + MerkleBatchSchemaVersion = "merkle-batch.v1.0.0" + TransparencyCheckpointVersion = "transparency-checkpoint.v1.0.0" + ObjectRetentionPolicyVersion = "object-retention-policy.v1.0.0" + BackupManifestSchemaVersion = "backup-manifest.v1.0.0" + CollectorReleaseSchemaVersion = "collector-release.v1.0.0" + OrganizationSchemaVersion = "organization.v1.0.0" + HumanUserSchemaVersion = "human-user.v1.0.0" + RoleBindingSchemaVersion = "role-binding.v1.0.0" + SSOProviderSchemaVersion = "sso-provider.v1.0.0" + SSOSessionSchemaVersion = "sso-session.v1.0.0" + LegalHoldSchemaVersion = "legal-hold.v1.0.0" + RetentionOverrideSchemaVersion = "retention-override.v1.0.0" + CustomerPortalAccessVersion = "customer-portal-access.v1.0.0" + QuestionnaireTemplateVersion = "questionnaire-template.v1.0.0" + QuestionnairePackageVersion = "questionnaire-package.v1.0.0" + QuestionnaireAnswerLibraryVersion = "questionnaire-answer-library.v1.0.0" + CommercialCollectorVersion = "commercial-collector.v1.0.0" + EvidenceSummaryVersion = "evidence-summary.v1.0.0" + QuestionnaireDraftVersion = "questionnaire-draft.v1.0.0" + EvidenceGraphSnapshotVersion = "evidence-graph-snapshot.v1.0.0" + SaaSEditionProfileVersion = "saas-edition-profile.v1.0.0" + PublicTransparencyLogVersion = "public-transparency-log.v1.0.0" + PublicTransparencyEntryVersion = "public-transparency-entry.v1.0.0" + MarketplaceCollectorVersion = "marketplace-collector.v1.0.0" + PDFReportPackageVersion = "pdf-report-package.v1.0.0" + AnomalyReportVersion = "anomaly-report.v1.0.0" + ProviderVerificationVersion = "provider-verification.v1.0.0" + SigningOperationVersion = "signing-operation.v1.0.0" ) type Actor struct { @@ -878,6 +879,10 @@ type CustomerPortalAccess struct { TenantID string `json:"tenant_id"` PackageID string `json:"package_id"` CustomerName string `json:"customer_name"` + RequireNDA bool `json:"require_nda"` + NDAAcceptedAt *time.Time `json:"nda_accepted_at,omitempty"` + NDAAcceptedBy string `json:"nda_accepted_by,omitempty"` + Watermark string `json:"watermark,omitempty"` Prefix string `json:"prefix"` ExpiresAt time.Time `json:"expires_at"` RevokedAt *time.Time `json:"revoked_at,omitempty"` @@ -928,6 +933,21 @@ type QuestionnaireResponse struct { Limitations []string `json:"limitations,omitempty"` } +type QuestionnaireAnswerLibraryEntry struct { + ID string `json:"id"` + TenantID string `json:"tenant_id"` + QuestionID string `json:"question_id,omitempty"` + EvidenceType string `json:"evidence_type,omitempty"` + ControlID string `json:"control_id,omitempty"` + ProductID string `json:"product_id,omitempty"` + ReleaseID string `json:"release_id,omitempty"` + Answer string `json:"answer"` + EvidenceIDs []string `json:"evidence_ids,omitempty"` + Limitations []string `json:"limitations,omitempty"` + SchemaVersion string `json:"schema_version"` + CreatedAt time.Time `json:"created_at"` +} + type CommercialCollectorDefinition struct { ID string `json:"id"` TenantID string `json:"tenant_id"` @@ -1701,19 +1721,20 @@ type RedactionProfile struct { } type CustomerSecurityPackage struct { - ID string `json:"id"` - TenantID string `json:"tenant_id"` - ProductID string `json:"product_id"` - ReleaseID string `json:"release_id,omitempty"` - RedactionProfileID string `json:"redaction_profile_id"` - Title string `json:"title"` - State string `json:"state"` - Manifest map[string]any `json:"manifest"` - ManifestHash string `json:"manifest_hash"` - ExpiresAt time.Time `json:"expires_at"` - AccessCount int `json:"access_count"` - SchemaVersion string `json:"schema_version"` - CreatedAt time.Time `json:"created_at"` + ID string `json:"id"` + TenantID string `json:"tenant_id"` + ProductID string `json:"product_id"` + ReleaseID string `json:"release_id,omitempty"` + RedactionProfileID string `json:"redaction_profile_id"` + Title string `json:"title"` + State string `json:"state"` + Manifest map[string]any `json:"manifest"` + ManifestHash string `json:"manifest_hash"` + DistributionWatermark string `json:"distribution_watermark,omitempty"` + ExpiresAt time.Time `json:"expires_at"` + AccessCount int `json:"access_count"` + SchemaVersion string `json:"schema_version"` + CreatedAt time.Time `json:"created_at"` } type SecurityReviewPackageReport struct { diff --git a/migrations/20260601000400_customer_portal_nda_answer_library.down.sql b/migrations/20260601000400_customer_portal_nda_answer_library.down.sql new file mode 100644 index 0000000..9c7630d --- /dev/null +++ b/migrations/20260601000400_customer_portal_nda_answer_library.down.sql @@ -0,0 +1,7 @@ +DROP TABLE IF EXISTS questionnaire_answer_library; + +ALTER TABLE customer_portal_access + DROP COLUMN IF EXISTS watermark, + DROP COLUMN IF EXISTS nda_accepted_by, + DROP COLUMN IF EXISTS nda_accepted_at, + DROP COLUMN IF EXISTS require_nda; diff --git a/migrations/20260601000400_customer_portal_nda_answer_library.up.sql b/migrations/20260601000400_customer_portal_nda_answer_library.up.sql new file mode 100644 index 0000000..5c1f7a6 --- /dev/null +++ b/migrations/20260601000400_customer_portal_nda_answer_library.up.sql @@ -0,0 +1,26 @@ +ALTER TABLE customer_portal_access + ADD COLUMN IF NOT EXISTS require_nda boolean NOT NULL DEFAULT false, + ADD COLUMN IF NOT EXISTS nda_accepted_at timestamptz, + ADD COLUMN IF NOT EXISTS nda_accepted_by text, + ADD COLUMN IF NOT EXISTS watermark text; + +CREATE TABLE IF NOT EXISTS questionnaire_answer_library ( + id text PRIMARY KEY, + tenant_id text NOT NULL, + question_id text, + evidence_type text, + control_id text, + product_id text, + release_id text, + answer text NOT NULL, + evidence_ids text[] NOT NULL DEFAULT '{}', + limitations text[] NOT NULL DEFAULT '{}', + schema_version text NOT NULL, + created_at timestamptz NOT NULL +); + +CREATE INDEX IF NOT EXISTS questionnaire_answer_library_tenant_question_idx + ON questionnaire_answer_library (tenant_id, question_id, created_at); + +CREATE INDEX IF NOT EXISTS questionnaire_answer_library_tenant_release_idx + ON questionnaire_answer_library (tenant_id, release_id, created_at); diff --git a/openapi.yaml b/openapi.yaml index 3b21809..9092d0c 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CRAVulnerabilityHandlingReport":{"additionalProperties":false,"properties":{"accepted_exceptions":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"CRAVulnerabilityHandlingReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"remediation":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"policy_set":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlow":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["needs_evidence","ready_for_review"],"type":"string"},"steps":{"items":{"$ref":"#/components/schemas/ReleaseEvidenceFlowStep"},"type":"array"}},"required":["release_id","product_id","status","counts","steps","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseEvidenceFlowEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseEvidenceFlow"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlowStep":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"idempotency_required":{"type":"boolean"},"method":{"type":"string"},"next_reference":{"type":"string"},"path":{"type":"string"},"required":{"type":"boolean"},"required_scopes":{"items":{"type":"string"},"type":"array"},"status":{"enum":["present","missing","optional"],"type":"string"},"title":{"type":"string"}},"required":["id","title","status","required","method","path","required_scopes","idempotency_required","description"],"type":"object"},"ReleaseSecurityApprovalSummary":{"additionalProperties":false,"properties":{"approved":{"type":"integer"},"total":{"type":"integer"}},"required":["total","approved"],"type":"object"},"ReleaseSecurityExceptionSummary":{"additionalProperties":false,"properties":{"approved_unexpired":{"type":"integer"},"expired":{"type":"integer"},"total":{"type":"integer"},"unapproved":{"type":"integer"}},"required":["total","approved_unexpired","unapproved","expired"],"type":"object"},"ReleaseSecurityMissingDecision":{"additionalProperties":false,"properties":{"component":{"type":"string"},"finding_id":{"type":"string"},"scan_id":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["finding_id","scan_id","vulnerability","severity","state"],"type":"object"},"ReleaseSecurityProductSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"],"type":"object"},"ReleaseSecurityReleaseSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"state":{"type":"string"},"version":{"type":"string"}},"required":["id","version","state"],"type":"object"},"ReleaseSecuritySummary":{"additionalProperties":false,"properties":{"approval_summary":{"$ref":"#/components/schemas/ReleaseSecurityApprovalSummary"},"artifact_count":{"type":"integer"},"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"decisions_by_status":{"additionalProperties":{"type":"integer"},"type":"object"},"exception_summary":{"$ref":"#/components/schemas/ReleaseSecurityExceptionSummary"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_required_decisions":{"items":{"$ref":"#/components/schemas/ReleaseSecurityMissingDecision"},"type":"array"},"open_findings_by_severity":{"additionalProperties":{"type":"integer"},"type":"object"},"package_status":{"enum":["generated","not_generated"],"type":"string"},"product":{"$ref":"#/components/schemas/ReleaseSecurityProductSummary"},"readiness_status":{"enum":["passed","failed"],"type":"string"},"release":{"$ref":"#/components/schemas/ReleaseSecurityReleaseSummary"},"sbom_status":{"enum":["present","missing"],"type":"string"},"schema_version":{"type":"string"},"vulnerability_scan_status":{"enum":["present","missing"],"type":"string"}},"required":["product","release","artifact_count","sbom_status","vulnerability_scan_status","open_findings_by_severity","decisions_by_status","approval_summary","exception_summary","readiness_status","package_status","counts","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseSecuritySummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseSecuritySummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityUpdateEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"fixed_decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incidents":{"items":{"$ref":"#/components/schemas/Incident"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"remediation_tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"SecurityUpdateEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"examples":{"release-evidence-package":{"summary":"Create a scoped release evidence package","value":{"expires_at":"2026-06-30T00:00:00Z","product_id":"prod_20260527120000","redaction_profile_id":"rp_20260527120000","release_id":"rel_20260527120000","title":"Payments API 1.0.0 release evidence package"}}},"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"examples":{"release-candidate":{"summary":"Create a release for evidence collection","value":{"product_id":"prod_20260527120000","project_id":"proj_20260527120000","version":"1.0.0-rc.1"}}},"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"examples":{"created-release":{"summary":"Created release response","value":{"data":{"created_at":"2026-05-27T12:00:00Z","id":"rel_20260527120000","product_id":"prod_20260527120000","project_id":"proj_20260527120000","schema_version":"release.v1.0.0","status":"draft","tenant_id":"ten_20260527120000","version":"1.0.0-rc.1"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/evidence-flow/start":{"post":{"description":"Returns a high-level release evidence workflow plan, current evidence counts, required scopes, assumptions, and limitations. This read-only convenience operation does not create evidence.","operationId":"startReleaseEvidenceFlow","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEvidenceFlowEnvelope"}}},"description":"Release evidence flow envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Start release evidence flow","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:read"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/security-summary":{"get":{"description":"Returns a tenant-scoped release security summary for review surfaces without raw evidence payload bytes.","operationId":"releaseSecuritySummary","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseSecuritySummaryEnvelope"}}},"description":"Release security summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release security summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-vulnerability-handling":{"get":{"description":"Returns a CRA-oriented vulnerability handling evidence report without legal compliance, certification, scanner-authority, or release-security conclusions.","operationId":"craVulnerabilityHandlingReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReportEnvelope"}}},"description":"CRA vulnerability handling report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA vulnerability handling report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"examples":{"failed-readiness-with-gap":{"summary":"Readiness report with a vulnerability decision gap","value":{"data":{"accepted_exceptions":[],"assumptions":["Readiness is based on tenant evidence recorded in Evydence."],"blocking_findings":[{"component":"pkg:apk/openssl@3.1.0-r0","decision_state":"missing","finding_id":"scan_20260527120000:finding:1","release_id":"rel_20260527120000","scan_id":"scan_20260527120000","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"generated_at":"2026-05-27T12:00:00Z","limitations":["Readiness supports technical review and does not prove legal compliance, certification, complete vulnerability coverage, or release security."],"missing_evidence":["vulnerability_decision"],"policy_set":"policy-set.v1.0.0","product_id":"prod_20260527120000","release_id":"rel_20260527120000","report_type":"release_readiness","result":"failed","schema_version":"release-readiness.v1.0.0","summary":{"headline":"Release evidence has one blocking vulnerability decision gap.","human_summary":"Required artifact, SBOM, scan, build, and bundle evidence is present, but one critical finding still needs a valid decision or approved exception.","policy_set":"policy-set.v1.0.0","result":"failed"},"template_version":"release-readiness.v1.0.0"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/security-update-evidence":{"get":{"description":"Returns a security update evidence report for release-scoped fixed decisions, incidents, remediation tasks, and linked evidence without legal or security conclusions.","operationId":"securityUpdateEvidenceReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReportEnvelope"}}},"description":"Security update evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security update evidence report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"examples":{"cyclonedx-release-sbom":{"summary":"Upload a CycloneDX SBOM linked to the release artifact","value":{"artifact_id":"art_20260527120000","payload":{"bomFormat":"CycloneDX","components":[{"name":"payments-api","purl":"pkg:oci/payments-api@sha256-ca978112","version":"1.0.0-rc.1"},{"name":"openssl","purl":"pkg:apk/openssl@3.1.0-r0","version":"3.1.0-r0"}],"specVersion":"1.6"},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"examples":{"not-affected-decision":{"summary":"Record a customer-visible not-affected decision","value":{"customer_visible":true,"evidence_ids":["ev_20260527120000"],"impact_statement":"The shipped artifact does not include the affected runtime path.","justification":"The vulnerable code path is not reachable in this release.","status":"not_affected"}}},"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"examples":{"generic-critical-finding":{"summary":"Upload a generic scanner finding for release triage","value":{"findings":[{"component":"pkg:apk/openssl@3.1.0-r0","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"release_id":"rel_20260527120000","scanner":"generic-json","target_ref":"pkg:oci/payments-api@sha256-ca978112"}}},"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CRAVulnerabilityHandlingReport":{"additionalProperties":false,"properties":{"accepted_exceptions":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"CRAVulnerabilityHandlingReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"},"require_nda":{"type":"boolean"},"watermark":{"description":"Optional customer-visible distribution watermark. It is not a token or secret.","type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireAnswerLibraryEntryRequest":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"}},"required":["answer"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"nda_accepted":{"description":"Set true to record acceptance for NDA-gated portal access.","type":"boolean"},"nda_accepted_by":{"description":"Reviewer label recorded when NDA acceptance is required. Do not include secrets.","type":"string"},"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"distribution_watermark":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"remediation":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntry":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","answer","schema_version","created_at"],"type":"object"},"QuestionnaireAnswerLibraryEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"policy_set":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlow":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["needs_evidence","ready_for_review"],"type":"string"},"steps":{"items":{"$ref":"#/components/schemas/ReleaseEvidenceFlowStep"},"type":"array"}},"required":["release_id","product_id","status","counts","steps","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseEvidenceFlowEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseEvidenceFlow"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlowStep":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"idempotency_required":{"type":"boolean"},"method":{"type":"string"},"next_reference":{"type":"string"},"path":{"type":"string"},"required":{"type":"boolean"},"required_scopes":{"items":{"type":"string"},"type":"array"},"status":{"enum":["present","missing","optional"],"type":"string"},"title":{"type":"string"}},"required":["id","title","status","required","method","path","required_scopes","idempotency_required","description"],"type":"object"},"ReleaseSecurityApprovalSummary":{"additionalProperties":false,"properties":{"approved":{"type":"integer"},"total":{"type":"integer"}},"required":["total","approved"],"type":"object"},"ReleaseSecurityExceptionSummary":{"additionalProperties":false,"properties":{"approved_unexpired":{"type":"integer"},"expired":{"type":"integer"},"total":{"type":"integer"},"unapproved":{"type":"integer"}},"required":["total","approved_unexpired","unapproved","expired"],"type":"object"},"ReleaseSecurityMissingDecision":{"additionalProperties":false,"properties":{"component":{"type":"string"},"finding_id":{"type":"string"},"scan_id":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["finding_id","scan_id","vulnerability","severity","state"],"type":"object"},"ReleaseSecurityProductSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"],"type":"object"},"ReleaseSecurityReleaseSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"state":{"type":"string"},"version":{"type":"string"}},"required":["id","version","state"],"type":"object"},"ReleaseSecuritySummary":{"additionalProperties":false,"properties":{"approval_summary":{"$ref":"#/components/schemas/ReleaseSecurityApprovalSummary"},"artifact_count":{"type":"integer"},"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"decisions_by_status":{"additionalProperties":{"type":"integer"},"type":"object"},"exception_summary":{"$ref":"#/components/schemas/ReleaseSecurityExceptionSummary"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_required_decisions":{"items":{"$ref":"#/components/schemas/ReleaseSecurityMissingDecision"},"type":"array"},"open_findings_by_severity":{"additionalProperties":{"type":"integer"},"type":"object"},"package_status":{"enum":["generated","not_generated"],"type":"string"},"product":{"$ref":"#/components/schemas/ReleaseSecurityProductSummary"},"readiness_status":{"enum":["passed","failed"],"type":"string"},"release":{"$ref":"#/components/schemas/ReleaseSecurityReleaseSummary"},"sbom_status":{"enum":["present","missing"],"type":"string"},"schema_version":{"type":"string"},"vulnerability_scan_status":{"enum":["present","missing"],"type":"string"}},"required":["product","release","artifact_count","sbom_status","vulnerability_scan_status","open_findings_by_severity","decisions_by_status","approval_summary","exception_summary","readiness_status","package_status","counts","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseSecuritySummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseSecuritySummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityUpdateEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"fixed_decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incidents":{"items":{"$ref":"#/components/schemas/Incident"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"remediation_tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"SecurityUpdateEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"examples":{"release-evidence-package":{"summary":"Create a scoped release evidence package","value":{"expires_at":"2026-06-30T00:00:00Z","product_id":"prod_20260527120000","redaction_profile_id":"rp_20260527120000","release_id":"rel_20260527120000","title":"Payments API 1.0.0 release evidence package"}}},"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-answer-library":{"get":{"description":"Lists tenant-scoped questionnaire answer library entries with optional question, product, and release filters.","operationId":"listQuestionnaireAnswerLibrary","parameters":[{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by questionnaire question id.","in":"query","name":"question_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryListEnvelope"}}},"description":"Questionnaire answer library entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List questionnaire answer library entries","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a tenant-scoped reusable questionnaire answer draft linked to optional evidence, product, release, or control scope.","operationId":"createQuestionnaireAnswerLibraryEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireAnswerLibraryEntryRequest"}}},"description":"Questionnaire answer library entry creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryEnvelope"}}},"description":"Created questionnaire answer library entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire answer library entry","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"examples":{"release-candidate":{"summary":"Create a release for evidence collection","value":{"product_id":"prod_20260527120000","project_id":"proj_20260527120000","version":"1.0.0-rc.1"}}},"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"examples":{"created-release":{"summary":"Created release response","value":{"data":{"created_at":"2026-05-27T12:00:00Z","id":"rel_20260527120000","product_id":"prod_20260527120000","project_id":"proj_20260527120000","schema_version":"release.v1.0.0","status":"draft","tenant_id":"ten_20260527120000","version":"1.0.0-rc.1"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/evidence-flow/start":{"post":{"description":"Returns a high-level release evidence workflow plan, current evidence counts, required scopes, assumptions, and limitations. This read-only convenience operation does not create evidence.","operationId":"startReleaseEvidenceFlow","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEvidenceFlowEnvelope"}}},"description":"Release evidence flow envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Start release evidence flow","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:read"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/security-summary":{"get":{"description":"Returns a tenant-scoped release security summary for review surfaces without raw evidence payload bytes.","operationId":"releaseSecuritySummary","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseSecuritySummaryEnvelope"}}},"description":"Release security summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release security summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-vulnerability-handling":{"get":{"description":"Returns a CRA-oriented vulnerability handling evidence report without legal compliance, certification, scanner-authority, or release-security conclusions.","operationId":"craVulnerabilityHandlingReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReportEnvelope"}}},"description":"CRA vulnerability handling report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA vulnerability handling report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"examples":{"failed-readiness-with-gap":{"summary":"Readiness report with a vulnerability decision gap","value":{"data":{"accepted_exceptions":[],"assumptions":["Readiness is based on tenant evidence recorded in Evydence."],"blocking_findings":[{"component":"pkg:apk/openssl@3.1.0-r0","decision_state":"missing","finding_id":"scan_20260527120000:finding:1","release_id":"rel_20260527120000","scan_id":"scan_20260527120000","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"generated_at":"2026-05-27T12:00:00Z","limitations":["Readiness supports technical review and does not prove legal compliance, certification, complete vulnerability coverage, or release security."],"missing_evidence":["vulnerability_decision"],"policy_set":"policy-set.v1.0.0","product_id":"prod_20260527120000","release_id":"rel_20260527120000","report_type":"release_readiness","result":"failed","schema_version":"release-readiness.v1.0.0","summary":{"headline":"Release evidence has one blocking vulnerability decision gap.","human_summary":"Required artifact, SBOM, scan, build, and bundle evidence is present, but one critical finding still needs a valid decision or approved exception.","policy_set":"policy-set.v1.0.0","result":"failed"},"template_version":"release-readiness.v1.0.0"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/security-update-evidence":{"get":{"description":"Returns a security update evidence report for release-scoped fixed decisions, incidents, remediation tasks, and linked evidence without legal or security conclusions.","operationId":"securityUpdateEvidenceReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReportEnvelope"}}},"description":"Security update evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security update evidence report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"examples":{"cyclonedx-release-sbom":{"summary":"Upload a CycloneDX SBOM linked to the release artifact","value":{"artifact_id":"art_20260527120000","payload":{"bomFormat":"CycloneDX","components":[{"name":"payments-api","purl":"pkg:oci/payments-api@sha256-ca978112","version":"1.0.0-rc.1"},{"name":"openssl","purl":"pkg:apk/openssl@3.1.0-r0","version":"3.1.0-r0"}],"specVersion":"1.6"},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"examples":{"not-affected-decision":{"summary":"Record a customer-visible not-affected decision","value":{"customer_visible":true,"evidence_ids":["ev_20260527120000"],"impact_statement":"The shipped artifact does not include the affected runtime path.","justification":"The vulnerable code path is not reachable in this release.","status":"not_affected"}}},"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"examples":{"generic-critical-finding":{"summary":"Upload a generic scanner finding for release triage","value":{"findings":[{"component":"pkg:apk/openssl@3.1.0-r0","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"release_id":"rel_20260527120000","scanner":"generic-json","target_ref":"pkg:oci/payments-api@sha256-ca978112"}}},"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/sdk/openapi-route-catalog.json b/sdk/openapi-route-catalog.json index bc5fe59..1bee899 100644 --- a/sdk/openapi-route-catalog.json +++ b/sdk/openapi-route-catalog.json @@ -1,5 +1,5 @@ { - "route_count": 173, + "route_count": 175, "routes": [ { "idempotency_key_required": false, @@ -1536,6 +1536,40 @@ "201" ] }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "listQuestionnaireAnswerLibrary", + "path": "/v1/questionnaire-answer-library", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/QuestionnaireAnswerLibraryEntryListEnvelope" + ], + "scopes": [ + "package:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "createQuestionnaireAnswerLibraryEntry", + "path": "/v1/questionnaire-answer-library", + "request_schema": "#/components/schemas/CreateQuestionnaireAnswerLibraryEntryRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/QuestionnaireAnswerLibraryEntryEnvelope" + ], + "scopes": [ + "package:write" + ], + "success_statuses": [ + "201" + ] + }, { "idempotency_key_required": true, "method": "POST", From 5971d4f585282f7878dd43f1e7cd1ca5587a1c51 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 23:09:15 +0300 Subject: [PATCH 210/287] feat(integrity): add custody review proofs --- .productization_next_steps.md | 8 +- README.md | 5 +- docs/api.md | 1 + docs/architecture.md | 2 +- docs/reference/api-contract-matrix.md | 3 +- docs/reference/configuration.md | 7 ++ docs/reference/customer-package-manifest.md | 24 +++-- docs/reference/production-readiness.md | 16 ++-- internal/adapters/httpapi/openapi.go | 20 +++++ .../adapters/httpapi/openapi_operations.go | 3 + .../adapters/httpapi/route_registration.go | 1 + internal/adapters/httpapi/router.go | 13 +++ internal/adapters/httpapi/router_test.go | 9 +- internal/app/context_cancellation_test.go | 2 + internal/app/governance_packages.go | 74 +++++++++++++++- internal/app/integrity_runtime.go | 78 ++++++++++++++++- internal/app/integrity_runtime_test.go | 87 +++++++++++++++++++ internal/app/ledger.go | 1 + internal/domain/domain.go | 11 +++ openapi.yaml | 2 +- sdk/openapi-route-catalog.json | 19 +++- 21 files changed, 358 insertions(+), 28 deletions(-) diff --git a/.productization_next_steps.md b/.productization_next_steps.md index fa97467..fa2d344 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -1244,18 +1244,18 @@ Potential later expansion: Keep language as readiness support, not legal conclusion. -#### [ ] EVY-203 — Advanced signing/HSM/WORM profiles +#### [x] EVY-203 — Advanced signing/HSM/WORM profiles Potential later expansion: * [x] external signing provider records and operation receipts * [x] HTTPS signing gateway executor * [x] AWS KMS, GCP Cloud KMS, and Azure Key Vault signing executors -* [ ] native PKCS#11/HSM module profile beyond gateway-backed `pkcs11-hsm` +* [x] native PKCS#11/HSM module profile beyond gateway-backed `pkcs11-hsm` * [x] object-retention policy records and configured object-store verification -* [ ] object-lock proof packages for customer/release export +* [x] object-lock proof packages for customer/release export * [x] public transparency proof records, verification, and optional proof fetcher -* [ ] deployment-specific custody review tooling +* [x] deployment-specific custody review tooling Do this when a real pilot requires it. diff --git a/README.md b/README.md index fa10f35..efa7bfa 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,8 @@ objects instead of unsupported prose: - Container publication uses the maintainer-run GHCR workflow and must be verified by immutable digest and cosign evidence; Helm installs should not use floating image tags. -- Native PKCS#11/HSM module handling, broad WORM/object-lock proof, direct +- Native PKCS#11/HSM module execution, broad provider-side WORM enforcement + proof beyond recorded object-lock verification metadata, direct provider-specific management API clients, external group synchronization, regulated production, and hosted SaaS production remain outside the current supported profile unless a deployment review closes those gaps. @@ -174,7 +175,7 @@ non-sensitive sample data and does not upload files. - AGPL license, commercial licensing, governance, contribution, security, support, code of conduct, trademark, release-evidence, and changelog metadata. -Implemented-but-partial areas are documented explicitly: signing-provider operation receipts can use an HTTPS signing gateway, built-in AWS KMS, GCP Cloud KMS, or Azure Key Vault executors, and `pkcs11-hsm` remains gateway-backed because native HSM modules are deployment-specific; deployment-specific custody review remains operator work. SSO credential exchange uses configured local OIDC/SAML trust material and session-scoped OIDC group-role mappings, and provider verification can optionally call OIDC UserInfo or an operator-controlled provider validation gateway when a caller supplies an access token, but the gateway receives only non-secret metadata and this does not replace direct provider-specific management API clients or external group synchronization. Public transparency records can verify operator-supplied proof material, fetch from configured endpoints, or use an operator-controlled transparency proof gateway without replacing provider-specific trust review. +Implemented-but-partial areas are documented explicitly: signing-provider operation receipts can use an HTTPS signing gateway, built-in AWS KMS, GCP Cloud KMS, or Azure Key Vault executors, `pkcs11-hsm` remains gateway-backed because native HSM modules are deployment-specific, and `native_pkcs11_hsm` provider records plus custody-review reports capture operator-supplied HSM profile evidence without loading modules or proving custody. SSO credential exchange uses configured local OIDC/SAML trust material and session-scoped OIDC group-role mappings, and provider verification can optionally call OIDC UserInfo or an operator-controlled provider validation gateway when a caller supplies an access token, but the gateway receives only non-secret metadata and this does not replace direct provider-specific management API clients or external group synchronization. Public transparency records can verify operator-supplied proof material, fetch from configured endpoints, or use an operator-controlled transparency proof gateway without replacing provider-specific trust review. ## License, Security, Support, And Governance diff --git a/docs/api.md b/docs/api.md index 3f51eb7..a23a4d0 100644 --- a/docs/api.md +++ b/docs/api.md @@ -493,6 +493,7 @@ presets; preset policy fields cannot be overridden in the create request. | `POST` | `/v1/legal-holds` | Record legal hold. | | `POST` | `/v1/retention-overrides` | Record retention override. | | `GET` | `/v1/reports/retention` | List retention records. | +| `GET` | `/v1/reports/custody-review` | Review tenant signing-provider and object-lock verification metadata for deployment custody review. | | `POST` | `/v1/backup-manifests` | Generate backup manifest. | | `GET` | `/v1/backup-manifests/{id}/verify` | Verify backup manifest. | diff --git a/docs/architecture.md b/docs/architecture.md index ff08463..a1952dc 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -52,6 +52,6 @@ Air-gapped import-bundle workflows preserve the same tenant-scoped import path a ## Limitations -The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, built-in AWS KMS, GCP Cloud KMS, and Azure Key Vault signing executors, gateway-backed `pkcs11-hsm` mode, OIDC discovery refresh, optional live OIDC UserInfo validation, an optional provider validation gateway, SSO credential exchange with session-scoped OIDC group-role mapping, public-transparency proof fetching, an optional transparency proof gateway, and optional worker-owned parser side effects are implemented, but native PKCS#11/HSM module handling, direct provider-specific management API clients, and external group synchronization remain deployment hardening work. Hand-tuned per-resource repository implementations remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, unsupported API writer modes or replica counts above one, local plaintext signing-key mode, and bootstrap secret printing. +The in-process store remains available only when `EVYDENCE_DATABASE_URL` is unset. S3/MinIO runtime object storage is available through the object-store port. Signing-provider operation receipts, an optional HTTPS signing gateway executor, built-in AWS KMS, GCP Cloud KMS, and Azure Key Vault signing executors, gateway-backed `pkcs11-hsm` mode, native PKCS#11/HSM custody profile records, OIDC discovery refresh, optional live OIDC UserInfo validation, an optional provider validation gateway, SSO credential exchange with session-scoped OIDC group-role mapping, public-transparency proof fetching, an optional transparency proof gateway, and optional worker-owned parser side effects are implemented, but native HSM module loading/execution, direct provider-specific management API clients, and external group synchronization remain deployment hardening work. Hand-tuned per-resource repository implementations remain production-readiness work. `ENV=production` rejects the in-process store, default API-key pepper, unsupported API writer modes or replica counts above one, local plaintext signing-key mode, and bootstrap secret printing. Evydence does not prove provider truth, scanner authority, runtime security, legal compliance, or release security by itself. diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index 081eee5..3981a9e 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 175 operations: 175 precise, 0 broad. +Generated from 176 operations: 176 precise, 0 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -128,6 +128,7 @@ Generated from 175 operations: 175 precise, 0 broad. | GET | /v1/reports/cra-readiness | craReadinessReport | Bearer | report:read | - | query:product_id, query:release_id | - | 200:application/json:ReadinessReportEnvelope | precise | | GET | /v1/reports/cra-readiness-html | craReadinessHTMLPackage | Bearer | report:read | - | query:product_id, query:release_id | - | 200:application/json:HTMLReportPackageEnvelope | precise | | GET | /v1/reports/cra-vulnerability-handling | craVulnerabilityHandlingReport | Bearer | report:read | - | query:product_id, query:release_id | - | 200:application/json:CRAVulnerabilityHandlingReportEnvelope | precise | +| GET | /v1/reports/custody-review | signingCustodyReviewReport | Bearer | keys:admin | - | - | - | 200:application/json:SigningCustodyReviewReportEnvelope | precise | | GET | /v1/reports/incident-package | incidentReport | Bearer | incident:read | - | query:incident_id | - | 200:application/json:IncidentReportEnvelope | precise | | GET | /v1/reports/missing-evidence | missingEvidenceReport | Bearer | verify:read | - | query:release_id | - | 200:application/json:MissingEvidenceReportEnvelope | precise | | POST | /v1/reports/pdf | createPDFReportPackage | Bearer | report:read | required | - | application/json:CreatePDFReportPackageRequest | 201:application/json:PDFReportPackageEnvelope | precise | diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index c902cac..cb4b292 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -148,6 +148,13 @@ native HSM modules and slots are deployment-specific. Operators remain responsible for provider credentials, IAM, key lifecycle, gateway operation where used, and custody review. +Tenant signing-provider records also accept `native_pkcs11_hsm` for deployments +that operate local PKCS#11 modules or slots outside Evydence. The provider +`key_ref` must be a `pkcs11:` URI and must not embed PIN values, PIN sources, +passwords, or secrets. This profile records custody evidence for review through +`GET /v1/reports/custody-review`; it does not load native HSM modules or prove +hardware custody by itself. + When `EVYDENCE_SIGNING_KEY_MODE=aws-kms`, Evydence uses the AWS KMS `Sign` operation against `EVYDENCE_AWS_KMS_KEY_ID`. The executor signs the decoded SHA-256 digest with KMS `MessageType=DIGEST`; it does not send raw evidence diff --git a/docs/reference/customer-package-manifest.md b/docs/reference/customer-package-manifest.md index bf2660b..2431ee1 100644 --- a/docs/reference/customer-package-manifest.md +++ b/docs/reference/customer-package-manifest.md @@ -36,6 +36,8 @@ matching release-scoped records exist: - `approvals`: release or product approval records. - `exceptions`: approved, unexpired release exceptions. - `waivers`: approved, unexpired product or release waivers. +- `object_lock_proofs`: tenant object-retention verification records, included + only when the profile explicitly allows `object_lock_proof`. - `provenance`: build runs and build attestation metadata. The `api_contracts` section contains `openapi_contracts` and `contract_diffs`. @@ -56,6 +58,12 @@ SSO/session token hashes, and tenant-internal vulnerability decision notes. Customer-visible vulnerability decisions require `impact_statement`; internal notes are not copied into `vulnerability_decisions`. +`object_lock_proofs` entries include policy identifiers, object-scope presence +indicators, retention mode/days, verification checks, verification hash, and +limitations. They do not include raw object payloads, object-store paths, or +storage credentials, and they do not prove legal compliance, IAM correctness, +lifecycle policy completeness, or complete WORM enforcement. + ## Customer-Safe Gaps `customer_safe_gaps` contains factual missing-evidence records only when the @@ -91,14 +99,14 @@ the matching archive fixture is Runtime ZIP exports also include `report.html`, a self-contained static HTML rendering of the redacted manifest. It shows release summary, VEX and vulnerability-decision tables, questionnaire answer-library entries when -included, API contract evidence when included, readiness checks, verification -material, limitations, and non-claims without requiring a server or loading -remote assets. Portal ZIP downloads can also include `WATERMARK.txt` and a -visible report watermark for customer-specific distribution. The watermark is -not a secret and does not change the canonical package manifest hash. The HTML -report is generated from package-scoped data only and excludes raw evidence -payload bytes, object-store references, token material, private keys, and -internal decision notes. +included, object-lock proof records when included, API contract evidence when +included, readiness checks, verification material, limitations, and non-claims +without requiring a server or loading remote assets. Portal ZIP downloads can +also include `WATERMARK.txt` and a visible report watermark for +customer-specific distribution. The watermark is not a secret and does not +change the canonical package manifest hash. The HTML report is generated from +package-scoped data only and excludes raw evidence payload bytes, object-store +references, token material, private keys, and internal decision notes. ## Redaction Leakage Guard diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index a48a3b6..34e3094 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -63,10 +63,11 @@ Known hardening work remains: parameters, and request/response schemas; - production signing can use the HTTPS signing gateway executor, built-in AWS KMS, GCP Cloud KMS, Azure Key Vault signing executors, or gateway-backed - `pkcs11-hsm`, but native PKCS#11/HSM module custody, direct - provider-specific management API clients/group synchronization, and broad - object-lock enforcement proof beyond bucket plus sample-object - retention/legal-hold checks remain provider- and deployment-dependent + `pkcs11-hsm`. Tenant records can also capture a `native_pkcs11_hsm` custody + profile and a custody-review report, but native module loading/execution, + direct provider-specific management API clients/group synchronization, and + broad object-lock enforcement proof beyond recorded bucket plus sample-object + retention/legal-hold metadata remain provider- and deployment-dependent hardening areas. SSO credential exchange can issue bearer sessions and HttpOnly cookies after local OIDC/SAML verification against configured trust material, OIDC group claim values can map to session-scoped roles without @@ -217,11 +218,12 @@ because they are hardening work on already implemented capabilities: PostgreSQL store supports them. - Keep OpenAPI precision at zero broad operations as routes are added or changed, and expand generated SDK coverage from the committed contract. -- Add native PKCS#11/HSM module support where required by the deployment +- Add native PKCS#11/HSM module execution where required by the deployment profile. The current HTTPS signing gateway executor covers deployments that put HSM custody behind a tenant-controlled signing service and do not send raw - payload bytes. AWS KMS, GCP Cloud KMS, and Azure Key Vault direct executors - sign stored SHA-256 payload hashes through their provider APIs. + payload bytes, while `native_pkcs11_hsm` records capture review metadata only. + AWS KMS, GCP Cloud KMS, and Azure Key Vault direct executors sign stored + SHA-256 payload hashes through their provider APIs. - Complete direct provider-specific management API clients and external group synchronization where those profiles are enabled. OIDC discovery/JWKS refresh is implemented for public trust-material updates, manual JWKS and SAML diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 96afdf5..21feacc 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -562,6 +562,26 @@ func registerCriticalSchemas(registry *specs.Registry) { "created_at": map[string]any{"type": "string", "format": "date-time"}, }, "id", "tenant_id", "name", "type", "status", "key_ref", "encrypted", "schema_version", "created_at")) registry.RegisterSchema("SigningProviderEnvelope", dataEnvelopeSchema("#/components/schemas/SigningProvider")) + registry.RegisterSchema("SigningCustodyReviewReport", objectSchema(map[string]any{ + "report_type": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "signing_providers": map[string]any{ + "type": "array", + "items": map[string]any{"$ref": "#/components/schemas/SigningProvider"}, + }, + "object_retention_policies": map[string]any{ + "type": "array", + "items": map[string]any{"$ref": "#/components/schemas/ObjectRetentionPolicy"}, + }, + "checks": map[string]any{ + "type": "array", + "items": map[string]any{"$ref": "#/components/schemas/VerifyCheck"}, + }, + "assumptions": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "generated_at": map[string]any{"type": "string", "format": "date-time"}, + }, "report_type", "tenant_id", "checks", "assumptions", "limitations", "generated_at")) + registry.RegisterSchema("SigningCustodyReviewReportEnvelope", dataEnvelopeSchema("#/components/schemas/SigningCustodyReviewReport")) registry.RegisterSchema("CreateSigningOperationRequest", objectSchema(map[string]any{ "provider_id": map[string]any{"type": "string"}, "subject_type": map[string]any{"type": "string"}, diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index bfb9f34..4b9fae6 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -726,6 +726,9 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Parameters = append(operation.Parameters, pathParam("id", "Object retention policy id.")) operation.RequestBody = jsonRequest("Empty JSON object.", "#/components/schemas/EmptyObject") operation.Responses[http.StatusOK] = jsonResponse("Verified object retention policy envelope.", "#/components/schemas/ObjectRetentionPolicyEnvelope") + case "signingCustodyReviewReport": + operation.Description = "Returns tenant signing-provider and object-lock verification metadata for deployment custody review. It is evidence metadata only, not legal compliance proof, certification, HSM custody proof, or a secure-deployment guarantee." + operation.Responses[http.StatusOK] = jsonResponse("Signing custody review report envelope.", "#/components/schemas/SigningCustodyReviewReportEnvelope") case "createLegalHold": operation.Description = "Creates an append-only legal-hold marker for a tenant-scoped retention subject." operation.RequestBody = jsonRequest("Legal hold creation request.", "#/components/schemas/CreateLegalHoldRequest") diff --git a/internal/adapters/httpapi/route_registration.go b/internal/adapters/httpapi/route_registration.go index 4311ffa..eee4d23 100644 --- a/internal/adapters/httpapi/route_registration.go +++ b/internal/adapters/httpapi/route_registration.go @@ -256,6 +256,7 @@ func (s *Server) integrityOpsRoutes() []routeDef { {http.MethodPost, "/v1/legal-holds", op("createLegalHold", http.MethodPost, "/v1/legal-holds", "Create legal hold", []string{app.ScopeAdmin}), http.HandlerFunc(s.createLegalHold)}, {http.MethodPost, "/v1/retention-overrides", op("createRetentionOverride", http.MethodPost, "/v1/retention-overrides", "Create retention override", []string{app.ScopeAdmin}), http.HandlerFunc(s.createRetentionOverride)}, {http.MethodGet, "/v1/reports/retention", op("retentionReport", http.MethodGet, "/v1/reports/retention", "Retention report", []string{app.ScopeAdmin}), http.HandlerFunc(s.retentionReport)}, + {http.MethodGet, "/v1/reports/custody-review", op("signingCustodyReviewReport", http.MethodGet, "/v1/reports/custody-review", "Signing custody review report", []string{app.ScopeKeysAdmin}), http.HandlerFunc(s.signingCustodyReviewReport)}, {http.MethodPost, "/v1/backup-manifests", op("generateBackupManifest", http.MethodPost, "/v1/backup-manifests", "Generate backup manifest", []string{app.ScopeAdmin}), http.HandlerFunc(s.generateBackupManifest)}, {http.MethodGet, "/v1/backup-manifests/{id}/verify", op("verifyBackupManifest", http.MethodGet, "/v1/backup-manifests/{id}/verify", "Verify backup manifest", []string{app.ScopeVerifyRead}), http.HandlerFunc(s.verifyBackupManifest)}, } diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index d94851f..ccb252c 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -1991,6 +1991,19 @@ func (s *Server) verifyObjectRetentionPolicy(w http.ResponseWriter, r *http.Requ }) } +func (s *Server) signingCustodyReviewReport(w http.ResponseWriter, r *http.Request) { + actor, ok := s.authenticate(w, r) + if !ok { + return + } + report, err := s.ledger.SigningCustodyReviewReport(r.Context(), actor) + if err != nil { + writeProblem(w, r, err) + return + } + writeData(w, http.StatusOK, report) +} + func (s *Server) generateBackupManifest(w http.ResponseWriter, r *http.Request) { s.create(w, r, func(ctx requestContext, actor domain.Actor, _ []byte) (int, any, error) { manifest, err := s.ledger.GenerateBackupManifest(ctx, actor) diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index e9269b3..4bc8af4 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -94,7 +94,7 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { if _, ok := redactionRequestProps["preset"]; !ok { t.Fatalf("redaction profile request schema missing preset: %#v", redactionRequestProps) } - for _, schemaName := range []string{"ReadinessStatusEnvelope", "BackupManifestEnvelope", "VerificationResultEnvelope", "ReadinessReportEnvelope", "CRAVulnerabilityHandlingReportEnvelope", "SecurityUpdateEvidenceReportEnvelope", "CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "ReleaseEvidenceFlowEnvelope", "ReleaseSecuritySummaryEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "VEXImportReportEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "VulnerabilityDecisionListEnvelope", "VulnerabilityDecisionSummaryReportEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "UpdateSSOProviderTrustMaterialRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "ExchangeSSOCredentialRequest", "SSOCredentialExchangeEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "QuestionnaireAnswerLibraryEntryEnvelope", "QuestionnaireAnswerLibraryEntryListEnvelope", "DataEnvelope"} { + for _, schemaName := range []string{"ReadinessStatusEnvelope", "BackupManifestEnvelope", "VerificationResultEnvelope", "ReadinessReportEnvelope", "CRAVulnerabilityHandlingReportEnvelope", "SecurityUpdateEvidenceReportEnvelope", "SigningCustodyReviewReportEnvelope", "CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "ReleaseEvidenceFlowEnvelope", "ReleaseSecuritySummaryEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "VEXImportReportEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "VulnerabilityDecisionListEnvelope", "VulnerabilityDecisionSummaryReportEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "UpdateSSOProviderTrustMaterialRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "ExchangeSSOCredentialRequest", "SSOCredentialExchangeEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "QuestionnaireAnswerLibraryEntryEnvelope", "QuestionnaireAnswerLibraryEntryListEnvelope", "DataEnvelope"} { if _, ok := schemas[schemaName]; !ok { t.Fatalf("schema %s missing from OpenAPI components", schemaName) } @@ -121,6 +121,8 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { securityUpdateEvidence := operationMap(t, paths, "/v1/reports/security-update-evidence", "get") assertQueryParams(t, securityUpdateEvidence, "product_id", "release_id") assertResponseRef(t, securityUpdateEvidence, "200", "#/components/schemas/SecurityUpdateEvidenceReportEnvelope") + custodyReview := operationMap(t, paths, "/v1/reports/custody-review", "get") + assertResponseRef(t, custodyReview, "200", "#/components/schemas/SigningCustodyReviewReportEnvelope") createProduct := operationMap(t, paths, "/v1/products", "post") assertRequestRef(t, createProduct, "#/components/schemas/CreateProductRequest") assertResponseRef(t, createProduct, "201", "#/components/schemas/ProductEnvelope") @@ -518,6 +520,7 @@ func TestAuthenticatedReadRoutesRejectMissingBearerToken(t *testing.T) { "/v1/reports/cra-readiness", "/v1/reports/cra-readiness-html", "/v1/reports/cra-vulnerability-handling", + "/v1/reports/custody-review", "/v1/reports/incident-package", "/v1/reports/missing-evidence", "/v1/reports/retention", @@ -804,6 +807,10 @@ func TestIntegrityRuntimeHTTPFlow(t *testing.T) { retentionBody := postJSON(t, server, secret, "/v1/object-retention-policies", "int-retention", map[string]any{"name": "lock", "mode": "governance", "retention_days": 30}, http.StatusCreated) retentionID := dataField(t, retentionBody, "id") postJSON(t, server, secret, "/v1/object-retention-policies/"+retentionID+"/verify", "int-retention-verify", map[string]any{}, http.StatusOK) + custodyReview := getJSON(t, server, secret, "/v1/reports/custody-review", http.StatusOK) + if !strings.Contains(custodyReview, `"report_type":"signing_custody_review"`) || !strings.Contains(custodyReview, `"object_lock_proof_recorded"`) || strings.Contains(custodyReview, "private_key") { + t.Fatalf("custody review response missing checks or leaked sensitive wording: %s", custodyReview) + } backupBody := postJSON(t, server, secret, "/v1/backup-manifests", "int-backup", map[string]any{}, http.StatusCreated) backupID := dataField(t, backupBody, "id") backupVerify := getJSON(t, server, secret, "/v1/backup-manifests/"+backupID+"/verify", http.StatusOK) diff --git a/internal/app/context_cancellation_test.go b/internal/app/context_cancellation_test.go index b363b57..336ba8b 100644 --- a/internal/app/context_cancellation_test.go +++ b/internal/app/context_cancellation_test.go @@ -387,6 +387,7 @@ func TestLedgerOperationsHonorCanceledContextBeforeWork(t *testing.T) { return err }}, {"VerifyObjectRetentionPolicy", func() error { _, err := ledger.VerifyObjectRetentionPolicy(ctx, actor, "policy"); return err }}, + {"SigningCustodyReviewReport", func() error { _, err := ledger.SigningCustodyReviewReport(ctx, actor); return err }}, {"GenerateBackupManifest", func() error { _, err := ledger.GenerateBackupManifest(ctx, actor); return err }}, {"VerifyBackupManifest", func() error { _, err := ledger.VerifyBackupManifest(ctx, actor, "backup"); return err }}, {"ReadinessStatus", func() error { _, err := ledger.ReadinessStatus(ctx); return err }}, @@ -728,6 +729,7 @@ func TestLedgerOperationsRejectActorsWithoutRequiredScopesBeforeResourceWork(t * return err }}, {"VerifyObjectRetentionPolicy", func() error { _, err := ledger.VerifyObjectRetentionPolicy(ctx, actor, "policy"); return err }}, + {"SigningCustodyReviewReport", func() error { _, err := ledger.SigningCustodyReviewReport(ctx, actor); return err }}, {"GenerateBackupManifest", func() error { _, err := ledger.GenerateBackupManifest(ctx, actor); return err }}, {"VerifyBackupManifest", func() error { _, err := ledger.VerifyBackupManifest(ctx, actor, "backup"); return err }}, {"Metrics", func() error { _, err := ledger.Metrics(ctx, actor); return err }}, diff --git a/internal/app/governance_packages.go b/internal/app/governance_packages.go index ae64331..84681b8 100644 --- a/internal/app/governance_packages.go +++ b/internal/app/governance_packages.go @@ -103,6 +103,7 @@ var redactionProfilePresets = map[string]redactionProfilePreset{ "release_bundle", "approval", "exception", + "object_lock_proof", "waiver", }, ExcludedFields: []string{ @@ -138,6 +139,7 @@ var redactionProfilePresets = map[string]redactionProfilePreset{ "exception", "license_scan", "manual_security_document", + "object_lock_proof", "openapi_contract", "pen_test_report", "release_bundle", @@ -462,6 +464,9 @@ func (l *Ledger) customerPackageManifestLocked(packageID string, generatedAt tim if profileAllowsPackageType(profile, "answer_library") { manifest["answer_library"] = l.packageAnswerLibraryMetadataLocked(tenantID, productID, releaseID) } + if profileAllowsPackageType(profile, "object_lock_proof") { + manifest["object_lock_proofs"] = l.packageObjectLockProofsLocked(tenantID) + } if profileAllowsPackageType(profile, "build") || profileAllowsPackageType(profile, "build_attestation") { manifest["provenance"] = l.packageProvenanceMetadataLocked(tenantID, releaseID, profile) } @@ -864,6 +869,52 @@ func (l *Ledger) packageAnswerLibraryMetadataLocked(tenantID, productID, release return out } +func (l *Ledger) packageObjectLockProofsLocked(tenantID string) []map[string]any { + out := []map[string]any{} + for _, policy := range l.retentionPolicies { + if policy.TenantID != tenantID { + continue + } + proof := map[string]any{ + "id": policy.ID, + "name": policy.Name, + "object_prefix_configured": policy.ObjectPrefix != "", + "sample_object_key_configured": policy.ObjectKey != "", + "require_legal_hold": policy.RequireLegalHold, + "mode": policy.Mode, + "retention_days": policy.RetentionDays, + "status": policy.Status, + "verification_hash": policy.VerificationHash, + "verification_checks": packageVerifyChecks(policy.VerificationChecks), + "verification_limitations": append([]string(nil), policy.VerificationLimitations...), + "created_at": policy.CreatedAt.UTC().Format(time.RFC3339), + "limitations": []string{ + "Object-lock proof records show configured Evydence verification results for tenant object-storage settings only.", + "They do not prove external WORM enforcement, IAM policy, lifecycle policy, backup behavior, or legal compliance.", + }, + } + if policy.VerifiedAt != nil { + proof["verified_at"] = policy.VerifiedAt.UTC().Format(time.RFC3339) + } + out = append(out, proof) + } + sortManifestMapsByID(out) + return out +} + +func packageVerifyChecks(checks []domain.VerifyCheck) []map[string]any { + out := make([]map[string]any, 0, len(checks)) + for _, check := range checks { + out = append(out, map[string]any{"name": check.Name, "result": check.Result, "detail": check.Detail}) + } + sort.Slice(out, func(i, j int) bool { + left, _ := out[i]["name"].(string) + right, _ := out[j]["name"].(string) + return left < right + }) + return out +} + func (l *Ledger) packageProvenanceMetadataLocked(tenantID, releaseID string, profile domain.RedactionProfile) map[string]any { builds := []map[string]any{} buildIDs := map[string]bool{} @@ -1299,6 +1350,7 @@ func customerPackageHTMLReport(pkg domain.CustomerSecurityPackage, metadata, ver vexDocuments := packageHTMLRecords(manifest["vex_documents"]) decisions := packageHTMLRecords(manifest["vulnerability_decisions"]) answerLibrary := packageHTMLRecords(manifest["answer_library"]) + objectLockProofs := packageHTMLRecords(manifest["object_lock_proofs"]) limitations := packageHTMLStrings(manifest["limitations"]) nonClaims := packageHTMLStrings(manifest["non_claims"]) @@ -1355,6 +1407,17 @@ func customerPackageHTMLReport(pkg domain.CustomerSecurityPackage, metadata, ver b.WriteString("") } + b.WriteString("

Object-Lock Proofs

") + if len(objectLockProofs) == 0 { + b.WriteString("

No customer-visible object-lock proof records are included by this package profile.

") + } else { + b.WriteString("") + for _, record := range objectLockProofs { + b.WriteString("") + } + b.WriteString("
IDStatusModeRetention DaysVerification Hash
" + packageHTMLEscape(packageHTMLString(record["id"])) + "" + packageHTMLEscape(packageHTMLString(record["status"])) + "" + packageHTMLEscape(packageHTMLString(record["mode"])) + "" + packageHTMLEscape(packageHTMLString(record["retention_days"])) + "" + packageHTMLEscape(packageHTMLString(record["verification_hash"])) + "
") + } + b.WriteString("

API Contract Evidence

") contractRecords := packageHTMLRecords(apiContracts["openapi_contracts"]) diffRecords := packageHTMLRecords(apiContracts["contract_diffs"]) @@ -1708,7 +1771,16 @@ func (s packageReportService) ExportEvidenceBundle(ctx context.Context, actor do if entries := l.chain[actor.TenantID]; len(entries) > 0 { head = entries[len(entries)-1].EntryHash } - manifest := map[string]any{"bundle_version": domain.EvidenceBundleSchemaVersion, "tenant_id": actor.TenantID, "release_id": releaseID, "evidence_ids": ids, "audit_chain_head": head, "verification": "Run evydence verify-evidence-bundle offline."} + manifest := map[string]any{ + "bundle_version": domain.EvidenceBundleSchemaVersion, + "tenant_id": actor.TenantID, + "release_id": releaseID, + "evidence_ids": ids, + "audit_chain_head": head, + "object_lock_proofs": l.packageObjectLockProofsLocked(actor.TenantID), + "verification": "Run evydence verify-evidence-bundle offline.", + "verification_limits": []string{"Object-lock proof records reflect Evydence verification metadata and do not prove legal compliance, provider IAM correctness, or complete WORM enforcement."}, + } hash, err := canonicalAnyHash(manifest) if err != nil { return domain.EvidenceBundle{}, err diff --git a/internal/app/integrity_runtime.go b/internal/app/integrity_runtime.go index 54a6999..b9c56b3 100644 --- a/internal/app/integrity_runtime.go +++ b/internal/app/integrity_runtime.go @@ -2,6 +2,7 @@ package app import ( "context" + "sort" "strings" "time" @@ -165,6 +166,12 @@ func (l *Ledger) CreateSigningProvider(ctx context.Context, actor domain.Actor, if in.Type == "local_encrypted_dev" && !in.Encrypted { return domain.SigningProvider{}, ErrValidation } + if in.Type == "native_pkcs11_hsm" && (!in.Encrypted || !strings.HasPrefix(in.KeyRef, "pkcs11:")) { + return domain.SigningProvider{}, ErrValidation + } + if in.Type == "native_pkcs11_hsm" && signingProviderRefContainsSecret(in.KeyRef) { + return domain.SigningProvider{}, ErrValidation + } l.mu.Lock() defer l.mu.Unlock() provider := domain.SigningProvider{ID: newID("sp"), TenantID: actor.TenantID, Name: in.Name, Type: in.Type, Status: "active", KeyRef: in.KeyRef, Encrypted: in.Encrypted, SchemaVersion: domain.SigningProviderSchemaVersion, CreatedAt: l.now()} @@ -419,6 +426,65 @@ func (l *Ledger) VerifyObjectRetentionPolicy(ctx context.Context, actor domain.A return policy, nil } +func (l *Ledger) SigningCustodyReviewReport(ctx context.Context, actor domain.Actor) (domain.SigningCustodyReviewReport, error) { + if err := ctx.Err(); err != nil { + return domain.SigningCustodyReviewReport{}, err + } + if err := require(actor, ScopeKeysAdmin); err != nil { + return domain.SigningCustodyReviewReport{}, err + } + l.mu.Lock() + defer l.mu.Unlock() + providers := []domain.SigningProvider{} + hasProductionProvider := false + hasNativePKCS11 := false + for _, provider := range l.signingProviders { + if provider.TenantID != actor.TenantID { + continue + } + providers = append(providers, provider) + if provider.Type != "local_encrypted_dev" { + hasProductionProvider = true + } + if provider.Type == "native_pkcs11_hsm" { + hasNativePKCS11 = true + } + } + sort.Slice(providers, func(i, j int) bool { return providers[i].ID < providers[j].ID }) + retentionPolicies := []domain.ObjectRetentionPolicy{} + hasVerifiedRetention := false + for _, policy := range l.retentionPolicies { + if policy.TenantID != actor.TenantID { + continue + } + retentionPolicies = append(retentionPolicies, policy) + if policy.Status == "verified" && policy.VerificationHash != "" { + hasVerifiedRetention = true + } + } + sort.Slice(retentionPolicies, func(i, j int) bool { return retentionPolicies[i].ID < retentionPolicies[j].ID }) + return domain.SigningCustodyReviewReport{ + ReportType: "signing_custody_review", + TenantID: actor.TenantID, + SigningProviders: providers, + ObjectRetentionPolicies: retentionPolicies, + Checks: []domain.VerifyCheck{ + {Name: "production_signing_provider_recorded", Result: checkResultString(hasProductionProvider), Detail: "At least one non-local signing provider is recorded for the tenant."}, + {Name: "native_pkcs11_hsm_profile_recorded", Result: checkResultString(hasNativePKCS11), Detail: "A native PKCS#11/HSM custody profile is recorded when the deployment uses local HSM modules or slots."}, + {Name: "object_lock_proof_recorded", Result: checkResultString(hasVerifiedRetention), Detail: "At least one object-retention policy has provider verification hash material."}, + }, + Assumptions: []string{ + "Custody review uses Evydence records and configured provider verification receipts.", + "Native PKCS#11/HSM records describe operator-supplied module and key references; Evydence does not load HSM modules in this API process.", + }, + Limitations: []string{ + "This report does not prove legal compliance, certification, HSM hardware custody, WORM enforcement, or deployment security.", + "Operators remain responsible for HSM driver installation, slot access controls, IAM policy, object-store retention settings, and independent review.", + }, + GeneratedAt: l.now(), + }, nil +} + func (l *Ledger) GenerateBackupManifest(ctx context.Context, actor domain.Actor) (domain.BackupManifest, error) { if err := ctx.Err(); err != nil { return domain.BackupManifest{}, err @@ -632,9 +698,19 @@ func merkleRoot(leaves []string) string { func validSigningProviderType(value string) bool { switch value { - case "local_encrypted_dev", "aws_kms", "gcp_kms", "azure_key_vault", "pkcs11_hsm": + case "local_encrypted_dev", "aws_kms", "gcp_kms", "azure_key_vault", "pkcs11_hsm", "native_pkcs11_hsm": return true default: return false } } + +func signingProviderRefContainsSecret(value string) bool { + lowered := strings.ToLower(value) + for _, marker := range []string{"pin-value=", "pin-source=", "password=", "secret=", "token=" + "secret"} { + if strings.Contains(lowered, marker) { + return true + } + } + return false +} diff --git a/internal/app/integrity_runtime_test.go b/internal/app/integrity_runtime_test.go index 08a076e..0930af0 100644 --- a/internal/app/integrity_runtime_test.go +++ b/internal/app/integrity_runtime_test.go @@ -173,6 +173,93 @@ func TestObjectRetentionVerifierRecordsProviderChecks(t *testing.T) { } } +func TestSigningCustodyReviewAndObjectLockProofExports(t *testing.T) { + verifier := &fakeObjectRetentionVerifier{result: ObjectRetentionResult{ + Provider: "s3", + Enforced: true, + Checks: []domain.VerifyCheck{ + {Name: "s3_bucket_versioning", Result: "passed"}, + {Name: "s3_object_lock_mode", Result: "passed"}, + }, + Limitations: []string{"Operator must review bucket IAM, lifecycle, and legal requirements."}, + }} + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow, Retention: verifier}) + ctx := context.Background() + actor, release, _ := setupReleaseRiskFixture(t, ledger) + + if _, err := ledger.CreateSigningProvider(ctx, actor, CreateSigningProviderInput{Name: "bad native", Type: "native_pkcs11_hsm", KeyRef: "pkcs11:token=release;object=key;pin-value=1234", Encrypted: true}); !errors.Is(err, ErrValidation) { + t.Fatalf("native provider with embedded PIN err=%v, want validation", err) + } + if _, err := ledger.CreateSigningProvider(ctx, actor, CreateSigningProviderInput{Name: "bad native", Type: "native_pkcs11_hsm", KeyRef: "pkcs11:token=release;object=key"}); !errors.Is(err, ErrValidation) { + t.Fatalf("unencrypted native provider err=%v, want validation", err) + } + provider, err := ledger.CreateSigningProvider(ctx, actor, CreateSigningProviderInput{Name: "native hsm", Type: "native_pkcs11_hsm", KeyRef: "pkcs11:token=release;object=evydence-signing-key", Encrypted: true}) + if err != nil { + t.Fatalf("native provider: %v", err) + } + policy, err := ledger.CreateObjectRetentionPolicy(ctx, actor, CreateObjectRetentionPolicyInput{Name: "release objects", ObjectPrefix: "tenants/" + actor.TenantID + "/raw/", Mode: "compliance", RetentionDays: 180}) + if err != nil { + t.Fatalf("retention policy: %v", err) + } + verified, err := ledger.VerifyObjectRetentionPolicy(ctx, actor, policy.ID) + if err != nil { + t.Fatalf("verify retention: %v", err) + } + report, err := ledger.SigningCustodyReviewReport(ctx, actor) + if err != nil { + t.Fatalf("custody report: %v", err) + } + if report.ReportType != "signing_custody_review" || len(report.SigningProviders) != 1 || report.SigningProviders[0].ID != provider.ID { + t.Fatalf("custody report providers = %#v", report) + } + if len(report.ObjectRetentionPolicies) != 1 || report.ObjectRetentionPolicies[0].VerificationHash != verified.VerificationHash { + t.Fatalf("custody report retention policies = %#v", report.ObjectRetentionPolicies) + } + for _, want := range []string{"production_signing_provider_recorded", "native_pkcs11_hsm_profile_recorded", "object_lock_proof_recorded"} { + if !hasVerifyCheck(report.Checks, want, "passed") { + t.Fatalf("custody report missing passed check %q: %#v", want, report.Checks) + } + } + if !strings.Contains(strings.Join(report.Limitations, "\n"), "does not prove legal compliance") || strings.Contains(strings.Join(report.Limitations, "\n"), "certified secure") { + t.Fatalf("unsafe custody limitations: %#v", report.Limitations) + } + + profile, err := ledger.CreateRedactionProfile(ctx, actor, CreateRedactionProfileInput{Name: "object lock proof", AllowedTypes: []string{"object_lock_proof"}}) + if err != nil { + t.Fatalf("profile: %v", err) + } + pkg, err := ledger.CreateCustomerSecurityPackage(ctx, actor, CreateCustomerPackageInput{ProductID: release.ProductID, ReleaseID: release.ID, RedactionProfileID: profile.ID, Title: "Object-lock proof package", ExpiresAt: fixedNow().Add(time.Hour)}) + if err != nil { + t.Fatalf("package: %v", err) + } + proofs, ok := pkg.Manifest["object_lock_proofs"].([]map[string]any) + if !ok || len(proofs) != 1 || proofs[0]["verification_hash"] != verified.VerificationHash { + t.Fatalf("package object-lock proofs = %#v", pkg.Manifest["object_lock_proofs"]) + } + if _, ok := proofs[0]["object_key"]; ok { + t.Fatalf("customer package object-lock proof exposed object key: %#v", proofs[0]) + } + limitations, _ := proofs[0]["limitations"].([]string) + if strings.Contains(strings.Join(limitations, "\n"), "secure release") { + t.Fatalf("object-lock proof made unsafe claim: %#v", proofs[0]) + } + + bundle, err := ledger.CreateReleaseBundle(ctx, actor, release.ID) + if err != nil { + t.Fatalf("release bundle: %v", err) + } + if proofs, ok := bundle.Manifest["object_lock_proofs"].([]map[string]any); !ok || len(proofs) != 1 || proofs[0]["verification_hash"] != verified.VerificationHash { + t.Fatalf("release bundle object-lock proofs = %#v", bundle.Manifest["object_lock_proofs"]) + } + evidenceBundle, err := ledger.ExportEvidenceBundle(ctx, actor, release.ID, nil) + if err != nil { + t.Fatalf("evidence bundle: %v", err) + } + if proofs, ok := evidenceBundle.Manifest["object_lock_proofs"].([]map[string]any); !ok || len(proofs) != 1 || proofs[0]["verification_hash"] != verified.VerificationHash { + t.Fatalf("evidence bundle object-lock proofs = %#v", evidenceBundle.Manifest["object_lock_proofs"]) + } +} + func TestObjectRetentionVerifierReceivesLegalHoldRequirement(t *testing.T) { verifier := &fakeObjectRetentionVerifier{result: ObjectRetentionResult{ Provider: "s3", diff --git a/internal/app/ledger.go b/internal/app/ledger.go index 638904b..e780a2b 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -1260,6 +1260,7 @@ func (l *Ledger) CreateReleaseBundle(ctx context.Context, actor domain.Actor, re "name": "evydence", "version": "dev", }, + "object_lock_proofs": l.packageObjectLockProofsLocked(actor.TenantID), } manifestHash, err := canonicalAnyHash(manifest) if err != nil { diff --git a/internal/domain/domain.go b/internal/domain/domain.go index 457fb19..c18cd3a 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -821,6 +821,17 @@ type ObjectRetentionPolicy struct { CreatedAt time.Time `json:"created_at"` } +type SigningCustodyReviewReport struct { + ReportType string `json:"report_type"` + TenantID string `json:"tenant_id"` + SigningProviders []SigningProvider `json:"signing_providers,omitempty"` + ObjectRetentionPolicies []ObjectRetentionPolicy `json:"object_retention_policies,omitempty"` + Checks []VerifyCheck `json:"checks"` + Assumptions []string `json:"assumptions"` + Limitations []string `json:"limitations"` + GeneratedAt time.Time `json:"generated_at"` +} + type BackupManifest struct { ID string `json:"id"` TenantID string `json:"tenant_id"` diff --git a/openapi.yaml b/openapi.yaml index 9092d0c..dd4368c 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CRAVulnerabilityHandlingReport":{"additionalProperties":false,"properties":{"accepted_exceptions":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"CRAVulnerabilityHandlingReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"},"require_nda":{"type":"boolean"},"watermark":{"description":"Optional customer-visible distribution watermark. It is not a token or secret.","type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireAnswerLibraryEntryRequest":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"}},"required":["answer"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"nda_accepted":{"description":"Set true to record acceptance for NDA-gated portal access.","type":"boolean"},"nda_accepted_by":{"description":"Reviewer label recorded when NDA acceptance is required. Do not include secrets.","type":"string"},"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"distribution_watermark":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"remediation":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntry":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","answer","schema_version","created_at"],"type":"object"},"QuestionnaireAnswerLibraryEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"policy_set":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlow":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["needs_evidence","ready_for_review"],"type":"string"},"steps":{"items":{"$ref":"#/components/schemas/ReleaseEvidenceFlowStep"},"type":"array"}},"required":["release_id","product_id","status","counts","steps","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseEvidenceFlowEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseEvidenceFlow"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlowStep":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"idempotency_required":{"type":"boolean"},"method":{"type":"string"},"next_reference":{"type":"string"},"path":{"type":"string"},"required":{"type":"boolean"},"required_scopes":{"items":{"type":"string"},"type":"array"},"status":{"enum":["present","missing","optional"],"type":"string"},"title":{"type":"string"}},"required":["id","title","status","required","method","path","required_scopes","idempotency_required","description"],"type":"object"},"ReleaseSecurityApprovalSummary":{"additionalProperties":false,"properties":{"approved":{"type":"integer"},"total":{"type":"integer"}},"required":["total","approved"],"type":"object"},"ReleaseSecurityExceptionSummary":{"additionalProperties":false,"properties":{"approved_unexpired":{"type":"integer"},"expired":{"type":"integer"},"total":{"type":"integer"},"unapproved":{"type":"integer"}},"required":["total","approved_unexpired","unapproved","expired"],"type":"object"},"ReleaseSecurityMissingDecision":{"additionalProperties":false,"properties":{"component":{"type":"string"},"finding_id":{"type":"string"},"scan_id":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["finding_id","scan_id","vulnerability","severity","state"],"type":"object"},"ReleaseSecurityProductSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"],"type":"object"},"ReleaseSecurityReleaseSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"state":{"type":"string"},"version":{"type":"string"}},"required":["id","version","state"],"type":"object"},"ReleaseSecuritySummary":{"additionalProperties":false,"properties":{"approval_summary":{"$ref":"#/components/schemas/ReleaseSecurityApprovalSummary"},"artifact_count":{"type":"integer"},"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"decisions_by_status":{"additionalProperties":{"type":"integer"},"type":"object"},"exception_summary":{"$ref":"#/components/schemas/ReleaseSecurityExceptionSummary"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_required_decisions":{"items":{"$ref":"#/components/schemas/ReleaseSecurityMissingDecision"},"type":"array"},"open_findings_by_severity":{"additionalProperties":{"type":"integer"},"type":"object"},"package_status":{"enum":["generated","not_generated"],"type":"string"},"product":{"$ref":"#/components/schemas/ReleaseSecurityProductSummary"},"readiness_status":{"enum":["passed","failed"],"type":"string"},"release":{"$ref":"#/components/schemas/ReleaseSecurityReleaseSummary"},"sbom_status":{"enum":["present","missing"],"type":"string"},"schema_version":{"type":"string"},"vulnerability_scan_status":{"enum":["present","missing"],"type":"string"}},"required":["product","release","artifact_count","sbom_status","vulnerability_scan_status","open_findings_by_severity","decisions_by_status","approval_summary","exception_summary","readiness_status","package_status","counts","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseSecuritySummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseSecuritySummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityUpdateEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"fixed_decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incidents":{"items":{"$ref":"#/components/schemas/Incident"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"remediation_tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"SecurityUpdateEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"examples":{"release-evidence-package":{"summary":"Create a scoped release evidence package","value":{"expires_at":"2026-06-30T00:00:00Z","product_id":"prod_20260527120000","redaction_profile_id":"rp_20260527120000","release_id":"rel_20260527120000","title":"Payments API 1.0.0 release evidence package"}}},"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-answer-library":{"get":{"description":"Lists tenant-scoped questionnaire answer library entries with optional question, product, and release filters.","operationId":"listQuestionnaireAnswerLibrary","parameters":[{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by questionnaire question id.","in":"query","name":"question_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryListEnvelope"}}},"description":"Questionnaire answer library entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List questionnaire answer library entries","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a tenant-scoped reusable questionnaire answer draft linked to optional evidence, product, release, or control scope.","operationId":"createQuestionnaireAnswerLibraryEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireAnswerLibraryEntryRequest"}}},"description":"Questionnaire answer library entry creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryEnvelope"}}},"description":"Created questionnaire answer library entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire answer library entry","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"examples":{"release-candidate":{"summary":"Create a release for evidence collection","value":{"product_id":"prod_20260527120000","project_id":"proj_20260527120000","version":"1.0.0-rc.1"}}},"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"examples":{"created-release":{"summary":"Created release response","value":{"data":{"created_at":"2026-05-27T12:00:00Z","id":"rel_20260527120000","product_id":"prod_20260527120000","project_id":"proj_20260527120000","schema_version":"release.v1.0.0","status":"draft","tenant_id":"ten_20260527120000","version":"1.0.0-rc.1"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/evidence-flow/start":{"post":{"description":"Returns a high-level release evidence workflow plan, current evidence counts, required scopes, assumptions, and limitations. This read-only convenience operation does not create evidence.","operationId":"startReleaseEvidenceFlow","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEvidenceFlowEnvelope"}}},"description":"Release evidence flow envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Start release evidence flow","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:read"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/security-summary":{"get":{"description":"Returns a tenant-scoped release security summary for review surfaces without raw evidence payload bytes.","operationId":"releaseSecuritySummary","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseSecuritySummaryEnvelope"}}},"description":"Release security summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release security summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-vulnerability-handling":{"get":{"description":"Returns a CRA-oriented vulnerability handling evidence report without legal compliance, certification, scanner-authority, or release-security conclusions.","operationId":"craVulnerabilityHandlingReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReportEnvelope"}}},"description":"CRA vulnerability handling report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA vulnerability handling report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"examples":{"failed-readiness-with-gap":{"summary":"Readiness report with a vulnerability decision gap","value":{"data":{"accepted_exceptions":[],"assumptions":["Readiness is based on tenant evidence recorded in Evydence."],"blocking_findings":[{"component":"pkg:apk/openssl@3.1.0-r0","decision_state":"missing","finding_id":"scan_20260527120000:finding:1","release_id":"rel_20260527120000","scan_id":"scan_20260527120000","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"generated_at":"2026-05-27T12:00:00Z","limitations":["Readiness supports technical review and does not prove legal compliance, certification, complete vulnerability coverage, or release security."],"missing_evidence":["vulnerability_decision"],"policy_set":"policy-set.v1.0.0","product_id":"prod_20260527120000","release_id":"rel_20260527120000","report_type":"release_readiness","result":"failed","schema_version":"release-readiness.v1.0.0","summary":{"headline":"Release evidence has one blocking vulnerability decision gap.","human_summary":"Required artifact, SBOM, scan, build, and bundle evidence is present, but one critical finding still needs a valid decision or approved exception.","policy_set":"policy-set.v1.0.0","result":"failed"},"template_version":"release-readiness.v1.0.0"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/security-update-evidence":{"get":{"description":"Returns a security update evidence report for release-scoped fixed decisions, incidents, remediation tasks, and linked evidence without legal or security conclusions.","operationId":"securityUpdateEvidenceReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReportEnvelope"}}},"description":"Security update evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security update evidence report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"examples":{"cyclonedx-release-sbom":{"summary":"Upload a CycloneDX SBOM linked to the release artifact","value":{"artifact_id":"art_20260527120000","payload":{"bomFormat":"CycloneDX","components":[{"name":"payments-api","purl":"pkg:oci/payments-api@sha256-ca978112","version":"1.0.0-rc.1"},{"name":"openssl","purl":"pkg:apk/openssl@3.1.0-r0","version":"3.1.0-r0"}],"specVersion":"1.6"},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"examples":{"not-affected-decision":{"summary":"Record a customer-visible not-affected decision","value":{"customer_visible":true,"evidence_ids":["ev_20260527120000"],"impact_statement":"The shipped artifact does not include the affected runtime path.","justification":"The vulnerable code path is not reachable in this release.","status":"not_affected"}}},"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"examples":{"generic-critical-finding":{"summary":"Upload a generic scanner finding for release triage","value":{"findings":[{"component":"pkg:apk/openssl@3.1.0-r0","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"release_id":"rel_20260527120000","scanner":"generic-json","target_ref":"pkg:oci/payments-api@sha256-ca978112"}}},"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CRAVulnerabilityHandlingReport":{"additionalProperties":false,"properties":{"accepted_exceptions":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"CRAVulnerabilityHandlingReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"},"require_nda":{"type":"boolean"},"watermark":{"description":"Optional customer-visible distribution watermark. It is not a token or secret.","type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireAnswerLibraryEntryRequest":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"}},"required":["answer"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"nda_accepted":{"description":"Set true to record acceptance for NDA-gated portal access.","type":"boolean"},"nda_accepted_by":{"description":"Reviewer label recorded when NDA acceptance is required. Do not include secrets.","type":"string"},"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"distribution_watermark":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"remediation":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntry":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","answer","schema_version","created_at"],"type":"object"},"QuestionnaireAnswerLibraryEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"policy_set":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlow":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["needs_evidence","ready_for_review"],"type":"string"},"steps":{"items":{"$ref":"#/components/schemas/ReleaseEvidenceFlowStep"},"type":"array"}},"required":["release_id","product_id","status","counts","steps","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseEvidenceFlowEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseEvidenceFlow"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlowStep":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"idempotency_required":{"type":"boolean"},"method":{"type":"string"},"next_reference":{"type":"string"},"path":{"type":"string"},"required":{"type":"boolean"},"required_scopes":{"items":{"type":"string"},"type":"array"},"status":{"enum":["present","missing","optional"],"type":"string"},"title":{"type":"string"}},"required":["id","title","status","required","method","path","required_scopes","idempotency_required","description"],"type":"object"},"ReleaseSecurityApprovalSummary":{"additionalProperties":false,"properties":{"approved":{"type":"integer"},"total":{"type":"integer"}},"required":["total","approved"],"type":"object"},"ReleaseSecurityExceptionSummary":{"additionalProperties":false,"properties":{"approved_unexpired":{"type":"integer"},"expired":{"type":"integer"},"total":{"type":"integer"},"unapproved":{"type":"integer"}},"required":["total","approved_unexpired","unapproved","expired"],"type":"object"},"ReleaseSecurityMissingDecision":{"additionalProperties":false,"properties":{"component":{"type":"string"},"finding_id":{"type":"string"},"scan_id":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["finding_id","scan_id","vulnerability","severity","state"],"type":"object"},"ReleaseSecurityProductSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"],"type":"object"},"ReleaseSecurityReleaseSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"state":{"type":"string"},"version":{"type":"string"}},"required":["id","version","state"],"type":"object"},"ReleaseSecuritySummary":{"additionalProperties":false,"properties":{"approval_summary":{"$ref":"#/components/schemas/ReleaseSecurityApprovalSummary"},"artifact_count":{"type":"integer"},"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"decisions_by_status":{"additionalProperties":{"type":"integer"},"type":"object"},"exception_summary":{"$ref":"#/components/schemas/ReleaseSecurityExceptionSummary"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_required_decisions":{"items":{"$ref":"#/components/schemas/ReleaseSecurityMissingDecision"},"type":"array"},"open_findings_by_severity":{"additionalProperties":{"type":"integer"},"type":"object"},"package_status":{"enum":["generated","not_generated"],"type":"string"},"product":{"$ref":"#/components/schemas/ReleaseSecurityProductSummary"},"readiness_status":{"enum":["passed","failed"],"type":"string"},"release":{"$ref":"#/components/schemas/ReleaseSecurityReleaseSummary"},"sbom_status":{"enum":["present","missing"],"type":"string"},"schema_version":{"type":"string"},"vulnerability_scan_status":{"enum":["present","missing"],"type":"string"}},"required":["product","release","artifact_count","sbom_status","vulnerability_scan_status","open_findings_by_severity","decisions_by_status","approval_summary","exception_summary","readiness_status","package_status","counts","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseSecuritySummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseSecuritySummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityUpdateEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"fixed_decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incidents":{"items":{"$ref":"#/components/schemas/Incident"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"remediation_tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"SecurityUpdateEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningCustodyReviewReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"object_retention_policies":{"items":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"type":"array"},"report_type":{"type":"string"},"signing_providers":{"items":{"$ref":"#/components/schemas/SigningProvider"},"type":"array"},"tenant_id":{"type":"string"}},"required":["report_type","tenant_id","checks","assumptions","limitations","generated_at"],"type":"object"},"SigningCustodyReviewReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningCustodyReviewReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"examples":{"release-evidence-package":{"summary":"Create a scoped release evidence package","value":{"expires_at":"2026-06-30T00:00:00Z","product_id":"prod_20260527120000","redaction_profile_id":"rp_20260527120000","release_id":"rel_20260527120000","title":"Payments API 1.0.0 release evidence package"}}},"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-answer-library":{"get":{"description":"Lists tenant-scoped questionnaire answer library entries with optional question, product, and release filters.","operationId":"listQuestionnaireAnswerLibrary","parameters":[{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by questionnaire question id.","in":"query","name":"question_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryListEnvelope"}}},"description":"Questionnaire answer library entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List questionnaire answer library entries","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a tenant-scoped reusable questionnaire answer draft linked to optional evidence, product, release, or control scope.","operationId":"createQuestionnaireAnswerLibraryEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireAnswerLibraryEntryRequest"}}},"description":"Questionnaire answer library entry creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryEnvelope"}}},"description":"Created questionnaire answer library entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire answer library entry","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"examples":{"release-candidate":{"summary":"Create a release for evidence collection","value":{"product_id":"prod_20260527120000","project_id":"proj_20260527120000","version":"1.0.0-rc.1"}}},"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"examples":{"created-release":{"summary":"Created release response","value":{"data":{"created_at":"2026-05-27T12:00:00Z","id":"rel_20260527120000","product_id":"prod_20260527120000","project_id":"proj_20260527120000","schema_version":"release.v1.0.0","status":"draft","tenant_id":"ten_20260527120000","version":"1.0.0-rc.1"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/evidence-flow/start":{"post":{"description":"Returns a high-level release evidence workflow plan, current evidence counts, required scopes, assumptions, and limitations. This read-only convenience operation does not create evidence.","operationId":"startReleaseEvidenceFlow","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEvidenceFlowEnvelope"}}},"description":"Release evidence flow envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Start release evidence flow","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:read"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/security-summary":{"get":{"description":"Returns a tenant-scoped release security summary for review surfaces without raw evidence payload bytes.","operationId":"releaseSecuritySummary","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseSecuritySummaryEnvelope"}}},"description":"Release security summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release security summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-vulnerability-handling":{"get":{"description":"Returns a CRA-oriented vulnerability handling evidence report without legal compliance, certification, scanner-authority, or release-security conclusions.","operationId":"craVulnerabilityHandlingReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReportEnvelope"}}},"description":"CRA vulnerability handling report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA vulnerability handling report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/custody-review":{"get":{"description":"Returns tenant signing-provider and object-lock verification metadata for deployment custody review. It is evidence metadata only, not legal compliance proof, certification, HSM custody proof, or a secure-deployment guarantee.","operationId":"signingCustodyReviewReport","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningCustodyReviewReportEnvelope"}}},"description":"Signing custody review report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Signing custody review report","tags":["evydence"],"x-scopes":["keys:admin"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"examples":{"failed-readiness-with-gap":{"summary":"Readiness report with a vulnerability decision gap","value":{"data":{"accepted_exceptions":[],"assumptions":["Readiness is based on tenant evidence recorded in Evydence."],"blocking_findings":[{"component":"pkg:apk/openssl@3.1.0-r0","decision_state":"missing","finding_id":"scan_20260527120000:finding:1","release_id":"rel_20260527120000","scan_id":"scan_20260527120000","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"generated_at":"2026-05-27T12:00:00Z","limitations":["Readiness supports technical review and does not prove legal compliance, certification, complete vulnerability coverage, or release security."],"missing_evidence":["vulnerability_decision"],"policy_set":"policy-set.v1.0.0","product_id":"prod_20260527120000","release_id":"rel_20260527120000","report_type":"release_readiness","result":"failed","schema_version":"release-readiness.v1.0.0","summary":{"headline":"Release evidence has one blocking vulnerability decision gap.","human_summary":"Required artifact, SBOM, scan, build, and bundle evidence is present, but one critical finding still needs a valid decision or approved exception.","policy_set":"policy-set.v1.0.0","result":"failed"},"template_version":"release-readiness.v1.0.0"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/security-update-evidence":{"get":{"description":"Returns a security update evidence report for release-scoped fixed decisions, incidents, remediation tasks, and linked evidence without legal or security conclusions.","operationId":"securityUpdateEvidenceReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReportEnvelope"}}},"description":"Security update evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security update evidence report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"examples":{"cyclonedx-release-sbom":{"summary":"Upload a CycloneDX SBOM linked to the release artifact","value":{"artifact_id":"art_20260527120000","payload":{"bomFormat":"CycloneDX","components":[{"name":"payments-api","purl":"pkg:oci/payments-api@sha256-ca978112","version":"1.0.0-rc.1"},{"name":"openssl","purl":"pkg:apk/openssl@3.1.0-r0","version":"3.1.0-r0"}],"specVersion":"1.6"},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"examples":{"not-affected-decision":{"summary":"Record a customer-visible not-affected decision","value":{"customer_visible":true,"evidence_ids":["ev_20260527120000"],"impact_statement":"The shipped artifact does not include the affected runtime path.","justification":"The vulnerable code path is not reachable in this release.","status":"not_affected"}}},"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"examples":{"generic-critical-finding":{"summary":"Upload a generic scanner finding for release triage","value":{"findings":[{"component":"pkg:apk/openssl@3.1.0-r0","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"release_id":"rel_20260527120000","scanner":"generic-json","target_ref":"pkg:oci/payments-api@sha256-ca978112"}}},"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/sdk/openapi-route-catalog.json b/sdk/openapi-route-catalog.json index 1bee899..c2524bf 100644 --- a/sdk/openapi-route-catalog.json +++ b/sdk/openapi-route-catalog.json @@ -1,5 +1,5 @@ { - "route_count": 175, + "route_count": 176, "routes": [ { "idempotency_key_required": false, @@ -2044,6 +2044,23 @@ "200" ] }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "signingCustodyReviewReport", + "path": "/v1/reports/custody-review", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/SigningCustodyReviewReportEnvelope" + ], + "scopes": [ + "keys:admin" + ], + "success_statuses": [ + "200" + ] + }, { "idempotency_key_required": false, "method": "GET", From 4ea8a3ce711b0e30cb083b438e50894ad06ef5c7 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 23:10:10 +0300 Subject: [PATCH 211/287] feat(portal): add reviewer access accounts --- .productization_next_steps.md | 4 +- docs/api.md | 4 +- docs/reference/api-contract-matrix.md | 4 +- docs/reference/customer-package-manifest.md | 6 ++ internal/adapters/httpapi/openapi.go | 37 +++++-- .../adapters/httpapi/openapi_operations.go | 11 ++- internal/adapters/httpapi/portal_handlers.go | 34 +++++-- .../adapters/httpapi/route_registration.go | 2 + internal/adapters/httpapi/router.go | 1 + internal/adapters/httpapi/router_test.go | 24 ++++- internal/adapters/postgres/store.go | 24 +++-- internal/adapters/postgres/store_test.go | 9 +- internal/app/context_cancellation_test.go | 4 + internal/app/enterprise.go | 98 +++++++++++++++++-- internal/app/enterprise_test.go | 27 ++++- internal/app/governance_packages.go | 15 ++- internal/app/identity_service.go | 8 ++ internal/domain/domain.go | 2 + ...1000500_customer_portal_reviewers.down.sql | 5 + ...601000500_customer_portal_reviewers.up.sql | 6 ++ openapi.yaml | 2 +- sdk/openapi-route-catalog.json | 36 ++++++- 22 files changed, 319 insertions(+), 44 deletions(-) create mode 100644 migrations/20260601000500_customer_portal_reviewers.down.sql create mode 100644 migrations/20260601000500_customer_portal_reviewers.up.sql diff --git a/.productization_next_steps.md b/.productization_next_steps.md index fa2d344..587f4a8 100644 --- a/.productization_next_steps.md +++ b/.productization_next_steps.md @@ -1259,11 +1259,11 @@ Potential later expansion: Do this when a real pilot requires it. -#### [ ] EVY-204 — Customer portal server mode +#### [x] EVY-204 — Customer portal server mode Potential later expansion: -* [ ] external reviewer accounts +* [x] external reviewer accounts * [x] package tokens * [x] access counters and failed-attempt counters * [x] expiry diff --git a/docs/api.md b/docs/api.md index a23a4d0..bb1a172 100644 --- a/docs/api.md +++ b/docs/api.md @@ -430,7 +430,9 @@ Source snapshots capture submitted provider metadata. They do not call provider | `POST` | `/v1/customer-packages` | Create scoped customer package manifest. | | `GET` | `/v1/customer-packages/{id}` | Read package manifest and record access. | | `GET` | `/v1/customer-packages/{id}/download` | Download scoped ZIP package with manifest metadata and verification guidance. | -| `POST` | `/v1/customer-portal/access` | Create one-time package access token. | +| `POST` | `/v1/customer-portal/access` | Create named external reviewer access with one-time package token. | +| `GET` | `/v1/customer-portal/access` | List external reviewer access records without token hashes or secrets. | +| `POST` | `/v1/customer-portal/access/{id}/revoke` | Revoke an external reviewer access record. | | `POST` | `/v1/customer-portal/package` | Exchange package token for scoped manifest. | | `POST` | `/v1/customer-portal/package/download` | Exchange package token for scoped ZIP package download. | | `POST` | `/v1/questionnaire-templates` | Create questionnaire template. | diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index 3981a9e..af66bae 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 176 operations: 176 precise, 0 broad. +Generated from 178 operations: 178 precise, 0 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -46,7 +46,9 @@ Generated from 176 operations: 176 precise, 0 broad. | POST | /v1/customer-packages | createCustomerPackage | Bearer | package:write | required | - | application/json:CreateCustomerPackageRequest | 201:application/json:CustomerSecurityPackageEnvelope | precise | | GET | /v1/customer-packages/{id} | getCustomerPackage | Bearer | package:read | - | path:id | - | 200:application/json:CustomerSecurityPackageEnvelope | precise | | GET | /v1/customer-packages/{id}/download | downloadCustomerPackage | Bearer | package:read | - | path:id | - | 200:application/zip:string/binary | precise | +| GET | /v1/customer-portal/access | listCustomerPortalAccess | Bearer | package:read | - | query:package_id | - | 200:application/json:CustomerPortalAccessListEnvelope | precise | | POST | /v1/customer-portal/access | createCustomerPortalAccess | Bearer | package:write | required | - | application/json:CreateCustomerPortalAccessRequest | 201:application/json:CustomerPortalAccessCreateEnvelope | precise | +| POST | /v1/customer-portal/access/{id}/revoke | revokeCustomerPortalAccess | Bearer | package:write | required | path:id | application/json:EmptyObject | 200:application/json:CustomerPortalAccessEnvelope | precise | | POST | /v1/customer-portal/package | accessCustomerPortalPackage | public | - | not required | - | application/json:CustomerPortalPackageRequest | 200:application/json:CustomerSecurityPackageEnvelope | precise | | POST | /v1/customer-portal/package/download | downloadCustomerPortalPackage | public | - | not required | - | application/json:CustomerPortalPackageRequest | 200:application/zip:string/binary | precise | | GET | /v1/deployments | listDeployments | Bearer | deployment:read | - | query:environment_id, query:release_id | - | 200:application/json:DeploymentEventListEnvelope | precise | diff --git a/docs/reference/customer-package-manifest.md b/docs/reference/customer-package-manifest.md index 2431ee1..2bb4e5a 100644 --- a/docs/reference/customer-package-manifest.md +++ b/docs/reference/customer-package-manifest.md @@ -108,6 +108,12 @@ change the canonical package manifest hash. The HTML report is generated from package-scoped data only and excludes raw evidence payload bytes, object-store references, token material, private keys, and internal decision notes. +Server-backed portal access records can be named for an external reviewer with +optional reviewer name and email labels. Those labels support access review, +watermarking, and audit triage only; the portal token remains the credential and +is returned once, stored only as a hash, and omitted from package manifests, +archives, logs, and list responses. + ## Redaction Leakage Guard Customer package generation is tested with canary values for API key secrets, diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 21feacc..ee0a9c9 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -2397,17 +2397,42 @@ func registerCriticalSchemas(registry *specs.Registry) { }, "result")) registry.RegisterSchema("ReleaseBundleVerificationEnvelope", dataEnvelopeSchema("#/components/schemas/ReleaseBundleVerification")) registry.RegisterSchema("CreateCustomerPortalAccessRequest", objectSchema(map[string]any{ - "package_id": map[string]any{"type": "string"}, - "customer_name": map[string]any{"type": "string"}, - "require_nda": map[string]any{"type": "boolean"}, - "watermark": map[string]any{"type": "string", "description": "Optional customer-visible distribution watermark. It is not a token or secret."}, - "expires_at": map[string]any{"type": "string", "format": "date-time"}, + "package_id": map[string]any{"type": "string"}, + "customer_name": map[string]any{"type": "string"}, + "reviewer_name": map[string]any{"type": "string", "description": "Optional external reviewer display name for this package access record."}, + "reviewer_email": map[string]any{"type": "string", "description": "Optional external reviewer email label. It is not used as an authentication secret."}, + "require_nda": map[string]any{"type": "boolean"}, + "watermark": map[string]any{"type": "string", "description": "Optional customer-visible distribution watermark. It is not a token or secret."}, + "expires_at": map[string]any{"type": "string", "format": "date-time"}, }, "package_id", "customer_name", "expires_at")) + registry.RegisterSchema("CustomerPortalAccess", objectSchema(map[string]any{ + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "package_id": map[string]any{"type": "string"}, + "customer_name": map[string]any{"type": "string"}, + "reviewer_name": map[string]any{"type": "string"}, + "reviewer_email": map[string]any{"type": "string"}, + "require_nda": map[string]any{"type": "boolean"}, + "nda_accepted_at": map[string]any{"type": "string", "format": "date-time"}, + "nda_accepted_by": map[string]any{"type": "string"}, + "watermark": map[string]any{"type": "string"}, + "prefix": map[string]any{"type": "string", "description": "Non-secret portal token prefix for operational lookup."}, + "expires_at": map[string]any{"type": "string", "format": "date-time"}, + "revoked_at": map[string]any{"type": "string", "format": "date-time"}, + "access_count": map[string]any{"type": "integer"}, + "failed_access_count": map[string]any{"type": "integer"}, + "last_accessed_at": map[string]any{"type": "string", "format": "date-time"}, + "last_failed_at": map[string]any{"type": "string", "format": "date-time"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, + }, "id", "tenant_id", "package_id", "customer_name", "prefix", "expires_at", "access_count", "failed_access_count", "schema_version", "created_at")) registry.RegisterSchema("CustomerPortalAccessCreateResponse", objectSchema(map[string]any{ - "access": map[string]any{"type": "object"}, + "access": map[string]any{"$ref": "#/components/schemas/CustomerPortalAccess"}, "secret": map[string]any{"type": "string", "description": "One-time portal token; stored only as a HMAC hash."}, }, "access", "secret")) registry.RegisterSchema("CustomerPortalAccessCreateEnvelope", dataEnvelopeSchema("#/components/schemas/CustomerPortalAccessCreateResponse")) + registry.RegisterSchema("CustomerPortalAccessEnvelope", dataEnvelopeSchema("#/components/schemas/CustomerPortalAccess")) + registry.RegisterSchema("CustomerPortalAccessListEnvelope", dataArrayEnvelopeSchema("#/components/schemas/CustomerPortalAccess")) registry.RegisterSchema("CustomerPortalPackageRequest", objectSchema(map[string]any{ "token": map[string]any{"type": "string", "description": "Customer portal access token issued by createCustomerPortalAccess."}, "nda_accepted": map[string]any{"type": "boolean", "description": "Set true to record acceptance for NDA-gated portal access."}, diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 4b9fae6..5144442 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -796,9 +796,18 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Parameters = append(operation.Parameters, pathParam("id", "Customer package id.")) operation.Responses[http.StatusOK] = jsonResponse("Customer security package envelope.", "#/components/schemas/CustomerSecurityPackageEnvelope") case "createCustomerPortalAccess": - operation.Description = "Creates token-based customer portal access for a customer package and returns the token once." + operation.Description = "Creates a named, expiring external reviewer access record for a customer package and returns the portal token once." operation.RequestBody = jsonRequest("Customer portal access creation request.", "#/components/schemas/CreateCustomerPortalAccessRequest") operation.Responses[http.StatusCreated] = jsonResponse("Created portal access and one-time token envelope.", "#/components/schemas/CustomerPortalAccessCreateEnvelope") + case "listCustomerPortalAccess": + operation.Description = "Lists tenant-scoped external reviewer access records without token hashes or token secrets." + operation.Parameters = append(operation.Parameters, queryParam("package_id", "Optional customer package id filter.", "string")) + operation.Responses[http.StatusOK] = jsonResponse("Customer portal access list envelope.", "#/components/schemas/CustomerPortalAccessListEnvelope") + case "revokeCustomerPortalAccess": + operation.Description = "Revokes a tenant-scoped external reviewer access record; revocation is append-only and the original token cannot be used afterwards." + operation.Parameters = append(operation.Parameters, pathParam("id", "Customer portal access id.")) + operation.RequestBody = jsonRequest("Empty JSON object.", "#/components/schemas/EmptyObject") + operation.Responses[http.StatusOK] = jsonResponse("Revoked customer portal access envelope.", "#/components/schemas/CustomerPortalAccessEnvelope") case "downloadCustomerPackage": operation.Description = "Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes." operation.Parameters = append(operation.Parameters, pathParam("id", "Customer package id.")) diff --git a/internal/adapters/httpapi/portal_handlers.go b/internal/adapters/httpapi/portal_handlers.go index 8adc8a1..4d155d9 100644 --- a/internal/adapters/httpapi/portal_handlers.go +++ b/internal/adapters/httpapi/portal_handlers.go @@ -10,21 +10,43 @@ import ( func (s *Server) createCustomerPortalAccess(w http.ResponseWriter, r *http.Request) { var req struct { - PackageID string `json:"package_id"` - CustomerName string `json:"customer_name"` - RequireNDA bool `json:"require_nda"` - Watermark string `json:"watermark"` - ExpiresAt time.Time `json:"expires_at"` + PackageID string `json:"package_id"` + CustomerName string `json:"customer_name"` + ReviewerName string `json:"reviewer_name"` + ReviewerEmail string `json:"reviewer_email"` + RequireNDA bool `json:"require_nda"` + Watermark string `json:"watermark"` + ExpiresAt time.Time `json:"expires_at"` } s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { return 0, nil, err } - access, secret, err := s.ledger.CreateCustomerPortalAccess(ctx, actor, app.CreateCustomerPortalAccessInput{PackageID: req.PackageID, CustomerName: req.CustomerName, RequireNDA: req.RequireNDA, Watermark: req.Watermark, ExpiresAt: req.ExpiresAt}) + access, secret, err := s.ledger.CreateCustomerPortalAccess(ctx, actor, app.CreateCustomerPortalAccessInput{PackageID: req.PackageID, CustomerName: req.CustomerName, ReviewerName: req.ReviewerName, ReviewerEmail: req.ReviewerEmail, RequireNDA: req.RequireNDA, Watermark: req.Watermark, ExpiresAt: req.ExpiresAt}) return http.StatusCreated, map[string]any{"access": access, "secret": secret}, err }) } +func (s *Server) listCustomerPortalAccess(w http.ResponseWriter, r *http.Request) { + actor, ok := s.authenticate(w, r) + if !ok { + return + } + access, err := s.ledger.ListCustomerPortalAccess(r.Context(), actor, r.URL.Query().Get("package_id")) + if err != nil { + writeProblem(w, r, err) + return + } + writeData(w, http.StatusOK, access) +} + +func (s *Server) revokeCustomerPortalAccess(w http.ResponseWriter, r *http.Request) { + s.create(w, r, func(ctx requestContext, actor domain.Actor, _ []byte) (int, any, error) { + access, err := s.ledger.RevokeCustomerPortalAccess(ctx, actor, r.PathValue("id")) + return http.StatusOK, access, err + }) +} + func (s *Server) accessCustomerPortalPackage(w http.ResponseWriter, r *http.Request) { var req struct { Token string `json:"token"` diff --git a/internal/adapters/httpapi/route_registration.go b/internal/adapters/httpapi/route_registration.go index eee4d23..0137229 100644 --- a/internal/adapters/httpapi/route_registration.go +++ b/internal/adapters/httpapi/route_registration.go @@ -176,6 +176,8 @@ func (s *Server) packagePortalRoutes() []routeDef { {http.MethodGet, "/v1/customer-packages/{id}", op("getCustomerPackage", http.MethodGet, "/v1/customer-packages/{id}", "Get customer security package", []string{app.ScopePackageRead}), http.HandlerFunc(s.getCustomerPackage)}, {http.MethodGet, "/v1/customer-packages/{id}/download", op("downloadCustomerPackage", http.MethodGet, "/v1/customer-packages/{id}/download", "Download customer security package ZIP", []string{app.ScopePackageRead}), http.HandlerFunc(s.downloadCustomerPackage)}, {http.MethodPost, "/v1/customer-portal/access", op("createCustomerPortalAccess", http.MethodPost, "/v1/customer-portal/access", "Create customer portal access", []string{app.ScopePackageWrite}), http.HandlerFunc(s.createCustomerPortalAccess)}, + {http.MethodGet, "/v1/customer-portal/access", op("listCustomerPortalAccess", http.MethodGet, "/v1/customer-portal/access", "List customer portal access records", []string{app.ScopePackageRead}), http.HandlerFunc(s.listCustomerPortalAccess)}, + {http.MethodPost, "/v1/customer-portal/access/{id}/revoke", op("revokeCustomerPortalAccess", http.MethodPost, "/v1/customer-portal/access/{id}/revoke", "Revoke customer portal access", []string{app.ScopePackageWrite}), http.HandlerFunc(s.revokeCustomerPortalAccess)}, {http.MethodPost, "/v1/customer-portal/package", op("accessCustomerPortalPackage", http.MethodPost, "/v1/customer-portal/package", "Access customer portal package", nil), http.HandlerFunc(s.accessCustomerPortalPackage)}, {http.MethodPost, "/v1/customer-portal/package/download", op("downloadCustomerPortalPackage", http.MethodPost, "/v1/customer-portal/package/download", "Download customer portal package ZIP", nil), http.HandlerFunc(s.downloadCustomerPortalPackage)}, {http.MethodPost, "/v1/questionnaire-templates", op("createQuestionnaireTemplate", http.MethodPost, "/v1/questionnaire-templates", "Create questionnaire template", []string{app.ScopePackageWrite}), http.HandlerFunc(s.createQuestionnaireTemplate)}, diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index ccb252c..f1d8860 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -2470,6 +2470,7 @@ func defaultSuccessStatus(operationID, method string) int { "approveWaiver", "accessCustomerPortalPackage", "downloadCustomerPortalPackage", + "revokeCustomerPortalAccess", "approveException", "verifyObjectRetentionPolicy", "verifyPublicTransparencyLogEntry", diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 4bc8af4..fc35d39 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -94,7 +94,7 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { if _, ok := redactionRequestProps["preset"]; !ok { t.Fatalf("redaction profile request schema missing preset: %#v", redactionRequestProps) } - for _, schemaName := range []string{"ReadinessStatusEnvelope", "BackupManifestEnvelope", "VerificationResultEnvelope", "ReadinessReportEnvelope", "CRAVulnerabilityHandlingReportEnvelope", "SecurityUpdateEvidenceReportEnvelope", "SigningCustodyReviewReportEnvelope", "CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "ReleaseEvidenceFlowEnvelope", "ReleaseSecuritySummaryEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "VEXImportReportEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "VulnerabilityDecisionListEnvelope", "VulnerabilityDecisionSummaryReportEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "UpdateSSOProviderTrustMaterialRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "ExchangeSSOCredentialRequest", "SSOCredentialExchangeEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalPackageRequest", "QuestionnaireAnswerLibraryEntryEnvelope", "QuestionnaireAnswerLibraryEntryListEnvelope", "DataEnvelope"} { + for _, schemaName := range []string{"ReadinessStatusEnvelope", "BackupManifestEnvelope", "VerificationResultEnvelope", "ReadinessReportEnvelope", "CRAVulnerabilityHandlingReportEnvelope", "SecurityUpdateEvidenceReportEnvelope", "SigningCustodyReviewReportEnvelope", "CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "ReleaseEvidenceFlowEnvelope", "ReleaseSecuritySummaryEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "VEXImportReportEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "VulnerabilityDecisionListEnvelope", "VulnerabilityDecisionSummaryReportEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "UpdateSSOProviderTrustMaterialRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "ExchangeSSOCredentialRequest", "SSOCredentialExchangeEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalAccessEnvelope", "CustomerPortalAccessListEnvelope", "CustomerPortalPackageRequest", "QuestionnaireAnswerLibraryEntryEnvelope", "QuestionnaireAnswerLibraryEntryListEnvelope", "DataEnvelope"} { if _, ok := schemas[schemaName]; !ok { t.Fatalf("schema %s missing from OpenAPI components", schemaName) } @@ -182,6 +182,12 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { createPortalAccess := operationMap(t, paths, "/v1/customer-portal/access", "post") assertRequestRef(t, createPortalAccess, "#/components/schemas/CreateCustomerPortalAccessRequest") assertResponseRef(t, createPortalAccess, "201", "#/components/schemas/CustomerPortalAccessCreateEnvelope") + listPortalAccess := operationMap(t, paths, "/v1/customer-portal/access", "get") + assertQueryParams(t, listPortalAccess, "package_id") + assertResponseRef(t, listPortalAccess, "200", "#/components/schemas/CustomerPortalAccessListEnvelope") + revokePortalAccess := operationMap(t, paths, "/v1/customer-portal/access/{id}/revoke", "post") + assertRequestRef(t, revokePortalAccess, "#/components/schemas/EmptyObject") + assertResponseRef(t, revokePortalAccess, "200", "#/components/schemas/CustomerPortalAccessEnvelope") portalPackage := operationMap(t, paths, "/v1/customer-portal/package", "post") assertRequestRef(t, portalPackage, "#/components/schemas/CustomerPortalPackageRequest") if _, ok := portalPackage["security"]; ok { @@ -495,6 +501,7 @@ func TestAuthenticatedReadRoutesRejectMissingBearerToken(t *testing.T) { "/v1/control-framework-template-packs", "/v1/control-frameworks", "/v1/controls/control_missing", + "/v1/customer-portal/access", "/v1/customer-packages/package_missing", "/v1/customer-packages/package_missing/download", "/v1/deployments", @@ -1262,8 +1269,16 @@ func TestEnterprisePortalRetentionAndCommercialCollectorHTTPFlow(t *testing.T) { profileID := dataField(t, profileBody, "id") packageBody := postJSON(t, server, sessionSecret, "/v1/customer-packages", "ent-package", map[string]any{"product_id": productID, "release_id": releaseID, "redaction_profile_id": profileID, "title": "Customer package", "expires_at": time.Now().UTC().Add(time.Hour).Format(time.RFC3339)}, http.StatusCreated) packageID := dataField(t, packageBody, "id") - accessBody := postJSON(t, server, sessionSecret, "/v1/customer-portal/access", "ent-access", map[string]any{"package_id": packageID, "customer_name": "ACME", "require_nda": true, "watermark": "ACME confidential review copy", "expires_at": time.Now().UTC().Add(time.Hour).Format(time.RFC3339)}, http.StatusCreated) + accessBody := postJSON(t, server, sessionSecret, "/v1/customer-portal/access", "ent-access", map[string]any{"package_id": packageID, "customer_name": "ACME", "reviewer_name": "Alice Reviewer", "reviewer_email": "alice.reviewer@example.test", "require_nda": true, "watermark": "ACME confidential review copy", "expires_at": time.Now().UTC().Add(time.Hour).Format(time.RFC3339)}, http.StatusCreated) + accessID := dataFieldFromNestedObject(t, accessBody, "access", "id") portalSecret := nestedDataField(t, accessBody, "secret") + if !strings.Contains(accessBody, `"reviewer_email":"alice.reviewer@example.test"`) || strings.Contains(accessBody, "hash") { + t.Fatalf("portal access response missing reviewer metadata or exposed hash: %s", accessBody) + } + listedAccess := getJSON(t, server, sessionSecret, "/v1/customer-portal/access?package_id="+packageID, http.StatusOK) + if !strings.Contains(listedAccess, accessID) || !strings.Contains(listedAccess, `"reviewer_name":"Alice Reviewer"`) || strings.Contains(listedAccess, portalSecret) { + t.Fatalf("portal access list invalid: %s", listedAccess) + } postJSONNoAuth(t, server, "/v1/customer-portal/package", map[string]any{"token": portalSecret}, http.StatusForbidden) portalBody := postJSONNoAuth(t, server, "/v1/customer-portal/package", map[string]any{"token": portalSecret, "nda_accepted": true, "nda_accepted_by": "reviewer@example.test"}, http.StatusOK) if !strings.Contains(portalBody, packageID) || !strings.Contains(portalBody, "ACME confidential review copy") || strings.Contains(portalBody, portalSecret) { @@ -1273,6 +1288,11 @@ func TestEnterprisePortalRetentionAndCommercialCollectorHTTPFlow(t *testing.T) { if portalArchive.Header().Get("Content-Type") != "application/zip" || !bytes.HasPrefix(portalArchive.Body.Bytes(), []byte("PK")) || bytes.Contains(portalArchive.Body.Bytes(), []byte(portalSecret)) || !bytes.Contains(portalArchive.Body.Bytes(), []byte("WATERMARK.txt")) { t.Fatalf("portal archive response invalid headers=%v len=%d", portalArchive.Header(), portalArchive.Body.Len()) } + revokedAccess := postJSON(t, server, sessionSecret, "/v1/customer-portal/access/"+accessID+"/revoke", "ent-access-revoke", map[string]any{}, http.StatusOK) + if !strings.Contains(revokedAccess, `"revoked_at"`) || strings.Contains(revokedAccess, portalSecret) { + t.Fatalf("portal revoke response invalid: %s", revokedAccess) + } + postJSONNoAuth(t, server, "/v1/customer-portal/package", map[string]any{"token": portalSecret}, http.StatusUnauthorized) postJSON(t, server, sessionSecret, "/v1/legal-holds", "ent-hold", map[string]any{"scope_type": "release", "scope_id": releaseID, "reason": "extended review", "owner": "legal"}, http.StatusCreated) postJSON(t, server, sessionSecret, "/v1/retention-overrides", "ent-retention", map[string]any{"scope_type": "evidence", "scope_id": evidenceID, "retention_until": time.Now().UTC().Add(24 * time.Hour).Format(time.RFC3339), "reason": "review", "owner": "security"}, http.StatusCreated) retention := getJSON(t, server, sessionSecret, "/v1/reports/retention?scope_type=release&scope_id="+releaseID, http.StatusOK) diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index cec8272..5499660 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -510,7 +510,7 @@ func (s *Store) loadRelationalAPIKeys(ctx context.Context, state *app.PersistedS func (s *Store) loadRelationalCustomerPortalAccess(ctx context.Context, state *app.PersistedState, loaded *bool) error { rows, err := s.pool.Query(ctx, ` - SELECT id, tenant_id, package_id, customer_name, prefix, hash, + SELECT id, tenant_id, package_id, customer_name, reviewer_name, reviewer_email, prefix, hash, expires_at, revoked_at, access_count, failed_access_count, last_accessed_at, last_failed_at, require_nda, nda_accepted_at, nda_accepted_by, watermark, schema_version, created_at @@ -524,14 +524,16 @@ func (s *Store) loadRelationalCustomerPortalAccess(ctx context.Context, state *a var access domain.CustomerPortalAccess var hash string var revokedAt, lastAccessedAt, lastFailedAt, ndaAcceptedAt sql.NullTime - var ndaAcceptedBy, watermark sql.NullString + var reviewerName, reviewerEmail, ndaAcceptedBy, watermark sql.NullString if err := rows.Scan( - &access.ID, &access.TenantID, &access.PackageID, &access.CustomerName, &access.Prefix, &hash, + &access.ID, &access.TenantID, &access.PackageID, &access.CustomerName, &reviewerName, &reviewerEmail, &access.Prefix, &hash, &access.ExpiresAt, &revokedAt, &access.AccessCount, &access.FailedAccessCount, &lastAccessedAt, &lastFailedAt, &access.RequireNDA, &ndaAcceptedAt, &ndaAcceptedBy, &watermark, &access.SchemaVersion, &access.CreatedAt, ); err != nil { return fmt.Errorf("scan relational customer portal access: %w", err) } + access.ReviewerName = nullableSQLString(reviewerName) + access.ReviewerEmail = nullableSQLString(reviewerEmail) access.RevokedAt = nullableSQLTime(revokedAt) access.LastAccessedAt = nullableSQLTime(lastAccessedAt) access.LastFailedAt = nullableSQLTime(lastFailedAt) @@ -4747,14 +4749,16 @@ func syncIdentityAndIdempotency(ctx context.Context, tx pgx.Tx, state app.Persis } if _, err := tx.Exec(ctx, ` INSERT INTO customer_portal_access ( - id, tenant_id, package_id, customer_name, prefix, hash, + id, tenant_id, package_id, customer_name, reviewer_name, reviewer_email, prefix, hash, expires_at, revoked_at, access_count, failed_access_count, last_accessed_at, last_failed_at, require_nda, nda_accepted_at, nda_accepted_by, watermark, schema_version, created_at ) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20) ON CONFLICT (id) DO UPDATE SET customer_name = EXCLUDED.customer_name, + reviewer_name = EXCLUDED.reviewer_name, + reviewer_email = EXCLUDED.reviewer_email, prefix = EXCLUDED.prefix, hash = EXCLUDED.hash, expires_at = EXCLUDED.expires_at, @@ -4768,7 +4772,7 @@ func syncIdentityAndIdempotency(ctx context.Context, tx pgx.Tx, state app.Persis nda_accepted_by = EXCLUDED.nda_accepted_by, watermark = EXCLUDED.watermark, schema_version = EXCLUDED.schema_version - `, access.ID, access.TenantID, access.PackageID, access.CustomerName, access.Prefix, hash, access.ExpiresAt, nullableTime(access.RevokedAt), access.AccessCount, access.FailedAccessCount, nullableTime(access.LastAccessedAt), nullableTime(access.LastFailedAt), access.RequireNDA, nullableTime(access.NDAAcceptedAt), nullableString(access.NDAAcceptedBy), nullableString(access.Watermark), access.SchemaVersion, nonZeroTime(access.CreatedAt)); err != nil { + `, access.ID, access.TenantID, access.PackageID, access.CustomerName, nullableString(access.ReviewerName), nullableString(access.ReviewerEmail), access.Prefix, hash, access.ExpiresAt, nullableTime(access.RevokedAt), access.AccessCount, access.FailedAccessCount, nullableTime(access.LastAccessedAt), nullableTime(access.LastFailedAt), access.RequireNDA, nullableTime(access.NDAAcceptedAt), nullableString(access.NDAAcceptedBy), nullableString(access.Watermark), access.SchemaVersion, nonZeroTime(access.CreatedAt)); err != nil { return fmt.Errorf("upsert customer portal access row: %w", err) } } @@ -4879,14 +4883,16 @@ func syncCriticalIdentityAndIdempotency(ctx context.Context, tx pgx.Tx, mutation } if _, err := tx.Exec(ctx, ` INSERT INTO customer_portal_access ( - id, tenant_id, package_id, customer_name, prefix, hash, + id, tenant_id, package_id, customer_name, reviewer_name, reviewer_email, prefix, hash, expires_at, revoked_at, access_count, failed_access_count, last_accessed_at, last_failed_at, require_nda, nda_accepted_at, nda_accepted_by, watermark, schema_version, created_at ) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20) ON CONFLICT (id) DO UPDATE SET customer_name = EXCLUDED.customer_name, + reviewer_name = EXCLUDED.reviewer_name, + reviewer_email = EXCLUDED.reviewer_email, prefix = EXCLUDED.prefix, hash = EXCLUDED.hash, expires_at = EXCLUDED.expires_at, @@ -4900,7 +4906,7 @@ func syncCriticalIdentityAndIdempotency(ctx context.Context, tx pgx.Tx, mutation nda_accepted_by = EXCLUDED.nda_accepted_by, watermark = EXCLUDED.watermark, schema_version = EXCLUDED.schema_version - `, access.ID, access.TenantID, access.PackageID, access.CustomerName, access.Prefix, hash, access.ExpiresAt, nullableTime(access.RevokedAt), access.AccessCount, access.FailedAccessCount, nullableTime(access.LastAccessedAt), nullableTime(access.LastFailedAt), access.RequireNDA, nullableTime(access.NDAAcceptedAt), nullableString(access.NDAAcceptedBy), nullableString(access.Watermark), access.SchemaVersion, nonZeroTime(access.CreatedAt)); err != nil { + `, access.ID, access.TenantID, access.PackageID, access.CustomerName, nullableString(access.ReviewerName), nullableString(access.ReviewerEmail), access.Prefix, hash, access.ExpiresAt, nullableTime(access.RevokedAt), access.AccessCount, access.FailedAccessCount, nullableTime(access.LastAccessedAt), nullableTime(access.LastFailedAt), access.RequireNDA, nullableTime(access.NDAAcceptedAt), nullableString(access.NDAAcceptedBy), nullableString(access.Watermark), access.SchemaVersion, nonZeroTime(access.CreatedAt)); err != nil { return fmt.Errorf("upsert critical customer portal access row: %w", err) } } diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index cd37849..e461757 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -259,7 +259,7 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { }, SSOSessionHashes: map[string]string{"sess_test": "session-hash"}, CustomerPortalAccess: map[string]domain.CustomerPortalAccess{ - "cpa_test": {ID: "cpa_test", TenantID: "ten_test", PackageID: "pkg_test", CustomerName: "Customer", Prefix: "evycp_test", ExpiresAt: time.Now().UTC().Add(time.Hour), AccessCount: 2, FailedAccessCount: 1, LastAccessedAt: ptrTime(time.Now().UTC()), LastFailedAt: ptrTime(time.Now().UTC()), SchemaVersion: domain.CustomerPortalAccessVersion, CreatedAt: time.Now().UTC()}, + "cpa_test": {ID: "cpa_test", TenantID: "ten_test", PackageID: "pkg_test", CustomerName: "Customer", ReviewerName: "Reviewer", ReviewerEmail: "reviewer@example.test", Prefix: "evycp_test", ExpiresAt: time.Now().UTC().Add(time.Hour), AccessCount: 2, FailedAccessCount: 1, LastAccessedAt: ptrTime(time.Now().UTC()), LastFailedAt: ptrTime(time.Now().UTC()), SchemaVersion: domain.CustomerPortalAccessVersion, CreatedAt: time.Now().UTC()}, }, CustomerPortalHashes: map[string]string{"cpa_test": "portal-token-hash"}, Products: map[string]domain.Product{ @@ -579,7 +579,7 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { t.Fatalf("idempotency actor = %q", idemActor) } var portalHash string - if err := store.pool.QueryRow(ctx, `SELECT hash FROM customer_portal_access WHERE id = 'cpa_test' AND failed_access_count = 1 AND last_accessed_at IS NOT NULL`).Scan(&portalHash); err != nil { + if err := store.pool.QueryRow(ctx, `SELECT hash FROM customer_portal_access WHERE id = 'cpa_test' AND reviewer_email = 'reviewer@example.test' AND failed_access_count = 1 AND last_accessed_at IS NOT NULL`).Scan(&portalHash); err != nil { t.Fatal(err) } if portalHash != "portal-token-hash" { @@ -770,7 +770,7 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { if len(relational.Idempotency) != 1 { t.Fatalf("relational idempotency records = %d, want 1", len(relational.Idempotency)) } - if relational.CustomerPortalHashes["cpa_test"] != "portal-token-hash" || relational.CustomerPortalAccess["cpa_test"].FailedAccessCount != 1 { + if relational.CustomerPortalHashes["cpa_test"] != "portal-token-hash" || relational.CustomerPortalAccess["cpa_test"].FailedAccessCount != 1 || relational.CustomerPortalAccess["cpa_test"].ReviewerEmail != "reviewer@example.test" { t.Fatalf("relational portal access = %#v hash=%q", relational.CustomerPortalAccess["cpa_test"], relational.CustomerPortalHashes["cpa_test"]) } if relational.RedactionProfiles["redact_test"].Name != "Default" || relational.CustomerPackages["pkg_test"].AccessCount != 3 { @@ -901,6 +901,7 @@ func TestApplyCriticalMutationWithPostgres(t *testing.T) { SSOSessionHashes: map[string]string{"sess_focus": "sso-session-hash"}, CustomerPortalAccess: []domain.CustomerPortalAccess{{ ID: "cpa_focus", TenantID: "ten_focus", PackageID: "pkg_focus", CustomerName: "Customer", + ReviewerName: "Reviewer", ReviewerEmail: "reviewer@example.test", Prefix: "evycp_focus", ExpiresAt: now.Add(time.Hour), AccessCount: 2, FailedAccessCount: 1, LastAccessedAt: ptrTime(now), LastFailedAt: ptrTime(now), SchemaVersion: domain.CustomerPortalAccessVersion, CreatedAt: now, @@ -979,7 +980,7 @@ func TestApplyCriticalMutationWithPostgres(t *testing.T) { {name: "tenant", query: `SELECT count(*) FROM tenants WHERE id = 'ten_focus'`}, {name: "api key hash", query: `SELECT count(*) FROM api_keys WHERE id = 'key_focus' AND hash = 'api-key-hmac-hash' AND last_used_at IS NOT NULL`}, {name: "sso session hash", query: `SELECT count(*) FROM sso_sessions WHERE id = 'sess_focus' AND hash = 'sso-session-hash' AND groups = '["security"]'::jsonb`}, - {name: "portal hash", query: `SELECT count(*) FROM customer_portal_access WHERE id = 'cpa_focus' AND hash = 'portal-token-hash' AND failed_access_count = 1`}, + {name: "portal hash", query: `SELECT count(*) FROM customer_portal_access WHERE id = 'cpa_focus' AND hash = 'portal-token-hash' AND reviewer_email = 'reviewer@example.test' AND failed_access_count = 1`}, {name: "audit chain", query: `SELECT count(*) FROM audit_chain_entries WHERE tenant_id = 'ten_focus' AND sequence = 1`}, {name: "signing key private", query: `SELECT count(*) FROM signing_keys WHERE id = 'sigkey_focus' AND encrypted_private_key IS NOT NULL`}, {name: "signature", query: `SELECT count(*) FROM signatures WHERE id = 'sig_focus' AND key_id = 'sigkey_focus'`}, diff --git a/internal/app/context_cancellation_test.go b/internal/app/context_cancellation_test.go index 336ba8b..94e87f2 100644 --- a/internal/app/context_cancellation_test.go +++ b/internal/app/context_cancellation_test.go @@ -292,6 +292,8 @@ func TestLedgerOperationsHonorCanceledContextBeforeWork(t *testing.T) { _, _, err := ledger.CreateCustomerPortalAccess(ctx, actor, CreateCustomerPortalAccessInput{PackageID: "pkg", CustomerName: "ACME", ExpiresAt: fixedNow().AddDate(0, 0, 1)}) return err }}, + {"ListCustomerPortalAccess", func() error { _, err := ledger.ListCustomerPortalAccess(ctx, actor, "pkg"); return err }}, + {"RevokeCustomerPortalAccess", func() error { _, err := ledger.RevokeCustomerPortalAccess(ctx, actor, "access"); return err }}, {"AccessCustomerPortalPackage", func() error { _, err := ledger.AccessCustomerPortalPackage(ctx, "token"); return err }}, {"AccessCustomerPortalPackageWithAcceptance", func() error { _, err := ledger.AccessCustomerPortalPackageWithAcceptance(ctx, "token", CustomerPortalAcceptanceInput{NDAAccepted: true, NDAAcceptedBy: "reviewer"}) @@ -639,6 +641,8 @@ func TestLedgerOperationsRejectActorsWithoutRequiredScopesBeforeResourceWork(t * _, _, err := ledger.CreateCustomerPortalAccess(ctx, actor, CreateCustomerPortalAccessInput{PackageID: "pkg", CustomerName: "ACME", ExpiresAt: fixedNow().AddDate(0, 0, 1)}) return err }}, + {"ListCustomerPortalAccess", func() error { _, err := ledger.ListCustomerPortalAccess(ctx, actor, "pkg"); return err }}, + {"RevokeCustomerPortalAccess", func() error { _, err := ledger.RevokeCustomerPortalAccess(ctx, actor, "access"); return err }}, {"CreateQuestionnaireTemplate", func() error { _, err := ledger.CreateQuestionnaireTemplate(ctx, actor, CreateQuestionnaireTemplateInput{Name: "template", Version: "1"}) return err diff --git a/internal/app/enterprise.go b/internal/app/enterprise.go index 41c89b4..ee9ebc4 100644 --- a/internal/app/enterprise.go +++ b/internal/app/enterprise.go @@ -88,11 +88,13 @@ type CreateRetentionOverrideInput struct { } type CreateCustomerPortalAccessInput struct { - PackageID string - CustomerName string - RequireNDA bool - Watermark string - ExpiresAt time.Time + PackageID string + CustomerName string + ReviewerName string + ReviewerEmail string + RequireNDA bool + Watermark string + ExpiresAt time.Time } type CustomerPortalAcceptanceInput struct { @@ -788,10 +790,15 @@ func (s identityService) CreateCustomerPortalAccess(ctx context.Context, actor d return domain.CustomerPortalAccess{}, "", err } in.PackageID, in.CustomerName = strings.TrimSpace(in.PackageID), cleanExternalLabel(in.CustomerName) + in.ReviewerName = cleanExternalLabel(in.ReviewerName) + in.ReviewerEmail = cleanReviewerEmail(in.ReviewerEmail) in.Watermark = cleanExternalLabel(in.Watermark) if in.PackageID == "" || in.CustomerName == "" || !in.ExpiresAt.After(l.now()) { return domain.CustomerPortalAccess{}, "", ErrValidation } + if in.ReviewerEmail != "" && !validReviewerEmail(in.ReviewerEmail) { + return domain.CustomerPortalAccess{}, "", ErrValidation + } l.mu.Lock() defer l.mu.Unlock() pkg, ok := l.customerPackages[in.PackageID] @@ -802,9 +809,9 @@ func (s identityService) CreateCustomerPortalAccess(ctx context.Context, actor d accessID := newID("cpa") watermark := in.Watermark if watermark == "" { - watermark = packageDistributionWatermark(pkg, in.CustomerName, accessID) + watermark = packageDistributionWatermark(pkg, portalReviewerLabel(in.CustomerName, in.ReviewerName, in.ReviewerEmail), accessID) } - access := domain.CustomerPortalAccess{ID: accessID, TenantID: actor.TenantID, PackageID: pkg.ID, CustomerName: in.CustomerName, RequireNDA: in.RequireNDA, Watermark: watermark, Prefix: secretPrefix(secret), ExpiresAt: in.ExpiresAt.UTC(), SchemaVersion: domain.CustomerPortalAccessVersion, CreatedAt: l.now(), Hash: l.hashSecret(secret)} + access := domain.CustomerPortalAccess{ID: accessID, TenantID: actor.TenantID, PackageID: pkg.ID, CustomerName: in.CustomerName, ReviewerName: in.ReviewerName, ReviewerEmail: in.ReviewerEmail, RequireNDA: in.RequireNDA, Watermark: watermark, Prefix: secretPrefix(secret), ExpiresAt: in.ExpiresAt.UTC(), SchemaVersion: domain.CustomerPortalAccessVersion, CreatedAt: l.now(), Hash: l.hashSecret(secret)} l.portalAccess[access.ID] = access _, _ = l.appendChainLocked(actor.TenantID, "customer_portal_access.created", "customer_security_package", pkg.ID, actorType(actor), actorID(actor), "", "") if err := l.persistCriticalLocked(ctx, l.criticalMutationLocked()); err != nil { @@ -814,6 +821,71 @@ func (s identityService) CreateCustomerPortalAccess(ctx context.Context, actor d return access, secret, nil } +func (s identityService) ListCustomerPortalAccess(ctx context.Context, actor domain.Actor, packageID string) ([]domain.CustomerPortalAccess, error) { + l := s.ledger + if err := ctx.Err(); err != nil { + return nil, err + } + if err := require(actor, ScopePackageRead); err != nil { + return nil, err + } + packageID = strings.TrimSpace(packageID) + l.mu.Lock() + defer l.mu.Unlock() + if packageID != "" { + pkg, ok := l.customerPackages[packageID] + if !ok || pkg.TenantID != actor.TenantID { + return nil, ErrNotFound + } + } + accesses := []domain.CustomerPortalAccess{} + for _, access := range l.portalAccess { + if access.TenantID != actor.TenantID || (packageID != "" && access.PackageID != packageID) { + continue + } + access.Hash = "" + accesses = append(accesses, access) + } + sort.Slice(accesses, func(i, j int) bool { + if accesses[i].CreatedAt.Equal(accesses[j].CreatedAt) { + return accesses[i].ID < accesses[j].ID + } + return accesses[i].CreatedAt.Before(accesses[j].CreatedAt) + }) + return accesses, nil +} + +func (s identityService) RevokeCustomerPortalAccess(ctx context.Context, actor domain.Actor, id string) (domain.CustomerPortalAccess, error) { + l := s.ledger + if err := ctx.Err(); err != nil { + return domain.CustomerPortalAccess{}, err + } + if err := require(actor, ScopePackageWrite); err != nil { + return domain.CustomerPortalAccess{}, err + } + id = strings.TrimSpace(id) + if id == "" { + return domain.CustomerPortalAccess{}, ErrValidation + } + l.mu.Lock() + defer l.mu.Unlock() + access, ok := l.portalAccess[id] + if !ok || access.TenantID != actor.TenantID { + return domain.CustomerPortalAccess{}, ErrNotFound + } + if access.RevokedAt == nil { + now := l.now() + access.RevokedAt = &now + l.portalAccess[id] = access + _, _ = l.appendChainLocked(access.TenantID, "customer_portal_access.revoked", "customer_portal_access", access.ID, actorType(actor), actorID(actor), "", "") + if err := l.persistCriticalLocked(ctx, l.criticalMutationLocked()); err != nil { + return domain.CustomerPortalAccess{}, err + } + } + access.Hash = "" + return access, nil +} + func (s identityService) AccessCustomerPortalPackage(ctx context.Context, token string) (domain.CustomerSecurityPackage, error) { return s.AccessCustomerPortalPackageWithAcceptance(ctx, token, CustomerPortalAcceptanceInput{}) } @@ -888,6 +960,18 @@ func (l *Ledger) appendCustomerPortalAccessEventLocked(entryType string, access _, _ = l.appendChainLocked(access.TenantID, entryType, "customer_security_package", pkg.ID, "customer_portal", access.ID, pkg.ManifestHash, "") } +func cleanReviewerEmail(value string) string { + return strings.ToLower(cleanExternalLabel(value)) +} + +func validReviewerEmail(value string) bool { + if strings.ContainsAny(value, " \t\r\n") { + return false + } + at := strings.IndexByte(value, '@') + return at > 0 && at < len(value)-1 && strings.Contains(value[at+1:], ".") +} + func (s packageReportService) CreateQuestionnaireTemplate(ctx context.Context, actor domain.Actor, in CreateQuestionnaireTemplateInput) (domain.QuestionnaireTemplate, error) { l := s.ledger if err := ctx.Err(); err != nil { diff --git a/internal/app/enterprise_test.go b/internal/app/enterprise_test.go index 2f3c81d..b7aee35 100644 --- a/internal/app/enterprise_test.go +++ b/internal/app/enterprise_test.go @@ -532,13 +532,20 @@ func TestCustomerPortalRetentionQuestionnairesAndCommercialCollectors(t *testing if err != nil { t.Fatalf("customer package: %v", err) } - access, token, err := ledger.CreateCustomerPortalAccess(ctx, actor, CreateCustomerPortalAccessInput{PackageID: pkg.ID, CustomerName: "ACME", RequireNDA: true, Watermark: "ACME confidential review copy", ExpiresAt: fixedNow().Add(time.Hour)}) + access, token, err := ledger.CreateCustomerPortalAccess(ctx, actor, CreateCustomerPortalAccessInput{PackageID: pkg.ID, CustomerName: "ACME", ReviewerName: "Alice Reviewer", ReviewerEmail: "ALICE.REVIEWER@EXAMPLE.TEST", RequireNDA: true, Watermark: "ACME confidential review copy", ExpiresAt: fixedNow().Add(time.Hour)}) if err != nil { t.Fatalf("portal access: %v", err) } - if token == "" || access.Hash != "" || !access.RequireNDA || access.Watermark == "" { + if token == "" || access.Hash != "" || !access.RequireNDA || access.Watermark == "" || access.ReviewerName != "Alice Reviewer" || access.ReviewerEmail != "alice.reviewer@example.test" { t.Fatalf("portal token/hash leakage access=%#v token=%q", access, token) } + listedAccess, err := ledger.ListCustomerPortalAccess(ctx, actor, pkg.ID) + if err != nil || len(listedAccess) != 1 || listedAccess[0].ID != access.ID || listedAccess[0].Hash != "" || listedAccess[0].ReviewerEmail != "alice.reviewer@example.test" { + t.Fatalf("portal access list=%#v err=%v", listedAccess, err) + } + if _, _, err := ledger.CreateCustomerPortalAccess(ctx, actor, CreateCustomerPortalAccessInput{PackageID: pkg.ID, CustomerName: "ACME", ReviewerEmail: "not an email", ExpiresAt: fixedNow().Add(time.Hour)}); !errors.Is(err, ErrValidation) { + t.Fatalf("invalid reviewer email err=%v, want validation", err) + } if _, err := ledger.AccessCustomerPortalPackage(ctx, token); !errors.Is(err, ErrForbidden) { t.Fatalf("NDA-gated portal package without acceptance err=%v, want forbidden", err) } @@ -604,6 +611,16 @@ func TestCustomerPortalRetentionQuestionnairesAndCommercialCollectors(t *testing if got := metrics["customer_portal_failed_access_count"]; got != 1 { t.Fatalf("portal failed access metric = %#v, want 1", got) } + revokedAccess, err := ledger.RevokeCustomerPortalAccess(ctx, actor, access.ID) + if err != nil { + t.Fatalf("revoke portal access: %v", err) + } + if revokedAccess.RevokedAt == nil || revokedAccess.Hash != "" { + t.Fatalf("revoked portal access leaked hash or missed timestamp: %#v", revokedAccess) + } + if _, err := ledger.AccessCustomerPortalPackage(ctx, token); !errors.Is(err, ErrUnauthorized) { + t.Fatalf("revoked reviewer token err=%v, want unauthorized", err) + } if _, err := ledger.CreateLegalHold(ctx, actor, CreateLegalHoldInput{ScopeType: "release", ScopeID: release.ID, Reason: "customer dispute", Owner: "legal"}); err != nil { t.Fatalf("legal hold: %v", err) } @@ -654,6 +671,12 @@ func TestCustomerPortalRetentionQuestionnairesAndCommercialCollectors(t *testing if _, _, err := ledger.CreateCustomerPortalAccess(ctx, other, CreateCustomerPortalAccessInput{PackageID: pkg.ID, CustomerName: "bad", ExpiresAt: fixedNow().Add(time.Hour)}); !errors.Is(err, ErrNotFound) { t.Fatalf("cross tenant portal err=%v, want not found", err) } + if _, err := ledger.ListCustomerPortalAccess(ctx, other, pkg.ID); !errors.Is(err, ErrNotFound) { + t.Fatalf("cross tenant portal list err=%v, want not found", err) + } + if _, err := ledger.RevokeCustomerPortalAccess(ctx, other, access.ID); !errors.Is(err, ErrNotFound) { + t.Fatalf("cross tenant portal revoke err=%v, want not found", err) + } if _, err := ledger.CreateQuestionnaireAnswerLibraryEntry(ctx, other, CreateQuestionnaireAnswerLibraryEntryInput{QuestionID: "q1", ProductID: release.ProductID, ReleaseID: release.ID, Answer: "bad"}); !errors.Is(err, ErrNotFound) { t.Fatalf("cross tenant answer library err=%v, want not found", err) } diff --git a/internal/app/governance_packages.go b/internal/app/governance_packages.go index 84681b8..e1b5bf3 100644 --- a/internal/app/governance_packages.go +++ b/internal/app/governance_packages.go @@ -1230,13 +1230,26 @@ func (s packageReportService) SecurityReviewPackageReport(ctx context.Context, a } func packageWithDistributionWatermark(pkg domain.CustomerSecurityPackage, access domain.CustomerPortalAccess) domain.CustomerSecurityPackage { - pkg.DistributionWatermark = packageDistributionWatermark(pkg, access.CustomerName, access.ID) + pkg.DistributionWatermark = packageDistributionWatermark(pkg, portalReviewerLabel(access.CustomerName, access.ReviewerName, access.ReviewerEmail), access.ID) if access.Watermark != "" { pkg.DistributionWatermark = access.Watermark } return pkg } +func portalReviewerLabel(customerName, reviewerName, reviewerEmail string) string { + if reviewerName != "" && reviewerEmail != "" { + return reviewerName + " <" + reviewerEmail + ">" + } + if reviewerEmail != "" { + return reviewerEmail + } + if reviewerName != "" { + return reviewerName + } + return customerName +} + func packageDistributionWatermark(pkg domain.CustomerSecurityPackage, customerName, accessID string) string { customerName = cleanExternalLabel(customerName) accessID = strings.TrimSpace(accessID) diff --git a/internal/app/identity_service.go b/internal/app/identity_service.go index d77e24c..519227a 100644 --- a/internal/app/identity_service.go +++ b/internal/app/identity_service.go @@ -215,6 +215,14 @@ func (l *Ledger) CreateCustomerPortalAccess(ctx context.Context, actor domain.Ac return l.identityService().CreateCustomerPortalAccess(ctx, actor, in) } +func (l *Ledger) ListCustomerPortalAccess(ctx context.Context, actor domain.Actor, packageID string) ([]domain.CustomerPortalAccess, error) { + return l.identityService().ListCustomerPortalAccess(ctx, actor, packageID) +} + +func (l *Ledger) RevokeCustomerPortalAccess(ctx context.Context, actor domain.Actor, id string) (domain.CustomerPortalAccess, error) { + return l.identityService().RevokeCustomerPortalAccess(ctx, actor, id) +} + func (l *Ledger) AccessCustomerPortalPackage(ctx context.Context, token string) (domain.CustomerSecurityPackage, error) { return l.identityService().AccessCustomerPortalPackage(ctx, token) } diff --git a/internal/domain/domain.go b/internal/domain/domain.go index c18cd3a..3e68992 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -890,6 +890,8 @@ type CustomerPortalAccess struct { TenantID string `json:"tenant_id"` PackageID string `json:"package_id"` CustomerName string `json:"customer_name"` + ReviewerName string `json:"reviewer_name,omitempty"` + ReviewerEmail string `json:"reviewer_email,omitempty"` RequireNDA bool `json:"require_nda"` NDAAcceptedAt *time.Time `json:"nda_accepted_at,omitempty"` NDAAcceptedBy string `json:"nda_accepted_by,omitempty"` diff --git a/migrations/20260601000500_customer_portal_reviewers.down.sql b/migrations/20260601000500_customer_portal_reviewers.down.sql new file mode 100644 index 0000000..2f112ef --- /dev/null +++ b/migrations/20260601000500_customer_portal_reviewers.down.sql @@ -0,0 +1,5 @@ +DROP INDEX IF EXISTS customer_portal_access_tenant_reviewer_idx; + +ALTER TABLE customer_portal_access + DROP COLUMN IF EXISTS reviewer_email, + DROP COLUMN IF EXISTS reviewer_name; diff --git a/migrations/20260601000500_customer_portal_reviewers.up.sql b/migrations/20260601000500_customer_portal_reviewers.up.sql new file mode 100644 index 0000000..853fdcf --- /dev/null +++ b/migrations/20260601000500_customer_portal_reviewers.up.sql @@ -0,0 +1,6 @@ +ALTER TABLE customer_portal_access + ADD COLUMN IF NOT EXISTS reviewer_name text, + ADD COLUMN IF NOT EXISTS reviewer_email text; + +CREATE INDEX IF NOT EXISTS customer_portal_access_tenant_reviewer_idx + ON customer_portal_access (tenant_id, reviewer_email, created_at); diff --git a/openapi.yaml b/openapi.yaml index dd4368c..8fe6c45 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CRAVulnerabilityHandlingReport":{"additionalProperties":false,"properties":{"accepted_exceptions":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"CRAVulnerabilityHandlingReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"},"require_nda":{"type":"boolean"},"watermark":{"description":"Optional customer-visible distribution watermark. It is not a token or secret.","type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireAnswerLibraryEntryRequest":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"}},"required":["answer"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"type":"object"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"nda_accepted":{"description":"Set true to record acceptance for NDA-gated portal access.","type":"boolean"},"nda_accepted_by":{"description":"Reviewer label recorded when NDA acceptance is required. Do not include secrets.","type":"string"},"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"distribution_watermark":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"remediation":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntry":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","answer","schema_version","created_at"],"type":"object"},"QuestionnaireAnswerLibraryEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"policy_set":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlow":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["needs_evidence","ready_for_review"],"type":"string"},"steps":{"items":{"$ref":"#/components/schemas/ReleaseEvidenceFlowStep"},"type":"array"}},"required":["release_id","product_id","status","counts","steps","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseEvidenceFlowEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseEvidenceFlow"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlowStep":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"idempotency_required":{"type":"boolean"},"method":{"type":"string"},"next_reference":{"type":"string"},"path":{"type":"string"},"required":{"type":"boolean"},"required_scopes":{"items":{"type":"string"},"type":"array"},"status":{"enum":["present","missing","optional"],"type":"string"},"title":{"type":"string"}},"required":["id","title","status","required","method","path","required_scopes","idempotency_required","description"],"type":"object"},"ReleaseSecurityApprovalSummary":{"additionalProperties":false,"properties":{"approved":{"type":"integer"},"total":{"type":"integer"}},"required":["total","approved"],"type":"object"},"ReleaseSecurityExceptionSummary":{"additionalProperties":false,"properties":{"approved_unexpired":{"type":"integer"},"expired":{"type":"integer"},"total":{"type":"integer"},"unapproved":{"type":"integer"}},"required":["total","approved_unexpired","unapproved","expired"],"type":"object"},"ReleaseSecurityMissingDecision":{"additionalProperties":false,"properties":{"component":{"type":"string"},"finding_id":{"type":"string"},"scan_id":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["finding_id","scan_id","vulnerability","severity","state"],"type":"object"},"ReleaseSecurityProductSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"],"type":"object"},"ReleaseSecurityReleaseSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"state":{"type":"string"},"version":{"type":"string"}},"required":["id","version","state"],"type":"object"},"ReleaseSecuritySummary":{"additionalProperties":false,"properties":{"approval_summary":{"$ref":"#/components/schemas/ReleaseSecurityApprovalSummary"},"artifact_count":{"type":"integer"},"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"decisions_by_status":{"additionalProperties":{"type":"integer"},"type":"object"},"exception_summary":{"$ref":"#/components/schemas/ReleaseSecurityExceptionSummary"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_required_decisions":{"items":{"$ref":"#/components/schemas/ReleaseSecurityMissingDecision"},"type":"array"},"open_findings_by_severity":{"additionalProperties":{"type":"integer"},"type":"object"},"package_status":{"enum":["generated","not_generated"],"type":"string"},"product":{"$ref":"#/components/schemas/ReleaseSecurityProductSummary"},"readiness_status":{"enum":["passed","failed"],"type":"string"},"release":{"$ref":"#/components/schemas/ReleaseSecurityReleaseSummary"},"sbom_status":{"enum":["present","missing"],"type":"string"},"schema_version":{"type":"string"},"vulnerability_scan_status":{"enum":["present","missing"],"type":"string"}},"required":["product","release","artifact_count","sbom_status","vulnerability_scan_status","open_findings_by_severity","decisions_by_status","approval_summary","exception_summary","readiness_status","package_status","counts","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseSecuritySummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseSecuritySummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityUpdateEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"fixed_decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incidents":{"items":{"$ref":"#/components/schemas/Incident"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"remediation_tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"SecurityUpdateEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningCustodyReviewReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"object_retention_policies":{"items":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"type":"array"},"report_type":{"type":"string"},"signing_providers":{"items":{"$ref":"#/components/schemas/SigningProvider"},"type":"array"},"tenant_id":{"type":"string"}},"required":["report_type","tenant_id","checks","assumptions","limitations","generated_at"],"type":"object"},"SigningCustodyReviewReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningCustodyReviewReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"examples":{"release-evidence-package":{"summary":"Create a scoped release evidence package","value":{"expires_at":"2026-06-30T00:00:00Z","product_id":"prod_20260527120000","redaction_profile_id":"rp_20260527120000","release_id":"rel_20260527120000","title":"Payments API 1.0.0 release evidence package"}}},"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"post":{"description":"Creates token-based customer portal access for a customer package and returns the token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-answer-library":{"get":{"description":"Lists tenant-scoped questionnaire answer library entries with optional question, product, and release filters.","operationId":"listQuestionnaireAnswerLibrary","parameters":[{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by questionnaire question id.","in":"query","name":"question_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryListEnvelope"}}},"description":"Questionnaire answer library entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List questionnaire answer library entries","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a tenant-scoped reusable questionnaire answer draft linked to optional evidence, product, release, or control scope.","operationId":"createQuestionnaireAnswerLibraryEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireAnswerLibraryEntryRequest"}}},"description":"Questionnaire answer library entry creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryEnvelope"}}},"description":"Created questionnaire answer library entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire answer library entry","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"examples":{"release-candidate":{"summary":"Create a release for evidence collection","value":{"product_id":"prod_20260527120000","project_id":"proj_20260527120000","version":"1.0.0-rc.1"}}},"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"examples":{"created-release":{"summary":"Created release response","value":{"data":{"created_at":"2026-05-27T12:00:00Z","id":"rel_20260527120000","product_id":"prod_20260527120000","project_id":"proj_20260527120000","schema_version":"release.v1.0.0","status":"draft","tenant_id":"ten_20260527120000","version":"1.0.0-rc.1"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/evidence-flow/start":{"post":{"description":"Returns a high-level release evidence workflow plan, current evidence counts, required scopes, assumptions, and limitations. This read-only convenience operation does not create evidence.","operationId":"startReleaseEvidenceFlow","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEvidenceFlowEnvelope"}}},"description":"Release evidence flow envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Start release evidence flow","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:read"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/security-summary":{"get":{"description":"Returns a tenant-scoped release security summary for review surfaces without raw evidence payload bytes.","operationId":"releaseSecuritySummary","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseSecuritySummaryEnvelope"}}},"description":"Release security summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release security summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-vulnerability-handling":{"get":{"description":"Returns a CRA-oriented vulnerability handling evidence report without legal compliance, certification, scanner-authority, or release-security conclusions.","operationId":"craVulnerabilityHandlingReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReportEnvelope"}}},"description":"CRA vulnerability handling report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA vulnerability handling report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/custody-review":{"get":{"description":"Returns tenant signing-provider and object-lock verification metadata for deployment custody review. It is evidence metadata only, not legal compliance proof, certification, HSM custody proof, or a secure-deployment guarantee.","operationId":"signingCustodyReviewReport","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningCustodyReviewReportEnvelope"}}},"description":"Signing custody review report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Signing custody review report","tags":["evydence"],"x-scopes":["keys:admin"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"examples":{"failed-readiness-with-gap":{"summary":"Readiness report with a vulnerability decision gap","value":{"data":{"accepted_exceptions":[],"assumptions":["Readiness is based on tenant evidence recorded in Evydence."],"blocking_findings":[{"component":"pkg:apk/openssl@3.1.0-r0","decision_state":"missing","finding_id":"scan_20260527120000:finding:1","release_id":"rel_20260527120000","scan_id":"scan_20260527120000","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"generated_at":"2026-05-27T12:00:00Z","limitations":["Readiness supports technical review and does not prove legal compliance, certification, complete vulnerability coverage, or release security."],"missing_evidence":["vulnerability_decision"],"policy_set":"policy-set.v1.0.0","product_id":"prod_20260527120000","release_id":"rel_20260527120000","report_type":"release_readiness","result":"failed","schema_version":"release-readiness.v1.0.0","summary":{"headline":"Release evidence has one blocking vulnerability decision gap.","human_summary":"Required artifact, SBOM, scan, build, and bundle evidence is present, but one critical finding still needs a valid decision or approved exception.","policy_set":"policy-set.v1.0.0","result":"failed"},"template_version":"release-readiness.v1.0.0"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/security-update-evidence":{"get":{"description":"Returns a security update evidence report for release-scoped fixed decisions, incidents, remediation tasks, and linked evidence without legal or security conclusions.","operationId":"securityUpdateEvidenceReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReportEnvelope"}}},"description":"Security update evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security update evidence report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"examples":{"cyclonedx-release-sbom":{"summary":"Upload a CycloneDX SBOM linked to the release artifact","value":{"artifact_id":"art_20260527120000","payload":{"bomFormat":"CycloneDX","components":[{"name":"payments-api","purl":"pkg:oci/payments-api@sha256-ca978112","version":"1.0.0-rc.1"},{"name":"openssl","purl":"pkg:apk/openssl@3.1.0-r0","version":"3.1.0-r0"}],"specVersion":"1.6"},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"examples":{"not-affected-decision":{"summary":"Record a customer-visible not-affected decision","value":{"customer_visible":true,"evidence_ids":["ev_20260527120000"],"impact_statement":"The shipped artifact does not include the affected runtime path.","justification":"The vulnerable code path is not reachable in this release.","status":"not_affected"}}},"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"examples":{"generic-critical-finding":{"summary":"Upload a generic scanner finding for release triage","value":{"findings":[{"component":"pkg:apk/openssl@3.1.0-r0","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"release_id":"rel_20260527120000","scanner":"generic-json","target_ref":"pkg:oci/payments-api@sha256-ca978112"}}},"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CRAVulnerabilityHandlingReport":{"additionalProperties":false,"properties":{"accepted_exceptions":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"CRAVulnerabilityHandlingReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"},"require_nda":{"type":"boolean"},"reviewer_email":{"description":"Optional external reviewer email label. It is not used as an authentication secret.","type":"string"},"reviewer_name":{"description":"Optional external reviewer display name for this package access record.","type":"string"},"watermark":{"description":"Optional customer-visible distribution watermark. It is not a token or secret.","type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireAnswerLibraryEntryRequest":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"}},"required":["answer"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccess":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"failed_access_count":{"type":"integer"},"id":{"type":"string"},"last_accessed_at":{"format":"date-time","type":"string"},"last_failed_at":{"format":"date-time","type":"string"},"nda_accepted_at":{"format":"date-time","type":"string"},"nda_accepted_by":{"type":"string"},"package_id":{"type":"string"},"prefix":{"description":"Non-secret portal token prefix for operational lookup.","type":"string"},"require_nda":{"type":"boolean"},"reviewer_email":{"type":"string"},"reviewer_name":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"watermark":{"type":"string"}},"required":["id","tenant_id","package_id","customer_name","prefix","expires_at","access_count","failed_access_count","schema_version","created_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"$ref":"#/components/schemas/CustomerPortalAccess"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalAccessEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccess"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CustomerPortalAccess"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"nda_accepted":{"description":"Set true to record acceptance for NDA-gated portal access.","type":"boolean"},"nda_accepted_by":{"description":"Reviewer label recorded when NDA acceptance is required. Do not include secrets.","type":"string"},"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"distribution_watermark":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"remediation":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntry":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","answer","schema_version","created_at"],"type":"object"},"QuestionnaireAnswerLibraryEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"policy_set":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlow":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["needs_evidence","ready_for_review"],"type":"string"},"steps":{"items":{"$ref":"#/components/schemas/ReleaseEvidenceFlowStep"},"type":"array"}},"required":["release_id","product_id","status","counts","steps","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseEvidenceFlowEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseEvidenceFlow"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlowStep":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"idempotency_required":{"type":"boolean"},"method":{"type":"string"},"next_reference":{"type":"string"},"path":{"type":"string"},"required":{"type":"boolean"},"required_scopes":{"items":{"type":"string"},"type":"array"},"status":{"enum":["present","missing","optional"],"type":"string"},"title":{"type":"string"}},"required":["id","title","status","required","method","path","required_scopes","idempotency_required","description"],"type":"object"},"ReleaseSecurityApprovalSummary":{"additionalProperties":false,"properties":{"approved":{"type":"integer"},"total":{"type":"integer"}},"required":["total","approved"],"type":"object"},"ReleaseSecurityExceptionSummary":{"additionalProperties":false,"properties":{"approved_unexpired":{"type":"integer"},"expired":{"type":"integer"},"total":{"type":"integer"},"unapproved":{"type":"integer"}},"required":["total","approved_unexpired","unapproved","expired"],"type":"object"},"ReleaseSecurityMissingDecision":{"additionalProperties":false,"properties":{"component":{"type":"string"},"finding_id":{"type":"string"},"scan_id":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["finding_id","scan_id","vulnerability","severity","state"],"type":"object"},"ReleaseSecurityProductSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"],"type":"object"},"ReleaseSecurityReleaseSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"state":{"type":"string"},"version":{"type":"string"}},"required":["id","version","state"],"type":"object"},"ReleaseSecuritySummary":{"additionalProperties":false,"properties":{"approval_summary":{"$ref":"#/components/schemas/ReleaseSecurityApprovalSummary"},"artifact_count":{"type":"integer"},"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"decisions_by_status":{"additionalProperties":{"type":"integer"},"type":"object"},"exception_summary":{"$ref":"#/components/schemas/ReleaseSecurityExceptionSummary"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_required_decisions":{"items":{"$ref":"#/components/schemas/ReleaseSecurityMissingDecision"},"type":"array"},"open_findings_by_severity":{"additionalProperties":{"type":"integer"},"type":"object"},"package_status":{"enum":["generated","not_generated"],"type":"string"},"product":{"$ref":"#/components/schemas/ReleaseSecurityProductSummary"},"readiness_status":{"enum":["passed","failed"],"type":"string"},"release":{"$ref":"#/components/schemas/ReleaseSecurityReleaseSummary"},"sbom_status":{"enum":["present","missing"],"type":"string"},"schema_version":{"type":"string"},"vulnerability_scan_status":{"enum":["present","missing"],"type":"string"}},"required":["product","release","artifact_count","sbom_status","vulnerability_scan_status","open_findings_by_severity","decisions_by_status","approval_summary","exception_summary","readiness_status","package_status","counts","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseSecuritySummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseSecuritySummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityUpdateEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"fixed_decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incidents":{"items":{"$ref":"#/components/schemas/Incident"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"remediation_tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"SecurityUpdateEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningCustodyReviewReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"object_retention_policies":{"items":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"type":"array"},"report_type":{"type":"string"},"signing_providers":{"items":{"$ref":"#/components/schemas/SigningProvider"},"type":"array"},"tenant_id":{"type":"string"}},"required":["report_type","tenant_id","checks","assumptions","limitations","generated_at"],"type":"object"},"SigningCustodyReviewReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningCustodyReviewReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"examples":{"release-evidence-package":{"summary":"Create a scoped release evidence package","value":{"expires_at":"2026-06-30T00:00:00Z","product_id":"prod_20260527120000","redaction_profile_id":"rp_20260527120000","release_id":"rel_20260527120000","title":"Payments API 1.0.0 release evidence package"}}},"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"get":{"description":"Lists tenant-scoped external reviewer access records without token hashes or token secrets.","operationId":"listCustomerPortalAccess","parameters":[{"description":"Optional customer package id filter.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessListEnvelope"}}},"description":"Customer portal access list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List customer portal access records","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a named, expiring external reviewer access record for a customer package and returns the portal token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/access/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped external reviewer access record; revocation is append-only and the original token cannot be used afterwards.","operationId":"revokeCustomerPortalAccess","parameters":[{"description":"Customer portal access id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessEnvelope"}}},"description":"Revoked customer portal access envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-answer-library":{"get":{"description":"Lists tenant-scoped questionnaire answer library entries with optional question, product, and release filters.","operationId":"listQuestionnaireAnswerLibrary","parameters":[{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by questionnaire question id.","in":"query","name":"question_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryListEnvelope"}}},"description":"Questionnaire answer library entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List questionnaire answer library entries","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a tenant-scoped reusable questionnaire answer draft linked to optional evidence, product, release, or control scope.","operationId":"createQuestionnaireAnswerLibraryEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireAnswerLibraryEntryRequest"}}},"description":"Questionnaire answer library entry creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryEnvelope"}}},"description":"Created questionnaire answer library entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire answer library entry","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"examples":{"release-candidate":{"summary":"Create a release for evidence collection","value":{"product_id":"prod_20260527120000","project_id":"proj_20260527120000","version":"1.0.0-rc.1"}}},"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"examples":{"created-release":{"summary":"Created release response","value":{"data":{"created_at":"2026-05-27T12:00:00Z","id":"rel_20260527120000","product_id":"prod_20260527120000","project_id":"proj_20260527120000","schema_version":"release.v1.0.0","status":"draft","tenant_id":"ten_20260527120000","version":"1.0.0-rc.1"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/evidence-flow/start":{"post":{"description":"Returns a high-level release evidence workflow plan, current evidence counts, required scopes, assumptions, and limitations. This read-only convenience operation does not create evidence.","operationId":"startReleaseEvidenceFlow","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEvidenceFlowEnvelope"}}},"description":"Release evidence flow envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Start release evidence flow","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:read"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/security-summary":{"get":{"description":"Returns a tenant-scoped release security summary for review surfaces without raw evidence payload bytes.","operationId":"releaseSecuritySummary","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseSecuritySummaryEnvelope"}}},"description":"Release security summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release security summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-vulnerability-handling":{"get":{"description":"Returns a CRA-oriented vulnerability handling evidence report without legal compliance, certification, scanner-authority, or release-security conclusions.","operationId":"craVulnerabilityHandlingReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReportEnvelope"}}},"description":"CRA vulnerability handling report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA vulnerability handling report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/custody-review":{"get":{"description":"Returns tenant signing-provider and object-lock verification metadata for deployment custody review. It is evidence metadata only, not legal compliance proof, certification, HSM custody proof, or a secure-deployment guarantee.","operationId":"signingCustodyReviewReport","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningCustodyReviewReportEnvelope"}}},"description":"Signing custody review report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Signing custody review report","tags":["evydence"],"x-scopes":["keys:admin"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"examples":{"failed-readiness-with-gap":{"summary":"Readiness report with a vulnerability decision gap","value":{"data":{"accepted_exceptions":[],"assumptions":["Readiness is based on tenant evidence recorded in Evydence."],"blocking_findings":[{"component":"pkg:apk/openssl@3.1.0-r0","decision_state":"missing","finding_id":"scan_20260527120000:finding:1","release_id":"rel_20260527120000","scan_id":"scan_20260527120000","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"generated_at":"2026-05-27T12:00:00Z","limitations":["Readiness supports technical review and does not prove legal compliance, certification, complete vulnerability coverage, or release security."],"missing_evidence":["vulnerability_decision"],"policy_set":"policy-set.v1.0.0","product_id":"prod_20260527120000","release_id":"rel_20260527120000","report_type":"release_readiness","result":"failed","schema_version":"release-readiness.v1.0.0","summary":{"headline":"Release evidence has one blocking vulnerability decision gap.","human_summary":"Required artifact, SBOM, scan, build, and bundle evidence is present, but one critical finding still needs a valid decision or approved exception.","policy_set":"policy-set.v1.0.0","result":"failed"},"template_version":"release-readiness.v1.0.0"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/security-update-evidence":{"get":{"description":"Returns a security update evidence report for release-scoped fixed decisions, incidents, remediation tasks, and linked evidence without legal or security conclusions.","operationId":"securityUpdateEvidenceReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReportEnvelope"}}},"description":"Security update evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security update evidence report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"examples":{"cyclonedx-release-sbom":{"summary":"Upload a CycloneDX SBOM linked to the release artifact","value":{"artifact_id":"art_20260527120000","payload":{"bomFormat":"CycloneDX","components":[{"name":"payments-api","purl":"pkg:oci/payments-api@sha256-ca978112","version":"1.0.0-rc.1"},{"name":"openssl","purl":"pkg:apk/openssl@3.1.0-r0","version":"3.1.0-r0"}],"specVersion":"1.6"},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"examples":{"not-affected-decision":{"summary":"Record a customer-visible not-affected decision","value":{"customer_visible":true,"evidence_ids":["ev_20260527120000"],"impact_statement":"The shipped artifact does not include the affected runtime path.","justification":"The vulnerable code path is not reachable in this release.","status":"not_affected"}}},"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"examples":{"generic-critical-finding":{"summary":"Upload a generic scanner finding for release triage","value":{"findings":[{"component":"pkg:apk/openssl@3.1.0-r0","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"release_id":"rel_20260527120000","scanner":"generic-json","target_ref":"pkg:oci/payments-api@sha256-ca978112"}}},"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/sdk/openapi-route-catalog.json b/sdk/openapi-route-catalog.json index c2524bf..8ca8662 100644 --- a/sdk/openapi-route-catalog.json +++ b/sdk/openapi-route-catalog.json @@ -1,5 +1,5 @@ { - "route_count": 176, + "route_count": 178, "routes": [ { "idempotency_key_required": false, @@ -663,6 +663,23 @@ "200" ] }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "listCustomerPortalAccess", + "path": "/v1/customer-portal/access", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/CustomerPortalAccessListEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "package:read" + ], + "success_statuses": [ + "200" + ] + }, { "idempotency_key_required": true, "method": "POST", @@ -680,6 +697,23 @@ "201" ] }, + { + "idempotency_key_required": true, + "method": "POST", + "operation_id": "revokeCustomerPortalAccess", + "path": "/v1/customer-portal/access/{id}/revoke", + "request_schema": "#/components/schemas/EmptyObject", + "response_schemas": [ + "#/components/schemas/CustomerPortalAccessEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "package:write" + ], + "success_statuses": [ + "200" + ] + }, { "idempotency_key_required": true, "method": "POST", From 4a68d40d7f925f0241271c08f1ae320bf346005d Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Sun, 31 May 2026 23:12:52 +0300 Subject: [PATCH 212/287] fix(postgres): normalize empty text arrays --- internal/adapters/postgres/sql_helpers.go | 7 ++++ internal/adapters/postgres/store.go | 40 +++++++++++------------ 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/internal/adapters/postgres/sql_helpers.go b/internal/adapters/postgres/sql_helpers.go index e18a681..aa0cb6b 100644 --- a/internal/adapters/postgres/sql_helpers.go +++ b/internal/adapters/postgres/sql_helpers.go @@ -70,6 +70,13 @@ func nullableBytes(value []byte) any { return value } +func textArray(value []string) []string { + if value == nil { + return []string{} + } + return value +} + func nonZeroTime(value time.Time) time.Time { if value.IsZero() { return time.Now().UTC() diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index 5499660..4213305 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -3289,7 +3289,7 @@ func syncRiskBuildControlRows(ctx context.Context, tx pgx.Tx, state app.Persiste updated_at = EXCLUDED.updated_at `, report.ID, report.TenantID, report.VEXDocumentID, report.EvidenceID, nullableString(report.ReleaseID), nullableString(report.ArtifactID), report.ParserVersion, report.Status, report.StatementCount, report.DecisionsCreated, - report.DecisionsSuperseded, report.UnsupportedFields, warnings, invalidStatements, + report.DecisionsSuperseded, textArray(report.UnsupportedFields), warnings, invalidStatements, mappingFailures, report.SchemaVersion, nonZeroTime(report.CreatedAt), nonZeroTime(report.UpdatedAt)); err != nil { return fmt.Errorf("upsert vex import report row: %w", err) } @@ -3322,7 +3322,7 @@ func syncRiskBuildControlRows(ctx context.Context, tx pgx.Tx, state app.Persiste END `, decision.ID, decision.TenantID, decision.FindingID, decision.ScanID, nullableString(decision.ReleaseID), decision.Vulnerability, nullableString(decision.Component), decision.Status, decision.Justification, nullableString(decision.ImpactStatement), nullableString(decision.ActionStatement), - decision.CustomerVisible, nullableString(decision.InternalNotes), decision.Source, nullableString(decision.EvidenceID), decision.EvidenceIDs, nullableString(decision.VEXDocumentID), nullableString(decision.Supersedes), nullableString(decision.SupersededBy), + decision.CustomerVisible, nullableString(decision.InternalNotes), decision.Source, nullableString(decision.EvidenceID), textArray(decision.EvidenceIDs), nullableString(decision.VEXDocumentID), nullableString(decision.Supersedes), nullableString(decision.SupersededBy), nullableString(decision.ApprovedBy), decision.SchemaVersion, nonZeroTime(decision.CreatedAt)); err != nil { return fmt.Errorf("upsert vulnerability decision row: %w", err) } @@ -3935,7 +3935,7 @@ func syncIntegrityProviderRows(ctx context.Context, tx pgx.Tx, state app.Persist schema_version = EXCLUDED.schema_version `, release.ID, release.TenantID, release.CollectorID, release.Version, release.ArtifactDigest, nullableString(release.SignatureID), nullableString(release.SBOMID), nullableString(release.ScanID), - release.Pinned, release.VerificationStatus, release.HealthStatus, release.Limitations, + release.Pinned, release.VerificationStatus, release.HealthStatus, textArray(release.Limitations), release.SchemaVersion, nonZeroTime(release.CreatedAt)); err != nil { return fmt.Errorf("upsert collector release row: %w", err) } @@ -3991,7 +3991,7 @@ func syncIntegrityProviderRows(ctx context.Context, tx pgx.Tx, state app.Persist ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) ON CONFLICT (id) DO UPDATE SET signature_refs = EXCLUDED.signature_refs, schema_version = EXCLUDED.schema_version - `, batch.ID, batch.TenantID, batch.FromSequence, batch.ToSequence, batch.EntryCount, batch.LeafHashes, batch.RootHash, batch.SignatureRefs, batch.SchemaVersion, nonZeroTime(batch.CreatedAt)); err != nil { + `, batch.ID, batch.TenantID, batch.FromSequence, batch.ToSequence, batch.EntryCount, textArray(batch.LeafHashes), batch.RootHash, textArray(batch.SignatureRefs), batch.SchemaVersion, nonZeroTime(batch.CreatedAt)); err != nil { return fmt.Errorf("upsert merkle batch row: %w", err) } } @@ -4030,7 +4030,7 @@ func syncPackageReportRetentionRows(ctx context.Context, tx pgx.Tx, state app.Pe allowed_types = EXCLUDED.allowed_types, excluded_fields = EXCLUDED.excluded_fields, schema_version = EXCLUDED.schema_version - `, profile.ID, profile.TenantID, profile.Name, nullableString(profile.Description), profile.AllowedTypes, profile.ExcludedFields, profile.SchemaVersion, nonZeroTime(profile.CreatedAt)); err != nil { + `, profile.ID, profile.TenantID, profile.Name, nullableString(profile.Description), textArray(profile.AllowedTypes), textArray(profile.ExcludedFields), profile.SchemaVersion, nonZeroTime(profile.CreatedAt)); err != nil { return fmt.Errorf("upsert redaction profile row: %w", err) } } @@ -4090,7 +4090,7 @@ func syncPackageReportRetentionRows(ctx context.Context, tx pgx.Tx, state app.Pe allowed_fields = EXCLUDED.allowed_fields, template = EXCLUDED.template, schema_version = EXCLUDED.schema_version - `, template.ID, template.TenantID, template.Name, template.Version, template.ReportType, template.AllowedFields, template.Template, template.SchemaVersion, nonZeroTime(template.CreatedAt)); err != nil { + `, template.ID, template.TenantID, template.Name, template.Version, template.ReportType, textArray(template.AllowedFields), template.Template, template.SchemaVersion, nonZeroTime(template.CreatedAt)); err != nil { return fmt.Errorf("upsert report template row: %w", err) } } @@ -4133,7 +4133,7 @@ func syncPackageReportRetentionRows(ctx context.Context, tx pgx.Tx, state app.Pe signature_refs = EXCLUDED.signature_refs, verification_text = EXCLUDED.verification_text, schema_version = EXCLUDED.schema_version - `, bundle.ID, bundle.TenantID, nullableString(bundle.ReleaseID), bundle.EvidenceIDs, manifest, bundle.ManifestHash, bundle.SignatureRefs, bundle.VerificationText, bundle.SchemaVersion, nonZeroTime(bundle.CreatedAt)); err != nil { + `, bundle.ID, bundle.TenantID, nullableString(bundle.ReleaseID), textArray(bundle.EvidenceIDs), manifest, bundle.ManifestHash, textArray(bundle.SignatureRefs), bundle.VerificationText, bundle.SchemaVersion, nonZeroTime(bundle.CreatedAt)); err != nil { return fmt.Errorf("upsert evidence bundle row: %w", err) } } @@ -4176,7 +4176,7 @@ func syncPackageReportRetentionRows(ctx context.Context, tx pgx.Tx, state app.Pe verification_checks = EXCLUDED.verification_checks, verification_limitations = EXCLUDED.verification_limitations, schema_version = EXCLUDED.schema_version - `, policy.ID, policy.TenantID, policy.Name, policy.ObjectPrefix, policy.ObjectKey, policy.RequireLegalHold, policy.Mode, policy.RetentionDays, policy.Status, nullableTime(policy.VerifiedAt), nullableString(policy.VerificationHash), checks, policy.VerificationLimitations, policy.SchemaVersion, nonZeroTime(policy.CreatedAt)); err != nil { + `, policy.ID, policy.TenantID, policy.Name, policy.ObjectPrefix, policy.ObjectKey, policy.RequireLegalHold, policy.Mode, policy.RetentionDays, policy.Status, nullableTime(policy.VerifiedAt), nullableString(policy.VerificationHash), checks, textArray(policy.VerificationLimitations), policy.SchemaVersion, nonZeroTime(policy.CreatedAt)); err != nil { return fmt.Errorf("upsert object retention policy row: %w", err) } } @@ -4203,7 +4203,7 @@ func syncPackageReportRetentionRows(ctx context.Context, tx pgx.Tx, state app.Pe consistency_checks = EXCLUDED.consistency_checks, limitations = EXCLUDED.limitations, schema_version = EXCLUDED.schema_version - `, manifest.ID, manifest.TenantID, manifest.StateHash, counts, checks, manifest.Limitations, manifest.SchemaVersion, nonZeroTime(manifest.CreatedAt)); err != nil { + `, manifest.ID, manifest.TenantID, manifest.StateHash, counts, checks, textArray(manifest.Limitations), manifest.SchemaVersion, nonZeroTime(manifest.CreatedAt)); err != nil { return fmt.Errorf("upsert backup manifest row: %w", err) } } @@ -4297,7 +4297,7 @@ func syncPackageReportRetentionRows(ctx context.Context, tx pgx.Tx, state app.Pe evidence_ids = EXCLUDED.evidence_ids, limitations = EXCLUDED.limitations, schema_version = EXCLUDED.schema_version - `, entry.ID, entry.TenantID, nullableString(entry.QuestionID), nullableString(entry.EvidenceType), nullableString(entry.ControlID), nullableString(entry.ProductID), nullableString(entry.ReleaseID), entry.Answer, entry.EvidenceIDs, entry.Limitations, entry.SchemaVersion, nonZeroTime(entry.CreatedAt)); err != nil { + `, entry.ID, entry.TenantID, nullableString(entry.QuestionID), nullableString(entry.EvidenceType), nullableString(entry.ControlID), nullableString(entry.ProductID), nullableString(entry.ReleaseID), entry.Answer, textArray(entry.EvidenceIDs), textArray(entry.Limitations), entry.SchemaVersion, nonZeroTime(entry.CreatedAt)); err != nil { return fmt.Errorf("upsert questionnaire answer library row: %w", err) } } @@ -4318,7 +4318,7 @@ func syncPackageReportRetentionRows(ctx context.Context, tx pgx.Tx, state app.Pe payload_size = EXCLUDED.payload_size, limitations = EXCLUDED.limitations, schema_version = EXCLUDED.schema_version - `, report.ID, report.TenantID, report.ReportType, nullableString(report.ProductID), nullableString(report.ReleaseID), report.Title, nullableString(report.PayloadRef), report.PayloadHash, report.PayloadSize, report.Limitations, report.SchemaVersion, nonZeroTime(report.CreatedAt)); err != nil { + `, report.ID, report.TenantID, report.ReportType, nullableString(report.ProductID), nullableString(report.ReleaseID), report.Title, nullableString(report.PayloadRef), report.PayloadHash, report.PayloadSize, textArray(report.Limitations), report.SchemaVersion, nonZeroTime(report.CreatedAt)); err != nil { return fmt.Errorf("upsert pdf report row: %w", err) } } @@ -4342,7 +4342,7 @@ func syncPackageReportRetentionRows(ctx context.Context, tx pgx.Tx, state app.Pe assumptions = EXCLUDED.assumptions, limitations = EXCLUDED.limitations, schema_version = EXCLUDED.schema_version - `, report.ID, report.TenantID, report.SubjectType, report.SubjectID, report.Result, signals, report.Assumptions, report.Limitations, report.SchemaVersion, nonZeroTime(report.CreatedAt)); err != nil { + `, report.ID, report.TenantID, report.SubjectType, report.SubjectID, report.Result, signals, textArray(report.Assumptions), textArray(report.Limitations), report.SchemaVersion, nonZeroTime(report.CreatedAt)); err != nil { return fmt.Errorf("upsert anomaly report row: %w", err) } } @@ -4364,7 +4364,7 @@ func syncFutureExtensionRows(ctx context.Context, tx pgx.Tx, state app.Persisted allowed_scopes = EXCLUDED.allowed_scopes, status = EXCLUDED.status, schema_version = EXCLUDED.schema_version - `, collector.ID, collector.TenantID, collector.Name, collector.Provider, collector.Version, collector.ManifestHash, collector.AllowedScopes, collector.Status, collector.SchemaVersion, nonZeroTime(collector.CreatedAt)); err != nil { + `, collector.ID, collector.TenantID, collector.Name, collector.Provider, collector.Version, collector.ManifestHash, textArray(collector.AllowedScopes), collector.Status, collector.SchemaVersion, nonZeroTime(collector.CreatedAt)); err != nil { return fmt.Errorf("upsert commercial collector row: %w", err) } } @@ -4383,7 +4383,7 @@ func syncFutureExtensionRows(ctx context.Context, tx pgx.Tx, state app.Persisted ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) ON CONFLICT (id) DO UPDATE SET summary = EXCLUDED.summary, citations = EXCLUDED.citations, assumptions = EXCLUDED.assumptions, limitations = EXCLUDED.limitations, schema_version = EXCLUDED.schema_version - `, summary.ID, summary.TenantID, summary.SubjectType, summary.SubjectID, summary.EvidenceIDs, summary.Summary, citations, summary.Assumptions, summary.Limitations, summary.SchemaVersion, nonZeroTime(summary.CreatedAt)); err != nil { + `, summary.ID, summary.TenantID, summary.SubjectType, summary.SubjectID, textArray(summary.EvidenceIDs), summary.Summary, citations, textArray(summary.Assumptions), textArray(summary.Limitations), summary.SchemaVersion, nonZeroTime(summary.CreatedAt)); err != nil { return fmt.Errorf("upsert evidence summary row: %w", err) } } @@ -4402,7 +4402,7 @@ func syncFutureExtensionRows(ctx context.Context, tx pgx.Tx, state app.Persisted ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) ON CONFLICT (id) DO UPDATE SET responses = EXCLUDED.responses, manifest_hash = EXCLUDED.manifest_hash, limitations = EXCLUDED.limitations, schema_version = EXCLUDED.schema_version - `, draft.ID, draft.TenantID, draft.TemplateID, nullableString(draft.ProductID), nullableString(draft.ReleaseID), responses, draft.ManifestHash, draft.Limitations, draft.SchemaVersion, nonZeroTime(draft.CreatedAt)); err != nil { + `, draft.ID, draft.TenantID, draft.TemplateID, nullableString(draft.ProductID), nullableString(draft.ReleaseID), responses, draft.ManifestHash, textArray(draft.Limitations), draft.SchemaVersion, nonZeroTime(draft.CreatedAt)); err != nil { return fmt.Errorf("upsert questionnaire draft row: %w", err) } } @@ -4425,7 +4425,7 @@ func syncFutureExtensionRows(ctx context.Context, tx pgx.Tx, state app.Persisted ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) ON CONFLICT (id) DO UPDATE SET nodes = EXCLUDED.nodes, edges = EXCLUDED.edges, graph_hash = EXCLUDED.graph_hash, limitations = EXCLUDED.limitations, schema_version = EXCLUDED.schema_version - `, graph.ID, graph.TenantID, nullableString(graph.ProductID), nullableString(graph.ReleaseID), nodes, edges, graph.GraphHash, graph.Limitations, graph.SchemaVersion, nonZeroTime(graph.CreatedAt)); err != nil { + `, graph.ID, graph.TenantID, nullableString(graph.ProductID), nullableString(graph.ReleaseID), nodes, edges, graph.GraphHash, textArray(graph.Limitations), graph.SchemaVersion, nonZeroTime(graph.CreatedAt)); err != nil { return fmt.Errorf("upsert graph snapshot row: %w", err) } } @@ -4440,7 +4440,7 @@ func syncFutureExtensionRows(ctx context.Context, tx pgx.Tx, state app.Persisted ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) ON CONFLICT (id) DO UPDATE SET status = EXCLUDED.status, config_hash = EXCLUDED.config_hash, limitations = EXCLUDED.limitations, schema_version = EXCLUDED.schema_version - `, profile.ID, profile.TenantID, profile.Name, profile.Region, profile.AdminTenantID, profile.IsolationModel, profile.Status, profile.ConfigHash, profile.Limitations, profile.SchemaVersion, nonZeroTime(profile.CreatedAt)); err != nil { + `, profile.ID, profile.TenantID, profile.Name, profile.Region, profile.AdminTenantID, profile.IsolationModel, profile.Status, profile.ConfigHash, textArray(profile.Limitations), profile.SchemaVersion, nonZeroTime(profile.CreatedAt)); err != nil { return fmt.Errorf("upsert saas profile row: %w", err) } } @@ -4485,7 +4485,7 @@ func syncFutureExtensionRows(ctx context.Context, tx pgx.Tx, state app.Persisted schema_version = EXCLUDED.schema_version `, entry.ID, entry.TenantID, entry.LogID, entry.CheckpointID, entry.MerkleBatchID, entry.ExternalID, entry.EntryHash, nullableString(entry.InclusionRootHash), nullableString(entry.InclusionProofHash), nullableTime(entry.InclusionVerifiedAt), - checks, entry.VerificationLimitations, entry.State, entry.SchemaVersion, nonZeroTime(entry.CreatedAt)); err != nil { + checks, textArray(entry.VerificationLimitations), entry.State, entry.SchemaVersion, nonZeroTime(entry.CreatedAt)); err != nil { return fmt.Errorf("upsert public transparency entry row: %w", err) } } @@ -4503,7 +4503,7 @@ func syncFutureExtensionRows(ctx context.Context, tx pgx.Tx, state app.Persisted ON CONFLICT (id) DO UPDATE SET state = EXCLUDED.state, limitations = EXCLUDED.limitations, schema_version = EXCLUDED.schema_version `, collector.ID, collector.TenantID, collector.Name, collector.Provider, collector.Version, collector.Publisher, collector.ManifestHash, nullableString(collector.SignatureID), nullableString(collector.SBOMID), nullableString(collector.ScanID), collector.State, - collector.Limitations, collector.SchemaVersion, nonZeroTime(collector.CreatedAt)); err != nil { + textArray(collector.Limitations), collector.SchemaVersion, nonZeroTime(collector.CreatedAt)); err != nil { return fmt.Errorf("upsert marketplace collector row: %w", err) } } @@ -4522,7 +4522,7 @@ func syncFutureExtensionRows(ctx context.Context, tx pgx.Tx, state app.Persisted ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) ON CONFLICT (id) DO UPDATE SET result = EXCLUDED.result, checks = EXCLUDED.checks, limitations = EXCLUDED.limitations, schema_version = EXCLUDED.schema_version - `, verification.ID, verification.TenantID, verification.ProviderType, verification.ProviderID, verification.Subject, verification.Result, checks, verification.Limitations, verification.SchemaVersion, nonZeroTime(verification.CreatedAt)); err != nil { + `, verification.ID, verification.TenantID, verification.ProviderType, verification.ProviderID, verification.Subject, verification.Result, checks, textArray(verification.Limitations), verification.SchemaVersion, nonZeroTime(verification.CreatedAt)); err != nil { return fmt.Errorf("upsert provider verification row: %w", err) } } From 532419cb02d225fc9ccfaaba78e120d4c9a152cf Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 14:53:58 +0300 Subject: [PATCH 213/287] chore(release): mark rc5 as current candidate --- .github/workflows/container-image.yml | 6 +-- CHANGELOG.md | 27 +++++++++++- Makefile | 12 +++--- README.md | 10 ++--- deploy/airgap/manifest.yaml | 4 +- docs/how-to/install-and-operate.md | 22 +++++----- docs/kubernetes.md | 2 +- docs/reference/production-exit-review.md | 2 +- docs/reference/release-candidate.md | 2 +- docs/reference/release-evidence-index.md | 42 +++++++++---------- docs/tutorials/getting-started.md | 2 +- .../end-to-end-release-evidence/README.md | 2 +- scripts/public_release_verify.sh | 4 +- scripts/release_acceptance.sh | 2 +- 14 files changed, 81 insertions(+), 58 deletions(-) diff --git a/.github/workflows/container-image.yml b/.github/workflows/container-image.yml index cd1f2c7..ad51f96 100644 --- a/.github/workflows/container-image.yml +++ b/.github/workflows/container-image.yml @@ -4,13 +4,13 @@ on: workflow_dispatch: inputs: ref: - description: "Git ref to build, such as v0.1.0-rc.4" + description: "Git ref to build, such as v0.1.0-rc.5" required: true - default: "v0.1.0-rc.4" + default: "v0.1.0-rc.5" image_tag: description: "OCI tag to publish" required: true - default: "v0.1.0-rc.4" + default: "v0.1.0-rc.5" permissions: contents: read diff --git a/CHANGELOG.md b/CHANGELOG.md index d12d7b5..957efb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,14 +9,23 @@ results, no secure-release guarantee, and no regulator or auditor acceptance. ## Unreleased +- No unreleased changes. + +## v0.1.0-rc.5 - 2026-06-01 + +Release status: controlled self-hosted production candidate. This prerelease is +suitable for evaluation, pilots, and controlled internal production after +operator review. Broad self-hosted production readiness, regulated production, +and hosted SaaS production remain out of scope for this status. + ### Added -- Public release verification helper for downloading `v0.1.0-rc.4` from +- Public release verification helper for downloading `v0.1.0-rc.5` from GitHub Releases into a clean temporary directory, checking release checksums, validating in-toto provenance metadata shape, and verifying the signed release manifest with the released Linux amd64 CLI. - Container image workflow evidence for - `ghcr.io/aatuh/evydence:v0.1.0-rc.4@sha256:de5627ec300cb603c3f1dc21029bffc096d43399114888cd5c194e00f1285603`, + `ghcr.io/aatuh/evydence:v0.1.0-rc.5@sha256:38188044a3e5ded3c6094564ab39ce989185f65e22cf4296985ec19ba0eb1888`, including release-attached image manifest and cosign verification output. - Repository-owned restore rehearsal target for app-layer and live PostgreSQL backup/restore mechanics. @@ -27,6 +36,20 @@ results, no secure-release guarantee, and no regulator or auditor acceptance. - Dependency maintenance updates for pinned GitHub Actions, the Docker build and runtime base images, and `kin-openapi`. +### Fixed + +- PostgreSQL release-evidence persistence now normalizes empty string slices to + empty `text[]` values for non-null array columns, including VEX import + reports and vulnerability decision evidence IDs. + +### Known Limits + +- Operators remain responsible for PostgreSQL, object storage, TLS, external + signing or KMS/HSM custody, WORM/object-lock policy where required, backups, + restore rehearsals, monitoring, provider validation, and incident response. +- Multi-writer API HA remains outside the supported production profile; use one + API writer replica and scale workers through PostgreSQL outbox locking. + ## v0.1.0-rc.4 - 2026-05-31 Release status: controlled self-hosted production candidate. This prerelease is diff --git a/Makefile b/Makefile index 8b9b5f6..c626de7 100644 --- a/Makefile +++ b/Makefile @@ -216,15 +216,15 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F './evydence release verify' docs/air-gapped.md >/dev/null @grep -F './evydence import-bundle upload' docs/air-gapped.md >/dev/null @test -x scripts/public_release_verify.sh - @grep -F 'make public-release-verify TAG=v0.1.0-rc.4' README.md >/dev/null - @grep -F 'make public-release-verify TAG=v0.1.0-rc.4' docs/how-to/install-and-operate.md >/dev/null - @grep -F 'make public-release-verify TAG=v0.1.0-rc.4' docs/reference/release-evidence-index.md >/dev/null - @grep -F 'make public-release-verify TAG=v0.1.0-rc.4' examples/end-to-end-release-evidence/README.md >/dev/null + @grep -F 'make public-release-verify TAG=v0.1.0-rc.5' README.md >/dev/null + @grep -F 'make public-release-verify TAG=v0.1.0-rc.5' docs/how-to/install-and-operate.md >/dev/null + @grep -F 'make public-release-verify TAG=v0.1.0-rc.5' docs/reference/release-evidence-index.md >/dev/null + @grep -F 'make public-release-verify TAG=v0.1.0-rc.5' examples/end-to-end-release-evidence/README.md >/dev/null @test -f docs/assets/package-viewer-preview.svg @grep -F 'package-viewer-preview.svg' docs/how-to/view-packages.md >/dev/null @grep -F 'report.html' docs/reference/customer-package-manifest.md docs/how-to/view-packages.md >/dev/null @grep -F 'Redaction Leakage Guard' docs/reference/customer-package-manifest.md >/dev/null - @grep -F 'v0.1.0-rc.4 - 2026-05-31' CHANGELOG.md >/dev/null + @grep -F 'v0.1.0-rc.5 - 2026-06-01' CHANGELOG.md >/dev/null @grep -F 'make restore-rehearsal-check' docs/runbooks/backup-restore.md >/dev/null @test -f docs/how-to/pilot-deployment-checklist.md @grep -F 'Required: external PostgreSQL' docs/how-to/pilot-deployment-checklist.md >/dev/null @@ -270,7 +270,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'ghcr.io/aatuh/evydence' docs/reference/release-evidence-index.md >/dev/null @grep -F 'ghcr.io/aatuh/evydence' docs/kubernetes.md >/dev/null @grep -F 'ghcr.io/aatuh/evydence' deploy/airgap/manifest.yaml >/dev/null - @grep -F 'sha256:de5627ec300cb603c3f1dc21029bffc096d43399114888cd5c194e00f1285603' docs/reference/release-evidence-index.md docs/kubernetes.md deploy/airgap/manifest.yaml >/dev/null + @grep -F 'sha256:38188044a3e5ded3c6094564ab39ce989185f65e22cf4296985ec19ba0eb1888' docs/reference/release-evidence-index.md docs/kubernetes.md deploy/airgap/manifest.yaml >/dev/null @grep -F 'cosign verify' docs/reference/release-evidence-index.md >/dev/null @grep -F 'github/codeql-action/init@7211b7c8077ea37d8641b6271f6a365a22a5fbfa' .github/workflows/codeql.yml >/dev/null @grep -F 'security-and-quality' .github/workflows/codeql.yml >/dev/null diff --git a/README.md b/README.md index efa7bfa..3e5b1eb 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ objects instead of unsupported prose: This repository contains a Go implementation under module `github.com/aatuh/evydence`. The current public release candidate is -[`v0.1.0-rc.4`](https://github.com/aatuh/evydence/releases/tag/v0.1.0-rc.4), +[`v0.1.0-rc.5`](https://github.com/aatuh/evydence/releases/tag/v0.1.0-rc.5), published as a prerelease with signed archives, checksums, OpenAPI and migration checksums, coverage output, production-check summary, SBOM/provenance metadata, release notes, and a signed release manifest. @@ -75,8 +75,8 @@ Container images for the release-candidate line are published, when the maintainer image workflow has run for the tag, as `ghcr.io/aatuh/evydence:`. Treat the digest and cosign evidence as the operator trust input, not the mutable tag alone. -For `v0.1.0-rc.4`, the published image is -`ghcr.io/aatuh/evydence:v0.1.0-rc.4@sha256:de5627ec300cb603c3f1dc21029bffc096d43399114888cd5c194e00f1285603`. +For `v0.1.0-rc.5`, the published image is +`ghcr.io/aatuh/evydence:v0.1.0-rc.5@sha256:38188044a3e5ded3c6094564ab39ce989185f65e22cf4296985ec19ba0eb1888`. ## Fastest Proof Path @@ -98,14 +98,14 @@ package in the [local package viewer](docs/how-to/view-packages.md). Release-candidate artifacts and their verification commands are indexed in [Release evidence index](docs/reference/release-evidence-index.md). Start with -the public `v0.1.0-rc.4` release if you want to evaluate release verification +the public `v0.1.0-rc.5` release if you want to evaluate release verification before running the API. To verify the public release assets from a clean temporary directory on Linux amd64, run: ```sh -make public-release-verify TAG=v0.1.0-rc.4 +make public-release-verify TAG=v0.1.0-rc.5 ``` The VEX-first evidence flow to evaluate first is: diff --git a/deploy/airgap/manifest.yaml b/deploy/airgap/manifest.yaml index 192be40..52f63f7 100644 --- a/deploy/airgap/manifest.yaml +++ b/deploy/airgap/manifest.yaml @@ -2,8 +2,8 @@ schema_version: evydence-airgap-package.v1.0.0 images: - name: evydence repository: ghcr.io/aatuh/evydence - tag: v0.1.0-rc.4 - digest: sha256:de5627ec300cb603c3f1dc21029bffc096d43399114888cd5c194e00f1285603 + tag: v0.1.0-rc.5 + digest: sha256:38188044a3e5ded3c6094564ab39ce989185f65e22cf4296985ec19ba0eb1888 required: true bundled_paths: - migrations/ diff --git a/docs/how-to/install-and-operate.md b/docs/how-to/install-and-operate.md index 0b28dc9..a693f5b 100644 --- a/docs/how-to/install-and-operate.md +++ b/docs/how-to/install-and-operate.md @@ -3,7 +3,7 @@ Use this guide for a local self-hosted development or evaluation deployment. For operator evaluation, start from the current public release candidate -[`v0.1.0-rc.4`](https://github.com/aatuh/evydence/releases/tag/v0.1.0-rc.4). +[`v0.1.0-rc.5`](https://github.com/aatuh/evydence/releases/tag/v0.1.0-rc.5). Download the release archive for your platform, then verify `SHA256SUMS`, `openapi.sha256`, `migrations.sha256`, and the signed release manifest before starting the API or worker. Source checkout remains the local development path. @@ -25,15 +25,15 @@ Configuration details live in [Configuration](../reference/configuration.md). For a release-backed evaluation on Linux amd64: ```sh -mkdir -p dist/v0.1.0-rc.4 -gh release download v0.1.0-rc.4 --repo aatuh/evydence --dir dist/v0.1.0-rc.4 -(cd dist/v0.1.0-rc.4 && sha256sum -c SHA256SUMS) -(cd dist/v0.1.0-rc.4 && sha256sum -c openapi.sha256) -sha256sum -c dist/v0.1.0-rc.4/migrations.sha256 -tar -C dist/v0.1.0-rc.4 -xzf dist/v0.1.0-rc.4/evydence_v0.1.0-rc.4_linux_amd64.tar.gz -./dist/v0.1.0-rc.4/evydence_v0.1.0-rc.4_linux_amd64/evydence release verify \ - --manifest dist/v0.1.0-rc.4/evydence-release-manifest.json \ - --signature dist/v0.1.0-rc.4/evydence-release-manifest.sig.json +mkdir -p dist/v0.1.0-rc.5 +gh release download v0.1.0-rc.5 --repo aatuh/evydence --dir dist/v0.1.0-rc.5 +(cd dist/v0.1.0-rc.5 && sha256sum -c SHA256SUMS) +(cd dist/v0.1.0-rc.5 && sha256sum -c openapi.sha256) +sha256sum -c dist/v0.1.0-rc.5/migrations.sha256 +tar -C dist/v0.1.0-rc.5 -xzf dist/v0.1.0-rc.5/evydence_v0.1.0-rc.5_linux_amd64.tar.gz +./dist/v0.1.0-rc.5/evydence_v0.1.0-rc.5_linux_amd64/evydence release verify \ + --manifest dist/v0.1.0-rc.5/evydence-release-manifest.json \ + --signature dist/v0.1.0-rc.5/evydence-release-manifest.sig.json ``` Expected result: checksum verification exits successfully, manifest signature @@ -45,7 +45,7 @@ For the same verification from a clean temporary directory, use the checked helper: ```sh -make public-release-verify TAG=v0.1.0-rc.4 +make public-release-verify TAG=v0.1.0-rc.5 ``` Expected result: the helper downloads the public GitHub Release assets, diff --git a/docs/kubernetes.md b/docs/kubernetes.md index 27f6e05..a3f8d2b 100644 --- a/docs/kubernetes.md +++ b/docs/kubernetes.md @@ -36,7 +36,7 @@ Store real values in your secret manager or sealed-secret process. Do not commit ```sh helm upgrade --install evydence ./deploy/helm/evydence \ --set image.repository=ghcr.io/aatuh/evydence \ - --set image.tag=v0.1.0-rc.4@sha256:de5627ec300cb603c3f1dc21029bffc096d43399114888cd5c194e00f1285603 \ + --set image.tag=v0.1.0-rc.5@sha256:38188044a3e5ded3c6094564ab39ce989185f65e22cf4296985ec19ba0eb1888 \ --set env.s3Endpoint=s3.example.com \ --set env.s3Bucket=evydence ``` diff --git a/docs/reference/production-exit-review.md b/docs/reference/production-exit-review.md index 4ad91ab..474172e 100644 --- a/docs/reference/production-exit-review.md +++ b/docs/reference/production-exit-review.md @@ -22,7 +22,7 @@ SaaS-ready, legally compliant, certified, or secure-release-guaranteed. - Release-candidate packaging generates checksums, OpenAPI checksum, migration checksum, release SBOM metadata, release provenance metadata, release notes, signed manifest, and manifest signature. -- Public prerelease `v0.1.0-rc.4` is published with signed release archives, +- Public prerelease `v0.1.0-rc.5` is published with signed release archives, checksums, OpenAPI and migration checksums, coverage output, production-check summary, SBOM/provenance metadata, release notes, and signed release manifest. diff --git a/docs/reference/release-candidate.md b/docs/reference/release-candidate.md index 8e14a2c..3aee05d 100644 --- a/docs/reference/release-candidate.md +++ b/docs/reference/release-candidate.md @@ -64,7 +64,7 @@ production, and hosted SaaS production require additional review and controls. ## Public Publication The first public release candidate, -[`v0.1.0-rc.4`](https://github.com/aatuh/evydence/releases/tag/v0.1.0-rc.4), +[`v0.1.0-rc.5`](https://github.com/aatuh/evydence/releases/tag/v0.1.0-rc.5), is published as a prerelease. Public release readiness requires a pushed tag, a completed release-artifacts workflow run, uploaded release archives, checksums, signed manifest files, release notes, and any configured repository or registry diff --git a/docs/reference/release-evidence-index.md b/docs/reference/release-evidence-index.md index 95fb65c..04fda10 100644 --- a/docs/reference/release-evidence-index.md +++ b/docs/reference/release-evidence-index.md @@ -38,15 +38,15 @@ under `dist//` after `make production-check` passes. ## Current Public Release Candidate The current public release candidate is -[`v0.1.0-rc.4`](https://github.com/aatuh/evydence/releases/tag/v0.1.0-rc.4). -It was built from tag `v0.1.0-rc.4` at commit -`944c4c6694535f6fc23a2b272e58347217321672`; the public Release Artifacts +[`v0.1.0-rc.5`](https://github.com/aatuh/evydence/releases/tag/v0.1.0-rc.5). +It was built from tag `v0.1.0-rc.5` at commit +`d5098c635ee7b171dac3a449ba7ca2e30d8b0c16`; the public Release Artifacts workflow run is -[`26719422897`](https://github.com/aatuh/evydence/actions/runs/26719422897). +[`26752006813`](https://github.com/aatuh/evydence/actions/runs/26752006813). The release commit also has a public CI `Production Check` run -[`26719406847`](https://github.com/aatuh/evydence/actions/runs/26719406847) +[`26748345740`](https://github.com/aatuh/evydence/actions/runs/26748345740) and CodeQL run -[`26719406836`](https://github.com/aatuh/evydence/actions/runs/26719406836). +[`26748345664`](https://github.com/aatuh/evydence/actions/runs/26748345664). The public prerelease includes release archives for Linux, macOS, and Windows; `SHA256SUMS`; `openapi.yaml`; `openapi.sha256`; `migrations.sha256`; @@ -60,24 +60,24 @@ The public prerelease includes release archives for Linux, macOS, and Windows; container image. The current project-owned container image is -`ghcr.io/aatuh/evydence:v0.1.0-rc.4@sha256:de5627ec300cb603c3f1dc21029bffc096d43399114888cd5c194e00f1285603`. +`ghcr.io/aatuh/evydence:v0.1.0-rc.5@sha256:38188044a3e5ded3c6094564ab39ce989185f65e22cf4296985ec19ba0eb1888`. It was produced by the Container Image workflow run -[`26721113041`](https://github.com/aatuh/evydence/actions/runs/26721113041) -from release source commit `944c4c6694535f6fc23a2b272e58347217321672`. +[`26752805538`](https://github.com/aatuh/evydence/actions/runs/26752805538) +from release source commit `d5098c635ee7b171dac3a449ba7ca2e30d8b0c16`. ## Local Verification After packaging, verify the evidence directory before publishing: ```sh -gh release download v0.1.0-rc.4 --repo aatuh/evydence --dir dist/v0.1.0-rc.4 -(cd dist/v0.1.0-rc.4 && sha256sum -c SHA256SUMS) -(cd dist/v0.1.0-rc.4 && sha256sum -c openapi.sha256) -sha256sum -c dist/v0.1.0-rc.4/migrations.sha256 -tar -C dist/v0.1.0-rc.4 -xzf dist/v0.1.0-rc.4/evydence_v0.1.0-rc.4_linux_amd64.tar.gz -./dist/v0.1.0-rc.4/evydence_v0.1.0-rc.4_linux_amd64/evydence release verify \ - --manifest dist/v0.1.0-rc.4/evydence-release-manifest.json \ - --signature dist/v0.1.0-rc.4/evydence-release-manifest.sig.json +gh release download v0.1.0-rc.5 --repo aatuh/evydence --dir dist/v0.1.0-rc.5 +(cd dist/v0.1.0-rc.5 && sha256sum -c SHA256SUMS) +(cd dist/v0.1.0-rc.5 && sha256sum -c openapi.sha256) +sha256sum -c dist/v0.1.0-rc.5/migrations.sha256 +tar -C dist/v0.1.0-rc.5 -xzf dist/v0.1.0-rc.5/evydence_v0.1.0-rc.5_linux_amd64.tar.gz +./dist/v0.1.0-rc.5/evydence_v0.1.0-rc.5_linux_amd64/evydence release verify \ + --manifest dist/v0.1.0-rc.5/evydence-release-manifest.json \ + --signature dist/v0.1.0-rc.5/evydence-release-manifest.sig.json ``` Use the platform-specific `evydence` binary from the release archive whenever @@ -88,7 +88,7 @@ To verify the already-published public release from a clean temporary directory, run: ```sh -make public-release-verify TAG=v0.1.0-rc.4 +make public-release-verify TAG=v0.1.0-rc.5 ``` The helper downloads the release assets with `gh`, checks the public checksums, @@ -98,16 +98,16 @@ and verifies the signed manifest with that released binary. To verify the public container image digest and workflow identity, run: ```sh -docker buildx imagetools inspect ghcr.io/aatuh/evydence:v0.1.0-rc.4 \ +docker buildx imagetools inspect ghcr.io/aatuh/evydence:v0.1.0-rc.5 \ --format '{{json .Manifest.Digest}}' cosign verify \ --certificate-identity-regexp 'https://github.com/aatuh/evydence/.github/workflows/container-image.yml@.*' \ --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \ - ghcr.io/aatuh/evydence@sha256:de5627ec300cb603c3f1dc21029bffc096d43399114888cd5c194e00f1285603 + ghcr.io/aatuh/evydence@sha256:38188044a3e5ded3c6094564ab39ce989185f65e22cf4296985ec19ba0eb1888 ``` Expected digest: -`sha256:de5627ec300cb603c3f1dc21029bffc096d43399114888cd5c194e00f1285603`. +`sha256:38188044a3e5ded3c6094564ab39ce989185f65e22cf4296985ec19ba0eb1888`. The cosign verification proves the configured workflow identity signed the image digest; it is not legal compliance proof, certification, complete SBOM proof, authoritative vulnerability coverage, or a secure-release guarantee. diff --git a/docs/tutorials/getting-started.md b/docs/tutorials/getting-started.md index 49cceb0..1b1a391 100644 --- a/docs/tutorials/getting-started.md +++ b/docs/tutorials/getting-started.md @@ -3,7 +3,7 @@ This tutorial runs Evydence with in-process state and records a small release evidence flow. It is for local development only; data is lost when the process exits. For operator evaluation, prefer the current public release candidate -[`v0.1.0-rc.4`](https://github.com/aatuh/evydence/releases/tag/v0.1.0-rc.4) +[`v0.1.0-rc.5`](https://github.com/aatuh/evydence/releases/tag/v0.1.0-rc.5) and verify the release evidence before starting binaries. This tutorial remains the source-checkout local development path. The release artifact map is in [Release evidence index](../reference/release-evidence-index.md). diff --git a/examples/end-to-end-release-evidence/README.md b/examples/end-to-end-release-evidence/README.md index 72b27d9..a55afe2 100644 --- a/examples/end-to-end-release-evidence/README.md +++ b/examples/end-to-end-release-evidence/README.md @@ -22,7 +22,7 @@ Before running a local API flow, verify the current public release-candidate assets from a clean temporary directory: ```sh -make public-release-verify TAG=v0.1.0-rc.4 +make public-release-verify TAG=v0.1.0-rc.5 ``` This proves the downloaded public archives, OpenAPI checksum, migration diff --git a/scripts/public_release_verify.sh b/scripts/public_release_verify.sh index ecd8a97..534c944 100755 --- a/scripts/public_release_verify.sh +++ b/scripts/public_release_verify.sh @@ -2,14 +2,14 @@ set -euo pipefail repo="${EVYDENCE_RELEASE_REPO:-aatuh/evydence}" -tag="${1:-${TAG:-v0.1.0-rc.4}}" +tag="${1:-${TAG:-v0.1.0-rc.5}}" if [[ ! "$repo" =~ ^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$ ]]; then echo "EVYDENCE_RELEASE_REPO must look like owner/name" >&2 exit 2 fi if [[ ! "$tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$ ]]; then - echo "release candidate tag must look like v0.1.0-rc.4" >&2 + echo "release candidate tag must look like v0.1.0-rc.5" >&2 exit 2 fi if ! command -v gh >/dev/null 2>&1; then diff --git a/scripts/release_acceptance.sh b/scripts/release_acceptance.sh index 2cc9c9c..5c7c951 100755 --- a/scripts/release_acceptance.sh +++ b/scripts/release_acceptance.sh @@ -104,7 +104,7 @@ require_text docs/reference/release-evidence-index.md "evydence-release-manifest require_text docs/reference/release-evidence-index.md "evydence-release-manifest.sig" require_text docs/reference/release-evidence-index.md "evydence-release-provenance.intoto.jsonl" require_text docs/reference/release-evidence-index.md "evydence-container-image-manifest.json" -require_text docs/reference/release-evidence-index.md "sha256:de5627ec300cb603c3f1dc21029bffc096d43399114888cd5c194e00f1285603" +require_text docs/reference/release-evidence-index.md "sha256:38188044a3e5ded3c6094564ab39ce989185f65e22cf4296985ec19ba0eb1888" require_text docs/reference/release-evidence-index.md "not legal compliance proof" require_text docs/reference/maintainer-review-policy.md "CODEOWNERS" require_text docs/reference/maintainer-review-policy.md "tenant-scoped resources cannot cross tenant boundaries" From 8432a728e2a75704e46ff785f898d232e3abdb45 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 16:11:22 +0300 Subject: [PATCH 214/287] ci(release): require explicit publish tokens --- .github/workflows/container-image.yml | 9 +- .github/workflows/release-artifacts.yml | 16 +- .productization_next_steps_missing.md | 600 ++++++++++++++++++++++++ Makefile | 4 + RELEASE_EVIDENCE.md | 6 + docs/reference/release-candidate.md | 9 + docs/reference/release-validation.md | 17 +- scripts/release_acceptance.sh | 10 + 8 files changed, 663 insertions(+), 8 deletions(-) create mode 100644 .productization_next_steps_missing.md diff --git a/.github/workflows/container-image.yml b/.github/workflows/container-image.yml index ad51f96..f85b2e8 100644 --- a/.github/workflows/container-image.yml +++ b/.github/workflows/container-image.yml @@ -14,7 +14,6 @@ on: permissions: contents: read - packages: write id-token: write jobs: @@ -50,10 +49,16 @@ jobs: cache: true - name: Log in to GitHub Container Registry + env: + EVYDENCE_GHCR_PUBLISH_TOKEN: ${{ secrets.EVYDENCE_GHCR_PUBLISH_TOKEN }} shell: bash run: | set -euo pipefail - printf '%s' "${{ github.token }}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin + if [[ -z "${EVYDENCE_GHCR_PUBLISH_TOKEN}" ]]; then + echo "EVYDENCE_GHCR_PUBLISH_TOKEN secret is required to publish container images" >&2 + exit 2 + fi + printf '%s' "${EVYDENCE_GHCR_PUBLISH_TOKEN}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin - name: Build and push image shell: bash diff --git a/.github/workflows/release-artifacts.yml b/.github/workflows/release-artifacts.yml index 62dad3c..79859ba 100644 --- a/.github/workflows/release-artifacts.yml +++ b/.github/workflows/release-artifacts.yml @@ -23,8 +23,6 @@ jobs: package: name: Package Signed Release Artifacts runs-on: ubuntu-latest - permissions: - contents: write services: postgres: image: postgres:16-alpine@sha256:16bc17c64a573ef34162af9298258d1aec548232985b33ed7b1eac33ba35c229 @@ -100,10 +98,22 @@ jobs: path: dist/${{ steps.release.outputs.tag }}/ if-no-files-found: error + - name: Require release publishing token + if: github.event_name == 'push' || github.event.inputs.upload_draft_release == 'true' + env: + EVYDENCE_RELEASE_PUBLISH_TOKEN: ${{ secrets.EVYDENCE_RELEASE_PUBLISH_TOKEN }} + shell: bash + run: | + set -euo pipefail + if [[ -z "${EVYDENCE_RELEASE_PUBLISH_TOKEN}" ]]; then + echo "EVYDENCE_RELEASE_PUBLISH_TOKEN secret is required to create or update draft GitHub releases" >&2 + exit 2 + fi + - name: Create or update draft GitHub release if: github.event_name == 'push' || github.event.inputs.upload_draft_release == 'true' env: - GH_TOKEN: ${{ github.token }} + GH_TOKEN: ${{ secrets.EVYDENCE_RELEASE_PUBLISH_TOKEN }} shell: bash run: | set -euo pipefail diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md new file mode 100644 index 0000000..592fb55 --- /dev/null +++ b/.productization_next_steps_missing.md @@ -0,0 +1,600 @@ +# Evydence Productization Missing/Partial Backlog + +Project: Evydence + +Purpose: Track the partial or non-fulfilled productization items identified from +`.productization_next_steps_doc.md`, the current repository evidence, and the +first production-readiness public repo audit in +`.audits/production_readiness_v1/`. + +Current baseline: + +- Evydence already has a credible VEX-first release-evidence core, public + `v0.1.0-rc.5` release evidence, OpenAPI, CLI, customer packages, local package + viewer, and production-candidate docs. +- The remaining work is productization, reviewer UX, trust hardening, + decision-model depth, production-profile clarity, and real market validation. +- Product language must remain conservative: compliance readiness, technical + evidence organization, tamper-evident records, reproducibility, gaps, + assumptions, exceptions, and limitations. Do not claim legal compliance, + certification, complete SBOMs, authoritative scanner results, secure releases, + or auditor/regulator acceptance. + +Status legend: + +- [ ] not done +- [x] done +- [e] external dependency, not fully implementable in this repository + +Implementation rules: + +- Implement tickets in dependency order. +- Keep changes small enough to test, document, and commit independently. +- Run the validation commands listed on each ticket. +- Prefer `make finalize` as the final local gate for source changes. +- Use Conventional Commits after each completed ticket. +- Update OpenAPI, docs, examples, migrations, and tests together when behavior + changes. +- Mark a ticket `[x]` only after implementation, docs, tests/checks, and commit + are complete. +- Mark an epic `[x]` only when all child tickets are complete or explicitly + external. +- Keep tenant isolation, append-only evidence, safe redaction, release evidence + integrity, and non-claim language intact. + +## Epic E1 - Close Public Trust And Release-Integrity Gaps [ ] + +Description: Remove the highest-impact public trust issues that prevent the +repository from cleanly exceeding the production-readiness score target. + +### Ticket E1-T1 - Remove broad token permissions from container image workflow [ ] + +Description: Change `.github/workflows/container-image.yml` so `GITHUB_TOKEN` +does not carry top-level `packages: write`. Use job-level least privilege only +where needed, or move registry publication to a narrowly scoped external token +with documented operator/maintainer requirements. + +Implementation rules: + +- Preserve container image build, digest capture, cosign signing, cosign + verification output, and image manifest generation. +- Keep `id-token: write` only for the signing step that needs keyless cosign. +- Avoid broad workflow-level write permissions. +- Update release evidence docs if the publishing trust model changes. +- Run `make docs-check`. +- Run or inspect a `Container Image` workflow execution before marking complete. +- Verify the related Scorecard code-scanning alert closes or document a + remaining external requirement. + +### Ticket E1-T2 - Split release packaging from release publishing permissions [ ] + +Description: Refactor `.github/workflows/release-artifacts.yml` so package +generation and validation run read-only, while draft-release creation/upload is +isolated behind the narrowest possible permission boundary. + +Implementation rules: + +- Preserve signed archives, checksums, OpenAPI checksum, migration checksum, + SBOM/provenance metadata, release notes, and signed manifest outputs. +- Move `contents: write` to the smallest job or workflow that actually needs to + create/upload a draft release. +- Prefer a fine-grained maintainer token or GitHub App token if needed to clear + Scorecard while preserving release publication. +- Update `docs/reference/release-candidate.md`, + `docs/reference/release-validation.md`, and `RELEASE_EVIDENCE.md` if release + publication steps change. +- Run `make release-acceptance`. +- Run `make public-release-verify TAG=v0.1.0-rc.5`. +- Verify the related Scorecard code-scanning alert closes or document a + remaining external requirement. + +### Ticket E1-T3 - Make coverage gate behavior deterministic [ ] + +Description: Fix the mismatch where public CI `make production-check` passes +coverage with live PostgreSQL, but local `make coverage-check` fails at 67.9% +when `EVYDENCE_TEST_DATABASE_URL` is unset. + +Implementation rules: + +- Preserve the 80% production coverage gate. +- Either make `make coverage-check` fail early with a clear live PostgreSQL + prerequisite, or add a separate local-only coverage target with explicitly + lower scope. +- Update `scripts/coverage_check.sh`, `Makefile`, and release/production docs. +- Avoid implying no-DB local coverage is production release evidence. +- Run `make coverage-check` without `EVYDENCE_TEST_DATABASE_URL` and verify the + intended deterministic behavior. +- Run `make docs-check` and `make release-acceptance`. + +### Ticket E1-T4 - Document maintainer branch-protection bypass posture [ ] + +Description: Document that branch protection can be bypassed by maintainers if +admin enforcement remains disabled, and state compensating controls without +overclaiming enforced PR-only changes. + +Implementation rules: + +- Update `docs/reference/maintainer-review-policy.md`. +- Mention required checks, CodeQL, production-check, release evidence, signed + artifacts, and audit visibility as compensating controls. +- Do not claim all changes must go through PR if maintainer bypass remains + possible. +- Run `make docs-check` and `make release-acceptance`. + +### Ticket E1-T5 - [e] Configure external publishing credentials if required [ ] + +Description: If least-privilege release publishing requires a fine-grained PAT, +GitHub App token, or registry credential, create and configure the external +GitHub secrets. + +Implementation rules: + +- Keep secrets out of source files, logs, release notes, and audit artifacts. +- Record only the secret purpose, required scopes, and rotation expectations. +- Validate with public workflow runs and release/container evidence. + +External reason: + +- GitHub repository secrets and app/PAT creation are provider/account settings. + +### Ticket E1-T6 - [e] Verify GitHub private vulnerability reporting and secret scanning [ ] + +Description: Confirm GitHub private vulnerability reporting, secret scanning, +and push protection are enabled where available. + +Implementation rules: + +- Record the setting state in a maintainer-only or sanitized security audit note. +- Update public docs only with statements that can be maintained. + +External reason: + +- These are GitHub account/repository security settings, not source files. + +## Epic E2 - Make The First Ten Minutes Reviewer-Obvious [ ] + +Description: Convert the already implemented VEX-first flow into an evaluation +path a skeptical product-security buyer or customer reviewer understands without +reading architecture docs. + +### Ticket E2-T1 - Add a one-page evaluator walkthrough [ ] + +Description: Add a concise "evaluate in 10 minutes" walkthrough that starts +from the current public release, sample package, local package viewer, and +public release verifier. + +Implementation rules: + +- Keep the walkthrough buyer-facing, not architecture-first. +- Show the exact customer question: "This CVE appears in your SBOM. Are you + affected, why, who approved it, and what can I verify?" +- Link to the sample customer package, package viewer, release verifier, and + end-to-end demo. +- Avoid asking the evaluator to understand every evidence family up front. +- Update `README.md`, `docs/tutorials/getting-started.md`, or a new focused + docs page. +- Run `make docs-check`, `make demo-check`, and `make package-viewer-check`. + +### Ticket E2-T2 - Add a visual reviewer journey using existing fixtures [ ] + +Description: Add a static, checked reviewer journey that shows the package +viewer states for release summary, VEX decisions, evidence contents, +verification, gaps, and limitations. + +Implementation rules: + +- Use non-sensitive sample data only. +- Do not upload data or require a running server for the visual path. +- Keep `site/package-viewer/index.html` local-only unless a later ticket adds a + server mode. +- Update `docs/how-to/view-packages.md` and docs assets. +- Run `make package-viewer-check` and `make docs-check`. + +### Ticket E2-T3 - Reduce first-screen feature sprawl [ ] + +Description: Keep the README first screen focused on products, releases, SBOMs, +vulnerability scans, VEX/manual decisions, provenance, release bundles, and +customer-safe packages; move broad evidence/report families to advanced docs. + +Implementation rules: + +- Do not remove implemented capability documentation. +- Keep advanced features discoverable under docs/reference or architecture. +- Keep VEX-first buyer language dominant near the top of the README. +- Run `make docs-check` and `make release-acceptance`. + +### Ticket E2-T4 - Add a proof-path checklist to the sample package [ ] + +Description: Make the sample customer package and package viewer show a +reviewer-oriented checklist: package scope, included evidence, excluded +evidence, hash/signature verification, non-claims, and escalation path. + +Implementation rules: + +- Update sample fixtures only if their hashes and golden tests are updated. +- Ensure redaction leakage tests still prove raw payloads and secrets are absent. +- Run `make demo-check`, `make package-viewer-check`, and targeted package tests. + +## Epic E3 - Make Vulnerability Decisions Fully Buyer-Facing [ ] + +Description: Close the documented decision-model gaps so vulnerability +decisions become a durable customer-review object, not only an operational API +record. + +### Ticket E3-T1 - Decide and document risk-status taxonomy [ ] + +Description: Decide whether `accepted_risk`, `false_positive`, and +`will_not_fix` belong as vulnerability decision statuses, exceptions, waivers, +or a separate risk outcome model. + +Implementation rules: + +- Update `docs/reference/vulnerability-decisions.md` with the final taxonomy. +- If new statuses are added, update domain validation, OpenAPI, tests, package + exports, readiness reports, and docs. +- If deferred, explicitly state how exceptions/waivers represent those cases. +- Run targeted app/API tests and `make openapi-check` if schemas change. + +### Ticket E3-T2 - Add decision review date or explicit freshness semantics [ ] + +Description: Address the current gap that customer-visible decisions have no +review date or expiry. + +Implementation rules: + +- Prefer append-only/versioned decision metadata over mutable historical edits. +- If implementing fields, add `reviewed_at`, `review_due_at`, or equivalent + semantics and expose freshness in customer-safe summaries. +- If deferring, document that expiry lives on exceptions/waivers and add report + limitations explaining decision freshness assumptions. +- Update package/report tests. +- Run `make openapi-check`, targeted app/API tests, and `make docs-check`. + +### Ticket E3-T3 - Link decisions directly to source SBOM context [ ] + +Description: Add first-class linkage from a vulnerability decision or finding +summary to the SBOM/component context that supported the answer, instead of +requiring reviewers to infer it through release/artifact relationships. + +Implementation rules: + +- Preserve tenant and release isolation for every link. +- Avoid duplicating raw SBOM payloads in customer-safe exports. +- Include safe SBOM/component identifiers in package summaries. +- Update OpenAPI, tests, and docs. +- Run targeted app/API tests and `make openapi-check`. + +### Ticket E3-T4 - Add first-class supporting links for non-evidence resources [ ] + +Description: Let decisions link to approvals, exceptions, waivers, remediation +tasks, release bundles, incident packages, or other first-class records without +forcing everything through generic evidence wrappers. + +Implementation rules: + +- Keep links append-only. +- Validate tenant ownership and release scope before linking. +- Exclude internal-only linked content from customer-safe exports unless the + redaction profile allows it. +- Add negative tests for cross-tenant and wrong-release links. +- Run targeted app/API tests, `make openapi-check`, and `make docs-check`. + +### Ticket E3-T5 - Add package-specific customer decision export [ ] + +Description: Extend customer package/report output so the canonical decision +view is package-scoped, customer-safe, and directly reviewable, not only a +release-scoped JSON summary. + +Implementation rules: + +- Include vulnerability ID, component/PURL, status, justification, + customer-safe impact/action statements, approver, supersession state, source + VEX/import info, supporting links, assumptions, and limitations. +- Exclude internal notes, raw payload bytes, object-store refs, tokens, hashes + of secrets, and private review context. +- Update package viewer, static `report.html`, package verifier/golden tests, + and docs. +- Run `make demo-check`, `make package-viewer-check`, targeted package tests, + and `make docs-check`. + +## Epic E4 - Improve VEX Import Depth And Parser Feedback [ ] + +Description: Make VEX import behavior operationally clear for both OpenVEX and +CycloneDX VEX without claiming authoritative vulnerability truth. + +### Ticket E4-T1 - Add CycloneDX VEX import report details [ ] + +Description: Extend CycloneDX VEX ingestion to produce format-specific import +issues, warnings, mapping failures, created/superseded decision counts, and +safe parser metadata comparable to OpenVEX import reports. + +Implementation rules: + +- Use strict structured parsing. +- Do not expose raw VEX payload bytes, object-store refs, tokens, or internal + notes in import reports. +- Preserve idempotent worker replay behavior. +- Add malformed, unsupported, duplicate, and mapping-failure fixtures. +- Run targeted VEX/parser tests and `make openapi-check` if schema changes. + +### Ticket E4-T2 - Add VEX import preview/dry-run mode [ ] + +Description: Add a way to validate a VEX document and see safe mapping +warnings before committing decisions, if it fits the API model. + +Implementation rules: + +- Treat preview output as advisory, not evidence. +- Do not store raw payloads during dry-run unless explicitly requested. +- Enforce body size, strict JSON, and safe errors. +- Update OpenAPI and docs if a new endpoint is added. +- Run API input validation tests and `make openapi-check`. + +### Ticket E4-T3 - Improve worker parser failure visibility [ ] + +Description: Make VEX parser failures visible in persisted import reports and +worker job status with safe error codes and no raw payload leakage. + +Implementation rules: + +- Preserve retry and terminal-failure behavior. +- Add tests for malformed payload, missing object, digest mismatch, and mapping + failure. +- Update worker/outbox docs. +- Run `go test ./cmd/evydence-worker ./internal/app` and `make docs-check`. + +## Epic E5 - Make CI Evidence Ingest Embarrassingly Simple [ ] + +Description: Reduce the first CI integration to one obvious release-evidence +path before users learn the full domain model. + +### Ticket E5-T1 - Add a minimal GitHub Actions setup guide [ ] + +Description: Add a short guide that starts from existing product/release/artifact +IDs and wires one build to upload SBOM, vulnerability scan, provenance, optional +OpenVEX, and a release bundle. + +Implementation rules: + +- Use `docs/github-actions/quickstart-release-evidence.yml` as the canonical + example. +- State required secrets and variables exactly. +- Avoid live GitHub API calls beyond the runner environment. +- Include expected output and troubleshooting for common 401/403/404/idempotency + errors. +- Run `make docs-check`. + +### Ticket E5-T2 - Add a preflight CLI command for CI configuration [ ] + +Description: Add a CLI command that verifies API URL, API key scope, product ID, +release ID, artifact ID, and manifest paths before a CI upload runs. + +Implementation rules: + +- Do not print API keys, bearer tokens, or secrets. +- Return stable exit codes for missing config, auth failure, wrong scope, wrong + tenant, and invalid manifest. +- Add CLI tests and safe error-message tests. +- Run `go test ./cmd/evydence` and `make docs-check`. + +### Ticket E5-T3 - Add a checked one-command local CI simulation [ ] + +Description: Add a local script that simulates the GitHub Actions quickstart +against a local API using non-sensitive fixture SBOM/scan/VEX data. + +Implementation rules: + +- Keep fixture IDs explicit or create them through the API. +- Write outputs under `tmp/`. +- Verify readiness, package, and audit-chain outputs. +- Add the script to `demo-check` or a separate checked target. +- Run the new target and `make fast-check`. + +## Epic E6 - Clarify Production Candidate Versus Broad Production [ ] + +Description: Keep production positioning honest while closing repo-local +hardening that affects controlled self-hosted adoption. + +### Ticket E6-T1 - Refresh production exit review after trust fixes [ ] + +Description: Update `docs/reference/production-exit-review.md` after release +workflow token-permission and coverage-gate fixes land. + +Implementation rules: + +- Keep the verdict conservative unless evidence supports a stronger claim. +- Separate repo-local fixed items from external/operator responsibilities. +- Cite current release, CI, CodeQL, Scorecard, and production-check evidence. +- Run `make docs-check` and `make release-acceptance`. + +### Ticket E6-T2 - Add external controls matrix for regulated deployments [ ] + +Description: Add a concise matrix of external controls required for regulated +or high-trust deployments, including KMS/HSM, WORM/object lock, TLS, identity +provider configuration, backups, monitoring, incident response, and legal/audit +review. + +Implementation rules: + +- Mark each item as repo-owned, operator-owned, provider-owned, or legal/review + owned. +- Do not imply Evydence can verify controls it only records as evidence. +- Link from production readiness, Kubernetes, and pilot checklist docs. +- Run `make docs-check`. + +### Ticket E6-T3 - Decide the long-term single-writer stance [ ] + +Description: Decide whether one API writer replica is an acceptable long-term +self-hosted profile, or whether multi-writer API HA must become a production +roadmap blocker. + +Implementation rules: + +- If one-writer remains supported, document capacity/failure expectations and + operational mitigations. +- If multi-writer is required, create a separate technical backlog for + concurrency design, optimistic locking, or focused repository decomposition. +- Do not change Helm defaults without tests. +- Run `make docs-check` and `make deploy-check`. + +### Ticket E6-T4 - Add current production-gate troubleshooting [ ] + +Description: Document how to diagnose failures in `make production-check`, +including PostgreSQL URL setup, migration compatibility, coverage, black-box +demo, release signing smoke, and package verification. + +Implementation rules: + +- Keep commands exact and safe for disposable local environments. +- Do not suggest running destructive commands against production databases. +- Link from release validation and production readiness docs. +- Run `make docs-check`. + +## Epic E7 - Turn Reviewer UX Into A Minimal Product Surface [ ] + +Description: Decide and implement the smallest browser-facing surface needed to +make customer package review credible without building a broad UI. + +### Ticket E7-T1 - Define UI boundary for reviewer and operator surfaces [ ] + +Description: Decide what remains API/CLI-only, what belongs in the local package +viewer, and whether a server-hosted customer portal page is in scope for the +next release. + +Implementation rules: + +- Keep tenant authorization server-side. +- Do not rely on frontend visibility for access control. +- Keep local viewer explicitly non-authoritative. +- Document the boundary in package viewer and customer portal docs. +- Run `make docs-check` and `make package-viewer-check`. + +### Ticket E7-T2 - Add server-hosted customer package view if approved [ ] + +Description: If the UI boundary allows it, add a minimal server-hosted customer +portal page for token-scoped package review and download. + +Implementation rules: + +- Use existing portal token exchange and package scope controls. +- Do not expose raw tenant evidence payloads or internal notes. +- Add CSRF/cache/header considerations if browser sessions are introduced. +- Add frontend/security tests and redaction leakage tests. +- Run focused HTTP tests, `make package-viewer-check`, and `make finalize`. + +### Ticket E7-T3 - Add reviewer export/download workflow proof [ ] + +Description: Prove that a reviewer can open a package, inspect limitations, +download the ZIP/report, and run verification instructions without maintainer +knowledge. + +Implementation rules: + +- Use checked fixtures and deterministic commands. +- Add a docs walkthrough and, if practical, a simple smoke script. +- Keep output language free of compliance/security guarantees. +- Run `make demo-check`, `make package-viewer-check`, and `make docs-check`. + +## Epic E8 - Gather External Market And Adoption Evidence [ ] + +Description: The remaining strongest productization gap is not code. It is +evidence that a non-maintainer can use Evydence on a real release to answer a +customer/security review question. + +### Ticket E8-T1 - [e] Run one design-partner pilot [ ] + +Description: Use Evydence with a non-maintainer team on one real release and +generate a customer-safe release evidence package. + +Implementation rules: + +- Use the existing design-partner pilot scope. +- Do not publish customer data, raw evidence, tokens, private keys, database + URLs, or provider credentials. +- Capture what worked, what was missing, and whether the package answered the + customer/security-review question. + +External reason: + +- Requires an external organization or design partner and permission to use the + outcome. + +### Ticket E8-T2 - [e] Publish an anonymized pilot report or case study [ ] + +Description: Publish a sanitized report showing one real release-evidence +workflow, verification path, limitations, and accepted gaps. + +Implementation rules: + +- Get explicit permission before publishing. +- Avoid legal compliance, certification, secure-release, complete-SBOM, or + authoritative-scanner claims. +- Link the report from commercial/pilot docs if public. + +External reason: + +- Requires external customer/design-partner approval. + +### Ticket E8-T3 - [e] Update public GitHub description to VEX-first positioning [ ] + +Description: Update the repository description so the public GitHub first +impression matches the README's sharper VEX-first release-evidence story. + +Suggested wording: + +`Self-hosted VEX-first release evidence ledger for customer CVE, SBOM, provenance, and release-review questions.` + +Implementation rules: + +- Verify with `gh repo view aatuh/evydence --json description`. +- Keep topics aligned with `vex`, `sbom`, `release-evidence`, and + `supply-chain-security`. + +External reason: + +- GitHub repository description and topics are provider settings. + +## Epic E9 - Re-Audit And Close Productization Loop [ ] + +Description: Re-run audits after the repo-local tickets are complete and only +raise product claims when evidence supports them. + +### Ticket E9-T1 - Re-run production readiness public repo audit loop [ ] + +Description: Re-run `production-readiness-public-repo-audit-loop` after E1-E7 +repo-local work is complete. + +Implementation rules: + +- Use target score `8`. +- Preserve prior audit directories. +- Treat `[e]` external items as tracked dependencies, not local failures. +- Do not run remediation in the audit turn unless explicitly requested. + +### Ticket E9-T2 - Re-run product-code audit focused on the VEX-first buyer path [ ] + +Description: Re-audit whether the implemented product now fulfills the +VEX-first customer-question workflow without overclaiming production or +compliance outcomes. + +Implementation rules: + +- Test the primary VEX-first flow, package viewer, public release verifier, and + customer package verification path. +- Turn findings into a follow-up backlog rather than broad feature expansion. + +### Ticket E9-T3 - Decide release status wording after audits [ ] + +Description: Decide whether the next release remains a controlled self-hosted +production candidate or can adopt a stronger narrow self-hosted production +profile. + +Implementation rules: + +- Require current audits, release evidence, CI, CodeQL, Scorecard, production + check, and package/demo proof. +- Keep regulated production, hosted SaaS production, legal compliance, + certification, complete SBOM proof, authoritative scanner results, and + secure-release claims out of scope unless independently proven. +- Update README, changelog, release notes, production readiness, release + evidence index, and commercial docs together. diff --git a/Makefile b/Makefile index c626de7..d3ef55d 100644 --- a/Makefile +++ b/Makefile @@ -258,12 +258,16 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'make production-check' .github/workflows/ci.yml >/dev/null @grep -F 'make production-check' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'EVYDENCE_RELEASE_SIGNING_PRIVATE_KEY_B64' .github/workflows/release-artifacts.yml >/dev/null + @grep -F 'EVYDENCE_RELEASE_PUBLISH_TOKEN' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'scripts/release_candidate_package.sh' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'evydence-release-manifest.sig.json' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'evydence-release-manifest.sig alias' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'gh release create' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'contents: read' .github/workflows/release-artifacts.yml >/dev/null + @! grep -F 'contents: write' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'Container Image' .github/workflows/container-image.yml >/dev/null + @grep -F 'EVYDENCE_GHCR_PUBLISH_TOKEN' .github/workflows/container-image.yml >/dev/null + @! grep -F 'packages: write' .github/workflows/container-image.yml >/dev/null @grep -F 'evydence-container-image-manifest.json' .github/workflows/container-image.yml >/dev/null @grep -F 'cosign-keyless' .github/workflows/container-image.yml >/dev/null @grep -F 'ghcr.io/aatuh/evydence' README.md >/dev/null diff --git a/RELEASE_EVIDENCE.md b/RELEASE_EVIDENCE.md index 55e05ce..101420d 100644 --- a/RELEASE_EVIDENCE.md +++ b/RELEASE_EVIDENCE.md @@ -34,6 +34,12 @@ release signing material, then writes release archives, checksums, OpenAPI and migration checksums, coverage output, release-check summary, checked release notes, a signed release manifest, and a manifest signature under `dist//`. +GitHub release and GHCR publication use explicit repository secrets instead of +broad `GITHUB_TOKEN` write permissions: `EVYDENCE_RELEASE_PUBLISH_TOKEN` for +draft release publication and `EVYDENCE_GHCR_PUBLISH_TOKEN` for container image +publication. Those secrets are external repository settings and are not release +evidence artifacts. + Release-candidate tagging is documented in [`docs/reference/release-candidate.md`](docs/reference/release-candidate.md). The required evidence set is a passing production-check summary, coverage diff --git a/docs/reference/release-candidate.md b/docs/reference/release-candidate.md index 3aee05d..d6639ee 100644 --- a/docs/reference/release-candidate.md +++ b/docs/reference/release-candidate.md @@ -78,6 +78,15 @@ evidence, and record that image digest with deployment evidence. If no image workflow evidence exists for a tag, operators must build and publish images into their own registry for Helm or air-gapped deployment flows. +The release packaging workflow keeps the repository `GITHUB_TOKEN` read-only. +Creating or updating the draft GitHub release requires the +`EVYDENCE_RELEASE_PUBLISH_TOKEN` secret with only the release-publication scope +the maintainer account approves for that workflow. The container image workflow +also keeps `GITHUB_TOKEN` from receiving package-write permissions; publishing +to GHCR requires `EVYDENCE_GHCR_PUBLISH_TOKEN`. Both secrets are external +repository settings and must not be printed in logs, committed to files, or +included in release evidence. + ## Deployment Constraints - Use one API writer replica for the current production profile. diff --git a/docs/reference/release-validation.md b/docs/reference/release-validation.md index 1c57a88..e06012c 100644 --- a/docs/reference/release-validation.md +++ b/docs/reference/release-validation.md @@ -163,9 +163,20 @@ set includes binaries, checksums, `openapi.yaml`, `openapi.sha256`, migration checksums, `coverage.out`, `release-check-summary.txt`, checked release notes, release SBOM/provenance metadata, the Scorecard-compatible in-toto provenance statement, the release manifest, and the manifest signature. Tag pushes create -or update a draft GitHub release. Maintainers publish it as a prerelease only -after the workflow artifact and release assets are verified. Manual runs can -upload only the workflow artifact unless `upload_draft_release` is enabled. +or update a draft GitHub release only when the external +`EVYDENCE_RELEASE_PUBLISH_TOKEN` secret is configured. The packaging job keeps +the repository `GITHUB_TOKEN` read-only; the publish token should be a +maintainer-controlled fine-grained token or GitHub App token with the minimum +release-publication scope needed for the repository. Maintainers publish a draft +as a prerelease only after the workflow artifact and release assets are +verified. Manual runs can upload only the workflow artifact unless +`upload_draft_release` is enabled. + +The container image workflow similarly keeps `GITHUB_TOKEN` from receiving +package-write permissions. GHCR publication requires +`EVYDENCE_GHCR_PUBLISH_TOKEN`; keyless image signing still requires GitHub OIDC +through `id-token: write`. These secrets are repository settings, not release +evidence artifacts, and must not be logged or committed. The canonical artifact map is [Release evidence index](release-evidence-index.md). Keep that page aligned diff --git a/scripts/release_acceptance.sh b/scripts/release_acceptance.sh index 5c7c951..f2d7580 100755 --- a/scripts/release_acceptance.sh +++ b/scripts/release_acceptance.sh @@ -80,7 +80,17 @@ require_text .github/workflows/codeql.yml "github/codeql-action/analyze@7211b7c8 require_text .github/workflows/codeql.yml "security-and-quality" require_text .github/workflows/ci.yml "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" require_text .github/workflows/release-artifacts.yml "contents: read" +require_text .github/workflows/release-artifacts.yml "EVYDENCE_RELEASE_PUBLISH_TOKEN" +if grep -F "contents: write" .github/workflows/release-artifacts.yml >/dev/null; then + printf '%s\n' "release-acceptance: release artifact workflow must not grant GITHUB_TOKEN contents: write" >&2 + exit 2 +fi require_text .github/workflows/container-image.yml "ghcr.io/\${{ github.repository }}" +require_text .github/workflows/container-image.yml "EVYDENCE_GHCR_PUBLISH_TOKEN" +if grep -F "packages: write" .github/workflows/container-image.yml >/dev/null; then + printf '%s\n' "release-acceptance: container image workflow must not grant GITHUB_TOKEN packages: write" >&2 + exit 2 +fi require_text .github/workflows/container-image.yml "cosign sign --yes" require_text .github/workflows/container-image.yml "cosign verify" require_text .github/workflows/container-image.yml "evydence-container-image-manifest.json" From 0db976ab903793ae21b0dd17e258e09acf1a5fcf Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 16:13:54 +0300 Subject: [PATCH 215/287] test(coverage): require postgres for production gate --- .productization_next_steps_missing.md | 2 +- Makefile | 2 +- README.md | 4 ++-- docs/reference/production-readiness.md | 6 +++++- docs/reference/release-validation.md | 4 ++++ scripts/coverage_check.sh | 6 ++++++ 6 files changed, 19 insertions(+), 5 deletions(-) diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index 592fb55..924f1e7 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -88,7 +88,7 @@ Implementation rules: - Verify the related Scorecard code-scanning alert closes or document a remaining external requirement. -### Ticket E1-T3 - Make coverage gate behavior deterministic [ ] +### Ticket E1-T3 - Make coverage gate behavior deterministic [x] Description: Fix the mismatch where public CI `make production-check` passes coverage with live PostgreSQL, but local `make coverage-check` fails at 67.9% diff --git a/Makefile b/Makefile index d3ef55d..5707897 100644 --- a/Makefile +++ b/Makefile @@ -44,7 +44,7 @@ coverage: ## Run tests with coverage @$(GO) test ./... -coverprofile=coverage.out @$(GO) tool cover -func=coverage.out -coverage-check: ## Enforce the production coverage threshold +coverage-check: ## Enforce the production coverage threshold; requires EVYDENCE_TEST_DATABASE_URL @scripts/coverage_check.sh openapi.yaml: ## Generate committed OpenAPI source diff --git a/README.md b/README.md index 3e5b1eb..4c4a8a0 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![License: AGPL-3.0-only](https://img.shields.io/badge/license-AGPL--3.0--only-blue.svg)](LICENSE) ![Go Version](https://img.shields.io/badge/go-1.25+-00ADD8.svg) ![OpenAPI](https://img.shields.io/badge/OpenAPI-171%20precise%20operations-brightgreen.svg) -![Coverage Gate](https://img.shields.io/badge/coverage%20gate-80%25+-brightgreen.svg) +![Coverage Gate](https://img.shields.io/badge/production%20coverage-80%25+-brightgreen.svg) Evydence is a self-hosted, API-first release evidence ledger for product security, AppSec, platform, release engineering, and compliance-readiness teams @@ -239,6 +239,6 @@ make live-postgres-check make postgres-integration-test ``` -`make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. +`make finalize` runs the project-owned formatting, unit, OpenAPI, docs, deployment, and SDK gates. `make release-check` extends that with lint, gosec, govulncheck, race tests, and live PostgreSQL gates when `EVYDENCE_TEST_DATABASE_URL` is configured. `make coverage` is the no-database local coverage view; `make coverage-check` is the production coverage gate and requires `EVYDENCE_TEST_DATABASE_URL` so PostgreSQL-backed coverage is included. `make production-check` is stricter: it requires `EVYDENCE_TEST_DATABASE_URL`, enforces the configured coverage threshold, and runs a release artifact signing smoke test. Passing the gate is required release-candidate evidence, but it does not by itself close the remaining service decomposition, PKCS#11/native HSM custody, direct provider-specific management API/group synchronization, broader object-lock enforcement beyond configured bucket/sample-object checks, HA, and exit-review work. Production API and worker processes default to relational-only PostgreSQL loads and skip compatibility snapshot writes; the compatibility snapshot remains for migration, recovery, and local workflows. Critical runtime mutations for tenants, credential hashes, idempotency, audit-chain entries, release bundles, signatures, verification results, vulnerability decisions, and outbox jobs use focused PostgreSQL write paths when available. Release-ledger and evidence-core mutations for products, projects, releases, artifacts, evidence items, evidence lifecycle events, SBOMs, vulnerability scans, OpenAPI contracts, VEX documents, audit-chain entries, and parser outbox jobs also use focused PostgreSQL write paths when available. Remaining aggregate persistence calls use PostgreSQL relational synchronization without writing the compatibility snapshot when that store is configured. Current self-hosted production guidance still uses a single API writer replica; production API startup rejects unsupported writer modes and declared replica counts above one, then enforces that stance with a PostgreSQL advisory writer lease. Worker replicas may scale through PostgreSQL outbox row locking. diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 34e3094..d52d07b 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -139,13 +139,17 @@ Release-candidate tagging additionally requires the evidence set in migration checksums, signed artifact manifests, artifact checksums, and release notes with limitations. -The default coverage threshold is 80 percent: +The default production coverage threshold is 80 percent and the gate requires +`EVYDENCE_TEST_DATABASE_URL` so live PostgreSQL adapter tests are included: ```sh make coverage-check EVYDENCE_COVERAGE_THRESHOLD=85 make coverage-check ``` +For local no-PostgreSQL exploration, use `make coverage`; do not treat that +output as production release evidence. + `make production-check` is intentionally stricter than `make finalize`. Use `make finalize` for routine local development. Use `make production-check` for self-hosted production readiness evidence. diff --git a/docs/reference/release-validation.md b/docs/reference/release-validation.md index e06012c..20e637b 100644 --- a/docs/reference/release-validation.md +++ b/docs/reference/release-validation.md @@ -45,6 +45,10 @@ PostgreSQL schema for a black-box demo/restart persistence check, and runs a release artifact signing smoke test. See [Production readiness](production-readiness.md) for the supported profiles and exit criteria. +`make coverage-check` is intentionally part of the production profile and fails +early when `EVYDENCE_TEST_DATABASE_URL` is unset. Use `make coverage` for a +local no-database coverage report that is not release-candidate evidence. + ## Release Candidate Checklist Before tagging `v0.1.0-rc.1`, `v0.9.0-rc.1`, or another controlled diff --git a/scripts/coverage_check.sh b/scripts/coverage_check.sh index c6fa198..902ab42 100755 --- a/scripts/coverage_check.sh +++ b/scripts/coverage_check.sh @@ -7,6 +7,12 @@ cd "$repo_root" threshold="${EVYDENCE_COVERAGE_THRESHOLD:-80.0}" profile="${EVYDENCE_COVERAGE_PROFILE:-coverage.out}" +if [ -z "${EVYDENCE_TEST_DATABASE_URL:-}" ]; then + printf '%s\n' "coverage-check: EVYDENCE_TEST_DATABASE_URL is required for the production coverage gate" >&2 + printf '%s\n' "coverage-check: use make coverage for local no-PostgreSQL coverage, or run make release-check-local-postgres" >&2 + exit 2 +fi + go test ./... -coverprofile="$profile" total="$(go tool cover -func="$profile" | awk '/^total:/ { gsub("%", "", $3); print $3 }')" From c4656251cb181332ed1f55b8af9e6d892ecded89 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 16:14:41 +0300 Subject: [PATCH 216/287] docs(security): document maintainer bypass posture --- .productization_next_steps_missing.md | 2 +- docs/reference/maintainer-review-policy.md | 28 ++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index 924f1e7..4c10988 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -106,7 +106,7 @@ Implementation rules: intended deterministic behavior. - Run `make docs-check` and `make release-acceptance`. -### Ticket E1-T4 - Document maintainer branch-protection bypass posture [ ] +### Ticket E1-T4 - Document maintainer branch-protection bypass posture [x] Description: Document that branch protection can be bypassed by maintainers if admin enforcement remains disabled, and state compensating controls without diff --git a/docs/reference/maintainer-review-policy.md b/docs/reference/maintainer-review-policy.md index 661cfb8..73ef20d 100644 --- a/docs/reference/maintainer-review-policy.md +++ b/docs/reference/maintainer-review-policy.md @@ -15,6 +15,34 @@ rules must enforce CODEOWNERS and required checks before it becomes a merge gate. Until those GitHub settings are enabled, this file is a public review policy and not a technical enforcement guarantee. +## Maintainer Bypass Posture + +The repository may allow maintainers or administrators to bypass branch +protection depending on the live GitHub repository settings. Evydence therefore +does not claim that every change is technically forced through pull-request +review, even though pull-request review is the expected path for high-risk +changes. + +When a maintainer bypass is used for an urgent or operational change, the +maintainer should record the reason in the pull request, release evidence, or a +follow-up audit note as appropriate. The compensating controls are: + +- required `Production Check` and `CodeQL Analyze` CI jobs on normal push and + pull-request paths; +- project-owned `make production-check`, `make release-acceptance`, and + release-candidate validation gates for release-affecting changes; +- signed release artifacts, checksums, OpenAPI checksums, migration checksums, + and release evidence manifests before candidate tags are treated as operator + evaluation inputs; +- `CODEOWNERS` coverage for high-risk paths, which states expected maintainer + ownership even when repository settings are not public proof of enforcement; +- public release evidence and audit visibility for candidate releases. + +These controls support review and reproducibility. They do not prove that a +specific live GitHub setting prevented maintainer bypass, and they are not legal +compliance proof, certification, complete vulnerability coverage, or a +secure-release guarantee. + ## High-Risk Paths Changes in these areas require maintainer review before merge or release: From d3d46937fb24113b0aad26666468bbd94d760413 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 16:16:16 +0300 Subject: [PATCH 217/287] docs(product): add evaluator walkthrough --- .productization_next_steps_missing.md | 2 +- Makefile | 8 ++ README.md | 2 + docs/README.md | 1 + docs/tutorials/evaluate-in-10-minutes.md | 137 +++++++++++++++++++++++ 5 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 docs/tutorials/evaluate-in-10-minutes.md diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index 4c10988..1e6e178 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -157,7 +157,7 @@ Description: Convert the already implemented VEX-first flow into an evaluation path a skeptical product-security buyer or customer reviewer understands without reading architecture docs. -### Ticket E2-T1 - Add a one-page evaluator walkthrough [ ] +### Ticket E2-T1 - Add a one-page evaluator walkthrough [x] Description: Add a concise "evaluate in 10 minutes" walkthrough that starts from the current public release, sample package, local package viewer, and diff --git a/Makefile b/Makefile index 5707897..52a4573 100644 --- a/Makefile +++ b/Makefile @@ -128,6 +128,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @test -f docs/air-gapped.md @test -f docs/release-signing.md @test -f docs/production-hardening.md + @test -f docs/tutorials/evaluate-in-10-minutes.md @test -f docs/tutorials/getting-started.md @test -f docs/how-to/integrate-ci.md @test -f docs/how-to/install-and-operate.md @@ -163,6 +164,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @test -f .github/workflows/codeql.yml @test -f docs/sdk/README.md @for path in \ + "tutorials/evaluate-in-10-minutes.md" \ "tutorials/getting-started.md" \ "how-to/install-and-operate.md" \ "how-to/view-packages.md" \ @@ -216,6 +218,12 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F './evydence release verify' docs/air-gapped.md >/dev/null @grep -F './evydence import-bundle upload' docs/air-gapped.md >/dev/null @test -x scripts/public_release_verify.sh + @grep -F 'This CVE appears in your SBOM. Are you affected, why, who approved it, and' docs/tutorials/evaluate-in-10-minutes.md >/dev/null + @grep -F 'sample-customer-package-manifest.json' docs/tutorials/evaluate-in-10-minutes.md >/dev/null + @grep -F 'site/package-viewer/index.html' docs/tutorials/evaluate-in-10-minutes.md >/dev/null + @grep -F 'make public-release-verify TAG=v0.1.0-rc.5' docs/tutorials/evaluate-in-10-minutes.md >/dev/null + @grep -F 'examples/end-to-end-release-evidence/run-local-demo.sh' docs/tutorials/evaluate-in-10-minutes.md >/dev/null + @grep -F 'Evaluate Evydence in 10 minutes' README.md docs/README.md >/dev/null @grep -F 'make public-release-verify TAG=v0.1.0-rc.5' README.md >/dev/null @grep -F 'make public-release-verify TAG=v0.1.0-rc.5' docs/how-to/install-and-operate.md >/dev/null @grep -F 'make public-release-verify TAG=v0.1.0-rc.5' docs/reference/release-evidence-index.md >/dev/null diff --git a/README.md b/README.md index 4c4a8a0..2781182 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,8 @@ For `v0.1.0-rc.5`, the published image is ## Fastest Proof Path +For a reviewer-first path, follow +[Evaluate Evydence in 10 minutes](docs/tutorials/evaluate-in-10-minutes.md). For a first local API flow, follow [Getting started](docs/tutorials/getting-started.md). For durable local evaluation, run the production-like Compose rehearsal in [Install and operate](docs/how-to/install-and-operate.md). diff --git a/docs/README.md b/docs/README.md index 342196b..4b1a895 100644 --- a/docs/README.md +++ b/docs/README.md @@ -4,6 +4,7 @@ This documentation is organized by reader task. Implementation claims should be ## Start Here +- [Evaluate Evydence in 10 minutes](tutorials/evaluate-in-10-minutes.md): inspect the public release verifier, sample customer package, local package viewer, and VEX-first proof path. - [Getting started](tutorials/getting-started.md): run the API locally and create a minimal release evidence flow. - [Install and operate](how-to/install-and-operate.md): choose a local runtime mode, start dependencies, run migrations, and launch API/worker processes. - [Operations](operations.md): find the canonical operator references for configuration, workers, CI, deployment, and validation. diff --git a/docs/tutorials/evaluate-in-10-minutes.md b/docs/tutorials/evaluate-in-10-minutes.md new file mode 100644 index 0000000..c50ea77 --- /dev/null +++ b/docs/tutorials/evaluate-in-10-minutes.md @@ -0,0 +1,137 @@ +# Evaluate Evydence In 10 Minutes + +This walkthrough is for a product-security, AppSec, platform, or customer +reviewer who wants to understand the VEX-first release-evidence path without +running a full production deployment. + +The question to answer is: + +> This CVE appears in your SBOM. Are you affected, why, who approved it, and +> what can I verify? + +Evydence answers that question by linking release, artifact, SBOM, +vulnerability scan, VEX or manual decision, approval or exception, readiness, +bundle, package, and audit-chain evidence. The checked fixtures are +non-sensitive examples. They are not legal compliance proof, certification, +complete SBOM proof, authoritative vulnerability results, or a secure-release +guarantee. + +## 1. Verify The Public Release Candidate + +Start by verifying the release artifacts you would install or evaluate: + +```sh +make public-release-verify TAG=v0.1.0-rc.5 +``` + +This downloads the public release-candidate evidence and checks the release +archives, OpenAPI checksum, migration checksum, in-toto provenance statement +shape, and signed release manifest. The release evidence index explains every +artifact in the set: + +- [Release evidence index](../reference/release-evidence-index.md) +- [Release candidate checklist](../reference/release-candidate.md) + +## 2. Open The Sample Customer Package + +Open the local package viewer: + +```sh +xdg-open site/package-viewer/index.html +``` + +If `xdg-open` is not available, open `site/package-viewer/index.html` directly +from your browser. + +In the viewer, press **Load bundled demo** or load this checked fixture: + +```text +examples/end-to-end-release-evidence/sample-customer-package-manifest.json +``` + +The sample package is also available as a ZIP archive: + +```text +examples/end-to-end-release-evidence/sample-customer-package.zip +``` + +Use the viewer to inspect: + +- release scope, package scope, and limitations; +- included artifact, SBOM, scan, VEX, decision, approval, and bundle metadata; +- the vulnerability decision that explains why the sample finding is not + treated as an unresolved blocker; +- verification status and audit-chain evidence; +- explicitly excluded raw payload bytes, secrets, hashes, and internal notes. + +The package viewer guide has the same path with screenshots and offline +verification commands: + +- [View packages locally](../how-to/view-packages.md) + +## 3. Verify The Sample Package + +Verify the checked package fixture without running the API: + +```sh +go run ./cmd/evydence package verify \ + --archive examples/end-to-end-release-evidence/sample-customer-package.zip \ + --expected-package-id csp_example \ + --expected-product-id prod_example \ + --expected-release-id rel_example +``` + +Expected result: the command exits successfully and validates the package +manifest, archive metadata, and expected scope identifiers. It verifies the +example package bytes; it does not verify facts outside the sample data. + +## 4. Read The Evidence Path + +Use the end-to-end example as the shortest map from the reviewer question to +concrete API outputs: + +- [End-to-end release evidence example](../../examples/end-to-end-release-evidence/README.md) +- [Sample readiness report](../../examples/end-to-end-release-evidence/sample-readiness-report.json) +- [Sample security summary](../../examples/end-to-end-release-evidence/sample-security-summary.json) +- [Sample audit-chain verification](../../examples/end-to-end-release-evidence/sample-audit-chain-verification.json) + +The key files are: + +| Reviewer question | Example file | +| --- | --- | +| Which SBOM did you use? | `sample-customer-package-manifest.json` and `sample-readiness-report.json` | +| Which scanner raised the finding? | `sample-security-summary.json` | +| Are you affected and why? | `sample-customer-package-manifest.json` vulnerability decision section | +| Who recorded or approved the answer? | package approvals and audit-chain fixture | +| What can I verify offline? | package archive, package manifest, bundle metadata, and audit-chain fixture | +| What is missing or limited? | readiness report gaps, assumptions, limitations, and non-claims | + +## 5. Run The Local API Demo When Ready + +After the static review path makes sense, run the API-backed demo: + +```sh +EVYDENCE_URL=http://localhost:8080 \ +EVYDENCE_API_KEY='evy_replace_with_scoped_secret' \ +examples/end-to-end-release-evidence/run-local-demo.sh +``` + +The demo creates a product, release, artifact, SBOM, vulnerability scan, +vulnerability decision, release bundle, redaction profile, customer package, +readiness report, security summary, and audit-chain verification output under +`tmp/end-to-end-release-evidence/`. + +For a step-by-step local API setup, use: + +- [Getting started](getting-started.md) +- [Install and operate](../how-to/install-and-operate.md) + +## What This Evaluation Should Show + +After these steps, a reviewer should be able to trace one vulnerability answer +from SBOM and scanner evidence through a VEX or manual decision into a +customer-safe package and verification commands. + +This supports compliance readiness and technical evidence organization. It +does not replace human review, legal analysis, scanner validation, provider +controls, or customer-specific disclosure decisions. From cc27bba251ad41b59ace09d41c3acd46a75fd7af Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 16:17:38 +0300 Subject: [PATCH 218/287] docs(product): add reviewer journey visual --- .productization_next_steps_missing.md | 2 +- Makefile | 8 ++++ docs/assets/reviewer-journey.svg | 56 +++++++++++++++++++++++++++ docs/how-to/view-packages.md | 17 ++++++++ 4 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 docs/assets/reviewer-journey.svg diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index 1e6e178..4214a81 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -175,7 +175,7 @@ Implementation rules: docs page. - Run `make docs-check`, `make demo-check`, and `make package-viewer-check`. -### Ticket E2-T2 - Add a visual reviewer journey using existing fixtures [ ] +### Ticket E2-T2 - Add a visual reviewer journey using existing fixtures [x] Description: Add a static, checked reviewer journey that shows the package viewer states for release summary, VEX decisions, evidence contents, diff --git a/Makefile b/Makefile index 52a4573..a2b27b5 100644 --- a/Makefile +++ b/Makefile @@ -367,6 +367,7 @@ benchmark-check: ## Run the checked app-layer release evidence benchmark package-viewer-check: ## Validate local package viewer and walkthrough @test -f site/package-viewer/index.html @test -f docs/how-to/view-packages.md + @test -f docs/assets/reviewer-journey.svg @grep -F 'Load bundled demo' site/package-viewer/index.html >/dev/null @grep -F 'textContent' site/package-viewer/index.html >/dev/null @! grep -F 'innerHTML' site/package-viewer/index.html >/dev/null @@ -374,6 +375,13 @@ package-viewer-check: ## Validate local package viewer and walkthrough @grep -F 'Vulnerability / VEX Decisions' site/package-viewer/index.html >/dev/null @grep -F 'Verification Status' site/package-viewer/index.html >/dev/null @grep -F 'examples/end-to-end-release-evidence/sample-customer-package-manifest.json' docs/how-to/view-packages.md >/dev/null + @grep -F 'reviewer-journey.svg' docs/how-to/view-packages.md >/dev/null + @grep -F 'Release Summary' docs/assets/reviewer-journey.svg >/dev/null + @grep -F 'VEX Decisions' docs/assets/reviewer-journey.svg >/dev/null + @grep -F 'Evidence Contents' docs/assets/reviewer-journey.svg >/dev/null + @grep -F 'Verification Status' docs/assets/reviewer-journey.svg >/dev/null + @grep -F 'Gaps' docs/assets/reviewer-journey.svg >/dev/null + @grep -F 'Limitations' docs/assets/reviewer-journey.svg >/dev/null restore-rehearsal-check: ## Run repository-owned backup/restore rehearsal tests @$(GO) test ./internal/app -run TestBackupRestoreRehearsalPreservesLedgerAndObjectPayloads -count=1 diff --git a/docs/assets/reviewer-journey.svg b/docs/assets/reviewer-journey.svg new file mode 100644 index 0000000..9df928b --- /dev/null +++ b/docs/assets/reviewer-journey.svg @@ -0,0 +1,56 @@ + + Evydence reviewer journey + Static journey through release summary, vulnerability decisions, evidence contents, verification, gaps, and limitations using non-sensitive sample package data. + + + Reviewer Journey + Sample package, local viewer only, no upload + + + + + + + + + + 1. Release Summary + Product, release, package scope, + artifact digests, report result. + + + 2. VEX Decisions + Affected, fixed, not affected, + approval and impact statements. + + + 3. Evidence Contents + SBOM, scan, VEX, bundle, + approvals, redaction metadata. + + + + + + 4. Verification Status + Manifest hash, archive scope, + bundle and audit-chain checks. + + + 5. Gaps + Missing evidence, stale items, + unhandled findings, exceptions. + + + 6. Limitations + No legal compliance proof, + no complete SBOM proof. + + + + + + + + Input: examples/end-to-end-release-evidence/sample-customer-package-manifest.json + diff --git a/docs/how-to/view-packages.md b/docs/how-to/view-packages.md index 8d5f9a5..c0f7904 100644 --- a/docs/how-to/view-packages.md +++ b/docs/how-to/view-packages.md @@ -30,6 +30,23 @@ redacted package manifest and local inline styles. ![Static package viewer preview](../assets/package-viewer-preview.svg) +The sample reviewer journey is: + +![Reviewer journey through package sections](../assets/reviewer-journey.svg) + +1. Read the release summary to confirm product, release, package scope, + artifact digests, and readiness result. +2. Inspect vulnerability and VEX decisions to see the recorded status, + impact/action statement, approval context, and whether the decision is + customer-visible. +3. Review evidence contents to confirm which SBOM, scan, VEX, release bundle, + approval, exception, and redaction metadata are included. +4. Check verification status before relying on package bytes for review. +5. Read gaps for missing evidence, stale evidence, unhandled findings, and + exceptions that did not unblock readiness. +6. Read assumptions and limitations before using the package in a customer or + internal review. + Use it for: - checking a release-readiness report before sending a customer package; From 80f3e9d52178e235dde4981ff0bddf3b7af16e38 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 16:19:26 +0300 Subject: [PATCH 219/287] docs(product): focus README proof path --- .productization_next_steps_missing.md | 2 +- Makefile | 5 ++ README.md | 59 ++++--------- docs/README.md | 1 + docs/reference/capability-map.md | 118 ++++++++++++++++++++++++++ 5 files changed, 143 insertions(+), 42 deletions(-) create mode 100644 docs/reference/capability-map.md diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index 4214a81..49d26af 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -190,7 +190,7 @@ Implementation rules: - Update `docs/how-to/view-packages.md` and docs assets. - Run `make package-viewer-check` and `make docs-check`. -### Ticket E2-T3 - Reduce first-screen feature sprawl [ ] +### Ticket E2-T3 - Reduce first-screen feature sprawl [x] Description: Keep the README first screen focused on products, releases, SBOMs, vulnerability scans, VEX/manual decisions, provenance, release bundles, and diff --git a/Makefile b/Makefile index a2b27b5..7baacd0 100644 --- a/Makefile +++ b/Makefile @@ -134,6 +134,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @test -f docs/how-to/install-and-operate.md @test -f docs/how-to/view-packages.md @test -f docs/reference/configuration.md + @test -f docs/reference/capability-map.md @test -f docs/reference/api-contract-matrix.md @test -f docs/reference/openapi.md @test -f docs/reference/vulnerability-decisions.md @@ -176,6 +177,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod "release-signing.md" \ "production-hardening.md" \ "reference/configuration.md" \ + "reference/capability-map.md" \ "reference/api-contract-matrix.md" \ "reference/openapi.md" \ "reference/vulnerability-decisions.md" \ @@ -225,6 +227,9 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'examples/end-to-end-release-evidence/run-local-demo.sh' docs/tutorials/evaluate-in-10-minutes.md >/dev/null @grep -F 'Evaluate Evydence in 10 minutes' README.md docs/README.md >/dev/null @grep -F 'make public-release-verify TAG=v0.1.0-rc.5' README.md >/dev/null + @grep -F 'Capability map' README.md docs/README.md >/dev/null + @grep -F 'Implemented-But-Partial Areas' docs/reference/capability-map.md >/dev/null + @grep -F 'VEX/manual' README.md >/dev/null @grep -F 'make public-release-verify TAG=v0.1.0-rc.5' docs/how-to/install-and-operate.md >/dev/null @grep -F 'make public-release-verify TAG=v0.1.0-rc.5' docs/reference/release-evidence-index.md >/dev/null @grep -F 'make public-release-verify TAG=v0.1.0-rc.5' examples/end-to-end-release-evidence/README.md >/dev/null diff --git a/README.md b/README.md index 2781182..b1091b2 100644 --- a/README.md +++ b/README.md @@ -137,47 +137,24 @@ non-sensitive sample data and does not upload files. contract, tenant scoping, idempotency, audit chains, release evidence, and checked non-claim language from the start. -### API And Contracts - -- HTTP API under `/v1` using `github.com/aatuh/api-toolkit/v3` route contracts, OpenAPI generation, response helpers, and Problem Details. -- Generated OpenAPI contract committed at `openapi.yaml` and served at `/v1/openapi.json`. -- Request idempotency for create/action endpoints and tenant-scoped Problem Details responses. - -### Identity And Tenant Boundaries - -- Multi-tenant scoped API keys with one-time secret output, HMAC-SHA256 storage, and server-side scope checks. -- Organizations, users, role bindings, admin-managed SSO provider/session records, collector keys, and customer portal package tokens. -- Instance diagnostics require explicit `instance:admin` scope. - -### Evidence And Release Records - -- Products, projects, releases, release candidates, artifacts, container images, artifact signatures, evidence search, evidence lifecycle events, SBOM and VEX upload, vulnerability scans, vulnerability decisions, exceptions, waivers, approvals, incidents, remediation tasks, source records, deployment events, controls, reports, policies, release bundles, evidence bundles, backup manifests, and retention records. -- Immutable or append-only behavior for evidence core fields, release bundles, approvals, exceptions, audit entries, chain entries, and related transition records. -- Release-readiness, control-coverage, CRA-readiness, vulnerability-posture, incident-package, security-review-package, evidence-summary, questionnaire-draft, graph-snapshot, PDF-package, anomaly, retention, and backup-manifest reports with assumptions and limitations. - -### Persistence, Object Storage, And Workers - -- In-process store for local demos and unit-test execution when `EVYDENCE_DATABASE_URL` is unset. -- PostgreSQL-backed durable ledger state, tenant-scoped relational projections, migrations, and persisted outbox jobs when `EVYDENCE_DATABASE_URL` is set. -- Filesystem or S3/MinIO-compatible object storage for raw upload payload bytes under tenant-prefixed paths. -- Polling `cmd/evydence-worker` process that claims persisted outbox jobs with PostgreSQL row locking and records retry or terminal status. -- Optional worker-owned parser side effects through `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, including OpenVEX-derived vulnerability decisions created idempotently by the `parse_vex` worker. - -### Tooling, Deployment, And Examples - -- `cmd/evydence` helper for hashing, one-shot release evidence upload, manifest verification, GitHub Actions build provenance upload, release artifact manifest signing/verification, bulk upload manifests, and air-gapped evidence bundle import. -- Docker Compose dependencies for PostgreSQL and MinIO. -- Production-like Docker Compose rehearsal with API, worker, migrations, - PostgreSQL, and MinIO. -- Kubernetes Helm chart under `deploy/helm/evydence`. -- Air-gapped package manifest under `deploy/airgap/manifest.yaml`. -- Lightweight Go, TypeScript, and Python SDK wrappers. -- GitHub Actions and GitLab CI workflow examples. -- Documentation portal under `docs/`. -- AGPL license, commercial licensing, governance, contribution, security, - support, code of conduct, trademark, release-evidence, and changelog metadata. - -Implemented-but-partial areas are documented explicitly: signing-provider operation receipts can use an HTTPS signing gateway, built-in AWS KMS, GCP Cloud KMS, or Azure Key Vault executors, `pkcs11-hsm` remains gateway-backed because native HSM modules are deployment-specific, and `native_pkcs11_hsm` provider records plus custody-review reports capture operator-supplied HSM profile evidence without loading modules or proving custody. SSO credential exchange uses configured local OIDC/SAML trust material and session-scoped OIDC group-role mappings, and provider verification can optionally call OIDC UserInfo or an operator-controlled provider validation gateway when a caller supplies an access token, but the gateway receives only non-secret metadata and this does not replace direct provider-specific management API clients or external group synchronization. Public transparency records can verify operator-supplied proof material, fetch from configured endpoints, or use an operator-controlled transparency proof gateway without replacing provider-specific trust review. +### Core Product Path + +- `/v1` API, committed OpenAPI contract, idempotent create/action requests, and + tenant-scoped Problem Details responses. +- Products, releases, artifacts, SBOMs, vulnerability scans, VEX/manual + decisions, exceptions, approvals, release bundles, audit-chain verification, + and customer-safe packages. +- Release-readiness, vulnerability-decision, control-coverage, CRA-readiness, + security-summary, package, retention, and backup reports with assumptions and + limitations. +- PostgreSQL, object storage, outbox worker, CLI upload/verification helpers, + GitHub Actions/GitLab examples, SDK wrappers, Compose, Helm, and air-gapped + packaging paths. + +For the full advanced capability inventory, including identity, controls, +source/deployment/incident evidence, retention, backup, signing-provider +profiles, provider verification, transparency records, and +implemented-but-partial areas, see [Capability map](docs/reference/capability-map.md). ## License, Security, Support, And Governance diff --git a/docs/README.md b/docs/README.md index 4b1a895..5124062 100644 --- a/docs/README.md +++ b/docs/README.md @@ -27,6 +27,7 @@ This documentation is organized by reader task. Implementation claims should be - [Configuration](reference/configuration.md): canonical environment variables and the roles of `.env.example`, `.api.env.example`, and `.test.env.example`. - [Documentation source of truth](reference/source-of-truth.md): canonical source map to keep commands, status, and limitations from drifting. +- [Capability map](reference/capability-map.md): advanced inventory of implemented capabilities, implementation limits, and implemented-but-partial areas. - [API contract matrix](reference/api-contract-matrix.md): generated route-by-route contract precision inventory for production hardening. - [OpenAPI contract](reference/openapi.md): generation, drift checks, and review tips for `openapi.yaml`. - [Vulnerability decisions](reference/vulnerability-decisions.md): current VEX/decision model, buyer-facing gaps, and planned API changes. diff --git a/docs/reference/capability-map.md b/docs/reference/capability-map.md new file mode 100644 index 0000000..3c950e3 --- /dev/null +++ b/docs/reference/capability-map.md @@ -0,0 +1,118 @@ +# Capability Map + +This reference keeps the broad implementation inventory out of the README +first screen while preserving a discoverable map for operators, reviewers, and +contributors. + +The map describes repository capabilities that are backed by source code, +OpenAPI, tests, deployment files, examples, or checked documentation. It is not +legal compliance proof, certification, complete SBOM proof, authoritative +vulnerability coverage, or a secure-release guarantee. + +## API And Contracts + +- HTTP API under `/v1` using `github.com/aatuh/api-toolkit/v3` route contracts, + OpenAPI generation, response helpers, and Problem Details. +- Generated OpenAPI contract committed at `openapi.yaml` and served at + `/v1/openapi.json`. +- Request idempotency for create/action endpoints and tenant-scoped Problem + Details responses. + +## Identity And Tenant Boundaries + +- Multi-tenant scoped API keys with one-time secret output, HMAC-SHA256 + storage, and server-side scope checks. +- Organizations, users, role bindings, admin-managed SSO provider/session + records, collector keys, and customer portal package tokens. +- Instance diagnostics require explicit `instance:admin` scope. + +## Release Evidence Core + +- Products, projects, releases, release candidates, artifacts, container + images, artifact signatures, SBOM and VEX upload, vulnerability scans, + vulnerability decisions, exceptions, waivers, approvals, policies, release + bundles, evidence bundles, and customer packages. +- Immutable or append-only behavior for evidence core fields, release bundles, + approvals, exceptions, audit entries, chain entries, and related transition + records. +- Release-readiness, vulnerability-decision-summary, missing-evidence, + security-summary, package, retention, and backup-manifest reports with + assumptions and limitations. + +## Extended Evidence Families + +- Evidence search, evidence lifecycle events, controls, CRA/control coverage, + source records, deployment events, incidents, remediation tasks, audit log + querying, object retention records, transparency records, backup manifests, + and customer package access records. +- Control-coverage, CRA-readiness, vulnerability-posture, incident-package, + security-review-package, evidence-summary, questionnaire-draft, + graph-snapshot, PDF-package, anomaly, retention, and backup reports. +- Customer package manifests and static report exports are redaction-aware and + exclude raw payload bytes, bearer tokens, private keys, API key hashes, SSO or + session token hashes, and internal notes by default. + +## Persistence, Object Storage, And Workers + +- In-process store for local demos and unit-test execution when + `EVYDENCE_DATABASE_URL` is unset. +- PostgreSQL-backed durable ledger state, tenant-scoped relational projections, + migrations, and persisted outbox jobs when `EVYDENCE_DATABASE_URL` is set. +- Production API and worker processes default to relational-only PostgreSQL + loads and skip compatibility snapshot writes; the compatibility snapshot + remains for migration, recovery, and local workflows. +- Filesystem or S3/MinIO-compatible object storage for raw upload payload bytes + under tenant-prefixed paths. +- Polling `cmd/evydence-worker` process that claims persisted outbox jobs with + PostgreSQL row locking and records retry or terminal status. +- Optional worker-owned parser side effects through + `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, including OpenVEX-derived + vulnerability decisions created idempotently by the `parse_vex` worker. + +## Tooling, Deployment, And Examples + +- `cmd/evydence` helper for hashing, one-shot release evidence upload, + manifest verification, GitHub Actions build provenance upload, release + artifact manifest signing/verification, bulk upload manifests, and air-gapped + evidence bundle import. +- Docker Compose dependencies for PostgreSQL and MinIO. +- Production-like Docker Compose rehearsal with API, worker, migrations, + PostgreSQL, and MinIO. +- Kubernetes Helm chart under `deploy/helm/evydence`. +- Air-gapped package manifest under `deploy/airgap/manifest.yaml`. +- Lightweight Go, TypeScript, and Python SDK wrappers. +- GitHub Actions and GitLab CI workflow examples. +- Documentation portal under `docs/`. +- AGPL license, commercial licensing, governance, contribution, security, + support, code of conduct, trademark, release-evidence, and changelog + metadata. + +## Implemented-But-Partial Areas + +- Signing-provider operation receipts can use an HTTPS signing gateway, built-in + AWS KMS, GCP Cloud KMS, or Azure Key Vault executors. +- `pkcs11-hsm` remains gateway-backed because native HSM modules are + deployment-specific. +- `native_pkcs11_hsm` provider records and custody-review reports capture + operator-supplied HSM profile evidence without loading modules or proving + custody. +- SSO credential exchange uses configured local OIDC/SAML trust material and + session-scoped OIDC group-role mappings. +- Provider verification can optionally call OIDC UserInfo or an + operator-controlled provider validation gateway when a caller supplies an + access token. The gateway receives only non-secret metadata and does not + replace direct provider-specific management API clients or external group + synchronization. +- Public transparency records can verify operator-supplied proof material, + fetch from configured endpoints, or use an operator-controlled transparency + proof gateway without replacing provider-specific trust review. +- Production API deployments remain intentionally single-writer until + multi-writer API concurrency is reviewed across every write family. Worker + replicas may scale through PostgreSQL outbox locking. + +## Where To Go Next + +- Start with [Evaluate Evydence in 10 minutes](../tutorials/evaluate-in-10-minutes.md). +- Run the local API path in [Getting started](../tutorials/getting-started.md). +- Review production limits in [Production readiness](production-readiness.md). +- Inspect public release artifacts in [Release evidence index](release-evidence-index.md). From 33a4d0f045ab37ce9bcf6d95091cd199d01282c5 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 16:22:54 +0300 Subject: [PATCH 220/287] feat(package): add reviewer proof checklist --- .productization_next_steps_missing.md | 2 +- Makefile | 6 +++ docs/how-to/view-packages.md | 3 ++ docs/reference/customer-package-manifest.md | 19 +++++++++ .../end-to-end-release-evidence/README.md | 5 ++- .../sample-customer-package-manifest.json | 38 ++++++++++++++++++ .../sample-customer-package-manifest.sha256 | 2 +- .../sample-customer-package.zip | Bin 3032 -> 3464 bytes internal/app/customer_package_golden_test.go | 19 +++++++++ site/package-viewer/index.html | 14 +++++++ 10 files changed, 104 insertions(+), 4 deletions(-) diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index 49d26af..7b2777e 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -203,7 +203,7 @@ Implementation rules: - Keep VEX-first buyer language dominant near the top of the README. - Run `make docs-check` and `make release-acceptance`. -### Ticket E2-T4 - Add a proof-path checklist to the sample package [ ] +### Ticket E2-T4 - Add a proof-path checklist to the sample package [x] Description: Make the sample customer package and package viewer show a reviewer-oriented checklist: package scope, included evidence, excluded diff --git a/Makefile b/Makefile index 7baacd0..b1fed4a 100644 --- a/Makefile +++ b/Makefile @@ -237,6 +237,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'package-viewer-preview.svg' docs/how-to/view-packages.md >/dev/null @grep -F 'report.html' docs/reference/customer-package-manifest.md docs/how-to/view-packages.md >/dev/null @grep -F 'Redaction Leakage Guard' docs/reference/customer-package-manifest.md >/dev/null + @grep -F 'reviewer_checklist' docs/reference/customer-package-manifest.md >/dev/null @grep -F 'v0.1.0-rc.5 - 2026-06-01' CHANGELOG.md >/dev/null @grep -F 'make restore-rehearsal-check' docs/runbooks/backup-restore.md >/dev/null @test -f docs/how-to/pilot-deployment-checklist.md @@ -360,6 +361,8 @@ demo-check: ## Validate checked end-to-end evidence demo fixtures @grep -F '/v1/audit-chain/verify' examples/end-to-end-release-evidence/run-local-demo.sh >/dev/null @grep -F '/v1/customer-packages' examples/end-to-end-release-evidence/run-local-demo.sh >/dev/null @grep -F 'not legal' examples/end-to-end-release-evidence/README.md >/dev/null + @grep -F 'reviewer_checklist' examples/end-to-end-release-evidence/sample-customer-package-manifest.json >/dev/null + @grep -F 'escalation_path' examples/end-to-end-release-evidence/sample-customer-package-manifest.json >/dev/null black-box-demo-check: ## Run live PostgreSQL black-box API/worker demo; requires EVYDENCE_TEST_DATABASE_URL @scripts/black_box_demo_check.sh @@ -379,8 +382,11 @@ package-viewer-check: ## Validate local package viewer and walkthrough @grep -F 'Release Summary' site/package-viewer/index.html >/dev/null @grep -F 'Vulnerability / VEX Decisions' site/package-viewer/index.html >/dev/null @grep -F 'Verification Status' site/package-viewer/index.html >/dev/null + @grep -F 'Reviewer checklist' site/package-viewer/index.html >/dev/null + @grep -F 'reviewer_checklist' site/package-viewer/index.html >/dev/null @grep -F 'examples/end-to-end-release-evidence/sample-customer-package-manifest.json' docs/how-to/view-packages.md >/dev/null @grep -F 'reviewer-journey.svg' docs/how-to/view-packages.md >/dev/null + @grep -F 'hash/signature verification' docs/how-to/view-packages.md >/dev/null @grep -F 'Release Summary' docs/assets/reviewer-journey.svg >/dev/null @grep -F 'VEX Decisions' docs/assets/reviewer-journey.svg >/dev/null @grep -F 'Evidence Contents' docs/assets/reviewer-journey.svg >/dev/null diff --git a/docs/how-to/view-packages.md b/docs/how-to/view-packages.md index c0f7904..a7f33ae 100644 --- a/docs/how-to/view-packages.md +++ b/docs/how-to/view-packages.md @@ -53,6 +53,9 @@ Use it for: - inspecting package manifests and limitations; - reviewing artifact, SBOM, vulnerability, VEX, approval, exception, readiness, contents, and verification sections; +- following the reviewer checklist for package scope, included evidence, + excluded evidence, hash/signature verification, non-claims, and escalation + path; - reading evidence-bundle metadata during an offline review; - confirming that a shared package does not contain raw evidence payload bytes or secrets. diff --git a/docs/reference/customer-package-manifest.md b/docs/reference/customer-package-manifest.md index 2bb4e5a..4c9e316 100644 --- a/docs/reference/customer-package-manifest.md +++ b/docs/reference/customer-package-manifest.md @@ -20,6 +20,7 @@ vulnerability result, or a secure-release guarantee. | `readiness_summary` | Deterministic readiness checks, gaps, and limitations. | | `customer_safe_gaps` | Optional customer-visible gap records filtered through the package redaction profile. | | `verification_material` | Hash algorithm, canonicalization profile, release bundle hashes, and audit-chain summary. | +| `reviewer_checklist` | Optional proof-path checklist covering package scope, included evidence, excluded evidence, verification, non-claims, and escalation path. | | `limitations`, `non_claims` | Required package limitations and conservative product-language boundaries. | ## Optional Sections @@ -73,6 +74,22 @@ while build-attestation or internal provenance gaps are omitted unless the profile explicitly includes `build` or `build_attestation`. Internal-only gaps remain outside the package manifest. +## Reviewer Checklist + +`reviewer_checklist` is a customer-safe proof-path summary. The checked sample +package uses it to show: + +- package scope; +- included evidence; +- excluded evidence; +- hash and signature verification; +- non-claims; +- escalation path for missing or broader evidence. + +Checklist entries are summaries only. They must not include raw payloads, +object-store paths, bearer credentials, signing material, token hashes, tenant +internal notes, or customer data outside the package scope. + ## Presets `POST /v1/redaction-profiles` accepts either an explicit `allowed_types` list or @@ -95,6 +112,8 @@ directly from disk. A non-sensitive sample is available at `examples/end-to-end-release-evidence/sample-customer-package-manifest.json`; the matching archive fixture is `examples/end-to-end-release-evidence/sample-customer-package.zip`. +The viewer renders the optional `reviewer_checklist` with text-only DOM APIs so +operator-provided package text is displayed as text, not interpreted as HTML. Runtime ZIP exports also include `report.html`, a self-contained static HTML rendering of the redacted manifest. It shows release summary, VEX and diff --git a/examples/end-to-end-release-evidence/README.md b/examples/end-to-end-release-evidence/README.md index a55afe2..e8d7b39 100644 --- a/examples/end-to-end-release-evidence/README.md +++ b/examples/end-to-end-release-evidence/README.md @@ -37,7 +37,7 @@ you use source-checkout commands for local development. - `sample-security-summary.json`: representative release security quick-check output without raw tenant payload bytes. - `sample-customer-package-manifest.json`: representative customer package - manifest without raw tenant payload bytes. + manifest with a reviewer checklist and without raw tenant payload bytes. - `sample-customer-package.zip`: downloadable fixture with `manifest.json`, `package.json`, `verification.json`, and `README.txt`. - `sample-audit-chain-verification.json`: representative audit-chain @@ -97,7 +97,8 @@ question to concrete Evydence records: - `release-security-summary.json`: the compact release security status for review surfaces. - `release-bundle.json`: the signed release bundle metadata. -- `customer-package.json`: the customer-safe package manifest. +- `customer-package.json`: the customer-safe package manifest, including the + proof-path checklist when present. - `audit-chain-verification.json`: audit-chain continuity verification. To visually inspect the customer-safe output, open diff --git a/examples/end-to-end-release-evidence/sample-customer-package-manifest.json b/examples/end-to-end-release-evidence/sample-customer-package-manifest.json index fe1c1ca..f58a554 100644 --- a/examples/end-to-end-release-evidence/sample-customer-package-manifest.json +++ b/examples/end-to-end-release-evidence/sample-customer-package-manifest.json @@ -184,6 +184,44 @@ ] } }, + "reviewer_checklist": [ + { + "id": "package_scope", + "label": "Package scope", + "status": "included", + "detail": "Scoped to product prod_example, release rel_example, redaction profile rp_example, and package csp_example." + }, + { + "id": "included_evidence", + "label": "Included evidence", + "status": "included", + "detail": "Includes artifact digest, SBOM metadata, vulnerability scan summary, OpenVEX metadata, active customer-visible decision, release bundle metadata, and audit-chain summary." + }, + { + "id": "excluded_evidence", + "label": "Excluded evidence", + "status": "documented", + "detail": "Excludes raw tenant evidence bytes, storage references, bearer credentials, signing material, API key hashes, SSO or session hashes, and internal decision notes." + }, + { + "id": "hash_signature_verification", + "label": "Hash and signature verification", + "status": "available", + "detail": "Verify the package archive or manifest hash with evydence package verify, then inspect release bundle and audit-chain verification material." + }, + { + "id": "non_claims", + "label": "Non-claims", + "status": "documented", + "detail": "The package supports technical evidence review and compliance readiness only; it is not legal compliance proof, certification, complete SBOM proof, an authoritative vulnerability result, or a secure-release guarantee." + }, + { + "id": "escalation_path", + "label": "Escalation path", + "status": "documented", + "detail": "Ask the package owner for missing release-specific evidence, a regenerated package with a broader approved redaction profile, or deployment-specific assumptions." + } + ], "limitations": [ "Package contents are scoped by product, release, redaction profile, and package expiry.", "Raw tenant evidence payload bytes, object-store payload references, bearer tokens, private keys, API key hashes, SSO/session token hashes, and internal decision notes are not included.", diff --git a/examples/end-to-end-release-evidence/sample-customer-package-manifest.sha256 b/examples/end-to-end-release-evidence/sample-customer-package-manifest.sha256 index b12608b..d70463e 100644 --- a/examples/end-to-end-release-evidence/sample-customer-package-manifest.sha256 +++ b/examples/end-to-end-release-evidence/sample-customer-package-manifest.sha256 @@ -1 +1 @@ -5079f1f386f7266a82c3d706b87db04f8c53fb4e65d53c1a6dbe3d9cb2e263e5 sample-customer-package-manifest.json +2858cdfa45ef35cc25781b50873588a6f23c6b5aa4ec3853b4575f77f60de4ac sample-customer-package-manifest.json diff --git a/examples/end-to-end-release-evidence/sample-customer-package.zip b/examples/end-to-end-release-evidence/sample-customer-package.zip index 5b337bb16c3e1bf780fd59b1916cb338d7a47cfa..00c95e860cd2acb844bce80394e7a65667bcda59 100644 GIT binary patch literal 3464 zcmZ`+XHXN`)(ydcRHci88i-VZ(2-t6q)11kgh&k_y;n7K5D^4I4+KF#1OtZNi_#)U zi1ZS=lmPeAL~lOc{eHZ6o%ha}GwaMbv;M3#d(Ga)`qUTL0RX_o^8*I(`s;0g&#$#S z007hZ%M-X4!o}G?K-}Hm+pEpm#(PGNJ&Ig&^QUJEE<+A+hGhW0yJQn5D;mf2OkJwqcZ-U(p*@B|g`3rl7PVvFwrD`2FoyxH36Eahh6^(8#-UGL{UUSN3 zF!W)K{MumkGT~^D&92yY zI||_tFY7A1+Bm&R>q6rf8FE!4TYcXr9{UG2%(vQAFD{V1?1-Z@fvP=Llh^Ok&LGjn zhYl1aC6*Z2u%;$w{Zi3eoI~R(WGH5sgYhSvCV@>mysLN2KI3d|kdL#fQq*|cMZEXk zyNX?(8SW981tv>8M9VFeM3U)1QOE_S95qdH{eAtzUi?*w(pkm>7rn8SL)J#xW;=8i zy+A|vGK7(Ar0yf(1MzVNF;2-KZRO`=^8uS~4n$1c8=S%Yhaz)qcHL-y*$)J}Y3c>q z2aU0xRQr}3jeh0qdJx@o+JBw4WrxPt2-=Khh36pm*jxHP>80iag-j(YCr=uo%Bnlk zqR;NKr)*vJO=a#kp6;&aRiMDGkeG7~iZ0Rkt>n6~PCg#0LQkqdT-WjCU4h9mzkOz!&=^VE5ACRPq!$Mn%0&&3NVm#<(7xiHpL6<k7NRB36&jQ?UbXej zv!%@*X78N6?Vi!zWN&9@*HL2AFJ3cVzp&GKuNE=J7mL0gOB)-1qRlKd5Wbk>s^!_a zxe{{?r%5EHdKOufz(aeTC$P7z(_6wSCKetGXeln2M`IBRlt_EMfdT+$CzLd3K z80Gk7>KTWwryrjx<<6!9u(O*0S9p3aFf;I)g~<1C{VWxprmRzeeztqq4n<}LCXd7Y zKC!!>>Q>&Z-G6q?_xQ{WrSg&E2~fpHo+No|JJC^kjX!KugtOja?D3~v_l^)$n%bRw z=3Oc$Q8-t)FH$17?m3Wdo-F@K$##Vj1s>bPjsI10myYIspYU)_M#?}T*&nDawV5iW zJR|iiSbO*qt(8JA{(<4mm)+$R)%dDg7S5Vgnt*QSxdvocOFauy*79GfQBXOrk~zXv z@e-TQ-HB5@_1g;J(Cxr@JIa85yFvNxN%6zD<0L9Wn(!kPGC{KyKms&Qb~D=0iZZpt z@1sK3<7QDI^+R{q%hM138dx^B9TrLA5I4DOa_{!|94(x#J`7Ln>ExBwRSj9jFkO9( z?BT`T0=J!nORT90u+;_kjewl6`KRS#Y^on7gsZltkue3!Ig^ke2Qe^ekwInjRBR-qXOcfzPWCe`)C6p(){e<{X? z;+jF`LTE$VG#&gOARGAWa;|@)?&?)1(lwnTO;O6**JT~aVl5DUF zG!b}3pF7id7kr{&q4iuxEZ=$vt+q&g@Wv$kz(nP$fA1-wxl0&`oZz)k>x- zYgSX)9&=jNc;RTVU93!ir`aAVE@LRA{a4gq1x=oR&2-{e{g?|_6%=xDTxyzaO1^Dn zH$z{sUm+)ISh0;*xjr?P-rmnPB@Y}0xAH63135$;!b<5kbv-ZT0x_L3b?}{ln{hiF z12U3}N$|9p3tm_06}^O$QtzYHlnT19tRxN|af(f>nw!%wNf8vdzIjjdJhfOe$@6?= zjywH>$NHw@#q!4ggJ!t?4GbvV|w(~qTgJ`DfkI9riGI@WBuAJ0xD^McB-lksAv1vYQ+|)+)*D0PP<{7Y}q-!Mn9zP&MbgEE1B1i_Z(t7wJdzhIif&_ zXKw+I8ZmPx1S)IIJQO-tK|YUqfBGv?5kh~u__C#|<_3)WeOJmc#gzc8YZwdQi9ZiH7+NC!U-H_dskwT%&(hp zR*>@F@{a|;da`qRF!G#UJ*#7dc!obe<%Ave9dcZsJruKSTFz_gJgtO(8;GXeUKWe*HLYrNg*i zXF`Jeax04o5g`!~FFURSu*{BD7?o3p#;rQn&yVA0ewk&Jzn5);J1yJ2CI$=Z?fZ`w zv|55enqNH&Qk+#+z6RVz4%wQX#&_INdmZdZ{=J$Zz$W)D+ zOm_^Si=HZSXqPe+l8>9^=`U-673c+NFk3z%i>sNYHB4|s$4SBz_>rA;#Eu*3JDtiT zyEW>~tI-=(d%zvvMQe@J3&umLt5Wma$lI;Mh}JZLZg7b8_*cErX@-{?UF&G!T0|@) zGz(?}G3|&7jePY@o9Y2D@9x%0jTCW@(FBtrxcJ#_5RTXIWN@OxZ1AhZfduqYNO_)n zj(X*~u8)#z8~RO?cI`tVUd}sH98E`~mm}|17gm11_b~lELBqRtHnaZD+wY^>gZDq? zsy?C1RNa-EDVruw1o@la8hEf1m?$6g*fY)70*Y20ilba?v~V9UZBNxQypg>B4X1$p zVUb+NFf_9PL7ql2Fi_q8%$)@EJ`NtK8O8L@n+fgKMdxaWm$emY4t{AI4}14`fgG>) zPtz}5R_yxo-0X;Rb3%c!3-Ry0Lh|0t)+F>^62p(C_># zn)gBz#J39RsL4mSvnEe1wTmCKTvhL1*9XSB7k&{6Sn?s!v9GRubl7MnTc<=F-C)Nm zCSOGm3p5OEvtB^4(tWl_YJF}X%^8n*~bkO1Af25J6yg|KidhVLJ_YaQQprj%`)8iq1>7?-d1Uy zG`S*Nmb(6@=LJCpWT*b$bI7?sf3MPWwSJpQey9E(JO57v07|J0&IgFx~w>94Uqh~{5^7tZ(gImZ1f90C6aDYHaK literal 3032 zcmZ`*XD}S<8s0^$#p)$WI666cZ;@yl(N|fbL|rw=!K#~(ST%?m(W69JHj8M{S&QhM zSR^D$v`xd&uY2x~b5G{p@0)L)nRn)y`Q~}%eV^CVfSiH_002;3K0d&+NefIeB>*tQ z3IISZD?U!Xo^FVMKuNCvKVPi1fge$sp<}~}L8Cu;xAaaQLOHh#@1MS3NoW4 zLB+HRAu$o-)Qb-7gi_HX#zP=Q9D#!__5(_e`#TZL$4sEE@TjA#Y_1Sda_zBsrF+F6 z6WNfqJyKt^^LSm_R?7Xydz8P|`rBIG!U1!&+X`Uy35-|~Gl^r??vqIdY7-jokf>)J z5F$8wzdTetV{ZKhS`?RBFJ5rx*708Hov=}xYt0N5ha+;iYI9Xs1!~J$ z6o!mNr%*R)h6S&B9IUR&JM3J9H=U(f*%3zwx!H@*R$<>aX#L;X+z`21`a1T$RFDzX4w;)-@l*lm1KpYxkPd&W5TnezB07-?Fojr-Ac%~#hSQ8SgCEoS!*SU zak?#s@7U4VL~;ndrE`Aa&1_#sGK7 zmMq^p<%}pZ>6He`yHm27IVBrWo)*E;OF)1bb+8 zq(0|Ro*31_VR_5(wcH^t=!bjuQfvlL_A1Lk(XbA6hw9M}lWU=al4fDZhv2(G?aj^3 z><=33+S>~p?Cm>?IJyY?UNg8LJK;b?t@dDK3pbSCk1>L zdE&?gPvD%48^Qpe(^3-<=qDAN(>P?0j`tYh>6*!{`h3R|p!NzZ5>oe*s%w}ckY7Xm z%ye8cVf`gDI2%FIek5@9CJ}a&)ZU1xSVUviUaoN7wOid(SM{PPV2|lJ*V`57-OiW` zy%j3+ycfyu%Sm=`xhH5_x^Kzj;@e@YCwt8iN@W_tcW7Hag3tDN3CEyyVX>$y4umYV)cX4CbT-!gNU)zVT$|8$3H%23ANFmodc58UWh8t zO|@0A$LjYpK311C>JZT_9&M%3W=j_OOFF4G zKN0)K9HSaduUr6IEq1$svhm!@|Bm@@Hi>2K^UoZ|lBOlVd-OQd9wpn-QN z5mqZ|ya&AVSawh*b7*Ubz>`i51Hrw!o4Qu;A!ro&q?-N@}jn*K21VJ zZGo}kVqOi z4!s|JGHyn6+%SJJ*{7){pqH3+UaWr_Z@iN<$xIz0q9-vh?t4lJSo8X3zviHYJ6aPP`gcNK$7rhJ;2fs9F=$DEH1F{)CH zKf9OrD^LxYQaG2^Xt%YIGx*3o7uB88Yv%#i=FeI-lN-$?!d?qoE4gDYxbr&?Yf_^) zvEO(ny0(&VaUzW7h9?DuCT$XcL z*hK%OM#p3T0OO@jK?r|OH%}L*Kup!Oo%@Cx2HJuhLuc$4VYg z7Fg>r#+`xZCoS2;XV&h>H#8MRx!GpGYwzNyxRYgzBKa1;*&p@Zw2gaHEvbn~GJ{f? z-kA=|DIFJS_SU{sdj#{mz{`h5-Q)o(a!wSVr3Ef=KI#WIC-JaO_oAquU_O zs^8Svt~f*%56n{CIjC-~*DHN=a(v8>i|6N|P)r&f@^jB$<4DtzGU-Y^$-~=4&a=H^ z6rQ;4l}KZlc9o#?{^Lg4D7alAqgi1Vmb?cKL78;pG+g}0FIFE4x6kfBy09?EZY2!t zVBC_7>~~w-h+m*nzO8tu4`#~~XZWU4(OWmO(vw)>+tgXdTmtQDeFB_;DV~~iHB8#% zpInDXJQVM9SXdoc!olMv~qo&V8+B*#%z2X!)U?zN5JjuHD*?D-4 z#sASP?_U4)gR{^-Y5wW@7l;99?$T|eOXsOC(M(rU$4FN)FeFenMaCa5O-m8pPDWpI z_LODMtW+PAdYg;!iWilhVuasdjv%WWT|l@p>b`^)`9R1$S<&is1XM`dx+ ziYgeXMgJ8&mw@?r=!4z4u{)evCl1vcCJyQc984LOU z-)k>5`0JEj3i8XA`z!U=$?_i}08k2id$}n8_ni5a`D?HJ&0GQfkIws*{;O$!)91kd XZK0{bmCKI+02G&Z=MrcC?J(e9LpWL2 diff --git a/internal/app/customer_package_golden_test.go b/internal/app/customer_package_golden_test.go index ebfcffb..9bc4f0b 100644 --- a/internal/app/customer_package_golden_test.go +++ b/internal/app/customer_package_golden_test.go @@ -39,6 +39,7 @@ func TestSampleCustomerPackageManifestGolden(t *testing.T) { "redaction_profile", "readiness_summary", "verification_material", + "reviewer_checklist", "limitations", "non_claims", } { @@ -49,4 +50,22 @@ func TestSampleCustomerPackageManifestGolden(t *testing.T) { if manifest["schema_version"] != domain.CustomerPackageSchemaVersion || manifest["package_version"] != domain.CustomerPackageSchemaVersion { t.Fatalf("manifest fixture schema version = schema:%v package:%v want %s", manifest["schema_version"], manifest["package_version"], domain.CustomerPackageSchemaVersion) } + checklist, ok := manifest["reviewer_checklist"].([]any) + if !ok || len(checklist) < 6 { + t.Fatalf("manifest fixture reviewer checklist missing expected proof-path entries: %#v", manifest["reviewer_checklist"]) + } + seen := map[string]bool{} + for _, item := range checklist { + entry, ok := item.(map[string]any) + if !ok { + t.Fatalf("manifest fixture reviewer checklist entry is not an object: %#v", item) + } + id, _ := entry["id"].(string) + seen[id] = true + } + for _, id := range []string{"package_scope", "included_evidence", "excluded_evidence", "hash_signature_verification", "non_claims", "escalation_path"} { + if !seen[id] { + t.Fatalf("manifest fixture reviewer checklist missing %q: %#v", id, checklist) + } + } } diff --git a/site/package-viewer/index.html b/site/package-viewer/index.html index 835b221..7a0054d 100644 --- a/site/package-viewer/index.html +++ b/site/package-viewer/index.html @@ -380,6 +380,14 @@

Evydence Package Viewer

release_bundles: [{ id: "rb_example", state: "generated", manifest_hash: "sha256:example", signature_refs: ["sig_example"] }], audit_chain: { result: "passed", latest_sequence: 12, head_hash: "sha256:example" } }, + reviewer_checklist: [ + { id: "package_scope", label: "Package scope", status: "included", detail: "Scoped to product prod_example, release rel_example, redaction profile rp_example, and package csp_example." }, + { id: "included_evidence", label: "Included evidence", status: "included", detail: "Includes artifact digest, SBOM metadata, vulnerability scan summary, OpenVEX metadata, active customer-visible decision, release bundle metadata, and audit-chain summary." }, + { id: "excluded_evidence", label: "Excluded evidence", status: "documented", detail: "Excludes raw tenant evidence bytes, storage references, bearer credentials, signing material, API key hashes, SSO or session hashes, and internal decision notes." }, + { id: "hash_signature_verification", label: "Hash and signature verification", status: "available", detail: "Verify the package archive or manifest hash with evydence package verify, then inspect release bundle and audit-chain verification material." }, + { id: "non_claims", label: "Non-claims", status: "documented", detail: "The package supports technical evidence review and compliance readiness only; it is not legal compliance proof, certification, complete SBOM proof, an authoritative vulnerability result, or a secure-release guarantee." }, + { id: "escalation_path", label: "Escalation path", status: "documented", detail: "Ask the package owner for missing release-specific evidence, a regenerated package with a broader approved redaction profile, or deployment-specific assumptions." } + ], limitations: [ "Package contents are scoped by product, release, redaction profile, and package expiry.", "Raw tenant evidence payload bytes, object-store payload references, bearer tokens, private keys, API key hashes, SSO/session token hashes, and internal decision notes are not included.", @@ -672,6 +680,12 @@

Evydence Package Viewer

? "Customer-safe view: internal-only payloads, object references, and internal notes are not shown unless explicitly included by the package profile." : "Security-review view: broader technical metadata may be present, but raw payloads and secrets remain excluded by package policy."; nodes.contents.append(boundary); + appendText(nodes.contents, "h3", "", "Reviewer checklist"); + table(nodes.contents, [ + { label: "Check", value: (row) => row.label || row.id }, + { label: "Status", value: "status", badge: true }, + { label: "Detail", value: "detail" } + ], data.reviewer_checklist, "No reviewer checklist is present."); }; const renderVerification = (data) => { From 38b6fee78c82143a88e381066d65cbbb7a6b5d09 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 16:24:20 +0300 Subject: [PATCH 221/287] docs(risk): define vulnerability decision taxonomy --- .productization_next_steps_missing.md | 4 +- docs/reference/vulnerability-decisions.md | 45 +++++++++++++++++------ 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index 7b2777e..c78089e 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -151,7 +151,7 @@ External reason: - These are GitHub account/repository security settings, not source files. -## Epic E2 - Make The First Ten Minutes Reviewer-Obvious [ ] +## Epic E2 - Make The First Ten Minutes Reviewer-Obvious [x] Description: Convert the already implemented VEX-first flow into an evaluation path a skeptical product-security buyer or customer reviewer understands without @@ -221,7 +221,7 @@ Description: Close the documented decision-model gaps so vulnerability decisions become a durable customer-review object, not only an operational API record. -### Ticket E3-T1 - Decide and document risk-status taxonomy [ ] +### Ticket E3-T1 - Decide and document risk-status taxonomy [x] Description: Decide whether `accepted_risk`, `false_positive`, and `will_not_fix` belong as vulnerability decision statuses, exceptions, waivers, diff --git a/docs/reference/vulnerability-decisions.md b/docs/reference/vulnerability-decisions.md index e399356..a8d455f 100644 --- a/docs/reference/vulnerability-decisions.md +++ b/docs/reference/vulnerability-decisions.md @@ -59,9 +59,29 @@ decision, appends `vulnerability_decision.superseded` for the prior decision, and appends `vulnerability_decision.created` for the replacement. The current transition table permits any canonical status to be superseded by any canonical status because VEX imports and manual corrections may revise earlier analysis. -Unknown statuses are rejected. Additional statuses such as `accepted_risk`, -`false_positive`, and `will_not_fix` are not accepted until a later API version -decides whether they belong in decisions or in exceptions/waivers. +Unknown statuses are rejected. Evydence intentionally does not add +`accepted_risk`, `false_positive`, or `will_not_fix` as decision statuses in the +current API version. Decision status answers the technical VEX question for the +release artifact. Business acceptance, policy exceptions, and control waivers +are represented by exception or waiver records with owner, reason, approval, +scope, expiry, and audit-chain entries. + +## Risk Outcome Taxonomy + +Use these mappings when turning scanner triage into Evydence records: + +| Reviewer phrase | Evydence representation | +| --- | --- | +| Accepted risk | Keep the decision `affected` or `under_investigation` as appropriate, then attach an approved, unexpired exception scoped to the release, finding, policy, or control. | +| Will not fix | Use a waiver or exception with owner, reason, scope, expiry, and approval. Do not turn it into `fixed` or `not_affected`. | +| False positive | Use `not_affected` only when the recorded technical analysis says the finding does not apply to this release artifact or component. Put scanner disagreement and supporting context in customer-safe impact/action text or supporting evidence. | +| Remediated in this release | Use `fixed` with release-specific impact/action text and supporting evidence. | +| Still investigating | Use `under_investigation`; readiness continues to show unresolved risk unless an approved exception applies. | + +This split keeps customer-facing wording precise: vulnerability decisions record +technical applicability/remediation, while exceptions and waivers record risk +acceptance and policy overrides. It also keeps expiry semantics on the risk +acceptance object instead of silently expiring historical technical decisions. Customer package manifests include only active decisions unless a future history-specific export is requested. @@ -144,7 +164,8 @@ yet the full buyer-facing VEX decision workflow: PDF, and package-specific rendering remain handled by package/report resources. - There is no review date or expiry on a decision. Expiry behavior currently - lives on exceptions and waivers, not decisions. + lives on exceptions and waivers, not decisions, and reports should state this + freshness assumption. - Supporting evidence links currently reference evidence-item records. Links to first-class non-evidence resources such as remediation tasks, approvals, exceptions, release bundles, or incident packages still need explicit link @@ -156,14 +177,16 @@ yet the full buyer-facing VEX decision workflow: The productization backlog should add these changes in order: -1. Decide whether `accepted_risk`, `false_positive`, and `will_not_fix` should - be separate statuses or represented by exceptions/waivers. -2. Add first-class decision links for non-evidence resources that should not be +1. Add decision freshness semantics or package/report limitations that make the + lack of review dates explicit. +2. Add first-class SBOM/component context links for decisions so reviewers do + not need to infer source component evidence through release/artifact + relationships. +3. Add first-class decision links for non-evidence resources that should not be wrapped as evidence items. -3. Add a decision history endpoint with filters for product, release, - vulnerability, component, status, and active/superseded state. -4. Add a customer-safe release decision summary endpoint for package viewer and - export use. +4. Add package-specific customer decision exports that include active + decisions, supporting links, assumptions, and limitations in one + customer-safe view. These follow-ups should update OpenAPI, HTTP tests, package export tests, and docs together. From 8dcd7e9495b51820f74343fc6ced500d701d2e0b Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 16:31:54 +0300 Subject: [PATCH 222/287] feat(risk): add decision freshness metadata --- .productization_next_steps_missing.md | 2 +- Makefile | 1 + docs/reference/customer-package-manifest.md | 4 +- docs/reference/vulnerability-decisions.md | 29 +++++-- .../sample-customer-package-manifest.json | 2 + .../sample-customer-package-manifest.sha256 | 2 +- .../sample-customer-package.zip | Bin 3464 -> 3500 bytes internal/adapters/httpapi/openapi.go | 6 ++ internal/adapters/httpapi/router.go | 20 +++-- internal/adapters/httpapi/router_test.go | 9 +- internal/adapters/postgres/store.go | 15 ++-- internal/app/governance_packages.go | 10 ++- internal/app/ledger_test.go | 24 ++++++ internal/app/vex.go | 55 +++++++++++- internal/domain/domain.go | 78 +++++++++--------- ...lnerability_decision_review_times.down.sql | 5 ++ ...vulnerability_decision_review_times.up.sql | 5 ++ openapi.yaml | 2 +- site/package-viewer/index.html | 4 +- 19 files changed, 204 insertions(+), 69 deletions(-) create mode 100644 migrations/20260601000600_vulnerability_decision_review_times.down.sql create mode 100644 migrations/20260601000600_vulnerability_decision_review_times.up.sql diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index c78089e..7fc21e1 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -235,7 +235,7 @@ Implementation rules: - If deferred, explicitly state how exceptions/waivers represent those cases. - Run targeted app/API tests and `make openapi-check` if schemas change. -### Ticket E3-T2 - Add decision review date or explicit freshness semantics [ ] +### Ticket E3-T2 - Add decision review date or explicit freshness semantics [x] Description: Address the current gap that customer-visible decisions have no review date or expiry. diff --git a/Makefile b/Makefile index b1fed4a..65473be 100644 --- a/Makefile +++ b/Makefile @@ -384,6 +384,7 @@ package-viewer-check: ## Validate local package viewer and walkthrough @grep -F 'Verification Status' site/package-viewer/index.html >/dev/null @grep -F 'Reviewer checklist' site/package-viewer/index.html >/dev/null @grep -F 'reviewer_checklist' site/package-viewer/index.html >/dev/null + @grep -F 'review_due_at' site/package-viewer/index.html >/dev/null @grep -F 'examples/end-to-end-release-evidence/sample-customer-package-manifest.json' docs/how-to/view-packages.md >/dev/null @grep -F 'reviewer-journey.svg' docs/how-to/view-packages.md >/dev/null @grep -F 'hash/signature verification' docs/how-to/view-packages.md >/dev/null diff --git a/docs/reference/customer-package-manifest.md b/docs/reference/customer-package-manifest.md index 4c9e316..3efae7d 100644 --- a/docs/reference/customer-package-manifest.md +++ b/docs/reference/customer-package-manifest.md @@ -31,7 +31,9 @@ matching release-scoped records exist: - `sboms`: SBOM metadata such as format, spec version, component count, and evidence ID. - `vulnerability_scans`: scanner metadata, target reference, summary counts, and finding count. - `vex_documents`: VEX metadata, statement counts, status summary, and evidence ID. -- `vulnerability_decisions`: active customer-visible decision summaries only. +- `vulnerability_decisions`: active customer-visible decision summaries only, + including `reviewed_at` and optional `review_due_at` freshness metadata when + recorded. - `api_contracts`: OpenAPI contract metadata, normalized operation summaries, deterministic contract diff results, and API-contract limitations. - `approvals`: release or product approval records. diff --git a/docs/reference/vulnerability-decisions.md b/docs/reference/vulnerability-decisions.md index a8d455f..2b2d357 100644 --- a/docs/reference/vulnerability-decisions.md +++ b/docs/reference/vulnerability-decisions.md @@ -33,6 +33,7 @@ finding: | Customer-safe impact/action text | `impact_statement` and `action_statement` exist. `impact_statement` is required when `customer_visible` is true. | | Customer visibility | `customer_visible` marks decisions eligible for customer-safe package summaries. | | Internal notes | `internal_notes` stores tenant-internal context separately from customer-safe impact text. | +| Review freshness | `reviewed_at` records when the decision was reviewed; `review_due_at` optionally records the next expected review time. | | Approver/actor | `approved_by` stores the actor id for API/OpenVEX-created decisions. | | Supersession | Creating a new decision for the same finding marks the prior active decision with `superseded_by` and sets `supersedes` on the new decision. | | Source VEX/import | `vex_document_id` and `evidence_id` link imported decisions to the VEX document and evidence item. Manual decisions may also set `vex_document_id` to link a same-release imported VEX document without changing the manual source. | @@ -83,6 +84,20 @@ technical applicability/remediation, while exceptions and waivers record risk acceptance and policy overrides. It also keeps expiry semantics on the risk acceptance object instead of silently expiring historical technical decisions. +## Decision Freshness + +New manual decisions may include `reviewed_at` and `review_due_at`. When +`reviewed_at` is omitted, Evydence records the decision creation time as the +review time. `review_due_at` is optional; when it is present, it must be after +`reviewed_at`. + +Freshness metadata is append-only with the decision version. To correct a stale +or inaccurate date, create a superseding decision with the corrected freshness +metadata rather than editing the existing version. Customer-safe decision +summaries and customer packages include `reviewed_at` and `review_due_at` when +available. Reports state the limitation that these dates are tenant-supplied +metadata and do not prove the vulnerability analysis is still correct. + Customer package manifests include only active decisions unless a future history-specific export is requested. @@ -163,9 +178,9 @@ yet the full buyer-facing VEX decision workflow: - The dedicated customer-safe summary endpoint is release-scoped JSON. HTML, PDF, and package-specific rendering remain handled by package/report resources. -- There is no review date or expiry on a decision. Expiry behavior currently - lives on exceptions and waivers, not decisions, and reports should state this - freshness assumption. +- Decisions now have append-only `reviewed_at` and optional `review_due_at` + metadata. Expiry behavior still lives on exceptions and waivers, not + decisions. - Supporting evidence links currently reference evidence-item records. Links to first-class non-evidence resources such as remediation tasks, approvals, exceptions, release bundles, or incident packages still need explicit link @@ -177,14 +192,12 @@ yet the full buyer-facing VEX decision workflow: The productization backlog should add these changes in order: -1. Add decision freshness semantics or package/report limitations that make the - lack of review dates explicit. -2. Add first-class SBOM/component context links for decisions so reviewers do +1. Add first-class SBOM/component context links for decisions so reviewers do not need to infer source component evidence through release/artifact relationships. -3. Add first-class decision links for non-evidence resources that should not be +2. Add first-class decision links for non-evidence resources that should not be wrapped as evidence items. -4. Add package-specific customer decision exports that include active +3. Add package-specific customer decision exports that include active decisions, supporting links, assumptions, and limitations in one customer-safe view. diff --git a/examples/end-to-end-release-evidence/sample-customer-package-manifest.json b/examples/end-to-end-release-evidence/sample-customer-package-manifest.json index f58a554..48cb1e1 100644 --- a/examples/end-to-end-release-evidence/sample-customer-package-manifest.json +++ b/examples/end-to-end-release-evidence/sample-customer-package-manifest.json @@ -137,6 +137,8 @@ "source": "vex", "evidence_id": "ev_vex", "vex_document_id": "vex_example", + "reviewed_at": "2026-05-27T12:00:00Z", + "review_due_at": "2026-08-25T12:00:00Z", "created_at": "2026-05-27T12:00:00Z" } ], diff --git a/examples/end-to-end-release-evidence/sample-customer-package-manifest.sha256 b/examples/end-to-end-release-evidence/sample-customer-package-manifest.sha256 index d70463e..abfc9b6 100644 --- a/examples/end-to-end-release-evidence/sample-customer-package-manifest.sha256 +++ b/examples/end-to-end-release-evidence/sample-customer-package-manifest.sha256 @@ -1 +1 @@ -2858cdfa45ef35cc25781b50873588a6f23c6b5aa4ec3853b4575f77f60de4ac sample-customer-package-manifest.json +8910d32bc08b85b7a1da5945520851a7c45b6d0d6835dd1ceb7a65c4b9f47e72 sample-customer-package-manifest.json diff --git a/examples/end-to-end-release-evidence/sample-customer-package.zip b/examples/end-to-end-release-evidence/sample-customer-package.zip index 00c95e860cd2acb844bce80394e7a65667bcda59..15a7cf3a46e1995d92f6d30da384db1ccb231efa 100644 GIT binary patch delta 3132 zcmY*b2{hCT7au!gEDff~XlyaE)TALMWR1u!o;OI=@R}I=)}OJHEc1x$S<8rIiL5aq z#uiVOnQVEsgfOz?>-*k$-}k+H&pp3;&OP_s-#Pc*bAIs%G6HU9#KI~F0)aSxhB(NZ z_l?)(pDE;Q8e9z4)Id`9IIQJnCiCH9mE>Z1A~kQ+4WyY!0NVo+=!4-v>{3Ejxzt zW9pFWfIA8xZYJ3p^rkBx35>%ajkzvOsWHUJYXcx3;@yi`DpOvBcARaG(=C6gMB0Gv z!|o@myp4GycHd}@pY0T*mt-!Od`tR%LeIXv^~B5B?ze$;<=Q7I&RiJ}H>Inai9))V z@q9Bq`QZ|`CoroIfh8GFmkD`y)4D&N+Tv`p#L=O^3j;}veEl7Zw-%H6%L)*zjerp? zMtw7UGa47PZYiR%G*+25G+Y0*e{FQbOutBU`9~!UlaNJ0&9p>wO3%BP zxh;T&y!E4>$dUzU5R6Dd&S8^)X#y#^s+{zSEjUiQEw4S6On%iWy z`-u+r?QS{L-PLW`b{Ctqb?WZ+>gs_I4IL1i=X#9)Q;%qz1Ut{VE2Ac(){P>h-k<|4 zLuv>o7L#(+OwFmRzE z)VOQ3e$Quun?&ezQ%3pN&KBP7^OK$IsbLg_$q{}KB)%<#*xOq+@!9rkbt%=nCXTpT zc{aApNW_HS_@dsOL%iau8LX7q9V`Lhg_#{5#B}{}=iyaP;ABhsB`@y6gbr<%a36b5 z)FClb$?(=EJ9+D(#Gu17sqYlL))9u`rIVYeLPMBqf8ieG*#AUnz{%7@e0xx38D4I- z0x{&VI0leJ&d-hIu$}PjEBFI#=YX~B*kAteLBC+HH7O;zV1`XcH)?>2jy`Bg zaW(41wj*>xG;sKJRD$*bhI+3}B?CL?y_kJx+f@79YD*P@IBR;>VZSG%SwlOBbij+Q z*lyMfVLK__qh+4rU{~&OQ>^Q0kPMLH9~#i>R-X3a`QxBoK}rEW;)DrjIp*A%(WE6t zgnP$8+a?n;t)7xpeb-g5)&TSI#-`onw2kkTxRPAhSwzKc)S8Xu>PhY}nn}!k6+Na| z()`|nC@Zu(hReJr(zN}Zy^myB+m7Ys<~fX5NWvYZxX;>BGnf-+Hy9)6P*1rj*3~(D z_hC{E>QQq35G+c$uB0jvb~S+Sh|(23BR}is{Z0(Q_2#3Icvuq-KnUJ;v~E|W^GV`& zxf4tp^Y$KV8lpMnOzsTkF5cXGi9u;vkPL0-vvavy0H+Pr*GP$g2cBS6VGUzifCJ5< z-q_<7SThL6sB+u9a8Ea?w5@$j^kFi>?@E2F(FVI>nCBjPf+<%WzSrD^p!9LDW*fJP zMr(`Ewb?Oe)+YhR2TSfPXgtfTQz+&)BQjuuafxj;9>F2l~R;TsN*ZXx>CaUB#P_Eo(Qs(wGF{hvE@@!|w zO*+h}^0M_L3UVT&n9BIv+uplVOZ0e8UF1`F))6vGhXV#j&1gP0iRVvMmN$yKNAh;A zFjR|-IfJ3COHJN>3VprTf$lN)IIgRo4&zF7^1l7%&s||ApU`@1urKZ_9)R#!`6@2+ zaw?zc9*ufgR@*^Nnkk5oO zEV)TQR8=e-DkWp@;b87i$z}F{=%ftG@6UVFOBk=ON);}M{8n{7Lp^zhMdR1ei6Du? z>mY1&V04^yp_A0j6f5!Lc&e7AqhOYsGC7a8yQcL)wlurlB?uv>!&pb_or2z^IoA&0 zUTz7GQZt{VKP?TpDwLrW1yLHL?BaIOjv2vd6yjXQy&r1&P#1^vD+o4hFS{dwsj7=Y{q8@T}5no?P9A(Oh$5A#g;5Z{lPUqMO(zj!JJ zw(cbK52&ER&lG>TFQR-a?ptV3jrMGjtjcq6drh6D6-Z&`1Ru5WI?1(K$uuN+lXS0F*L(x{;D&Aq{q?GU#!P`0 z{Q9Uwkd@MY1z6HhCgldw(#O<8uNPZA(%&=Zs|cgTEL@UgoIO~0I2E>1CR{LVdKO9G ziyB!DqY=HXysg*tbvQ32bz0u?{0HJ{*$7db!ybU1=R73^D|BUf__*YEqEM5;B{^aH z)SHrvD`^^&=G4&%{qK9t4LB>Y)-!P-yLBs@=f3O|tntrOC(*_OYAMK7wkq7KJz#J! zMSbdHQEt_i=oafX4>C(0BhIDDI0~8P0cIltt}=>37v9*npH-MMwY%$cX&;$?$9z*L zj78v|Vk*^61KUfA=RyL;_ova2R)!6~#TO#$9jdM0p&irVF;~j!z0i zg7f=)nIE!h?8~N^X8QJjkIp~Z>Z;Iq0|TWptVcd^f0E`a=#OPdkv&X3%IFpn$> zbw-f5D~j^6EVvZ<;yFbgDHcVGPYEb?rb!1EP4G_zTG&bPN=T&_WqIJ=!^t-Iv68Pk z?SZUZhn;=yBC-6gJksOAIrVgZJ3WrCWx#(ciW7GbxO2!+MrYZ0FUp%%6a2o3kvOyPO9pA?mu-eImR{Gv9y<;l+YU^=> z3W4Euad1%ne(_^S*|fp{D_Rm&A=^U#B-L)13=K7X*-ZW6%FzV(RgK9l*o`}UnHUZr ze=z@Z!IY28msyxVpeLkAZdK+tQKS}b{B6GVc(I13PLWjbE9n%>ucrDKakKjRjmye% z4c1aK$W@)j!1P^(^5|!MaWfll*EAld`>vla+?S?ZWAPrI=s%nW%1$*MO5+kBVR`s9{!9L66Zr3rpIE{KaDzY=dRn^1dKdhH{LGBl*#BK-{pssJ J@%euy{0rK0zbya& delta 3078 zcmZ8jXHXLg5>A4Elpu&SDH@1W>Ag!)1Oe%Ylz{XiReFgUx=4#a=z$2}0V&dXN0*o5-psw5cRRDQyYuajZ)W$K`QCFUa&wwIpt^Jo003ORNC<#8NPi7- z(PDWrIB&AI;E@WRXLSsq_g8G=<;CK`FYf5$x-yLU;dPnga#PZkjUH}(y|*{su*)ME zy6cPs+h91kNHn$WwnG1SpnU$4n&RP((EiMT=~F_H$E?*ravG!ehsB5KGn1xdMS;vM zrAVl+O|?BXUcbtw$mBIrp?Ywm``7rBpx}nNR{NTT`5j;TiD8;xjZW)HzI(JJ1iIwF zk)o;!XNiRkXlt|M7Kt8G%~>Fycu6{t><%{J-1>{nOSZ)2=$zC~x* z1v2s~_cWG|)_W|nFEPd-&MqCItM+ooqSqEqVDpTPe~ULXcqBT@YEM81$$uo;PgBj) zK5UHps?ojZYN8>g1FDYV@QACe$%Ja=-|KI(hH2Z5Y#gE=`$@$Wu|py4xbrHyK^Z@(KaOrZsqZ$ zsweUsx(Gm~0MF$19Irzym8;_}B{PzdDRocRI6gk2}a>uGS ze)zPsIlvrTb2hz@pPL-)?d{u3ZF?kY$8hsot@p8>Bm8k_zBt;rgkxPMnO=D0Law`x z&zJS(SZ=)b#6+r3v1O@Kc$e#V-EA&t@(&jJQeUn15q&`wa}G&G7;wbtIWH|^tUFL4 zaa0!2N#~!~_~^6*O?6EiWeg==I*FTkS1+1o2k(Xry7cmTFEmc-s5w zs>tR8uN}zTa;pfaZ{s6$h!q|%#=N^P#)D^ao-sW;OH*Xnz>a>THjXr_Xnjx3}j9rQIv#;C`h*eD50U$(cZOg28 zHNEDuQk0~y(hA5Dc|7k&+ZSPO5(4-s2XE{|?Nf;7P$D~K-F8h6y-M@T>e41c?9J|= z6|U@R;Q-3{`_v0Ko1RY~zXnBl-4XPKKy*@iem^)XnA=kHSLB0ib)Kf|6Tu$V`*rOq zOblS}gS~F?dtd99->(?F;0`!C^FXP8VtWcw_g5rK-`Y%amR%8u7#3y6S&lsUy6x2- zhDz5|E@0XQx`;V(L-aJFpQZQcXbieV26B-py+u1g zAYGaDRB<(u%!^Rnfh)AuN?k(_jc%q9-c{BNRo}97)vneC5L{;)5FITz7I5~`pBgbz z3cjVY#Oo5Jw%-UzQ=Pa?rAVpG-~@Y0?}N{V@3xOi9>pIe1C3}R57l>w+N}UGpmCDG zXiF;wZb^Xep~6?=XHa3de&uWLGWY-NU9zwn5KU&2Fl9Eqe|v0})`<=mF*MQng;!or zBWwu+zWxT$$&0@QX*-UTT+tL{tq<)Uq;{z*IC&?|s_}7Lq3Z?~&JxPf75Df?>f}wIqibJEdm4lM6=k3Aw&A zws7Zs>3hjgIKG+MLfE5g?)S=aXJ~_Fyk40ymxce!*MIb*(R+wyxtU7!G)zPbfpc)l2eL0%t!uIo19^j{t zu$%K@(@fK=+t&6Z`pUgZ1u>(_P0wY%sgcajJ*-oTpkYX>fEo_OCgvDXM!&A-b0rUi z`65^EwDs&}{1#iUob*DnQ#$FA?{#_=Uy@7x$u>RZU6TCj5l1&LBb9a#S_^T@? zrSrgF_SOyMl6I+)Yn4UPM6op@E}ZXcPPFTWNi(vSmIq!2*S;ez6@5^b1TF8Tn(0}= ziq8YRP#=jd+Y#%mIk^GGr!x0Q^AMjZrq!ce$G9&#mi`uOG1Q(fDgcigF|)@+ppAAu z3Z18g6PT$pp?p~B^S_KFG zqOQr&$I{c)fsHH=X8RvbC-;30Tlpg;L^D*2Ihi_=$ac2N8JlduXUbklE~pR~c?Rpu z$?e1_vio-a94Q)N_}ACm2>4<50UO`Ufw)!EQhw8ylPael1F_zZTu(CYuDXT;Sj&iU zP(u-j$TJ(FNY*L;q!>0^C$FM;K&B=WA!w-QuH9OGbm(w}T>U93<|#?si`{R#!E0Zl zyc>x-hku}MfpKh2gp8t>ykdjRCuCL^ezzfB^SEGp;JWJl+%T3jWzlj}5#=|I%+*e& zQLT*}Z`<1{EuP3;5R$-hg69zKj~dUWqpALBnxG-n z-9eTx*hMKdOu*peB^j-?xm^$ek*akQtZXE;;G?d9b}L6A__)v5U&JDaTo zo~`ME1W1_8*r@*SG((zJ$0}L`>lp_P&xYAT&Dvwa;n5jCbb${+`S&)KYh@;O8BH-r zp@nbueNIDKJ`65&m^A_QcxplY6mq`LuCx9-J@?1Sb`3pd$=eQLQE79o6lb$x_)_$} znxd*-_a9|`AZqzxXR>h06~Bfz`wTwiX*{LN(%4oYl~3=ChXh&N>V3EsoTM1?#3wz# zQVOln?+{P9+-T`FR`xkn$LPkZy&rg`x>L(n^$h)_H7MdFhJgWi`x{p>$nPk0uyz>J zHD@loT@TOGk|=L0((e1-I2Q5#$^1@&=0DGSg;}NJUl$69LS{24gI-M`M;Lrf)Okll zwZb<+IKo>4WNW&vHBbJRdF6bL*} z<_L)S{h3%M9Q6ho#idR1Ll!ae(ErbUBfA)-x&L2+7aabIGN2)n8GM8L rufMyH=P3vPVEHe2QOkhANCPmG`)}eGJM{m+y^u*@UYhv-=o;{ElnuT> diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index ee0a9c9..b40b224 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -301,6 +301,8 @@ func registerCriticalSchemas(registry *specs.Registry) { "internal_notes": map[string]any{"type": "string", "description": "Tenant-internal notes; excluded from customer-safe package summaries."}, "evidence_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, "vex_document_id": map[string]any{"type": "string", "description": "Optional tenant-scoped VEX document from the same release to link to this manual decision."}, + "reviewed_at": map[string]any{"type": "string", "format": "date-time", "description": "Optional UTC time when the decision was reviewed. Defaults to creation time."}, + "review_due_at": map[string]any{"type": "string", "format": "date-time", "description": "Optional UTC time when this decision should be reviewed again."}, }, "status", "justification")) registry.RegisterSchema("VulnerabilityDecision", objectSchema(map[string]any{ "id": map[string]any{"type": "string"}, @@ -323,6 +325,8 @@ func registerCriticalSchemas(registry *specs.Registry) { "supersedes": map[string]any{"type": "string"}, "superseded_by": map[string]any{"type": "string"}, "approved_by": map[string]any{"type": "string"}, + "reviewed_at": map[string]any{"type": "string", "format": "date-time"}, + "review_due_at": map[string]any{"type": "string", "format": "date-time"}, "schema_version": map[string]any{"type": "string"}, "created_at": map[string]any{"type": "string", "format": "date-time"}, }, "id", "tenant_id", "finding_id", "scan_id", "vulnerability", "status", "justification", "source", "schema_version", "created_at")) @@ -343,6 +347,8 @@ func registerCriticalSchemas(registry *specs.Registry) { "evidence_id": map[string]any{"type": "string"}, "evidence_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, "vex_document_id": map[string]any{"type": "string"}, + "reviewed_at": map[string]any{"type": "string", "format": "date-time"}, + "review_due_at": map[string]any{"type": "string", "format": "date-time"}, "created_at": map[string]any{"type": "string", "format": "date-time"}, }, "id", "finding_id", "scan_id", "release_id", "vulnerability", "status", "impact_statement", "source", "created_at")) registry.RegisterSchema("VulnerabilityDecisionSummaryReport", objectSchema(map[string]any{ diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index f1d8860..a4e6c10 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -1509,14 +1509,16 @@ func (s *Server) getVulnerabilityScan(w http.ResponseWriter, r *http.Request) { func (s *Server) createVulnerabilityDecision(w http.ResponseWriter, r *http.Request) { var req struct { - Status string `json:"status"` - Justification string `json:"justification"` - ImpactStatement string `json:"impact_statement"` - ActionStatement string `json:"action_statement"` - CustomerVisible bool `json:"customer_visible"` - InternalNotes string `json:"internal_notes"` - EvidenceIDs []string `json:"evidence_ids"` - VEXDocumentID string `json:"vex_document_id"` + Status string `json:"status"` + Justification string `json:"justification"` + ImpactStatement string `json:"impact_statement"` + ActionStatement string `json:"action_statement"` + CustomerVisible bool `json:"customer_visible"` + InternalNotes string `json:"internal_notes"` + EvidenceIDs []string `json:"evidence_ids"` + VEXDocumentID string `json:"vex_document_id"` + ReviewedAt *time.Time `json:"reviewed_at"` + ReviewDueAt *time.Time `json:"review_due_at"` } s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { @@ -1531,6 +1533,8 @@ func (s *Server) createVulnerabilityDecision(w http.ResponseWriter, r *http.Requ InternalNotes: req.InternalNotes, EvidenceIDs: req.EvidenceIDs, VEXDocumentID: req.VEXDocumentID, + ReviewedAt: req.ReviewedAt, + ReviewDueAt: req.ReviewDueAt, }) return http.StatusCreated, decision, err }) diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index fc35d39..7114ee5 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -90,6 +90,9 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { if _, ok := decisionRequestProps["vex_document_id"]; !ok { t.Fatalf("manual decision request schema missing vex_document_id: %#v", decisionRequestProps) } + if _, ok := decisionRequestProps["review_due_at"]; !ok { + t.Fatalf("manual decision request schema missing review_due_at: %#v", decisionRequestProps) + } redactionRequestProps := asStringAnyMap(t, asStringAnyMap(t, schemas["CreateRedactionProfileRequest"])["properties"]) if _, ok := redactionRequestProps["preset"]; !ok { t.Fatalf("redaction profile request schema missing preset: %#v", redactionRequestProps) @@ -758,9 +761,9 @@ func TestReleaseRiskDecisionHTTPFlow(t *testing.T) { t.Fatalf("expected failed readiness report with blocking findings: %s", report) } postJSON(t, server, secret, "/v1/vulnerability-findings/"+findingID+"/decisions", "risk-decision-bad", map[string]any{"status": "not_affected", "justification": "vulnerable code is not present", "customer_visible": true}, http.StatusBadRequest) - decisionPayload := map[string]any{"status": "not_affected", "justification": "vulnerable code is not present", "impact_statement": "The vulnerable code path is not present in this release.", "customer_visible": true, "internal_notes": "private note", "evidence_ids": []string{evidenceID}} + decisionPayload := map[string]any{"status": "not_affected", "justification": "vulnerable code is not present", "impact_statement": "The vulnerable code path is not present in this release.", "customer_visible": true, "internal_notes": "private note", "evidence_ids": []string{evidenceID}, "reviewed_at": "2026-05-27T12:00:00Z", "review_due_at": "2026-08-25T12:00:00Z"} decisionBody := postJSON(t, server, secret, "/v1/vulnerability-findings/"+findingID+"/decisions", "risk-decision", decisionPayload, http.StatusCreated) - if !strings.Contains(decisionBody, `"customer_visible":true`) || !strings.Contains(decisionBody, `"internal_notes":"private note"`) || !strings.Contains(decisionBody, evidenceID) { + if !strings.Contains(decisionBody, `"customer_visible":true`) || !strings.Contains(decisionBody, `"internal_notes":"private note"`) || !strings.Contains(decisionBody, evidenceID) || !strings.Contains(decisionBody, `"review_due_at":"2026-08-25T12:00:00Z"`) { t.Fatalf("decision response missing customer visibility/internal note fields: %s", decisionBody) } replayed := postJSON(t, server, secret, "/v1/vulnerability-findings/"+findingID+"/decisions", "risk-decision", decisionPayload, http.StatusCreated) @@ -775,7 +778,7 @@ func TestReleaseRiskDecisionHTTPFlow(t *testing.T) { getJSON(t, server, secret, "/v1/vulnerability-decisions?active=maybe", http.StatusBadRequest) getJSON(t, server, secret, "/v1/vulnerability-decisions?status=not_a_status", http.StatusBadRequest) summary := getJSON(t, server, secret, "/v1/reports/vulnerability-decision-summary?release_id="+releaseID, http.StatusOK) - if !strings.Contains(summary, `"report_type":"vulnerability_decision_summary"`) || !strings.Contains(summary, `"The vulnerable code path is not present in this release."`) { + if !strings.Contains(summary, `"report_type":"vulnerability_decision_summary"`) || !strings.Contains(summary, `"The vulnerable code path is not present in this release."`) || !strings.Contains(summary, `"reviewed_at":"2026-05-27T12:00:00Z"`) { t.Fatalf("decision summary missing customer-safe content: %s", summary) } if strings.Contains(summary, "private note") || strings.Contains(summary, "payload_ref") { diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index 4213305..d512d06 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -1164,7 +1164,7 @@ func (s *Store) loadRelationalRiskDecisions(ctx context.Context, state *app.Pers SELECT id, tenant_id, finding_id, scan_id, release_id, vulnerability, component, status, justification, impact_statement, action_statement, customer_visible, internal_notes, source, evidence_id, evidence_ids, vex_document_id, - supersedes, superseded_by, approved_by, schema_version, created_at + supersedes, superseded_by, approved_by, reviewed_at, review_due_at, schema_version, created_at FROM vulnerability_decisions `) if err != nil { @@ -1174,11 +1174,12 @@ func (s *Store) loadRelationalRiskDecisions(ctx context.Context, state *app.Pers for decisionRows.Next() { var decision domain.VulnerabilityDecision var releaseID, component, impactStatement, actionStatement, internalNotes, evidenceID, vexDocumentID, supersedes, supersededBy, approvedBy sql.NullString + var reviewedAt, reviewDueAt sql.NullTime if err := decisionRows.Scan( &decision.ID, &decision.TenantID, &decision.FindingID, &decision.ScanID, &releaseID, &decision.Vulnerability, &component, &decision.Status, &decision.Justification, &impactStatement, &actionStatement, &decision.CustomerVisible, &internalNotes, &decision.Source, &evidenceID, &decision.EvidenceIDs, &vexDocumentID, &supersedes, &supersededBy, - &approvedBy, &decision.SchemaVersion, &decision.CreatedAt, + &approvedBy, &reviewedAt, &reviewDueAt, &decision.SchemaVersion, &decision.CreatedAt, ); err != nil { return fmt.Errorf("scan relational vulnerability decision: %w", err) } @@ -1192,6 +1193,8 @@ func (s *Store) loadRelationalRiskDecisions(ctx context.Context, state *app.Pers decision.Supersedes = nullableSQLString(supersedes) decision.SupersededBy = nullableSQLString(supersededBy) decision.ApprovedBy = nullableSQLString(approvedBy) + decision.ReviewedAt = nullableSQLTime(reviewedAt) + decision.ReviewDueAt = nullableSQLTime(reviewDueAt) state.Decisions[decision.ID] = decision *loaded = true } @@ -3303,17 +3306,19 @@ func syncRiskBuildControlRows(ctx context.Context, tx pgx.Tx, state app.Persiste id, tenant_id, finding_id, scan_id, release_id, vulnerability, component, status, justification, impact_statement, action_statement, customer_visible, internal_notes, source, evidence_id, evidence_ids, vex_document_id, - supersedes, superseded_by, approved_by, schema_version, created_at + supersedes, superseded_by, approved_by, reviewed_at, review_due_at, schema_version, created_at ) VALUES ( $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, - $17, $18, $19, $20, $21, $22 + $17, $18, $19, $20, $21, $22, $23, $24 ) ON CONFLICT (id) DO UPDATE SET superseded_by = EXCLUDED.superseded_by, approved_by = EXCLUDED.approved_by, + reviewed_at = COALESCE(vulnerability_decisions.reviewed_at, EXCLUDED.reviewed_at), + review_due_at = COALESCE(vulnerability_decisions.review_due_at, EXCLUDED.review_due_at), customer_visible = vulnerability_decisions.customer_visible OR EXCLUDED.customer_visible, internal_notes = COALESCE(NULLIF(vulnerability_decisions.internal_notes, ''), EXCLUDED.internal_notes), evidence_ids = CASE @@ -3323,7 +3328,7 @@ func syncRiskBuildControlRows(ctx context.Context, tx pgx.Tx, state app.Persiste `, decision.ID, decision.TenantID, decision.FindingID, decision.ScanID, nullableString(decision.ReleaseID), decision.Vulnerability, nullableString(decision.Component), decision.Status, decision.Justification, nullableString(decision.ImpactStatement), nullableString(decision.ActionStatement), decision.CustomerVisible, nullableString(decision.InternalNotes), decision.Source, nullableString(decision.EvidenceID), textArray(decision.EvidenceIDs), nullableString(decision.VEXDocumentID), nullableString(decision.Supersedes), nullableString(decision.SupersededBy), - nullableString(decision.ApprovedBy), decision.SchemaVersion, nonZeroTime(decision.CreatedAt)); err != nil { + nullableString(decision.ApprovedBy), nullableTime(decision.ReviewedAt), nullableTime(decision.ReviewDueAt), decision.SchemaVersion, nonZeroTime(decision.CreatedAt)); err != nil { return fmt.Errorf("upsert vulnerability decision row: %w", err) } } diff --git a/internal/app/governance_packages.go b/internal/app/governance_packages.go index e1b5bf3..8cec062 100644 --- a/internal/app/governance_packages.go +++ b/internal/app/governance_packages.go @@ -1401,9 +1401,9 @@ func customerPackageHTMLReport(pkg domain.CustomerSecurityPackage, metadata, ver b.WriteString("") } if len(decisions) > 0 { - b.WriteString("

Vulnerability Decisions

") + b.WriteString("

Vulnerability Decisions

VulnerabilityComponentStatusImpact StatementSource
") for _, record := range decisions { - b.WriteString("") + b.WriteString("") } b.WriteString("
VulnerabilityComponentStatusImpact StatementReviewedReview DueSource
" + packageHTMLEscape(packageHTMLString(record["vulnerability"])) + "" + packageHTMLEscape(packageHTMLString(record["component"])) + "" + packageHTMLEscape(packageHTMLString(record["status"])) + "" + packageHTMLEscape(packageHTMLString(record["impact_statement"])) + "" + packageHTMLEscape(packageHTMLString(record["source"])) + "
" + packageHTMLEscape(packageHTMLString(record["vulnerability"])) + "" + packageHTMLEscape(packageHTMLString(record["component"])) + "" + packageHTMLEscape(packageHTMLString(record["status"])) + "" + packageHTMLEscape(packageHTMLString(record["impact_statement"])) + "" + packageHTMLEscape(packageHTMLString(record["reviewed_at"])) + "" + packageHTMLEscape(packageHTMLString(record["review_due_at"])) + "" + packageHTMLEscape(packageHTMLString(record["source"])) + "
") } @@ -1978,6 +1978,12 @@ func (l *Ledger) packageDecisionSummariesLocked(tenantID, releaseID string, prof "source": decision.Source, "created_at": decision.CreatedAt.UTC().Format(time.RFC3339), } + if decision.ReviewedAt != nil && !excluded["reviewed_at"] { + summary["reviewed_at"] = decision.ReviewedAt.UTC().Format(time.RFC3339) + } + if decision.ReviewDueAt != nil && !excluded["review_due_at"] { + summary["review_due_at"] = decision.ReviewDueAt.UTC().Format(time.RFC3339) + } if decision.ActionStatement != "" && !excluded["action_statement"] { summary["action_statement"] = decision.ActionStatement } diff --git a/internal/app/ledger_test.go b/internal/app/ledger_test.go index 7518873..03d9bd5 100644 --- a/internal/app/ledger_test.go +++ b/internal/app/ledger_test.go @@ -830,6 +830,8 @@ func TestCustomerVisibleDecisionRequiresImpactAndRedactsInternalNotes(t *testing }); !errors.Is(err, ErrValidation) { t.Fatalf("customer-visible decision without impact err=%v, want validation", err) } + reviewedAt := fixedNow().Add(-time.Hour) + reviewDueAt := fixedNow().Add(30 * 24 * time.Hour) decision, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{ Status: decisionStatusNotAffected, Justification: "runtime code path is not present", @@ -837,6 +839,8 @@ func TestCustomerVisibleDecisionRequiresImpactAndRedactsInternalNotes(t *testing ActionStatement: "No customer action is required for this finding.", CustomerVisible: true, InternalNotes: "private triage note", + ReviewedAt: &reviewedAt, + ReviewDueAt: &reviewDueAt, }) if err != nil { t.Fatalf("decision: %v", err) @@ -865,6 +869,9 @@ func TestCustomerVisibleDecisionRequiresImpactAndRedactsInternalNotes(t *testing if !strings.Contains(string(body), decision.ImpactStatement) { t.Fatalf("package manifest missing customer-safe impact statement: %s", body) } + if !strings.Contains(string(body), `"reviewed_at"`) || !strings.Contains(string(body), `"review_due_at"`) { + t.Fatalf("package manifest missing decision freshness metadata: %s", body) + } if strings.Contains(string(body), "private triage note") { t.Fatalf("package manifest leaked internal notes: %s", body) } @@ -902,6 +909,18 @@ func TestVulnerabilityDecisionSummaryReportRedactsInternalAndOnlyIncludesActiveV if err != nil { t.Fatalf("first decision: %v", err) } + reviewedAt := fixedNow().Add(-2 * time.Hour) + reviewDueAt := fixedNow().Add(90 * 24 * time.Hour) + if _, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{ + Status: decisionStatusNotAffected, + Justification: "bad freshness metadata", + ImpactStatement: "This release is not affected.", + CustomerVisible: true, + ReviewedAt: &reviewedAt, + ReviewDueAt: &reviewedAt, + }); !errors.Is(err, ErrValidation) { + t.Fatalf("decision with non-increasing review due err=%v, want validation", err) + } second, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{ Status: decisionStatusNotAffected, Justification: "runtime path not present", @@ -910,6 +929,8 @@ func TestVulnerabilityDecisionSummaryReportRedactsInternalAndOnlyIncludesActiveV CustomerVisible: true, InternalNotes: "replacement private note", EvidenceIDs: []string{supporting.ID}, + ReviewedAt: &reviewedAt, + ReviewDueAt: &reviewDueAt, }) if err != nil { t.Fatalf("second decision: %v", err) @@ -932,6 +953,9 @@ func TestVulnerabilityDecisionSummaryReportRedactsInternalAndOnlyIncludesActiveV if got.ID != second.ID || got.ImpactStatement != second.ImpactStatement || len(got.EvidenceIDs) != 1 || got.EvidenceIDs[0] != supporting.ID { t.Fatalf("summary decision=%#v, want active customer-visible decision", got) } + if got.ReviewedAt == nil || got.ReviewDueAt == nil || !got.ReviewedAt.Equal(reviewedAt) || !got.ReviewDueAt.Equal(reviewDueAt) { + t.Fatalf("summary freshness metadata=%#v/%#v, want %#v/%#v", got.ReviewedAt, got.ReviewDueAt, reviewedAt, reviewDueAt) + } body, err := json.Marshal(report) if err != nil { t.Fatalf("marshal summary: %v", err) diff --git a/internal/app/vex.go b/internal/app/vex.go index d878629..236e25d 100644 --- a/internal/app/vex.go +++ b/internal/app/vex.go @@ -37,6 +37,8 @@ type CreateVulnerabilityDecisionInput struct { InternalNotes string EvidenceIDs []string VEXDocumentID string + ReviewedAt *time.Time + ReviewDueAt *time.Time } type ListVulnerabilityDecisionsInput struct { @@ -320,6 +322,9 @@ func (s releaseEvidenceService) CreateVulnerabilityDecision(ctx context.Context, if len(strings.TrimSpace(in.InternalNotes)) > 8192 { return domain.VulnerabilityDecision{}, ErrValidation } + if err := normalizeDecisionReviewTimes(&in, l.now()); err != nil { + return domain.VulnerabilityDecision{}, err + } l.mu.Lock() defer l.mu.Unlock() scan, finding, ok := l.findFindingLocked(actor.TenantID, strings.TrimSpace(findingID)) @@ -485,10 +490,12 @@ func (s releaseEvidenceService) VulnerabilityDecisionSummaryReport(ctx context.C Assumptions: []string{ "Only active vulnerability decisions marked customer_visible are included.", "Evidence identifiers point to records in this Evydence instance; raw evidence payload bytes are not included.", + "reviewed_at records when the decision was reviewed; missing review_due_at means no scheduled follow-up review was recorded.", }, Limitations: []string{ "This summary supports compliance-readiness review; it is not certification, legal advice, complete SBOM proof, or authoritative vulnerability coverage.", "Decision accuracy depends on tenant-supplied evidence, scanner inputs, and review quality.", + "Review dates are tenant-supplied metadata and do not prove that the underlying vulnerability analysis is still correct.", }, GeneratedAt: l.now(), }, nil @@ -510,6 +517,8 @@ func customerDecisionSummary(decision domain.VulnerabilityDecision) domain.Vulne EvidenceID: decision.EvidenceID, EvidenceIDs: append([]string(nil), decision.EvidenceIDs...), VEXDocumentID: decision.VEXDocumentID, + ReviewedAt: cloneTimePtr(decision.ReviewedAt), + ReviewDueAt: cloneTimePtr(decision.ReviewDueAt), CreatedAt: decision.CreatedAt, } } @@ -1101,6 +1110,7 @@ func openVEXProductIDs(products []openVEXProduct) map[string]struct{} { func (l *Ledger) createDecisionLocked(tenantID string, scan domain.VulnerabilityScan, finding domain.VulnerabilityFinding, in CreateVulnerabilityDecisionInput, source, actorID, evidenceID, vexID string) domain.VulnerabilityDecision { decisionID := newID("vd") + createdAt := l.now() var supersedes string for id, existing := range l.decisions { if existing.TenantID == tenantID && existing.FindingID == finding.ID && existing.SupersededBy == "" { @@ -1129,12 +1139,55 @@ func (l *Ledger) createDecisionLocked(tenantID string, scan domain.Vulnerability VEXDocumentID: vexID, Supersedes: supersedes, ApprovedBy: actorID, + ReviewedAt: decisionReviewedAt(in.ReviewedAt, createdAt), + ReviewDueAt: cloneTimePtr(in.ReviewDueAt), SchemaVersion: domain.VulnerabilityDecisionVersion, - CreatedAt: l.now(), + CreatedAt: createdAt, } return decision } +func normalizeDecisionReviewTimes(in *CreateVulnerabilityDecisionInput, now time.Time) error { + now = now.UTC() + var reviewedAt time.Time + if in.ReviewedAt != nil { + if in.ReviewedAt.IsZero() || in.ReviewedAt.After(now.Add(time.Minute)) { + return ErrValidation + } + reviewedAt = in.ReviewedAt.UTC() + in.ReviewedAt = &reviewedAt + } else { + reviewedAt = now + } + if in.ReviewDueAt != nil { + if in.ReviewDueAt.IsZero() { + return ErrValidation + } + dueAt := in.ReviewDueAt.UTC() + if !dueAt.After(reviewedAt) { + return ErrValidation + } + in.ReviewDueAt = &dueAt + } + return nil +} + +func decisionReviewedAt(reviewedAt *time.Time, fallback time.Time) *time.Time { + if reviewedAt != nil { + return cloneTimePtr(reviewedAt) + } + value := fallback.UTC() + return &value +} + +func cloneTimePtr(value *time.Time) *time.Time { + if value == nil { + return nil + } + clone := value.UTC() + return &clone +} + func (l *Ledger) validateDecisionEvidenceLinksLocked(tenantID, releaseID string, evidenceIDs []string) ([]string, error) { ids := sortedUniqueNonEmptyStrings(evidenceIDs) if len(evidenceIDs) != len(ids) { diff --git a/internal/domain/domain.go b/internal/domain/domain.go index 3e68992..853bb60 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -1259,46 +1259,50 @@ type VEXImportReport struct { } type VulnerabilityDecision struct { - ID string `json:"id"` - TenantID string `json:"tenant_id"` - FindingID string `json:"finding_id"` - ScanID string `json:"scan_id"` - ReleaseID string `json:"release_id,omitempty"` - Vulnerability string `json:"vulnerability"` - Component string `json:"component,omitempty"` - Status string `json:"status"` - Justification string `json:"justification"` - ImpactStatement string `json:"impact_statement,omitempty"` - ActionStatement string `json:"action_statement,omitempty"` - CustomerVisible bool `json:"customer_visible"` - InternalNotes string `json:"internal_notes,omitempty"` - Source string `json:"source"` - EvidenceID string `json:"evidence_id,omitempty"` - EvidenceIDs []string `json:"evidence_ids,omitempty"` - VEXDocumentID string `json:"vex_document_id,omitempty"` - Supersedes string `json:"supersedes,omitempty"` - SupersededBy string `json:"superseded_by,omitempty"` - ApprovedBy string `json:"approved_by,omitempty"` - SchemaVersion string `json:"schema_version"` - CreatedAt time.Time `json:"created_at"` + ID string `json:"id"` + TenantID string `json:"tenant_id"` + FindingID string `json:"finding_id"` + ScanID string `json:"scan_id"` + ReleaseID string `json:"release_id,omitempty"` + Vulnerability string `json:"vulnerability"` + Component string `json:"component,omitempty"` + Status string `json:"status"` + Justification string `json:"justification"` + ImpactStatement string `json:"impact_statement,omitempty"` + ActionStatement string `json:"action_statement,omitempty"` + CustomerVisible bool `json:"customer_visible"` + InternalNotes string `json:"internal_notes,omitempty"` + Source string `json:"source"` + EvidenceID string `json:"evidence_id,omitempty"` + EvidenceIDs []string `json:"evidence_ids,omitempty"` + VEXDocumentID string `json:"vex_document_id,omitempty"` + Supersedes string `json:"supersedes,omitempty"` + SupersededBy string `json:"superseded_by,omitempty"` + ApprovedBy string `json:"approved_by,omitempty"` + ReviewedAt *time.Time `json:"reviewed_at,omitempty"` + ReviewDueAt *time.Time `json:"review_due_at,omitempty"` + SchemaVersion string `json:"schema_version"` + CreatedAt time.Time `json:"created_at"` } type VulnerabilityDecisionCustomerSummary struct { - ID string `json:"id"` - FindingID string `json:"finding_id"` - ScanID string `json:"scan_id"` - ReleaseID string `json:"release_id"` - Vulnerability string `json:"vulnerability"` - Component string `json:"component,omitempty"` - Status string `json:"status"` - Justification string `json:"justification,omitempty"` - ImpactStatement string `json:"impact_statement"` - ActionStatement string `json:"action_statement,omitempty"` - Source string `json:"source"` - EvidenceID string `json:"evidence_id,omitempty"` - EvidenceIDs []string `json:"evidence_ids,omitempty"` - VEXDocumentID string `json:"vex_document_id,omitempty"` - CreatedAt time.Time `json:"created_at"` + ID string `json:"id"` + FindingID string `json:"finding_id"` + ScanID string `json:"scan_id"` + ReleaseID string `json:"release_id"` + Vulnerability string `json:"vulnerability"` + Component string `json:"component,omitempty"` + Status string `json:"status"` + Justification string `json:"justification,omitempty"` + ImpactStatement string `json:"impact_statement"` + ActionStatement string `json:"action_statement,omitempty"` + Source string `json:"source"` + EvidenceID string `json:"evidence_id,omitempty"` + EvidenceIDs []string `json:"evidence_ids,omitempty"` + VEXDocumentID string `json:"vex_document_id,omitempty"` + ReviewedAt *time.Time `json:"reviewed_at,omitempty"` + ReviewDueAt *time.Time `json:"review_due_at,omitempty"` + CreatedAt time.Time `json:"created_at"` } type VulnerabilityDecisionSummaryReport struct { diff --git a/migrations/20260601000600_vulnerability_decision_review_times.down.sql b/migrations/20260601000600_vulnerability_decision_review_times.down.sql new file mode 100644 index 0000000..22727f3 --- /dev/null +++ b/migrations/20260601000600_vulnerability_decision_review_times.down.sql @@ -0,0 +1,5 @@ +ALTER TABLE IF EXISTS vulnerability_decisions + DROP COLUMN IF EXISTS review_due_at; + +ALTER TABLE IF EXISTS vulnerability_decisions + DROP COLUMN IF EXISTS reviewed_at; diff --git a/migrations/20260601000600_vulnerability_decision_review_times.up.sql b/migrations/20260601000600_vulnerability_decision_review_times.up.sql new file mode 100644 index 0000000..d25f8ca --- /dev/null +++ b/migrations/20260601000600_vulnerability_decision_review_times.up.sql @@ -0,0 +1,5 @@ +ALTER TABLE IF EXISTS vulnerability_decisions + ADD COLUMN IF NOT EXISTS reviewed_at timestamptz; + +ALTER TABLE IF EXISTS vulnerability_decisions + ADD COLUMN IF NOT EXISTS review_due_at timestamptz; diff --git a/openapi.yaml b/openapi.yaml index 8fe6c45..b3b4601 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CRAVulnerabilityHandlingReport":{"additionalProperties":false,"properties":{"accepted_exceptions":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"CRAVulnerabilityHandlingReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"},"require_nda":{"type":"boolean"},"reviewer_email":{"description":"Optional external reviewer email label. It is not used as an authentication secret.","type":"string"},"reviewer_name":{"description":"Optional external reviewer display name for this package access record.","type":"string"},"watermark":{"description":"Optional customer-visible distribution watermark. It is not a token or secret.","type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireAnswerLibraryEntryRequest":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"}},"required":["answer"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccess":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"failed_access_count":{"type":"integer"},"id":{"type":"string"},"last_accessed_at":{"format":"date-time","type":"string"},"last_failed_at":{"format":"date-time","type":"string"},"nda_accepted_at":{"format":"date-time","type":"string"},"nda_accepted_by":{"type":"string"},"package_id":{"type":"string"},"prefix":{"description":"Non-secret portal token prefix for operational lookup.","type":"string"},"require_nda":{"type":"boolean"},"reviewer_email":{"type":"string"},"reviewer_name":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"watermark":{"type":"string"}},"required":["id","tenant_id","package_id","customer_name","prefix","expires_at","access_count","failed_access_count","schema_version","created_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"$ref":"#/components/schemas/CustomerPortalAccess"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalAccessEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccess"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CustomerPortalAccess"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"nda_accepted":{"description":"Set true to record acceptance for NDA-gated portal access.","type":"boolean"},"nda_accepted_by":{"description":"Reviewer label recorded when NDA acceptance is required. Do not include secrets.","type":"string"},"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"distribution_watermark":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"remediation":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntry":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","answer","schema_version","created_at"],"type":"object"},"QuestionnaireAnswerLibraryEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"policy_set":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlow":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["needs_evidence","ready_for_review"],"type":"string"},"steps":{"items":{"$ref":"#/components/schemas/ReleaseEvidenceFlowStep"},"type":"array"}},"required":["release_id","product_id","status","counts","steps","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseEvidenceFlowEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseEvidenceFlow"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlowStep":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"idempotency_required":{"type":"boolean"},"method":{"type":"string"},"next_reference":{"type":"string"},"path":{"type":"string"},"required":{"type":"boolean"},"required_scopes":{"items":{"type":"string"},"type":"array"},"status":{"enum":["present","missing","optional"],"type":"string"},"title":{"type":"string"}},"required":["id","title","status","required","method","path","required_scopes","idempotency_required","description"],"type":"object"},"ReleaseSecurityApprovalSummary":{"additionalProperties":false,"properties":{"approved":{"type":"integer"},"total":{"type":"integer"}},"required":["total","approved"],"type":"object"},"ReleaseSecurityExceptionSummary":{"additionalProperties":false,"properties":{"approved_unexpired":{"type":"integer"},"expired":{"type":"integer"},"total":{"type":"integer"},"unapproved":{"type":"integer"}},"required":["total","approved_unexpired","unapproved","expired"],"type":"object"},"ReleaseSecurityMissingDecision":{"additionalProperties":false,"properties":{"component":{"type":"string"},"finding_id":{"type":"string"},"scan_id":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["finding_id","scan_id","vulnerability","severity","state"],"type":"object"},"ReleaseSecurityProductSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"],"type":"object"},"ReleaseSecurityReleaseSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"state":{"type":"string"},"version":{"type":"string"}},"required":["id","version","state"],"type":"object"},"ReleaseSecuritySummary":{"additionalProperties":false,"properties":{"approval_summary":{"$ref":"#/components/schemas/ReleaseSecurityApprovalSummary"},"artifact_count":{"type":"integer"},"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"decisions_by_status":{"additionalProperties":{"type":"integer"},"type":"object"},"exception_summary":{"$ref":"#/components/schemas/ReleaseSecurityExceptionSummary"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_required_decisions":{"items":{"$ref":"#/components/schemas/ReleaseSecurityMissingDecision"},"type":"array"},"open_findings_by_severity":{"additionalProperties":{"type":"integer"},"type":"object"},"package_status":{"enum":["generated","not_generated"],"type":"string"},"product":{"$ref":"#/components/schemas/ReleaseSecurityProductSummary"},"readiness_status":{"enum":["passed","failed"],"type":"string"},"release":{"$ref":"#/components/schemas/ReleaseSecurityReleaseSummary"},"sbom_status":{"enum":["present","missing"],"type":"string"},"schema_version":{"type":"string"},"vulnerability_scan_status":{"enum":["present","missing"],"type":"string"}},"required":["product","release","artifact_count","sbom_status","vulnerability_scan_status","open_findings_by_severity","decisions_by_status","approval_summary","exception_summary","readiness_status","package_status","counts","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseSecuritySummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseSecuritySummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityUpdateEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"fixed_decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incidents":{"items":{"$ref":"#/components/schemas/Incident"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"remediation_tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"SecurityUpdateEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningCustodyReviewReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"object_retention_policies":{"items":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"type":"array"},"report_type":{"type":"string"},"signing_providers":{"items":{"$ref":"#/components/schemas/SigningProvider"},"type":"array"},"tenant_id":{"type":"string"}},"required":["report_type","tenant_id","checks","assumptions","limitations","generated_at"],"type":"object"},"SigningCustodyReviewReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningCustodyReviewReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"examples":{"release-evidence-package":{"summary":"Create a scoped release evidence package","value":{"expires_at":"2026-06-30T00:00:00Z","product_id":"prod_20260527120000","redaction_profile_id":"rp_20260527120000","release_id":"rel_20260527120000","title":"Payments API 1.0.0 release evidence package"}}},"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"get":{"description":"Lists tenant-scoped external reviewer access records without token hashes or token secrets.","operationId":"listCustomerPortalAccess","parameters":[{"description":"Optional customer package id filter.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessListEnvelope"}}},"description":"Customer portal access list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List customer portal access records","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a named, expiring external reviewer access record for a customer package and returns the portal token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/access/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped external reviewer access record; revocation is append-only and the original token cannot be used afterwards.","operationId":"revokeCustomerPortalAccess","parameters":[{"description":"Customer portal access id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessEnvelope"}}},"description":"Revoked customer portal access envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-answer-library":{"get":{"description":"Lists tenant-scoped questionnaire answer library entries with optional question, product, and release filters.","operationId":"listQuestionnaireAnswerLibrary","parameters":[{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by questionnaire question id.","in":"query","name":"question_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryListEnvelope"}}},"description":"Questionnaire answer library entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List questionnaire answer library entries","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a tenant-scoped reusable questionnaire answer draft linked to optional evidence, product, release, or control scope.","operationId":"createQuestionnaireAnswerLibraryEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireAnswerLibraryEntryRequest"}}},"description":"Questionnaire answer library entry creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryEnvelope"}}},"description":"Created questionnaire answer library entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire answer library entry","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"examples":{"release-candidate":{"summary":"Create a release for evidence collection","value":{"product_id":"prod_20260527120000","project_id":"proj_20260527120000","version":"1.0.0-rc.1"}}},"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"examples":{"created-release":{"summary":"Created release response","value":{"data":{"created_at":"2026-05-27T12:00:00Z","id":"rel_20260527120000","product_id":"prod_20260527120000","project_id":"proj_20260527120000","schema_version":"release.v1.0.0","status":"draft","tenant_id":"ten_20260527120000","version":"1.0.0-rc.1"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/evidence-flow/start":{"post":{"description":"Returns a high-level release evidence workflow plan, current evidence counts, required scopes, assumptions, and limitations. This read-only convenience operation does not create evidence.","operationId":"startReleaseEvidenceFlow","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEvidenceFlowEnvelope"}}},"description":"Release evidence flow envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Start release evidence flow","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:read"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/security-summary":{"get":{"description":"Returns a tenant-scoped release security summary for review surfaces without raw evidence payload bytes.","operationId":"releaseSecuritySummary","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseSecuritySummaryEnvelope"}}},"description":"Release security summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release security summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-vulnerability-handling":{"get":{"description":"Returns a CRA-oriented vulnerability handling evidence report without legal compliance, certification, scanner-authority, or release-security conclusions.","operationId":"craVulnerabilityHandlingReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReportEnvelope"}}},"description":"CRA vulnerability handling report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA vulnerability handling report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/custody-review":{"get":{"description":"Returns tenant signing-provider and object-lock verification metadata for deployment custody review. It is evidence metadata only, not legal compliance proof, certification, HSM custody proof, or a secure-deployment guarantee.","operationId":"signingCustodyReviewReport","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningCustodyReviewReportEnvelope"}}},"description":"Signing custody review report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Signing custody review report","tags":["evydence"],"x-scopes":["keys:admin"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"examples":{"failed-readiness-with-gap":{"summary":"Readiness report with a vulnerability decision gap","value":{"data":{"accepted_exceptions":[],"assumptions":["Readiness is based on tenant evidence recorded in Evydence."],"blocking_findings":[{"component":"pkg:apk/openssl@3.1.0-r0","decision_state":"missing","finding_id":"scan_20260527120000:finding:1","release_id":"rel_20260527120000","scan_id":"scan_20260527120000","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"generated_at":"2026-05-27T12:00:00Z","limitations":["Readiness supports technical review and does not prove legal compliance, certification, complete vulnerability coverage, or release security."],"missing_evidence":["vulnerability_decision"],"policy_set":"policy-set.v1.0.0","product_id":"prod_20260527120000","release_id":"rel_20260527120000","report_type":"release_readiness","result":"failed","schema_version":"release-readiness.v1.0.0","summary":{"headline":"Release evidence has one blocking vulnerability decision gap.","human_summary":"Required artifact, SBOM, scan, build, and bundle evidence is present, but one critical finding still needs a valid decision or approved exception.","policy_set":"policy-set.v1.0.0","result":"failed"},"template_version":"release-readiness.v1.0.0"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/security-update-evidence":{"get":{"description":"Returns a security update evidence report for release-scoped fixed decisions, incidents, remediation tasks, and linked evidence without legal or security conclusions.","operationId":"securityUpdateEvidenceReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReportEnvelope"}}},"description":"Security update evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security update evidence report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"examples":{"cyclonedx-release-sbom":{"summary":"Upload a CycloneDX SBOM linked to the release artifact","value":{"artifact_id":"art_20260527120000","payload":{"bomFormat":"CycloneDX","components":[{"name":"payments-api","purl":"pkg:oci/payments-api@sha256-ca978112","version":"1.0.0-rc.1"},{"name":"openssl","purl":"pkg:apk/openssl@3.1.0-r0","version":"3.1.0-r0"}],"specVersion":"1.6"},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"examples":{"not-affected-decision":{"summary":"Record a customer-visible not-affected decision","value":{"customer_visible":true,"evidence_ids":["ev_20260527120000"],"impact_statement":"The shipped artifact does not include the affected runtime path.","justification":"The vulnerable code path is not reachable in this release.","status":"not_affected"}}},"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"examples":{"generic-critical-finding":{"summary":"Upload a generic scanner finding for release triage","value":{"findings":[{"component":"pkg:apk/openssl@3.1.0-r0","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"release_id":"rel_20260527120000","scanner":"generic-json","target_ref":"pkg:oci/payments-api@sha256-ca978112"}}},"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CRAVulnerabilityHandlingReport":{"additionalProperties":false,"properties":{"accepted_exceptions":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"CRAVulnerabilityHandlingReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"},"require_nda":{"type":"boolean"},"reviewer_email":{"description":"Optional external reviewer email label. It is not used as an authentication secret.","type":"string"},"reviewer_name":{"description":"Optional external reviewer display name for this package access record.","type":"string"},"watermark":{"description":"Optional customer-visible distribution watermark. It is not a token or secret.","type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireAnswerLibraryEntryRequest":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"}},"required":["answer"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"review_due_at":{"description":"Optional UTC time when this decision should be reviewed again.","format":"date-time","type":"string"},"reviewed_at":{"description":"Optional UTC time when the decision was reviewed. Defaults to creation time.","format":"date-time","type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccess":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"failed_access_count":{"type":"integer"},"id":{"type":"string"},"last_accessed_at":{"format":"date-time","type":"string"},"last_failed_at":{"format":"date-time","type":"string"},"nda_accepted_at":{"format":"date-time","type":"string"},"nda_accepted_by":{"type":"string"},"package_id":{"type":"string"},"prefix":{"description":"Non-secret portal token prefix for operational lookup.","type":"string"},"require_nda":{"type":"boolean"},"reviewer_email":{"type":"string"},"reviewer_name":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"watermark":{"type":"string"}},"required":["id","tenant_id","package_id","customer_name","prefix","expires_at","access_count","failed_access_count","schema_version","created_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"$ref":"#/components/schemas/CustomerPortalAccess"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalAccessEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccess"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CustomerPortalAccess"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"nda_accepted":{"description":"Set true to record acceptance for NDA-gated portal access.","type":"boolean"},"nda_accepted_by":{"description":"Reviewer label recorded when NDA acceptance is required. Do not include secrets.","type":"string"},"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"distribution_watermark":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"remediation":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntry":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","answer","schema_version","created_at"],"type":"object"},"QuestionnaireAnswerLibraryEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"policy_set":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlow":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["needs_evidence","ready_for_review"],"type":"string"},"steps":{"items":{"$ref":"#/components/schemas/ReleaseEvidenceFlowStep"},"type":"array"}},"required":["release_id","product_id","status","counts","steps","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseEvidenceFlowEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseEvidenceFlow"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlowStep":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"idempotency_required":{"type":"boolean"},"method":{"type":"string"},"next_reference":{"type":"string"},"path":{"type":"string"},"required":{"type":"boolean"},"required_scopes":{"items":{"type":"string"},"type":"array"},"status":{"enum":["present","missing","optional"],"type":"string"},"title":{"type":"string"}},"required":["id","title","status","required","method","path","required_scopes","idempotency_required","description"],"type":"object"},"ReleaseSecurityApprovalSummary":{"additionalProperties":false,"properties":{"approved":{"type":"integer"},"total":{"type":"integer"}},"required":["total","approved"],"type":"object"},"ReleaseSecurityExceptionSummary":{"additionalProperties":false,"properties":{"approved_unexpired":{"type":"integer"},"expired":{"type":"integer"},"total":{"type":"integer"},"unapproved":{"type":"integer"}},"required":["total","approved_unexpired","unapproved","expired"],"type":"object"},"ReleaseSecurityMissingDecision":{"additionalProperties":false,"properties":{"component":{"type":"string"},"finding_id":{"type":"string"},"scan_id":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["finding_id","scan_id","vulnerability","severity","state"],"type":"object"},"ReleaseSecurityProductSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"],"type":"object"},"ReleaseSecurityReleaseSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"state":{"type":"string"},"version":{"type":"string"}},"required":["id","version","state"],"type":"object"},"ReleaseSecuritySummary":{"additionalProperties":false,"properties":{"approval_summary":{"$ref":"#/components/schemas/ReleaseSecurityApprovalSummary"},"artifact_count":{"type":"integer"},"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"decisions_by_status":{"additionalProperties":{"type":"integer"},"type":"object"},"exception_summary":{"$ref":"#/components/schemas/ReleaseSecurityExceptionSummary"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_required_decisions":{"items":{"$ref":"#/components/schemas/ReleaseSecurityMissingDecision"},"type":"array"},"open_findings_by_severity":{"additionalProperties":{"type":"integer"},"type":"object"},"package_status":{"enum":["generated","not_generated"],"type":"string"},"product":{"$ref":"#/components/schemas/ReleaseSecurityProductSummary"},"readiness_status":{"enum":["passed","failed"],"type":"string"},"release":{"$ref":"#/components/schemas/ReleaseSecurityReleaseSummary"},"sbom_status":{"enum":["present","missing"],"type":"string"},"schema_version":{"type":"string"},"vulnerability_scan_status":{"enum":["present","missing"],"type":"string"}},"required":["product","release","artifact_count","sbom_status","vulnerability_scan_status","open_findings_by_severity","decisions_by_status","approval_summary","exception_summary","readiness_status","package_status","counts","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseSecuritySummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseSecuritySummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityUpdateEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"fixed_decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incidents":{"items":{"$ref":"#/components/schemas/Incident"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"remediation_tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"SecurityUpdateEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningCustodyReviewReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"object_retention_policies":{"items":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"type":"array"},"report_type":{"type":"string"},"signing_providers":{"items":{"$ref":"#/components/schemas/SigningProvider"},"type":"array"},"tenant_id":{"type":"string"}},"required":["report_type","tenant_id","checks","assumptions","limitations","generated_at"],"type":"object"},"SigningCustodyReviewReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningCustodyReviewReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"review_due_at":{"format":"date-time","type":"string"},"reviewed_at":{"format":"date-time","type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"review_due_at":{"format":"date-time","type":"string"},"reviewed_at":{"format":"date-time","type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"examples":{"release-evidence-package":{"summary":"Create a scoped release evidence package","value":{"expires_at":"2026-06-30T00:00:00Z","product_id":"prod_20260527120000","redaction_profile_id":"rp_20260527120000","release_id":"rel_20260527120000","title":"Payments API 1.0.0 release evidence package"}}},"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"get":{"description":"Lists tenant-scoped external reviewer access records without token hashes or token secrets.","operationId":"listCustomerPortalAccess","parameters":[{"description":"Optional customer package id filter.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessListEnvelope"}}},"description":"Customer portal access list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List customer portal access records","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a named, expiring external reviewer access record for a customer package and returns the portal token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/access/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped external reviewer access record; revocation is append-only and the original token cannot be used afterwards.","operationId":"revokeCustomerPortalAccess","parameters":[{"description":"Customer portal access id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessEnvelope"}}},"description":"Revoked customer portal access envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-answer-library":{"get":{"description":"Lists tenant-scoped questionnaire answer library entries with optional question, product, and release filters.","operationId":"listQuestionnaireAnswerLibrary","parameters":[{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by questionnaire question id.","in":"query","name":"question_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryListEnvelope"}}},"description":"Questionnaire answer library entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List questionnaire answer library entries","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a tenant-scoped reusable questionnaire answer draft linked to optional evidence, product, release, or control scope.","operationId":"createQuestionnaireAnswerLibraryEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireAnswerLibraryEntryRequest"}}},"description":"Questionnaire answer library entry creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryEnvelope"}}},"description":"Created questionnaire answer library entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire answer library entry","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"examples":{"release-candidate":{"summary":"Create a release for evidence collection","value":{"product_id":"prod_20260527120000","project_id":"proj_20260527120000","version":"1.0.0-rc.1"}}},"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"examples":{"created-release":{"summary":"Created release response","value":{"data":{"created_at":"2026-05-27T12:00:00Z","id":"rel_20260527120000","product_id":"prod_20260527120000","project_id":"proj_20260527120000","schema_version":"release.v1.0.0","status":"draft","tenant_id":"ten_20260527120000","version":"1.0.0-rc.1"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/evidence-flow/start":{"post":{"description":"Returns a high-level release evidence workflow plan, current evidence counts, required scopes, assumptions, and limitations. This read-only convenience operation does not create evidence.","operationId":"startReleaseEvidenceFlow","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEvidenceFlowEnvelope"}}},"description":"Release evidence flow envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Start release evidence flow","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:read"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/security-summary":{"get":{"description":"Returns a tenant-scoped release security summary for review surfaces without raw evidence payload bytes.","operationId":"releaseSecuritySummary","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseSecuritySummaryEnvelope"}}},"description":"Release security summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release security summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-vulnerability-handling":{"get":{"description":"Returns a CRA-oriented vulnerability handling evidence report without legal compliance, certification, scanner-authority, or release-security conclusions.","operationId":"craVulnerabilityHandlingReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReportEnvelope"}}},"description":"CRA vulnerability handling report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA vulnerability handling report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/custody-review":{"get":{"description":"Returns tenant signing-provider and object-lock verification metadata for deployment custody review. It is evidence metadata only, not legal compliance proof, certification, HSM custody proof, or a secure-deployment guarantee.","operationId":"signingCustodyReviewReport","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningCustodyReviewReportEnvelope"}}},"description":"Signing custody review report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Signing custody review report","tags":["evydence"],"x-scopes":["keys:admin"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"examples":{"failed-readiness-with-gap":{"summary":"Readiness report with a vulnerability decision gap","value":{"data":{"accepted_exceptions":[],"assumptions":["Readiness is based on tenant evidence recorded in Evydence."],"blocking_findings":[{"component":"pkg:apk/openssl@3.1.0-r0","decision_state":"missing","finding_id":"scan_20260527120000:finding:1","release_id":"rel_20260527120000","scan_id":"scan_20260527120000","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"generated_at":"2026-05-27T12:00:00Z","limitations":["Readiness supports technical review and does not prove legal compliance, certification, complete vulnerability coverage, or release security."],"missing_evidence":["vulnerability_decision"],"policy_set":"policy-set.v1.0.0","product_id":"prod_20260527120000","release_id":"rel_20260527120000","report_type":"release_readiness","result":"failed","schema_version":"release-readiness.v1.0.0","summary":{"headline":"Release evidence has one blocking vulnerability decision gap.","human_summary":"Required artifact, SBOM, scan, build, and bundle evidence is present, but one critical finding still needs a valid decision or approved exception.","policy_set":"policy-set.v1.0.0","result":"failed"},"template_version":"release-readiness.v1.0.0"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/security-update-evidence":{"get":{"description":"Returns a security update evidence report for release-scoped fixed decisions, incidents, remediation tasks, and linked evidence without legal or security conclusions.","operationId":"securityUpdateEvidenceReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReportEnvelope"}}},"description":"Security update evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security update evidence report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"examples":{"cyclonedx-release-sbom":{"summary":"Upload a CycloneDX SBOM linked to the release artifact","value":{"artifact_id":"art_20260527120000","payload":{"bomFormat":"CycloneDX","components":[{"name":"payments-api","purl":"pkg:oci/payments-api@sha256-ca978112","version":"1.0.0-rc.1"},{"name":"openssl","purl":"pkg:apk/openssl@3.1.0-r0","version":"3.1.0-r0"}],"specVersion":"1.6"},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"examples":{"not-affected-decision":{"summary":"Record a customer-visible not-affected decision","value":{"customer_visible":true,"evidence_ids":["ev_20260527120000"],"impact_statement":"The shipped artifact does not include the affected runtime path.","justification":"The vulnerable code path is not reachable in this release.","status":"not_affected"}}},"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"examples":{"generic-critical-finding":{"summary":"Upload a generic scanner finding for release triage","value":{"findings":[{"component":"pkg:apk/openssl@3.1.0-r0","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"release_id":"rel_20260527120000","scanner":"generic-json","target_ref":"pkg:oci/payments-api@sha256-ca978112"}}},"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/site/package-viewer/index.html b/site/package-viewer/index.html index 7a0054d..a171590 100644 --- a/site/package-viewer/index.html +++ b/site/package-viewer/index.html @@ -360,7 +360,7 @@

Evydence Package Viewer

{ id: "vex_example", format: "openvex", author: "security@example.test", statement_count: 1, status_summary: { fixed: 1 } } ], vulnerability_decisions: [ - { id: "vd_example", vulnerability: "CVE-2026-0002", component: "pkg:apk/openssl@3.1.0", status: "fixed", source: "vex", impact_statement: "The finding is fixed in this release artifact.", action_statement: "Upgrade to this release after normal operator review." } + { id: "vd_example", vulnerability: "CVE-2026-0002", component: "pkg:apk/openssl@3.1.0", status: "fixed", source: "vex", impact_statement: "The finding is fixed in this release artifact.", action_statement: "Upgrade to this release after normal operator review.", reviewed_at: "2026-05-27T12:00:00Z", review_due_at: "2026-08-25T12:00:00Z" } ], approvals: [{ id: "appr_example", subject_type: "release", decision: "approved", reason: "Release evidence package reviewed." }], exceptions: [], @@ -608,6 +608,8 @@

Evydence Package Viewer

{ label: "Component", value: "component" }, { label: "Status", value: "status", badge: true }, { label: "Source", value: "source" }, + { label: "Reviewed", value: "reviewed_at" }, + { label: "Review due", value: "review_due_at" }, { label: "Impact", value: "impact_statement" }, { label: "Action", value: "action_statement" } ], decisions, "No active customer-visible decisions are present."); From d7e317ef47981805643640ef5896e6170d54d308 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 16:39:46 +0300 Subject: [PATCH 223/287] feat(risk): link decisions to sbom context --- .productization_next_steps_missing.md | 2 +- Makefile | 2 + docs/reference/customer-package-manifest.md | 4 +- docs/reference/vulnerability-decisions.md | 26 +++- .../sample-customer-package-manifest.json | 3 + .../sample-customer-package-manifest.sha256 | 2 +- .../sample-customer-package.zip | Bin 3500 -> 3529 bytes internal/adapters/httpapi/openapi.go | 88 +++++++------ internal/adapters/httpapi/router_test.go | 8 +- internal/adapters/postgres/store.go | 26 ++-- internal/adapters/postgres/store_test.go | 12 +- internal/app/customer_package_golden_test.go | 13 ++ internal/app/governance_packages.go | 27 ++-- internal/app/ledger_test.go | 25 ++++ internal/app/vex.go | 123 ++++++++++++------ internal/domain/domain.go | 88 +++++++------ ...lnerability_decision_sbom_context.down.sql | 8 ++ ...vulnerability_decision_sbom_context.up.sql | 8 ++ openapi.yaml | 2 +- site/package-viewer/index.html | 4 +- 20 files changed, 309 insertions(+), 162 deletions(-) create mode 100644 migrations/20260601000700_vulnerability_decision_sbom_context.down.sql create mode 100644 migrations/20260601000700_vulnerability_decision_sbom_context.up.sql diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index 7fc21e1..0ec8d1e 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -250,7 +250,7 @@ Implementation rules: - Update package/report tests. - Run `make openapi-check`, targeted app/API tests, and `make docs-check`. -### Ticket E3-T3 - Link decisions directly to source SBOM context [ ] +### Ticket E3-T3 - Link decisions directly to source SBOM context [x] Description: Add first-class linkage from a vulnerability decision or finding summary to the SBOM/component context that supported the answer, instead of diff --git a/Makefile b/Makefile index 65473be..68380a1 100644 --- a/Makefile +++ b/Makefile @@ -363,6 +363,7 @@ demo-check: ## Validate checked end-to-end evidence demo fixtures @grep -F 'not legal' examples/end-to-end-release-evidence/README.md >/dev/null @grep -F 'reviewer_checklist' examples/end-to-end-release-evidence/sample-customer-package-manifest.json >/dev/null @grep -F 'escalation_path' examples/end-to-end-release-evidence/sample-customer-package-manifest.json >/dev/null + @grep -F 'sbom_component_purl' examples/end-to-end-release-evidence/sample-customer-package-manifest.json >/dev/null black-box-demo-check: ## Run live PostgreSQL black-box API/worker demo; requires EVYDENCE_TEST_DATABASE_URL @scripts/black_box_demo_check.sh @@ -385,6 +386,7 @@ package-viewer-check: ## Validate local package viewer and walkthrough @grep -F 'Reviewer checklist' site/package-viewer/index.html >/dev/null @grep -F 'reviewer_checklist' site/package-viewer/index.html >/dev/null @grep -F 'review_due_at' site/package-viewer/index.html >/dev/null + @grep -F 'sbom_component_purl' site/package-viewer/index.html >/dev/null @grep -F 'examples/end-to-end-release-evidence/sample-customer-package-manifest.json' docs/how-to/view-packages.md >/dev/null @grep -F 'reviewer-journey.svg' docs/how-to/view-packages.md >/dev/null @grep -F 'hash/signature verification' docs/how-to/view-packages.md >/dev/null diff --git a/docs/reference/customer-package-manifest.md b/docs/reference/customer-package-manifest.md index 3efae7d..0fffc17 100644 --- a/docs/reference/customer-package-manifest.md +++ b/docs/reference/customer-package-manifest.md @@ -33,7 +33,9 @@ matching release-scoped records exist: - `vex_documents`: VEX metadata, statement counts, status summary, and evidence ID. - `vulnerability_decisions`: active customer-visible decision summaries only, including `reviewed_at` and optional `review_due_at` freshness metadata when - recorded. + recorded, plus safe `sbom_id`, `sbom_component_purl`, and + `sbom_component_name` context when a same-release SBOM component matched the + finding. - `api_contracts`: OpenAPI contract metadata, normalized operation summaries, deterministic contract diff results, and API-contract limitations. - `approvals`: release or product approval records. diff --git a/docs/reference/vulnerability-decisions.md b/docs/reference/vulnerability-decisions.md index 2b2d357..59bcfe4 100644 --- a/docs/reference/vulnerability-decisions.md +++ b/docs/reference/vulnerability-decisions.md @@ -27,6 +27,7 @@ finding: | Vulnerability ID | `vulnerability` is copied from the finding. | | Source scanner | Indirect through `scan_id`; scanner metadata is on the vulnerability scan. | | Affected component/package/PURL | `component` is copied from the finding. | +| Source SBOM context | `sbom_id`, `sbom_component_purl`, and `sbom_component_name` are populated when a same-release SBOM component matches the finding component. | | Product/release scope | `release_id` is copied from the scan; product scope is indirect through the release. | | Status | `affected`, `not_affected`, `fixed`, and `under_investigation`. | | Justification | Required for manual decisions and imported from VEX where available. | @@ -98,6 +99,19 @@ summaries and customer packages include `reviewed_at` and `review_due_at` when available. Reports state the limitation that these dates are tenant-supplied metadata and do not prove the vulnerability analysis is still correct. +## SBOM Context + +When a decision is created, Evydence searches tenant-owned SBOMs for the same +release. If an SBOM component PURL exactly matches the finding component, the +decision records `sbom_id`, `sbom_component_purl`, and `sbom_component_name`. +If no PURL match exists, Evydence falls back to an exact component name or +`name@version` match. Raw SBOM payload bytes are not copied into the decision or +customer package. + +The link is created only from same-tenant, same-release SBOM metadata already +stored in Evydence. If a matching SBOM is uploaded after a decision is created, +create a superseding decision to attach the new context. + Customer package manifests include only active decisions unless a future history-specific export is requested. @@ -185,19 +199,17 @@ yet the full buyer-facing VEX decision workflow: first-class non-evidence resources such as remediation tasks, approvals, exceptions, release bundles, or incident packages still need explicit link modeling or evidence wrappers before they can be attached directly. -- The source SBOM is indirect through release/artifact relationships rather - than a direct `sbom_id` link. +- The source SBOM context is direct when a same-release SBOM component matches + the finding component. More advanced multi-SBOM disambiguation remains future + work. ## Concrete Follow-Up Changes The productization backlog should add these changes in order: -1. Add first-class SBOM/component context links for decisions so reviewers do - not need to infer source component evidence through release/artifact - relationships. -2. Add first-class decision links for non-evidence resources that should not be +1. Add first-class decision links for non-evidence resources that should not be wrapped as evidence items. -3. Add package-specific customer decision exports that include active +2. Add package-specific customer decision exports that include active decisions, supporting links, assumptions, and limitations in one customer-safe view. diff --git a/examples/end-to-end-release-evidence/sample-customer-package-manifest.json b/examples/end-to-end-release-evidence/sample-customer-package-manifest.json index 48cb1e1..996a909 100644 --- a/examples/end-to-end-release-evidence/sample-customer-package-manifest.json +++ b/examples/end-to-end-release-evidence/sample-customer-package-manifest.json @@ -130,6 +130,9 @@ "release_id": "rel_example", "vulnerability": "CVE-2026-0002", "component": "pkg:apk/openssl@3.1.0", + "sbom_id": "sbom_example", + "sbom_component_purl": "pkg:apk/openssl@3.1.0", + "sbom_component_name": "openssl", "status": "fixed", "justification": "fixed_in_release", "impact_statement": "The finding is fixed in this release artifact.", diff --git a/examples/end-to-end-release-evidence/sample-customer-package-manifest.sha256 b/examples/end-to-end-release-evidence/sample-customer-package-manifest.sha256 index abfc9b6..f4125bd 100644 --- a/examples/end-to-end-release-evidence/sample-customer-package-manifest.sha256 +++ b/examples/end-to-end-release-evidence/sample-customer-package-manifest.sha256 @@ -1 +1 @@ -8910d32bc08b85b7a1da5945520851a7c45b6d0d6835dd1ceb7a65c4b9f47e72 sample-customer-package-manifest.json +54c940232b1989f44a89dc82a0a9513eb68dbe18119bd8073a0fbdaf06e102c0 sample-customer-package-manifest.json diff --git a/examples/end-to-end-release-evidence/sample-customer-package.zip b/examples/end-to-end-release-evidence/sample-customer-package.zip index 15a7cf3a46e1995d92f6d30da384db1ccb231efa..7d77c5d91195a89257599b04380da9bc82ba1fa3 100644 GIT binary patch delta 3220 zcmZuzcQhLc7f);=irSmjc(z&%HCm!d8?~vuYmb<138H3Ii5fvFs6At+iqs5!R%%nL zMvEGKYV$eoJMWM8o$sD=&%NjT?zw;b?yTe{a&`Wq z;hn)KlX{`|TIX)V zj;!PuN%t-dLvMoL?1K!Dr5MLi7d@jgQywMgzS|>Ah{Ry%6B$#R1d@-7kPZp`gCQkv z)cV)F{krw7m^CqJ*nZOS<<~O1J+x<`b>-(Rr7`qv7nC+o7|~>G^_96=_lAO3ql3{W zvuVtR6upY^b^ZC5A9urRV`f9WjCs^uzr6e2?wV}&ZT8*5DI~>jbB%c>Kx19tPEYk- z(AbS;K%&Vjaiw-?`V`;O&oBWd$clJqZXwbzy{XoVy7!Vju_dXPbcl>1YZXDWyq?+> zr)e7Q=Y9H>PaZ+)Uq4r<65pfI+Xx?|+A1>o1?FL!(lE|0J*}}ZcgXDzr6h=(Lc9wg zzXKoE+C!9O+_`*~xk>`SNI*w6#e z<1+SgOG24khLdv-eC0%D(4Z~Zt49Od?GertyOrmcJu`MtG3g6GS^M#<@yUANTNfy7 zX>BvfGlBTpmD+x|Z9*(7Q>N+QejuZm?R~L$Jms-YN$bW# z+cs+irFI-cFpq539Z+plCI-kM9jV_<9J@xzng5g+C_dd=dx(7@5pWS8w7(KzV`JQU z&2aE;mtt*8^r%a^M|0bp(93YWZK>{@Xk`~oM3^EbVMW_ofuik*W+rzOpwc1I_P3oWalvOfIARpRcm(o;6#A1gQSvAfy&FAr!(Ip)jbXd?|?ek z{X2CHVyK_b{gUa^y)C7p#Ml9ws44EgY}Fu;Mdp@i8N~fDZkmy5QdU~DfID02Pa=_e zPh*`CK|D%a8G?Pv%}4wOfO@n9B@2PHQ|R#fi&+Ehmo8F#GrNNU&*nq^N-9%?-vcXF z@8B)YlcYG>R?E)q#RM%SW>}rC(NRE(PXBpl<%Qo1jLzH-W#&8|)$N7+^!y#u+)ro- zF?%cA9Tr(6l2+d>4`Dw#>lq2zRe^4ujj zS9ryez1Nw#pT1|Pldk}wXbnOCi;FOhbdXVfF_ODw*Y8yx&h#U4B$0E(+0WH($iTZ> zUw|PpX?(g?99O^emn@(Bj&&yY^^{=BxV8`P+jiD+_meE4a$zNOcjyva_@o^IKn>4e zlUjYe++0>11(UEpPvEe_@&@drmykOm(sCyOoiM~}163Fs zwUav-b+|Wt*j^JP2FFzUkh7)<*QLxrj(6v`Q?MFJqR8bK`(!O^hAfno?kT@-L{gD= zj!YmF#mi#LX}_#ri{R7V9NROB9PksD%iS-@jS*K+glPu-3Zybo7dAkyHbpW=sh==7 z(#%iu-SL5GIwY9I?sndUbz1b6#u$<1@@p$nSfnF0qsNm{TH#*5Q>mLoH?mrObj4Y5 z53&le#WL|Pl+lJVlW>rPRNDIRqeSvciYFS84G{540g^-kV&W%*eSsy9*0T-uWk;_p z+#haHZUMEoLtRyG)r~wE%}(JVf2@`Ypkn{ zXuztduImaB-U?@Tuf{jA8ac76ETB!MN&V*$k?6l5nErOgNV+B7B`iy+1?}JsLmCZ7 z_+u6hU~x7g$WxSD-OCP991k?6&zqz2Gk!ec|G+TVgzS9!J7cc^%%rL5Y1vm;n9Cah ztpvFLxtSWhh0Do-GqMQR^KM-?`qf=+vIzj-VQiv+m&4Kh2O^YrK$;ROsl& zx3YQJ7Zm*=HuGq_pIkMz#H063O}-JS_*aU?6R{jb9PZ<=mY@f$D97P-6kX=v;|D_# z+41I5^XB>aDON(K*LlPVyW_);DCDI07L%3ZoQ@eDcg4RKahlZUZ~2@E|CDJsbJ6Xn z71YuZM=eibTOM6ezDsTZ(xx2wbh^_U#}Lmvb3`%Tojq+GKbg@qA&@$FHPPURsbjqm zut%HJrN&3Lta;NlqTa9E#+i0j%;D-OyPfSB_}@2wEbgu9B>)vba}&`(5cmy8TDl;) zNPLyMbzWK`i2;YZ`a(hny{0u4-!AAs$);tD7+V#ll*^J)3Au*R_o%&0tP8R&%uFsU z8O@k`d0o!!koROI@Wb&~HX3s~3&RlBX($oU{&OUVdr2k6+5}8Z7E8%4FevFAkShPy z->6*b34xVGXx);|z11V&ecCIoA^pYdr*Bqi?&Ir>RrT%oS7$e8e9EBT4-_UUN&*c; z-Ty>Xiw1T`ADGV)UsF}G<9z;{xrC@{fSsN02Q!V5hJ?6 zs)yL;+ov`iyi!XB)=%9>|3XF5vQegWfS>iDa%lMwcVExS(zoqM#OH299YtZa&A)9~ zrhc2T0HqA;lyJ_vfjFPhj?4h&=I1ylLu?o4MFg2eP!|3M-Z(zvL&O1D#TSQ0Pc!IG zm02sDCW5H@`I|Hr4e0nZD2fh4gp<9ZP(QkrYLEdRoC@K)AuKBx4Wi@K##`V&DR$TU zFQE~bb=rG}iRO%af6qClnCyeuQ26fvHLXXq9-Qg8-zi;yi6hMi=bQ8uy` zVGt5d!)Cej4RBPN`+OKC-gnu{={r ztd}3$+z>{7_Xo)XKljrPFz+0O4Az(wc7HXNMDW)mrteDk&cOuN-Ok-1W_3HmB)fli zu`*1u83Y6XYOj>;>X$Ww-qn5tl@1IIRC{yRs7sa}dI)*R@MewibL~cS6wu6zWBeGV zZPV&RbZ=FI4LC~-8eE>QuZF}>z1dquYhuysAUYdJZWtM~^*KU{1OF4wR#>yb{jzeX zKnHzb|M+^Qi|DJZhjQ$C5Wg8n(&9vI<&9Mi)KhM(ZhEJ*<@bz1Nb!q$?DIbSLw2(S zS^fw~PlE!%al^oZXzDH1&ot{d*VK|}93@2ArYdDUiK#l9%_x3@8W}5}xp2g7Y!8L0 z6;|D8cwj=E=_ev*WP~@*`E8J17TT!aTe__&SPIgIAxqp5KX(GY?wh{M)A{xTF1_4# z(D_ytmi`k;eVv(^#r&}=-$5??Vu!5=d9Ijas@mL>7#zOvo9)4Z`0DMK;KT>o> zBLLv-;N$M<0!J;-vvL1-O#lE@R|x$-VOO>Y7=&U3^K<__OjpxS8mkAEOf?5kmB+i4h`7h#Dm( zV+bLljObU3AQ&~C_wIV@-FMGkd+oEs#CYx^AaAyJ zURTer;75Fhj0N4q!@(fA(nnr0Kmqia!WH7UT&d`4Qje8(>(z}{7~ewZVK*eVb2$lt zd8&{m{Ft0gxA+)d??vCO^`)bLy6{YV&8F3Q6A^xLOs*yhOco8gA23gKuQ-Hppz2{8 zfI9-Wm13jU|5)*aYm67%l;_f%9*2v*F#z(x-MyTxH0kBrfwAdxx-Ay~PbLp&Kj?Y3 z#@3WSZ2Ob!uw*MAyDTYZ{4?e7Y$oT<_A@VM+dl?26ziTTIcMll!GU%Q%nam}o)}7| z!O{G^`9#5rEEsLgWk8No-HO;mS2L4Z&L#tRmXjV>r{m2t zKTAA*UE!QeM{JH(?pHhP-CBnY73=k*m%Vqo>bqM7qYMPS zQ}P3Rw>XN-YbA6Sk0TsVsRN3IZDj{Z*HsM^!vuXBIz;b|~lW8Xnq&8=D=^UVKz zJBvp-E~DnM)kH6}rCoA|h_koraLXm_t?fv4xLB`mkoI=g){c0{$iR?%*Hi4DIyj>g z-b=K5k}8raJpjTt{niZ4kP6g^#<&78UCUY57`S-c3SpHNm8;5HS`{{HeQ3%Nz;cvo z>^Gd#65RZYIgyQKL&-r{g{4;GNdXnVag^4M=ZiU*nxM5dI&!*OC(YT0P-&K2Zao1ecLjZ-Wo)A&20JVK&T=y5p2iHA; zvu%mjY#6z5E%L1Iee^vc`{XPI{oCJcWvq&mgO4wye~|Usfa*t-O>7~G^m$#0Mf<&{ z0cQ#WP9`2AJA+Cq{1v9FV0~8eQvilzTykKTT&+fi??&ug!yaim2d?MD|MtZP`HH^I zxGcj31$;6Y*{rSXBtX(iY7l2OonhlbL7(2nBxx?7NcY;6GSP$Hi#d)vCYs`Ft<_N6 ztjS&bgTBlbHO=6RBQ|8^PK!<`-C4;#Ig68lUa`+jzP_(fEKr(bXh5e&amtJJ%Ta?Y zT$X>>2^B$e%D6kNPEL-B@Q#DDPb6nqKF?4F{5F)Y*Ul#zne(&-)XL+BHRKo6S$WisumXGE*DW1JiOx6v-=AA=&LWV_M2bztA^*CxF1#^<-K5IkD zq)wjQqzog&Jf$aT*XFQ2$0@alhp7cayfKRPrPay2*8|y4db?w%WoG@oKL|sa-hBlO zM8cafQ0_YpRvpSS>|)qGmL%h*{Qalu`bb7;W5>a~MZ^8qD1^FshQ7^wP994u;Iygy z7A6`P>B+1tpk_o4v?rT47vLYthx$6t z55Jl6E4Zj{e;`oX1DfBD>NHpfhxKhF|Zb z1<6h)`trHb%4SK=aQ^N!igK|LV+f>ex!K!ame79_=oxiSV7mV8IH61{|K}e8ES07* zNo}_W2?;;20GQpvxAJY zrKU7h7yC;Ah|HRXXxC=%pVP|ijgJ@_5&YRo>)i>MTq2JsZ#<{anI&XPe3`T;ep7<9 zzbb8f!gco)H0f4_j4>QaoUsZ5agpW)N3SwLsPjA_@s!h%0W#cX2cd0FUno=lAxu)<*P9%c{ekQstRK*clf{Zi3| zxPV0=we%o$el)H&c1{SM!|g2#nj%YYJ0@TI#Eq|x4G~xkiV7Vct6pW{TY!bWbO-M- zqZRHI%xqiJxUQQvQUWAhNJ+j|@mD_0`CdR1CN6UUhcC;HnZdgu1}=c6Iy}2QbV3{Q zd7cUz>i0G42S{PyH&6MXw%sJ+fD$6&Ldp00f{M2jeuf3tYR(o*DZOOwsI6DG1j$aH zVZ+y=WQvUpO^xz$NzuXgJiIPK;=;E+kY}G})_}(y`i{@8dPYy!xxT`qhHR?7+sz&R z)(&j*E%ko;|K;AY0;U2{Wh60*1796zj+?vibsDK;7=A0`Uca{4CM@!ncInL9wSdg& zLJj_#Bcj2U3I~^d&W&Y9TW^|^8YD{wU1 z;t8kuI|~L8P`a%ex5a zSdV{{@YDnQUu4sd{G;1gYH)DDe;-h17LqLX;R|dIbgeB z>fuG6uBZ%_%HsTNb0%3rBBS6#`QliSNiO-WM-m~$;~bMg=C*J)QTXHHY!B>5e!Mky zwDgBoM-VO3aTmc|FrLGeRbnh8w_zs0R)^t7dB{UH&1Xyr{4Pei3>sC!D!g=eaL@a{ zFy7k7x7O>GMur_80a7(wIx37CDD>ry>VPbS9&?)tmF}i5n+1~-MqD>rTj<4=LF6qb z?r$zJg??z&P%p{tncsAkTQGCms&scw(g+%7DHI#8GDV}d5#l7ur2L+d#b{i6Q+4~u|$zfxbNp#p)PojdcnxHZ?&&^FSM^AGk{P1nG7Bf+#kBI$%?4**WO z(Ej4P!~3HKo&D0eshV`6OX3|hc}4AzcQJGAauiMh^}at1sN*~fh9v#xyyuy?mzEnG zR$6}8Jc!&E;;uud2zY$S*D$ipN=4RP?X{I$>hxHU!FhGpJ$&M9`22gUs2TM;mohK8 zitL@S_)RXa>_I%lQSIdSF9q6KFH3+GZ90>$A_I&S;>+wCiNcM~ouWz1ZzR%Cznkcy zL`)kRHm@p5H(J4`VQX4VL67%jD`H;|5~erbud6+M?6+~L=s<#egU0*QIPrK2DCcZG z%1cqYk!9m)&aI{o>9`hAMF{icx^h7i6J(vHYVVQrTz7vI^1t)jnpdJXDDp?yTZ!|D^rD_W;Y^*_#^B(f>O~ Ndu|)&@#TMt{|l2H-sS)R diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index b40b224..6d02b0a 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -305,51 +305,57 @@ func registerCriticalSchemas(registry *specs.Registry) { "review_due_at": map[string]any{"type": "string", "format": "date-time", "description": "Optional UTC time when this decision should be reviewed again."}, }, "status", "justification")) registry.RegisterSchema("VulnerabilityDecision", objectSchema(map[string]any{ - "id": map[string]any{"type": "string"}, - "tenant_id": map[string]any{"type": "string"}, - "finding_id": map[string]any{"type": "string"}, - "scan_id": map[string]any{"type": "string"}, - "release_id": map[string]any{"type": "string"}, - "vulnerability": map[string]any{"type": "string"}, - "component": map[string]any{"type": "string"}, - "status": map[string]any{"type": "string"}, - "justification": map[string]any{"type": "string"}, - "impact_statement": map[string]any{"type": "string"}, - "action_statement": map[string]any{"type": "string"}, - "customer_visible": map[string]any{"type": "boolean"}, - "internal_notes": map[string]any{"type": "string", "description": "Tenant-internal notes; do not include in customer-safe exports."}, - "source": map[string]any{"type": "string"}, - "evidence_id": map[string]any{"type": "string"}, - "evidence_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, - "vex_document_id": map[string]any{"type": "string"}, - "supersedes": map[string]any{"type": "string"}, - "superseded_by": map[string]any{"type": "string"}, - "approved_by": map[string]any{"type": "string"}, - "reviewed_at": map[string]any{"type": "string", "format": "date-time"}, - "review_due_at": map[string]any{"type": "string", "format": "date-time"}, - "schema_version": map[string]any{"type": "string"}, - "created_at": map[string]any{"type": "string", "format": "date-time"}, + "id": map[string]any{"type": "string"}, + "tenant_id": map[string]any{"type": "string"}, + "finding_id": map[string]any{"type": "string"}, + "scan_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "vulnerability": map[string]any{"type": "string"}, + "component": map[string]any{"type": "string"}, + "sbom_id": map[string]any{"type": "string", "description": "Same-release SBOM that contained the matched component, when available."}, + "sbom_component_purl": map[string]any{"type": "string"}, + "sbom_component_name": map[string]any{"type": "string"}, + "status": map[string]any{"type": "string"}, + "justification": map[string]any{"type": "string"}, + "impact_statement": map[string]any{"type": "string"}, + "action_statement": map[string]any{"type": "string"}, + "customer_visible": map[string]any{"type": "boolean"}, + "internal_notes": map[string]any{"type": "string", "description": "Tenant-internal notes; do not include in customer-safe exports."}, + "source": map[string]any{"type": "string"}, + "evidence_id": map[string]any{"type": "string"}, + "evidence_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "vex_document_id": map[string]any{"type": "string"}, + "supersedes": map[string]any{"type": "string"}, + "superseded_by": map[string]any{"type": "string"}, + "approved_by": map[string]any{"type": "string"}, + "reviewed_at": map[string]any{"type": "string", "format": "date-time"}, + "review_due_at": map[string]any{"type": "string", "format": "date-time"}, + "schema_version": map[string]any{"type": "string"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, }, "id", "tenant_id", "finding_id", "scan_id", "vulnerability", "status", "justification", "source", "schema_version", "created_at")) registry.RegisterSchema("VulnerabilityDecisionEnvelope", dataEnvelopeSchema("#/components/schemas/VulnerabilityDecision")) registry.RegisterSchema("VulnerabilityDecisionListEnvelope", dataArrayEnvelopeSchema("#/components/schemas/VulnerabilityDecision")) registry.RegisterSchema("VulnerabilityDecisionCustomerSummary", objectSchema(map[string]any{ - "id": map[string]any{"type": "string"}, - "finding_id": map[string]any{"type": "string"}, - "scan_id": map[string]any{"type": "string"}, - "release_id": map[string]any{"type": "string"}, - "vulnerability": map[string]any{"type": "string"}, - "component": map[string]any{"type": "string"}, - "status": map[string]any{"type": "string"}, - "justification": map[string]any{"type": "string"}, - "impact_statement": map[string]any{"type": "string"}, - "action_statement": map[string]any{"type": "string"}, - "source": map[string]any{"type": "string"}, - "evidence_id": map[string]any{"type": "string"}, - "evidence_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, - "vex_document_id": map[string]any{"type": "string"}, - "reviewed_at": map[string]any{"type": "string", "format": "date-time"}, - "review_due_at": map[string]any{"type": "string", "format": "date-time"}, - "created_at": map[string]any{"type": "string", "format": "date-time"}, + "id": map[string]any{"type": "string"}, + "finding_id": map[string]any{"type": "string"}, + "scan_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "vulnerability": map[string]any{"type": "string"}, + "component": map[string]any{"type": "string"}, + "sbom_id": map[string]any{"type": "string", "description": "Same-release SBOM that contained the matched component, when available."}, + "sbom_component_purl": map[string]any{"type": "string"}, + "sbom_component_name": map[string]any{"type": "string"}, + "status": map[string]any{"type": "string"}, + "justification": map[string]any{"type": "string"}, + "impact_statement": map[string]any{"type": "string"}, + "action_statement": map[string]any{"type": "string"}, + "source": map[string]any{"type": "string"}, + "evidence_id": map[string]any{"type": "string"}, + "evidence_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "vex_document_id": map[string]any{"type": "string"}, + "reviewed_at": map[string]any{"type": "string", "format": "date-time"}, + "review_due_at": map[string]any{"type": "string", "format": "date-time"}, + "created_at": map[string]any{"type": "string", "format": "date-time"}, }, "id", "finding_id", "scan_id", "release_id", "vulnerability", "status", "impact_statement", "source", "created_at")) registry.RegisterSchema("VulnerabilityDecisionSummaryReport", objectSchema(map[string]any{ "report_type": map[string]any{"type": "string"}, diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 7114ee5..bb25121 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -93,6 +93,10 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { if _, ok := decisionRequestProps["review_due_at"]; !ok { t.Fatalf("manual decision request schema missing review_due_at: %#v", decisionRequestProps) } + decisionProps := asStringAnyMap(t, asStringAnyMap(t, schemas["VulnerabilityDecision"])["properties"]) + if _, ok := decisionProps["sbom_component_purl"]; !ok { + t.Fatalf("decision schema missing sbom_component_purl: %#v", decisionProps) + } redactionRequestProps := asStringAnyMap(t, asStringAnyMap(t, schemas["CreateRedactionProfileRequest"])["properties"]) if _, ok := redactionRequestProps["preset"]; !ok { t.Fatalf("redaction profile request schema missing preset: %#v", redactionRequestProps) @@ -763,7 +767,7 @@ func TestReleaseRiskDecisionHTTPFlow(t *testing.T) { postJSON(t, server, secret, "/v1/vulnerability-findings/"+findingID+"/decisions", "risk-decision-bad", map[string]any{"status": "not_affected", "justification": "vulnerable code is not present", "customer_visible": true}, http.StatusBadRequest) decisionPayload := map[string]any{"status": "not_affected", "justification": "vulnerable code is not present", "impact_statement": "The vulnerable code path is not present in this release.", "customer_visible": true, "internal_notes": "private note", "evidence_ids": []string{evidenceID}, "reviewed_at": "2026-05-27T12:00:00Z", "review_due_at": "2026-08-25T12:00:00Z"} decisionBody := postJSON(t, server, secret, "/v1/vulnerability-findings/"+findingID+"/decisions", "risk-decision", decisionPayload, http.StatusCreated) - if !strings.Contains(decisionBody, `"customer_visible":true`) || !strings.Contains(decisionBody, `"internal_notes":"private note"`) || !strings.Contains(decisionBody, evidenceID) || !strings.Contains(decisionBody, `"review_due_at":"2026-08-25T12:00:00Z"`) { + if !strings.Contains(decisionBody, `"customer_visible":true`) || !strings.Contains(decisionBody, `"internal_notes":"private note"`) || !strings.Contains(decisionBody, evidenceID) || !strings.Contains(decisionBody, `"review_due_at":"2026-08-25T12:00:00Z"`) || !strings.Contains(decisionBody, `"sbom_component_purl":"pkg:apk/openssl@3.1.0"`) { t.Fatalf("decision response missing customer visibility/internal note fields: %s", decisionBody) } replayed := postJSON(t, server, secret, "/v1/vulnerability-findings/"+findingID+"/decisions", "risk-decision", decisionPayload, http.StatusCreated) @@ -778,7 +782,7 @@ func TestReleaseRiskDecisionHTTPFlow(t *testing.T) { getJSON(t, server, secret, "/v1/vulnerability-decisions?active=maybe", http.StatusBadRequest) getJSON(t, server, secret, "/v1/vulnerability-decisions?status=not_a_status", http.StatusBadRequest) summary := getJSON(t, server, secret, "/v1/reports/vulnerability-decision-summary?release_id="+releaseID, http.StatusOK) - if !strings.Contains(summary, `"report_type":"vulnerability_decision_summary"`) || !strings.Contains(summary, `"The vulnerable code path is not present in this release."`) || !strings.Contains(summary, `"reviewed_at":"2026-05-27T12:00:00Z"`) { + if !strings.Contains(summary, `"report_type":"vulnerability_decision_summary"`) || !strings.Contains(summary, `"The vulnerable code path is not present in this release."`) || !strings.Contains(summary, `"reviewed_at":"2026-05-27T12:00:00Z"`) || !strings.Contains(summary, `"sbom_component_purl":"pkg:apk/openssl@3.1.0"`) { t.Fatalf("decision summary missing customer-safe content: %s", summary) } if strings.Contains(summary, "private note") || strings.Contains(summary, "payload_ref") { diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index d512d06..7c97f08 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -1162,7 +1162,8 @@ func (s *Store) loadRelationalRiskDecisions(ctx context.Context, state *app.Pers decisionRows, err := s.pool.Query(ctx, ` SELECT id, tenant_id, finding_id, scan_id, release_id, vulnerability, - component, status, justification, impact_statement, action_statement, + component, sbom_id, sbom_component_purl, sbom_component_name, + status, justification, impact_statement, action_statement, customer_visible, internal_notes, source, evidence_id, evidence_ids, vex_document_id, supersedes, superseded_by, approved_by, reviewed_at, review_due_at, schema_version, created_at FROM vulnerability_decisions @@ -1173,11 +1174,11 @@ func (s *Store) loadRelationalRiskDecisions(ctx context.Context, state *app.Pers defer decisionRows.Close() for decisionRows.Next() { var decision domain.VulnerabilityDecision - var releaseID, component, impactStatement, actionStatement, internalNotes, evidenceID, vexDocumentID, supersedes, supersededBy, approvedBy sql.NullString + var releaseID, component, sbomID, sbomComponentPURL, sbomComponentName, impactStatement, actionStatement, internalNotes, evidenceID, vexDocumentID, supersedes, supersededBy, approvedBy sql.NullString var reviewedAt, reviewDueAt sql.NullTime if err := decisionRows.Scan( &decision.ID, &decision.TenantID, &decision.FindingID, &decision.ScanID, &releaseID, &decision.Vulnerability, - &component, &decision.Status, &decision.Justification, &impactStatement, &actionStatement, + &component, &sbomID, &sbomComponentPURL, &sbomComponentName, &decision.Status, &decision.Justification, &impactStatement, &actionStatement, &decision.CustomerVisible, &internalNotes, &decision.Source, &evidenceID, &decision.EvidenceIDs, &vexDocumentID, &supersedes, &supersededBy, &approvedBy, &reviewedAt, &reviewDueAt, &decision.SchemaVersion, &decision.CreatedAt, ); err != nil { @@ -1185,6 +1186,9 @@ func (s *Store) loadRelationalRiskDecisions(ctx context.Context, state *app.Pers } decision.ReleaseID = nullableSQLString(releaseID) decision.Component = nullableSQLString(component) + decision.SBOMID = nullableSQLString(sbomID) + decision.SBOMComponentPURL = nullableSQLString(sbomComponentPURL) + decision.SBOMComponentName = nullableSQLString(sbomComponentName) decision.ImpactStatement = nullableSQLString(impactStatement) decision.ActionStatement = nullableSQLString(actionStatement) decision.InternalNotes = nullableSQLString(internalNotes) @@ -3304,21 +3308,26 @@ func syncRiskBuildControlRows(ctx context.Context, tx pgx.Tx, state app.Persiste if _, err := tx.Exec(ctx, ` INSERT INTO vulnerability_decisions ( id, tenant_id, finding_id, scan_id, release_id, vulnerability, - component, status, justification, impact_statement, action_statement, + component, sbom_id, sbom_component_purl, sbom_component_name, + status, justification, impact_statement, action_statement, customer_visible, internal_notes, source, evidence_id, evidence_ids, vex_document_id, supersedes, superseded_by, approved_by, reviewed_at, review_due_at, schema_version, created_at ) VALUES ( $1, $2, $3, $4, $5, $6, - $7, $8, $9, $10, $11, - $12, $13, $14, $15, $16, - $17, $18, $19, $20, $21, $22, $23, $24 + $7, $8, $9, $10, + $11, $12, $13, $14, + $15, $16, $17, $18, $19, $20, + $21, $22, $23, $24, $25, $26, $27 ) ON CONFLICT (id) DO UPDATE SET superseded_by = EXCLUDED.superseded_by, approved_by = EXCLUDED.approved_by, reviewed_at = COALESCE(vulnerability_decisions.reviewed_at, EXCLUDED.reviewed_at), review_due_at = COALESCE(vulnerability_decisions.review_due_at, EXCLUDED.review_due_at), + sbom_id = COALESCE(NULLIF(vulnerability_decisions.sbom_id, ''), EXCLUDED.sbom_id), + sbom_component_purl = COALESCE(NULLIF(vulnerability_decisions.sbom_component_purl, ''), EXCLUDED.sbom_component_purl), + sbom_component_name = COALESCE(NULLIF(vulnerability_decisions.sbom_component_name, ''), EXCLUDED.sbom_component_name), customer_visible = vulnerability_decisions.customer_visible OR EXCLUDED.customer_visible, internal_notes = COALESCE(NULLIF(vulnerability_decisions.internal_notes, ''), EXCLUDED.internal_notes), evidence_ids = CASE @@ -3326,7 +3335,8 @@ func syncRiskBuildControlRows(ctx context.Context, tx pgx.Tx, state app.Persiste ELSE vulnerability_decisions.evidence_ids END `, decision.ID, decision.TenantID, decision.FindingID, decision.ScanID, nullableString(decision.ReleaseID), decision.Vulnerability, - nullableString(decision.Component), decision.Status, decision.Justification, nullableString(decision.ImpactStatement), nullableString(decision.ActionStatement), + nullableString(decision.Component), nullableString(decision.SBOMID), nullableString(decision.SBOMComponentPURL), nullableString(decision.SBOMComponentName), + decision.Status, decision.Justification, nullableString(decision.ImpactStatement), nullableString(decision.ActionStatement), decision.CustomerVisible, nullableString(decision.InternalNotes), decision.Source, nullableString(decision.EvidenceID), textArray(decision.EvidenceIDs), nullableString(decision.VEXDocumentID), nullableString(decision.Supersedes), nullableString(decision.SupersededBy), nullableString(decision.ApprovedBy), nullableTime(decision.ReviewedAt), nullableTime(decision.ReviewDueAt), decision.SchemaVersion, nonZeroTime(decision.CreatedAt)); err != nil { return fmt.Errorf("upsert vulnerability decision row: %w", err) diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index e461757..967ff0c 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -409,7 +409,7 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { "vex_report_test": {ID: "vex_report_test", TenantID: "ten_test", VEXDocumentID: "vex_test", EvidenceID: "ev_test", ReleaseID: "rel_test", ArtifactID: "art_test", ParserVersion: app.ParserVersionOpenVEXJSON, Status: "parsed", StatementCount: 1, DecisionsCreated: 1, MappingFailures: []domain.VEXImportIssue{{StatementIndex: 2, Code: "finding_not_found", Detail: "No matching finding."}}, SchemaVersion: domain.VEXImportReportSchemaVersion, CreatedAt: time.Now().UTC(), UpdatedAt: time.Now().UTC()}, }, Decisions: map[string]domain.VulnerabilityDecision{ - "decision_test": {ID: "decision_test", TenantID: "ten_test", FindingID: "finding_test", ScanID: "scan_test", ReleaseID: "rel_test", Vulnerability: "CVE-0000-0001", Component: "lib", Status: "not_affected", Justification: "not_present", Source: "manual", EvidenceID: "ev_test", VEXDocumentID: "vex_test", SchemaVersion: domain.VulnerabilityDecisionVersion, CreatedAt: time.Now().UTC()}, + "decision_test": {ID: "decision_test", TenantID: "ten_test", FindingID: "finding_test", ScanID: "scan_test", ReleaseID: "rel_test", Vulnerability: "CVE-0000-0001", Component: "lib", SBOMID: "sbom_test", SBOMComponentName: "lib", Status: "not_affected", Justification: "not_present", Source: "manual", EvidenceID: "ev_test", VEXDocumentID: "vex_test", SchemaVersion: domain.VulnerabilityDecisionVersion, CreatedAt: time.Now().UTC()}, }, Contracts: map[string]domain.OpenAPIContract{ "contract_test": {ID: "contract_test", TenantID: "ten_test", ProductID: "prod_test", ReleaseID: "rel_test", Version: "1.0.0", Hash: "sha256:" + strings.Repeat("f", 64), PathCount: 1, Operations: []domain.OpenAPIOperation{{Path: "/v1/test", Method: "get", OperationID: "getTest"}}, EvidenceID: "ev_test", CreatedAt: time.Now().UTC()}, @@ -635,7 +635,7 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { {name: "scan", query: `SELECT count(*) FROM vulnerability_scans WHERE tenant_id = 'ten_test' AND release_id = 'rel_test'`}, {name: "vex", query: `SELECT count(*) FROM vex_documents WHERE tenant_id = 'ten_test' AND id = 'vex_test' AND statement_count = 1`}, {name: "vex report", query: `SELECT count(*) FROM vex_import_reports WHERE tenant_id = 'ten_test' AND id = 'vex_report_test' AND decisions_created = 1`}, - {name: "decision", query: `SELECT count(*) FROM vulnerability_decisions WHERE tenant_id = 'ten_test' AND id = 'decision_test' AND status = 'not_affected'`}, + {name: "decision", query: `SELECT count(*) FROM vulnerability_decisions WHERE tenant_id = 'ten_test' AND id = 'decision_test' AND status = 'not_affected' AND sbom_id = 'sbom_test'`}, {name: "exception", query: `SELECT count(*) FROM exceptions WHERE tenant_id = 'ten_test' AND id = 'exception_test' AND approved = true`}, {name: "contract", query: `SELECT count(*) FROM openapi_contracts WHERE tenant_id = 'ten_test' AND id = 'contract_test' AND operations <> '[]'::jsonb`}, {name: "policy", query: `SELECT count(*) FROM policy_evaluations WHERE tenant_id = 'ten_test' AND id = 'policy_test'`}, @@ -932,7 +932,7 @@ func TestApplyCriticalMutationWithPostgres(t *testing.T) { }}, VulnerabilityDecisions: []domain.VulnerabilityDecision{{ ID: "decision_focus", TenantID: "ten_focus", FindingID: "finding_focus", ScanID: "scan_focus", - ReleaseID: "rel_focus", Vulnerability: "CVE-2099-0001", Component: "pkg:generic/api", + ReleaseID: "rel_focus", Vulnerability: "CVE-2099-0001", Component: "pkg:generic/api", SBOMID: "sbom_focus", SBOMComponentPURL: "pkg:generic/api", SBOMComponentName: "api", Status: "not_affected", Justification: "component_not_present", ImpactStatement: "not shipped", CustomerVisible: true, InternalNotes: "private triage", EvidenceIDs: []string{"ev_support"}, Source: "manual", SchemaVersion: domain.VulnerabilityDecisionVersion, CreatedAt: now, @@ -986,7 +986,7 @@ func TestApplyCriticalMutationWithPostgres(t *testing.T) { {name: "signature", query: `SELECT count(*) FROM signatures WHERE id = 'sig_focus' AND key_id = 'sigkey_focus'`}, {name: "bundle", query: `SELECT count(*) FROM release_bundles WHERE id = 'bundle_focus' AND signature_refs = '["sig_focus"]'::jsonb`}, {name: "verification", query: `SELECT count(*) FROM verification_results WHERE id = 'verify_focus' AND result = 'passed'`}, - {name: "decision", query: `SELECT count(*) FROM vulnerability_decisions WHERE id = 'decision_focus' AND status = 'not_affected' AND customer_visible = true AND internal_notes = 'private triage' AND evidence_ids = ARRAY['ev_support']::text[]`}, + {name: "decision", query: `SELECT count(*) FROM vulnerability_decisions WHERE id = 'decision_focus' AND status = 'not_affected' AND customer_visible = true AND internal_notes = 'private triage' AND evidence_ids = ARRAY['ev_support']::text[] AND sbom_component_purl = 'pkg:generic/api'`}, {name: "outbox", query: `SELECT count(*) FROM outbox_jobs WHERE id = 'job_focus' AND status = 'queued'`}, {name: "resource index", query: `SELECT count(*) FROM resource_index WHERE tenant_id = 'ten_focus' AND resource_type = 'release_bundle' AND resource_id = 'bundle_focus'`}, } @@ -1124,7 +1124,7 @@ func TestApplyReleaseLedgerMutationWithPostgres(t *testing.T) { }}, VulnerabilityDecisions: []domain.VulnerabilityDecision{{ ID: "decision_release_focus", TenantID: "ten_release_focus", FindingID: "finding_focus", ScanID: "scan_focus", - ReleaseID: "rel_focus", Vulnerability: "CVE-2099-0001", Component: "lib", Status: "not_affected", + ReleaseID: "rel_focus", Vulnerability: "CVE-2099-0001", Component: "lib", SBOMID: "sbom_focus", SBOMComponentName: "lib", Status: "not_affected", Justification: "component_not_present", Source: "vex", EvidenceID: "ev_focus", VEXDocumentID: "vex_focus", SchemaVersion: domain.VulnerabilityDecisionVersion, CreatedAt: now, }}, @@ -1168,7 +1168,7 @@ func TestApplyReleaseLedgerMutationWithPostgres(t *testing.T) { {name: "contract", query: `SELECT count(*) FROM openapi_contracts WHERE id = 'oas_focus' AND path_count = 1`}, {name: "vex", query: `SELECT count(*) FROM vex_documents WHERE id = 'vex_focus' AND statement_count = 1`}, {name: "vex report", query: `SELECT count(*) FROM vex_import_reports WHERE id = 'vex_report_focus' AND decisions_created = 1`}, - {name: "decision", query: `SELECT count(*) FROM vulnerability_decisions WHERE id = 'decision_release_focus' AND status = 'not_affected'`}, + {name: "decision", query: `SELECT count(*) FROM vulnerability_decisions WHERE id = 'decision_release_focus' AND status = 'not_affected' AND sbom_id = 'sbom_focus'`}, {name: "audit chain", query: `SELECT count(*) FROM audit_chain_entries WHERE id = 'chain_release_focus'`}, {name: "outbox", query: `SELECT count(*) FROM outbox_jobs WHERE id = 'job_release_focus' AND status = 'queued'`}, {name: "resource index", query: `SELECT count(*) FROM resource_index WHERE tenant_id = 'ten_release_focus' AND resource_type = 'evidence_item' AND resource_id = 'ev_focus'`}, diff --git a/internal/app/customer_package_golden_test.go b/internal/app/customer_package_golden_test.go index 9bc4f0b..4dd2fcd 100644 --- a/internal/app/customer_package_golden_test.go +++ b/internal/app/customer_package_golden_test.go @@ -68,4 +68,17 @@ func TestSampleCustomerPackageManifestGolden(t *testing.T) { t.Fatalf("manifest fixture reviewer checklist missing %q: %#v", id, checklist) } } + decisions, ok := manifest["vulnerability_decisions"].([]any) + if !ok || len(decisions) == 0 { + t.Fatalf("manifest fixture missing vulnerability decisions: %#v", manifest["vulnerability_decisions"]) + } + firstDecision, ok := decisions[0].(map[string]any) + if !ok { + t.Fatalf("manifest fixture decision is not an object: %#v", decisions[0]) + } + for _, key := range []string{"reviewed_at", "review_due_at", "sbom_id", "sbom_component_purl", "sbom_component_name"} { + if firstDecision[key] == "" || firstDecision[key] == nil { + t.Fatalf("manifest fixture decision missing %q: %#v", key, firstDecision) + } + } } diff --git a/internal/app/governance_packages.go b/internal/app/governance_packages.go index 8cec062..6b4f0b4 100644 --- a/internal/app/governance_packages.go +++ b/internal/app/governance_packages.go @@ -1401,9 +1401,9 @@ func customerPackageHTMLReport(pkg domain.CustomerSecurityPackage, metadata, ver b.WriteString("") } if len(decisions) > 0 { - b.WriteString("

Vulnerability Decisions

") + b.WriteString("

Vulnerability Decisions

VulnerabilityComponentStatusImpact StatementReviewedReview DueSource
") for _, record := range decisions { - b.WriteString("") + b.WriteString("") } b.WriteString("
VulnerabilityComponentSBOMStatusImpact StatementReviewedReview DueSource
" + packageHTMLEscape(packageHTMLString(record["vulnerability"])) + "" + packageHTMLEscape(packageHTMLString(record["component"])) + "" + packageHTMLEscape(packageHTMLString(record["status"])) + "" + packageHTMLEscape(packageHTMLString(record["impact_statement"])) + "" + packageHTMLEscape(packageHTMLString(record["reviewed_at"])) + "" + packageHTMLEscape(packageHTMLString(record["review_due_at"])) + "" + packageHTMLEscape(packageHTMLString(record["source"])) + "
" + packageHTMLEscape(packageHTMLString(record["vulnerability"])) + "" + packageHTMLEscape(packageHTMLString(record["component"])) + "" + packageHTMLEscape(packageHTMLString(record["sbom_id"])) + "" + packageHTMLEscape(packageHTMLString(record["status"])) + "" + packageHTMLEscape(packageHTMLString(record["impact_statement"])) + "" + packageHTMLEscape(packageHTMLString(record["reviewed_at"])) + "" + packageHTMLEscape(packageHTMLString(record["review_due_at"])) + "" + packageHTMLEscape(packageHTMLString(record["source"])) + "
") } @@ -1967,16 +1967,19 @@ func (l *Ledger) packageDecisionSummariesLocked(tenantID, releaseID string, prof continue } summary := map[string]any{ - "id": decision.ID, - "finding_id": decision.FindingID, - "scan_id": decision.ScanID, - "release_id": decision.ReleaseID, - "vulnerability": decision.Vulnerability, - "component": decision.Component, - "status": decision.Status, - "impact_statement": decision.ImpactStatement, - "source": decision.Source, - "created_at": decision.CreatedAt.UTC().Format(time.RFC3339), + "id": decision.ID, + "finding_id": decision.FindingID, + "scan_id": decision.ScanID, + "release_id": decision.ReleaseID, + "vulnerability": decision.Vulnerability, + "component": decision.Component, + "sbom_id": decision.SBOMID, + "sbom_component_purl": decision.SBOMComponentPURL, + "sbom_component_name": decision.SBOMComponentName, + "status": decision.Status, + "impact_statement": decision.ImpactStatement, + "source": decision.Source, + "created_at": decision.CreatedAt.UTC().Format(time.RFC3339), } if decision.ReviewedAt != nil && !excluded["reviewed_at"] { summary["reviewed_at"] = decision.ReviewedAt.UTC().Format(time.RFC3339) diff --git a/internal/app/ledger_test.go b/internal/app/ledger_test.go index 03d9bd5..8b09e57 100644 --- a/internal/app/ledger_test.go +++ b/internal/app/ledger_test.go @@ -822,6 +822,14 @@ func TestCustomerVisibleDecisionRequiresImpactAndRedactsInternalNotes(t *testing if err != nil { t.Fatalf("scan: %v", err) } + sbom, err := ledger.UploadSBOM(ctx, actor, release.ID, "", []byte(`{ + "bomFormat":"CycloneDX", + "specVersion":"1.6", + "components":[{"name":"openssl","version":"3.1.0","purl":"pkg:apk/openssl@3.1.0"}] + }`)) + if err != nil { + t.Fatalf("sbom: %v", err) + } if _, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{ Status: decisionStatusNotAffected, Justification: "runtime code path is not present", @@ -848,6 +856,9 @@ func TestCustomerVisibleDecisionRequiresImpactAndRedactsInternalNotes(t *testing if !decision.CustomerVisible || decision.InternalNotes != "private triage note" { t.Fatalf("decision customer visibility/internal notes not preserved: %#v", decision) } + if decision.SBOMID != sbom.ID || decision.SBOMComponentPURL != "pkg:apk/openssl@3.1.0" || decision.SBOMComponentName != "openssl" { + t.Fatalf("decision sbom context = %#v, want sbom %s openssl", decision, sbom.ID) + } profile, err := ledger.CreateRedactionProfile(ctx, actor, CreateRedactionProfileInput{Name: "customer decisions", AllowedTypes: []string{"vulnerability_decision"}}) if err != nil { t.Fatalf("redaction profile: %v", err) @@ -872,6 +883,9 @@ func TestCustomerVisibleDecisionRequiresImpactAndRedactsInternalNotes(t *testing if !strings.Contains(string(body), `"reviewed_at"`) || !strings.Contains(string(body), `"review_due_at"`) { t.Fatalf("package manifest missing decision freshness metadata: %s", body) } + if !strings.Contains(string(body), `"sbom_id"`) || !strings.Contains(string(body), sbom.ID) { + t.Fatalf("package manifest missing decision SBOM context: %s", body) + } if strings.Contains(string(body), "private triage note") { t.Fatalf("package manifest leaked internal notes: %s", body) } @@ -899,6 +913,14 @@ func TestVulnerabilityDecisionSummaryReportRedactsInternalAndOnlyIncludesActiveV if err != nil { t.Fatalf("scan: %v", err) } + sbom, err := ledger.UploadSBOM(ctx, actor, release.ID, "", []byte(`{ + "bomFormat":"CycloneDX", + "specVersion":"1.6", + "components":[{"name":"openssl","version":"3.1.0","purl":"pkg:apk/openssl@3.1.0"}] + }`)) + if err != nil { + t.Fatalf("summary sbom: %v", err) + } first, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{ Status: decisionStatusUnderInvestigation, Justification: "review started", @@ -956,6 +978,9 @@ func TestVulnerabilityDecisionSummaryReportRedactsInternalAndOnlyIncludesActiveV if got.ReviewedAt == nil || got.ReviewDueAt == nil || !got.ReviewedAt.Equal(reviewedAt) || !got.ReviewDueAt.Equal(reviewDueAt) { t.Fatalf("summary freshness metadata=%#v/%#v, want %#v/%#v", got.ReviewedAt, got.ReviewDueAt, reviewedAt, reviewDueAt) } + if got.SBOMID != sbom.ID || got.SBOMComponentPURL != "pkg:apk/openssl@3.1.0" { + t.Fatalf("summary SBOM context=%#v, want sbom %s", got, sbom.ID) + } body, err := json.Marshal(report) if err != nil { t.Fatalf("marshal summary: %v", err) diff --git a/internal/app/vex.go b/internal/app/vex.go index 236e25d..cbbc6e7 100644 --- a/internal/app/vex.go +++ b/internal/app/vex.go @@ -503,23 +503,26 @@ func (s releaseEvidenceService) VulnerabilityDecisionSummaryReport(ctx context.C func customerDecisionSummary(decision domain.VulnerabilityDecision) domain.VulnerabilityDecisionCustomerSummary { return domain.VulnerabilityDecisionCustomerSummary{ - ID: decision.ID, - FindingID: decision.FindingID, - ScanID: decision.ScanID, - ReleaseID: decision.ReleaseID, - Vulnerability: decision.Vulnerability, - Component: decision.Component, - Status: decision.Status, - Justification: decision.Justification, - ImpactStatement: decision.ImpactStatement, - ActionStatement: decision.ActionStatement, - Source: decision.Source, - EvidenceID: decision.EvidenceID, - EvidenceIDs: append([]string(nil), decision.EvidenceIDs...), - VEXDocumentID: decision.VEXDocumentID, - ReviewedAt: cloneTimePtr(decision.ReviewedAt), - ReviewDueAt: cloneTimePtr(decision.ReviewDueAt), - CreatedAt: decision.CreatedAt, + ID: decision.ID, + FindingID: decision.FindingID, + ScanID: decision.ScanID, + ReleaseID: decision.ReleaseID, + Vulnerability: decision.Vulnerability, + Component: decision.Component, + SBOMID: decision.SBOMID, + SBOMComponentPURL: decision.SBOMComponentPURL, + SBOMComponentName: decision.SBOMComponentName, + Status: decision.Status, + Justification: decision.Justification, + ImpactStatement: decision.ImpactStatement, + ActionStatement: decision.ActionStatement, + Source: decision.Source, + EvidenceID: decision.EvidenceID, + EvidenceIDs: append([]string(nil), decision.EvidenceIDs...), + VEXDocumentID: decision.VEXDocumentID, + ReviewedAt: cloneTimePtr(decision.ReviewedAt), + ReviewDueAt: cloneTimePtr(decision.ReviewDueAt), + CreatedAt: decision.CreatedAt, } } @@ -1111,6 +1114,7 @@ func openVEXProductIDs(products []openVEXProduct) map[string]struct{} { func (l *Ledger) createDecisionLocked(tenantID string, scan domain.VulnerabilityScan, finding domain.VulnerabilityFinding, in CreateVulnerabilityDecisionInput, source, actorID, evidenceID, vexID string) domain.VulnerabilityDecision { decisionID := newID("vd") createdAt := l.now() + sbomID, sbomComponentPURL, sbomComponentName := l.decisionSBOMContextLocked(tenantID, scan.ReleaseID, finding.Component) var supersedes string for id, existing := range l.decisions { if existing.TenantID == tenantID && existing.FindingID == finding.ID && existing.SupersededBy == "" { @@ -1120,33 +1124,72 @@ func (l *Ledger) createDecisionLocked(tenantID string, scan domain.Vulnerability } } decision := domain.VulnerabilityDecision{ - ID: decisionID, - TenantID: tenantID, - FindingID: finding.ID, - ScanID: scan.ID, - ReleaseID: scan.ReleaseID, - Vulnerability: finding.Vulnerability, - Component: finding.Component, - Status: strings.TrimSpace(in.Status), - Justification: strings.TrimSpace(in.Justification), - ImpactStatement: strings.TrimSpace(in.ImpactStatement), - ActionStatement: strings.TrimSpace(in.ActionStatement), - CustomerVisible: in.CustomerVisible, - InternalNotes: strings.TrimSpace(in.InternalNotes), - Source: source, - EvidenceID: evidenceID, - EvidenceIDs: decisionEvidenceIDs(evidenceID, in.EvidenceIDs), - VEXDocumentID: vexID, - Supersedes: supersedes, - ApprovedBy: actorID, - ReviewedAt: decisionReviewedAt(in.ReviewedAt, createdAt), - ReviewDueAt: cloneTimePtr(in.ReviewDueAt), - SchemaVersion: domain.VulnerabilityDecisionVersion, - CreatedAt: createdAt, + ID: decisionID, + TenantID: tenantID, + FindingID: finding.ID, + ScanID: scan.ID, + ReleaseID: scan.ReleaseID, + Vulnerability: finding.Vulnerability, + Component: finding.Component, + SBOMID: sbomID, + SBOMComponentPURL: sbomComponentPURL, + SBOMComponentName: sbomComponentName, + Status: strings.TrimSpace(in.Status), + Justification: strings.TrimSpace(in.Justification), + ImpactStatement: strings.TrimSpace(in.ImpactStatement), + ActionStatement: strings.TrimSpace(in.ActionStatement), + CustomerVisible: in.CustomerVisible, + InternalNotes: strings.TrimSpace(in.InternalNotes), + Source: source, + EvidenceID: evidenceID, + EvidenceIDs: decisionEvidenceIDs(evidenceID, in.EvidenceIDs), + VEXDocumentID: vexID, + Supersedes: supersedes, + ApprovedBy: actorID, + ReviewedAt: decisionReviewedAt(in.ReviewedAt, createdAt), + ReviewDueAt: cloneTimePtr(in.ReviewDueAt), + SchemaVersion: domain.VulnerabilityDecisionVersion, + CreatedAt: createdAt, } return decision } +func (l *Ledger) decisionSBOMContextLocked(tenantID, releaseID, findingComponent string) (string, string, string) { + findingComponent = strings.TrimSpace(findingComponent) + if releaseID == "" || findingComponent == "" { + return "", "", "" + } + sboms := make([]domain.SBOM, 0, len(l.sboms)) + for _, sbom := range l.sboms { + if sbom.TenantID == tenantID && sbom.ReleaseID == releaseID { + sboms = append(sboms, sbom) + } + } + sort.Slice(sboms, func(i, j int) bool { + if sboms[i].CreatedAt.Equal(sboms[j].CreatedAt) { + return sboms[i].ID < sboms[j].ID + } + return sboms[i].CreatedAt.Before(sboms[j].CreatedAt) + }) + for _, sbom := range sboms { + for _, component := range sbom.Components { + if strings.TrimSpace(component.PURL) != "" && strings.TrimSpace(component.PURL) == findingComponent { + return sbom.ID, strings.TrimSpace(component.PURL), strings.TrimSpace(component.Name) + } + } + } + for _, sbom := range sboms { + for _, component := range sbom.Components { + name := strings.TrimSpace(component.Name) + version := strings.TrimSpace(component.Version) + if name == findingComponent || (version != "" && name+"@"+version == findingComponent) { + return sbom.ID, strings.TrimSpace(component.PURL), name + } + } + } + return "", "", "" +} + func normalizeDecisionReviewTimes(in *CreateVulnerabilityDecisionInput, now time.Time) error { now = now.UTC() var reviewedAt time.Time diff --git a/internal/domain/domain.go b/internal/domain/domain.go index 853bb60..b5ae22a 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -1259,50 +1259,56 @@ type VEXImportReport struct { } type VulnerabilityDecision struct { - ID string `json:"id"` - TenantID string `json:"tenant_id"` - FindingID string `json:"finding_id"` - ScanID string `json:"scan_id"` - ReleaseID string `json:"release_id,omitempty"` - Vulnerability string `json:"vulnerability"` - Component string `json:"component,omitempty"` - Status string `json:"status"` - Justification string `json:"justification"` - ImpactStatement string `json:"impact_statement,omitempty"` - ActionStatement string `json:"action_statement,omitempty"` - CustomerVisible bool `json:"customer_visible"` - InternalNotes string `json:"internal_notes,omitempty"` - Source string `json:"source"` - EvidenceID string `json:"evidence_id,omitempty"` - EvidenceIDs []string `json:"evidence_ids,omitempty"` - VEXDocumentID string `json:"vex_document_id,omitempty"` - Supersedes string `json:"supersedes,omitempty"` - SupersededBy string `json:"superseded_by,omitempty"` - ApprovedBy string `json:"approved_by,omitempty"` - ReviewedAt *time.Time `json:"reviewed_at,omitempty"` - ReviewDueAt *time.Time `json:"review_due_at,omitempty"` - SchemaVersion string `json:"schema_version"` - CreatedAt time.Time `json:"created_at"` + ID string `json:"id"` + TenantID string `json:"tenant_id"` + FindingID string `json:"finding_id"` + ScanID string `json:"scan_id"` + ReleaseID string `json:"release_id,omitempty"` + Vulnerability string `json:"vulnerability"` + Component string `json:"component,omitempty"` + SBOMID string `json:"sbom_id,omitempty"` + SBOMComponentPURL string `json:"sbom_component_purl,omitempty"` + SBOMComponentName string `json:"sbom_component_name,omitempty"` + Status string `json:"status"` + Justification string `json:"justification"` + ImpactStatement string `json:"impact_statement,omitempty"` + ActionStatement string `json:"action_statement,omitempty"` + CustomerVisible bool `json:"customer_visible"` + InternalNotes string `json:"internal_notes,omitempty"` + Source string `json:"source"` + EvidenceID string `json:"evidence_id,omitempty"` + EvidenceIDs []string `json:"evidence_ids,omitempty"` + VEXDocumentID string `json:"vex_document_id,omitempty"` + Supersedes string `json:"supersedes,omitempty"` + SupersededBy string `json:"superseded_by,omitempty"` + ApprovedBy string `json:"approved_by,omitempty"` + ReviewedAt *time.Time `json:"reviewed_at,omitempty"` + ReviewDueAt *time.Time `json:"review_due_at,omitempty"` + SchemaVersion string `json:"schema_version"` + CreatedAt time.Time `json:"created_at"` } type VulnerabilityDecisionCustomerSummary struct { - ID string `json:"id"` - FindingID string `json:"finding_id"` - ScanID string `json:"scan_id"` - ReleaseID string `json:"release_id"` - Vulnerability string `json:"vulnerability"` - Component string `json:"component,omitempty"` - Status string `json:"status"` - Justification string `json:"justification,omitempty"` - ImpactStatement string `json:"impact_statement"` - ActionStatement string `json:"action_statement,omitempty"` - Source string `json:"source"` - EvidenceID string `json:"evidence_id,omitempty"` - EvidenceIDs []string `json:"evidence_ids,omitempty"` - VEXDocumentID string `json:"vex_document_id,omitempty"` - ReviewedAt *time.Time `json:"reviewed_at,omitempty"` - ReviewDueAt *time.Time `json:"review_due_at,omitempty"` - CreatedAt time.Time `json:"created_at"` + ID string `json:"id"` + FindingID string `json:"finding_id"` + ScanID string `json:"scan_id"` + ReleaseID string `json:"release_id"` + Vulnerability string `json:"vulnerability"` + Component string `json:"component,omitempty"` + SBOMID string `json:"sbom_id,omitempty"` + SBOMComponentPURL string `json:"sbom_component_purl,omitempty"` + SBOMComponentName string `json:"sbom_component_name,omitempty"` + Status string `json:"status"` + Justification string `json:"justification,omitempty"` + ImpactStatement string `json:"impact_statement"` + ActionStatement string `json:"action_statement,omitempty"` + Source string `json:"source"` + EvidenceID string `json:"evidence_id,omitempty"` + EvidenceIDs []string `json:"evidence_ids,omitempty"` + VEXDocumentID string `json:"vex_document_id,omitempty"` + ReviewedAt *time.Time `json:"reviewed_at,omitempty"` + ReviewDueAt *time.Time `json:"review_due_at,omitempty"` + CreatedAt time.Time `json:"created_at"` } type VulnerabilityDecisionSummaryReport struct { diff --git a/migrations/20260601000700_vulnerability_decision_sbom_context.down.sql b/migrations/20260601000700_vulnerability_decision_sbom_context.down.sql new file mode 100644 index 0000000..b758962 --- /dev/null +++ b/migrations/20260601000700_vulnerability_decision_sbom_context.down.sql @@ -0,0 +1,8 @@ +ALTER TABLE IF EXISTS vulnerability_decisions + DROP COLUMN IF EXISTS sbom_component_name; + +ALTER TABLE IF EXISTS vulnerability_decisions + DROP COLUMN IF EXISTS sbom_component_purl; + +ALTER TABLE IF EXISTS vulnerability_decisions + DROP COLUMN IF EXISTS sbom_id; diff --git a/migrations/20260601000700_vulnerability_decision_sbom_context.up.sql b/migrations/20260601000700_vulnerability_decision_sbom_context.up.sql new file mode 100644 index 0000000..620527b --- /dev/null +++ b/migrations/20260601000700_vulnerability_decision_sbom_context.up.sql @@ -0,0 +1,8 @@ +ALTER TABLE IF EXISTS vulnerability_decisions + ADD COLUMN IF NOT EXISTS sbom_id text; + +ALTER TABLE IF EXISTS vulnerability_decisions + ADD COLUMN IF NOT EXISTS sbom_component_purl text; + +ALTER TABLE IF EXISTS vulnerability_decisions + ADD COLUMN IF NOT EXISTS sbom_component_name text; diff --git a/openapi.yaml b/openapi.yaml index b3b4601..dccd2c3 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CRAVulnerabilityHandlingReport":{"additionalProperties":false,"properties":{"accepted_exceptions":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"CRAVulnerabilityHandlingReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"},"require_nda":{"type":"boolean"},"reviewer_email":{"description":"Optional external reviewer email label. It is not used as an authentication secret.","type":"string"},"reviewer_name":{"description":"Optional external reviewer display name for this package access record.","type":"string"},"watermark":{"description":"Optional customer-visible distribution watermark. It is not a token or secret.","type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireAnswerLibraryEntryRequest":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"}},"required":["answer"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"review_due_at":{"description":"Optional UTC time when this decision should be reviewed again.","format":"date-time","type":"string"},"reviewed_at":{"description":"Optional UTC time when the decision was reviewed. Defaults to creation time.","format":"date-time","type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccess":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"failed_access_count":{"type":"integer"},"id":{"type":"string"},"last_accessed_at":{"format":"date-time","type":"string"},"last_failed_at":{"format":"date-time","type":"string"},"nda_accepted_at":{"format":"date-time","type":"string"},"nda_accepted_by":{"type":"string"},"package_id":{"type":"string"},"prefix":{"description":"Non-secret portal token prefix for operational lookup.","type":"string"},"require_nda":{"type":"boolean"},"reviewer_email":{"type":"string"},"reviewer_name":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"watermark":{"type":"string"}},"required":["id","tenant_id","package_id","customer_name","prefix","expires_at","access_count","failed_access_count","schema_version","created_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"$ref":"#/components/schemas/CustomerPortalAccess"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalAccessEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccess"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CustomerPortalAccess"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"nda_accepted":{"description":"Set true to record acceptance for NDA-gated portal access.","type":"boolean"},"nda_accepted_by":{"description":"Reviewer label recorded when NDA acceptance is required. Do not include secrets.","type":"string"},"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"distribution_watermark":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"remediation":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntry":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","answer","schema_version","created_at"],"type":"object"},"QuestionnaireAnswerLibraryEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"policy_set":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlow":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["needs_evidence","ready_for_review"],"type":"string"},"steps":{"items":{"$ref":"#/components/schemas/ReleaseEvidenceFlowStep"},"type":"array"}},"required":["release_id","product_id","status","counts","steps","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseEvidenceFlowEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseEvidenceFlow"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlowStep":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"idempotency_required":{"type":"boolean"},"method":{"type":"string"},"next_reference":{"type":"string"},"path":{"type":"string"},"required":{"type":"boolean"},"required_scopes":{"items":{"type":"string"},"type":"array"},"status":{"enum":["present","missing","optional"],"type":"string"},"title":{"type":"string"}},"required":["id","title","status","required","method","path","required_scopes","idempotency_required","description"],"type":"object"},"ReleaseSecurityApprovalSummary":{"additionalProperties":false,"properties":{"approved":{"type":"integer"},"total":{"type":"integer"}},"required":["total","approved"],"type":"object"},"ReleaseSecurityExceptionSummary":{"additionalProperties":false,"properties":{"approved_unexpired":{"type":"integer"},"expired":{"type":"integer"},"total":{"type":"integer"},"unapproved":{"type":"integer"}},"required":["total","approved_unexpired","unapproved","expired"],"type":"object"},"ReleaseSecurityMissingDecision":{"additionalProperties":false,"properties":{"component":{"type":"string"},"finding_id":{"type":"string"},"scan_id":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["finding_id","scan_id","vulnerability","severity","state"],"type":"object"},"ReleaseSecurityProductSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"],"type":"object"},"ReleaseSecurityReleaseSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"state":{"type":"string"},"version":{"type":"string"}},"required":["id","version","state"],"type":"object"},"ReleaseSecuritySummary":{"additionalProperties":false,"properties":{"approval_summary":{"$ref":"#/components/schemas/ReleaseSecurityApprovalSummary"},"artifact_count":{"type":"integer"},"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"decisions_by_status":{"additionalProperties":{"type":"integer"},"type":"object"},"exception_summary":{"$ref":"#/components/schemas/ReleaseSecurityExceptionSummary"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_required_decisions":{"items":{"$ref":"#/components/schemas/ReleaseSecurityMissingDecision"},"type":"array"},"open_findings_by_severity":{"additionalProperties":{"type":"integer"},"type":"object"},"package_status":{"enum":["generated","not_generated"],"type":"string"},"product":{"$ref":"#/components/schemas/ReleaseSecurityProductSummary"},"readiness_status":{"enum":["passed","failed"],"type":"string"},"release":{"$ref":"#/components/schemas/ReleaseSecurityReleaseSummary"},"sbom_status":{"enum":["present","missing"],"type":"string"},"schema_version":{"type":"string"},"vulnerability_scan_status":{"enum":["present","missing"],"type":"string"}},"required":["product","release","artifact_count","sbom_status","vulnerability_scan_status","open_findings_by_severity","decisions_by_status","approval_summary","exception_summary","readiness_status","package_status","counts","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseSecuritySummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseSecuritySummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityUpdateEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"fixed_decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incidents":{"items":{"$ref":"#/components/schemas/Incident"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"remediation_tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"SecurityUpdateEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningCustodyReviewReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"object_retention_policies":{"items":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"type":"array"},"report_type":{"type":"string"},"signing_providers":{"items":{"$ref":"#/components/schemas/SigningProvider"},"type":"array"},"tenant_id":{"type":"string"}},"required":["report_type","tenant_id","checks","assumptions","limitations","generated_at"],"type":"object"},"SigningCustodyReviewReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningCustodyReviewReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"review_due_at":{"format":"date-time","type":"string"},"reviewed_at":{"format":"date-time","type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"review_due_at":{"format":"date-time","type":"string"},"reviewed_at":{"format":"date-time","type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"examples":{"release-evidence-package":{"summary":"Create a scoped release evidence package","value":{"expires_at":"2026-06-30T00:00:00Z","product_id":"prod_20260527120000","redaction_profile_id":"rp_20260527120000","release_id":"rel_20260527120000","title":"Payments API 1.0.0 release evidence package"}}},"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"get":{"description":"Lists tenant-scoped external reviewer access records without token hashes or token secrets.","operationId":"listCustomerPortalAccess","parameters":[{"description":"Optional customer package id filter.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessListEnvelope"}}},"description":"Customer portal access list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List customer portal access records","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a named, expiring external reviewer access record for a customer package and returns the portal token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/access/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped external reviewer access record; revocation is append-only and the original token cannot be used afterwards.","operationId":"revokeCustomerPortalAccess","parameters":[{"description":"Customer portal access id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessEnvelope"}}},"description":"Revoked customer portal access envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-answer-library":{"get":{"description":"Lists tenant-scoped questionnaire answer library entries with optional question, product, and release filters.","operationId":"listQuestionnaireAnswerLibrary","parameters":[{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by questionnaire question id.","in":"query","name":"question_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryListEnvelope"}}},"description":"Questionnaire answer library entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List questionnaire answer library entries","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a tenant-scoped reusable questionnaire answer draft linked to optional evidence, product, release, or control scope.","operationId":"createQuestionnaireAnswerLibraryEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireAnswerLibraryEntryRequest"}}},"description":"Questionnaire answer library entry creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryEnvelope"}}},"description":"Created questionnaire answer library entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire answer library entry","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"examples":{"release-candidate":{"summary":"Create a release for evidence collection","value":{"product_id":"prod_20260527120000","project_id":"proj_20260527120000","version":"1.0.0-rc.1"}}},"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"examples":{"created-release":{"summary":"Created release response","value":{"data":{"created_at":"2026-05-27T12:00:00Z","id":"rel_20260527120000","product_id":"prod_20260527120000","project_id":"proj_20260527120000","schema_version":"release.v1.0.0","status":"draft","tenant_id":"ten_20260527120000","version":"1.0.0-rc.1"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/evidence-flow/start":{"post":{"description":"Returns a high-level release evidence workflow plan, current evidence counts, required scopes, assumptions, and limitations. This read-only convenience operation does not create evidence.","operationId":"startReleaseEvidenceFlow","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEvidenceFlowEnvelope"}}},"description":"Release evidence flow envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Start release evidence flow","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:read"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/security-summary":{"get":{"description":"Returns a tenant-scoped release security summary for review surfaces without raw evidence payload bytes.","operationId":"releaseSecuritySummary","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseSecuritySummaryEnvelope"}}},"description":"Release security summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release security summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-vulnerability-handling":{"get":{"description":"Returns a CRA-oriented vulnerability handling evidence report without legal compliance, certification, scanner-authority, or release-security conclusions.","operationId":"craVulnerabilityHandlingReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReportEnvelope"}}},"description":"CRA vulnerability handling report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA vulnerability handling report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/custody-review":{"get":{"description":"Returns tenant signing-provider and object-lock verification metadata for deployment custody review. It is evidence metadata only, not legal compliance proof, certification, HSM custody proof, or a secure-deployment guarantee.","operationId":"signingCustodyReviewReport","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningCustodyReviewReportEnvelope"}}},"description":"Signing custody review report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Signing custody review report","tags":["evydence"],"x-scopes":["keys:admin"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"examples":{"failed-readiness-with-gap":{"summary":"Readiness report with a vulnerability decision gap","value":{"data":{"accepted_exceptions":[],"assumptions":["Readiness is based on tenant evidence recorded in Evydence."],"blocking_findings":[{"component":"pkg:apk/openssl@3.1.0-r0","decision_state":"missing","finding_id":"scan_20260527120000:finding:1","release_id":"rel_20260527120000","scan_id":"scan_20260527120000","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"generated_at":"2026-05-27T12:00:00Z","limitations":["Readiness supports technical review and does not prove legal compliance, certification, complete vulnerability coverage, or release security."],"missing_evidence":["vulnerability_decision"],"policy_set":"policy-set.v1.0.0","product_id":"prod_20260527120000","release_id":"rel_20260527120000","report_type":"release_readiness","result":"failed","schema_version":"release-readiness.v1.0.0","summary":{"headline":"Release evidence has one blocking vulnerability decision gap.","human_summary":"Required artifact, SBOM, scan, build, and bundle evidence is present, but one critical finding still needs a valid decision or approved exception.","policy_set":"policy-set.v1.0.0","result":"failed"},"template_version":"release-readiness.v1.0.0"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/security-update-evidence":{"get":{"description":"Returns a security update evidence report for release-scoped fixed decisions, incidents, remediation tasks, and linked evidence without legal or security conclusions.","operationId":"securityUpdateEvidenceReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReportEnvelope"}}},"description":"Security update evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security update evidence report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"examples":{"cyclonedx-release-sbom":{"summary":"Upload a CycloneDX SBOM linked to the release artifact","value":{"artifact_id":"art_20260527120000","payload":{"bomFormat":"CycloneDX","components":[{"name":"payments-api","purl":"pkg:oci/payments-api@sha256-ca978112","version":"1.0.0-rc.1"},{"name":"openssl","purl":"pkg:apk/openssl@3.1.0-r0","version":"3.1.0-r0"}],"specVersion":"1.6"},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"examples":{"not-affected-decision":{"summary":"Record a customer-visible not-affected decision","value":{"customer_visible":true,"evidence_ids":["ev_20260527120000"],"impact_statement":"The shipped artifact does not include the affected runtime path.","justification":"The vulnerable code path is not reachable in this release.","status":"not_affected"}}},"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"examples":{"generic-critical-finding":{"summary":"Upload a generic scanner finding for release triage","value":{"findings":[{"component":"pkg:apk/openssl@3.1.0-r0","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"release_id":"rel_20260527120000","scanner":"generic-json","target_ref":"pkg:oci/payments-api@sha256-ca978112"}}},"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CRAVulnerabilityHandlingReport":{"additionalProperties":false,"properties":{"accepted_exceptions":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"CRAVulnerabilityHandlingReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"},"require_nda":{"type":"boolean"},"reviewer_email":{"description":"Optional external reviewer email label. It is not used as an authentication secret.","type":"string"},"reviewer_name":{"description":"Optional external reviewer display name for this package access record.","type":"string"},"watermark":{"description":"Optional customer-visible distribution watermark. It is not a token or secret.","type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireAnswerLibraryEntryRequest":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"}},"required":["answer"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"review_due_at":{"description":"Optional UTC time when this decision should be reviewed again.","format":"date-time","type":"string"},"reviewed_at":{"description":"Optional UTC time when the decision was reviewed. Defaults to creation time.","format":"date-time","type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccess":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"failed_access_count":{"type":"integer"},"id":{"type":"string"},"last_accessed_at":{"format":"date-time","type":"string"},"last_failed_at":{"format":"date-time","type":"string"},"nda_accepted_at":{"format":"date-time","type":"string"},"nda_accepted_by":{"type":"string"},"package_id":{"type":"string"},"prefix":{"description":"Non-secret portal token prefix for operational lookup.","type":"string"},"require_nda":{"type":"boolean"},"reviewer_email":{"type":"string"},"reviewer_name":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"watermark":{"type":"string"}},"required":["id","tenant_id","package_id","customer_name","prefix","expires_at","access_count","failed_access_count","schema_version","created_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"$ref":"#/components/schemas/CustomerPortalAccess"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalAccessEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccess"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CustomerPortalAccess"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"nda_accepted":{"description":"Set true to record acceptance for NDA-gated portal access.","type":"boolean"},"nda_accepted_by":{"description":"Reviewer label recorded when NDA acceptance is required. Do not include secrets.","type":"string"},"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"distribution_watermark":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"remediation":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntry":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","answer","schema_version","created_at"],"type":"object"},"QuestionnaireAnswerLibraryEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"policy_set":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlow":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["needs_evidence","ready_for_review"],"type":"string"},"steps":{"items":{"$ref":"#/components/schemas/ReleaseEvidenceFlowStep"},"type":"array"}},"required":["release_id","product_id","status","counts","steps","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseEvidenceFlowEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseEvidenceFlow"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlowStep":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"idempotency_required":{"type":"boolean"},"method":{"type":"string"},"next_reference":{"type":"string"},"path":{"type":"string"},"required":{"type":"boolean"},"required_scopes":{"items":{"type":"string"},"type":"array"},"status":{"enum":["present","missing","optional"],"type":"string"},"title":{"type":"string"}},"required":["id","title","status","required","method","path","required_scopes","idempotency_required","description"],"type":"object"},"ReleaseSecurityApprovalSummary":{"additionalProperties":false,"properties":{"approved":{"type":"integer"},"total":{"type":"integer"}},"required":["total","approved"],"type":"object"},"ReleaseSecurityExceptionSummary":{"additionalProperties":false,"properties":{"approved_unexpired":{"type":"integer"},"expired":{"type":"integer"},"total":{"type":"integer"},"unapproved":{"type":"integer"}},"required":["total","approved_unexpired","unapproved","expired"],"type":"object"},"ReleaseSecurityMissingDecision":{"additionalProperties":false,"properties":{"component":{"type":"string"},"finding_id":{"type":"string"},"scan_id":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["finding_id","scan_id","vulnerability","severity","state"],"type":"object"},"ReleaseSecurityProductSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"],"type":"object"},"ReleaseSecurityReleaseSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"state":{"type":"string"},"version":{"type":"string"}},"required":["id","version","state"],"type":"object"},"ReleaseSecuritySummary":{"additionalProperties":false,"properties":{"approval_summary":{"$ref":"#/components/schemas/ReleaseSecurityApprovalSummary"},"artifact_count":{"type":"integer"},"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"decisions_by_status":{"additionalProperties":{"type":"integer"},"type":"object"},"exception_summary":{"$ref":"#/components/schemas/ReleaseSecurityExceptionSummary"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_required_decisions":{"items":{"$ref":"#/components/schemas/ReleaseSecurityMissingDecision"},"type":"array"},"open_findings_by_severity":{"additionalProperties":{"type":"integer"},"type":"object"},"package_status":{"enum":["generated","not_generated"],"type":"string"},"product":{"$ref":"#/components/schemas/ReleaseSecurityProductSummary"},"readiness_status":{"enum":["passed","failed"],"type":"string"},"release":{"$ref":"#/components/schemas/ReleaseSecurityReleaseSummary"},"sbom_status":{"enum":["present","missing"],"type":"string"},"schema_version":{"type":"string"},"vulnerability_scan_status":{"enum":["present","missing"],"type":"string"}},"required":["product","release","artifact_count","sbom_status","vulnerability_scan_status","open_findings_by_severity","decisions_by_status","approval_summary","exception_summary","readiness_status","package_status","counts","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseSecuritySummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseSecuritySummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityUpdateEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"fixed_decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incidents":{"items":{"$ref":"#/components/schemas/Incident"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"remediation_tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"SecurityUpdateEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningCustodyReviewReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"object_retention_policies":{"items":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"type":"array"},"report_type":{"type":"string"},"signing_providers":{"items":{"$ref":"#/components/schemas/SigningProvider"},"type":"array"},"tenant_id":{"type":"string"}},"required":["report_type","tenant_id","checks","assumptions","limitations","generated_at"],"type":"object"},"SigningCustodyReviewReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningCustodyReviewReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"review_due_at":{"format":"date-time","type":"string"},"reviewed_at":{"format":"date-time","type":"string"},"sbom_component_name":{"type":"string"},"sbom_component_purl":{"type":"string"},"sbom_id":{"description":"Same-release SBOM that contained the matched component, when available.","type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"review_due_at":{"format":"date-time","type":"string"},"reviewed_at":{"format":"date-time","type":"string"},"sbom_component_name":{"type":"string"},"sbom_component_purl":{"type":"string"},"sbom_id":{"description":"Same-release SBOM that contained the matched component, when available.","type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"examples":{"release-evidence-package":{"summary":"Create a scoped release evidence package","value":{"expires_at":"2026-06-30T00:00:00Z","product_id":"prod_20260527120000","redaction_profile_id":"rp_20260527120000","release_id":"rel_20260527120000","title":"Payments API 1.0.0 release evidence package"}}},"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"get":{"description":"Lists tenant-scoped external reviewer access records without token hashes or token secrets.","operationId":"listCustomerPortalAccess","parameters":[{"description":"Optional customer package id filter.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessListEnvelope"}}},"description":"Customer portal access list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List customer portal access records","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a named, expiring external reviewer access record for a customer package and returns the portal token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/access/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped external reviewer access record; revocation is append-only and the original token cannot be used afterwards.","operationId":"revokeCustomerPortalAccess","parameters":[{"description":"Customer portal access id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessEnvelope"}}},"description":"Revoked customer portal access envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-answer-library":{"get":{"description":"Lists tenant-scoped questionnaire answer library entries with optional question, product, and release filters.","operationId":"listQuestionnaireAnswerLibrary","parameters":[{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by questionnaire question id.","in":"query","name":"question_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryListEnvelope"}}},"description":"Questionnaire answer library entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List questionnaire answer library entries","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a tenant-scoped reusable questionnaire answer draft linked to optional evidence, product, release, or control scope.","operationId":"createQuestionnaireAnswerLibraryEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireAnswerLibraryEntryRequest"}}},"description":"Questionnaire answer library entry creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryEnvelope"}}},"description":"Created questionnaire answer library entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire answer library entry","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"examples":{"release-candidate":{"summary":"Create a release for evidence collection","value":{"product_id":"prod_20260527120000","project_id":"proj_20260527120000","version":"1.0.0-rc.1"}}},"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"examples":{"created-release":{"summary":"Created release response","value":{"data":{"created_at":"2026-05-27T12:00:00Z","id":"rel_20260527120000","product_id":"prod_20260527120000","project_id":"proj_20260527120000","schema_version":"release.v1.0.0","status":"draft","tenant_id":"ten_20260527120000","version":"1.0.0-rc.1"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/evidence-flow/start":{"post":{"description":"Returns a high-level release evidence workflow plan, current evidence counts, required scopes, assumptions, and limitations. This read-only convenience operation does not create evidence.","operationId":"startReleaseEvidenceFlow","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEvidenceFlowEnvelope"}}},"description":"Release evidence flow envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Start release evidence flow","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:read"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/security-summary":{"get":{"description":"Returns a tenant-scoped release security summary for review surfaces without raw evidence payload bytes.","operationId":"releaseSecuritySummary","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseSecuritySummaryEnvelope"}}},"description":"Release security summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release security summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-vulnerability-handling":{"get":{"description":"Returns a CRA-oriented vulnerability handling evidence report without legal compliance, certification, scanner-authority, or release-security conclusions.","operationId":"craVulnerabilityHandlingReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReportEnvelope"}}},"description":"CRA vulnerability handling report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA vulnerability handling report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/custody-review":{"get":{"description":"Returns tenant signing-provider and object-lock verification metadata for deployment custody review. It is evidence metadata only, not legal compliance proof, certification, HSM custody proof, or a secure-deployment guarantee.","operationId":"signingCustodyReviewReport","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningCustodyReviewReportEnvelope"}}},"description":"Signing custody review report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Signing custody review report","tags":["evydence"],"x-scopes":["keys:admin"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"examples":{"failed-readiness-with-gap":{"summary":"Readiness report with a vulnerability decision gap","value":{"data":{"accepted_exceptions":[],"assumptions":["Readiness is based on tenant evidence recorded in Evydence."],"blocking_findings":[{"component":"pkg:apk/openssl@3.1.0-r0","decision_state":"missing","finding_id":"scan_20260527120000:finding:1","release_id":"rel_20260527120000","scan_id":"scan_20260527120000","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"generated_at":"2026-05-27T12:00:00Z","limitations":["Readiness supports technical review and does not prove legal compliance, certification, complete vulnerability coverage, or release security."],"missing_evidence":["vulnerability_decision"],"policy_set":"policy-set.v1.0.0","product_id":"prod_20260527120000","release_id":"rel_20260527120000","report_type":"release_readiness","result":"failed","schema_version":"release-readiness.v1.0.0","summary":{"headline":"Release evidence has one blocking vulnerability decision gap.","human_summary":"Required artifact, SBOM, scan, build, and bundle evidence is present, but one critical finding still needs a valid decision or approved exception.","policy_set":"policy-set.v1.0.0","result":"failed"},"template_version":"release-readiness.v1.0.0"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/security-update-evidence":{"get":{"description":"Returns a security update evidence report for release-scoped fixed decisions, incidents, remediation tasks, and linked evidence without legal or security conclusions.","operationId":"securityUpdateEvidenceReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReportEnvelope"}}},"description":"Security update evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security update evidence report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"examples":{"cyclonedx-release-sbom":{"summary":"Upload a CycloneDX SBOM linked to the release artifact","value":{"artifact_id":"art_20260527120000","payload":{"bomFormat":"CycloneDX","components":[{"name":"payments-api","purl":"pkg:oci/payments-api@sha256-ca978112","version":"1.0.0-rc.1"},{"name":"openssl","purl":"pkg:apk/openssl@3.1.0-r0","version":"3.1.0-r0"}],"specVersion":"1.6"},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"examples":{"not-affected-decision":{"summary":"Record a customer-visible not-affected decision","value":{"customer_visible":true,"evidence_ids":["ev_20260527120000"],"impact_statement":"The shipped artifact does not include the affected runtime path.","justification":"The vulnerable code path is not reachable in this release.","status":"not_affected"}}},"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"examples":{"generic-critical-finding":{"summary":"Upload a generic scanner finding for release triage","value":{"findings":[{"component":"pkg:apk/openssl@3.1.0-r0","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"release_id":"rel_20260527120000","scanner":"generic-json","target_ref":"pkg:oci/payments-api@sha256-ca978112"}}},"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/site/package-viewer/index.html b/site/package-viewer/index.html index a171590..9bd5159 100644 --- a/site/package-viewer/index.html +++ b/site/package-viewer/index.html @@ -360,7 +360,7 @@

Evydence Package Viewer

{ id: "vex_example", format: "openvex", author: "security@example.test", statement_count: 1, status_summary: { fixed: 1 } } ], vulnerability_decisions: [ - { id: "vd_example", vulnerability: "CVE-2026-0002", component: "pkg:apk/openssl@3.1.0", status: "fixed", source: "vex", impact_statement: "The finding is fixed in this release artifact.", action_statement: "Upgrade to this release after normal operator review.", reviewed_at: "2026-05-27T12:00:00Z", review_due_at: "2026-08-25T12:00:00Z" } + { id: "vd_example", vulnerability: "CVE-2026-0002", component: "pkg:apk/openssl@3.1.0", sbom_id: "sbom_example", sbom_component_purl: "pkg:apk/openssl@3.1.0", sbom_component_name: "openssl", status: "fixed", source: "vex", impact_statement: "The finding is fixed in this release artifact.", action_statement: "Upgrade to this release after normal operator review.", reviewed_at: "2026-05-27T12:00:00Z", review_due_at: "2026-08-25T12:00:00Z" } ], approvals: [{ id: "appr_example", subject_type: "release", decision: "approved", reason: "Release evidence package reviewed." }], exceptions: [], @@ -606,6 +606,8 @@

Evydence Package Viewer

table(nodes.risk, [ { label: "Vulnerability", value: "vulnerability" }, { label: "Component", value: "component" }, + { label: "SBOM", value: "sbom_id" }, + { label: "SBOM PURL", value: "sbom_component_purl" }, { label: "Status", value: "status", badge: true }, { label: "Source", value: "source" }, { label: "Reviewed", value: "reviewed_at" }, From 4e6547b09e0daa3fcfbe4bd97a34bc2f14ac4696 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 16:55:20 +0300 Subject: [PATCH 224/287] feat(risk): add decision supporting refs --- .productization_next_steps_missing.md | 2 +- docs/reference/customer-package-manifest.md | 8 +- docs/reference/vulnerability-decisions.md | 21 +++ .../end-to-end-release-evidence/README.md | 4 +- .../sample-customer-package-manifest.json | 10 ++ .../sample-customer-package-manifest.sha256 | 2 +- .../sample-customer-package.zip | Bin 3529 -> 3585 bytes internal/adapters/httpapi/openapi.go | 3 + .../adapters/httpapi/openapi_operations.go | 1 + internal/adapters/httpapi/router.go | 22 +-- internal/adapters/httpapi/router_test.go | 6 + internal/adapters/postgres/store.go | 26 +++- internal/adapters/postgres/store_test.go | 8 +- internal/app/governance_packages.go | 7 +- internal/app/manual_decisions_test.go | 137 ++++++++++++++++++ internal/app/vex.go | 117 +++++++++++++++ internal/domain/domain.go | 96 ++++++------ ...rability_decision_supporting_refs.down.sql | 2 + ...nerability_decision_supporting_refs.up.sql | 2 + openapi.yaml | 2 +- site/package-viewer/index.html | 12 +- 21 files changed, 413 insertions(+), 75 deletions(-) create mode 100644 migrations/20260601000800_vulnerability_decision_supporting_refs.down.sql create mode 100644 migrations/20260601000800_vulnerability_decision_supporting_refs.up.sql diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index 0ec8d1e..911fb5d 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -264,7 +264,7 @@ Implementation rules: - Update OpenAPI, tests, and docs. - Run targeted app/API tests and `make openapi-check`. -### Ticket E3-T4 - Add first-class supporting links for non-evidence resources [ ] +### Ticket E3-T4 - Add first-class supporting links for non-evidence resources [x] Description: Let decisions link to approvals, exceptions, waivers, remediation tasks, release bundles, incident packages, or other first-class records without diff --git a/docs/reference/customer-package-manifest.md b/docs/reference/customer-package-manifest.md index 0fffc17..0f09dff 100644 --- a/docs/reference/customer-package-manifest.md +++ b/docs/reference/customer-package-manifest.md @@ -35,7 +35,8 @@ matching release-scoped records exist: including `reviewed_at` and optional `review_due_at` freshness metadata when recorded, plus safe `sbom_id`, `sbom_component_purl`, and `sbom_component_name` context when a same-release SBOM component matched the - finding. + finding, and optional `supporting_refs` with first-class same-release record + type/id pairs. - `api_contracts`: OpenAPI contract metadata, normalized operation summaries, deterministic contract diff results, and API-contract limitations. - `approvals`: release or product approval records. @@ -61,7 +62,10 @@ Customer package manifests exclude raw tenant evidence payload bytes, object-store payload references, bearer tokens, private keys, API key hashes, SSO/session token hashes, and tenant-internal vulnerability decision notes. Customer-visible vulnerability decisions require `impact_statement`; internal -notes are not copied into `vulnerability_decisions`. +notes are not copied into `vulnerability_decisions`. Decision `supporting_refs` +include only validated record type and id values. They do not copy approval +reason internals, exception payloads, incident timeline details, object-store +paths, raw payloads, or token/key material. `object_lock_proofs` entries include policy identifiers, object-scope presence indicators, retention mode/days, verification checks, verification hash, and diff --git a/docs/reference/vulnerability-decisions.md b/docs/reference/vulnerability-decisions.md index 59bcfe4..c230c00 100644 --- a/docs/reference/vulnerability-decisions.md +++ b/docs/reference/vulnerability-decisions.md @@ -40,6 +40,7 @@ finding: | Source VEX/import | `vex_document_id` and `evidence_id` link imported decisions to the VEX document and evidence item. Manual decisions may also set `vex_document_id` to link a same-release imported VEX document without changing the manual source. | | Scan finding link | `finding_id` and `scan_id` link the decision to the normalized finding. | | Supporting evidence links | `evidence_ids` can link tenant-scoped supporting evidence from the same release. | +| Supporting record links | `supporting_refs` can link same-release first-class records: `approval`, `exception`, `waiver`, `remediation_task`, `release_bundle`, and `incident`. | | Audit history | Decision creation appends an audit-chain entry. | | Import report | `GET /v1/vex/{id}/import-report` exposes safe parser counts, warnings, and mapping failures for OpenVEX imports. | @@ -115,6 +116,26 @@ create a superseding decision to attach the new context. Customer package manifests include only active decisions unless a future history-specific export is requested. +## Supporting Record Links + +Manual decisions may include `supporting_refs` when the reviewer wants to point +to first-class Evydence records instead of wrapping everything as generic +evidence. Evydence validates each reference before the decision is created: + +- the referenced record must belong to the same tenant; +- the referenced record must be scoped to the same release, or to the product + subject in a way that matches the decision release; +- duplicates, empty references, unknown types, and supplied digests are + rejected; +- refs are normalized deterministically and are immutable with the decision + version. + +Customer-safe summaries and packages include only reference type and id. They do +not copy approval reason internals, exception payloads, incident timeline +details, raw evidence payloads, object-store paths, or tenant-internal decision +notes. To add, remove, or correct supporting links, create a superseding +decision. + Manual decisions are the fallback when a VEX document is not available or when automated VEX mapping does not create the required decision. They use the same append-only lifecycle as imported decisions. If a VEX document is imported diff --git a/examples/end-to-end-release-evidence/README.md b/examples/end-to-end-release-evidence/README.md index e8d7b39..01df0b2 100644 --- a/examples/end-to-end-release-evidence/README.md +++ b/examples/end-to-end-release-evidence/README.md @@ -91,14 +91,14 @@ question to concrete Evydence records: - `sbom.json`: which SBOM was used for the release answer. - `vulnerability-scan.json`: which scanner result raised the finding. - `vulnerability-decision.json`: why the finding is treated as not affected in - this demo. + this demo, including any same-release supporting record references. - `release-readiness.json`: the readiness result, gaps, assumptions, and limitations. - `release-security-summary.json`: the compact release security status for review surfaces. - `release-bundle.json`: the signed release bundle metadata. - `customer-package.json`: the customer-safe package manifest, including the - proof-path checklist when present. + proof-path checklist and customer-safe decision supporting refs when present. - `audit-chain-verification.json`: audit-chain continuity verification. To visually inspect the customer-safe output, open diff --git a/examples/end-to-end-release-evidence/sample-customer-package-manifest.json b/examples/end-to-end-release-evidence/sample-customer-package-manifest.json index 996a909..2dec809 100644 --- a/examples/end-to-end-release-evidence/sample-customer-package-manifest.json +++ b/examples/end-to-end-release-evidence/sample-customer-package-manifest.json @@ -140,6 +140,16 @@ "source": "vex", "evidence_id": "ev_vex", "vex_document_id": "vex_example", + "supporting_refs": [ + { + "type": "exception", + "id": "exc_example" + }, + { + "type": "release_bundle", + "id": "bundle_example" + } + ], "reviewed_at": "2026-05-27T12:00:00Z", "review_due_at": "2026-08-25T12:00:00Z", "created_at": "2026-05-27T12:00:00Z" diff --git a/examples/end-to-end-release-evidence/sample-customer-package-manifest.sha256 b/examples/end-to-end-release-evidence/sample-customer-package-manifest.sha256 index f4125bd..3315e4b 100644 --- a/examples/end-to-end-release-evidence/sample-customer-package-manifest.sha256 +++ b/examples/end-to-end-release-evidence/sample-customer-package-manifest.sha256 @@ -1 +1 @@ -54c940232b1989f44a89dc82a0a9513eb68dbe18119bd8073a0fbdaf06e102c0 sample-customer-package-manifest.json +768ab2e353125b055c5f2d24ce4e278f52747bd14d52551fc97cc2585b577180 sample-customer-package-manifest.json diff --git a/examples/end-to-end-release-evidence/sample-customer-package.zip b/examples/end-to-end-release-evidence/sample-customer-package.zip index 7d77c5d91195a89257599b04380da9bc82ba1fa3..7aa230d70ac0a168ddd12d095631b040f3a16773 100644 GIT binary patch literal 3585 zcmZ`+S5y<)woQHEG=(6bhTfzw=eKv9eLZiZf`Y}pg8Y05wzhuU^33;#Yp(88S_*tl$Xk3tMK8ltmDJCW$kC5( zGgz&kdnI6vySUg97B?BlMD#Leqh?N$R$6+N;}oH_?wCY8$lfWtrKR!81P#Ozz<8FZ3H3>>D@b@H&{$dr7zn$6g zKHe#E2$JA1;jvtK8!dwEvzRYgjW~kabtK}f!=9~9?{b}<_)el^t4x=rkGH0KR-7W4 zKQ?laquqtj8%d7kEU>BrXa)V{P*~Tfj@w1>>4yuwv}l6Uf=A8g6JKpeBI@(E>p1D+ z+X7Y=AuX%u(!_Nt(K0ljjBY?(?ya4({fXlz*7lwx4OfolhvU6m2IWpMlb)YZV*E%4 z2z6F304Y-Hp~HSp*KWkkq2k)O7GG#dIOP{2x;e(cOr91yCB^6Ta#76!h?yAgjahql z<=0$fx46=tFe7i!kKrAYIy=PH>hOBrAm5Cgt=3;_ZXDg_BeE(+QHyNM*9427q@>dI zkj7LRE_zTBTQ)h}d(^r0|H{TuEuYb8lGRBE+g)mLbrT<@eCkLqtbGbbp4rSng2t{d z=VfD2+tfPcngiewMC^j%r$OB_4I$+C*;JU|mR7gH)mJv9jf`&O@7XT>X4TGnfmF!R zan37|X)rR;P2)AG@`_0pdNMH~7b_J5`#VbV&bt9f%Ug=(DQ;*a6HtWnmAO{?7b+c6 zr_V`4Gh6iYmlEV5NP_|imQitQxk0sQ@8Sy5V?a@4FemG|OIGxcED>x#MIMU3e(|Nz z$8yr2!ku* zyWY5I2S4$eQG?JXbb9}^26o& zz*0N~{yo(!S#|u%B`EU-v3S(ydKn0F-%mhnsh4_(RlrnmtGJ_Y2gP$wG!GShj5|>7 z?Wi=MhsHm?)~1!O<^o@?G&>z`Y~(1djU3MKf zd?6=)1t;>0x+3KbRW~C<=gpQb+3HC;Y$g(Fb{n%#e$7b3ucFRW?>!ABKgh-e`lI6< zE?hX_@wWWL2nI50bZ8Gp4~&UEZYAcRQrvETqiNvU$?u@1dKWNJ_wX>J@t$ni>F{@; zkQ${FOi-MeSS>@N^Mc;@I>>X ztEPwVH*q{A`W+@?FLCB;`bZix1W|a<_DN_`GLa znthmpR=Rq}8|7jyc1sLb?Je$+)(8eaOZ)p@M#FNFQ)(1Ly|lgCF%g_Um3O|;x--S) ztw|Oesl17ITa)c?mOVvzG7DjpkEV$;8cL5kf&OJ=my)p(M*j7gOl~U3>P^NwTI%6v z3LzpA9D;q00@yUu%QlCQrC3nRco5ErHLN#OJiMovq1-pHMfiPqM1TZaE?KK`UmV{q zG9(9CV=*f;_6X_L-@dw-pAFt>Z*ASLa>Pn$f8i7n9Xxgn5iW<-vy9@X{G^XwjCR z479K{9DYG$(s>Yrdivn;Bb8PvQ{!18@TM=K)9IljIKqhnB#D(2DU?PpQdxp1lOogv zJ|)A392TYp!=0$m2?-4j}yRDgs3WJ zaG2V$VjsYY)L{HxbQGVldG1C^h1YIK>UHYqc24PSQ8$78l`q@pwa!7%4A^oYAPQ_s zy3X~+=&oDp4kEKKxX%+2F6gdyK$G~{=B_V!285l4u=9?OX*_+Wl1yG^ZY-(U)Y?e_ z1XHh5?^mf21G6FJ6elum2=hYrY!{)bD#pcH{NN8Eu)UOFpyt=sqCyh(+Isne4fitP zWT0_oX|u;mk)`@k@3f+Re9L`NUa;v4Rn;^eaF*w(eX`bNsrdLeTmV4PI`#2I_~~_o z)`jLPwX^MbV_`?lj5?gpj;49Xg^z93qfcoIGTI;I|Kz+!KpP>yGjaZ6(8+~oUa{xd zs)U*Q#>s-=_To`c{4Z2oja|g`F10s*A-A9c7BM^H1Gn`IWtsd@4&AsYrgA=4qU~D5 z_jrS0g-7j;BTGr?MPAYOshF&&l`LprQ+*K1Gu#(1Z@hdZcm=JGuP$BK(~v3(ap!3V;LiE*0wFD&^p zInduLD6tiZ#cE$IurTWdy#jK%`?qhV?S$%8tc-|Xzk0Q!D;$ncJXwZo?Ef?iYs&L_ zsf$kw@t!yx{(Mje;b>f#NS^a+Hf$OL7OtaiyRu8vFE}r(r zVmUO|=Q%k*x4Pv2NmS0IJSpNiNrw~w0LwX1p{PL5+n%n@!JdA;|6m(NgtgFb7F}zA-LvbAB^$nA)lb|{e+4JCMg_H6*Q4|e?UNY&q@1hSPBXqRB`e)LB=tuI? zXdcTD=?HPP(a=8B!d0_toQXM0rO90p-*k|NDm#(7X|=q6NA){Xn@%{Hba-PK zyy2U>ymGZ9$3I?uA~=}2k+$2_bOUrf(I+L%Z8*^&N$W@R)0&zsxM?q@)2MiRtF3ux zixN@v6#Dh8!;rIxnorUqb;b(6Y(J+EB6;DN&qk0@nXVs$pl?b@W^o%kH3A#pYiLAD8>X)2XV-9b!EBDSFPG@f)@?#d@4zzmv#8}_<^IaIVGM7ds1%jd! z(;zu}B?(WJAQiC3!v6Tm2b-HSC5BQ&WZP06&b7s5NzZFGRp0kvkY3ZWl3EeZ9*+*K zxl0pA1Z^cZlw(vXqvDzQkEYnvvdO29q^m;d<(aCs#ri_s(nc}f$oAK1N30gJR&t{( z6yv-URjDNoL2_TKKo~8IJHtXyf7K8^zL$dncBbmu#+x>>wi8Cus+7}r?$J#*K<3ao zD%8z7AicL@=B}g7Hii}0^<(rUEyPy3X1<*>2&8~q_}>fAIgNmGIsqjQe|P^_hyH~A z=}*4_{}289e53kLxB3(L=fM6O*+=tV#`jP7pSu4WPN4hGUtnSY0{?!aJU`^~diL8z G0sjYz0%+O* literal 3529 zcmZ`+S5On$77e`wkPadp1uhthG(%SiRYM0cfP^Y7lu%V_kg6gbLWl$qM0)6vVx)s2 z5a}JHC?Lg)ba>qRKHj^|d*{raz2}@+KWok2v$nAz1tmKG0HD1HA%ImzpS;0EnaBqK zFkZZP!4YmQ&PabLcceF>#Tw>4rN|z(RVjGl*;JpZ=yr?;l9yeA#VAO|Fh*+X*M5Ys zDx~-=a-MFf#44HKH-gt?@-#(uxBXgw<^q#6+60}7c0r|X1V>Zfp^vjE*0XBmebwP)K&ebX3 zUwYH^mINopRP!3)*F0S1nd@V{yB7FX0<3&aDsy`)s6pD}A?n7f1xemZ1*j!>K5lRR zMCBc`Xj|6v=<9Cn8YW&upDFzeptU&nK|2Gp5=$->P}lV?Hb}BR_`Zd0JPF|}tV2S7 zXG+Q)viUhp%DKJ)Gs2BlWDF%9l&* z&>F0T_ET>Zn*LA%YJiQX=???^aN88B`m;R`QTsvcdG2cN;0t_m+p=#P}w}5 z2XFK~x=mOp@AhbaJ{uAmdIu}I&~tKj->mI znxA`iYT!EDLs?=ra(%KVhxbayypcyM-yhZ8U-eIShCmlq))OrPcVa4}6Hf4XR%4YD zF31)_bD#9Yi1K4(OEZBG22pxuYv*bmJ{f|wZ_kI&-%_K$1m$03yWB&$73qu(s3t2W zvAK-XTEoYI9M_*`gi@A#qD&(;|NrTI>k+EckG&N!l|@lnF4ubvQ&Xpk(pRB zZm9^vj^5!*RG0G}_WDaqbXD!+o=Ezg`3dhXh1uGgHC;04ztyf#)fhG8oaWxpJT3e* z)L;|TkrSoltQn$!jbGBXk*91vVTyg-&K;C?cD8iafwA7EA{I~lY8No6-pmg2NPFAb zbg%3-=gyIwVA9m+ni6I&+okdl)zYhDnv#wZ>aj=XWrSI zv&P6Sjyqp@iro-Poh5_5F+!jHQ^Oa96}MmYk-5|+)p&`OA{#cX4zcxO}v72MQ@AZtLX&z7ilv44zMWF(uHyeXW+pDgqwl1N?0F;3wDyox*-LfuLY2LeWb8nh%8 zJCU?i0RQ#HvX<^kJ1MS#3vR@_en+5;+QLU4#^DvXarr1QmafVA{pNhUmLe;(+S~NN zFG;88^nKZx&l9Z9^mirJT!hNzTwYq5v0+9h`Iy25l=t zHcp1wO(~zC@kHwY!x6>T7JmR1yk@KjL_#eKqa{yh>4LrIiMo%WN3f%}AhB?T;U^Dq z1O=B?c`}IEc+lhdHk9Ri#9+eZK_?%V2Lnc49fpET5s4!cRTB7`g+FEZ<+f}xudpQr zQpGmEd)>UXg4s>9hRB8#)2q_QJM&Ay{eZQPpkrFyd?TT=Axouu2$2{<)U(RTa%af_mEViw46=>ACt(#_jNb*rl+%F zDOs-h^7?;!T(MHvHbo>CHEku5J=z;9s5d8M%{np9=aU`|^LBWx7tvYEE ze7HTcnS|3&6hkdW+dtQ`VaiH{=^YDrhb0zzp^!Z50 zVs?u$(Gv0sP|bj!{?z8`*Njlh^%1O*>PJitv@;X@stBkiJl-;9`~6ku`+Hq)qD{#$ z0@@0c_tH?BQ6q^-O-RpQ$u#w1Ygvuo+hbu@`Z{O6Y=FNqBI4GF?sRK?21& z<$aBaTChZ!AW1TR^aqoDzBRAbqc!zK2hS}0JdODZ>?+;b8by^!it6nOGMjx)D`~_F z8a$Dc5fBkdq2@A_rLvPwF)U^h^(B3UW4R6uSQgWBS?WbLA-UWt2=yGMj$F!fX!8kD z&uLf$`cE*nrL3mLdnHfXwG_{YJ z@u081NuW9T>BKkYEEeY`hZ0?UB!SDP=+Y^UsxH z9S@m|+v8q~I*u6%G=5A#e#kVLJnL}K3TSMLrIDkwdmB~ycALTos7*Ea;drYnmMM;P z@_=%rBYVOoZY-mIR4}>!qLmrL#t#jG7~PxCHCi~cW-L~E4Sr(kCR;hM`^(2%5A04D zjsIafhGWxJ&M(YHIT--JaFKoBjvjDV=f6FN?Mp*Mv<$QMK8C!Ssi&4G_zQ`$c1H1# z_{+AdJ+(v={PwpEg@yOJEGkRCo-uroNy!*AgB2vbl_94Vb_rqVRC}6G9bi|G`MjWb zC}a95o2=_T-_er)yTjpZH1=i|mMP@DiKJiakHLT|3(Cvva+y|_P;I7S_&{KJYJCz>0{ONlKU!MsZzSgS zDZE0=zfEe-YO41Ibr}~P@oDlLtfIl_(oLDCU90KjrVRG_n;n~R$x+~3U` z@i$u*rng>9$uKl;NycF|Ar4~Ds)k>7?Bl;I*~vgA)rxp0J%2o6s4dfvwc#-y!W7ef z`7Dh5UO*N>gkTnz@h)tSyz~pa&chP&LwO3OQ%@9gJAIkLt^paD07lYddy(YNDAf;c zBpYQQ`^SU$MXt#RMFHvgv7EzRl3{z30BPfe=?8{edQoVqypdIa`zPD3kED6kL`Ye;;?572-=_CT>n8D*AN(s~nS7 z9G*J$d-JFJTzo-8#CLAk0@O>F4?@(|q#^x53ECtGktO%efOEtyjfKNYS7 zLR9HCZYWE)l?P;q>Cv~SlIi~NV=^OifL+zi(iSL@9gxv?V4rhBy+SIhJ@OFW8M>zn zCg?64f~eY#;(BkLC+@#4mwY?gSeawMSDzC&wlV4gOO<_8nKNmA>|*7uG_oSth%)hT zUq3P)nJVhsV=7fqk#%>nVP|+VfL{nF|B+rW(o{L@Q@B5I0E6*bpC~8P$n~$UT|<5I z1ISx~-ug^>@K4p1pw}CK7phlX z1pS5TrjT3OcOg>#!TxG5Z<)5sFhKUfPnlk>Fn_FCi;5((^yD5nglgM1Irh3WsX_ak zB>RodPgj?NqN!i*ETc7X=v5%SEf^C*4rzJ};wJn+au!rBU3pqIkgtQ@vo~hTbQXKI zaYvTR0PHgfPMjaDDic}ePJMUh3sagLYCc=RUgtT&_z7*$Hc5YwUIH*uYm7BHN;zSLf?@q|{>bUfq{M@h2%)&!!5? zibRJK9B)LA9^wQe8RadcrtuBe!;KBe$k{3W{~~k2+ux_~g2dm}n%|+nkE4GB0f0iX zfQ!xOzlYQB$lv?(KS(Uy|LE4=;lB(0A9xz@zhyTzq@w=okMiPfT;%S*h9=-&UOr2t diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 6d02b0a..2e3a649 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -300,6 +300,7 @@ func registerCriticalSchemas(registry *specs.Registry) { "customer_visible": map[string]any{"type": "boolean"}, "internal_notes": map[string]any{"type": "string", "description": "Tenant-internal notes; excluded from customer-safe package summaries."}, "evidence_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "supporting_refs": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/SubjectRef"}, "description": "Optional tenant-scoped first-class decision support records from the same release. Supported types are approval, exception, waiver, remediation_task, release_bundle, and incident."}, "vex_document_id": map[string]any{"type": "string", "description": "Optional tenant-scoped VEX document from the same release to link to this manual decision."}, "reviewed_at": map[string]any{"type": "string", "format": "date-time", "description": "Optional UTC time when the decision was reviewed. Defaults to creation time."}, "review_due_at": map[string]any{"type": "string", "format": "date-time", "description": "Optional UTC time when this decision should be reviewed again."}, @@ -324,6 +325,7 @@ func registerCriticalSchemas(registry *specs.Registry) { "source": map[string]any{"type": "string"}, "evidence_id": map[string]any{"type": "string"}, "evidence_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "supporting_refs": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/SubjectRef"}}, "vex_document_id": map[string]any{"type": "string"}, "supersedes": map[string]any{"type": "string"}, "superseded_by": map[string]any{"type": "string"}, @@ -352,6 +354,7 @@ func registerCriticalSchemas(registry *specs.Registry) { "source": map[string]any{"type": "string"}, "evidence_id": map[string]any{"type": "string"}, "evidence_ids": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "supporting_refs": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/SubjectRef"}}, "vex_document_id": map[string]any{"type": "string"}, "reviewed_at": map[string]any{"type": "string", "format": "date-time"}, "review_due_at": map[string]any{"type": "string", "format": "date-time"}, diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index 5144442..d30fc54 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -987,6 +987,7 @@ func vulnerabilityDecisionExample() map[string]any { "impact_statement": "The shipped artifact does not include the affected runtime path.", "customer_visible": true, "evidence_ids": []string{"ev_20260527120000"}, + "supporting_refs": []map[string]string{{"type": "exception", "id": "exc_20260527120000"}}, } } diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index a4e6c10..3d2ee06 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -1509,16 +1509,17 @@ func (s *Server) getVulnerabilityScan(w http.ResponseWriter, r *http.Request) { func (s *Server) createVulnerabilityDecision(w http.ResponseWriter, r *http.Request) { var req struct { - Status string `json:"status"` - Justification string `json:"justification"` - ImpactStatement string `json:"impact_statement"` - ActionStatement string `json:"action_statement"` - CustomerVisible bool `json:"customer_visible"` - InternalNotes string `json:"internal_notes"` - EvidenceIDs []string `json:"evidence_ids"` - VEXDocumentID string `json:"vex_document_id"` - ReviewedAt *time.Time `json:"reviewed_at"` - ReviewDueAt *time.Time `json:"review_due_at"` + Status string `json:"status"` + Justification string `json:"justification"` + ImpactStatement string `json:"impact_statement"` + ActionStatement string `json:"action_statement"` + CustomerVisible bool `json:"customer_visible"` + InternalNotes string `json:"internal_notes"` + EvidenceIDs []string `json:"evidence_ids"` + SupportingRefs []domain.SubjectRef `json:"supporting_refs"` + VEXDocumentID string `json:"vex_document_id"` + ReviewedAt *time.Time `json:"reviewed_at"` + ReviewDueAt *time.Time `json:"review_due_at"` } s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { if err := decodeJSON(body, &req); err != nil { @@ -1532,6 +1533,7 @@ func (s *Server) createVulnerabilityDecision(w http.ResponseWriter, r *http.Requ CustomerVisible: req.CustomerVisible, InternalNotes: req.InternalNotes, EvidenceIDs: req.EvidenceIDs, + SupportingRefs: req.SupportingRefs, VEXDocumentID: req.VEXDocumentID, ReviewedAt: req.ReviewedAt, ReviewDueAt: req.ReviewDueAt, diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index bb25121..7d0667d 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -93,10 +93,16 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { if _, ok := decisionRequestProps["review_due_at"]; !ok { t.Fatalf("manual decision request schema missing review_due_at: %#v", decisionRequestProps) } + if _, ok := decisionRequestProps["supporting_refs"]; !ok { + t.Fatalf("manual decision request schema missing supporting_refs: %#v", decisionRequestProps) + } decisionProps := asStringAnyMap(t, asStringAnyMap(t, schemas["VulnerabilityDecision"])["properties"]) if _, ok := decisionProps["sbom_component_purl"]; !ok { t.Fatalf("decision schema missing sbom_component_purl: %#v", decisionProps) } + if _, ok := decisionProps["supporting_refs"]; !ok { + t.Fatalf("decision schema missing supporting_refs: %#v", decisionProps) + } redactionRequestProps := asStringAnyMap(t, asStringAnyMap(t, schemas["CreateRedactionProfileRequest"])["properties"]) if _, ok := redactionRequestProps["preset"]; !ok { t.Fatalf("redaction profile request schema missing preset: %#v", redactionRequestProps) diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index 7c97f08..40c840f 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -1164,7 +1164,7 @@ func (s *Store) loadRelationalRiskDecisions(ctx context.Context, state *app.Pers SELECT id, tenant_id, finding_id, scan_id, release_id, vulnerability, component, sbom_id, sbom_component_purl, sbom_component_name, status, justification, impact_statement, action_statement, - customer_visible, internal_notes, source, evidence_id, evidence_ids, vex_document_id, + customer_visible, internal_notes, source, evidence_id, evidence_ids, supporting_refs, vex_document_id, supersedes, superseded_by, approved_by, reviewed_at, review_due_at, schema_version, created_at FROM vulnerability_decisions `) @@ -1176,10 +1176,11 @@ func (s *Store) loadRelationalRiskDecisions(ctx context.Context, state *app.Pers var decision domain.VulnerabilityDecision var releaseID, component, sbomID, sbomComponentPURL, sbomComponentName, impactStatement, actionStatement, internalNotes, evidenceID, vexDocumentID, supersedes, supersededBy, approvedBy sql.NullString var reviewedAt, reviewDueAt sql.NullTime + var supportingRefs []byte if err := decisionRows.Scan( &decision.ID, &decision.TenantID, &decision.FindingID, &decision.ScanID, &releaseID, &decision.Vulnerability, &component, &sbomID, &sbomComponentPURL, &sbomComponentName, &decision.Status, &decision.Justification, &impactStatement, &actionStatement, - &decision.CustomerVisible, &internalNotes, &decision.Source, &evidenceID, &decision.EvidenceIDs, &vexDocumentID, &supersedes, &supersededBy, + &decision.CustomerVisible, &internalNotes, &decision.Source, &evidenceID, &decision.EvidenceIDs, &supportingRefs, &vexDocumentID, &supersedes, &supersededBy, &approvedBy, &reviewedAt, &reviewDueAt, &decision.SchemaVersion, &decision.CreatedAt, ); err != nil { return fmt.Errorf("scan relational vulnerability decision: %w", err) @@ -1193,6 +1194,9 @@ func (s *Store) loadRelationalRiskDecisions(ctx context.Context, state *app.Pers decision.ActionStatement = nullableSQLString(actionStatement) decision.InternalNotes = nullableSQLString(internalNotes) decision.EvidenceID = nullableSQLString(evidenceID) + if err := decodeJSON(supportingRefs, &decision.SupportingRefs); err != nil { + return fmt.Errorf("decode relational vulnerability decision supporting refs: %w", err) + } decision.VEXDocumentID = nullableSQLString(vexDocumentID) decision.Supersedes = nullableSQLString(supersedes) decision.SupersededBy = nullableSQLString(supersededBy) @@ -3305,12 +3309,20 @@ func syncRiskBuildControlRows(ctx context.Context, tx pgx.Tx, state app.Persiste if decision.ID == "" || decision.TenantID == "" || decision.FindingID == "" || decision.ScanID == "" { continue } + supportingRefs := decision.SupportingRefs + if supportingRefs == nil { + supportingRefs = []domain.SubjectRef{} + } + supportingRefsJSON, err := json.Marshal(supportingRefs) + if err != nil { + return fmt.Errorf("encode vulnerability decision supporting refs: %w", err) + } if _, err := tx.Exec(ctx, ` INSERT INTO vulnerability_decisions ( id, tenant_id, finding_id, scan_id, release_id, vulnerability, component, sbom_id, sbom_component_purl, sbom_component_name, status, justification, impact_statement, action_statement, - customer_visible, internal_notes, source, evidence_id, evidence_ids, vex_document_id, + customer_visible, internal_notes, source, evidence_id, evidence_ids, supporting_refs, vex_document_id, supersedes, superseded_by, approved_by, reviewed_at, review_due_at, schema_version, created_at ) VALUES ( @@ -3318,7 +3330,7 @@ func syncRiskBuildControlRows(ctx context.Context, tx pgx.Tx, state app.Persiste $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, - $21, $22, $23, $24, $25, $26, $27 + $21, $22, $23, $24, $25, $26, $27, $28 ) ON CONFLICT (id) DO UPDATE SET superseded_by = EXCLUDED.superseded_by, @@ -3333,11 +3345,15 @@ func syncRiskBuildControlRows(ctx context.Context, tx pgx.Tx, state app.Persiste evidence_ids = CASE WHEN cardinality(vulnerability_decisions.evidence_ids) = 0 THEN EXCLUDED.evidence_ids ELSE vulnerability_decisions.evidence_ids + END, + supporting_refs = CASE + WHEN vulnerability_decisions.supporting_refs = '[]'::jsonb THEN EXCLUDED.supporting_refs + ELSE vulnerability_decisions.supporting_refs END `, decision.ID, decision.TenantID, decision.FindingID, decision.ScanID, nullableString(decision.ReleaseID), decision.Vulnerability, nullableString(decision.Component), nullableString(decision.SBOMID), nullableString(decision.SBOMComponentPURL), nullableString(decision.SBOMComponentName), decision.Status, decision.Justification, nullableString(decision.ImpactStatement), nullableString(decision.ActionStatement), - decision.CustomerVisible, nullableString(decision.InternalNotes), decision.Source, nullableString(decision.EvidenceID), textArray(decision.EvidenceIDs), nullableString(decision.VEXDocumentID), nullableString(decision.Supersedes), nullableString(decision.SupersededBy), + decision.CustomerVisible, nullableString(decision.InternalNotes), decision.Source, nullableString(decision.EvidenceID), textArray(decision.EvidenceIDs), supportingRefsJSON, nullableString(decision.VEXDocumentID), nullableString(decision.Supersedes), nullableString(decision.SupersededBy), nullableString(decision.ApprovedBy), nullableTime(decision.ReviewedAt), nullableTime(decision.ReviewDueAt), decision.SchemaVersion, nonZeroTime(decision.CreatedAt)); err != nil { return fmt.Errorf("upsert vulnerability decision row: %w", err) } diff --git a/internal/adapters/postgres/store_test.go b/internal/adapters/postgres/store_test.go index 967ff0c..e45172b 100644 --- a/internal/adapters/postgres/store_test.go +++ b/internal/adapters/postgres/store_test.go @@ -409,7 +409,7 @@ func TestStoreLoadSaveAndOutboxWithPostgres(t *testing.T) { "vex_report_test": {ID: "vex_report_test", TenantID: "ten_test", VEXDocumentID: "vex_test", EvidenceID: "ev_test", ReleaseID: "rel_test", ArtifactID: "art_test", ParserVersion: app.ParserVersionOpenVEXJSON, Status: "parsed", StatementCount: 1, DecisionsCreated: 1, MappingFailures: []domain.VEXImportIssue{{StatementIndex: 2, Code: "finding_not_found", Detail: "No matching finding."}}, SchemaVersion: domain.VEXImportReportSchemaVersion, CreatedAt: time.Now().UTC(), UpdatedAt: time.Now().UTC()}, }, Decisions: map[string]domain.VulnerabilityDecision{ - "decision_test": {ID: "decision_test", TenantID: "ten_test", FindingID: "finding_test", ScanID: "scan_test", ReleaseID: "rel_test", Vulnerability: "CVE-0000-0001", Component: "lib", SBOMID: "sbom_test", SBOMComponentName: "lib", Status: "not_affected", Justification: "not_present", Source: "manual", EvidenceID: "ev_test", VEXDocumentID: "vex_test", SchemaVersion: domain.VulnerabilityDecisionVersion, CreatedAt: time.Now().UTC()}, + "decision_test": {ID: "decision_test", TenantID: "ten_test", FindingID: "finding_test", ScanID: "scan_test", ReleaseID: "rel_test", Vulnerability: "CVE-0000-0001", Component: "lib", SBOMID: "sbom_test", SBOMComponentName: "lib", Status: "not_affected", Justification: "not_present", Source: "manual", EvidenceID: "ev_test", VEXDocumentID: "vex_test", SupportingRefs: []domain.SubjectRef{{Type: "release_bundle", ID: "bundle_test"}}, SchemaVersion: domain.VulnerabilityDecisionVersion, CreatedAt: time.Now().UTC()}, }, Contracts: map[string]domain.OpenAPIContract{ "contract_test": {ID: "contract_test", TenantID: "ten_test", ProductID: "prod_test", ReleaseID: "rel_test", Version: "1.0.0", Hash: "sha256:" + strings.Repeat("f", 64), PathCount: 1, Operations: []domain.OpenAPIOperation{{Path: "/v1/test", Method: "get", OperationID: "getTest"}}, EvidenceID: "ev_test", CreatedAt: time.Now().UTC()}, @@ -935,7 +935,8 @@ func TestApplyCriticalMutationWithPostgres(t *testing.T) { ReleaseID: "rel_focus", Vulnerability: "CVE-2099-0001", Component: "pkg:generic/api", SBOMID: "sbom_focus", SBOMComponentPURL: "pkg:generic/api", SBOMComponentName: "api", Status: "not_affected", Justification: "component_not_present", ImpactStatement: "not shipped", CustomerVisible: true, InternalNotes: "private triage", EvidenceIDs: []string{"ev_support"}, Source: "manual", - SchemaVersion: domain.VulnerabilityDecisionVersion, CreatedAt: now, + SupportingRefs: []domain.SubjectRef{{Type: "release_bundle", ID: "bundle_focus"}}, + SchemaVersion: domain.VulnerabilityDecisionVersion, CreatedAt: now, }}, AuditChainEntries: []domain.AuditChainEntry{{ ID: "chain_focus", TenantID: "ten_focus", Sequence: 1, EntryType: "release_bundle.created", @@ -1126,7 +1127,8 @@ func TestApplyReleaseLedgerMutationWithPostgres(t *testing.T) { ID: "decision_release_focus", TenantID: "ten_release_focus", FindingID: "finding_focus", ScanID: "scan_focus", ReleaseID: "rel_focus", Vulnerability: "CVE-2099-0001", Component: "lib", SBOMID: "sbom_focus", SBOMComponentName: "lib", Status: "not_affected", Justification: "component_not_present", Source: "vex", EvidenceID: "ev_focus", VEXDocumentID: "vex_focus", - SchemaVersion: domain.VulnerabilityDecisionVersion, CreatedAt: now, + SupportingRefs: []domain.SubjectRef{{Type: "release_bundle", ID: "bundle_focus"}}, + SchemaVersion: domain.VulnerabilityDecisionVersion, CreatedAt: now, }}, AuditChainEntries: []domain.AuditChainEntry{{ ID: "chain_release_focus", TenantID: "ten_release_focus", Sequence: 1, EntryType: "evidence.created", diff --git a/internal/app/governance_packages.go b/internal/app/governance_packages.go index 6b4f0b4..53b62bd 100644 --- a/internal/app/governance_packages.go +++ b/internal/app/governance_packages.go @@ -1401,9 +1401,9 @@ func customerPackageHTMLReport(pkg domain.CustomerSecurityPackage, metadata, ver b.WriteString("") } if len(decisions) > 0 { - b.WriteString("

Vulnerability Decisions

") + b.WriteString("

Vulnerability Decisions

VulnerabilityComponentSBOMStatusImpact StatementReviewedReview DueSource
") for _, record := range decisions { - b.WriteString("") + b.WriteString("") } b.WriteString("
VulnerabilityComponentSBOMStatusImpact StatementReviewedReview DueSupporting LinksSource
" + packageHTMLEscape(packageHTMLString(record["vulnerability"])) + "" + packageHTMLEscape(packageHTMLString(record["component"])) + "" + packageHTMLEscape(packageHTMLString(record["sbom_id"])) + "" + packageHTMLEscape(packageHTMLString(record["status"])) + "" + packageHTMLEscape(packageHTMLString(record["impact_statement"])) + "" + packageHTMLEscape(packageHTMLString(record["reviewed_at"])) + "" + packageHTMLEscape(packageHTMLString(record["review_due_at"])) + "" + packageHTMLEscape(packageHTMLString(record["source"])) + "
" + packageHTMLEscape(packageHTMLString(record["vulnerability"])) + "" + packageHTMLEscape(packageHTMLString(record["component"])) + "" + packageHTMLEscape(packageHTMLString(record["sbom_id"])) + "" + packageHTMLEscape(packageHTMLString(record["status"])) + "" + packageHTMLEscape(packageHTMLString(record["impact_statement"])) + "" + packageHTMLEscape(packageHTMLString(record["reviewed_at"])) + "" + packageHTMLEscape(packageHTMLString(record["review_due_at"])) + "" + packageHTMLEscape(packageHTMLJSON(record["supporting_refs"])) + "" + packageHTMLEscape(packageHTMLString(record["source"])) + "
") } @@ -2002,6 +2002,9 @@ func (l *Ledger) packageDecisionSummariesLocked(tenantID, releaseID string, prof if len(decision.EvidenceIDs) > 0 && !excluded["evidence_ids"] { summary["evidence_ids"] = append([]string(nil), decision.EvidenceIDs...) } + if len(decision.SupportingRefs) > 0 && !excluded["supporting_refs"] { + summary["supporting_refs"] = cloneSubjectRefs(decision.SupportingRefs) + } summaries = append(summaries, summary) } sort.Slice(summaries, func(i, j int) bool { diff --git a/internal/app/manual_decisions_test.go b/internal/app/manual_decisions_test.go index 3866742..92dd0fa 100644 --- a/internal/app/manual_decisions_test.go +++ b/internal/app/manual_decisions_test.go @@ -7,6 +7,8 @@ import ( "strings" "testing" "time" + + "github.com/aatuh/evydence/internal/domain" ) func TestManualDecisionCanLinkImportedVEXAndExportCustomerPackage(t *testing.T) { @@ -112,6 +114,141 @@ func TestManualDecisionRejectsForeignReleaseVEXLink(t *testing.T) { } } +func TestManualDecisionSupportingRefsAreScopedAndCustomerSafe(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, release, _ := setupReleaseRiskFixture(t, ledger) + scan := uploadVEXMappingScan(t, ctx, ledger, actor, release.ID, "CVE-2026-0610", "pkg:apk/openssl@3.1.0") + exception, err := ledger.CreateException(ctx, actor, CreateExceptionInput{ReleaseID: release.ID, FindingID: scan.Findings[0].ID, Reason: "temporary customer-visible exception", Owner: "security", ExpiresAt: fixedNow().Add(24 * time.Hour)}) + if err != nil { + t.Fatalf("exception: %v", err) + } + if _, err := ledger.ApproveException(ctx, actor, exception.ID); err != nil { + t.Fatalf("approve exception: %v", err) + } + waiver, err := ledger.CreateWaiver(ctx, actor, CreateWaiverInput{ScopeType: "release", ScopeID: release.ID, Owner: "security", Risk: "documented risk", Reason: "release-scoped waiver", ExpiresAt: fixedNow().Add(24 * time.Hour)}) + if err != nil { + t.Fatalf("waiver: %v", err) + } + if _, err := ledger.ApproveWaiver(ctx, actor, waiver.ID); err != nil { + t.Fatalf("approve waiver: %v", err) + } + approval, err := ledger.CreateApprovalRecord(ctx, actor, CreateApprovalInput{SubjectType: "release", SubjectID: release.ID, Decision: "approved", Reason: "release risk reviewed"}) + if err != nil { + t.Fatalf("approval: %v", err) + } + incident, err := ledger.CreateIncident(ctx, actor, CreateIncidentInput{ProductID: release.ProductID, ReleaseID: release.ID, Title: "Patch tracking", Severity: "medium", OpenedAt: fixedNow()}) + if err != nil { + t.Fatalf("incident: %v", err) + } + task, err := ledger.CreateRemediationTask(ctx, actor, CreateRemediationTaskInput{ReleaseID: release.ID, Title: "Monitor upstream fix", Owner: "security"}) + if err != nil { + t.Fatalf("task: %v", err) + } + ledger.bundles["bundle_support"] = domain.ReleaseBundle{ID: "bundle_support", TenantID: actor.TenantID, ReleaseID: release.ID, State: "generated", ManifestHash: sampleDigest("bundle"), CreatedAt: fixedNow()} + + decision, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{ + Status: decisionStatusAffected, + Justification: "affected while a follow-up fix is tracked", + ImpactStatement: "The finding is tracked with linked release-scoped decision support.", + ActionStatement: "Review the linked exception, waiver, approval, bundle, incident, and remediation task before relying on the release.", + CustomerVisible: true, + InternalNotes: "private support note", + SupportingRefs: []domain.SubjectRef{ + {Type: "waiver", ID: waiver.ID}, + {Type: "release_bundle", ID: "bundle_support"}, + {Type: "exception", ID: exception.ID}, + {Type: "remediation_task", ID: task.ID}, + {Type: "incident", ID: incident.ID}, + {Type: "approval", ID: approval.ID}, + }, + }) + if err != nil { + t.Fatalf("decision: %v", err) + } + gotTypes := []string{} + for _, ref := range decision.SupportingRefs { + gotTypes = append(gotTypes, ref.Type) + if ref.Digest != "" { + t.Fatalf("supporting ref leaked digest: %#v", decision.SupportingRefs) + } + } + if strings.Join(gotTypes, ",") != "approval,exception,incident,release_bundle,remediation_task,waiver" { + t.Fatalf("supporting refs not normalized deterministically: %#v", decision.SupportingRefs) + } + report, err := ledger.VulnerabilityDecisionSummaryReport(ctx, actor, release.ID) + if err != nil { + t.Fatalf("summary report: %v", err) + } + if len(report.Decisions) != 1 || len(report.Decisions[0].SupportingRefs) != len(decision.SupportingRefs) { + t.Fatalf("summary supporting refs = %#v", report.Decisions) + } + profile, err := ledger.CreateRedactionProfile(ctx, actor, CreateRedactionProfileInput{Name: "decision support refs", AllowedTypes: []string{"vulnerability_decision"}}) + if err != nil { + t.Fatalf("profile: %v", err) + } + pkg, err := ledger.CreateCustomerSecurityPackage(ctx, actor, CreateCustomerPackageInput{ + ProductID: release.ProductID, + ReleaseID: release.ID, + RedactionProfileID: profile.ID, + Title: "Decision support refs", + ExpiresAt: fixedNow().Add(24 * time.Hour), + }) + if err != nil { + t.Fatalf("package: %v", err) + } + body, err := json.Marshal(pkg.Manifest) + if err != nil { + t.Fatalf("marshal manifest: %v", err) + } + text := string(body) + for _, want := range []string{"supporting_refs", approval.ID, exception.ID, waiver.ID, incident.ID, task.ID, "bundle_support"} { + if !strings.Contains(text, want) { + t.Fatalf("manifest missing %q in %s", want, body) + } + } + if strings.Contains(text, "private support note") { + t.Fatalf("manifest leaked internal notes: %s", body) + } +} + +func TestManualDecisionRejectsInvalidSupportingRefs(t *testing.T) { + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) + ctx := context.Background() + actor, releaseA, _ := setupReleaseRiskFixture(t, ledger) + releaseB, err := ledger.CreateRelease(ctx, actor, releaseA.ProductID, "2.0.0") + if err != nil { + t.Fatalf("release B: %v", err) + } + scan := uploadVEXMappingScan(t, ctx, ledger, actor, releaseA.ID, "CVE-2026-0611", "pkg:apk/openssl@3.1.0") + otherException, err := ledger.CreateException(ctx, actor, CreateExceptionInput{ReleaseID: releaseB.ID, Reason: "wrong release", Owner: "security", ExpiresAt: fixedNow().Add(24 * time.Hour)}) + if err != nil { + t.Fatalf("other exception: %v", err) + } + + _, err = ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{ + Status: decisionStatusAffected, + Justification: "manual review", + ImpactStatement: "Customer-safe review statement.", + CustomerVisible: true, + SupportingRefs: []domain.SubjectRef{{Type: "exception", ID: otherException.ID}}, + }) + if !errors.Is(err, ErrNotFound) { + t.Fatalf("wrong-release supporting ref err=%v, want not found", err) + } + + _, err = ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{ + Status: decisionStatusAffected, + Justification: "manual review", + ImpactStatement: "Customer-safe review statement.", + CustomerVisible: true, + SupportingRefs: []domain.SubjectRef{{Type: "release_bundle", ID: "bundle_missing", Digest: sampleDigest("support")}}, + }) + if !errors.Is(err, ErrValidation) { + t.Fatalf("supporting ref digest err=%v, want validation", err) + } +} + func TestManualCustomerVisibleDecisionRequiresCustomerStatement(t *testing.T) { ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow}) ctx := context.Background() diff --git a/internal/app/vex.go b/internal/app/vex.go index cbbc6e7..6660ca2 100644 --- a/internal/app/vex.go +++ b/internal/app/vex.go @@ -36,6 +36,7 @@ type CreateVulnerabilityDecisionInput struct { CustomerVisible bool InternalNotes string EvidenceIDs []string + SupportingRefs []domain.SubjectRef VEXDocumentID string ReviewedAt *time.Time ReviewDueAt *time.Time @@ -350,6 +351,11 @@ func (s releaseEvidenceService) CreateVulnerabilityDecision(ctx context.Context, return domain.VulnerabilityDecision{}, err } in.EvidenceIDs = evidenceIDs + supportingRefs, err := l.validateDecisionSupportingRefsLocked(actor.TenantID, scan.ReleaseID, in.SupportingRefs) + if err != nil { + return domain.VulnerabilityDecision{}, err + } + in.SupportingRefs = supportingRefs decision := l.createDecisionLocked(actor.TenantID, scan, finding, in, "api", actor.KeyID, "", in.VEXDocumentID) l.decisions[decision.ID] = decision l.appendDecisionLifecycleAuditLocked(actor.TenantID, decision, finding.ID, "api_key", actor.KeyID, "") @@ -519,6 +525,7 @@ func customerDecisionSummary(decision domain.VulnerabilityDecision) domain.Vulne Source: decision.Source, EvidenceID: decision.EvidenceID, EvidenceIDs: append([]string(nil), decision.EvidenceIDs...), + SupportingRefs: cloneSubjectRefs(decision.SupportingRefs), VEXDocumentID: decision.VEXDocumentID, ReviewedAt: cloneTimePtr(decision.ReviewedAt), ReviewDueAt: cloneTimePtr(decision.ReviewDueAt), @@ -1143,6 +1150,7 @@ func (l *Ledger) createDecisionLocked(tenantID string, scan domain.Vulnerability Source: source, EvidenceID: evidenceID, EvidenceIDs: decisionEvidenceIDs(evidenceID, in.EvidenceIDs), + SupportingRefs: cloneSubjectRefs(in.SupportingRefs), VEXDocumentID: vexID, Supersedes: supersedes, ApprovedBy: actorID, @@ -1257,6 +1265,115 @@ func (l *Ledger) validateDecisionEvidenceLinksLocked(tenantID, releaseID string, return ids, nil } +func (l *Ledger) validateDecisionSupportingRefsLocked(tenantID, releaseID string, refs []domain.SubjectRef) ([]domain.SubjectRef, error) { + if len(refs) == 0 { + return nil, nil + } + if releaseID == "" { + return nil, ErrValidation + } + release, ok := l.releases[releaseID] + if !ok || release.TenantID != tenantID { + return nil, ErrNotFound + } + if len(refs) > 20 { + return nil, ErrValidation + } + seen := map[string]struct{}{} + out := make([]domain.SubjectRef, 0, len(refs)) + for _, ref := range refs { + typ := strings.ToLower(strings.TrimSpace(ref.Type)) + id := strings.TrimSpace(ref.ID) + if typ == "" || id == "" || strings.TrimSpace(ref.Digest) != "" { + return nil, ErrValidation + } + normalized := domain.SubjectRef{Type: typ, ID: id} + key := normalized.Type + "\x00" + normalized.ID + if _, ok := seen[key]; ok { + return nil, ErrValidation + } + seen[key] = struct{}{} + if !l.decisionSupportingRefInScopeLocked(tenantID, release.ProductID, releaseID, normalized) { + return nil, ErrNotFound + } + out = append(out, normalized) + } + sort.Slice(out, func(i, j int) bool { + if out[i].Type == out[j].Type { + return out[i].ID < out[j].ID + } + return out[i].Type < out[j].Type + }) + return out, nil +} + +func (l *Ledger) decisionSupportingRefInScopeLocked(tenantID, productID, releaseID string, ref domain.SubjectRef) bool { + switch ref.Type { + case "approval": + approval, ok := l.approvals[ref.ID] + return ok && approval.TenantID == tenantID && l.approvalSupportsReleaseLocked(tenantID, productID, releaseID, approval) + case "exception": + exception, ok := l.exceptions[ref.ID] + return ok && exception.TenantID == tenantID && exception.ReleaseID == releaseID + case "waiver": + waiver, ok := l.waivers[ref.ID] + return ok && waiver.TenantID == tenantID && waiverBelongsToPackage(waiver, productID, releaseID) + case "release_bundle": + bundle, ok := l.bundles[ref.ID] + return ok && bundle.TenantID == tenantID && bundle.ReleaseID == releaseID + case "incident": + incident, ok := l.incidents[ref.ID] + return ok && incident.TenantID == tenantID && incident.ReleaseID == releaseID + case "remediation_task": + task, ok := l.tasks[ref.ID] + if !ok || task.TenantID != tenantID { + return false + } + if task.ReleaseID == releaseID { + return true + } + if task.IncidentID != "" { + incident, ok := l.incidents[task.IncidentID] + return ok && incident.TenantID == tenantID && incident.ReleaseID == releaseID + } + return false + default: + return false + } +} + +func (l *Ledger) approvalSupportsReleaseLocked(tenantID, productID, releaseID string, approval domain.ApprovalRecord) bool { + switch approval.SubjectType { + case "release": + return approval.SubjectID == releaseID + case "waiver": + waiver, ok := l.waivers[approval.SubjectID] + return ok && waiver.TenantID == tenantID && waiverBelongsToPackage(waiver, productID, releaseID) + case "customer_package": + pkg, ok := l.customerPackages[approval.SubjectID] + return ok && pkg.TenantID == tenantID && pkg.ProductID == productID && pkg.ReleaseID == releaseID + case "contract_diff": + diff, ok := l.contractDiffs[approval.SubjectID] + return ok && diff.TenantID == tenantID && diff.ProductID == productID && diff.ReleaseID == releaseID + case "security_review": + doc, ok := l.manualDocs[approval.SubjectID] + return ok && doc.TenantID == tenantID && doc.ProductID == productID && doc.ReleaseID == releaseID && doc.DocumentType == "security_review" + default: + return false + } +} + +func cloneSubjectRefs(refs []domain.SubjectRef) []domain.SubjectRef { + if len(refs) == 0 { + return nil + } + out := make([]domain.SubjectRef, 0, len(refs)) + for _, ref := range refs { + out = append(out, domain.SubjectRef{Type: strings.TrimSpace(ref.Type), ID: strings.TrimSpace(ref.ID), Digest: strings.TrimSpace(ref.Digest)}) + } + return out +} + func decisionEvidenceIDs(primary string, extra []string) []string { ids := append([]string(nil), extra...) if strings.TrimSpace(primary) != "" { diff --git a/internal/domain/domain.go b/internal/domain/domain.go index b5ae22a..7c9a4a5 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -1259,56 +1259,58 @@ type VEXImportReport struct { } type VulnerabilityDecision struct { - ID string `json:"id"` - TenantID string `json:"tenant_id"` - FindingID string `json:"finding_id"` - ScanID string `json:"scan_id"` - ReleaseID string `json:"release_id,omitempty"` - Vulnerability string `json:"vulnerability"` - Component string `json:"component,omitempty"` - SBOMID string `json:"sbom_id,omitempty"` - SBOMComponentPURL string `json:"sbom_component_purl,omitempty"` - SBOMComponentName string `json:"sbom_component_name,omitempty"` - Status string `json:"status"` - Justification string `json:"justification"` - ImpactStatement string `json:"impact_statement,omitempty"` - ActionStatement string `json:"action_statement,omitempty"` - CustomerVisible bool `json:"customer_visible"` - InternalNotes string `json:"internal_notes,omitempty"` - Source string `json:"source"` - EvidenceID string `json:"evidence_id,omitempty"` - EvidenceIDs []string `json:"evidence_ids,omitempty"` - VEXDocumentID string `json:"vex_document_id,omitempty"` - Supersedes string `json:"supersedes,omitempty"` - SupersededBy string `json:"superseded_by,omitempty"` - ApprovedBy string `json:"approved_by,omitempty"` - ReviewedAt *time.Time `json:"reviewed_at,omitempty"` - ReviewDueAt *time.Time `json:"review_due_at,omitempty"` - SchemaVersion string `json:"schema_version"` - CreatedAt time.Time `json:"created_at"` + ID string `json:"id"` + TenantID string `json:"tenant_id"` + FindingID string `json:"finding_id"` + ScanID string `json:"scan_id"` + ReleaseID string `json:"release_id,omitempty"` + Vulnerability string `json:"vulnerability"` + Component string `json:"component,omitempty"` + SBOMID string `json:"sbom_id,omitempty"` + SBOMComponentPURL string `json:"sbom_component_purl,omitempty"` + SBOMComponentName string `json:"sbom_component_name,omitempty"` + Status string `json:"status"` + Justification string `json:"justification"` + ImpactStatement string `json:"impact_statement,omitempty"` + ActionStatement string `json:"action_statement,omitempty"` + CustomerVisible bool `json:"customer_visible"` + InternalNotes string `json:"internal_notes,omitempty"` + Source string `json:"source"` + EvidenceID string `json:"evidence_id,omitempty"` + EvidenceIDs []string `json:"evidence_ids,omitempty"` + SupportingRefs []SubjectRef `json:"supporting_refs,omitempty"` + VEXDocumentID string `json:"vex_document_id,omitempty"` + Supersedes string `json:"supersedes,omitempty"` + SupersededBy string `json:"superseded_by,omitempty"` + ApprovedBy string `json:"approved_by,omitempty"` + ReviewedAt *time.Time `json:"reviewed_at,omitempty"` + ReviewDueAt *time.Time `json:"review_due_at,omitempty"` + SchemaVersion string `json:"schema_version"` + CreatedAt time.Time `json:"created_at"` } type VulnerabilityDecisionCustomerSummary struct { - ID string `json:"id"` - FindingID string `json:"finding_id"` - ScanID string `json:"scan_id"` - ReleaseID string `json:"release_id"` - Vulnerability string `json:"vulnerability"` - Component string `json:"component,omitempty"` - SBOMID string `json:"sbom_id,omitempty"` - SBOMComponentPURL string `json:"sbom_component_purl,omitempty"` - SBOMComponentName string `json:"sbom_component_name,omitempty"` - Status string `json:"status"` - Justification string `json:"justification,omitempty"` - ImpactStatement string `json:"impact_statement"` - ActionStatement string `json:"action_statement,omitempty"` - Source string `json:"source"` - EvidenceID string `json:"evidence_id,omitempty"` - EvidenceIDs []string `json:"evidence_ids,omitempty"` - VEXDocumentID string `json:"vex_document_id,omitempty"` - ReviewedAt *time.Time `json:"reviewed_at,omitempty"` - ReviewDueAt *time.Time `json:"review_due_at,omitempty"` - CreatedAt time.Time `json:"created_at"` + ID string `json:"id"` + FindingID string `json:"finding_id"` + ScanID string `json:"scan_id"` + ReleaseID string `json:"release_id"` + Vulnerability string `json:"vulnerability"` + Component string `json:"component,omitempty"` + SBOMID string `json:"sbom_id,omitempty"` + SBOMComponentPURL string `json:"sbom_component_purl,omitempty"` + SBOMComponentName string `json:"sbom_component_name,omitempty"` + Status string `json:"status"` + Justification string `json:"justification,omitempty"` + ImpactStatement string `json:"impact_statement"` + ActionStatement string `json:"action_statement,omitempty"` + Source string `json:"source"` + EvidenceID string `json:"evidence_id,omitempty"` + EvidenceIDs []string `json:"evidence_ids,omitempty"` + SupportingRefs []SubjectRef `json:"supporting_refs,omitempty"` + VEXDocumentID string `json:"vex_document_id,omitempty"` + ReviewedAt *time.Time `json:"reviewed_at,omitempty"` + ReviewDueAt *time.Time `json:"review_due_at,omitempty"` + CreatedAt time.Time `json:"created_at"` } type VulnerabilityDecisionSummaryReport struct { diff --git a/migrations/20260601000800_vulnerability_decision_supporting_refs.down.sql b/migrations/20260601000800_vulnerability_decision_supporting_refs.down.sql new file mode 100644 index 0000000..a3524d9 --- /dev/null +++ b/migrations/20260601000800_vulnerability_decision_supporting_refs.down.sql @@ -0,0 +1,2 @@ +ALTER TABLE IF EXISTS vulnerability_decisions + DROP COLUMN IF EXISTS supporting_refs; diff --git a/migrations/20260601000800_vulnerability_decision_supporting_refs.up.sql b/migrations/20260601000800_vulnerability_decision_supporting_refs.up.sql new file mode 100644 index 0000000..9d86a61 --- /dev/null +++ b/migrations/20260601000800_vulnerability_decision_supporting_refs.up.sql @@ -0,0 +1,2 @@ +ALTER TABLE IF EXISTS vulnerability_decisions + ADD COLUMN IF NOT EXISTS supporting_refs jsonb NOT NULL DEFAULT '[]'::jsonb; diff --git a/openapi.yaml b/openapi.yaml index dccd2c3..f7dcfb5 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CRAVulnerabilityHandlingReport":{"additionalProperties":false,"properties":{"accepted_exceptions":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"CRAVulnerabilityHandlingReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"},"require_nda":{"type":"boolean"},"reviewer_email":{"description":"Optional external reviewer email label. It is not used as an authentication secret.","type":"string"},"reviewer_name":{"description":"Optional external reviewer display name for this package access record.","type":"string"},"watermark":{"description":"Optional customer-visible distribution watermark. It is not a token or secret.","type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireAnswerLibraryEntryRequest":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"}},"required":["answer"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"review_due_at":{"description":"Optional UTC time when this decision should be reviewed again.","format":"date-time","type":"string"},"reviewed_at":{"description":"Optional UTC time when the decision was reviewed. Defaults to creation time.","format":"date-time","type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccess":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"failed_access_count":{"type":"integer"},"id":{"type":"string"},"last_accessed_at":{"format":"date-time","type":"string"},"last_failed_at":{"format":"date-time","type":"string"},"nda_accepted_at":{"format":"date-time","type":"string"},"nda_accepted_by":{"type":"string"},"package_id":{"type":"string"},"prefix":{"description":"Non-secret portal token prefix for operational lookup.","type":"string"},"require_nda":{"type":"boolean"},"reviewer_email":{"type":"string"},"reviewer_name":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"watermark":{"type":"string"}},"required":["id","tenant_id","package_id","customer_name","prefix","expires_at","access_count","failed_access_count","schema_version","created_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"$ref":"#/components/schemas/CustomerPortalAccess"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalAccessEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccess"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CustomerPortalAccess"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"nda_accepted":{"description":"Set true to record acceptance for NDA-gated portal access.","type":"boolean"},"nda_accepted_by":{"description":"Reviewer label recorded when NDA acceptance is required. Do not include secrets.","type":"string"},"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"distribution_watermark":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"remediation":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntry":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","answer","schema_version","created_at"],"type":"object"},"QuestionnaireAnswerLibraryEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"policy_set":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlow":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["needs_evidence","ready_for_review"],"type":"string"},"steps":{"items":{"$ref":"#/components/schemas/ReleaseEvidenceFlowStep"},"type":"array"}},"required":["release_id","product_id","status","counts","steps","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseEvidenceFlowEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseEvidenceFlow"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlowStep":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"idempotency_required":{"type":"boolean"},"method":{"type":"string"},"next_reference":{"type":"string"},"path":{"type":"string"},"required":{"type":"boolean"},"required_scopes":{"items":{"type":"string"},"type":"array"},"status":{"enum":["present","missing","optional"],"type":"string"},"title":{"type":"string"}},"required":["id","title","status","required","method","path","required_scopes","idempotency_required","description"],"type":"object"},"ReleaseSecurityApprovalSummary":{"additionalProperties":false,"properties":{"approved":{"type":"integer"},"total":{"type":"integer"}},"required":["total","approved"],"type":"object"},"ReleaseSecurityExceptionSummary":{"additionalProperties":false,"properties":{"approved_unexpired":{"type":"integer"},"expired":{"type":"integer"},"total":{"type":"integer"},"unapproved":{"type":"integer"}},"required":["total","approved_unexpired","unapproved","expired"],"type":"object"},"ReleaseSecurityMissingDecision":{"additionalProperties":false,"properties":{"component":{"type":"string"},"finding_id":{"type":"string"},"scan_id":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["finding_id","scan_id","vulnerability","severity","state"],"type":"object"},"ReleaseSecurityProductSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"],"type":"object"},"ReleaseSecurityReleaseSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"state":{"type":"string"},"version":{"type":"string"}},"required":["id","version","state"],"type":"object"},"ReleaseSecuritySummary":{"additionalProperties":false,"properties":{"approval_summary":{"$ref":"#/components/schemas/ReleaseSecurityApprovalSummary"},"artifact_count":{"type":"integer"},"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"decisions_by_status":{"additionalProperties":{"type":"integer"},"type":"object"},"exception_summary":{"$ref":"#/components/schemas/ReleaseSecurityExceptionSummary"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_required_decisions":{"items":{"$ref":"#/components/schemas/ReleaseSecurityMissingDecision"},"type":"array"},"open_findings_by_severity":{"additionalProperties":{"type":"integer"},"type":"object"},"package_status":{"enum":["generated","not_generated"],"type":"string"},"product":{"$ref":"#/components/schemas/ReleaseSecurityProductSummary"},"readiness_status":{"enum":["passed","failed"],"type":"string"},"release":{"$ref":"#/components/schemas/ReleaseSecurityReleaseSummary"},"sbom_status":{"enum":["present","missing"],"type":"string"},"schema_version":{"type":"string"},"vulnerability_scan_status":{"enum":["present","missing"],"type":"string"}},"required":["product","release","artifact_count","sbom_status","vulnerability_scan_status","open_findings_by_severity","decisions_by_status","approval_summary","exception_summary","readiness_status","package_status","counts","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseSecuritySummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseSecuritySummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityUpdateEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"fixed_decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incidents":{"items":{"$ref":"#/components/schemas/Incident"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"remediation_tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"SecurityUpdateEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningCustodyReviewReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"object_retention_policies":{"items":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"type":"array"},"report_type":{"type":"string"},"signing_providers":{"items":{"$ref":"#/components/schemas/SigningProvider"},"type":"array"},"tenant_id":{"type":"string"}},"required":["report_type","tenant_id","checks","assumptions","limitations","generated_at"],"type":"object"},"SigningCustodyReviewReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningCustodyReviewReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"review_due_at":{"format":"date-time","type":"string"},"reviewed_at":{"format":"date-time","type":"string"},"sbom_component_name":{"type":"string"},"sbom_component_purl":{"type":"string"},"sbom_id":{"description":"Same-release SBOM that contained the matched component, when available.","type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"review_due_at":{"format":"date-time","type":"string"},"reviewed_at":{"format":"date-time","type":"string"},"sbom_component_name":{"type":"string"},"sbom_component_purl":{"type":"string"},"sbom_id":{"description":"Same-release SBOM that contained the matched component, when available.","type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"examples":{"release-evidence-package":{"summary":"Create a scoped release evidence package","value":{"expires_at":"2026-06-30T00:00:00Z","product_id":"prod_20260527120000","redaction_profile_id":"rp_20260527120000","release_id":"rel_20260527120000","title":"Payments API 1.0.0 release evidence package"}}},"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"get":{"description":"Lists tenant-scoped external reviewer access records without token hashes or token secrets.","operationId":"listCustomerPortalAccess","parameters":[{"description":"Optional customer package id filter.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessListEnvelope"}}},"description":"Customer portal access list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List customer portal access records","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a named, expiring external reviewer access record for a customer package and returns the portal token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/access/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped external reviewer access record; revocation is append-only and the original token cannot be used afterwards.","operationId":"revokeCustomerPortalAccess","parameters":[{"description":"Customer portal access id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessEnvelope"}}},"description":"Revoked customer portal access envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-answer-library":{"get":{"description":"Lists tenant-scoped questionnaire answer library entries with optional question, product, and release filters.","operationId":"listQuestionnaireAnswerLibrary","parameters":[{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by questionnaire question id.","in":"query","name":"question_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryListEnvelope"}}},"description":"Questionnaire answer library entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List questionnaire answer library entries","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a tenant-scoped reusable questionnaire answer draft linked to optional evidence, product, release, or control scope.","operationId":"createQuestionnaireAnswerLibraryEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireAnswerLibraryEntryRequest"}}},"description":"Questionnaire answer library entry creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryEnvelope"}}},"description":"Created questionnaire answer library entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire answer library entry","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"examples":{"release-candidate":{"summary":"Create a release for evidence collection","value":{"product_id":"prod_20260527120000","project_id":"proj_20260527120000","version":"1.0.0-rc.1"}}},"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"examples":{"created-release":{"summary":"Created release response","value":{"data":{"created_at":"2026-05-27T12:00:00Z","id":"rel_20260527120000","product_id":"prod_20260527120000","project_id":"proj_20260527120000","schema_version":"release.v1.0.0","status":"draft","tenant_id":"ten_20260527120000","version":"1.0.0-rc.1"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/evidence-flow/start":{"post":{"description":"Returns a high-level release evidence workflow plan, current evidence counts, required scopes, assumptions, and limitations. This read-only convenience operation does not create evidence.","operationId":"startReleaseEvidenceFlow","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEvidenceFlowEnvelope"}}},"description":"Release evidence flow envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Start release evidence flow","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:read"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/security-summary":{"get":{"description":"Returns a tenant-scoped release security summary for review surfaces without raw evidence payload bytes.","operationId":"releaseSecuritySummary","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseSecuritySummaryEnvelope"}}},"description":"Release security summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release security summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-vulnerability-handling":{"get":{"description":"Returns a CRA-oriented vulnerability handling evidence report without legal compliance, certification, scanner-authority, or release-security conclusions.","operationId":"craVulnerabilityHandlingReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReportEnvelope"}}},"description":"CRA vulnerability handling report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA vulnerability handling report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/custody-review":{"get":{"description":"Returns tenant signing-provider and object-lock verification metadata for deployment custody review. It is evidence metadata only, not legal compliance proof, certification, HSM custody proof, or a secure-deployment guarantee.","operationId":"signingCustodyReviewReport","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningCustodyReviewReportEnvelope"}}},"description":"Signing custody review report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Signing custody review report","tags":["evydence"],"x-scopes":["keys:admin"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"examples":{"failed-readiness-with-gap":{"summary":"Readiness report with a vulnerability decision gap","value":{"data":{"accepted_exceptions":[],"assumptions":["Readiness is based on tenant evidence recorded in Evydence."],"blocking_findings":[{"component":"pkg:apk/openssl@3.1.0-r0","decision_state":"missing","finding_id":"scan_20260527120000:finding:1","release_id":"rel_20260527120000","scan_id":"scan_20260527120000","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"generated_at":"2026-05-27T12:00:00Z","limitations":["Readiness supports technical review and does not prove legal compliance, certification, complete vulnerability coverage, or release security."],"missing_evidence":["vulnerability_decision"],"policy_set":"policy-set.v1.0.0","product_id":"prod_20260527120000","release_id":"rel_20260527120000","report_type":"release_readiness","result":"failed","schema_version":"release-readiness.v1.0.0","summary":{"headline":"Release evidence has one blocking vulnerability decision gap.","human_summary":"Required artifact, SBOM, scan, build, and bundle evidence is present, but one critical finding still needs a valid decision or approved exception.","policy_set":"policy-set.v1.0.0","result":"failed"},"template_version":"release-readiness.v1.0.0"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/security-update-evidence":{"get":{"description":"Returns a security update evidence report for release-scoped fixed decisions, incidents, remediation tasks, and linked evidence without legal or security conclusions.","operationId":"securityUpdateEvidenceReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReportEnvelope"}}},"description":"Security update evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security update evidence report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"examples":{"cyclonedx-release-sbom":{"summary":"Upload a CycloneDX SBOM linked to the release artifact","value":{"artifact_id":"art_20260527120000","payload":{"bomFormat":"CycloneDX","components":[{"name":"payments-api","purl":"pkg:oci/payments-api@sha256-ca978112","version":"1.0.0-rc.1"},{"name":"openssl","purl":"pkg:apk/openssl@3.1.0-r0","version":"3.1.0-r0"}],"specVersion":"1.6"},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"examples":{"not-affected-decision":{"summary":"Record a customer-visible not-affected decision","value":{"customer_visible":true,"evidence_ids":["ev_20260527120000"],"impact_statement":"The shipped artifact does not include the affected runtime path.","justification":"The vulnerable code path is not reachable in this release.","status":"not_affected"}}},"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"examples":{"generic-critical-finding":{"summary":"Upload a generic scanner finding for release triage","value":{"findings":[{"component":"pkg:apk/openssl@3.1.0-r0","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"release_id":"rel_20260527120000","scanner":"generic-json","target_ref":"pkg:oci/payments-api@sha256-ca978112"}}},"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CRAVulnerabilityHandlingReport":{"additionalProperties":false,"properties":{"accepted_exceptions":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"CRAVulnerabilityHandlingReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"},"require_nda":{"type":"boolean"},"reviewer_email":{"description":"Optional external reviewer email label. It is not used as an authentication secret.","type":"string"},"reviewer_name":{"description":"Optional external reviewer display name for this package access record.","type":"string"},"watermark":{"description":"Optional customer-visible distribution watermark. It is not a token or secret.","type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireAnswerLibraryEntryRequest":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"}},"required":["answer"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"review_due_at":{"description":"Optional UTC time when this decision should be reviewed again.","format":"date-time","type":"string"},"reviewed_at":{"description":"Optional UTC time when the decision was reviewed. Defaults to creation time.","format":"date-time","type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"supporting_refs":{"description":"Optional tenant-scoped first-class decision support records from the same release. Supported types are approval, exception, waiver, remediation_task, release_bundle, and incident.","items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccess":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"failed_access_count":{"type":"integer"},"id":{"type":"string"},"last_accessed_at":{"format":"date-time","type":"string"},"last_failed_at":{"format":"date-time","type":"string"},"nda_accepted_at":{"format":"date-time","type":"string"},"nda_accepted_by":{"type":"string"},"package_id":{"type":"string"},"prefix":{"description":"Non-secret portal token prefix for operational lookup.","type":"string"},"require_nda":{"type":"boolean"},"reviewer_email":{"type":"string"},"reviewer_name":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"watermark":{"type":"string"}},"required":["id","tenant_id","package_id","customer_name","prefix","expires_at","access_count","failed_access_count","schema_version","created_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"$ref":"#/components/schemas/CustomerPortalAccess"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalAccessEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccess"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CustomerPortalAccess"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"nda_accepted":{"description":"Set true to record acceptance for NDA-gated portal access.","type":"boolean"},"nda_accepted_by":{"description":"Reviewer label recorded when NDA acceptance is required. Do not include secrets.","type":"string"},"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"distribution_watermark":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"remediation":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntry":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","answer","schema_version","created_at"],"type":"object"},"QuestionnaireAnswerLibraryEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"policy_set":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlow":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["needs_evidence","ready_for_review"],"type":"string"},"steps":{"items":{"$ref":"#/components/schemas/ReleaseEvidenceFlowStep"},"type":"array"}},"required":["release_id","product_id","status","counts","steps","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseEvidenceFlowEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseEvidenceFlow"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlowStep":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"idempotency_required":{"type":"boolean"},"method":{"type":"string"},"next_reference":{"type":"string"},"path":{"type":"string"},"required":{"type":"boolean"},"required_scopes":{"items":{"type":"string"},"type":"array"},"status":{"enum":["present","missing","optional"],"type":"string"},"title":{"type":"string"}},"required":["id","title","status","required","method","path","required_scopes","idempotency_required","description"],"type":"object"},"ReleaseSecurityApprovalSummary":{"additionalProperties":false,"properties":{"approved":{"type":"integer"},"total":{"type":"integer"}},"required":["total","approved"],"type":"object"},"ReleaseSecurityExceptionSummary":{"additionalProperties":false,"properties":{"approved_unexpired":{"type":"integer"},"expired":{"type":"integer"},"total":{"type":"integer"},"unapproved":{"type":"integer"}},"required":["total","approved_unexpired","unapproved","expired"],"type":"object"},"ReleaseSecurityMissingDecision":{"additionalProperties":false,"properties":{"component":{"type":"string"},"finding_id":{"type":"string"},"scan_id":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["finding_id","scan_id","vulnerability","severity","state"],"type":"object"},"ReleaseSecurityProductSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"],"type":"object"},"ReleaseSecurityReleaseSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"state":{"type":"string"},"version":{"type":"string"}},"required":["id","version","state"],"type":"object"},"ReleaseSecuritySummary":{"additionalProperties":false,"properties":{"approval_summary":{"$ref":"#/components/schemas/ReleaseSecurityApprovalSummary"},"artifact_count":{"type":"integer"},"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"decisions_by_status":{"additionalProperties":{"type":"integer"},"type":"object"},"exception_summary":{"$ref":"#/components/schemas/ReleaseSecurityExceptionSummary"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_required_decisions":{"items":{"$ref":"#/components/schemas/ReleaseSecurityMissingDecision"},"type":"array"},"open_findings_by_severity":{"additionalProperties":{"type":"integer"},"type":"object"},"package_status":{"enum":["generated","not_generated"],"type":"string"},"product":{"$ref":"#/components/schemas/ReleaseSecurityProductSummary"},"readiness_status":{"enum":["passed","failed"],"type":"string"},"release":{"$ref":"#/components/schemas/ReleaseSecurityReleaseSummary"},"sbom_status":{"enum":["present","missing"],"type":"string"},"schema_version":{"type":"string"},"vulnerability_scan_status":{"enum":["present","missing"],"type":"string"}},"required":["product","release","artifact_count","sbom_status","vulnerability_scan_status","open_findings_by_severity","decisions_by_status","approval_summary","exception_summary","readiness_status","package_status","counts","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseSecuritySummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseSecuritySummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityUpdateEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"fixed_decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incidents":{"items":{"$ref":"#/components/schemas/Incident"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"remediation_tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"SecurityUpdateEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningCustodyReviewReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"object_retention_policies":{"items":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"type":"array"},"report_type":{"type":"string"},"signing_providers":{"items":{"$ref":"#/components/schemas/SigningProvider"},"type":"array"},"tenant_id":{"type":"string"}},"required":["report_type","tenant_id","checks","assumptions","limitations","generated_at"],"type":"object"},"SigningCustodyReviewReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningCustodyReviewReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"review_due_at":{"format":"date-time","type":"string"},"reviewed_at":{"format":"date-time","type":"string"},"sbom_component_name":{"type":"string"},"sbom_component_purl":{"type":"string"},"sbom_id":{"description":"Same-release SBOM that contained the matched component, when available.","type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"supporting_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"review_due_at":{"format":"date-time","type":"string"},"reviewed_at":{"format":"date-time","type":"string"},"sbom_component_name":{"type":"string"},"sbom_component_purl":{"type":"string"},"sbom_id":{"description":"Same-release SBOM that contained the matched component, when available.","type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"supporting_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"examples":{"release-evidence-package":{"summary":"Create a scoped release evidence package","value":{"expires_at":"2026-06-30T00:00:00Z","product_id":"prod_20260527120000","redaction_profile_id":"rp_20260527120000","release_id":"rel_20260527120000","title":"Payments API 1.0.0 release evidence package"}}},"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"get":{"description":"Lists tenant-scoped external reviewer access records without token hashes or token secrets.","operationId":"listCustomerPortalAccess","parameters":[{"description":"Optional customer package id filter.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessListEnvelope"}}},"description":"Customer portal access list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List customer portal access records","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a named, expiring external reviewer access record for a customer package and returns the portal token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/access/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped external reviewer access record; revocation is append-only and the original token cannot be used afterwards.","operationId":"revokeCustomerPortalAccess","parameters":[{"description":"Customer portal access id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessEnvelope"}}},"description":"Revoked customer portal access envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-answer-library":{"get":{"description":"Lists tenant-scoped questionnaire answer library entries with optional question, product, and release filters.","operationId":"listQuestionnaireAnswerLibrary","parameters":[{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by questionnaire question id.","in":"query","name":"question_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryListEnvelope"}}},"description":"Questionnaire answer library entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List questionnaire answer library entries","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a tenant-scoped reusable questionnaire answer draft linked to optional evidence, product, release, or control scope.","operationId":"createQuestionnaireAnswerLibraryEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireAnswerLibraryEntryRequest"}}},"description":"Questionnaire answer library entry creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryEnvelope"}}},"description":"Created questionnaire answer library entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire answer library entry","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"examples":{"release-candidate":{"summary":"Create a release for evidence collection","value":{"product_id":"prod_20260527120000","project_id":"proj_20260527120000","version":"1.0.0-rc.1"}}},"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"examples":{"created-release":{"summary":"Created release response","value":{"data":{"created_at":"2026-05-27T12:00:00Z","id":"rel_20260527120000","product_id":"prod_20260527120000","project_id":"proj_20260527120000","schema_version":"release.v1.0.0","status":"draft","tenant_id":"ten_20260527120000","version":"1.0.0-rc.1"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/evidence-flow/start":{"post":{"description":"Returns a high-level release evidence workflow plan, current evidence counts, required scopes, assumptions, and limitations. This read-only convenience operation does not create evidence.","operationId":"startReleaseEvidenceFlow","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEvidenceFlowEnvelope"}}},"description":"Release evidence flow envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Start release evidence flow","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:read"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/security-summary":{"get":{"description":"Returns a tenant-scoped release security summary for review surfaces without raw evidence payload bytes.","operationId":"releaseSecuritySummary","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseSecuritySummaryEnvelope"}}},"description":"Release security summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release security summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-vulnerability-handling":{"get":{"description":"Returns a CRA-oriented vulnerability handling evidence report without legal compliance, certification, scanner-authority, or release-security conclusions.","operationId":"craVulnerabilityHandlingReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReportEnvelope"}}},"description":"CRA vulnerability handling report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA vulnerability handling report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/custody-review":{"get":{"description":"Returns tenant signing-provider and object-lock verification metadata for deployment custody review. It is evidence metadata only, not legal compliance proof, certification, HSM custody proof, or a secure-deployment guarantee.","operationId":"signingCustodyReviewReport","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningCustodyReviewReportEnvelope"}}},"description":"Signing custody review report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Signing custody review report","tags":["evydence"],"x-scopes":["keys:admin"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"examples":{"failed-readiness-with-gap":{"summary":"Readiness report with a vulnerability decision gap","value":{"data":{"accepted_exceptions":[],"assumptions":["Readiness is based on tenant evidence recorded in Evydence."],"blocking_findings":[{"component":"pkg:apk/openssl@3.1.0-r0","decision_state":"missing","finding_id":"scan_20260527120000:finding:1","release_id":"rel_20260527120000","scan_id":"scan_20260527120000","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"generated_at":"2026-05-27T12:00:00Z","limitations":["Readiness supports technical review and does not prove legal compliance, certification, complete vulnerability coverage, or release security."],"missing_evidence":["vulnerability_decision"],"policy_set":"policy-set.v1.0.0","product_id":"prod_20260527120000","release_id":"rel_20260527120000","report_type":"release_readiness","result":"failed","schema_version":"release-readiness.v1.0.0","summary":{"headline":"Release evidence has one blocking vulnerability decision gap.","human_summary":"Required artifact, SBOM, scan, build, and bundle evidence is present, but one critical finding still needs a valid decision or approved exception.","policy_set":"policy-set.v1.0.0","result":"failed"},"template_version":"release-readiness.v1.0.0"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/security-update-evidence":{"get":{"description":"Returns a security update evidence report for release-scoped fixed decisions, incidents, remediation tasks, and linked evidence without legal or security conclusions.","operationId":"securityUpdateEvidenceReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReportEnvelope"}}},"description":"Security update evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security update evidence report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"examples":{"cyclonedx-release-sbom":{"summary":"Upload a CycloneDX SBOM linked to the release artifact","value":{"artifact_id":"art_20260527120000","payload":{"bomFormat":"CycloneDX","components":[{"name":"payments-api","purl":"pkg:oci/payments-api@sha256-ca978112","version":"1.0.0-rc.1"},{"name":"openssl","purl":"pkg:apk/openssl@3.1.0-r0","version":"3.1.0-r0"}],"specVersion":"1.6"},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"examples":{"not-affected-decision":{"summary":"Record a customer-visible not-affected decision","value":{"customer_visible":true,"evidence_ids":["ev_20260527120000"],"impact_statement":"The shipped artifact does not include the affected runtime path.","justification":"The vulnerable code path is not reachable in this release.","status":"not_affected","supporting_refs":[{"id":"exc_20260527120000","type":"exception"}]}}},"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"examples":{"generic-critical-finding":{"summary":"Upload a generic scanner finding for release triage","value":{"findings":[{"component":"pkg:apk/openssl@3.1.0-r0","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"release_id":"rel_20260527120000","scanner":"generic-json","target_ref":"pkg:oci/payments-api@sha256-ca978112"}}},"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/site/package-viewer/index.html b/site/package-viewer/index.html index 9bd5159..f1c066f 100644 --- a/site/package-viewer/index.html +++ b/site/package-viewer/index.html @@ -360,7 +360,7 @@

Evydence Package Viewer

{ id: "vex_example", format: "openvex", author: "security@example.test", statement_count: 1, status_summary: { fixed: 1 } } ], vulnerability_decisions: [ - { id: "vd_example", vulnerability: "CVE-2026-0002", component: "pkg:apk/openssl@3.1.0", sbom_id: "sbom_example", sbom_component_purl: "pkg:apk/openssl@3.1.0", sbom_component_name: "openssl", status: "fixed", source: "vex", impact_statement: "The finding is fixed in this release artifact.", action_statement: "Upgrade to this release after normal operator review.", reviewed_at: "2026-05-27T12:00:00Z", review_due_at: "2026-08-25T12:00:00Z" } + { id: "vd_example", vulnerability: "CVE-2026-0002", component: "pkg:apk/openssl@3.1.0", sbom_id: "sbom_example", sbom_component_purl: "pkg:apk/openssl@3.1.0", sbom_component_name: "openssl", status: "fixed", source: "vex", impact_statement: "The finding is fixed in this release artifact.", action_statement: "Upgrade to this release after normal operator review.", reviewed_at: "2026-05-27T12:00:00Z", review_due_at: "2026-08-25T12:00:00Z", supporting_refs: [{ type: "exception", id: "exc_example" }, { type: "release_bundle", id: "bundle_example" }] } ], approvals: [{ id: "appr_example", subject_type: "release", decision: "approved", reason: "Release evidence package reviewed." }], exceptions: [], @@ -413,6 +413,15 @@

Evydence Package Viewer

} return String(value); }; + const formatRefs = (refs) => { + const values = safeArray(refs).map((ref) => { + if (!ref || typeof ref !== "object") { + return ""; + } + return [ref.type, ref.id].filter(Boolean).join(":"); + }).filter(Boolean); + return values.length ? values.join(", ") : "not present"; + }; const pick = (obj, paths) => { for (const path of paths) { const value = path.split(".").reduce((current, key) => { @@ -612,6 +621,7 @@

Evydence Package Viewer

{ label: "Source", value: "source" }, { label: "Reviewed", value: "reviewed_at" }, { label: "Review due", value: "review_due_at" }, + { label: "Supporting links", value: (row) => formatRefs(row.supporting_refs) }, { label: "Impact", value: "impact_statement" }, { label: "Action", value: "action_statement" } ], decisions, "No active customer-visible decisions are present."); From 6c64c386106f1eb3c080d0a75d7f32200a5663f8 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 17:02:17 +0300 Subject: [PATCH 225/287] feat(package): export customer decision proof --- .productization_next_steps_missing.md | 4 +- cmd/evydence/main.go | 69 +++++++++++++++++- cmd/evydence/main_test.go | 32 ++++++-- docs/reference/customer-package-manifest.md | 12 +++ docs/reference/vulnerability-decisions.md | 6 ++ .../end-to-end-release-evidence/README.md | 3 +- .../sample-customer-package-manifest.json | 6 ++ .../sample-customer-package-manifest.sha256 | 2 +- .../sample-customer-package.zip | Bin 3585 -> 4639 bytes internal/app/customer_package_golden_test.go | 7 +- internal/app/governance_packages.go | 58 ++++++++++++++- internal/app/productization_flow_test.go | 11 ++- site/package-viewer/index.html | 8 ++ 13 files changed, 203 insertions(+), 15 deletions(-) diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index 911fb5d..0862beb 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -215,7 +215,7 @@ Implementation rules: - Ensure redaction leakage tests still prove raw payloads and secrets are absent. - Run `make demo-check`, `make package-viewer-check`, and targeted package tests. -## Epic E3 - Make Vulnerability Decisions Fully Buyer-Facing [ ] +## Epic E3 - Make Vulnerability Decisions Fully Buyer-Facing [x] Description: Close the documented decision-model gaps so vulnerability decisions become a durable customer-review object, not only an operational API @@ -279,7 +279,7 @@ Implementation rules: - Add negative tests for cross-tenant and wrong-release links. - Run targeted app/API tests, `make openapi-check`, and `make docs-check`. -### Ticket E3-T5 - Add package-specific customer decision export [ ] +### Ticket E3-T5 - Add package-specific customer decision export [x] Description: Extend customer package/report output so the canonical decision view is package-scoped, customer-safe, and directly reviewable, not only a diff --git a/cmd/evydence/main.go b/cmd/evydence/main.go index c127c07..da47ade 100644 --- a/cmd/evydence/main.go +++ b/cmd/evydence/main.go @@ -427,11 +427,14 @@ type customerPackageVerifyResult struct { } type customerPackageArchiveFiles struct { - Manifest []byte - Metadata map[string]any - Verification map[string]any + Manifest []byte + DecisionExport []byte + Metadata map[string]any + Verification map[string]any } +const customerDecisionExportSchemaVersion = "customer-vulnerability-decisions.v1.0.0" + func verifyCustomerPackage(args []string) error { fs := flag.NewFlagSet("package verify", flag.ContinueOnError) fs.SetOutput(io.Discard) @@ -665,6 +668,8 @@ func readCustomerPackageArchive(path string) (customerPackageArchiveFiles, error if err == nil { err = json.Unmarshal(body, &files.Verification) } + case "vulnerability-decisions.json": + files.DecisionExport, err = readZIPFileLimited(file) } if err != nil { return customerPackageArchiveFiles{}, err @@ -711,6 +716,64 @@ func verifyCustomerPackageArchiveMetadata(archive customerPackageArchiveFiles, r } } } + if exportFile := stringMapField(archive.Verification, "decision_export_file"); strings.TrimSpace(exportFile) != "" { + if strings.TrimSpace(exportFile) != "vulnerability-decisions.json" { + return errors.New("verification.json decision_export_file is unsupported") + } + if len(archive.DecisionExport) == 0 { + return errors.New("customer package archive missing declared vulnerability decision export") + } + if err := verifyCustomerDecisionExportBytes(archive.DecisionExport, result); err != nil { + return err + } + } + return nil +} + +func verifyCustomerDecisionExportBytes(body []byte, result customerPackageVerifyResult) error { + var raw any + if err := json.Unmarshal(body, &raw); err != nil { + return errors.New("customer package decision export is not valid JSON") + } + if err := rejectCustomerPackageSensitiveKeys(raw); err != nil { + return err + } + var export struct { + SchemaVersion string `json:"schema_version"` + PackageID string `json:"package_id"` + ProductID string `json:"product_id"` + ReleaseID string `json:"release_id"` + SourceManifestHash string `json:"source_manifest_hash"` + Decisions []map[string]any `json:"decisions"` + Assumptions []string `json:"assumptions"` + Limitations []string `json:"limitations"` + GeneratedAt string `json:"generated_at"` + } + if err := json.Unmarshal(body, &export); err != nil { + return errors.New("customer package decision export structure is invalid") + } + if strings.TrimSpace(export.SchemaVersion) != customerDecisionExportSchemaVersion { + return errors.New("customer package decision export schema_version is unsupported") + } + if strings.TrimSpace(export.PackageID) != result.PackageID || strings.TrimSpace(export.ProductID) != result.ProductID || strings.TrimSpace(export.ReleaseID) != result.ReleaseID { + return errors.New("customer package decision export scope mismatch") + } + if strings.TrimSpace(export.SourceManifestHash) != result.ManifestHash { + return errors.New("customer package decision export manifest_hash mismatch") + } + if len(export.Decisions) == 0 || len(export.Assumptions) == 0 || len(export.Limitations) == 0 { + return errors.New("customer package decision export missing decisions, assumptions, or limitations") + } + if _, err := time.Parse(time.RFC3339Nano, strings.TrimSpace(export.GeneratedAt)); err != nil { + return errors.New("customer package decision export generated_at must be RFC3339") + } + for _, decision := range export.Decisions { + for _, key := range []string{"id", "vulnerability", "status", "impact_statement"} { + if strings.TrimSpace(stringMapField(decision, key)) == "" { + return fmt.Errorf("customer package decision export missing decision field %s", key) + } + } + } return nil } diff --git a/cmd/evydence/main_test.go b/cmd/evydence/main_test.go index 041decf..914ba93 100644 --- a/cmd/evydence/main_test.go +++ b/cmd/evydence/main_test.go @@ -263,7 +263,18 @@ func TestVerifyCustomerPackageManifestArchiveAndBundle(t *testing.T) { if err := os.WriteFile(manifestPath, body, 0o600); err != nil { t.Fatalf("write manifest: %v", err) } - archivePath := writeTestCustomerPackageArchive(t, dir+"/package.zip", body, hash, "csp_1") + decisionExport := mustMarshalJSON(t, map[string]any{ + "schema_version": "customer-vulnerability-decisions.v1.0.0", + "package_id": "csp_1", + "product_id": "prod_1", + "release_id": "rel_1", + "source_manifest_hash": hash, + "decisions": []any{map[string]any{"id": "vd_1", "vulnerability": "CVE-2026-0001", "status": "fixed", "impact_statement": "Customer-safe impact."}}, + "assumptions": []any{"Package-scoped decisions only."}, + "limitations": []any{"This export does not prove legal compliance or complete vulnerability coverage."}, + "generated_at": "2026-05-28T12:00:00Z", + }) + archivePath := writeTestCustomerPackageArchive(t, dir+"/package.zip", body, hash, "csp_1", decisionExport) bundlePath := writeSignedEvidenceBundle(t, dir+"/evidence-bundle.json", []any{"ev_1"}, "sk_1") if err := verifyCustomerPackage([]string{ "--manifest", manifestPath, @@ -842,21 +853,32 @@ func testCustomerPackageManifest() map[string]any { } } -func writeTestCustomerPackageArchive(t *testing.T, path string, manifest []byte, manifestHash, packageID string) string { +func writeTestCustomerPackageArchive(t *testing.T, path string, manifest []byte, manifestHash, packageID string, decisionExport ...[]byte) string { t.Helper() file, err := os.Create(path) if err != nil { t.Fatalf("create archive: %v", err) } zw := zip.NewWriter(file) - for _, entry := range []struct { + verification := map[string]any{"package_id": packageID, "manifest_hash": manifestHash, "manifest_file": "manifest.json"} + if len(decisionExport) > 0 { + verification["decision_export_file"] = "vulnerability-decisions.json" + } + entries := []struct { name string body []byte }{ {name: "manifest.json", body: manifest}, {name: "package.json", body: mustMarshalJSON(t, map[string]any{"id": packageID, "manifest_hash": manifestHash})}, - {name: "verification.json", body: mustMarshalJSON(t, map[string]any{"package_id": packageID, "manifest_hash": manifestHash, "manifest_file": "manifest.json"})}, - } { + {name: "verification.json", body: mustMarshalJSON(t, verification)}, + } + if len(decisionExport) > 0 { + entries = append(entries, struct { + name string + body []byte + }{name: "vulnerability-decisions.json", body: decisionExport[0]}) + } + for _, entry := range entries { writer, err := zw.Create(entry.name) if err != nil { t.Fatalf("create archive entry: %v", err) diff --git a/docs/reference/customer-package-manifest.md b/docs/reference/customer-package-manifest.md index 0f09dff..41d257c 100644 --- a/docs/reference/customer-package-manifest.md +++ b/docs/reference/customer-package-manifest.md @@ -18,6 +18,7 @@ vulnerability result, or a secure-release guarantee. | `evidence_ids` | Included evidence metadata identifiers after redaction profile filtering. | | `artifact_digests` | Artifact IDs, names, media types, sizes, and digests linked to the release. | | `readiness_summary` | Deterministic readiness checks, gaps, and limitations. | +| `customer_decision_export` | Optional archive file metadata for the package-scoped customer-safe decision export. | | `customer_safe_gaps` | Optional customer-visible gap records filtered through the package redaction profile. | | `verification_material` | Hash algorithm, canonicalization profile, release bundle hashes, and audit-chain summary. | | `reviewer_checklist` | Optional proof-path checklist covering package scope, included evidence, excluded evidence, verification, non-claims, and escalation path. | @@ -56,6 +57,12 @@ schema version, and timestamp. The section deliberately omits raw OpenAPI document bytes, object-store references, and private/internal document extensions. +When customer-visible vulnerability decisions are present, generated package +archives also include `vulnerability-decisions.json`. That file is scoped to the +package, repeats only customer-safe decision fields, records the source manifest +hash, and includes assumptions and limitations. The package verifier validates +the file when `verification.json` declares `decision_export_file`. + ## Exclusions Customer package manifests exclude raw tenant evidence payload bytes, @@ -175,6 +182,11 @@ go run ./cmd/evydence package verify \ --hash sha256: ``` +The checked sample ZIP includes `vulnerability-decisions.json` for the +package-scoped decision export. The verifier checks the export scope and source +manifest hash alongside `manifest.json`, `package.json`, and +`verification.json`. + When an evidence bundle is supplied, the verifier also checks the bundle manifest hash, included signatures, and package evidence-id coverage: diff --git a/docs/reference/vulnerability-decisions.md b/docs/reference/vulnerability-decisions.md index c230c00..55f275a 100644 --- a/docs/reference/vulnerability-decisions.md +++ b/docs/reference/vulnerability-decisions.md @@ -116,6 +116,12 @@ create a superseding decision to attach the new context. Customer package manifests include only active decisions unless a future history-specific export is requested. +Customer package ZIP exports now include `vulnerability-decisions.json` when the +package contains customer-visible decisions. The file is package-scoped, records +the source manifest hash, and repeats only the safe decision fields already +allowed by the redaction profile, plus assumptions and limitations for reviewer +context. + ## Supporting Record Links Manual decisions may include `supporting_refs` when the reviewer wants to point diff --git a/examples/end-to-end-release-evidence/README.md b/examples/end-to-end-release-evidence/README.md index 01df0b2..3014e71 100644 --- a/examples/end-to-end-release-evidence/README.md +++ b/examples/end-to-end-release-evidence/README.md @@ -39,7 +39,8 @@ you use source-checkout commands for local development. - `sample-customer-package-manifest.json`: representative customer package manifest with a reviewer checklist and without raw tenant payload bytes. - `sample-customer-package.zip`: downloadable fixture with `manifest.json`, - `package.json`, `verification.json`, and `README.txt`. + `package.json`, `verification.json`, `vulnerability-decisions.json`, and + `README.txt`. - `sample-audit-chain-verification.json`: representative audit-chain verification result. diff --git a/examples/end-to-end-release-evidence/sample-customer-package-manifest.json b/examples/end-to-end-release-evidence/sample-customer-package-manifest.json index 2dec809..b879f0a 100644 --- a/examples/end-to-end-release-evidence/sample-customer-package-manifest.json +++ b/examples/end-to-end-release-evidence/sample-customer-package-manifest.json @@ -155,6 +155,12 @@ "created_at": "2026-05-27T12:00:00Z" } ], + "customer_decision_export": { + "file": "vulnerability-decisions.json", + "schema_version": "customer-vulnerability-decisions.v1.0.0", + "decision_count": 1, + "scope": "package" + }, "readiness_summary": { "result": "passed", "checks": [ diff --git a/examples/end-to-end-release-evidence/sample-customer-package-manifest.sha256 b/examples/end-to-end-release-evidence/sample-customer-package-manifest.sha256 index 3315e4b..b54ae64 100644 --- a/examples/end-to-end-release-evidence/sample-customer-package-manifest.sha256 +++ b/examples/end-to-end-release-evidence/sample-customer-package-manifest.sha256 @@ -1 +1 @@ -768ab2e353125b055c5f2d24ce4e278f52747bd14d52551fc97cc2585b577180 sample-customer-package-manifest.json +cb4ddb298d888c0d7512eddfcfc38d617fe463d90020f012a0210d6aa238bcb1 sample-customer-package-manifest.json diff --git a/examples/end-to-end-release-evidence/sample-customer-package.zip b/examples/end-to-end-release-evidence/sample-customer-package.zip index 7aa230d70ac0a168ddd12d095631b040f3a16773..aeb3d84452513cafbe86c7a179ea13a2c5a32262 100644 GIT binary patch literal 4639 zcmaJ_WmJ@1+a0=wkdScbPHDuUL12{blCGg)h(TZol@_E029S_cKpARi1SAA$B!=z= zkr088=lOm--{ZI5ciro(b^^yS=6LCgRE z>Fut&jR(}x0p=^@0`v4}F?IKxeL#6VZ>4x%vo@nOQ-rzS6hK&gRh`i-X)JI`L71vC z;Kre=rU#iTxVdsX=i2U02xxlnR>98aT=d&l88J{u$fI7RwIHLhlO#y@qZ+vO-M|u5 zX{HAC0J!fbD-?RI@TBh9T;*iNPurNCx$jn1y(BfNwY)*ae&!C#kj>gXIXt=Yizi{=^`8ZV>F zGowdP#pus=wBl30y{lnD^hz*lTJDR%-=PQNRq(-DT_Gb!?|V>9R$CI45;|zjK6Jryn#=S*gx0?pAB3*J(5zz9|cQs86+n z<_}uBv?i)Q`d<7X_-kp~sPZ7ghhFVA#377nX>yPgwT2i{g!eb~OhFRouq}#g4L%>v#Nj37`o6pTr zTsv9Vm9o*GQ#W>2jJFYKsddM_L3`y2>N${yoQdSx8o**X%v{!toqz<356{&{rB$9l zbxhs;N6i#uP3F^b zBhl5=8tuGl-LjRAZA}ZI@~KvX#@^QH;Ov=nNPu6OcF_ld2<>&IRC?7+aF0+`&3pO1X7y^6bCQxyV(0S|{a`j6`eP=O z^=^uL=f2N6fnZkG3N=J8|4234vBShC8AgikSwcMBdX|MvaoU`|xQy9@FlPqqFIdm} zY5@0Cw&=r_up3m60#`b(v1kP|wK!+#4?=hr;*f2*Hi)^Z3Rgbz@LG_##dBI?VRVAt zUT#K^uT7p_5Xn*Tq9(o0e7uuwZggB^SjK{l*~55mwXIMD8uGqla%WFR^37a@)@;;N zfx|1kiA358&0aRkQ2e2lI*DJTP9eq9M^0X80=5Gzr-N61H?q0ixnoMJIU>U%c}n?W z7A^`uLxTv}QlC>fmz;H;7gnW&`VJT~On*2N@A{PR+*|C;j={s7c>G_c_1RoB4W`T9 zCl{-pByi7PEBFk?!n)2#f7k$RN$CnuIhUR*luJe6D6b#O5w$U0mom{fds-1(;5QnV zWc32D%Ppt8*A*Z%c8b-XJx=>pF?CAtS%8;(YU`}nvRk-cqbV@0QLq<7)XkgJD6lEA)Z7uy^elM<UyDy9Q1 z54yzDtv1<;_6K-K7*#mXL7jM9Ob_K3+|4(A@Xw)pc2 z-KFVv;WMPr-85O}q~|(YG`hd_kaX^j)#c)=DoK`|zO`Z%M#9mtxO~^ltQvj~rly*A zDV~L9<*}$C69;p%R*2-AgB_fO{GAQrVqU2@`Q-v^D%6g2Qo}3?NDnSA_Zt4m9SsW@ z4e&{SA<4Q58OQi7ZR#zntA%!t*L;r8WezU%=7Z%{df?EM)7mxxpBx`C*SEchTuTP} z5O)-$G=Qo(>UE+*&=<1Fbs@&1P8_}B^w!HTE%E}=EjX`&LolC++?uvDk>RFjPT2PP z1+X;ul{k6&EVhf}uT^t&IJyQ$WiC0alkx-bq@6>n-K3}V#SB>lvx)?TKtEQJwe*&B zKn%wCxSb3ahsrqQH{7++g4NcB?&#=4O&GU`EGmVLK5K7_pX-_)g}{fx3``W)ja6Ds z)xu&NMWRlILpr;^cQ~?=m3}?j}*zQ^^n zQdvo}giyZ2-^q_XHX95(zOU}M(gzFK5E`8`oIW>YS;#h+Zc4g*`#kGJI=8o#B8+&6 zpi`Mw=ObmhT7iPRtrRbDJYei=WNk_~UEMct{jM~)u(*Hv%z#@6+Lh(~&og*s$uI~vCl$k)`+(L`nrzJ$ADCK))0 zFRT-rIx^}GfKzXKqHdhVBb)-#wpfQj3!A4O4t)d`+J2pGhwA(*$EY)kdoyAI02{Xh zc$;IqZ0uZZoE-j+F;8E2czkA|P&v3D9@v=iiT;=~cS#`qGeQ_BLYi>LTFP)D^nMql z!eF^`Xf_jbHDhlo1cHaz%dAETaMM6zWA7Hpdi3R&F9!`+QASlvkX^^P#y<6HRt!a^ zLultkEiRl%Cy#sYn{^OKddYKik|T%Lhxdw-i(DNr{;74o+|-0gO1=_XI|)ihOoA9S zI-N`OR!nKVUJ`oN)4X>AgN6*TRZGZR<&H6O&?;)v-j#Sqx?fatBaO2kYWT)!Iu487 zi3FKwSug9vTzseUkfLU6sixWjc|o+M)L;I7KZG^+!4kK{;%MX4v*C`p?JC#Dr_}?X zyRQ;=J?cg&l}hFwq~uswLleiFzj8I6&J_J7SQ`jncA5+JL;(IxV^Yvht(jX2#c=?D zJGV6YJNQ5yp>{UDP*0D)xir-4@R$__wrubd=Ivqo?agetH__suF_9f_Ir)qV)gw8$ zk0P%wdB8`LDT2pKEoySt^H}yck@?CnFUv1WsVxe3@db7^1hk(PYCp6cAHw&zTBM|H zgNtm6g?mXRzrq@(GI5GiklcJ@_SkA=l{d_XDW1x?eav(WPiTla%{$|;nnxG|whRj# zR<(}i;3rf?zEUQ-0`aa6Q$2x4@Anc*$6Mx!P=cWAv}Qz=H!OGJC>YI;ih8-TnraAV zh{Yhu*_&tKEQ?U_-|(9L$|r8jEqD=>=H zLL-f2|MV(B+lqzO)|TTP4JL9RSi9%gv+7lX7;boaUYI^ej|@iEEU6tSTrE$TVr7l& z>IzyRLI`akhg}}A`aiz+cmzX2&fGD*E5?O)b$>qN6vAg(_v(FCU1jz!2oK*AUKR7S zkcr8n>XPDlu{Y{_6&tP86NLs26Z_2flBN7(c|?}ityR2NiEhNaDtyg~TM6ydrW}r3 zv!y=mRjdpO2^^%X0oN}D1#qiboOp2!U@n+hrYbAR&;K`rZ zq7bDh4#*Vs_4hkTEhSrD8*{i!n})Xtdxu z8Angow3@*K9|gNUuQbsf4r6!n161@Hu8ZuF#yNwD@ESbuvrN+213mrgnxOnSK@p&2H`y&}n z#}T-O8EK@bdX=BbZ)al*WRXC4hyCl)06N9sp@zfUSamm+*O&4v;@M&GbsC`z0bMT7 zsU+}{+8G)LtW2VNeaZbst22<{_fogIlB(uv%c7p@5S0EvktHJ ztt%yAL&_v$ug@5H`;)g>7%6a$U2=AtC`p&m? z=S+pe^{B)CLOgf3L24a`^gz45S;+5)kZJyh{RH0%Gp(^DnDG;yO2fwTsUz#dRU&Z5 z_TV$cA_fG|AzKN)fbx05lMJrpcCjy9k`j4nsyMMWOYfhEZwo^Yc+Q4hMDisevq6@9 z$ktYkIu_qV{6X8DAa76F?)@<|-0Z{V!ND$p7q1zz<1Ehhk^yO6RMwjL%fp(6-r;Lw zUBV#4y(gow5qgAk&fkjstx;%&*IH4+=6Vfsyc}|sW{P|=7V4^mTlAbQ(U!gno(}3@ zb?!?zqaaV26=;iQsj*3AS_dR$q(IjR=HO#;xE0w>}0a3jb^NuNKFj&_8p;Ux5FG_TF|${%@-I6Zz-U`45u( z)I*B*Xn-& DLP%0s literal 3585 zcmZ`+S5y<)woQHEG=(6bhTfzw=eKv9eLZiZf`Y}pg8Y05wzhuU^33;#Yp(88S_*tl$Xk3tMK8ltmDJCW$kC5( zGgz&kdnI6vySUg97B?BlMD#Leqh?N$R$6+N;}oH_?wCY8$lfWtrKR!81P#Ozz<8FZ3H3>>D@b@H&{$dr7zn$6g zKHe#E2$JA1;jvtK8!dwEvzRYgjW~kabtK}f!=9~9?{b}<_)el^t4x=rkGH0KR-7W4 zKQ?laquqtj8%d7kEU>BrXa)V{P*~Tfj@w1>>4yuwv}l6Uf=A8g6JKpeBI@(E>p1D+ z+X7Y=AuX%u(!_Nt(K0ljjBY?(?ya4({fXlz*7lwx4OfolhvU6m2IWpMlb)YZV*E%4 z2z6F304Y-Hp~HSp*KWkkq2k)O7GG#dIOP{2x;e(cOr91yCB^6Ta#76!h?yAgjahql z<=0$fx46=tFe7i!kKrAYIy=PH>hOBrAm5Cgt=3;_ZXDg_BeE(+QHyNM*9427q@>dI zkj7LRE_zTBTQ)h}d(^r0|H{TuEuYb8lGRBE+g)mLbrT<@eCkLqtbGbbp4rSng2t{d z=VfD2+tfPcngiewMC^j%r$OB_4I$+C*;JU|mR7gH)mJv9jf`&O@7XT>X4TGnfmF!R zan37|X)rR;P2)AG@`_0pdNMH~7b_J5`#VbV&bt9f%Ug=(DQ;*a6HtWnmAO{?7b+c6 zr_V`4Gh6iYmlEV5NP_|imQitQxk0sQ@8Sy5V?a@4FemG|OIGxcED>x#MIMU3e(|Nz z$8yr2!ku* zyWY5I2S4$eQG?JXbb9}^26o& zz*0N~{yo(!S#|u%B`EU-v3S(ydKn0F-%mhnsh4_(RlrnmtGJ_Y2gP$wG!GShj5|>7 z?Wi=MhsHm?)~1!O<^o@?G&>z`Y~(1djU3MKf zd?6=)1t;>0x+3KbRW~C<=gpQb+3HC;Y$g(Fb{n%#e$7b3ucFRW?>!ABKgh-e`lI6< zE?hX_@wWWL2nI50bZ8Gp4~&UEZYAcRQrvETqiNvU$?u@1dKWNJ_wX>J@t$ni>F{@; zkQ${FOi-MeSS>@N^Mc;@I>>X ztEPwVH*q{A`W+@?FLCB;`bZix1W|a<_DN_`GLa znthmpR=Rq}8|7jyc1sLb?Je$+)(8eaOZ)p@M#FNFQ)(1Ly|lgCF%g_Um3O|;x--S) ztw|Oesl17ITa)c?mOVvzG7DjpkEV$;8cL5kf&OJ=my)p(M*j7gOl~U3>P^NwTI%6v z3LzpA9D;q00@yUu%QlCQrC3nRco5ErHLN#OJiMovq1-pHMfiPqM1TZaE?KK`UmV{q zG9(9CV=*f;_6X_L-@dw-pAFt>Z*ASLa>Pn$f8i7n9Xxgn5iW<-vy9@X{G^XwjCR z479K{9DYG$(s>Yrdivn;Bb8PvQ{!18@TM=K)9IljIKqhnB#D(2DU?PpQdxp1lOogv zJ|)A392TYp!=0$m2?-4j}yRDgs3WJ zaG2V$VjsYY)L{HxbQGVldG1C^h1YIK>UHYqc24PSQ8$78l`q@pwa!7%4A^oYAPQ_s zy3X~+=&oDp4kEKKxX%+2F6gdyK$G~{=B_V!285l4u=9?OX*_+Wl1yG^ZY-(U)Y?e_ z1XHh5?^mf21G6FJ6elum2=hYrY!{)bD#pcH{NN8Eu)UOFpyt=sqCyh(+Isne4fitP zWT0_oX|u;mk)`@k@3f+Re9L`NUa;v4Rn;^eaF*w(eX`bNsrdLeTmV4PI`#2I_~~_o z)`jLPwX^MbV_`?lj5?gpj;49Xg^z93qfcoIGTI;I|Kz+!KpP>yGjaZ6(8+~oUa{xd zs)U*Q#>s-=_To`c{4Z2oja|g`F10s*A-A9c7BM^H1Gn`IWtsd@4&AsYrgA=4qU~D5 z_jrS0g-7j;BTGr?MPAYOshF&&l`LprQ+*K1Gu#(1Z@hdZcm=JGuP$BK(~v3(ap!3V;LiE*0wFD&^p zInduLD6tiZ#cE$IurTWdy#jK%`?qhV?S$%8tc-|Xzk0Q!D;$ncJXwZo?Ef?iYs&L_ zsf$kw@t!yx{(Mje;b>f#NS^a+Hf$OL7OtaiyRu8vFE}r(r zVmUO|=Q%k*x4Pv2NmS0IJSpNiNrw~w0LwX1p{PL5+n%n@!JdA;|6m(NgtgFb7F}zA-LvbAB^$nA)lb|{e+4JCMg_H6*Q4|e?UNY&q@1hSPBXqRB`e)LB=tuI? zXdcTD=?HPP(a=8B!d0_toQXM0rO90p-*k|NDm#(7X|=q6NA){Xn@%{Hba-PK zyy2U>ymGZ9$3I?uA~=}2k+$2_bOUrf(I+L%Z8*^&N$W@R)0&zsxM?q@)2MiRtF3ux zixN@v6#Dh8!;rIxnorUqb;b(6Y(J+EB6;DN&qk0@nXVs$pl?b@W^o%kH3A#pYiLAD8>X)2XV-9b!EBDSFPG@f)@?#d@4zzmv#8}_<^IaIVGM7ds1%jd! z(;zu}B?(WJAQiC3!v6Tm2b-HSC5BQ&WZP06&b7s5NzZFGRp0kvkY3ZWl3EeZ9*+*K zxl0pA1Z^cZlw(vXqvDzQkEYnvvdO29q^m;d<(aCs#ri_s(nc}f$oAK1N30gJR&t{( z6yv-URjDNoL2_TKKo~8IJHtXyf7K8^zL$dncBbmu#+x>>wi8Cus+7}r?$J#*K<3ao zD%8z7AicL@=B}g7Hii}0^<(rUEyPy3X1<*>2&8~q_}>fAIgNmGIsqjQe|P^_hyH~A z=}*4_{}289e53kLxB3(L=fM6O*+=tV#`jP7pSu4WPN4hGUtnSY0{?!aJU`^~diL8z G0sjYz0%+O* diff --git a/internal/app/customer_package_golden_test.go b/internal/app/customer_package_golden_test.go index 4dd2fcd..145a82f 100644 --- a/internal/app/customer_package_golden_test.go +++ b/internal/app/customer_package_golden_test.go @@ -40,6 +40,7 @@ func TestSampleCustomerPackageManifestGolden(t *testing.T) { "readiness_summary", "verification_material", "reviewer_checklist", + "customer_decision_export", "limitations", "non_claims", } { @@ -76,9 +77,13 @@ func TestSampleCustomerPackageManifestGolden(t *testing.T) { if !ok { t.Fatalf("manifest fixture decision is not an object: %#v", decisions[0]) } - for _, key := range []string{"reviewed_at", "review_due_at", "sbom_id", "sbom_component_purl", "sbom_component_name"} { + for _, key := range []string{"reviewed_at", "review_due_at", "sbom_id", "sbom_component_purl", "sbom_component_name", "supporting_refs"} { if firstDecision[key] == "" || firstDecision[key] == nil { t.Fatalf("manifest fixture decision missing %q: %#v", key, firstDecision) } } + export, ok := manifest["customer_decision_export"].(map[string]any) + if !ok || export["file"] != "vulnerability-decisions.json" || export["schema_version"] != "customer-vulnerability-decisions.v1.0.0" { + t.Fatalf("manifest fixture customer decision export missing expected metadata: %#v", manifest["customer_decision_export"]) + } } diff --git a/internal/app/governance_packages.go b/internal/app/governance_packages.go index 53b62bd..413b86d 100644 --- a/internal/app/governance_packages.go +++ b/internal/app/governance_packages.go @@ -61,6 +61,11 @@ type CustomerPackageArchive struct { Size int64 } +const ( + customerDecisionExportFile = "vulnerability-decisions.json" + customerDecisionExportVersion = "customer-vulnerability-decisions.v1.0.0" +) + type CreateReportTemplateInput struct { Name string Version string @@ -451,6 +456,12 @@ func (l *Ledger) customerPackageManifestLocked(packageID string, generatedAt tim } if decisions := l.packageDecisionSummariesLocked(tenantID, releaseID, profile); len(decisions) > 0 { manifest["vulnerability_decisions"] = decisions + manifest["customer_decision_export"] = map[string]any{ + "file": customerDecisionExportFile, + "schema_version": customerDecisionExportVersion, + "decision_count": len(decisions), + "scope": "package", + } } if profileAllowsPackageType(profile, "approval") { manifest["approvals"] = l.packageApprovalSummariesLocked(tenantID, productID, releaseID) @@ -1280,6 +1291,7 @@ func cleanExternalLabel(value string) string { func customerPackageArchive(pkg domain.CustomerSecurityPackage) (CustomerPackageArchive, error) { var buf bytes.Buffer zw := zip.NewWriter(&buf) + decisionExport := customerPackageDecisionExport(pkg) metadata := map[string]any{ "id": pkg.ID, "product_id": pkg.ProductID, @@ -1293,6 +1305,9 @@ func customerPackageArchive(pkg domain.CustomerSecurityPackage) (CustomerPackage "schema_version": pkg.SchemaVersion, "created_at": pkg.CreatedAt.UTC().Format(time.RFC3339), } + if decisionExport != nil { + metadata["decision_export_file"] = customerDecisionExportFile + } if pkg.DistributionWatermark != "" { metadata["distribution_watermark"] = pkg.DistributionWatermark } @@ -1310,8 +1325,11 @@ func customerPackageArchive(pkg domain.CustomerSecurityPackage) (CustomerPackage "This package supports technical evidence review and does not prove legal compliance, certification, or release security status.", }, } + if decisionExport != nil { + verification["decision_export_file"] = customerDecisionExportFile + } readme := "Evydence customer security package\n\n" + - "This ZIP contains a scoped package manifest, package metadata, and verification guidance.\n" + + "This ZIP contains a scoped package manifest, package metadata, verification guidance, and customer-safe decision export when present.\n" + "It intentionally excludes raw tenant evidence payload bytes and bearer tokens.\n" + "Use the manifest hash with Evydence verification records or signed bundles before relying on package contents.\n" for _, entry := range []struct { @@ -1333,6 +1351,18 @@ func customerPackageArchive(pkg domain.CustomerSecurityPackage) (CustomerPackage return CustomerPackageArchive{}, err } } + if decisionExport != nil { + body, err := json.MarshalIndent(decisionExport, "", " ") + if err != nil { + _ = zw.Close() + return CustomerPackageArchive{}, err + } + body = append(body, '\n') + if err := addZIPFile(zw, customerDecisionExportFile, body); err != nil { + _ = zw.Close() + return CustomerPackageArchive{}, err + } + } if err := addZIPFile(zw, "README.txt", []byte(readme)); err != nil { _ = zw.Close() return CustomerPackageArchive{}, err @@ -1354,6 +1384,31 @@ func customerPackageArchive(pkg domain.CustomerSecurityPackage) (CustomerPackage return CustomerPackageArchive{PackageID: pkg.ID, Filename: "evydence-customer-package-" + pkg.ID + ".zip", MediaType: "application/zip", Bytes: body, Hash: hashBytes(body), Size: int64(len(body))}, nil } +func customerPackageDecisionExport(pkg domain.CustomerSecurityPackage) map[string]any { + decisions := packageHTMLRecords(pkg.Manifest["vulnerability_decisions"]) + if len(decisions) == 0 { + return nil + } + return map[string]any{ + "schema_version": customerDecisionExportVersion, + "package_id": pkg.ID, + "product_id": pkg.ProductID, + "release_id": pkg.ReleaseID, + "source_manifest_hash": pkg.ManifestHash, + "decision_count": len(decisions), + "decisions": decisions, + "assumptions": []string{ + "This file contains only active vulnerability decisions included by the package redaction profile.", + "Supporting links are Evydence record type/id pairs scoped by the package manifest.", + }, + "limitations": []string{ + "This export supports technical evidence review and compliance readiness only; it is not legal compliance proof, certification, complete SBOM proof, authoritative vulnerability coverage, or a secure-release guarantee.", + "Decision accuracy depends on tenant-supplied scanner, VEX, SBOM, exception, waiver, approval, and review evidence.", + }, + "generated_at": pkg.CreatedAt.UTC().Format(time.RFC3339), + } +} + func customerPackageHTMLReport(pkg domain.CustomerSecurityPackage, metadata, verification map[string]any) []byte { manifest := pkg.Manifest product := packageHTMLMap(manifest["product"]) @@ -1458,6 +1513,7 @@ func customerPackageHTMLReport(pkg domain.CustomerSecurityPackage, metadata, ver b.WriteString("

Verification

") packageHTMLRow(&b, "Manifest File", packageHTMLString(verification["manifest_file"])) packageHTMLRow(&b, "Manifest Hash", packageHTMLString(verification["manifest_hash"])) + packageHTMLRow(&b, "Decision Export", packageHTMLString(verification["decision_export_file"])) packageHTMLRow(&b, "Hash Algorithm", packageHTMLString(verification["hash_algorithm"])) packageHTMLRow(&b, "Verification Note", packageHTMLString(verification["verification_note"])) b.WriteString("
") diff --git a/internal/app/productization_flow_test.go b/internal/app/productization_flow_test.go index 4852438..ea9f863 100644 --- a/internal/app/productization_flow_test.go +++ b/internal/app/productization_flow_test.go @@ -184,7 +184,7 @@ func TestVEXFirstReleaseEvidenceFlowEndToEnd(t *testing.T) { t.Fatalf("export archive: %v", err) } files := packageArchiveFiles(t, archive.Bytes) - for _, name := range []string{"manifest.json", "package.json", "verification.json", "README.txt", "report.html"} { + for _, name := range []string{"manifest.json", "package.json", "verification.json", "README.txt", "report.html", "vulnerability-decisions.json"} { if strings.TrimSpace(files[name]) == "" { t.Fatalf("archive missing %s: %#v", name, files) } @@ -204,6 +204,15 @@ func TestVEXFirstReleaseEvidenceFlowEndToEnd(t *testing.T) { if !strings.Contains(reportHTML, "Release Summary") || !strings.Contains(reportHTML, "Verification") || strings.Contains(reportHTML, "Evydence Package Viewer vulnerability_decisions: [ { id: "vd_example", vulnerability: "CVE-2026-0002", component: "pkg:apk/openssl@3.1.0", sbom_id: "sbom_example", sbom_component_purl: "pkg:apk/openssl@3.1.0", sbom_component_name: "openssl", status: "fixed", source: "vex", impact_statement: "The finding is fixed in this release artifact.", action_statement: "Upgrade to this release after normal operator review.", reviewed_at: "2026-05-27T12:00:00Z", review_due_at: "2026-08-25T12:00:00Z", supporting_refs: [{ type: "exception", id: "exc_example" }, { type: "release_bundle", id: "bundle_example" }] } ], + customer_decision_export: { file: "vulnerability-decisions.json", schema_version: "customer-vulnerability-decisions.v1.0.0", decision_count: 1, scope: "package" }, approvals: [{ id: "appr_example", subject_type: "release", decision: "approved", reason: "Release evidence package reviewed." }], exceptions: [], readiness_summary: { @@ -579,10 +580,17 @@

Evydence Package Viewer

const renderRisk = (data) => { const decisions = safeArray(data.vulnerability_decisions); + const decisionExport = safeObject(data.customer_decision_export); const vexDocs = safeArray(data.vex_documents); const scans = safeArray(data.vulnerability_scans); const findings = safeArray(data.vulnerability_findings).concat(scans.flatMap((scan) => safeArray(scan.findings))); sectionHead(nodes.risk, "Vulnerability / VEX Decisions", String(decisions.length) + " active decisions"); + if (Object.keys(decisionExport).length) { + const exportNote = document.createElement("p"); + exportNote.className = "muted"; + exportNote.textContent = "Package decision export: " + text(decisionExport.file) + " (" + text(decisionExport.schema_version) + ")"; + nodes.risk.append(exportNote); + } const split = document.createElement("div"); split.className = "split"; const scanNode = document.createElement("div"); From 000049798a8463046f17788c4a4a11d547bda62c Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 17:13:23 +0300 Subject: [PATCH 226/287] feat(vex): report cyclonedx import issues --- .productization_next_steps_missing.md | 2 +- cmd/evydence-worker/main.go | 78 +++++++++ cmd/evydence-worker/main_test.go | 21 +++ docs/architecture.md | 4 +- docs/reference/capability-map.md | 2 +- docs/reference/configuration.md | 2 +- docs/reference/production-readiness.md | 10 +- docs/reference/vulnerability-decisions.md | 38 ++-- docs/reference/worker-outbox.md | 11 +- internal/app/parser_versions.go | 1 + internal/app/risk_workflows.go | 204 +++++++++++++++++----- internal/app/risk_workflows_test.go | 71 ++++++++ 12 files changed, 372 insertions(+), 72 deletions(-) diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index 0862beb..6283774 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -302,7 +302,7 @@ Implementation rules: Description: Make VEX import behavior operationally clear for both OpenVEX and CycloneDX VEX without claiming authoritative vulnerability truth. -### Ticket E4-T1 - Add CycloneDX VEX import report details [ ] +### Ticket E4-T1 - Add CycloneDX VEX import report details [x] Description: Extend CycloneDX VEX ingestion to produce format-specific import issues, warnings, mapping failures, created/superseded decision counts, and diff --git a/cmd/evydence-worker/main.go b/cmd/evydence-worker/main.go index c661ee1..2d51003 100644 --- a/cmd/evydence-worker/main.go +++ b/cmd/evydence-worker/main.go @@ -360,6 +360,9 @@ func requireParserVersion(job postgres.ClaimedJob) error { if got == "" { return nil } + if job.Kind == "parse_vex" && (got == app.ParserVersionOpenVEXJSON || got == app.ParserVersionCycloneDXVEXJSON) { + return nil + } if got != expected { return errors.New("unsupported outbox parser version") } @@ -692,6 +695,17 @@ func mergeReplayedVEX(vex domain.VEXDocument, parsed replayedVEX) (domain.VEXDoc } func parseReplayedVEX(raw []byte) (replayedVEX, error) { + var probe struct { + BOMFormat string `json:"bomFormat"` + } + _ = json.Unmarshal(raw, &probe) + if strings.EqualFold(strings.TrimSpace(probe.BOMFormat), "cyclonedx") { + return parseReplayedCycloneDXVEX(raw) + } + return parseReplayedOpenVEX(raw) +} + +func parseReplayedOpenVEX(raw []byte) (replayedVEX, error) { var doc struct { Context any `json:"@context"` ID string `json:"@id"` @@ -737,6 +751,70 @@ func parseReplayedVEX(raw []byte) (replayedVEX, error) { return replayedVEX{Author: strings.TrimSpace(doc.Author), StatementCount: len(doc.Statements), StatusSummary: summary, Statements: statements}, nil } +func parseReplayedCycloneDXVEX(raw []byte) (replayedVEX, error) { + var doc struct { + BOMFormat string `json:"bomFormat"` + SpecVersion string `json:"specVersion"` + Vulnerabilities []struct { + ID string `json:"id"` + Affects []struct { + Ref string `json:"ref"` + } `json:"affects,omitempty"` + Analysis struct { + State string `json:"state"` + Justification string `json:"justification"` + Detail string `json:"detail"` + Response []string `json:"response"` + } `json:"analysis"` + } `json:"vulnerabilities"` + } + if err := strictDecodeWorker(raw, &doc); err != nil || !strings.EqualFold(strings.TrimSpace(doc.BOMFormat), "cyclonedx") || len(doc.Vulnerabilities) == 0 { + return replayedVEX{}, errors.New("replayed vex payload is invalid") + } + summary := map[string]int{} + statements := make([]replayedVEXStatement, 0, len(doc.Vulnerabilities)) + for _, vuln := range doc.Vulnerabilities { + status := workerCycloneDXAnalysisStatus(vuln.Analysis.State) + if strings.TrimSpace(vuln.ID) == "" || status == "" { + continue + } + products := map[string]struct{}{} + for _, affect := range vuln.Affects { + if ref := strings.TrimSpace(affect.Ref); ref != "" { + products[ref] = struct{}{} + } + } + summary[status]++ + statements = append(statements, replayedVEXStatement{ + Vulnerability: strings.TrimSpace(vuln.ID), + Products: products, + Status: status, + Justification: nonEmptyWorker(strings.TrimSpace(vuln.Analysis.Justification), "cyclonedx_vex"), + ImpactStatement: strings.TrimSpace(vuln.Analysis.Detail), + ActionStatement: strings.Join(vuln.Analysis.Response, ","), + }) + } + if len(statements) == 0 { + return replayedVEX{}, errors.New("replayed vex payload is invalid") + } + return replayedVEX{Author: "cyclonedx", StatementCount: len(doc.Vulnerabilities), StatusSummary: summary, Statements: statements}, nil +} + +func workerCycloneDXAnalysisStatus(state string) string { + switch strings.ToLower(strings.TrimSpace(state)) { + case "resolved", "fixed": + return "fixed" + case "not_affected": + return "not_affected" + case "exploitable", "affected": + return "affected" + case "in_triage", "under_investigation": + return "under_investigation" + default: + return "" + } +} + func replayedVEXProductIDs(products []map[string]any) map[string]struct{} { out := map[string]struct{}{} var walk func([]map[string]any) diff --git a/cmd/evydence-worker/main_test.go b/cmd/evydence-worker/main_test.go index 508849d..22c6e0b 100644 --- a/cmd/evydence-worker/main_test.go +++ b/cmd/evydence-worker/main_test.go @@ -339,6 +339,27 @@ func TestProcessJobWithObjectsCreatesVEXDecisionsIdempotently(t *testing.T) { } } +func TestParseReplayedVEXSupportsCycloneDX(t *testing.T) { + body := []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","vulnerabilities":[{"id":"CVE-2026-2001","affects":[{"ref":"pkg:oci/api"}],"analysis":{"state":"resolved","justification":"code_not_reachable","detail":"patched in release artifact","response":["update"]}},{"id":"CVE-2026-2999","analysis":{"state":"unknown"}}]}`) + parsed, err := parseReplayedVEX(body) + if err != nil { + t.Fatalf("parse cyclonedx vex replay: %v", err) + } + if parsed.Author != "cyclonedx" || parsed.StatementCount != 2 || parsed.StatusSummary["fixed"] != 1 { + t.Fatalf("parsed cyclonedx vex summary = %#v", parsed) + } + if len(parsed.Statements) != 1 { + t.Fatalf("statements = %#v, want one valid statement", parsed.Statements) + } + statement := parsed.Statements[0] + if statement.Vulnerability != "CVE-2026-2001" || statement.Status != "fixed" || statement.Justification != "code_not_reachable" || statement.ImpactStatement != "patched in release artifact" || statement.ActionStatement != "update" { + t.Fatalf("statement = %#v", statement) + } + if _, ok := statement.Products["pkg:oci/api"]; !ok { + t.Fatalf("products = %#v, want affected ref", statement.Products) + } +} + func TestProcessJobWithObjectsFailsSafelyForParserMismatches(t *testing.T) { body := []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","components":[{"name":"api"},{"name":"worker"}]}`) hash := digestBytes(body) diff --git a/docs/architecture.md b/docs/architecture.md index a1952dc..a6dced5 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -22,11 +22,11 @@ Instance diagnostics require explicit `instance:admin` scope. Tenant admin and o ## Storage And Append-Only Behavior -When `EVYDENCE_DATABASE_URL` is set, mutations are saved to PostgreSQL before successful responses return. Upload payload bytes, including raw SBOM, vulnerability scan, OpenAPI, OpenVEX, and DSSE build-attestation payloads, are written to the configured object store with tenant-prefixed keys and SHA-256 digest checks before metadata is accepted. +When `EVYDENCE_DATABASE_URL` is set, mutations are saved to PostgreSQL before successful responses return. Upload payload bytes, including raw SBOM, vulnerability scan, OpenAPI, OpenVEX, CycloneDX VEX, and DSSE build-attestation payloads, are written to the configured object store with tenant-prefixed keys and SHA-256 digest checks before metadata is accepted. Evidence, evidence lifecycle events, incidents, remediation tasks, security scans, manual security documents, SBOM diffs, VEX documents, vulnerability decisions/workflow records, organizations, users, role bindings, SSO providers, SSO sessions, legal holds, retention overrides, customer portal access records, questionnaire packages and drafts, evidence summaries, evidence graph snapshots, commercial and marketplace collector definitions, waivers, approvals, customer packages, report templates, evidence bundles, exceptions, build runs, build attestations, release candidates, artifact signatures, source-control records, deployment events, contract diffs, custom policy evaluations, provider verifications, signing operations, control evidence links, public transparency log entries, and release bundle records are append-only in behavior. Changes are represented by supersession, lifecycle events, approval transitions, session revocation, package access records, links, verification receipts, rollback-as-new-event records, or new audit-chain entries. -Outbox jobs are persisted in PostgreSQL and claimed by workers with `FOR UPDATE SKIP LOCKED`. Parser jobs re-read tenant-prefixed object-store payloads, verify size and digest, validate durable state, persist missing parser-derived normalized fields, and fail closed on mismatches. With `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, parser-backed uploads store accepted records and workers populate normalized document fields from replayed payloads. OpenVEX-derived vulnerability decisions are created idempotently by the `parse_vex` worker in that mode. +Outbox jobs are persisted in PostgreSQL and claimed by workers with `FOR UPDATE SKIP LOCKED`. Parser jobs re-read tenant-prefixed object-store payloads, verify size and digest, validate durable state, persist missing parser-derived normalized fields, and fail closed on mismatches. With `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, parser-backed uploads store accepted records and workers populate normalized document fields from replayed payloads. VEX-derived vulnerability decisions are created idempotently by the `parse_vex` worker in that mode. ## Verification And Trust diff --git a/docs/reference/capability-map.md b/docs/reference/capability-map.md index 3c950e3..a2776be 100644 --- a/docs/reference/capability-map.md +++ b/docs/reference/capability-map.md @@ -66,7 +66,7 @@ vulnerability coverage, or a secure-release guarantee. - Polling `cmd/evydence-worker` process that claims persisted outbox jobs with PostgreSQL row locking and records retry or terminal status. - Optional worker-owned parser side effects through - `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, including OpenVEX-derived + `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, including VEX-derived vulnerability decisions created idempotently by the `parse_vex` worker. ## Tooling, Deployment, And Examples diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index cb4b292..2113319 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -39,7 +39,7 @@ The example secrets are placeholders. Replace them before using shared or produc | `EVYDENCE_S3_REGION` | No | empty | Optional S3 region. | | `EVYDENCE_S3_USE_SSL` | No | `false` locally, `true` in chart values | Use TLS for remote object storage. | | `EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE` | No | `0` disabled | Optional in-process per-client request limit using the TCP remote address. Use reverse-proxy or ingress rate limiting for production edge controls. | -| `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS` | No | `false` | Optional hardening mode for parser-backed uploads. When set to `true`, the API stores accepted records and the outbox worker populates parser-derived fields from tenant-prefixed raw payloads after digest verification, including OpenVEX-derived vulnerability decisions. | +| `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS` | No | `false` | Optional hardening mode for parser-backed uploads. When set to `true`, the API stores accepted records and the outbox worker populates parser-derived fields from tenant-prefixed raw payloads after digest verification, including VEX-derived vulnerability decisions. | | `EVYDENCE_SKIP_MIGRATIONS` | No | unset | Set to `true` only when migrations are applied by a separate release process. API and worker startup still verify that no committed migrations are pending and fail closed if the database is behind. | | `EVYDENCE_MIGRATIONS_DIR` | No | `migrations` | Migration directory for API startup and `cmd/evydence-migrate`. | | `EVYDENCE_BOOTSTRAP_TENANT` | No | `Local Tenant` | Tenant name used when bootstrapping an empty store. | diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index d52d07b..685270f 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -53,9 +53,9 @@ Known hardening work remains: - worker parser jobs re-read raw object-store payloads for key formats, verify digests, validate durable state, and persist missing parser-derived normalized fields. CycloneDX SBOM, generic vulnerability-scan, OpenAPI - contract, DSSE build-attestation, and OpenVEX uploads can run with + contract, DSSE build-attestation, OpenVEX, and CycloneDX VEX uploads can run with worker-owned parser side effects by setting - `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; OpenVEX-derived + `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; VEX-derived vulnerability decisions are created idempotently by the `parse_vex` worker in that mode; - OpenAPI precision is enforced across the registered public API. The generated @@ -215,10 +215,10 @@ because they are hardening work on already implemented capabilities: append-only behavior throughout. - Keep worker-owned parser side effects covered as parser formats evolve. CycloneDX SBOM, generic vulnerability scan, OpenAPI contract, DSSE - build-attestation, OpenVEX document metadata, and OpenVEX-derived - vulnerability decisions can be worker-owned behind + build-attestation, OpenVEX document metadata, CycloneDX VEX document metadata, + and VEX-derived vulnerability decisions can be worker-owned behind `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`; SBOM, scan, OpenAPI, and - OpenVEX replay side effects use focused release-ledger mutations when the + VEX replay side effects use focused release-ledger mutations when the PostgreSQL store supports them. - Keep OpenAPI precision at zero broad operations as routes are added or changed, and expand generated SDK coverage from the committed contract. diff --git a/docs/reference/vulnerability-decisions.md b/docs/reference/vulnerability-decisions.md index 55f275a..942980a 100644 --- a/docs/reference/vulnerability-decisions.md +++ b/docs/reference/vulnerability-decisions.md @@ -17,7 +17,7 @@ security. | Raw payload preservation | Raw bytes are stored in object storage through the evidence item payload reference and hash. | | Import linkage | The VEX document links to the created evidence item through `evidence_id`. | | Statement summary | Author, version, statement count, and status summary are recorded when parsed. | -| Parser replay | Worker-owned parser mode can defer normalized VEX fields and OpenVEX-derived decisions to the outbox worker. | +| Parser replay | Worker-owned parser mode can defer normalized VEX fields and VEX-derived decisions to the outbox worker. | `VulnerabilityDecision` records the operational answer for one normalized scan finding: @@ -42,7 +42,7 @@ finding: | Supporting evidence links | `evidence_ids` can link tenant-scoped supporting evidence from the same release. | | Supporting record links | `supporting_refs` can link same-release first-class records: `approval`, `exception`, `waiver`, `remediation_task`, `release_bundle`, and `incident`. | | Audit history | Decision creation appends an audit-chain entry. | -| Import report | `GET /v1/vex/{id}/import-report` exposes safe parser counts, warnings, and mapping failures for OpenVEX imports. | +| Import report | `GET /v1/vex/{id}/import-report` exposes safe parser counts, warnings, invalid-statement issues, and mapping failures for OpenVEX and CycloneDX VEX imports. | ## Canonical Lifecycle @@ -173,7 +173,8 @@ the release must belong to the requested product when both filters are present. ## VEX Import Reports -OpenVEX upload creates a durable import report. The report captures: +OpenVEX and CycloneDX VEX uploads create durable import reports. The report +captures: - parser version; - number of statements parsed; @@ -192,6 +193,10 @@ mode initially stores the report as `accepted`; the worker updates it to `parsed` after replaying the tenant-prefixed payload and applying idempotent decision side effects. +CycloneDX VEX reports include format-specific invalid-statement issues for +missing vulnerability IDs and unsupported analysis states, duplicate mapping +warnings, and no-finding mapping failures. + ## Customer-Safe Summary API `GET /v1/reports/vulnerability-decision-summary?release_id=...` returns active @@ -207,25 +212,24 @@ scanner coverage. The current model is enough to support release-readiness gating, but it is not yet the full buyer-facing VEX decision workflow: -- Decision history can now be queried directly, but it is still a read-only - operational API rather than a dedicated customer-facing export. -- VEX import reports are available for OpenVEX imports. CycloneDX VEX reports - use the same VEX document metadata path but still need format-specific issue - detail in a later increment. +- Decision history can now be queried directly, but it is still an operational + API in addition to the package-scoped customer export. +- VEX import reports cover OpenVEX and CycloneDX VEX, but dry-run preview and + parser-failure visibility still need deeper workflow support. - Customer package manifests can include active `customer_visible` decision summaries when the redaction profile explicitly allows `vulnerability_decision`. They exclude `internal_notes`, raw payload bytes, - and bearer secrets. + and bearer secrets, and package ZIPs include a scoped + `vulnerability-decisions.json` export when such decisions are present. - The dedicated customer-safe summary endpoint is release-scoped JSON. HTML, PDF, and package-specific rendering remain handled by package/report resources. - Decisions now have append-only `reviewed_at` and optional `review_due_at` metadata. Expiry behavior still lives on exceptions and waivers, not decisions. -- Supporting evidence links currently reference evidence-item records. Links to - first-class non-evidence resources such as remediation tasks, approvals, - exceptions, release bundles, or incident packages still need explicit link - modeling or evidence wrappers before they can be attached directly. +- Supporting links now cover evidence-item records and selected same-release + first-class records. Expanding link types to future resources still needs + explicit modeling. - The source SBOM context is direct when a same-release SBOM component matches the finding component. More advanced multi-SBOM disambiguation remains future work. @@ -234,11 +238,9 @@ yet the full buyer-facing VEX decision workflow: The productization backlog should add these changes in order: -1. Add first-class decision links for non-evidence resources that should not be - wrapped as evidence items. -2. Add package-specific customer decision exports that include active - decisions, supporting links, assumptions, and limitations in one - customer-safe view. +1. Add VEX dry-run preview before committing evidence or decisions. +2. Persist safe parser failure details into import reports and worker job + status. These follow-ups should update OpenAPI, HTTP tests, package export tests, and docs together. diff --git a/docs/reference/worker-outbox.md b/docs/reference/worker-outbox.md index d2d2a00..2bec2b5 100644 --- a/docs/reference/worker-outbox.md +++ b/docs/reference/worker-outbox.md @@ -12,17 +12,18 @@ Configured job kinds: - `verify_subject` - `verify_attestation` -Current behavior is intentionally conservative. The API still records normalized signing and verification results before enqueueing jobs for the implemented paths. Parser jobs independently replay tenant-prefixed payload objects when `payload_ref` is present, verify object metadata and byte digests when `payload_hash` is present, parse SBOM, vulnerability-scan, OpenAPI, OpenVEX, and DSSE attestation payloads, and check that replayed payload summaries match the expected durable state. When `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, parser-backed uploads store accepted records first and workers write parser-derived document fields after replay. The `parse_vex` worker also creates OpenVEX-derived vulnerability decisions idempotently in that mode and updates the VEX import report from `accepted` to `parsed` with safe decision and mapping-failure counts. Missing objects, wrong tenant prefixes, tenant mismatches, oversized payload objects, malformed replay payloads, durable-state mismatches, incomplete verification, missing signatures, hash mismatch, uninitialized storage, and unsupported job kinds fail the job safely. +Current behavior is intentionally conservative. The API still records normalized signing and verification results before enqueueing jobs for the implemented paths. Parser jobs independently replay tenant-prefixed payload objects when `payload_ref` is present, verify object metadata and byte digests when `payload_hash` is present, parse SBOM, vulnerability-scan, OpenAPI, OpenVEX, CycloneDX VEX, and DSSE attestation payloads, and check that replayed payload summaries match the expected durable state. When `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, parser-backed uploads store accepted records first and workers write parser-derived document fields after replay. The `parse_vex` worker also creates VEX-derived vulnerability decisions idempotently in that mode and updates the VEX import report from `accepted` to `parsed` with safe decision and mapping-failure counts. Missing objects, wrong tenant prefixes, tenant mismatches, oversized payload objects, malformed replay payloads, durable-state mismatches, incomplete verification, missing signatures, hash mismatch, uninitialized storage, and unsupported job kinds fail the job safely. Parser and attestation jobs include a deterministic `parser_version` payload field for new uploads. Workers reject unsupported parser versions and accept older jobs with no parser version for upgrade compatibility. Parser replay is worker-owned for CycloneDX SBOM, generic vulnerability-scan, -OpenAPI contract, DSSE build-attestation, and OpenVEX document metadata when -`EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`. OpenVEX-derived -vulnerability decision creation is also worker-owned in that mode and uses -deterministic decision IDs to avoid duplicate side effects on retry. +OpenAPI contract, DSSE build-attestation, OpenVEX document metadata, and +CycloneDX VEX document metadata when +`EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`. VEX-derived vulnerability +decision creation is also worker-owned in that mode and uses deterministic +decision IDs to avoid duplicate side effects on retry. Workers use the same object-store environment variables as the API. The default worker payload replay limit is 20 MiB and can be adjusted with `EVYDENCE_WORKER_MAX_PAYLOAD_BYTES`. diff --git a/internal/app/parser_versions.go b/internal/app/parser_versions.go index 7a4bd21..fe177d1 100644 --- a/internal/app/parser_versions.go +++ b/internal/app/parser_versions.go @@ -2,6 +2,7 @@ package app const ( ParserVersionCycloneDXJSON = "cyclonedx-json.v1.0.0" + ParserVersionCycloneDXVEXJSON = "cyclonedx-vex-json.v1.0.0" ParserVersionGenericVulnerabilityJSON = "generic-vulnerability-scan-json.v1.0.0" ParserVersionOpenAPIJSON = "openapi-json.v1.0.0" ParserVersionOpenVEXJSON = "openvex-json.v1.0.0" diff --git a/internal/app/risk_workflows.go b/internal/app/risk_workflows.go index af12161..6a6e252 100644 --- a/internal/app/risk_workflows.go +++ b/internal/app/risk_workflows.go @@ -101,6 +101,25 @@ type CreateCustomPolicyInput struct { const incidentWebhookTimestampTolerance = 5 * time.Minute +type cycloneDXVEXDocument struct { + BOMFormat string `json:"bomFormat"` + SpecVersion string `json:"specVersion"` + Vulnerabilities []cycloneDXVEXVulnerability `json:"vulnerabilities"` +} + +type cycloneDXVEXVulnerability struct { + ID string `json:"id"` + Affects []struct { + Ref string `json:"ref"` + } `json:"affects,omitempty"` + Analysis struct { + State string `json:"state"` + Justification string `json:"justification"` + Detail string `json:"detail"` + Response []string `json:"response"` + } `json:"analysis"` +} + func (l *Ledger) CreateIncident(ctx context.Context, actor domain.Actor, in CreateIncidentInput) (domain.Incident, error) { if err := ctx.Err(); err != nil { return domain.Incident{}, err @@ -820,33 +839,26 @@ func (l *Ledger) UploadCycloneDXVEX(ctx context.Context, actor domain.Actor, rel if len(raw) == 0 || len(raw) > 20<<20 { return domain.VEXDocument{}, ErrValidation } - var doc struct { - BOMFormat string `json:"bomFormat"` - SpecVersion string `json:"specVersion"` - Vulnerabilities []struct { - ID string `json:"id"` - Analysis struct { - State string `json:"state"` - Justification string `json:"justification"` - Detail string `json:"detail"` - Response []string `json:"response"` - } `json:"analysis"` - } `json:"vulnerabilities"` - } - if err := strictDecode(raw, &doc); err != nil || strings.ToLower(doc.BOMFormat) != "cyclonedx" || len(doc.Vulnerabilities) == 0 { + var doc cycloneDXVEXDocument + if err := strictDecode(raw, &doc); err != nil || !strings.EqualFold(strings.TrimSpace(doc.BOMFormat), "cyclonedx") || len(doc.Vulnerabilities) == 0 { + return domain.VEXDocument{}, ErrValidation + } + statusSummary, invalidStatements, validStatements := analyzeCycloneDXVEXStatements(doc) + if len(validStatements) == 0 { return domain.VEXDocument{}, ErrValidation } + releaseID = strings.TrimSpace(releaseID) + artifactID = strings.TrimSpace(artifactID) l.mu.Lock() - if err := l.ensureScopeLocked(actor.TenantID, "", "", strings.TrimSpace(releaseID)); err != nil { + if err := l.ensureScopeLocked(actor.TenantID, "", "", releaseID); err != nil { l.mu.Unlock() return domain.VEXDocument{}, err } - if err := l.authorizeResourceLocked(actor, ScopeEvidenceWrite, resourceRefs{ReleaseID: strings.TrimSpace(releaseID)}); err != nil { + if err := l.authorizeResourceLocked(actor, ScopeEvidenceWrite, resourceRefs{ReleaseID: releaseID}); err != nil { l.mu.Unlock() return domain.VEXDocument{}, err } l.mu.Unlock() - statusSummary := map[string]int{} payloadHash := hashBytes(raw) payloadRef, err := l.storePayload(ctx, actor.TenantID, "vex-cyclonedx", "application/vnd.cyclonedx+json", payloadHash, raw) if err != nil { @@ -863,38 +875,152 @@ func (l *Ledger) UploadCycloneDXVEX(ctx context.Context, actor domain.Actor, rel l.mu.Lock() defer l.mu.Unlock() vex := domain.VEXDocument{ID: newID("vex"), TenantID: actor.TenantID, EvidenceID: item.ID, ReleaseID: releaseID, ArtifactID: artifactID, Format: "cyclonedx", Author: "cyclonedx", Version: doc.SpecVersion, StatementCount: len(doc.Vulnerabilities), StatusSummary: statusSummary, SchemaVersion: domain.VEXDocumentSchemaVersion, CreatedAt: l.now()} - for _, vuln := range doc.Vulnerabilities { + persistedVEX := vex + chainAction := "vex.parsed" + if l.workerOwnedParsers { + persistedVEX.Author = "" + persistedVEX.StatementCount = 0 + persistedVEX.StatusSummary = nil + chainAction = "vex.accepted" + } + l.vexDocuments[vex.ID] = persistedVEX + createdDecisions := 0 + supersededDecisions := 0 + mappingFailures := []domain.VEXImportIssue{} + warnings := []string{} + createdForFinding := map[string]struct{}{} + duplicateWarningAdded := false + for _, statement := range validStatements { + matches := l.findCycloneDXVEXMatchingFindingsLocked(actor.TenantID, releaseID, statement) + if len(matches) == 0 { + mappingFailures = append(mappingFailures, vexImportIssue(statement.index, "finding_not_found", "No matching vulnerability scan finding was found for this CycloneDX VEX vulnerability.")) + } + if l.workerOwnedParsers { + continue + } + for _, matched := range matches { + if _, seen := createdForFinding[matched.finding.ID]; seen { + if !duplicateWarningAdded { + warnings = append(warnings, "Duplicate CycloneDX VEX vulnerabilities for an already mapped finding were ignored.") + duplicateWarningAdded = true + } + continue + } + createdForFinding[matched.finding.ID] = struct{}{} + decision := l.createDecisionLocked(actor.TenantID, matched.scan, matched.finding, CreateVulnerabilityDecisionInput{ + Status: statement.status, + Justification: nonEmpty(statement.vulnerability.Analysis.Justification, "cyclonedx_vex"), + ImpactStatement: strings.TrimSpace(statement.vulnerability.Analysis.Detail), + ActionStatement: strings.Join(statement.vulnerability.Analysis.Response, ","), + CustomerVisible: strings.TrimSpace(statement.vulnerability.Analysis.Detail) != "", + }, "cyclonedx_vex", actor.KeyID, item.ID, vex.ID) + l.decisions[decision.ID] = decision + if decision.Supersedes != "" { + supersededDecisions++ + } + l.appendDecisionLifecycleAuditLocked(actor.TenantID, decision, matched.finding.ID, "api_key", actor.KeyID, payloadHash) + createdDecisions++ + } + } + if len(invalidStatements) > 0 { + warnings = append(warnings, "One or more CycloneDX VEX vulnerabilities were skipped because required analysis fields were missing or unsupported.") + } + if l.workerOwnedParsers { + warnings = append(warnings, "Worker-owned parser side effects are enabled; CycloneDX VEX decisions are created asynchronously after payload replay.") + } + report := domain.VEXImportReport{ + ID: newID("vexrep"), + TenantID: actor.TenantID, + VEXDocumentID: vex.ID, + EvidenceID: item.ID, + ReleaseID: releaseID, + ArtifactID: artifactID, + ParserVersion: ParserVersionCycloneDXVEXJSON, + Status: ternary(l.workerOwnedParsers, "accepted", "parsed"), + StatementCount: len(doc.Vulnerabilities), + DecisionsCreated: createdDecisions, + DecisionsSuperseded: supersededDecisions, + UnsupportedFields: []string{}, + Warnings: warnings, + InvalidStatements: invalidStatements, + MappingFailures: mappingFailures, + SchemaVersion: domain.VEXImportReportSchemaVersion, + CreatedAt: l.now(), + UpdatedAt: l.now(), + } + l.vexImportReports[report.ID] = report + _, _ = l.appendChainLocked(actor.TenantID, chainAction, "vex_document", vex.ID, "api_key", actor.KeyID, payloadHash, "") + jobPayload := map[string]any{"payload_ref": payloadRef, "payload_hash": payloadHash, "parser_version": ParserVersionCycloneDXVEXJSON, "decisions_created": createdDecisions, "import_report_id": report.ID} + if l.workerOwnedParsers { + jobPayload["worker_create_decisions"] = true + jobPayload["actor_type"] = "api_key" + jobPayload["actor_id"] = actor.KeyID + jobPayload["evidence_id"] = item.ID + } + job := l.newOutboxJob(actor.TenantID, "parse_vex", "vex_document", vex.ID, jobPayload) + if err := l.persistReleaseLedgerWithOutboxLocked(ctx, job); err != nil { + return domain.VEXDocument{}, err + } + return vex, nil +} + +type cycloneDXVEXStatement struct { + index int + vulnerability cycloneDXVEXVulnerability + status string + affectedRefs map[string]struct{} +} + +func analyzeCycloneDXVEXStatements(doc cycloneDXVEXDocument) (map[string]int, []domain.VEXImportIssue, []cycloneDXVEXStatement) { + statusSummary := map[string]int{} + invalid := []domain.VEXImportIssue{} + valid := []cycloneDXVEXStatement{} + for index, vuln := range doc.Vulnerabilities { + vuln.ID = strings.TrimSpace(vuln.ID) status := cyclonedxAnalysisStatus(vuln.Analysis.State) - if status == "" || strings.TrimSpace(vuln.ID) == "" { - return domain.VEXDocument{}, ErrValidation + switch { + case vuln.ID == "": + invalid = append(invalid, vexImportIssue(index+1, "missing_vulnerability", "CycloneDX VEX vulnerability is missing an id.")) + continue + case status == "": + invalid = append(invalid, vexImportIssue(index+1, "unsupported_analysis_state", "CycloneDX VEX vulnerability has an unsupported analysis state.")) + continue } statusSummary[status]++ - for _, scan := range l.scans { - if scan.TenantID != actor.TenantID || scan.ReleaseID != releaseID { + valid = append(valid, cycloneDXVEXStatement{index: index + 1, vulnerability: vuln, status: status, affectedRefs: cycloneDXVEXAffectedRefs(vuln)}) + } + return statusSummary, invalid, valid +} + +func cycloneDXVEXAffectedRefs(vuln cycloneDXVEXVulnerability) map[string]struct{} { + out := map[string]struct{}{} + for _, affect := range vuln.Affects { + if ref := strings.TrimSpace(affect.Ref); ref != "" { + out[ref] = struct{}{} + } + } + return out +} + +func (l *Ledger) findCycloneDXVEXMatchingFindingsLocked(tenantID, releaseID string, statement cycloneDXVEXStatement) []matchedFinding { + out := []matchedFinding{} + for _, scan := range l.scans { + if scan.TenantID != tenantID || scan.ReleaseID != releaseID { + continue + } + for _, finding := range scan.Findings { + if finding.Vulnerability != statement.vulnerability.ID { continue } - for _, finding := range scan.Findings { - if finding.Vulnerability != vuln.ID { + if len(statement.affectedRefs) > 0 && finding.Component != "" { + if _, ok := statement.affectedRefs[finding.Component]; !ok { continue } - decision := l.createDecisionLocked(actor.TenantID, scan, finding, CreateVulnerabilityDecisionInput{ - Status: status, - Justification: nonEmpty(vuln.Analysis.Justification, "cyclonedx_vex"), - ImpactStatement: vuln.Analysis.Detail, - ActionStatement: strings.Join(vuln.Analysis.Response, ","), - CustomerVisible: strings.TrimSpace(vuln.Analysis.Detail) != "", - }, "cyclonedx_vex", actor.KeyID, item.ID, vex.ID) - l.decisions[decision.ID] = decision - l.appendDecisionLifecycleAuditLocked(actor.TenantID, decision, finding.ID, "api_key", actor.KeyID, payloadHash) } + out = append(out, matchedFinding{scan: scan, finding: finding}) } } - l.vexDocuments[vex.ID] = vex - _, _ = l.appendChainLocked(actor.TenantID, "vex.parsed", "vex_document", vex.ID, "api_key", actor.KeyID, payloadHash, "") - if err := l.persistReleaseLedgerLocked(ctx, l.releaseLedgerMutationLocked()); err != nil { - return domain.VEXDocument{}, err - } - return vex, nil + return out } func (l *Ledger) RecordVulnerabilityWorkflow(ctx context.Context, actor domain.Actor, in RecordVulnerabilityWorkflowInput) (domain.VulnerabilityWorkflowRecord, error) { diff --git a/internal/app/risk_workflows_test.go b/internal/app/risk_workflows_test.go index 9ea244d..be5ce93 100644 --- a/internal/app/risk_workflows_test.go +++ b/internal/app/risk_workflows_test.go @@ -151,3 +151,74 @@ func TestCycloneDXVEXVulnerabilityWorkflowContractDiffAndPolicyV2(t *testing.T) t.Fatalf("eval = %#v, want missing sbom failure", eval) } } + +func TestCycloneDXVEXImportReportTracksIssuesDuplicatesAndOutbox(t *testing.T) { + outbox := &recordingOutbox{} + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow, Outbox: outbox}) + ctx := context.Background() + actor, release, artifact := setupReleaseRiskFixture(t, ledger) + scan, err := ledger.UploadVulnerabilityScan(ctx, actor, []byte(`{ + "scanner":"grype", + "target_ref":"pkg:oci/payments-api", + "release_id":"`+release.ID+`", + "findings":[ + {"vulnerability":"CVE-2026-2001","component":"pkg:apk/openssl@3.1.0","severity":"critical","state":"open"}, + {"vulnerability":"CVE-2026-2002","component":"pkg:apk/curl@8.0.0","severity":"high","state":"open"} + ] + }`)) + if err != nil { + t.Fatalf("scan: %v", err) + } + if _, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{Status: decisionStatusAffected, Justification: "initial triage"}); err != nil { + t.Fatalf("initial decision: %v", err) + } + outbox.jobs = nil + + vex, err := ledger.UploadCycloneDXVEX(ctx, actor, release.ID, artifact.ID, []byte(`{ + "bomFormat":"CycloneDX", + "specVersion":"1.6", + "vulnerabilities":[ + {"id":"CVE-2026-2001","affects":[{"ref":"pkg:apk/openssl@3.1.0"}],"analysis":{"state":"resolved","justification":"fixed_in_release","detail":"fixed in this release","response":["update"]}}, + {"id":"CVE-2026-2001","affects":[{"ref":"pkg:apk/openssl@3.1.0"}],"analysis":{"state":"resolved","justification":"fixed_in_release","detail":"duplicate statement","response":["update"]}}, + {"id":"CVE-2026-2999","affects":[{"ref":"pkg:apk/missing@1.0.0"}],"analysis":{"state":"resolved","justification":"fixed_elsewhere","detail":"not in scan","response":["none"]}}, + {"id":"CVE-2026-2002","analysis":{"state":"unknown","justification":"unknown_state","detail":"bad state"}} + ] + }`)) + if err != nil { + t.Fatalf("cyclonedx vex: %v", err) + } + report, err := ledger.GetVEXImportReport(ctx, actor, vex.ID) + if err != nil { + t.Fatalf("import report: %v", err) + } + if report.ParserVersion != ParserVersionCycloneDXVEXJSON || report.StatementCount != 4 || report.DecisionsCreated != 1 || report.DecisionsSuperseded != 1 { + t.Fatalf("import report counts = %#v", report) + } + if len(report.MappingFailures) != 1 || report.MappingFailures[0].StatementIndex != 3 || report.MappingFailures[0].Code != "finding_not_found" { + t.Fatalf("mapping failures = %#v", report.MappingFailures) + } + if len(report.InvalidStatements) != 1 || report.InvalidStatements[0].StatementIndex != 4 || report.InvalidStatements[0].Code != "unsupported_analysis_state" { + t.Fatalf("invalid statements = %#v", report.InvalidStatements) + } + if !strings.Contains(strings.Join(report.Warnings, "\n"), "Duplicate CycloneDX VEX vulnerabilities") || !strings.Contains(strings.Join(report.Warnings, "\n"), "skipped") { + t.Fatalf("warnings = %#v", report.Warnings) + } + active := true + decisions, err := ledger.ListVulnerabilityDecisions(ctx, actor, ListVulnerabilityDecisionsInput{ReleaseID: release.ID, Vulnerability: "CVE-2026-2001", Active: &active}) + if err != nil { + t.Fatalf("list decisions: %v", err) + } + if len(decisions) != 1 || decisions[0].Status != decisionStatusFixed || decisions[0].Source != "cyclonedx_vex" { + t.Fatalf("active decisions = %#v", decisions) + } + if len(outbox.jobs) != 1 || outbox.jobs[0].Kind != "parse_vex" || outbox.jobs[0].Payload["parser_version"] != ParserVersionCycloneDXVEXJSON || outbox.jobs[0].Payload["import_report_id"] != report.ID { + t.Fatalf("outbox jobs = %#v", outbox.jobs) + } + + if _, err := ledger.UploadCycloneDXVEX(ctx, actor, release.ID, artifact.ID, []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","unexpected":true,"vulnerabilities":[{"id":"CVE-2026-2001","analysis":{"state":"resolved"}}]}`)); !errors.Is(err, ErrValidation) { + t.Fatalf("unsupported field err=%v, want validation", err) + } + if _, err := ledger.UploadCycloneDXVEX(ctx, actor, release.ID, artifact.ID, []byte(`{"bomFormat":"CycloneDX","vulnerabilities":[`)); !errors.Is(err, ErrValidation) { + t.Fatalf("malformed err=%v, want validation", err) + } +} From 825e6271b6aca54eedbb57afd2d11e652ef8c0f9 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 17:24:17 +0300 Subject: [PATCH 227/287] feat(vex): add import preview endpoints --- .productization_next_steps_missing.md | 2 +- docs/api.md | 14 +++ docs/reference/api-contract-matrix.md | 4 +- docs/reference/vulnerability-decisions.md | 13 +- internal/adapters/httpapi/openapi.go | 20 ++++ .../adapters/httpapi/openapi_operations.go | 8 ++ .../adapters/httpapi/route_registration.go | 2 + internal/adapters/httpapi/router.go | 62 ++++++++++ internal/adapters/httpapi/router_test.go | 43 ++++++- internal/app/release_evidence_service.go | 4 + internal/app/risk_workflows.go | 84 +++++++++++++ internal/app/risk_workflows_test.go | 70 +++++++++++ internal/app/vex.go | 112 ++++++++++++++++++ internal/domain/domain.go | 21 ++++ openapi.yaml | 2 +- scripts/openapi_contract_matrix.py | 3 + 16 files changed, 456 insertions(+), 8 deletions(-) diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index 6283774..a2f3619 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -317,7 +317,7 @@ Implementation rules: - Add malformed, unsupported, duplicate, and mapping-failure fixtures. - Run targeted VEX/parser tests and `make openapi-check` if schema changes. -### Ticket E4-T2 - Add VEX import preview/dry-run mode [ ] +### Ticket E4-T2 - Add VEX import preview/dry-run mode [x] Description: Add a way to validate a VEX document and see safe mapping warnings before committing decisions, if it fits the API model. diff --git a/docs/api.md b/docs/api.md index bb1a172..2ceea95 100644 --- a/docs/api.md +++ b/docs/api.md @@ -218,6 +218,18 @@ The import report records parser version, statement counts, decision counts, supersession counts, warnings, invalid statement issues, and mapping failures. It does not include raw VEX payload bytes or object-store payload references. +VEX import preview: + +```http +POST /v1/vex/preview +POST /v1/vex/cyclonedx/preview +``` + +Preview validates OpenVEX or CycloneDX VEX payloads and returns advisory +mapping counts, warnings, invalid-statement issues, and mapping failures. It +does not store raw payloads, create evidence, create decisions, or enqueue +worker jobs, so it does not require `Idempotency-Key`. + Customer-safe decision summary: ```http @@ -507,7 +519,9 @@ presets; preset policy fields cannot be overridden in the create request. | `POST` | `/v1/api-security-scans` | Convenience API-security scan route. | | `POST` | `/v1/security-documents` | Upload sensitive manual security document metadata/payload. | | `POST` | `/v1/vex` | Upload OpenVEX. | +| `POST` | `/v1/vex/preview` | Preview OpenVEX mapping without storing evidence. | | `POST` | `/v1/vex/cyclonedx` | Upload CycloneDX VEX. | +| `POST` | `/v1/vex/cyclonedx/preview` | Preview CycloneDX VEX mapping without storing evidence. | | `GET` | `/v1/vex/{id}` | Read VEX metadata. | | `GET` | `/v1/vex/{id}/import-report` | Read VEX parser report with safe counts, warnings, and mapping failures. | | `POST` | `/v1/openapi-contracts` | Upload OpenAPI contract. | diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index af66bae..1c4c850 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 178 operations: 178 precise, 0 broad. +Generated from 180 operations: 180 precise, 0 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -176,6 +176,8 @@ Generated from 178 operations: 178 precise, 0 broad. | GET | /v1/version | version | public | - | - | - | - | 200:application/json:VersionInfoEnvelope | precise | | POST | /v1/vex | uploadVEX | Bearer | evidence:write | required | - | application/json:EvidenceUploadRequest | 201:application/json:VEXDocumentEnvelope | precise | | POST | /v1/vex/cyclonedx | uploadCycloneDXVEX | Bearer | evidence:write | required | - | application/json:EvidenceUploadRequest | 201:application/json:VEXDocumentEnvelope | precise | +| POST | /v1/vex/cyclonedx/preview | previewCycloneDXVEXImport | Bearer | evidence:read | not required | - | application/json:EvidenceUploadRequest | 200:application/json:VEXImportPreviewEnvelope | precise | +| POST | /v1/vex/preview | previewVEXImport | Bearer | evidence:read | not required | - | application/json:EvidenceUploadRequest | 200:application/json:VEXImportPreviewEnvelope | precise | | GET | /v1/vex/{id} | getVEX | Bearer | evidence:read | - | path:id | - | 200:application/json:VEXDocumentEnvelope | precise | | GET | /v1/vex/{id}/import-report | getVEXImportReport | Bearer | evidence:read | - | path:id | - | 200:application/json:VEXImportReportEnvelope | precise | | GET | /v1/vulnerability-decisions | listVulnerabilityDecisions | Bearer | evidence:read | - | query:active, query:component, query:product_id, query:release_id, query:status, query:vulnerability | - | 200:application/json:VulnerabilityDecisionListEnvelope | precise | diff --git a/docs/reference/vulnerability-decisions.md b/docs/reference/vulnerability-decisions.md index 942980a..b9e9b7f 100644 --- a/docs/reference/vulnerability-decisions.md +++ b/docs/reference/vulnerability-decisions.md @@ -197,6 +197,12 @@ CycloneDX VEX reports include format-specific invalid-statement issues for missing vulnerability IDs and unsupported analysis states, duplicate mapping warnings, and no-finding mapping failures. +`POST /v1/vex/preview` and `POST /v1/vex/cyclonedx/preview` validate payloads +and return advisory mapping counts before committing an import. Preview results +do not store raw payloads, create evidence, create decisions, append audit-chain +entries, or enqueue parser jobs. They are recalculated from current stored scan +findings and active decisions and may change before a later upload. + ## Customer-Safe Summary API `GET /v1/reports/vulnerability-decision-summary?release_id=...` returns active @@ -214,8 +220,8 @@ yet the full buyer-facing VEX decision workflow: - Decision history can now be queried directly, but it is still an operational API in addition to the package-scoped customer export. -- VEX import reports cover OpenVEX and CycloneDX VEX, but dry-run preview and - parser-failure visibility still need deeper workflow support. +- VEX import reports and dry-run previews cover OpenVEX and CycloneDX VEX, but + parser-failure visibility still needs deeper workflow support. - Customer package manifests can include active `customer_visible` decision summaries when the redaction profile explicitly allows `vulnerability_decision`. They exclude `internal_notes`, raw payload bytes, @@ -238,8 +244,7 @@ yet the full buyer-facing VEX decision workflow: The productization backlog should add these changes in order: -1. Add VEX dry-run preview before committing evidence or decisions. -2. Persist safe parser failure details into import reports and worker job +1. Persist safe parser failure details into import reports and worker job status. These follow-ups should update OpenAPI, HTTP tests, package export tests, and diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 2e3a649..64a8735 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -1971,6 +1971,26 @@ func registerCriticalSchemas(registry *specs.Registry) { "updated_at": map[string]any{"type": "string", "format": "date-time"}, }, "id", "tenant_id", "vex_document_id", "evidence_id", "parser_version", "status", "statement_count", "decisions_created", "decisions_superseded", "schema_version", "created_at", "updated_at")) registry.RegisterSchema("VEXImportReportEnvelope", dataEnvelopeSchema("#/components/schemas/VEXImportReport")) + registry.RegisterSchema("VEXImportPreview", objectSchema(map[string]any{ + "tenant_id": map[string]any{"type": "string"}, + "release_id": map[string]any{"type": "string"}, + "artifact_id": map[string]any{"type": "string"}, + "format": map[string]any{"type": "string", "enum": []string{"openvex", "cyclonedx"}}, + "parser_version": map[string]any{"type": "string"}, + "advisory": map[string]any{"type": "boolean"}, + "statement_count": map[string]any{"type": "integer"}, + "status_summary": map[string]any{"type": "object", "additionalProperties": map[string]any{"type": "integer"}}, + "decisions_would_create": map[string]any{"type": "integer"}, + "decisions_would_supersede": map[string]any{"type": "integer"}, + "warnings": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "invalid_statements": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/VEXImportIssue"}}, + "mapping_failures": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/VEXImportIssue"}}, + "assumptions": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "limitations": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, + "schema_version": map[string]any{"type": "string"}, + "generated_at": map[string]any{"type": "string", "format": "date-time"}, + }, "tenant_id", "release_id", "format", "parser_version", "advisory", "statement_count", "status_summary", "decisions_would_create", "decisions_would_supersede", "assumptions", "limitations", "schema_version", "generated_at")) + registry.RegisterSchema("VEXImportPreviewEnvelope", dataEnvelopeSchema("#/components/schemas/VEXImportPreview")) registry.RegisterSchema("VulnerabilityScan", objectSchema(map[string]any{ "id": map[string]any{"type": "string"}, "tenant_id": map[string]any{"type": "string"}, diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index d30fc54..a17fab0 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -258,10 +258,18 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { }, } operation.Responses[http.StatusCreated] = jsonResponse("Created VEX document envelope.", "#/components/schemas/VEXDocumentEnvelope") + case "previewVEXImport": + operation.Description = "Validates an OpenVEX payload and returns advisory mapping counts without storing raw payloads, creating evidence, creating decisions, or enqueueing parser jobs." + operation.RequestBody = jsonRequest("OpenVEX import preview request.", "#/components/schemas/EvidenceUploadRequest") + operation.Responses[http.StatusOK] = jsonResponse("Advisory VEX import preview envelope.", "#/components/schemas/VEXImportPreviewEnvelope") case "uploadCycloneDXVEX": operation.Description = "Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable." operation.RequestBody = jsonRequest("CycloneDX VEX upload request.", "#/components/schemas/EvidenceUploadRequest") operation.Responses[http.StatusCreated] = jsonResponse("Created VEX document envelope.", "#/components/schemas/VEXDocumentEnvelope") + case "previewCycloneDXVEXImport": + operation.Description = "Validates a CycloneDX VEX payload and returns advisory mapping counts without storing raw payloads, creating evidence, creating decisions, or enqueueing parser jobs." + operation.RequestBody = jsonRequest("CycloneDX VEX import preview request.", "#/components/schemas/EvidenceUploadRequest") + operation.Responses[http.StatusOK] = jsonResponse("Advisory VEX import preview envelope.", "#/components/schemas/VEXImportPreviewEnvelope") case "getVEX": operation.Description = "Returns a tenant-scoped VEX document metadata record by id." operation.Parameters = append(operation.Parameters, pathParam("id", "VEX document id.")) diff --git a/internal/adapters/httpapi/route_registration.go b/internal/adapters/httpapi/route_registration.go index 0137229..fa71508 100644 --- a/internal/adapters/httpapi/route_registration.go +++ b/internal/adapters/httpapi/route_registration.go @@ -213,7 +213,9 @@ func (s *Server) evidenceRiskPolicyRoutes() []routeDef { {http.MethodGet, "/v1/sboms/{id}", op("getSBOM", http.MethodGet, "/v1/sboms/{id}", "Get SBOM", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.getSBOM)}, {http.MethodGet, "/v1/sbom-components", op("listSBOMComponents", http.MethodGet, "/v1/sbom-components", "List SBOM components", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.listSBOMComponents)}, {http.MethodPost, "/v1/vex", op("uploadVEX", http.MethodPost, "/v1/vex", "Upload OpenVEX document", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.uploadVEX)}, + {http.MethodPost, "/v1/vex/preview", readOnlyPostOp("previewVEXImport", http.MethodPost, "/v1/vex/preview", "Preview OpenVEX import", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.previewVEXImport)}, {http.MethodPost, "/v1/vex/cyclonedx", op("uploadCycloneDXVEX", http.MethodPost, "/v1/vex/cyclonedx", "Upload CycloneDX VEX document", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.uploadCycloneDXVEX)}, + {http.MethodPost, "/v1/vex/cyclonedx/preview", readOnlyPostOp("previewCycloneDXVEXImport", http.MethodPost, "/v1/vex/cyclonedx/preview", "Preview CycloneDX VEX import", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.previewCycloneDXVEXImport)}, {http.MethodGet, "/v1/vex/{id}", op("getVEX", http.MethodGet, "/v1/vex/{id}", "Get VEX document", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.getVEX)}, {http.MethodGet, "/v1/vex/{id}/import-report", op("getVEXImportReport", http.MethodGet, "/v1/vex/{id}/import-report", "Get VEX import report", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.getVEXImportReport)}, {http.MethodPost, "/v1/vulnerability-scans", op("uploadVulnerabilityScan", http.MethodPost, "/v1/vulnerability-scans", "Upload vulnerability scan", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.uploadVulnerabilityScan)}, diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index 3d2ee06..067e542 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -1446,6 +1446,33 @@ func (s *Server) uploadVEX(w http.ResponseWriter, r *http.Request) { }) } +func (s *Server) previewVEXImport(w http.ResponseWriter, r *http.Request) { + var req struct { + ReleaseID string `json:"release_id"` + ArtifactID string `json:"artifact_id"` + Payload json.RawMessage `json:"payload"` + } + actor, ok := s.authenticate(w, r) + if !ok { + return + } + body, err := readBody(r) + if err != nil { + writeProblem(w, r, err) + return + } + if err := decodeJSON(body, &req); err != nil { + writeProblem(w, r, err) + return + } + preview, err := s.ledger.PreviewVEXImport(r.Context(), actor, req.ReleaseID, req.ArtifactID, req.Payload) + if err != nil { + writeProblem(w, r, err) + return + } + writeData(w, http.StatusOK, preview) +} + func (s *Server) getVEX(w http.ResponseWriter, r *http.Request) { actor, ok := s.authenticate(w, r) if !ok { @@ -1487,6 +1514,33 @@ func (s *Server) uploadCycloneDXVEX(w http.ResponseWriter, r *http.Request) { }) } +func (s *Server) previewCycloneDXVEXImport(w http.ResponseWriter, r *http.Request) { + var req struct { + ReleaseID string `json:"release_id"` + ArtifactID string `json:"artifact_id"` + Payload json.RawMessage `json:"payload"` + } + actor, ok := s.authenticate(w, r) + if !ok { + return + } + body, err := readBody(r) + if err != nil { + writeProblem(w, r, err) + return + } + if err := decodeJSON(body, &req); err != nil { + writeProblem(w, r, err) + return + } + preview, err := s.ledger.PreviewCycloneDXVEXImport(r.Context(), actor, req.ReleaseID, req.ArtifactID, req.Payload) + if err != nil { + writeProblem(w, r, err) + return + } + writeData(w, http.StatusOK, preview) +} + func (s *Server) uploadVulnerabilityScan(w http.ResponseWriter, r *http.Request) { s.create(w, r, func(ctx requestContext, actor domain.Actor, body []byte) (int, any, error) { scan, err := s.ledger.UploadVulnerabilityScan(ctx, actor, body) @@ -2446,6 +2500,12 @@ func authenticatedOp(id, method, path, summary string) specs.Operation { return operation } +func readOnlyPostOp(id, method, path, summary string, scopes []string) specs.Operation { + operation := op(id, method, path, summary, scopes) + operation.Extensions = idempotent.OperationExtensions(false) + return operation +} + func publicPostOp(id, method, path, summary string) specs.Operation { operation := op(id, method, path, summary, nil) operation.Security = nil @@ -2473,6 +2533,8 @@ func defaultSuccessStatus(operationID, method string) int { "rejectReleaseCandidate", "verifyCosignSignature", "verifyBuildAttestationSignature", + "previewVEXImport", + "previewCycloneDXVEXImport", "approveWaiver", "accessCustomerPortalPackage", "downloadCustomerPortalPackage", diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 7d0667d..f4c2d59 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -107,7 +107,7 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { if _, ok := redactionRequestProps["preset"]; !ok { t.Fatalf("redaction profile request schema missing preset: %#v", redactionRequestProps) } - for _, schemaName := range []string{"ReadinessStatusEnvelope", "BackupManifestEnvelope", "VerificationResultEnvelope", "ReadinessReportEnvelope", "CRAVulnerabilityHandlingReportEnvelope", "SecurityUpdateEvidenceReportEnvelope", "SigningCustodyReviewReportEnvelope", "CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "ReleaseEvidenceFlowEnvelope", "ReleaseSecuritySummaryEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "VEXImportReportEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "VulnerabilityDecisionListEnvelope", "VulnerabilityDecisionSummaryReportEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "UpdateSSOProviderTrustMaterialRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "ExchangeSSOCredentialRequest", "SSOCredentialExchangeEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalAccessEnvelope", "CustomerPortalAccessListEnvelope", "CustomerPortalPackageRequest", "QuestionnaireAnswerLibraryEntryEnvelope", "QuestionnaireAnswerLibraryEntryListEnvelope", "DataEnvelope"} { + for _, schemaName := range []string{"ReadinessStatusEnvelope", "BackupManifestEnvelope", "VerificationResultEnvelope", "ReadinessReportEnvelope", "CRAVulnerabilityHandlingReportEnvelope", "SecurityUpdateEvidenceReportEnvelope", "SigningCustodyReviewReportEnvelope", "CreateProductRequest", "ProductEnvelope", "ProductListEnvelope", "CreateProjectRequest", "ProjectEnvelope", "CreateReleaseRequest", "ReleaseEnvelope", "ReleaseEvidenceFlowEnvelope", "ReleaseSecuritySummaryEnvelope", "RegisterArtifactRequest", "ArtifactEnvelope", "CreateBuildRequest", "BuildRunEnvelope", "EvidenceUploadRequest", "SBOMEnvelope", "VEXDocumentEnvelope", "VEXImportReportEnvelope", "VEXImportPreviewEnvelope", "UploadVulnerabilityScanRequest", "VulnerabilityScanEnvelope", "VulnerabilityDecisionListEnvelope", "VulnerabilityDecisionSummaryReportEnvelope", "CreateEvidenceRequest", "CreateReleaseBundleRequest", "CreateSSOProviderRequest", "UpdateSSOProviderTrustMaterialRequest", "SSOProviderEnvelope", "VerifyProviderIdentityRequest", "ProviderVerificationEnvelope", "CreateSSOSessionRequest", "SSOSessionCreateEnvelope", "ExchangeSSOCredentialRequest", "SSOCredentialExchangeEnvelope", "CreateCustomerPortalAccessRequest", "CustomerPortalAccessCreateEnvelope", "CustomerPortalAccessEnvelope", "CustomerPortalAccessListEnvelope", "CustomerPortalPackageRequest", "QuestionnaireAnswerLibraryEntryEnvelope", "QuestionnaireAnswerLibraryEntryListEnvelope", "DataEnvelope"} { if _, ok := schemas[schemaName]; !ok { t.Fatalf("schema %s missing from OpenAPI components", schemaName) } @@ -184,6 +184,12 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { assertRequestRef(t, uploadVEX, "#/components/schemas/EvidenceUploadRequest") assertRequestExampleContains(t, uploadVEX, "openvex-fixed-decision", "CVE-2026-0002") assertResponseRef(t, uploadVEX, "201", "#/components/schemas/VEXDocumentEnvelope") + previewVEX := operationMap(t, paths, "/v1/vex/preview", "post") + assertRequestRef(t, previewVEX, "#/components/schemas/EvidenceUploadRequest") + assertResponseRef(t, previewVEX, "200", "#/components/schemas/VEXImportPreviewEnvelope") + previewCycloneDXVEX := operationMap(t, paths, "/v1/vex/cyclonedx/preview", "post") + assertRequestRef(t, previewCycloneDXVEX, "#/components/schemas/EvidenceUploadRequest") + assertResponseRef(t, previewCycloneDXVEX, "200", "#/components/schemas/VEXImportPreviewEnvelope") getVEXImportReport := operationMap(t, paths, "/v1/vex/{id}/import-report", "get") assertQueryParams(t, getVEXImportReport, "id") assertResponseRef(t, getVEXImportReport, "200", "#/components/schemas/VEXImportReportEnvelope") @@ -873,6 +879,41 @@ func TestVEXAndExceptionHTTPValidation(t *testing.T) { "findings": []map[string]any{{"vulnerability": "CVE-2026-0100", "component": "pkg:apk/openssl@3.1.0", "severity": "critical", "state": "open"}}, }, http.StatusCreated) findingID := firstFindingID(t, scanBody) + previewPayload := map[string]any{ + "release_id": releaseID, + "artifact_id": artifactID, + "payload": map[string]any{ + "@context": "https://openvex.dev/ns/v0.2.0", + "@id": "https://example.test/vex/preview", + "author": "security@example.test", + "timestamp": "2026-05-27T12:00:00Z", + "version": 1, + "statements": []map[string]any{{ + "vulnerability": map[string]any{"name": "CVE-2026-0100"}, + "products": []map[string]any{{"@id": "pkg:apk/openssl@3.1.0"}}, + "status": "fixed", + "justification": "fixed in release candidate", + "impact_statement": "patched before release", + "action_statement": "ship fixed artifact", + }}, + }, + } + previewBodyBytes, err := json.Marshal(previewPayload) + if err != nil { + t.Fatalf("marshal preview: %v", err) + } + previewRec := httptest.NewRecorder() + previewReq := httptest.NewRequest(http.MethodPost, "/v1/vex/preview", bytes.NewReader(previewBodyBytes)) + previewReq.Header.Set("Authorization", "Bearer "+secret) + previewReq.Header.Set("Content-Type", "application/json") + server.Handler().ServeHTTP(previewRec, previewReq) + if previewRec.Code != http.StatusOK || !strings.Contains(previewRec.Body.String(), `"advisory":true`) || !strings.Contains(previewRec.Body.String(), `"decisions_would_create":1`) || strings.Contains(previewRec.Body.String(), "payload_ref") { + t.Fatalf("preview status=%d body=%s", previewRec.Code, previewRec.Body.String()) + } + badPreview := postRaw(t, server, secret, "/v1/vex/preview", "", []byte(`{"release_id":"`+releaseID+`","payload":{"author":"a"},"unexpected":true}`), http.StatusBadRequest) + if strings.Contains(badPreview, "author") { + t.Fatalf("bad preview leaked payload details: %s", badPreview) + } vexBody := postJSON(t, server, secret, "/v1/vex", "vex-upload", map[string]any{ "release_id": releaseID, "artifact_id": artifactID, diff --git a/internal/app/release_evidence_service.go b/internal/app/release_evidence_service.go index a0ca187..78dc81a 100644 --- a/internal/app/release_evidence_service.go +++ b/internal/app/release_evidence_service.go @@ -98,6 +98,10 @@ func (l *Ledger) UploadVEX(ctx context.Context, actor domain.Actor, releaseID, a return l.releaseEvidenceService().UploadVEX(ctx, actor, releaseID, artifactID, raw) } +func (l *Ledger) PreviewVEXImport(ctx context.Context, actor domain.Actor, releaseID, artifactID string, raw []byte) (domain.VEXImportPreview, error) { + return l.releaseEvidenceService().PreviewVEXImport(ctx, actor, releaseID, artifactID, raw) +} + func (l *Ledger) GetVEXDocument(ctx context.Context, actor domain.Actor, id string) (domain.VEXDocument, error) { return l.releaseEvidenceService().GetVEXDocument(ctx, actor, id) } diff --git a/internal/app/risk_workflows.go b/internal/app/risk_workflows.go index 6a6e252..b97f69b 100644 --- a/internal/app/risk_workflows.go +++ b/internal/app/risk_workflows.go @@ -964,6 +964,68 @@ func (l *Ledger) UploadCycloneDXVEX(ctx context.Context, actor domain.Actor, rel return vex, nil } +func (l *Ledger) PreviewCycloneDXVEXImport(ctx context.Context, actor domain.Actor, releaseID, artifactID string, raw []byte) (domain.VEXImportPreview, error) { + if err := ctx.Err(); err != nil { + return domain.VEXImportPreview{}, err + } + if err := require(actor, ScopeEvidenceRead); err != nil { + return domain.VEXImportPreview{}, err + } + if len(raw) == 0 || len(raw) > 20<<20 { + return domain.VEXImportPreview{}, ErrValidation + } + var doc cycloneDXVEXDocument + if err := strictDecode(raw, &doc); err != nil || !strings.EqualFold(strings.TrimSpace(doc.BOMFormat), "cyclonedx") || len(doc.Vulnerabilities) == 0 { + return domain.VEXImportPreview{}, ErrValidation + } + statusSummary, invalidStatements, validStatements := analyzeCycloneDXVEXStatements(doc) + if len(validStatements) == 0 { + return domain.VEXImportPreview{}, ErrValidation + } + releaseID = strings.TrimSpace(releaseID) + artifactID = strings.TrimSpace(artifactID) + if releaseID == "" { + return domain.VEXImportPreview{}, ErrValidation + } + l.mu.Lock() + defer l.mu.Unlock() + if err := l.ensureScopeLocked(actor.TenantID, "", "", releaseID); err != nil { + return domain.VEXImportPreview{}, err + } + if artifactID != "" { + artifact, ok := l.artifacts[artifactID] + if !ok || artifact.TenantID != actor.TenantID { + return domain.VEXImportPreview{}, ErrNotFound + } + } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceRead, resourceRefs{ReleaseID: releaseID}); err != nil { + return domain.VEXImportPreview{}, err + } + created, superseded, warnings, mappingFailures := l.previewCycloneDXVEXDecisionEffectsLocked(actor.TenantID, releaseID, validStatements) + if len(invalidStatements) > 0 { + warnings = append(warnings, "One or more CycloneDX VEX vulnerabilities were skipped because required analysis fields were missing or unsupported.") + } + return domain.VEXImportPreview{ + TenantID: actor.TenantID, + ReleaseID: releaseID, + ArtifactID: artifactID, + Format: "cyclonedx", + ParserVersion: ParserVersionCycloneDXVEXJSON, + Advisory: true, + StatementCount: len(doc.Vulnerabilities), + StatusSummary: cloneIntMap(statusSummary), + DecisionsWouldCreate: created, + DecisionsWouldSupersede: superseded, + Warnings: warnings, + InvalidStatements: invalidStatements, + MappingFailures: mappingFailures, + Assumptions: vexImportPreviewAssumptions(), + Limitations: vexImportPreviewLimitations(), + SchemaVersion: domain.VEXImportPreviewSchemaVersion, + GeneratedAt: l.now(), + }, nil +} + type cycloneDXVEXStatement struct { index int vulnerability cycloneDXVEXVulnerability @@ -1023,6 +1085,28 @@ func (l *Ledger) findCycloneDXVEXMatchingFindingsLocked(tenantID, releaseID stri return out } +func (l *Ledger) previewCycloneDXVEXDecisionEffectsLocked(tenantID, releaseID string, statements []cycloneDXVEXStatement) (int, int, []string, []domain.VEXImportIssue) { + created, superseded := 0, 0 + mappingFailures := []domain.VEXImportIssue{} + warnings := []string{} + createdForFinding := map[string]struct{}{} + duplicateWarningAdded := false + for _, statement := range statements { + matches := l.findCycloneDXVEXMatchingFindingsLocked(tenantID, releaseID, statement) + if len(matches) == 0 { + mappingFailures = append(mappingFailures, vexImportIssue(statement.index, "finding_not_found", "No matching vulnerability scan finding was found for this CycloneDX VEX vulnerability.")) + } + added, replaced, duplicate := l.previewDecisionEffectsForMatchesLocked(tenantID, matches, createdForFinding) + created += added + superseded += replaced + if duplicate && !duplicateWarningAdded { + warnings = append(warnings, "Duplicate CycloneDX VEX vulnerabilities for an already mapped finding were ignored.") + duplicateWarningAdded = true + } + } + return created, superseded, warnings, mappingFailures +} + func (l *Ledger) RecordVulnerabilityWorkflow(ctx context.Context, actor domain.Actor, in RecordVulnerabilityWorkflowInput) (domain.VulnerabilityWorkflowRecord, error) { if err := ctx.Err(); err != nil { return domain.VulnerabilityWorkflowRecord{}, err diff --git a/internal/app/risk_workflows_test.go b/internal/app/risk_workflows_test.go index be5ce93..56eb164 100644 --- a/internal/app/risk_workflows_test.go +++ b/internal/app/risk_workflows_test.go @@ -222,3 +222,73 @@ func TestCycloneDXVEXImportReportTracksIssuesDuplicatesAndOutbox(t *testing.T) { t.Fatalf("malformed err=%v, want validation", err) } } + +func TestVEXImportPreviewIsAdvisoryAndDoesNotMutateLedger(t *testing.T) { + outbox := &recordingOutbox{} + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow, Outbox: outbox}) + ctx := context.Background() + actor, release, artifact := setupReleaseRiskFixture(t, ledger) + scan, err := ledger.UploadVulnerabilityScan(ctx, actor, []byte(`{ + "scanner":"grype", + "target_ref":"pkg:oci/payments-api", + "release_id":"`+release.ID+`", + "findings":[{"vulnerability":"CVE-2026-4001","component":"pkg:apk/openssl@3.1.0","severity":"critical","state":"open"}] + }`)) + if err != nil { + t.Fatalf("scan: %v", err) + } + if _, err := ledger.CreateVulnerabilityDecision(ctx, actor, scan.Findings[0].ID, CreateVulnerabilityDecisionInput{Status: decisionStatusAffected, Justification: "initial triage"}); err != nil { + t.Fatalf("initial decision: %v", err) + } + outbox.jobs = nil + evidenceCount, vexCount, decisionCount := len(ledger.evidence), len(ledger.vexDocuments), len(ledger.decisions) + + preview, err := ledger.PreviewVEXImport(ctx, actor, release.ID, artifact.ID, []byte(`{ + "@context":"https://openvex.dev/ns/v0.2.0", + "@id":"https://example.test/vex/preview", + "author":"security@example.test", + "timestamp":"2026-05-27T12:00:00Z", + "version":1, + "statements":[ + {"vulnerability":{"name":"CVE-2026-4001"},"products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","justification":"fixed","impact_statement":"patched","action_statement":"ship"}, + {"vulnerability":{"name":"CVE-2026-4999"},"products":[{"@id":"pkg:apk/missing@1.0.0"}],"status":"fixed","justification":"fixed","impact_statement":"missing","action_statement":"none"} + ] + }`)) + if err != nil { + t.Fatalf("openvex preview: %v", err) + } + if preview.Format != "openvex" || !preview.Advisory || preview.ParserVersion != ParserVersionOpenVEXJSON || preview.StatementCount != 2 || preview.DecisionsWouldCreate != 1 || preview.DecisionsWouldSupersede != 1 { + t.Fatalf("openvex preview = %#v", preview) + } + if len(preview.MappingFailures) != 1 || preview.MappingFailures[0].StatementIndex != 2 || preview.MappingFailures[0].Code != "finding_not_found" { + t.Fatalf("openvex mapping failures = %#v", preview.MappingFailures) + } + if len(ledger.evidence) != evidenceCount || len(ledger.vexDocuments) != vexCount || len(ledger.decisions) != decisionCount || len(outbox.jobs) != 0 { + t.Fatalf("preview mutated state evidence=%d/%d vex=%d/%d decisions=%d/%d jobs=%d", len(ledger.evidence), evidenceCount, len(ledger.vexDocuments), vexCount, len(ledger.decisions), decisionCount, len(outbox.jobs)) + } + + cyclonePreview, err := ledger.PreviewCycloneDXVEXImport(ctx, actor, release.ID, artifact.ID, []byte(`{ + "bomFormat":"CycloneDX", + "specVersion":"1.6", + "vulnerabilities":[ + {"id":"CVE-2026-4001","affects":[{"ref":"pkg:apk/openssl@3.1.0"}],"analysis":{"state":"resolved","justification":"fixed","detail":"patched","response":["update"]}}, + {"id":"CVE-2026-4999","analysis":{"state":"resolved","justification":"fixed","detail":"not in scan"}}, + {"id":"CVE-2026-4002","analysis":{"state":"unknown","detail":"bad state"}} + ] + }`)) + if err != nil { + t.Fatalf("cyclonedx preview: %v", err) + } + if cyclonePreview.Format != "cyclonedx" || cyclonePreview.ParserVersion != ParserVersionCycloneDXVEXJSON || cyclonePreview.StatementCount != 3 || cyclonePreview.DecisionsWouldCreate != 1 || cyclonePreview.DecisionsWouldSupersede != 1 { + t.Fatalf("cyclonedx preview = %#v", cyclonePreview) + } + if len(cyclonePreview.InvalidStatements) != 1 || cyclonePreview.InvalidStatements[0].StatementIndex != 3 { + t.Fatalf("cyclonedx invalid statements = %#v", cyclonePreview.InvalidStatements) + } + if len(cyclonePreview.MappingFailures) != 1 || cyclonePreview.MappingFailures[0].StatementIndex != 2 { + t.Fatalf("cyclonedx mapping failures = %#v", cyclonePreview.MappingFailures) + } + if _, err := ledger.PreviewCycloneDXVEXImport(ctx, actor, release.ID, artifact.ID, []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","unexpected":true,"vulnerabilities":[{"id":"CVE-2026-4001","analysis":{"state":"resolved"}}]}`)); !errors.Is(err, ErrValidation) { + t.Fatalf("strict preview err=%v, want validation", err) + } +} diff --git a/internal/app/vex.go b/internal/app/vex.go index 6660ca2..baefcf7 100644 --- a/internal/app/vex.go +++ b/internal/app/vex.go @@ -261,6 +261,65 @@ func (s releaseEvidenceService) UploadVEX(ctx context.Context, actor domain.Acto return vex, nil } +func (s releaseEvidenceService) PreviewVEXImport(ctx context.Context, actor domain.Actor, releaseID, artifactID string, raw []byte) (domain.VEXImportPreview, error) { + l := s.ledger + if err := ctx.Err(); err != nil { + return domain.VEXImportPreview{}, err + } + if err := require(actor, ScopeEvidenceRead); err != nil { + return domain.VEXImportPreview{}, err + } + if len(raw) == 0 || len(raw) > 20<<20 { + return domain.VEXImportPreview{}, ErrValidation + } + doc, err := parseOpenVEX(raw) + if err != nil { + return domain.VEXImportPreview{}, err + } + releaseID = strings.TrimSpace(releaseID) + artifactID = strings.TrimSpace(artifactID) + if releaseID == "" { + return domain.VEXImportPreview{}, ErrValidation + } + statusSummary := map[string]int{} + for _, statement := range doc.Statements { + statusSummary[statement.Status]++ + } + l.mu.Lock() + defer l.mu.Unlock() + if err := l.ensureScopeLocked(actor.TenantID, "", "", releaseID); err != nil { + return domain.VEXImportPreview{}, err + } + if artifactID != "" { + artifact, ok := l.artifacts[artifactID] + if !ok || artifact.TenantID != actor.TenantID { + return domain.VEXImportPreview{}, ErrNotFound + } + } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceRead, resourceRefs{ReleaseID: releaseID}); err != nil { + return domain.VEXImportPreview{}, err + } + created, superseded, warnings, mappingFailures := l.previewOpenVEXDecisionEffectsLocked(actor.TenantID, releaseID, doc.Statements) + return domain.VEXImportPreview{ + TenantID: actor.TenantID, + ReleaseID: releaseID, + ArtifactID: artifactID, + Format: "openvex", + ParserVersion: ParserVersionOpenVEXJSON, + Advisory: true, + StatementCount: len(doc.Statements), + StatusSummary: cloneIntMap(statusSummary), + DecisionsWouldCreate: created, + DecisionsWouldSupersede: superseded, + Warnings: warnings, + MappingFailures: mappingFailures, + Assumptions: vexImportPreviewAssumptions(), + Limitations: vexImportPreviewLimitations(), + SchemaVersion: domain.VEXImportPreviewSchemaVersion, + GeneratedAt: l.now(), + }, nil +} + func (s releaseEvidenceService) GetVEXImportReport(ctx context.Context, actor domain.Actor, vexID string) (domain.VEXImportReport, error) { l := s.ledger if err := ctx.Err(); err != nil { @@ -1103,6 +1162,45 @@ func (l *Ledger) findMatchingFindingsLocked(tenantID, releaseID string, statemen return out } +func (l *Ledger) previewOpenVEXDecisionEffectsLocked(tenantID, releaseID string, statements []openVEXStatement) (int, int, []string, []domain.VEXImportIssue) { + created, superseded := 0, 0 + mappingFailures := []domain.VEXImportIssue{} + warnings := []string{} + createdForFinding := map[string]struct{}{} + duplicateWarningAdded := false + for index, statement := range statements { + matches := l.findMatchingFindingsLocked(tenantID, releaseID, statement) + if len(matches) == 0 { + mappingFailures = append(mappingFailures, vexImportIssue(index+1, "finding_not_found", "No matching vulnerability scan finding was found for this VEX statement.")) + } + added, replaced, duplicate := l.previewDecisionEffectsForMatchesLocked(tenantID, matches, createdForFinding) + created += added + superseded += replaced + if duplicate && !duplicateWarningAdded { + warnings = append(warnings, "Duplicate VEX statements for an already mapped finding were ignored.") + duplicateWarningAdded = true + } + } + return created, superseded, warnings, mappingFailures +} + +func (l *Ledger) previewDecisionEffectsForMatchesLocked(tenantID string, matches []matchedFinding, createdForFinding map[string]struct{}) (int, int, bool) { + created, superseded := 0, 0 + duplicate := false + for _, matched := range matches { + if _, seen := createdForFinding[matched.finding.ID]; seen { + duplicate = true + continue + } + createdForFinding[matched.finding.ID] = struct{}{} + created++ + if _, ok := l.latestDecisionForFindingLocked(tenantID, matched.finding.ID); ok { + superseded++ + } + } + return created, superseded, duplicate +} + func openVEXProductIDs(products []openVEXProduct) map[string]struct{} { out := map[string]struct{}{} var walk func([]openVEXProduct) @@ -1386,6 +1484,20 @@ func vexImportIssue(statementIndex int, code, detail string) domain.VEXImportIss return domain.VEXImportIssue{StatementIndex: statementIndex, Code: code, Detail: detail} } +func vexImportPreviewAssumptions() []string { + return []string{ + "Preview results are computed from currently stored scan findings and active decisions for the requested release.", + "Preview does not store raw VEX payloads, create evidence, create decisions, or enqueue parser jobs.", + } +} + +func vexImportPreviewLimitations() []string { + return []string{ + "Preview is advisory and may change if scans, decisions, exceptions, or releases change before upload.", + "Preview does not prove legal compliance, complete vulnerability coverage, complete SBOM coverage, or release security.", + } +} + func sortedUniqueNonEmptyStrings(in []string) []string { set := map[string]struct{}{} for _, value := range in { diff --git a/internal/domain/domain.go b/internal/domain/domain.go index 7c9a4a5..648cdab 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -12,6 +12,7 @@ const ( PolicySetVersion = "policy-set.v1.0.0" VEXDocumentSchemaVersion = "vex-document.v1.0.0" VEXImportReportSchemaVersion = "vex-import-report.v1.0.0" + VEXImportPreviewSchemaVersion = "vex-import-preview.v1.0.0" VulnerabilityDecisionVersion = "vulnerability-decision.v1.0.0" ReleaseReadinessTemplateVersion = "release-readiness.v1.0.0" CollectorSchemaVersion = "collector.v1.0.0" @@ -1258,6 +1259,26 @@ type VEXImportReport struct { UpdatedAt time.Time `json:"updated_at"` } +type VEXImportPreview struct { + TenantID string `json:"tenant_id"` + ReleaseID string `json:"release_id"` + ArtifactID string `json:"artifact_id,omitempty"` + Format string `json:"format"` + ParserVersion string `json:"parser_version"` + Advisory bool `json:"advisory"` + StatementCount int `json:"statement_count"` + StatusSummary map[string]int `json:"status_summary"` + DecisionsWouldCreate int `json:"decisions_would_create"` + DecisionsWouldSupersede int `json:"decisions_would_supersede"` + Warnings []string `json:"warnings,omitempty"` + InvalidStatements []VEXImportIssue `json:"invalid_statements,omitempty"` + MappingFailures []VEXImportIssue `json:"mapping_failures,omitempty"` + Assumptions []string `json:"assumptions"` + Limitations []string `json:"limitations"` + SchemaVersion string `json:"schema_version"` + GeneratedAt time.Time `json:"generated_at"` +} + type VulnerabilityDecision struct { ID string `json:"id"` TenantID string `json:"tenant_id"` diff --git a/openapi.yaml b/openapi.yaml index f7dcfb5..5923f61 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CRAVulnerabilityHandlingReport":{"additionalProperties":false,"properties":{"accepted_exceptions":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"CRAVulnerabilityHandlingReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"},"require_nda":{"type":"boolean"},"reviewer_email":{"description":"Optional external reviewer email label. It is not used as an authentication secret.","type":"string"},"reviewer_name":{"description":"Optional external reviewer display name for this package access record.","type":"string"},"watermark":{"description":"Optional customer-visible distribution watermark. It is not a token or secret.","type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireAnswerLibraryEntryRequest":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"}},"required":["answer"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"review_due_at":{"description":"Optional UTC time when this decision should be reviewed again.","format":"date-time","type":"string"},"reviewed_at":{"description":"Optional UTC time when the decision was reviewed. Defaults to creation time.","format":"date-time","type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"supporting_refs":{"description":"Optional tenant-scoped first-class decision support records from the same release. Supported types are approval, exception, waiver, remediation_task, release_bundle, and incident.","items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccess":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"failed_access_count":{"type":"integer"},"id":{"type":"string"},"last_accessed_at":{"format":"date-time","type":"string"},"last_failed_at":{"format":"date-time","type":"string"},"nda_accepted_at":{"format":"date-time","type":"string"},"nda_accepted_by":{"type":"string"},"package_id":{"type":"string"},"prefix":{"description":"Non-secret portal token prefix for operational lookup.","type":"string"},"require_nda":{"type":"boolean"},"reviewer_email":{"type":"string"},"reviewer_name":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"watermark":{"type":"string"}},"required":["id","tenant_id","package_id","customer_name","prefix","expires_at","access_count","failed_access_count","schema_version","created_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"$ref":"#/components/schemas/CustomerPortalAccess"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalAccessEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccess"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CustomerPortalAccess"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"nda_accepted":{"description":"Set true to record acceptance for NDA-gated portal access.","type":"boolean"},"nda_accepted_by":{"description":"Reviewer label recorded when NDA acceptance is required. Do not include secrets.","type":"string"},"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"distribution_watermark":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"remediation":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntry":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","answer","schema_version","created_at"],"type":"object"},"QuestionnaireAnswerLibraryEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"policy_set":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlow":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["needs_evidence","ready_for_review"],"type":"string"},"steps":{"items":{"$ref":"#/components/schemas/ReleaseEvidenceFlowStep"},"type":"array"}},"required":["release_id","product_id","status","counts","steps","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseEvidenceFlowEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseEvidenceFlow"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlowStep":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"idempotency_required":{"type":"boolean"},"method":{"type":"string"},"next_reference":{"type":"string"},"path":{"type":"string"},"required":{"type":"boolean"},"required_scopes":{"items":{"type":"string"},"type":"array"},"status":{"enum":["present","missing","optional"],"type":"string"},"title":{"type":"string"}},"required":["id","title","status","required","method","path","required_scopes","idempotency_required","description"],"type":"object"},"ReleaseSecurityApprovalSummary":{"additionalProperties":false,"properties":{"approved":{"type":"integer"},"total":{"type":"integer"}},"required":["total","approved"],"type":"object"},"ReleaseSecurityExceptionSummary":{"additionalProperties":false,"properties":{"approved_unexpired":{"type":"integer"},"expired":{"type":"integer"},"total":{"type":"integer"},"unapproved":{"type":"integer"}},"required":["total","approved_unexpired","unapproved","expired"],"type":"object"},"ReleaseSecurityMissingDecision":{"additionalProperties":false,"properties":{"component":{"type":"string"},"finding_id":{"type":"string"},"scan_id":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["finding_id","scan_id","vulnerability","severity","state"],"type":"object"},"ReleaseSecurityProductSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"],"type":"object"},"ReleaseSecurityReleaseSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"state":{"type":"string"},"version":{"type":"string"}},"required":["id","version","state"],"type":"object"},"ReleaseSecuritySummary":{"additionalProperties":false,"properties":{"approval_summary":{"$ref":"#/components/schemas/ReleaseSecurityApprovalSummary"},"artifact_count":{"type":"integer"},"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"decisions_by_status":{"additionalProperties":{"type":"integer"},"type":"object"},"exception_summary":{"$ref":"#/components/schemas/ReleaseSecurityExceptionSummary"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_required_decisions":{"items":{"$ref":"#/components/schemas/ReleaseSecurityMissingDecision"},"type":"array"},"open_findings_by_severity":{"additionalProperties":{"type":"integer"},"type":"object"},"package_status":{"enum":["generated","not_generated"],"type":"string"},"product":{"$ref":"#/components/schemas/ReleaseSecurityProductSummary"},"readiness_status":{"enum":["passed","failed"],"type":"string"},"release":{"$ref":"#/components/schemas/ReleaseSecurityReleaseSummary"},"sbom_status":{"enum":["present","missing"],"type":"string"},"schema_version":{"type":"string"},"vulnerability_scan_status":{"enum":["present","missing"],"type":"string"}},"required":["product","release","artifact_count","sbom_status","vulnerability_scan_status","open_findings_by_severity","decisions_by_status","approval_summary","exception_summary","readiness_status","package_status","counts","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseSecuritySummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseSecuritySummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityUpdateEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"fixed_decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incidents":{"items":{"$ref":"#/components/schemas/Incident"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"remediation_tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"SecurityUpdateEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningCustodyReviewReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"object_retention_policies":{"items":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"type":"array"},"report_type":{"type":"string"},"signing_providers":{"items":{"$ref":"#/components/schemas/SigningProvider"},"type":"array"},"tenant_id":{"type":"string"}},"required":["report_type","tenant_id","checks","assumptions","limitations","generated_at"],"type":"object"},"SigningCustodyReviewReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningCustodyReviewReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"review_due_at":{"format":"date-time","type":"string"},"reviewed_at":{"format":"date-time","type":"string"},"sbom_component_name":{"type":"string"},"sbom_component_purl":{"type":"string"},"sbom_id":{"description":"Same-release SBOM that contained the matched component, when available.","type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"supporting_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"review_due_at":{"format":"date-time","type":"string"},"reviewed_at":{"format":"date-time","type":"string"},"sbom_component_name":{"type":"string"},"sbom_component_purl":{"type":"string"},"sbom_id":{"description":"Same-release SBOM that contained the matched component, when available.","type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"supporting_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"examples":{"release-evidence-package":{"summary":"Create a scoped release evidence package","value":{"expires_at":"2026-06-30T00:00:00Z","product_id":"prod_20260527120000","redaction_profile_id":"rp_20260527120000","release_id":"rel_20260527120000","title":"Payments API 1.0.0 release evidence package"}}},"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"get":{"description":"Lists tenant-scoped external reviewer access records without token hashes or token secrets.","operationId":"listCustomerPortalAccess","parameters":[{"description":"Optional customer package id filter.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessListEnvelope"}}},"description":"Customer portal access list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List customer portal access records","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a named, expiring external reviewer access record for a customer package and returns the portal token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/access/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped external reviewer access record; revocation is append-only and the original token cannot be used afterwards.","operationId":"revokeCustomerPortalAccess","parameters":[{"description":"Customer portal access id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessEnvelope"}}},"description":"Revoked customer portal access envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-answer-library":{"get":{"description":"Lists tenant-scoped questionnaire answer library entries with optional question, product, and release filters.","operationId":"listQuestionnaireAnswerLibrary","parameters":[{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by questionnaire question id.","in":"query","name":"question_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryListEnvelope"}}},"description":"Questionnaire answer library entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List questionnaire answer library entries","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a tenant-scoped reusable questionnaire answer draft linked to optional evidence, product, release, or control scope.","operationId":"createQuestionnaireAnswerLibraryEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireAnswerLibraryEntryRequest"}}},"description":"Questionnaire answer library entry creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryEnvelope"}}},"description":"Created questionnaire answer library entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire answer library entry","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"examples":{"release-candidate":{"summary":"Create a release for evidence collection","value":{"product_id":"prod_20260527120000","project_id":"proj_20260527120000","version":"1.0.0-rc.1"}}},"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"examples":{"created-release":{"summary":"Created release response","value":{"data":{"created_at":"2026-05-27T12:00:00Z","id":"rel_20260527120000","product_id":"prod_20260527120000","project_id":"proj_20260527120000","schema_version":"release.v1.0.0","status":"draft","tenant_id":"ten_20260527120000","version":"1.0.0-rc.1"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/evidence-flow/start":{"post":{"description":"Returns a high-level release evidence workflow plan, current evidence counts, required scopes, assumptions, and limitations. This read-only convenience operation does not create evidence.","operationId":"startReleaseEvidenceFlow","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEvidenceFlowEnvelope"}}},"description":"Release evidence flow envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Start release evidence flow","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:read"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/security-summary":{"get":{"description":"Returns a tenant-scoped release security summary for review surfaces without raw evidence payload bytes.","operationId":"releaseSecuritySummary","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseSecuritySummaryEnvelope"}}},"description":"Release security summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release security summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-vulnerability-handling":{"get":{"description":"Returns a CRA-oriented vulnerability handling evidence report without legal compliance, certification, scanner-authority, or release-security conclusions.","operationId":"craVulnerabilityHandlingReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReportEnvelope"}}},"description":"CRA vulnerability handling report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA vulnerability handling report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/custody-review":{"get":{"description":"Returns tenant signing-provider and object-lock verification metadata for deployment custody review. It is evidence metadata only, not legal compliance proof, certification, HSM custody proof, or a secure-deployment guarantee.","operationId":"signingCustodyReviewReport","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningCustodyReviewReportEnvelope"}}},"description":"Signing custody review report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Signing custody review report","tags":["evydence"],"x-scopes":["keys:admin"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"examples":{"failed-readiness-with-gap":{"summary":"Readiness report with a vulnerability decision gap","value":{"data":{"accepted_exceptions":[],"assumptions":["Readiness is based on tenant evidence recorded in Evydence."],"blocking_findings":[{"component":"pkg:apk/openssl@3.1.0-r0","decision_state":"missing","finding_id":"scan_20260527120000:finding:1","release_id":"rel_20260527120000","scan_id":"scan_20260527120000","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"generated_at":"2026-05-27T12:00:00Z","limitations":["Readiness supports technical review and does not prove legal compliance, certification, complete vulnerability coverage, or release security."],"missing_evidence":["vulnerability_decision"],"policy_set":"policy-set.v1.0.0","product_id":"prod_20260527120000","release_id":"rel_20260527120000","report_type":"release_readiness","result":"failed","schema_version":"release-readiness.v1.0.0","summary":{"headline":"Release evidence has one blocking vulnerability decision gap.","human_summary":"Required artifact, SBOM, scan, build, and bundle evidence is present, but one critical finding still needs a valid decision or approved exception.","policy_set":"policy-set.v1.0.0","result":"failed"},"template_version":"release-readiness.v1.0.0"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/security-update-evidence":{"get":{"description":"Returns a security update evidence report for release-scoped fixed decisions, incidents, remediation tasks, and linked evidence without legal or security conclusions.","operationId":"securityUpdateEvidenceReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReportEnvelope"}}},"description":"Security update evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security update evidence report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"examples":{"cyclonedx-release-sbom":{"summary":"Upload a CycloneDX SBOM linked to the release artifact","value":{"artifact_id":"art_20260527120000","payload":{"bomFormat":"CycloneDX","components":[{"name":"payments-api","purl":"pkg:oci/payments-api@sha256-ca978112","version":"1.0.0-rc.1"},{"name":"openssl","purl":"pkg:apk/openssl@3.1.0-r0","version":"3.1.0-r0"}],"specVersion":"1.6"},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"examples":{"not-affected-decision":{"summary":"Record a customer-visible not-affected decision","value":{"customer_visible":true,"evidence_ids":["ev_20260527120000"],"impact_statement":"The shipped artifact does not include the affected runtime path.","justification":"The vulnerable code path is not reachable in this release.","status":"not_affected","supporting_refs":[{"id":"exc_20260527120000","type":"exception"}]}}},"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"examples":{"generic-critical-finding":{"summary":"Upload a generic scanner finding for release triage","value":{"findings":[{"component":"pkg:apk/openssl@3.1.0-r0","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"release_id":"rel_20260527120000","scanner":"generic-json","target_ref":"pkg:oci/payments-api@sha256-ca978112"}}},"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CRAVulnerabilityHandlingReport":{"additionalProperties":false,"properties":{"accepted_exceptions":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"CRAVulnerabilityHandlingReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"},"require_nda":{"type":"boolean"},"reviewer_email":{"description":"Optional external reviewer email label. It is not used as an authentication secret.","type":"string"},"reviewer_name":{"description":"Optional external reviewer display name for this package access record.","type":"string"},"watermark":{"description":"Optional customer-visible distribution watermark. It is not a token or secret.","type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireAnswerLibraryEntryRequest":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"}},"required":["answer"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"review_due_at":{"description":"Optional UTC time when this decision should be reviewed again.","format":"date-time","type":"string"},"reviewed_at":{"description":"Optional UTC time when the decision was reviewed. Defaults to creation time.","format":"date-time","type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"supporting_refs":{"description":"Optional tenant-scoped first-class decision support records from the same release. Supported types are approval, exception, waiver, remediation_task, release_bundle, and incident.","items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccess":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"failed_access_count":{"type":"integer"},"id":{"type":"string"},"last_accessed_at":{"format":"date-time","type":"string"},"last_failed_at":{"format":"date-time","type":"string"},"nda_accepted_at":{"format":"date-time","type":"string"},"nda_accepted_by":{"type":"string"},"package_id":{"type":"string"},"prefix":{"description":"Non-secret portal token prefix for operational lookup.","type":"string"},"require_nda":{"type":"boolean"},"reviewer_email":{"type":"string"},"reviewer_name":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"watermark":{"type":"string"}},"required":["id","tenant_id","package_id","customer_name","prefix","expires_at","access_count","failed_access_count","schema_version","created_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"$ref":"#/components/schemas/CustomerPortalAccess"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalAccessEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccess"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CustomerPortalAccess"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"nda_accepted":{"description":"Set true to record acceptance for NDA-gated portal access.","type":"boolean"},"nda_accepted_by":{"description":"Reviewer label recorded when NDA acceptance is required. Do not include secrets.","type":"string"},"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"distribution_watermark":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"remediation":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntry":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","answer","schema_version","created_at"],"type":"object"},"QuestionnaireAnswerLibraryEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"policy_set":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlow":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["needs_evidence","ready_for_review"],"type":"string"},"steps":{"items":{"$ref":"#/components/schemas/ReleaseEvidenceFlowStep"},"type":"array"}},"required":["release_id","product_id","status","counts","steps","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseEvidenceFlowEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseEvidenceFlow"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlowStep":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"idempotency_required":{"type":"boolean"},"method":{"type":"string"},"next_reference":{"type":"string"},"path":{"type":"string"},"required":{"type":"boolean"},"required_scopes":{"items":{"type":"string"},"type":"array"},"status":{"enum":["present","missing","optional"],"type":"string"},"title":{"type":"string"}},"required":["id","title","status","required","method","path","required_scopes","idempotency_required","description"],"type":"object"},"ReleaseSecurityApprovalSummary":{"additionalProperties":false,"properties":{"approved":{"type":"integer"},"total":{"type":"integer"}},"required":["total","approved"],"type":"object"},"ReleaseSecurityExceptionSummary":{"additionalProperties":false,"properties":{"approved_unexpired":{"type":"integer"},"expired":{"type":"integer"},"total":{"type":"integer"},"unapproved":{"type":"integer"}},"required":["total","approved_unexpired","unapproved","expired"],"type":"object"},"ReleaseSecurityMissingDecision":{"additionalProperties":false,"properties":{"component":{"type":"string"},"finding_id":{"type":"string"},"scan_id":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["finding_id","scan_id","vulnerability","severity","state"],"type":"object"},"ReleaseSecurityProductSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"],"type":"object"},"ReleaseSecurityReleaseSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"state":{"type":"string"},"version":{"type":"string"}},"required":["id","version","state"],"type":"object"},"ReleaseSecuritySummary":{"additionalProperties":false,"properties":{"approval_summary":{"$ref":"#/components/schemas/ReleaseSecurityApprovalSummary"},"artifact_count":{"type":"integer"},"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"decisions_by_status":{"additionalProperties":{"type":"integer"},"type":"object"},"exception_summary":{"$ref":"#/components/schemas/ReleaseSecurityExceptionSummary"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_required_decisions":{"items":{"$ref":"#/components/schemas/ReleaseSecurityMissingDecision"},"type":"array"},"open_findings_by_severity":{"additionalProperties":{"type":"integer"},"type":"object"},"package_status":{"enum":["generated","not_generated"],"type":"string"},"product":{"$ref":"#/components/schemas/ReleaseSecurityProductSummary"},"readiness_status":{"enum":["passed","failed"],"type":"string"},"release":{"$ref":"#/components/schemas/ReleaseSecurityReleaseSummary"},"sbom_status":{"enum":["present","missing"],"type":"string"},"schema_version":{"type":"string"},"vulnerability_scan_status":{"enum":["present","missing"],"type":"string"}},"required":["product","release","artifact_count","sbom_status","vulnerability_scan_status","open_findings_by_severity","decisions_by_status","approval_summary","exception_summary","readiness_status","package_status","counts","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseSecuritySummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseSecuritySummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityUpdateEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"fixed_decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incidents":{"items":{"$ref":"#/components/schemas/Incident"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"remediation_tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"SecurityUpdateEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningCustodyReviewReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"object_retention_policies":{"items":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"type":"array"},"report_type":{"type":"string"},"signing_providers":{"items":{"$ref":"#/components/schemas/SigningProvider"},"type":"array"},"tenant_id":{"type":"string"}},"required":["report_type","tenant_id","checks","assumptions","limitations","generated_at"],"type":"object"},"SigningCustodyReviewReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningCustodyReviewReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportPreview":{"additionalProperties":false,"properties":{"advisory":{"type":"boolean"},"artifact_id":{"type":"string"},"assumptions":{"items":{"type":"string"},"type":"array"},"decisions_would_create":{"type":"integer"},"decisions_would_supersede":{"type":"integer"},"format":{"enum":["openvex","cyclonedx"],"type":"string"},"generated_at":{"format":"date-time","type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["tenant_id","release_id","format","parser_version","advisory","statement_count","status_summary","decisions_would_create","decisions_would_supersede","assumptions","limitations","schema_version","generated_at"],"type":"object"},"VEXImportPreviewEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportPreview"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"review_due_at":{"format":"date-time","type":"string"},"reviewed_at":{"format":"date-time","type":"string"},"sbom_component_name":{"type":"string"},"sbom_component_purl":{"type":"string"},"sbom_id":{"description":"Same-release SBOM that contained the matched component, when available.","type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"supporting_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"review_due_at":{"format":"date-time","type":"string"},"reviewed_at":{"format":"date-time","type":"string"},"sbom_component_name":{"type":"string"},"sbom_component_purl":{"type":"string"},"sbom_id":{"description":"Same-release SBOM that contained the matched component, when available.","type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"supporting_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"examples":{"release-evidence-package":{"summary":"Create a scoped release evidence package","value":{"expires_at":"2026-06-30T00:00:00Z","product_id":"prod_20260527120000","redaction_profile_id":"rp_20260527120000","release_id":"rel_20260527120000","title":"Payments API 1.0.0 release evidence package"}}},"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"get":{"description":"Lists tenant-scoped external reviewer access records without token hashes or token secrets.","operationId":"listCustomerPortalAccess","parameters":[{"description":"Optional customer package id filter.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessListEnvelope"}}},"description":"Customer portal access list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List customer portal access records","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a named, expiring external reviewer access record for a customer package and returns the portal token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/access/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped external reviewer access record; revocation is append-only and the original token cannot be used afterwards.","operationId":"revokeCustomerPortalAccess","parameters":[{"description":"Customer portal access id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessEnvelope"}}},"description":"Revoked customer portal access envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-answer-library":{"get":{"description":"Lists tenant-scoped questionnaire answer library entries with optional question, product, and release filters.","operationId":"listQuestionnaireAnswerLibrary","parameters":[{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by questionnaire question id.","in":"query","name":"question_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryListEnvelope"}}},"description":"Questionnaire answer library entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List questionnaire answer library entries","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a tenant-scoped reusable questionnaire answer draft linked to optional evidence, product, release, or control scope.","operationId":"createQuestionnaireAnswerLibraryEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireAnswerLibraryEntryRequest"}}},"description":"Questionnaire answer library entry creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryEnvelope"}}},"description":"Created questionnaire answer library entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire answer library entry","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"examples":{"release-candidate":{"summary":"Create a release for evidence collection","value":{"product_id":"prod_20260527120000","project_id":"proj_20260527120000","version":"1.0.0-rc.1"}}},"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"examples":{"created-release":{"summary":"Created release response","value":{"data":{"created_at":"2026-05-27T12:00:00Z","id":"rel_20260527120000","product_id":"prod_20260527120000","project_id":"proj_20260527120000","schema_version":"release.v1.0.0","status":"draft","tenant_id":"ten_20260527120000","version":"1.0.0-rc.1"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/evidence-flow/start":{"post":{"description":"Returns a high-level release evidence workflow plan, current evidence counts, required scopes, assumptions, and limitations. This read-only convenience operation does not create evidence.","operationId":"startReleaseEvidenceFlow","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEvidenceFlowEnvelope"}}},"description":"Release evidence flow envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Start release evidence flow","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:read"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/security-summary":{"get":{"description":"Returns a tenant-scoped release security summary for review surfaces without raw evidence payload bytes.","operationId":"releaseSecuritySummary","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseSecuritySummaryEnvelope"}}},"description":"Release security summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release security summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-vulnerability-handling":{"get":{"description":"Returns a CRA-oriented vulnerability handling evidence report without legal compliance, certification, scanner-authority, or release-security conclusions.","operationId":"craVulnerabilityHandlingReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReportEnvelope"}}},"description":"CRA vulnerability handling report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA vulnerability handling report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/custody-review":{"get":{"description":"Returns tenant signing-provider and object-lock verification metadata for deployment custody review. It is evidence metadata only, not legal compliance proof, certification, HSM custody proof, or a secure-deployment guarantee.","operationId":"signingCustodyReviewReport","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningCustodyReviewReportEnvelope"}}},"description":"Signing custody review report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Signing custody review report","tags":["evydence"],"x-scopes":["keys:admin"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"examples":{"failed-readiness-with-gap":{"summary":"Readiness report with a vulnerability decision gap","value":{"data":{"accepted_exceptions":[],"assumptions":["Readiness is based on tenant evidence recorded in Evydence."],"blocking_findings":[{"component":"pkg:apk/openssl@3.1.0-r0","decision_state":"missing","finding_id":"scan_20260527120000:finding:1","release_id":"rel_20260527120000","scan_id":"scan_20260527120000","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"generated_at":"2026-05-27T12:00:00Z","limitations":["Readiness supports technical review and does not prove legal compliance, certification, complete vulnerability coverage, or release security."],"missing_evidence":["vulnerability_decision"],"policy_set":"policy-set.v1.0.0","product_id":"prod_20260527120000","release_id":"rel_20260527120000","report_type":"release_readiness","result":"failed","schema_version":"release-readiness.v1.0.0","summary":{"headline":"Release evidence has one blocking vulnerability decision gap.","human_summary":"Required artifact, SBOM, scan, build, and bundle evidence is present, but one critical finding still needs a valid decision or approved exception.","policy_set":"policy-set.v1.0.0","result":"failed"},"template_version":"release-readiness.v1.0.0"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/security-update-evidence":{"get":{"description":"Returns a security update evidence report for release-scoped fixed decisions, incidents, remediation tasks, and linked evidence without legal or security conclusions.","operationId":"securityUpdateEvidenceReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReportEnvelope"}}},"description":"Security update evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security update evidence report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"examples":{"cyclonedx-release-sbom":{"summary":"Upload a CycloneDX SBOM linked to the release artifact","value":{"artifact_id":"art_20260527120000","payload":{"bomFormat":"CycloneDX","components":[{"name":"payments-api","purl":"pkg:oci/payments-api@sha256-ca978112","version":"1.0.0-rc.1"},{"name":"openssl","purl":"pkg:apk/openssl@3.1.0-r0","version":"3.1.0-r0"}],"specVersion":"1.6"},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx/preview":{"post":{"description":"Validates a CycloneDX VEX payload and returns advisory mapping counts without storing raw payloads, creating evidence, creating decisions, or enqueueing parser jobs.","operationId":"previewCycloneDXVEXImport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX import preview request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportPreviewEnvelope"}}},"description":"Advisory VEX import preview envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Preview CycloneDX VEX import","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":false},"x-scopes":["evidence:read"]}},"/v1/vex/preview":{"post":{"description":"Validates an OpenVEX payload and returns advisory mapping counts without storing raw payloads, creating evidence, creating decisions, or enqueueing parser jobs.","operationId":"previewVEXImport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX import preview request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportPreviewEnvelope"}}},"description":"Advisory VEX import preview envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Preview OpenVEX import","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":false},"x-scopes":["evidence:read"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"examples":{"not-affected-decision":{"summary":"Record a customer-visible not-affected decision","value":{"customer_visible":true,"evidence_ids":["ev_20260527120000"],"impact_statement":"The shipped artifact does not include the affected runtime path.","justification":"The vulnerable code path is not reachable in this release.","status":"not_affected","supporting_refs":[{"id":"exc_20260527120000","type":"exception"}]}}},"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"examples":{"generic-critical-finding":{"summary":"Upload a generic scanner finding for release triage","value":{"findings":[{"component":"pkg:apk/openssl@3.1.0-r0","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"release_id":"rel_20260527120000","scanner":"generic-json","target_ref":"pkg:oci/payments-api@sha256-ca978112"}}},"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/scripts/openapi_contract_matrix.py b/scripts/openapi_contract_matrix.py index df53f5c..2b60eb4 100755 --- a/scripts/openapi_contract_matrix.py +++ b/scripts/openapi_contract_matrix.py @@ -67,6 +67,9 @@ def auth_label(operation: dict) -> str: def idempotency_label(method: str, operation: dict) -> str: if method.lower() != "post": return "-" + policy = operation.get("x-idempotency-key") + if isinstance(policy, dict) and policy.get("required") is False: + return "not required" if auth_label(operation) == "public": return "not required" return "required" From 131227fe3001cdd7bff510b9383ffcc692fc8a22 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 17:29:15 +0300 Subject: [PATCH 228/287] feat(worker): record vex parser failures --- .productization_next_steps_missing.md | 4 +- cmd/evydence-worker/main.go | 169 ++++++++++++++++-- cmd/evydence-worker/main_test.go | 125 +++++++++++++ docs/api.md | 4 +- docs/reference/vulnerability-decisions.md | 13 +- docs/reference/worker-outbox.md | 6 +- internal/adapters/httpapi/openapi.go | 2 + internal/adapters/postgres/store.go | 12 +- internal/domain/domain.go | 2 + ...000900_vex_import_report_failures.down.sql | 3 + ...01000900_vex_import_report_failures.up.sql | 3 + openapi.yaml | 2 +- 12 files changed, 317 insertions(+), 28 deletions(-) create mode 100644 migrations/20260601000900_vex_import_report_failures.down.sql create mode 100644 migrations/20260601000900_vex_import_report_failures.up.sql diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index a2f3619..9abcf84 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -297,7 +297,7 @@ Implementation rules: - Run `make demo-check`, `make package-viewer-check`, targeted package tests, and `make docs-check`. -## Epic E4 - Improve VEX Import Depth And Parser Feedback [ ] +## Epic E4 - Improve VEX Import Depth And Parser Feedback [x] Description: Make VEX import behavior operationally clear for both OpenVEX and CycloneDX VEX without claiming authoritative vulnerability truth. @@ -330,7 +330,7 @@ Implementation rules: - Update OpenAPI and docs if a new endpoint is added. - Run API input validation tests and `make openapi-check`. -### Ticket E4-T3 - Improve worker parser failure visibility [ ] +### Ticket E4-T3 - Improve worker parser failure visibility [x] Description: Make VEX parser failures visible in persisted import reports and worker job status with safe error codes and no raw payload leakage. diff --git a/cmd/evydence-worker/main.go b/cmd/evydence-worker/main.go index 2d51003..9cb92fc 100644 --- a/cmd/evydence-worker/main.go +++ b/cmd/evydence-worker/main.go @@ -163,6 +163,7 @@ func processJobInternal(ctx context.Context, state jobStateLoader, objects jobOb if requireObjectReplay { object, ok, err := verifyJobObject(ctx, objects, job) if err != nil { + recordVEXImportReportFailure(ctx, state, job, err) return err } replayed, hasReplayedObject = object, ok @@ -175,6 +176,11 @@ func processJobInternal(ctx context.Context, state jobStateLoader, objects jobOb return errors.New("durable state is not initialized") } if err := requireParserVersion(job); err != nil { + if job.Kind == "parse_vex" { + if vex, ok := snapshot.VEXDocuments[job.SubjectID]; ok && vex.TenantID == job.TenantID { + return failVEXImportReportWithSnapshot(ctx, state, &snapshot, job, vex, err) + } + } return err } stateChanged := false @@ -250,10 +256,10 @@ func processJobInternal(ctx context.Context, state jobStateLoader, objects jobOb if hasReplayedObject { parsed, err := parseReplayedVEX(replayed.Bytes) if err != nil { - return err + return failVEXImportReportWithSnapshot(ctx, state, &snapshot, job, vex, err) } if err := verifyReplayedVEX(parsed, vex); err != nil { - return err + return failVEXImportReportWithSnapshot(ctx, state, &snapshot, job, vex, err) } if updated, changed := mergeReplayedVEX(vex, parsed); changed { snapshot.VEXDocuments[job.SubjectID] = updated @@ -262,7 +268,7 @@ func processJobInternal(ctx context.Context, state jobStateLoader, objects jobOb if payloadBool(job, "worker_create_decisions") { created, superseded, mappingFailures, err := applyReplayedVEXDecisions(&snapshot, job, vex, parsed, replayed.Digest) if err != nil { - return err + return failVEXImportReportWithSnapshot(ctx, state, &snapshot, job, vex, err) } if created > 0 { stateChanged = true @@ -325,19 +331,24 @@ func processJobInternal(ctx context.Context, state jobStateLoader, objects jobOb return errors.New("unsupported outbox job kind") } if stateChanged { - if focused, ok := state.(jobReleaseLedgerMutationStore); ok && releaseLedgerParserJob(job.Kind) { - if err := focused.ApplyReleaseLedgerMutation(ctx, app.ReleaseLedgerMutationFromState(snapshot)); err != nil { - return errors.New("persist durable parser side effects") - } - return nil - } - stateStore, ok := state.(jobStateStore) - if !ok { - return errors.New("durable parser side effects require writable state") - } - if err := stateStore.SaveState(ctx, snapshot); err != nil { + return persistParserSideEffects(ctx, state, snapshot, job.Kind) + } + return nil +} + +func persistParserSideEffects(ctx context.Context, state jobStateLoader, snapshot app.PersistedState, kind string) error { + if focused, ok := state.(jobReleaseLedgerMutationStore); ok && releaseLedgerParserJob(kind) { + if err := focused.ApplyReleaseLedgerMutation(ctx, app.ReleaseLedgerMutationFromState(snapshot)); err != nil { return errors.New("persist durable parser side effects") } + return nil + } + stateStore, ok := state.(jobStateStore) + if !ok { + return errors.New("durable parser side effects require writable state") + } + if err := stateStore.SaveState(ctx, snapshot); err != nil { + return errors.New("persist durable parser side effects") } return nil } @@ -967,6 +978,11 @@ func updateVEXImportReport(state *app.PersistedState, job postgres.ClaimedJob, v updated.Status = "parsed" changed = true } + if updated.FailureCode != "" || updated.FailureDetail != "" { + updated.FailureCode = "" + updated.FailureDetail = "" + changed = true + } if updated.StatementCount != parsed.StatementCount { updated.StatementCount = parsed.StatementCount changed = true @@ -995,6 +1011,131 @@ func updateVEXImportReport(state *app.PersistedState, job postgres.ClaimedJob, v return true } +func failVEXImportReportWithSnapshot(ctx context.Context, state jobStateLoader, snapshot *app.PersistedState, job postgres.ClaimedJob, vex domain.VEXDocument, cause error) error { + if updateVEXImportReportFailure(snapshot, job, vex, cause) { + if err := persistParserSideEffects(ctx, state, *snapshot, job.Kind); err != nil { + return err + } + } + return cause +} + +func recordVEXImportReportFailure(ctx context.Context, state jobStateLoader, job postgres.ClaimedJob, cause error) { + if job.Kind != "parse_vex" || state == nil { + return + } + snapshot, ok, err := state.LoadState(ctx) + if err != nil || !ok { + return + } + vex, ok := snapshot.VEXDocuments[job.SubjectID] + if !ok || vex.TenantID != job.TenantID { + return + } + if !updateVEXImportReportFailure(&snapshot, job, vex, cause) { + return + } + _ = persistParserSideEffects(ctx, state, snapshot, job.Kind) +} + +func updateVEXImportReportFailure(state *app.PersistedState, job postgres.ClaimedJob, vex domain.VEXDocument, cause error) bool { + reportID := payloadString(job, "import_report_id") + if reportID == "" { + for id, report := range state.VEXImportReports { + if report.TenantID == job.TenantID && report.VEXDocumentID == vex.ID { + reportID = id + break + } + } + } + if reportID == "" { + return false + } + if state.VEXImportReports == nil { + state.VEXImportReports = map[string]domain.VEXImportReport{} + } + report, ok := state.VEXImportReports[reportID] + if !ok || report.TenantID != job.TenantID || report.VEXDocumentID != vex.ID { + return false + } + code := safeVEXParserFailureCode(cause) + detail := safeVEXParserFailureDetail(code) + updated := report + changed := false + if updated.Status != "failed" { + updated.Status = "failed" + changed = true + } + if updated.FailureCode != code { + updated.FailureCode = code + changed = true + } + if updated.FailureDetail != detail { + updated.FailureDetail = detail + changed = true + } + if updated.SchemaVersion == "" { + updated.SchemaVersion = domain.VEXImportReportSchemaVersion + changed = true + } + if !changed { + return false + } + updated.UpdatedAt = time.Now().UTC() + state.VEXImportReports[reportID] = updated + return true +} + +func safeVEXParserFailureCode(cause error) string { + if cause == nil { + return "parser_failed" + } + message := cause.Error() + switch { + case strings.Contains(message, "read outbox payload object"): + return "payload_read_failed" + case strings.Contains(message, "tenant-prefixed"): + return "payload_ref_invalid" + case strings.Contains(message, "tenant mismatch"): + return "payload_tenant_mismatch" + case strings.Contains(message, "digest mismatch"), strings.Contains(message, "payload hash"): + return "payload_digest_mismatch" + case strings.Contains(message, "size limit"): + return "payload_too_large" + case strings.Contains(message, "unsupported outbox parser version"): + return "unsupported_parser_version" + case strings.Contains(message, "durable state"), strings.Contains(message, "not available"): + return "durable_state_mismatch" + case strings.Contains(message, "replayed vex payload is invalid"): + return "payload_invalid" + default: + return "parser_failed" + } +} + +func safeVEXParserFailureDetail(code string) string { + switch code { + case "payload_read_failed": + return "The worker could not read the referenced VEX payload object." + case "payload_ref_invalid": + return "The VEX payload reference was not tenant-prefixed." + case "payload_tenant_mismatch": + return "The VEX payload object tenant did not match the job tenant." + case "payload_digest_mismatch": + return "The VEX payload digest did not match the expected digest." + case "payload_too_large": + return "The VEX payload exceeded the worker replay size limit." + case "unsupported_parser_version": + return "The VEX parser version is not supported by this worker." + case "durable_state_mismatch": + return "The replayed VEX payload did not match durable state for the job." + case "payload_invalid": + return "The VEX payload could not be parsed as a supported VEX document." + default: + return "The worker could not parse or verify the VEX payload." + } +} + func vexImportIssuesEqual(a, b []domain.VEXImportIssue) bool { if len(a) != len(b) { return false diff --git a/cmd/evydence-worker/main_test.go b/cmd/evydence-worker/main_test.go index 22c6e0b..6c3d9bd 100644 --- a/cmd/evydence-worker/main_test.go +++ b/cmd/evydence-worker/main_test.go @@ -339,6 +339,131 @@ func TestProcessJobWithObjectsCreatesVEXDecisionsIdempotently(t *testing.T) { } } +func TestProcessJobWithObjectsRecordsVEXImportReportFailure(t *testing.T) { + now := time.Date(2026, 5, 28, 12, 0, 0, 0, time.UTC) + validBody := []byte(`{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex","author":"security@example.test","timestamp":"2026-05-28T12:00:00Z","version":1,"statements":[{"vulnerability":{"name":"CVE-1"},"products":[{"@id":"pkg:oci/api"}],"status":"fixed","justification":"fixed"}]}`) + baseJob := postgres.ClaimedJob{ + ID: "job_vex", + TenantID: "ten_test", + Kind: "parse_vex", + SubjectID: "vex_test", + Payload: map[string]any{ + "payload_ref": "object://tenants/ten_test/payloads/vex.json", + "payload_hash": digestBytes(validBody), + "parser_version": app.ParserVersionOpenVEXJSON, + "import_report_id": "vex_report", + }, + } + baseState := func() app.PersistedState { + return app.PersistedState{ + VEXDocuments: map[string]domain.VEXDocument{ + "vex_test": {ID: "vex_test", TenantID: "ten_test", ReleaseID: "rel_test", EvidenceID: "ev_vex", Format: "openvex"}, + }, + VEXImportReports: map[string]domain.VEXImportReport{ + "vex_report": {ID: "vex_report", TenantID: "ten_test", VEXDocumentID: "vex_test", EvidenceID: "ev_vex", Status: "accepted", SchemaVersion: domain.VEXImportReportSchemaVersion, CreatedAt: now, UpdatedAt: now}, + }, + } + } + tests := []struct { + name string + object fakeObjectGetter + payloadHash string + want string + noLeak string + wantErr string + }{ + { + name: "malformed payload", + object: fakeObjectGetter{object: app.Object{Key: "tenants/ten_test/payloads/vex.json", TenantID: "ten_test", Digest: digestBytes([]byte(`{"not":"vex"}`)), Bytes: []byte(`{"not":"vex"}`)}}, + payloadHash: digestBytes([]byte(`{"not":"vex"}`)), + want: "payload_invalid", + noLeak: `{"not":"vex"}`, + wantErr: "replayed vex payload is invalid", + }, + { + name: "missing object", + object: fakeObjectGetter{err: errors.New("backend leaked secret")}, + want: "payload_read_failed", + noLeak: "backend leaked secret", + wantErr: "read outbox payload object", + }, + { + name: "digest mismatch", + object: fakeObjectGetter{object: app.Object{Key: "tenants/ten_test/payloads/vex.json", TenantID: "ten_test", Digest: digestBytes([]byte("other")), Bytes: []byte("other")}}, + want: "payload_digest_mismatch", + noLeak: "other", + wantErr: "metadata digest mismatch", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + store := &fakeStateStore{ok: true, state: baseState()} + job := baseJob + if tt.payloadHash != "" { + payload := map[string]any{} + for key, value := range baseJob.Payload { + payload[key] = value + } + payload["payload_hash"] = tt.payloadHash + job.Payload = payload + } + err := processJobWithObjects(context.Background(), store, tt.object, job) + if err == nil || !strings.Contains(err.Error(), tt.wantErr) { + t.Fatalf("err=%v want %q", err, tt.wantErr) + } + report := store.saved.VEXImportReports["vex_report"] + if report.Status != "failed" || report.FailureCode != tt.want || report.FailureDetail == "" { + t.Fatalf("saved report = %#v", report) + } + text := report.FailureDetail + strings.Join(report.Warnings, "\n") + if strings.Contains(text, tt.noLeak) || strings.Contains(text, "vex.json") { + t.Fatalf("failure report leaked unsafe details: %#v", report) + } + }) + } +} + +func TestProcessJobWithObjectsRecordsVEXMappingFailure(t *testing.T) { + now := time.Date(2026, 5, 28, 12, 0, 0, 0, time.UTC) + body := []byte(`{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex","author":"security@example.test","timestamp":"2026-05-28T12:00:00Z","version":1,"statements":[{"vulnerability":{"name":"CVE-missing"},"products":[{"@id":"pkg:oci/api"}],"status":"fixed","justification":"fixed"}]}`) + hash := digestBytes(body) + job := postgres.ClaimedJob{ + ID: "job_vex", + TenantID: "ten_test", + Kind: "parse_vex", + SubjectID: "vex_test", + Payload: map[string]any{ + "payload_ref": "object://tenants/ten_test/payloads/vex.json", + "payload_hash": hash, + "parser_version": app.ParserVersionOpenVEXJSON, + "worker_create_decisions": true, + "actor_type": "api_key", + "actor_id": "key_test", + "evidence_id": "ev_vex", + "import_report_id": "vex_report", + }, + } + store := &fakeStateStore{ok: true, state: app.PersistedState{ + VEXDocuments: map[string]domain.VEXDocument{ + "vex_test": {ID: "vex_test", TenantID: "ten_test", ReleaseID: "rel_test", EvidenceID: "ev_vex", Format: "openvex"}, + }, + VEXImportReports: map[string]domain.VEXImportReport{ + "vex_report": {ID: "vex_report", TenantID: "ten_test", VEXDocumentID: "vex_test", EvidenceID: "ev_vex", Status: "accepted", SchemaVersion: domain.VEXImportReportSchemaVersion, CreatedAt: now, UpdatedAt: now}, + }, + Scans: map[string]domain.VulnerabilityScan{}, + Decisions: map[string]domain.VulnerabilityDecision{}, + Chain: map[string][]domain.AuditChainEntry{}, + }} + object := app.Object{Key: "tenants/ten_test/payloads/vex.json", TenantID: "ten_test", Digest: hash, Bytes: body} + if err := processJobWithObjects(context.Background(), store, fakeObjectGetter{object: object}, job); err != nil { + t.Fatalf("process vex job: %v", err) + } + report := store.saved.VEXImportReports["vex_report"] + if report.Status != "parsed" || report.DecisionsCreated != 0 || len(report.MappingFailures) != 1 || report.MappingFailures[0].Code != "finding_not_found" { + t.Fatalf("report = %#v", report) + } +} + func TestParseReplayedVEXSupportsCycloneDX(t *testing.T) { body := []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","vulnerabilities":[{"id":"CVE-2026-2001","affects":[{"ref":"pkg:oci/api"}],"analysis":{"state":"resolved","justification":"code_not_reachable","detail":"patched in release artifact","response":["update"]}},{"id":"CVE-2026-2999","analysis":{"state":"unknown"}}]}`) parsed, err := parseReplayedVEX(body) diff --git a/docs/api.md b/docs/api.md index 2ceea95..a0f6fb2 100644 --- a/docs/api.md +++ b/docs/api.md @@ -216,7 +216,9 @@ GET /v1/vex/{id}/import-report The import report records parser version, statement counts, decision counts, supersession counts, warnings, invalid statement issues, and mapping failures. -It does not include raw VEX payload bytes or object-store payload references. +When worker replay fails it records safe `failure_code` and `failure_detail` +fields. It does not include raw VEX payload bytes, object-store payload +references, backend error strings, or bearer tokens. VEX import preview: diff --git a/docs/reference/vulnerability-decisions.md b/docs/reference/vulnerability-decisions.md index b9e9b7f..94bc6eb 100644 --- a/docs/reference/vulnerability-decisions.md +++ b/docs/reference/vulnerability-decisions.md @@ -184,6 +184,7 @@ captures: - warnings; - invalid statement issue codes; - mapping failures such as no matching scan finding. +- safe parser failure code and detail when worker replay fails. `GET /v1/vex/{id}/import-report` returns the report for operators with `evidence:read`. The report is intentionally safe to show in operational review: @@ -197,6 +198,11 @@ CycloneDX VEX reports include format-specific invalid-statement issues for missing vulnerability IDs and unsupported analysis states, duplicate mapping warnings, and no-finding mapping failures. +When worker replay fails, the import report status becomes `failed` and records +only safe operator fields such as `failure_code` and `failure_detail`. It does +not include raw payload bytes, object-store keys, bearer tokens, backend error +strings, or tenant-internal notes. + `POST /v1/vex/preview` and `POST /v1/vex/cyclonedx/preview` validate payloads and return advisory mapping counts before committing an import. Preview results do not store raw payloads, create evidence, create decisions, append audit-chain @@ -220,8 +226,8 @@ yet the full buyer-facing VEX decision workflow: - Decision history can now be queried directly, but it is still an operational API in addition to the package-scoped customer export. -- VEX import reports and dry-run previews cover OpenVEX and CycloneDX VEX, but - parser-failure visibility still needs deeper workflow support. +- VEX import reports, dry-run previews, and safe worker parser-failure fields + cover OpenVEX and CycloneDX VEX. - Customer package manifests can include active `customer_visible` decision summaries when the redaction profile explicitly allows `vulnerability_decision`. They exclude `internal_notes`, raw payload bytes, @@ -244,8 +250,7 @@ yet the full buyer-facing VEX decision workflow: The productization backlog should add these changes in order: -1. Persist safe parser failure details into import reports and worker job - status. +1. Add richer operator filtering for failed VEX imports and parser job states. These follow-ups should update OpenAPI, HTTP tests, package export tests, and docs together. diff --git a/docs/reference/worker-outbox.md b/docs/reference/worker-outbox.md index 2bec2b5..2a630fb 100644 --- a/docs/reference/worker-outbox.md +++ b/docs/reference/worker-outbox.md @@ -12,7 +12,7 @@ Configured job kinds: - `verify_subject` - `verify_attestation` -Current behavior is intentionally conservative. The API still records normalized signing and verification results before enqueueing jobs for the implemented paths. Parser jobs independently replay tenant-prefixed payload objects when `payload_ref` is present, verify object metadata and byte digests when `payload_hash` is present, parse SBOM, vulnerability-scan, OpenAPI, OpenVEX, CycloneDX VEX, and DSSE attestation payloads, and check that replayed payload summaries match the expected durable state. When `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, parser-backed uploads store accepted records first and workers write parser-derived document fields after replay. The `parse_vex` worker also creates VEX-derived vulnerability decisions idempotently in that mode and updates the VEX import report from `accepted` to `parsed` with safe decision and mapping-failure counts. Missing objects, wrong tenant prefixes, tenant mismatches, oversized payload objects, malformed replay payloads, durable-state mismatches, incomplete verification, missing signatures, hash mismatch, uninitialized storage, and unsupported job kinds fail the job safely. +Current behavior is intentionally conservative. The API still records normalized signing and verification results before enqueueing jobs for the implemented paths. Parser jobs independently replay tenant-prefixed payload objects when `payload_ref` is present, verify object metadata and byte digests when `payload_hash` is present, parse SBOM, vulnerability-scan, OpenAPI, OpenVEX, CycloneDX VEX, and DSSE attestation payloads, and check that replayed payload summaries match the expected durable state. When `EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true`, parser-backed uploads store accepted records first and workers write parser-derived document fields after replay. The `parse_vex` worker also creates VEX-derived vulnerability decisions idempotently in that mode and updates the VEX import report from `accepted` to `parsed` with safe decision and mapping-failure counts. VEX parser failures update the import report to `failed` with `failure_code` and `failure_detail` before the outbox job is retried or marked terminal by the persisted job status. Missing objects, wrong tenant prefixes, tenant mismatches, oversized payload objects, malformed replay payloads, durable-state mismatches, incomplete verification, missing signatures, hash mismatch, uninitialized storage, and unsupported job kinds fail the job safely. Parser and attestation jobs include a deterministic `parser_version` payload field for new uploads. Workers reject unsupported parser versions and accept @@ -32,5 +32,9 @@ Safe logging rules: - Log job ID, kind, subject type, and attempt count. - Do not log raw payload bytes, object paths, bearer tokens, customer portal tokens, private keys, or full provider environment dumps. - Error messages should describe the failed invariant without echoing subject IDs or raw payload fields. +- VEX import report `failure_code` values are stable operator hints such as + `payload_read_failed`, `payload_ref_invalid`, `payload_tenant_mismatch`, + `payload_digest_mismatch`, `payload_too_large`, `payload_invalid`, + `unsupported_parser_version`, and `durable_state_mismatch`. This contract supports operations evidence for asynchronous processing. It does not claim external scanner authority, complete parsing coverage, or cryptographic attestation trust unless the relevant trust roots and verification receipts are recorded. diff --git a/internal/adapters/httpapi/openapi.go b/internal/adapters/httpapi/openapi.go index 64a8735..0b69f34 100644 --- a/internal/adapters/httpapi/openapi.go +++ b/internal/adapters/httpapi/openapi.go @@ -1966,6 +1966,8 @@ func registerCriticalSchemas(registry *specs.Registry) { "warnings": map[string]any{"type": "array", "items": map[string]any{"type": "string"}}, "invalid_statements": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/VEXImportIssue"}}, "mapping_failures": map[string]any{"type": "array", "items": map[string]any{"$ref": "#/components/schemas/VEXImportIssue"}}, + "failure_code": map[string]any{"type": "string"}, + "failure_detail": map[string]any{"type": "string"}, "schema_version": map[string]any{"type": "string"}, "created_at": map[string]any{"type": "string", "format": "date-time"}, "updated_at": map[string]any{"type": "string", "format": "date-time"}, diff --git a/internal/adapters/postgres/store.go b/internal/adapters/postgres/store.go index 40c840f..047ab66 100644 --- a/internal/adapters/postgres/store.go +++ b/internal/adapters/postgres/store.go @@ -1123,7 +1123,7 @@ func (s *Store) loadRelationalRiskDecisions(ctx context.Context, state *app.Pers SELECT id, tenant_id, vex_document_id, evidence_id, release_id, artifact_id, parser_version, status, statement_count, decisions_created, decisions_superseded, unsupported_fields, warnings, invalid_statements, - mapping_failures, schema_version, created_at, updated_at + mapping_failures, failure_code, failure_detail, schema_version, created_at, updated_at FROM vex_import_reports `) if err != nil { @@ -1138,7 +1138,7 @@ func (s *Store) loadRelationalRiskDecisions(ctx context.Context, state *app.Pers &report.ID, &report.TenantID, &report.VEXDocumentID, &report.EvidenceID, &releaseID, &artifactID, &report.ParserVersion, &report.Status, &report.StatementCount, &report.DecisionsCreated, &report.DecisionsSuperseded, &report.UnsupportedFields, &warnings, &invalidStatements, - &mappingFailures, &report.SchemaVersion, &report.CreatedAt, &report.UpdatedAt, + &mappingFailures, &report.FailureCode, &report.FailureDetail, &report.SchemaVersion, &report.CreatedAt, &report.UpdatedAt, ); err != nil { return fmt.Errorf("scan relational vex import report: %w", err) } @@ -3280,13 +3280,13 @@ func syncRiskBuildControlRows(ctx context.Context, tx pgx.Tx, state app.Persiste id, tenant_id, vex_document_id, evidence_id, release_id, artifact_id, parser_version, status, statement_count, decisions_created, decisions_superseded, unsupported_fields, warnings, invalid_statements, - mapping_failures, schema_version, created_at, updated_at + mapping_failures, failure_code, failure_detail, schema_version, created_at, updated_at ) VALUES ( $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, - $15, $16, $17, $18 + $15, $16, $17, $18, $19, $20 ) ON CONFLICT (id) DO UPDATE SET status = EXCLUDED.status, @@ -3297,11 +3297,13 @@ func syncRiskBuildControlRows(ctx context.Context, tx pgx.Tx, state app.Persiste warnings = EXCLUDED.warnings, invalid_statements = EXCLUDED.invalid_statements, mapping_failures = EXCLUDED.mapping_failures, + failure_code = EXCLUDED.failure_code, + failure_detail = EXCLUDED.failure_detail, updated_at = EXCLUDED.updated_at `, report.ID, report.TenantID, report.VEXDocumentID, report.EvidenceID, nullableString(report.ReleaseID), nullableString(report.ArtifactID), report.ParserVersion, report.Status, report.StatementCount, report.DecisionsCreated, report.DecisionsSuperseded, textArray(report.UnsupportedFields), warnings, invalidStatements, - mappingFailures, report.SchemaVersion, nonZeroTime(report.CreatedAt), nonZeroTime(report.UpdatedAt)); err != nil { + mappingFailures, report.FailureCode, report.FailureDetail, report.SchemaVersion, nonZeroTime(report.CreatedAt), nonZeroTime(report.UpdatedAt)); err != nil { return fmt.Errorf("upsert vex import report row: %w", err) } } diff --git a/internal/domain/domain.go b/internal/domain/domain.go index 648cdab..213608f 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -1254,6 +1254,8 @@ type VEXImportReport struct { Warnings []string `json:"warnings,omitempty"` InvalidStatements []VEXImportIssue `json:"invalid_statements,omitempty"` MappingFailures []VEXImportIssue `json:"mapping_failures,omitempty"` + FailureCode string `json:"failure_code,omitempty"` + FailureDetail string `json:"failure_detail,omitempty"` SchemaVersion string `json:"schema_version"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` diff --git a/migrations/20260601000900_vex_import_report_failures.down.sql b/migrations/20260601000900_vex_import_report_failures.down.sql new file mode 100644 index 0000000..845eca8 --- /dev/null +++ b/migrations/20260601000900_vex_import_report_failures.down.sql @@ -0,0 +1,3 @@ +ALTER TABLE vex_import_reports + DROP COLUMN IF EXISTS failure_detail, + DROP COLUMN IF EXISTS failure_code; diff --git a/migrations/20260601000900_vex_import_report_failures.up.sql b/migrations/20260601000900_vex_import_report_failures.up.sql new file mode 100644 index 0000000..3cc55d0 --- /dev/null +++ b/migrations/20260601000900_vex_import_report_failures.up.sql @@ -0,0 +1,3 @@ +ALTER TABLE vex_import_reports + ADD COLUMN IF NOT EXISTS failure_code text NOT NULL DEFAULT '', + ADD COLUMN IF NOT EXISTS failure_detail text NOT NULL DEFAULT ''; diff --git a/openapi.yaml b/openapi.yaml index 5923f61..289930e 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CRAVulnerabilityHandlingReport":{"additionalProperties":false,"properties":{"accepted_exceptions":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"CRAVulnerabilityHandlingReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"},"require_nda":{"type":"boolean"},"reviewer_email":{"description":"Optional external reviewer email label. It is not used as an authentication secret.","type":"string"},"reviewer_name":{"description":"Optional external reviewer display name for this package access record.","type":"string"},"watermark":{"description":"Optional customer-visible distribution watermark. It is not a token or secret.","type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireAnswerLibraryEntryRequest":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"}},"required":["answer"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"review_due_at":{"description":"Optional UTC time when this decision should be reviewed again.","format":"date-time","type":"string"},"reviewed_at":{"description":"Optional UTC time when the decision was reviewed. Defaults to creation time.","format":"date-time","type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"supporting_refs":{"description":"Optional tenant-scoped first-class decision support records from the same release. Supported types are approval, exception, waiver, remediation_task, release_bundle, and incident.","items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccess":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"failed_access_count":{"type":"integer"},"id":{"type":"string"},"last_accessed_at":{"format":"date-time","type":"string"},"last_failed_at":{"format":"date-time","type":"string"},"nda_accepted_at":{"format":"date-time","type":"string"},"nda_accepted_by":{"type":"string"},"package_id":{"type":"string"},"prefix":{"description":"Non-secret portal token prefix for operational lookup.","type":"string"},"require_nda":{"type":"boolean"},"reviewer_email":{"type":"string"},"reviewer_name":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"watermark":{"type":"string"}},"required":["id","tenant_id","package_id","customer_name","prefix","expires_at","access_count","failed_access_count","schema_version","created_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"$ref":"#/components/schemas/CustomerPortalAccess"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalAccessEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccess"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CustomerPortalAccess"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"nda_accepted":{"description":"Set true to record acceptance for NDA-gated portal access.","type":"boolean"},"nda_accepted_by":{"description":"Reviewer label recorded when NDA acceptance is required. Do not include secrets.","type":"string"},"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"distribution_watermark":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"remediation":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntry":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","answer","schema_version","created_at"],"type":"object"},"QuestionnaireAnswerLibraryEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"policy_set":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlow":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["needs_evidence","ready_for_review"],"type":"string"},"steps":{"items":{"$ref":"#/components/schemas/ReleaseEvidenceFlowStep"},"type":"array"}},"required":["release_id","product_id","status","counts","steps","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseEvidenceFlowEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseEvidenceFlow"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlowStep":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"idempotency_required":{"type":"boolean"},"method":{"type":"string"},"next_reference":{"type":"string"},"path":{"type":"string"},"required":{"type":"boolean"},"required_scopes":{"items":{"type":"string"},"type":"array"},"status":{"enum":["present","missing","optional"],"type":"string"},"title":{"type":"string"}},"required":["id","title","status","required","method","path","required_scopes","idempotency_required","description"],"type":"object"},"ReleaseSecurityApprovalSummary":{"additionalProperties":false,"properties":{"approved":{"type":"integer"},"total":{"type":"integer"}},"required":["total","approved"],"type":"object"},"ReleaseSecurityExceptionSummary":{"additionalProperties":false,"properties":{"approved_unexpired":{"type":"integer"},"expired":{"type":"integer"},"total":{"type":"integer"},"unapproved":{"type":"integer"}},"required":["total","approved_unexpired","unapproved","expired"],"type":"object"},"ReleaseSecurityMissingDecision":{"additionalProperties":false,"properties":{"component":{"type":"string"},"finding_id":{"type":"string"},"scan_id":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["finding_id","scan_id","vulnerability","severity","state"],"type":"object"},"ReleaseSecurityProductSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"],"type":"object"},"ReleaseSecurityReleaseSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"state":{"type":"string"},"version":{"type":"string"}},"required":["id","version","state"],"type":"object"},"ReleaseSecuritySummary":{"additionalProperties":false,"properties":{"approval_summary":{"$ref":"#/components/schemas/ReleaseSecurityApprovalSummary"},"artifact_count":{"type":"integer"},"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"decisions_by_status":{"additionalProperties":{"type":"integer"},"type":"object"},"exception_summary":{"$ref":"#/components/schemas/ReleaseSecurityExceptionSummary"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_required_decisions":{"items":{"$ref":"#/components/schemas/ReleaseSecurityMissingDecision"},"type":"array"},"open_findings_by_severity":{"additionalProperties":{"type":"integer"},"type":"object"},"package_status":{"enum":["generated","not_generated"],"type":"string"},"product":{"$ref":"#/components/schemas/ReleaseSecurityProductSummary"},"readiness_status":{"enum":["passed","failed"],"type":"string"},"release":{"$ref":"#/components/schemas/ReleaseSecurityReleaseSummary"},"sbom_status":{"enum":["present","missing"],"type":"string"},"schema_version":{"type":"string"},"vulnerability_scan_status":{"enum":["present","missing"],"type":"string"}},"required":["product","release","artifact_count","sbom_status","vulnerability_scan_status","open_findings_by_severity","decisions_by_status","approval_summary","exception_summary","readiness_status","package_status","counts","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseSecuritySummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseSecuritySummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityUpdateEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"fixed_decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incidents":{"items":{"$ref":"#/components/schemas/Incident"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"remediation_tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"SecurityUpdateEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningCustodyReviewReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"object_retention_policies":{"items":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"type":"array"},"report_type":{"type":"string"},"signing_providers":{"items":{"$ref":"#/components/schemas/SigningProvider"},"type":"array"},"tenant_id":{"type":"string"}},"required":["report_type","tenant_id","checks","assumptions","limitations","generated_at"],"type":"object"},"SigningCustodyReviewReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningCustodyReviewReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportPreview":{"additionalProperties":false,"properties":{"advisory":{"type":"boolean"},"artifact_id":{"type":"string"},"assumptions":{"items":{"type":"string"},"type":"array"},"decisions_would_create":{"type":"integer"},"decisions_would_supersede":{"type":"integer"},"format":{"enum":["openvex","cyclonedx"],"type":"string"},"generated_at":{"format":"date-time","type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["tenant_id","release_id","format","parser_version","advisory","statement_count","status_summary","decisions_would_create","decisions_would_supersede","assumptions","limitations","schema_version","generated_at"],"type":"object"},"VEXImportPreviewEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportPreview"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"review_due_at":{"format":"date-time","type":"string"},"reviewed_at":{"format":"date-time","type":"string"},"sbom_component_name":{"type":"string"},"sbom_component_purl":{"type":"string"},"sbom_id":{"description":"Same-release SBOM that contained the matched component, when available.","type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"supporting_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"review_due_at":{"format":"date-time","type":"string"},"reviewed_at":{"format":"date-time","type":"string"},"sbom_component_name":{"type":"string"},"sbom_component_purl":{"type":"string"},"sbom_id":{"description":"Same-release SBOM that contained the matched component, when available.","type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"supporting_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"examples":{"release-evidence-package":{"summary":"Create a scoped release evidence package","value":{"expires_at":"2026-06-30T00:00:00Z","product_id":"prod_20260527120000","redaction_profile_id":"rp_20260527120000","release_id":"rel_20260527120000","title":"Payments API 1.0.0 release evidence package"}}},"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"get":{"description":"Lists tenant-scoped external reviewer access records without token hashes or token secrets.","operationId":"listCustomerPortalAccess","parameters":[{"description":"Optional customer package id filter.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessListEnvelope"}}},"description":"Customer portal access list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List customer portal access records","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a named, expiring external reviewer access record for a customer package and returns the portal token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/access/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped external reviewer access record; revocation is append-only and the original token cannot be used afterwards.","operationId":"revokeCustomerPortalAccess","parameters":[{"description":"Customer portal access id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessEnvelope"}}},"description":"Revoked customer portal access envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-answer-library":{"get":{"description":"Lists tenant-scoped questionnaire answer library entries with optional question, product, and release filters.","operationId":"listQuestionnaireAnswerLibrary","parameters":[{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by questionnaire question id.","in":"query","name":"question_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryListEnvelope"}}},"description":"Questionnaire answer library entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List questionnaire answer library entries","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a tenant-scoped reusable questionnaire answer draft linked to optional evidence, product, release, or control scope.","operationId":"createQuestionnaireAnswerLibraryEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireAnswerLibraryEntryRequest"}}},"description":"Questionnaire answer library entry creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryEnvelope"}}},"description":"Created questionnaire answer library entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire answer library entry","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"examples":{"release-candidate":{"summary":"Create a release for evidence collection","value":{"product_id":"prod_20260527120000","project_id":"proj_20260527120000","version":"1.0.0-rc.1"}}},"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"examples":{"created-release":{"summary":"Created release response","value":{"data":{"created_at":"2026-05-27T12:00:00Z","id":"rel_20260527120000","product_id":"prod_20260527120000","project_id":"proj_20260527120000","schema_version":"release.v1.0.0","status":"draft","tenant_id":"ten_20260527120000","version":"1.0.0-rc.1"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/evidence-flow/start":{"post":{"description":"Returns a high-level release evidence workflow plan, current evidence counts, required scopes, assumptions, and limitations. This read-only convenience operation does not create evidence.","operationId":"startReleaseEvidenceFlow","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEvidenceFlowEnvelope"}}},"description":"Release evidence flow envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Start release evidence flow","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:read"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/security-summary":{"get":{"description":"Returns a tenant-scoped release security summary for review surfaces without raw evidence payload bytes.","operationId":"releaseSecuritySummary","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseSecuritySummaryEnvelope"}}},"description":"Release security summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release security summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-vulnerability-handling":{"get":{"description":"Returns a CRA-oriented vulnerability handling evidence report without legal compliance, certification, scanner-authority, or release-security conclusions.","operationId":"craVulnerabilityHandlingReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReportEnvelope"}}},"description":"CRA vulnerability handling report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA vulnerability handling report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/custody-review":{"get":{"description":"Returns tenant signing-provider and object-lock verification metadata for deployment custody review. It is evidence metadata only, not legal compliance proof, certification, HSM custody proof, or a secure-deployment guarantee.","operationId":"signingCustodyReviewReport","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningCustodyReviewReportEnvelope"}}},"description":"Signing custody review report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Signing custody review report","tags":["evydence"],"x-scopes":["keys:admin"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"examples":{"failed-readiness-with-gap":{"summary":"Readiness report with a vulnerability decision gap","value":{"data":{"accepted_exceptions":[],"assumptions":["Readiness is based on tenant evidence recorded in Evydence."],"blocking_findings":[{"component":"pkg:apk/openssl@3.1.0-r0","decision_state":"missing","finding_id":"scan_20260527120000:finding:1","release_id":"rel_20260527120000","scan_id":"scan_20260527120000","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"generated_at":"2026-05-27T12:00:00Z","limitations":["Readiness supports technical review and does not prove legal compliance, certification, complete vulnerability coverage, or release security."],"missing_evidence":["vulnerability_decision"],"policy_set":"policy-set.v1.0.0","product_id":"prod_20260527120000","release_id":"rel_20260527120000","report_type":"release_readiness","result":"failed","schema_version":"release-readiness.v1.0.0","summary":{"headline":"Release evidence has one blocking vulnerability decision gap.","human_summary":"Required artifact, SBOM, scan, build, and bundle evidence is present, but one critical finding still needs a valid decision or approved exception.","policy_set":"policy-set.v1.0.0","result":"failed"},"template_version":"release-readiness.v1.0.0"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/security-update-evidence":{"get":{"description":"Returns a security update evidence report for release-scoped fixed decisions, incidents, remediation tasks, and linked evidence without legal or security conclusions.","operationId":"securityUpdateEvidenceReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReportEnvelope"}}},"description":"Security update evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security update evidence report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"examples":{"cyclonedx-release-sbom":{"summary":"Upload a CycloneDX SBOM linked to the release artifact","value":{"artifact_id":"art_20260527120000","payload":{"bomFormat":"CycloneDX","components":[{"name":"payments-api","purl":"pkg:oci/payments-api@sha256-ca978112","version":"1.0.0-rc.1"},{"name":"openssl","purl":"pkg:apk/openssl@3.1.0-r0","version":"3.1.0-r0"}],"specVersion":"1.6"},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx/preview":{"post":{"description":"Validates a CycloneDX VEX payload and returns advisory mapping counts without storing raw payloads, creating evidence, creating decisions, or enqueueing parser jobs.","operationId":"previewCycloneDXVEXImport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX import preview request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportPreviewEnvelope"}}},"description":"Advisory VEX import preview envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Preview CycloneDX VEX import","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":false},"x-scopes":["evidence:read"]}},"/v1/vex/preview":{"post":{"description":"Validates an OpenVEX payload and returns advisory mapping counts without storing raw payloads, creating evidence, creating decisions, or enqueueing parser jobs.","operationId":"previewVEXImport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX import preview request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportPreviewEnvelope"}}},"description":"Advisory VEX import preview envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Preview OpenVEX import","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":false},"x-scopes":["evidence:read"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"examples":{"not-affected-decision":{"summary":"Record a customer-visible not-affected decision","value":{"customer_visible":true,"evidence_ids":["ev_20260527120000"],"impact_statement":"The shipped artifact does not include the affected runtime path.","justification":"The vulnerable code path is not reachable in this release.","status":"not_affected","supporting_refs":[{"id":"exc_20260527120000","type":"exception"}]}}},"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"examples":{"generic-critical-finding":{"summary":"Upload a generic scanner finding for release triage","value":{"findings":[{"component":"pkg:apk/openssl@3.1.0-r0","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"release_id":"rel_20260527120000","scanner":"generic-json","target_ref":"pkg:oci/payments-api@sha256-ca978112"}}},"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CRAVulnerabilityHandlingReport":{"additionalProperties":false,"properties":{"accepted_exceptions":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"CRAVulnerabilityHandlingReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"},"require_nda":{"type":"boolean"},"reviewer_email":{"description":"Optional external reviewer email label. It is not used as an authentication secret.","type":"string"},"reviewer_name":{"description":"Optional external reviewer display name for this package access record.","type":"string"},"watermark":{"description":"Optional customer-visible distribution watermark. It is not a token or secret.","type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireAnswerLibraryEntryRequest":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"}},"required":["answer"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"review_due_at":{"description":"Optional UTC time when this decision should be reviewed again.","format":"date-time","type":"string"},"reviewed_at":{"description":"Optional UTC time when the decision was reviewed. Defaults to creation time.","format":"date-time","type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"supporting_refs":{"description":"Optional tenant-scoped first-class decision support records from the same release. Supported types are approval, exception, waiver, remediation_task, release_bundle, and incident.","items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccess":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"failed_access_count":{"type":"integer"},"id":{"type":"string"},"last_accessed_at":{"format":"date-time","type":"string"},"last_failed_at":{"format":"date-time","type":"string"},"nda_accepted_at":{"format":"date-time","type":"string"},"nda_accepted_by":{"type":"string"},"package_id":{"type":"string"},"prefix":{"description":"Non-secret portal token prefix for operational lookup.","type":"string"},"require_nda":{"type":"boolean"},"reviewer_email":{"type":"string"},"reviewer_name":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"watermark":{"type":"string"}},"required":["id","tenant_id","package_id","customer_name","prefix","expires_at","access_count","failed_access_count","schema_version","created_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"$ref":"#/components/schemas/CustomerPortalAccess"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalAccessEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccess"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CustomerPortalAccess"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"nda_accepted":{"description":"Set true to record acceptance for NDA-gated portal access.","type":"boolean"},"nda_accepted_by":{"description":"Reviewer label recorded when NDA acceptance is required. Do not include secrets.","type":"string"},"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"distribution_watermark":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"remediation":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntry":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","answer","schema_version","created_at"],"type":"object"},"QuestionnaireAnswerLibraryEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"policy_set":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlow":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["needs_evidence","ready_for_review"],"type":"string"},"steps":{"items":{"$ref":"#/components/schemas/ReleaseEvidenceFlowStep"},"type":"array"}},"required":["release_id","product_id","status","counts","steps","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseEvidenceFlowEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseEvidenceFlow"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlowStep":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"idempotency_required":{"type":"boolean"},"method":{"type":"string"},"next_reference":{"type":"string"},"path":{"type":"string"},"required":{"type":"boolean"},"required_scopes":{"items":{"type":"string"},"type":"array"},"status":{"enum":["present","missing","optional"],"type":"string"},"title":{"type":"string"}},"required":["id","title","status","required","method","path","required_scopes","idempotency_required","description"],"type":"object"},"ReleaseSecurityApprovalSummary":{"additionalProperties":false,"properties":{"approved":{"type":"integer"},"total":{"type":"integer"}},"required":["total","approved"],"type":"object"},"ReleaseSecurityExceptionSummary":{"additionalProperties":false,"properties":{"approved_unexpired":{"type":"integer"},"expired":{"type":"integer"},"total":{"type":"integer"},"unapproved":{"type":"integer"}},"required":["total","approved_unexpired","unapproved","expired"],"type":"object"},"ReleaseSecurityMissingDecision":{"additionalProperties":false,"properties":{"component":{"type":"string"},"finding_id":{"type":"string"},"scan_id":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["finding_id","scan_id","vulnerability","severity","state"],"type":"object"},"ReleaseSecurityProductSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"],"type":"object"},"ReleaseSecurityReleaseSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"state":{"type":"string"},"version":{"type":"string"}},"required":["id","version","state"],"type":"object"},"ReleaseSecuritySummary":{"additionalProperties":false,"properties":{"approval_summary":{"$ref":"#/components/schemas/ReleaseSecurityApprovalSummary"},"artifact_count":{"type":"integer"},"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"decisions_by_status":{"additionalProperties":{"type":"integer"},"type":"object"},"exception_summary":{"$ref":"#/components/schemas/ReleaseSecurityExceptionSummary"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_required_decisions":{"items":{"$ref":"#/components/schemas/ReleaseSecurityMissingDecision"},"type":"array"},"open_findings_by_severity":{"additionalProperties":{"type":"integer"},"type":"object"},"package_status":{"enum":["generated","not_generated"],"type":"string"},"product":{"$ref":"#/components/schemas/ReleaseSecurityProductSummary"},"readiness_status":{"enum":["passed","failed"],"type":"string"},"release":{"$ref":"#/components/schemas/ReleaseSecurityReleaseSummary"},"sbom_status":{"enum":["present","missing"],"type":"string"},"schema_version":{"type":"string"},"vulnerability_scan_status":{"enum":["present","missing"],"type":"string"}},"required":["product","release","artifact_count","sbom_status","vulnerability_scan_status","open_findings_by_severity","decisions_by_status","approval_summary","exception_summary","readiness_status","package_status","counts","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseSecuritySummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseSecuritySummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityUpdateEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"fixed_decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incidents":{"items":{"$ref":"#/components/schemas/Incident"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"remediation_tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"SecurityUpdateEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningCustodyReviewReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"object_retention_policies":{"items":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"type":"array"},"report_type":{"type":"string"},"signing_providers":{"items":{"$ref":"#/components/schemas/SigningProvider"},"type":"array"},"tenant_id":{"type":"string"}},"required":["report_type","tenant_id","checks","assumptions","limitations","generated_at"],"type":"object"},"SigningCustodyReviewReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningCustodyReviewReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportPreview":{"additionalProperties":false,"properties":{"advisory":{"type":"boolean"},"artifact_id":{"type":"string"},"assumptions":{"items":{"type":"string"},"type":"array"},"decisions_would_create":{"type":"integer"},"decisions_would_supersede":{"type":"integer"},"format":{"enum":["openvex","cyclonedx"],"type":"string"},"generated_at":{"format":"date-time","type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["tenant_id","release_id","format","parser_version","advisory","statement_count","status_summary","decisions_would_create","decisions_would_supersede","assumptions","limitations","schema_version","generated_at"],"type":"object"},"VEXImportPreviewEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportPreview"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"failure_code":{"type":"string"},"failure_detail":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"review_due_at":{"format":"date-time","type":"string"},"reviewed_at":{"format":"date-time","type":"string"},"sbom_component_name":{"type":"string"},"sbom_component_purl":{"type":"string"},"sbom_id":{"description":"Same-release SBOM that contained the matched component, when available.","type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"supporting_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"review_due_at":{"format":"date-time","type":"string"},"reviewed_at":{"format":"date-time","type":"string"},"sbom_component_name":{"type":"string"},"sbom_component_purl":{"type":"string"},"sbom_id":{"description":"Same-release SBOM that contained the matched component, when available.","type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"supporting_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"examples":{"release-evidence-package":{"summary":"Create a scoped release evidence package","value":{"expires_at":"2026-06-30T00:00:00Z","product_id":"prod_20260527120000","redaction_profile_id":"rp_20260527120000","release_id":"rel_20260527120000","title":"Payments API 1.0.0 release evidence package"}}},"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"get":{"description":"Lists tenant-scoped external reviewer access records without token hashes or token secrets.","operationId":"listCustomerPortalAccess","parameters":[{"description":"Optional customer package id filter.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessListEnvelope"}}},"description":"Customer portal access list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List customer portal access records","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a named, expiring external reviewer access record for a customer package and returns the portal token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/access/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped external reviewer access record; revocation is append-only and the original token cannot be used afterwards.","operationId":"revokeCustomerPortalAccess","parameters":[{"description":"Customer portal access id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessEnvelope"}}},"description":"Revoked customer portal access envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-answer-library":{"get":{"description":"Lists tenant-scoped questionnaire answer library entries with optional question, product, and release filters.","operationId":"listQuestionnaireAnswerLibrary","parameters":[{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by questionnaire question id.","in":"query","name":"question_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryListEnvelope"}}},"description":"Questionnaire answer library entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List questionnaire answer library entries","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a tenant-scoped reusable questionnaire answer draft linked to optional evidence, product, release, or control scope.","operationId":"createQuestionnaireAnswerLibraryEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireAnswerLibraryEntryRequest"}}},"description":"Questionnaire answer library entry creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryEnvelope"}}},"description":"Created questionnaire answer library entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire answer library entry","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"examples":{"release-candidate":{"summary":"Create a release for evidence collection","value":{"product_id":"prod_20260527120000","project_id":"proj_20260527120000","version":"1.0.0-rc.1"}}},"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"examples":{"created-release":{"summary":"Created release response","value":{"data":{"created_at":"2026-05-27T12:00:00Z","id":"rel_20260527120000","product_id":"prod_20260527120000","project_id":"proj_20260527120000","schema_version":"release.v1.0.0","status":"draft","tenant_id":"ten_20260527120000","version":"1.0.0-rc.1"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/evidence-flow/start":{"post":{"description":"Returns a high-level release evidence workflow plan, current evidence counts, required scopes, assumptions, and limitations. This read-only convenience operation does not create evidence.","operationId":"startReleaseEvidenceFlow","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEvidenceFlowEnvelope"}}},"description":"Release evidence flow envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Start release evidence flow","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:read"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/security-summary":{"get":{"description":"Returns a tenant-scoped release security summary for review surfaces without raw evidence payload bytes.","operationId":"releaseSecuritySummary","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseSecuritySummaryEnvelope"}}},"description":"Release security summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release security summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-vulnerability-handling":{"get":{"description":"Returns a CRA-oriented vulnerability handling evidence report without legal compliance, certification, scanner-authority, or release-security conclusions.","operationId":"craVulnerabilityHandlingReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReportEnvelope"}}},"description":"CRA vulnerability handling report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA vulnerability handling report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/custody-review":{"get":{"description":"Returns tenant signing-provider and object-lock verification metadata for deployment custody review. It is evidence metadata only, not legal compliance proof, certification, HSM custody proof, or a secure-deployment guarantee.","operationId":"signingCustodyReviewReport","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningCustodyReviewReportEnvelope"}}},"description":"Signing custody review report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Signing custody review report","tags":["evydence"],"x-scopes":["keys:admin"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"examples":{"failed-readiness-with-gap":{"summary":"Readiness report with a vulnerability decision gap","value":{"data":{"accepted_exceptions":[],"assumptions":["Readiness is based on tenant evidence recorded in Evydence."],"blocking_findings":[{"component":"pkg:apk/openssl@3.1.0-r0","decision_state":"missing","finding_id":"scan_20260527120000:finding:1","release_id":"rel_20260527120000","scan_id":"scan_20260527120000","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"generated_at":"2026-05-27T12:00:00Z","limitations":["Readiness supports technical review and does not prove legal compliance, certification, complete vulnerability coverage, or release security."],"missing_evidence":["vulnerability_decision"],"policy_set":"policy-set.v1.0.0","product_id":"prod_20260527120000","release_id":"rel_20260527120000","report_type":"release_readiness","result":"failed","schema_version":"release-readiness.v1.0.0","summary":{"headline":"Release evidence has one blocking vulnerability decision gap.","human_summary":"Required artifact, SBOM, scan, build, and bundle evidence is present, but one critical finding still needs a valid decision or approved exception.","policy_set":"policy-set.v1.0.0","result":"failed"},"template_version":"release-readiness.v1.0.0"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/security-update-evidence":{"get":{"description":"Returns a security update evidence report for release-scoped fixed decisions, incidents, remediation tasks, and linked evidence without legal or security conclusions.","operationId":"securityUpdateEvidenceReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReportEnvelope"}}},"description":"Security update evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security update evidence report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"examples":{"cyclonedx-release-sbom":{"summary":"Upload a CycloneDX SBOM linked to the release artifact","value":{"artifact_id":"art_20260527120000","payload":{"bomFormat":"CycloneDX","components":[{"name":"payments-api","purl":"pkg:oci/payments-api@sha256-ca978112","version":"1.0.0-rc.1"},{"name":"openssl","purl":"pkg:apk/openssl@3.1.0-r0","version":"3.1.0-r0"}],"specVersion":"1.6"},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx/preview":{"post":{"description":"Validates a CycloneDX VEX payload and returns advisory mapping counts without storing raw payloads, creating evidence, creating decisions, or enqueueing parser jobs.","operationId":"previewCycloneDXVEXImport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX import preview request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportPreviewEnvelope"}}},"description":"Advisory VEX import preview envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Preview CycloneDX VEX import","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":false},"x-scopes":["evidence:read"]}},"/v1/vex/preview":{"post":{"description":"Validates an OpenVEX payload and returns advisory mapping counts without storing raw payloads, creating evidence, creating decisions, or enqueueing parser jobs.","operationId":"previewVEXImport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX import preview request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportPreviewEnvelope"}}},"description":"Advisory VEX import preview envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Preview OpenVEX import","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":false},"x-scopes":["evidence:read"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"examples":{"not-affected-decision":{"summary":"Record a customer-visible not-affected decision","value":{"customer_visible":true,"evidence_ids":["ev_20260527120000"],"impact_statement":"The shipped artifact does not include the affected runtime path.","justification":"The vulnerable code path is not reachable in this release.","status":"not_affected","supporting_refs":[{"id":"exc_20260527120000","type":"exception"}]}}},"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"examples":{"generic-critical-finding":{"summary":"Upload a generic scanner finding for release triage","value":{"findings":[{"component":"pkg:apk/openssl@3.1.0-r0","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"release_id":"rel_20260527120000","scanner":"generic-json","target_ref":"pkg:oci/payments-api@sha256-ca978112"}}},"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} From ed3b23a721d8920c614a90254a67154f6f7b9153 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 17:30:09 +0300 Subject: [PATCH 229/287] docs(ci): add github actions quickstart setup --- .productization_next_steps_missing.md | 2 +- docs/how-to/integrate-ci.md | 52 +++++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index 9abcf84..e6ac406 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -348,7 +348,7 @@ Implementation rules: Description: Reduce the first CI integration to one obvious release-evidence path before users learn the full domain model. -### Ticket E5-T1 - Add a minimal GitHub Actions setup guide [ ] +### Ticket E5-T1 - Add a minimal GitHub Actions setup guide [x] Description: Add a short guide that starts from existing product/release/artifact IDs and wires one build to upload SBOM, vulnerability scan, provenance, optional diff --git a/docs/how-to/integrate-ci.md b/docs/how-to/integrate-ci.md index 2eee8ee..365ddbc 100644 --- a/docs/how-to/integrate-ci.md +++ b/docs/how-to/integrate-ci.md @@ -40,8 +40,9 @@ The composite upload action is Required quickstart inputs: -- `EVYDENCE_API_URL` as a GitHub secret -- `EVYDENCE_API_KEY` as a GitHub secret +- `EVYDENCE_API_URL` as a GitHub secret, for example `https://evydence.example.test` +- `EVYDENCE_API_KEY` as a GitHub secret with `build:write`, `evidence:write`, + `bundle:write`, and `verify:read` - `EVYDENCE_PROJECT_ID` as a GitHub variable - `EVYDENCE_RELEASE_ID` as a GitHub variable - `EVYDENCE_ARTIFACT_ID` as a GitHub variable @@ -61,6 +62,53 @@ and record GitHub OIDC metadata, grant `id-token: write` in the workflow and pas the value as evidence metadata; it does not request or verify a GitHub OIDC token. +### Minimal GitHub Actions Setup + +1. Create or locate the Evydence product, project, release, and artifact + records for the release candidate. Copy the project, release, and artifact + IDs into GitHub Actions variables named exactly `EVYDENCE_PROJECT_ID`, + `EVYDENCE_RELEASE_ID`, and `EVYDENCE_ARTIFACT_ID`. +2. Create a collector API key or tenant API key with the scopes listed above. + Store the API URL and API key as GitHub Actions secrets named exactly + `EVYDENCE_API_URL` and `EVYDENCE_API_KEY`. +3. Copy + [`docs/github-actions/quickstart-release-evidence.yml`](../github-actions/quickstart-release-evidence.yml) + into `.github/workflows/evydence-release-evidence.yml` in the repository + that builds the artifact. +4. Run the workflow manually with `workflow_dispatch`. + +Expected output: + +- `.evydence/artifact.digest` contains the SHA-256 digest of the built CLI + artifact. +- `.evydence/sbom.cdx.json` and `.evydence/grype.json` are uploaded as release + evidence through an upload manifest. +- GitHub Actions build provenance is recorded for the configured project and + release. +- The manifest upload creates a release bundle when the required release + evidence is present. +- `.evydence/release-readiness.json` contains the current readiness result, + gaps, assumptions, and limitations for review. + +Troubleshooting: + +- `401 Unauthorized` usually means `EVYDENCE_API_KEY` is missing, revoked, or + pasted with extra whitespace. Rotate the key if it may have been exposed; do + not print it in logs. +- `403 Forbidden` means the key authenticated but lacks a required scope. The + quickstart requires `build:write`, `evidence:write`, `bundle:write`, and + `verify:read`. +- `404 Not Found` usually means the project, release, or artifact ID is wrong + for the tenant bound to the API key. Check the GitHub variable values against + Evydence API responses. +- `409 IDEMPOTENCY_KEY_REUSED` means the same workflow run idempotency prefix + was reused with different payload content. Re-run with a new + `GITHUB_RUN_ATTEMPT` or change the manifest idempotency prefix only after + reviewing whether the earlier upload should remain authoritative. +- Readiness failures should be treated as evidence gaps or policy findings to + review, not as legal compliance, certification, or release-security + conclusions. + ## One-Shot CLI Upload For a local or CI path that already has files on disk, use the one-shot release From 75a40ed15db3c04e05f6fc24851968612a4f7728 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 17:43:23 +0300 Subject: [PATCH 230/287] feat(cli): add ci preflight checks --- .productization_next_steps_missing.md | 2 +- cmd/evydence/main.go | 238 +++++++++++++++++- cmd/evydence/main_test.go | 131 ++++++++++ docs/api.md | 3 + .../quickstart-release-evidence.yml | 13 + .../release-evidence-workflow.yml | 12 + docs/how-to/integrate-ci.md | 31 ++- docs/reference/api-contract-matrix.md | 5 +- .../adapters/httpapi/openapi_operations.go | 12 + .../adapters/httpapi/route_registration.go | 3 + internal/adapters/httpapi/router.go | 39 +++ internal/adapters/httpapi/router_test.go | 35 +++ internal/app/ledger.go | 60 +++++ internal/app/release_evidence_service.go | 12 + openapi.yaml | 2 +- sdk/openapi-route-catalog.json | 87 ++++++- 16 files changed, 666 insertions(+), 19 deletions(-) diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index e6ac406..68ebcd7 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -364,7 +364,7 @@ Implementation rules: errors. - Run `make docs-check`. -### Ticket E5-T2 - Add a preflight CLI command for CI configuration [ ] +### Ticket E5-T2 - Add a preflight CLI command for CI configuration [x] Description: Add a CLI command that verifies API URL, API key scope, product ID, release ID, artifact ID, and manifest paths before a CI upload runs. diff --git a/cmd/evydence/main.go b/cmd/evydence/main.go index da47ade..de5b4dc 100644 --- a/cmd/evydence/main.go +++ b/cmd/evydence/main.go @@ -25,6 +25,10 @@ import ( func main() { if err := run(os.Args[1:]); err != nil { fmt.Fprintln(os.Stderr, err) + var exitErr interface{ ExitCode() int } + if errors.As(err, &exitErr) { + os.Exit(exitErr.ExitCode()) + } os.Exit(1) } } @@ -69,6 +73,11 @@ func run(args []string) error { return usage() } return uploadGitHubActionsBuild(context.Background(), http.DefaultClient, args[2:]) + case "ci": + if len(args) < 2 || args[1] != "preflight" { + return usage() + } + return ciPreflight(context.Background(), http.DefaultClient, args[2:]) case "import-bundle": if len(args) < 2 || args[1] != "upload" { return usage() @@ -110,7 +119,7 @@ func run(args []string) error { } func usage() error { - return errors.New("usage: evydence hash | evydence verify-manifest --hash sha256: | evydence verify-evidence-bundle | evydence verify-audit-chain | evydence package verify ... | evydence github-actions upload-build ... | evydence import-bundle upload ... | evydence upload manifest|validate-manifest ... | evydence release upload-evidence|manifest|sign|verify|keygen") + return errors.New("usage: evydence hash | evydence verify-manifest --hash sha256: | evydence verify-evidence-bundle | evydence verify-audit-chain | evydence package verify ... | evydence github-actions upload-build ... | evydence ci preflight ... | evydence import-bundle upload ... | evydence upload manifest|validate-manifest ... | evydence release upload-evidence|manifest|sign|verify|keygen") } func hashFile(path string) (string, error) { @@ -1124,6 +1133,183 @@ func validateUploadManifestCommand(args []string) error { return nil } +const ( + exitCIPreflightMissingConfig = 2 + exitCIPreflightAuthFailure = 3 + exitCIPreflightWrongScope = 4 + exitCIPreflightWrongTenant = 5 + exitCIPreflightInvalidManifest = 6 +) + +type cliExitError struct { + code int + message string +} + +func (e cliExitError) Error() string { + return e.message +} + +func (e cliExitError) ExitCode() int { + return e.code +} + +func ciPreflight(ctx context.Context, client *http.Client, args []string) error { + fs := flag.NewFlagSet("ci preflight", flag.ContinueOnError) + fs.SetOutput(io.Discard) + apiURL := fs.String("url", strings.TrimSpace(os.Getenv("EVYDENCE_API_URL")), "Evydence API URL") + apiKey := fs.String("api-key", strings.TrimSpace(os.Getenv("EVYDENCE_API_KEY")), "Evydence API key") + productID := fs.String("product-id", strings.TrimSpace(os.Getenv("EVYDENCE_PRODUCT_ID")), "Evydence product ID") + projectID := fs.String("project-id", strings.TrimSpace(os.Getenv("EVYDENCE_PROJECT_ID")), "Evydence project ID") + releaseID := fs.String("release-id", strings.TrimSpace(os.Getenv("EVYDENCE_RELEASE_ID")), "Evydence release ID") + artifactID := fs.String("artifact-id", strings.TrimSpace(os.Getenv("EVYDENCE_ARTIFACT_ID")), "Evydence artifact ID") + manifestPath := fs.String("manifest", "", "upload manifest JSON path") + if err := fs.Parse(args); err != nil { + return ciExit(exitCIPreflightMissingConfig, "ci preflight configuration is invalid") + } + if fs.NArg() != 0 || strings.TrimSpace(*apiURL) == "" || strings.TrimSpace(*apiKey) == "" || + strings.TrimSpace(*productID) == "" || strings.TrimSpace(*projectID) == "" || + strings.TrimSpace(*releaseID) == "" || strings.TrimSpace(*artifactID) == "" || + strings.TrimSpace(*manifestPath) == "" { + return ciExit(exitCIPreflightMissingConfig, "ci preflight requires url, api key, product id, project id, release id, artifact id, and manifest path") + } + manifest, err := readAndValidateUploadManifest(*manifestPath) + if err != nil { + return ciExit(exitCIPreflightInvalidManifest, "ci preflight manifest is invalid: "+err.Error()) + } + if err := validatePreflightManifestIDs(manifest, *productID, *projectID, *releaseID, *artifactID); err != nil { + return ciExit(exitCIPreflightInvalidManifest, err.Error()) + } + productBody, err := getEvydence(ctx, client, *apiURL, *apiKey, "/v1/products/"+url.PathEscape(strings.TrimSpace(*productID))) + if err != nil { + return mapCIPreflightAPIError(err) + } + if err := ensureResponseDataID(productBody, *productID, "product"); err != nil { + return ciExit(exitCIPreflightWrongTenant, err.Error()) + } + projectBody, err := getEvydence(ctx, client, *apiURL, *apiKey, "/v1/projects/"+url.PathEscape(strings.TrimSpace(*projectID))) + if err != nil { + return mapCIPreflightAPIError(err) + } + if err := ensureResponseDataID(projectBody, *projectID, "project"); err != nil { + return ciExit(exitCIPreflightWrongTenant, err.Error()) + } + if err := ensureResponseDataField(projectBody, "product_id", *productID, "project product"); err != nil { + return ciExit(exitCIPreflightWrongTenant, err.Error()) + } + releaseBody, err := getEvydence(ctx, client, *apiURL, *apiKey, "/v1/releases/"+url.PathEscape(strings.TrimSpace(*releaseID))) + if err != nil { + return mapCIPreflightAPIError(err) + } + if err := ensureResponseDataID(releaseBody, *releaseID, "release"); err != nil { + return ciExit(exitCIPreflightWrongTenant, err.Error()) + } + if err := ensureResponseDataField(releaseBody, "product_id", *productID, "release product"); err != nil { + return ciExit(exitCIPreflightWrongTenant, err.Error()) + } + artifactBody, err := getEvydence(ctx, client, *apiURL, *apiKey, "/v1/artifacts/"+url.PathEscape(strings.TrimSpace(*artifactID))) + if err != nil { + return mapCIPreflightAPIError(err) + } + if err := ensureResponseDataID(artifactBody, *artifactID, "artifact"); err != nil { + return ciExit(exitCIPreflightWrongTenant, err.Error()) + } + fmt.Printf("ci preflight ok: product=%s project=%s release=%s artifact=%s manifest_requests=%d\n", strings.TrimSpace(*productID), strings.TrimSpace(*projectID), strings.TrimSpace(*releaseID), strings.TrimSpace(*artifactID), len(manifest.Requests)) + return nil +} + +func ciExit(code int, message string) error { + return cliExitError{code: code, message: message} +} + +func mapCIPreflightAPIError(err error) error { + var apiErr apiRequestError + if errors.As(err, &apiErr) { + switch apiErr.status { + case http.StatusUnauthorized: + return ciExit(exitCIPreflightAuthFailure, "ci preflight authentication failed") + case http.StatusForbidden: + return ciExit(exitCIPreflightWrongScope, "ci preflight API key lacks required scope") + case http.StatusNotFound: + return ciExit(exitCIPreflightWrongTenant, "ci preflight resource was not found for this tenant") + } + } + return err +} + +func ensureResponseDataID(body []byte, expected, name string) error { + return ensureResponseDataField(body, "id", expected, name) +} + +func ensureResponseDataField(body []byte, field, expected, name string) error { + var decoded struct { + Data map[string]any `json:"data"` + } + if err := json.Unmarshal(body, &decoded); err != nil { + return errors.New("ci preflight response is not valid JSON") + } + got, _ := decoded.Data[field].(string) + if strings.TrimSpace(got) != strings.TrimSpace(expected) { + return fmt.Errorf("ci preflight %s mismatch", name) + } + return nil +} + +func validatePreflightManifestIDs(manifest uploadManifestFile, productID, projectID, releaseID, artifactID string) error { + for index, req := range manifest.Requests { + payload, err := req.PayloadBytes() + if err != nil { + return fmt.Errorf("ci preflight manifest request %d payload cannot be read", index) + } + var value any + if err := json.Unmarshal(payload, &value); err != nil { + return fmt.Errorf("ci preflight manifest request %d payload is not valid JSON", index) + } + if err := checkManifestIDField(value, "product_id", productID, index); err != nil { + return err + } + if err := checkManifestIDField(value, "project_id", projectID, index); err != nil { + return err + } + if err := checkManifestIDField(value, "release_id", releaseID, index); err != nil { + return err + } + if err := checkManifestIDField(value, "artifact_id", artifactID, index); err != nil { + return err + } + } + return nil +} + +func checkManifestIDField(value any, field, expected string, index int) error { + found := []string{} + var walk func(any) + walk = func(node any) { + switch typed := node.(type) { + case map[string]any: + for key, child := range typed { + if key == field { + if got, ok := child.(string); ok && strings.TrimSpace(got) != "" { + found = append(found, strings.TrimSpace(got)) + } + } + walk(child) + } + case []any: + for _, child := range typed { + walk(child) + } + } + } + walk(value) + for _, got := range found { + if got != strings.TrimSpace(expected) { + return fmt.Errorf("ci preflight manifest request %d %s does not match configured value", index, field) + } + } + return nil +} + const uploadManifestSchemaVersion = "evydence-upload-manifest.v1.0.0" type uploadManifestFile struct { @@ -1922,6 +2108,38 @@ func postRawEvydence(ctx context.Context, client *http.Client, apiURL, apiKey, p return responseBody, nil } +func getEvydence(ctx context.Context, client *http.Client, apiURL, apiKey, path string) ([]byte, error) { + if client == nil { + client = http.DefaultClient + } + baseURL, err := cleanAPIURL(apiURL) + if err != nil { + return nil, err + } + // #nosec G704 -- this CLI intentionally sends requests to an operator-specified Evydence API URL after scheme and host validation. + req, err := http.NewRequestWithContext(ctx, http.MethodGet, baseURL+path, nil) + if err != nil { + return nil, err + } + req.Header.Set("Authorization", "Bearer "+strings.TrimSpace(apiKey)) + // #nosec G704 -- request target is the validated operator-specified Evydence API URL for this CLI command. + resp, err := client.Do(req) + if err != nil { + return nil, err + } + defer func() { + _ = resp.Body.Close() + }() + responseBody, err := io.ReadAll(io.LimitReader(resp.Body, 1<<20)) + if err != nil { + return nil, err + } + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + return nil, safeAPIError(resp.StatusCode, responseBody) + } + return responseBody, nil +} + func cleanAPIURL(raw string) (string, error) { parsed, err := url.Parse(strings.TrimSpace(raw)) if err != nil { @@ -1938,6 +2156,19 @@ func cleanAPIURL(raw string) (string, error) { return strings.TrimRight(parsed.String(), "/"), nil } +type apiRequestError struct { + status int + code string + detail string +} + +func (e apiRequestError) Error() string { + if e.code != "" { + return fmt.Sprintf("evydence API request failed: status=%d code=%s detail=%s", e.status, e.code, e.detail) + } + return fmt.Sprintf("evydence API request failed: status=%d detail=%s", e.status, e.detail) +} + func safeAPIError(status int, body []byte) error { var problem struct { Detail string `json:"detail"` @@ -1955,10 +2186,7 @@ func safeAPIError(status int, body []byte) error { if detail == "" { detail = http.StatusText(status) } - if code != "" { - return fmt.Errorf("evydence API request failed: status=%d code=%s detail=%s", status, code, detail) - } - return fmt.Errorf("evydence API request failed: status=%d detail=%s", status, detail) + return apiRequestError{status: status, code: code, detail: detail} } func responseDataID(body []byte) (string, error) { diff --git a/cmd/evydence/main_test.go b/cmd/evydence/main_test.go index 914ba93..d2ef4b2 100644 --- a/cmd/evydence/main_test.go +++ b/cmd/evydence/main_test.go @@ -8,6 +8,7 @@ import ( "encoding/base64" "encoding/hex" "encoding/json" + "errors" "io" "net/http" "net/http/httptest" @@ -109,6 +110,104 @@ func TestValidateUploadManifestCommand(t *testing.T) { } } +func TestCIPreflightVerifiesAPIAndManifestWithoutSecretLeakage(t *testing.T) { + dir := t.TempDir() + manifestPath := dir + "/upload.json" + body, err := json.Marshal(map[string]any{ + "schema_version": uploadManifestSchemaVersion, + "requests": []map[string]any{{ + "kind": "sbom", + "path": "/v1/sboms", + "idempotency_key": "sbom-1", + "payload": map[string]any{"release_id": "rel_1", "artifact_id": "art_1", "payload": map[string]any{"bomFormat": "CycloneDX"}}, + }, { + "kind": "release_bundle", + "path": "/v1/release-bundles", + "idempotency_key": "bundle-1", + "payload": map[string]any{"release_id": "rel_1"}, + }}, + }) + if err != nil { + t.Fatalf("marshal manifest: %v", err) + } + if err := os.WriteFile(manifestPath, body, 0o600); err != nil { + t.Fatalf("write manifest: %v", err) + } + seen := map[string]bool{} + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if got := r.Header.Get("Authorization"); got != "Bearer evy_secret_should_not_print" { + t.Fatalf("authorization header=%q", got) + } + seen[r.URL.Path] = true + switch r.URL.Path { + case "/v1/products/prod_1": + _, _ = w.Write([]byte(`{"data":{"id":"prod_1","tenant_id":"ten_1","name":"Payments","slug":"payments"},"meta":{"api_version":"v1"}}`)) + case "/v1/projects/proj_1": + _, _ = w.Write([]byte(`{"data":{"id":"proj_1","tenant_id":"ten_1","product_id":"prod_1","name":"api"},"meta":{"api_version":"v1"}}`)) + case "/v1/releases/rel_1": + _, _ = w.Write([]byte(`{"data":{"id":"rel_1","tenant_id":"ten_1","product_id":"prod_1","version":"1.0.0","state":"open"},"meta":{"api_version":"v1"}}`)) + case "/v1/artifacts/art_1": + _, _ = w.Write([]byte(`{"data":{"id":"art_1","tenant_id":"ten_1","name":"api.tar.gz","digest":"sha256:abc"},"meta":{"api_version":"v1"}}`)) + default: + t.Fatalf("unexpected path %s", r.URL.Path) + } + })) + defer server.Close() + out, err := captureStdout(t, func() error { + return ciPreflight(t.Context(), server.Client(), []string{ + "--url", server.URL, + "--api-key", "evy_secret_should_not_print", + "--product-id", "prod_1", + "--project-id", "proj_1", + "--release-id", "rel_1", + "--artifact-id", "art_1", + "--manifest", manifestPath, + }) + }) + if err != nil { + t.Fatalf("ci preflight: %v", err) + } + for _, path := range []string{"/v1/products/prod_1", "/v1/projects/proj_1", "/v1/releases/rel_1", "/v1/artifacts/art_1"} { + if !seen[path] { + t.Fatalf("missing preflight request %s, saw %#v", path, seen) + } + } + if !strings.Contains(out, "ci preflight ok") || strings.Contains(out, "evy_secret_should_not_print") { + t.Fatalf("unsafe or incomplete output: %s", out) + } +} + +func TestCIPreflightMapsStableExitCodesAndRedactsSecrets(t *testing.T) { + dir := t.TempDir() + badManifest := dir + "/bad.json" + if err := os.WriteFile(badManifest, []byte(`{"requests":[]}`), 0o600); err != nil { + t.Fatalf("write manifest: %v", err) + } + err := ciPreflight(t.Context(), http.DefaultClient, []string{"--url", "https://example.test", "--api-key", "evy_secret", "--product-id", "prod_1", "--project-id", "proj_1", "--release-id", "rel_1", "--artifact-id", "art_1", "--manifest", badManifest}) + assertCLIExitCode(t, err, exitCIPreflightInvalidManifest) + + statusTests := []struct { + status int + code int + }{ + {status: http.StatusUnauthorized, code: exitCIPreflightAuthFailure}, + {status: http.StatusForbidden, code: exitCIPreflightWrongScope}, + {status: http.StatusNotFound, code: exitCIPreflightWrongTenant}, + } + for _, tt := range statusTests { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.Error(w, `{"code":"TEST","detail":"safe failure"}`, tt.status) + })) + err := ciPreflight(t.Context(), server.Client(), []string{"--url", server.URL, "--api-key", "evy_secret_should_not_print", "--product-id", "prod_1", "--project-id", "proj_1", "--release-id", "rel_1", "--artifact-id", "art_1", "--manifest", validPreflightManifest(t, dir)}) + server.Close() + assertCLIExitCode(t, err, tt.code) + if strings.Contains(err.Error(), "evy_secret_should_not_print") { + t.Fatalf("preflight error leaked secret: %v", err) + } + } + assertCLIExitCode(t, ciPreflight(t.Context(), http.DefaultClient, []string{"--url", "https://example.test"}), exitCIPreflightMissingConfig) +} + func TestUploadManifestValidationRejectsUnsafeInputs(t *testing.T) { dir := t.TempDir() writeTestFile(t, dir+"/payload.json", []byte(`{"release_id":"rel_1"}`)) @@ -941,3 +1040,35 @@ func mustMarshalJSON(t *testing.T, value any) []byte { } return body } + +func validPreflightManifest(t *testing.T, dir string) string { + t.Helper() + path := dir + "/preflight-valid.json" + body := mustMarshalJSON(t, map[string]any{ + "schema_version": uploadManifestSchemaVersion, + "requests": []map[string]any{{ + "kind": "sbom", + "path": "/v1/sboms", + "idempotency_key": "sbom-1", + "payload": map[string]any{"release_id": "rel_1", "artifact_id": "art_1", "payload": map[string]any{"bomFormat": "CycloneDX"}}, + }}, + }) + if err := os.WriteFile(path, body, 0o600); err != nil { + t.Fatalf("write preflight manifest: %v", err) + } + return path +} + +func assertCLIExitCode(t *testing.T, err error, want int) { + t.Helper() + if err == nil { + t.Fatalf("expected exit code %d, got nil", want) + } + var exitErr interface{ ExitCode() int } + if !errors.As(err, &exitErr) { + t.Fatalf("err=%v does not expose exit code %d", err, want) + } + if got := exitErr.ExitCode(); got != want { + t.Fatalf("exit code=%d want=%d err=%v", got, want, err) + } +} diff --git a/docs/api.md b/docs/api.md index a0f6fb2..b6d747e 100644 --- a/docs/api.md +++ b/docs/api.md @@ -344,7 +344,9 @@ Current SSO endpoints model admin-managed provider, identity-link, trust-materia |--------|------|-------| | `POST` | `/v1/products` | Create product. | | `GET` | `/v1/products` | List products. | +| `GET` | `/v1/products/{id}` | Read product. | | `POST` | `/v1/projects` | Create project under product. | +| `GET` | `/v1/projects/{id}` | Read project. | | `POST` | `/v1/releases` | Create release. | | `GET` | `/v1/releases/{id}` | Read release. | | `POST` | `/v1/releases/{id}/evidence-flow/start` | Read high-level release evidence workflow plan. | @@ -352,6 +354,7 @@ Current SSO endpoints model admin-managed provider, identity-link, trust-materia | `POST` | `/v1/releases/{id}/freeze` | Append freeze transition. | | `POST` | `/v1/releases/{id}/approve` | Append approval transition. | | `POST` | `/v1/artifacts` | Register artifact digest metadata. | +| `GET` | `/v1/artifacts/{id}` | Read artifact digest metadata. | | `POST` | `/v1/evidence` | Create immutable evidence metadata. | | `GET` | `/v1/evidence` | List evidence by release/type. | | `GET` | `/v1/evidence/search` | Search by product, project, release, build, deployment, type, subtype, source, collector, verification status, subject, tag, created time, and limit. | diff --git a/docs/github-actions/quickstart-release-evidence.yml b/docs/github-actions/quickstart-release-evidence.yml index 78ff592..ed1d014 100644 --- a/docs/github-actions/quickstart-release-evidence.yml +++ b/docs/github-actions/quickstart-release-evidence.yml @@ -11,6 +11,7 @@ jobs: env: EVYDENCE_API_URL: ${{ secrets.EVYDENCE_API_URL }} EVYDENCE_API_KEY: ${{ secrets.EVYDENCE_API_KEY }} + EVYDENCE_PRODUCT_ID: ${{ vars.EVYDENCE_PRODUCT_ID }} EVYDENCE_PROJECT_ID: ${{ vars.EVYDENCE_PROJECT_ID }} EVYDENCE_RELEASE_ID: ${{ vars.EVYDENCE_RELEASE_ID }} EVYDENCE_ARTIFACT_ID: ${{ vars.EVYDENCE_ARTIFACT_ID }} @@ -88,6 +89,18 @@ jobs: fi python3 "${args[@]}" + - name: Preflight Evydence CI configuration + run: | + set -euo pipefail + dist/evydence ci preflight \ + --url "$EVYDENCE_API_URL" \ + --api-key "$EVYDENCE_API_KEY" \ + --product-id "$EVYDENCE_PRODUCT_ID" \ + --project-id "$EVYDENCE_PROJECT_ID" \ + --release-id "$EVYDENCE_RELEASE_ID" \ + --artifact-id "$EVYDENCE_ARTIFACT_ID" \ + --manifest .evydence/upload-manifest.json + - name: Upload release evidence and create release bundle run: | set -euo pipefail diff --git a/docs/github-actions/release-evidence-workflow.yml b/docs/github-actions/release-evidence-workflow.yml index 24bdb14..5f73759 100644 --- a/docs/github-actions/release-evidence-workflow.yml +++ b/docs/github-actions/release-evidence-workflow.yml @@ -81,9 +81,21 @@ jobs: env: EVYDENCE_API_URL: ${{ secrets.EVYDENCE_API_URL }} EVYDENCE_API_KEY: ${{ secrets.EVYDENCE_API_KEY }} + EVYDENCE_PRODUCT_ID: ${{ vars.EVYDENCE_PRODUCT_ID }} + EVYDENCE_PROJECT_ID: ${{ vars.EVYDENCE_PROJECT_ID }} + EVYDENCE_RELEASE_ID: ${{ vars.EVYDENCE_RELEASE_ID }} + EVYDENCE_ARTIFACT_ID: ${{ vars.EVYDENCE_ARTIFACT_ID }} run: | dist/evydence upload validate-manifest \ --manifest .evydence/upload-manifest.json + dist/evydence ci preflight \ + --url "$EVYDENCE_API_URL" \ + --api-key "$EVYDENCE_API_KEY" \ + --product-id "$EVYDENCE_PRODUCT_ID" \ + --project-id "$EVYDENCE_PROJECT_ID" \ + --release-id "$EVYDENCE_RELEASE_ID" \ + --artifact-id "$EVYDENCE_ARTIFACT_ID" \ + --manifest .evydence/upload-manifest.json dist/evydence upload manifest \ --url "$EVYDENCE_API_URL" \ --api-key "$EVYDENCE_API_KEY" \ diff --git a/docs/how-to/integrate-ci.md b/docs/how-to/integrate-ci.md index 365ddbc..0fbe169 100644 --- a/docs/how-to/integrate-ci.md +++ b/docs/how-to/integrate-ci.md @@ -42,7 +42,9 @@ Required quickstart inputs: - `EVYDENCE_API_URL` as a GitHub secret, for example `https://evydence.example.test` - `EVYDENCE_API_KEY` as a GitHub secret with `build:write`, `evidence:write`, - `bundle:write`, and `verify:read` + `bundle:write`, `verify:read`, `product:read`, `project:read`, + `release:read`, and `evidence:read` +- `EVYDENCE_PRODUCT_ID` as a GitHub variable - `EVYDENCE_PROJECT_ID` as a GitHub variable - `EVYDENCE_RELEASE_ID` as a GitHub variable - `EVYDENCE_ARTIFACT_ID` as a GitHub variable @@ -52,7 +54,8 @@ Required quickstart inputs: The CLI command used by the workflow reads GitHub-provided environment variables such as `GITHUB_REPOSITORY`, `GITHUB_WORKFLOW_REF`, `GITHUB_RUN_ID`, `GITHUB_RUN_ATTEMPT`, `GITHUB_REF`, and `GITHUB_SHA`. The API key used by the quickstart must be scoped for the operations it runs: -`build:write`, `evidence:write`, `bundle:write`, and `verify:read`. Add +`build:write`, `evidence:write`, `bundle:write`, `verify:read`, +`product:read`, `project:read`, `release:read`, and `evidence:read`. Add `package:write` only when the workflow is extended to generate a customer package. @@ -65,9 +68,10 @@ token. ### Minimal GitHub Actions Setup 1. Create or locate the Evydence product, project, release, and artifact - records for the release candidate. Copy the project, release, and artifact - IDs into GitHub Actions variables named exactly `EVYDENCE_PROJECT_ID`, - `EVYDENCE_RELEASE_ID`, and `EVYDENCE_ARTIFACT_ID`. + records for the release candidate. Copy the product, project, release, and + artifact IDs into GitHub Actions variables named exactly + `EVYDENCE_PRODUCT_ID`, `EVYDENCE_PROJECT_ID`, `EVYDENCE_RELEASE_ID`, and + `EVYDENCE_ARTIFACT_ID`. 2. Create a collector API key or tenant API key with the scopes listed above. Store the API URL and API key as GitHub Actions secrets named exactly `EVYDENCE_API_URL` and `EVYDENCE_API_KEY`. @@ -83,6 +87,8 @@ Expected output: artifact. - `.evydence/sbom.cdx.json` and `.evydence/grype.json` are uploaded as release evidence through an upload manifest. +- `evydence ci preflight` validates the API URL, API key scopes, product, + project, release, artifact, and manifest before the upload step. - GitHub Actions build provenance is recorded for the configured project and release. - The manifest upload creates a release bundle when the required release @@ -96,11 +102,16 @@ Troubleshooting: pasted with extra whitespace. Rotate the key if it may have been exposed; do not print it in logs. - `403 Forbidden` means the key authenticated but lacks a required scope. The - quickstart requires `build:write`, `evidence:write`, `bundle:write`, and - `verify:read`. -- `404 Not Found` usually means the project, release, or artifact ID is wrong - for the tenant bound to the API key. Check the GitHub variable values against - Evydence API responses. + quickstart requires `build:write`, `evidence:write`, `bundle:write`, + `verify:read`, `product:read`, `project:read`, `release:read`, and + `evidence:read`. +- `404 Not Found` usually means the product, project, release, or artifact ID + is wrong for the tenant bound to the API key. Check the GitHub variable values + against Evydence API responses. +- `evydence ci preflight` uses stable exit codes for CI routing: `2` for + missing configuration, `3` for authentication failure, `4` for missing scope, + `5` for wrong-tenant or missing resource, and `6` for invalid manifests. It + does not print the API key. - `409 IDEMPOTENCY_KEY_REUSED` means the same workflow run idempotency prefix was reused with different payload content. Re-run with a new `GITHUB_RUN_ATTEMPT` or change the manifest idempotency prefix only after diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index 1c4c850..777faff 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 180 operations: 180 precise, 0 broad. +Generated from 183 operations: 183 precise, 0 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -16,6 +16,7 @@ Generated from 180 operations: 180 precise, 0 broad. | GET | /v1/artifact-signatures/{id} | getArtifactSignature | Bearer | evidence:read | - | path:id | - | 200:application/json:ArtifactSignatureEnvelope | precise | | POST | /v1/artifact-signatures/{id}/verify-cosign | verifyCosignSignature | Bearer | verify:read | required | path:id | application/json:VerifyCosignSignatureRequest | 200:application/json:CosignVerificationEnvelope | precise | | POST | /v1/artifacts | registerArtifact | Bearer | evidence:write | required | - | application/json:RegisterArtifactRequest | 201:application/json:ArtifactEnvelope | precise | +| GET | /v1/artifacts/{id} | getArtifact | Bearer | evidence:read | - | path:id | - | 200:application/json:ArtifactEnvelope | precise | | GET | /v1/audit-chain/verify | verifyAuditChain | Bearer | verify:read | - | - | - | 200:application/json:VerificationResultEnvelope | precise | | GET | /v1/audit-log | listAuditLog | Bearer | admin | - | query:limit, query:since, query:subject_id, query:subject_type | - | 200:application/json:AuditChainEntryListEnvelope | precise | | POST | /v1/backup-manifests | generateBackupManifest | Bearer | admin | required | - | application/json:EmptyObject | 201:application/json:BackupManifestEnvelope | precise | @@ -94,7 +95,9 @@ Generated from 180 operations: 180 precise, 0 broad. | POST | /v1/policies/evaluate | evaluatePolicy | Bearer | verify:read | required | - | application/json:EvaluatePolicyRequest | 201:application/json:PolicyEvaluationEnvelope | precise | | GET | /v1/products | listProducts | Bearer | product:read | - | - | - | 200:application/json:ProductListEnvelope | precise | | POST | /v1/products | createProduct | Bearer | product:write | required | - | application/json:CreateProductRequest | 201:application/json:ProductEnvelope | precise | +| GET | /v1/products/{id} | getProduct | Bearer | product:read | - | path:id | - | 200:application/json:ProductEnvelope | precise | | POST | /v1/projects | createProject | Bearer | project:write | required | - | application/json:CreateProjectRequest | 201:application/json:ProjectEnvelope | precise | +| GET | /v1/projects/{id} | getProject | Bearer | project:read | - | path:id | - | 200:application/json:ProjectEnvelope | precise | | POST | /v1/provider-verifications | verifyProviderIdentity | Bearer | identity:admin | required | - | application/json:VerifyProviderIdentityRequest | 201:application/json:ProviderVerificationEnvelope | precise | | POST | /v1/public-transparency-log-entries | publishPublicTransparencyLogEntry | Bearer | keys:admin | required | - | application/json:PublishPublicTransparencyLogEntryRequest | 201:application/json:PublicTransparencyLogEntryEnvelope | precise | | POST | /v1/public-transparency-log-entries/{id}/fetch-proof | fetchPublicTransparencyLogEntryProof | Bearer | keys:admin | required | path:id | application/json:EmptyObject | 200:application/json:PublicTransparencyLogEntryEnvelope | precise | diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index a17fab0..d2c141e 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -152,10 +152,18 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { case "listProducts": operation.Description = "Lists tenant-scoped products visible to the authenticated actor." operation.Responses[http.StatusOK] = jsonResponse("Product list envelope.", "#/components/schemas/ProductListEnvelope") + case "getProduct": + operation.Description = "Returns a tenant-scoped product by id." + operation.Parameters = append(operation.Parameters, pathParam("id", "Product id.")) + operation.Responses[http.StatusOK] = jsonResponse("Product envelope.", "#/components/schemas/ProductEnvelope") case "createProject": operation.Description = "Creates a tenant-scoped project under a product." operation.RequestBody = jsonRequest("Project creation request.", "#/components/schemas/CreateProjectRequest") operation.Responses[http.StatusCreated] = jsonResponse("Created project envelope.", "#/components/schemas/ProjectEnvelope") + case "getProject": + operation.Description = "Returns a tenant-scoped project by id." + operation.Parameters = append(operation.Parameters, pathParam("id", "Project id.")) + operation.Responses[http.StatusOK] = jsonResponse("Project envelope.", "#/components/schemas/ProjectEnvelope") case "createRelease": operation.Description = "Creates an append-only release record under a product and optional project." operation.RequestBody = jsonRequest("Release creation request.", "#/components/schemas/CreateReleaseRequest") @@ -215,6 +223,10 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Description = "Registers an artifact digest for release evidence and later build/attestation matching." operation.RequestBody = jsonRequest("Artifact registration request.", "#/components/schemas/RegisterArtifactRequest") operation.Responses[http.StatusCreated] = jsonResponse("Registered artifact envelope.", "#/components/schemas/ArtifactEnvelope") + case "getArtifact": + operation.Description = "Returns a tenant-scoped artifact by id." + operation.Parameters = append(operation.Parameters, pathParam("id", "Artifact id.")) + operation.Responses[http.StatusOK] = jsonResponse("Artifact envelope.", "#/components/schemas/ArtifactEnvelope") case "createBuild": operation.Description = "Records an immutable CI build run. Collector identity is derived from the authenticated key when present." operation.RequestBody = jsonRequest("Build run creation request.", "#/components/schemas/CreateBuildRequest") diff --git a/internal/adapters/httpapi/route_registration.go b/internal/adapters/httpapi/route_registration.go index fa71508..96ba152 100644 --- a/internal/adapters/httpapi/route_registration.go +++ b/internal/adapters/httpapi/route_registration.go @@ -110,7 +110,9 @@ func (s *Server) productReleaseRoutes() []routeDef { return []routeDef{ {http.MethodPost, "/v1/products", op("createProduct", http.MethodPost, "/v1/products", "Create product", []string{app.ScopeProductWrite}), http.HandlerFunc(s.createProduct)}, {http.MethodGet, "/v1/products", op("listProducts", http.MethodGet, "/v1/products", "List products", []string{app.ScopeProductRead}), http.HandlerFunc(s.listProducts)}, + {http.MethodGet, "/v1/products/{id}", op("getProduct", http.MethodGet, "/v1/products/{id}", "Get product", []string{app.ScopeProductRead}), http.HandlerFunc(s.getProduct)}, {http.MethodPost, "/v1/projects", op("createProject", http.MethodPost, "/v1/projects", "Create project", []string{app.ScopeProjectWrite}), http.HandlerFunc(s.createProject)}, + {http.MethodGet, "/v1/projects/{id}", op("getProject", http.MethodGet, "/v1/projects/{id}", "Get project", []string{app.ScopeProjectRead}), http.HandlerFunc(s.getProject)}, {http.MethodPost, "/v1/releases", op("createRelease", http.MethodPost, "/v1/releases", "Create release", []string{app.ScopeReleaseWrite}), http.HandlerFunc(s.createRelease)}, {http.MethodGet, "/v1/releases/{id}", op("getRelease", http.MethodGet, "/v1/releases/{id}", "Get release", []string{app.ScopeReleaseRead}), http.HandlerFunc(s.getRelease)}, {http.MethodPost, "/v1/releases/{id}/evidence-flow/start", op("startReleaseEvidenceFlow", http.MethodPost, "/v1/releases/{id}/evidence-flow/start", "Start release evidence flow", []string{app.ScopeReleaseRead}), http.HandlerFunc(s.startReleaseEvidenceFlow)}, @@ -128,6 +130,7 @@ func (s *Server) productReleaseRoutes() []routeDef { func (s *Server) artifactBuildSourceRoutes() []routeDef { return []routeDef{ {http.MethodPost, "/v1/artifacts", op("registerArtifact", http.MethodPost, "/v1/artifacts", "Register artifact", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.registerArtifact)}, + {http.MethodGet, "/v1/artifacts/{id}", op("getArtifact", http.MethodGet, "/v1/artifacts/{id}", "Get artifact", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.getArtifact)}, {http.MethodPost, "/v1/container-images", op("registerContainerImage", http.MethodPost, "/v1/container-images", "Register container image", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.registerContainerImage)}, {http.MethodPost, "/v1/artifact-signatures", op("createArtifactSignature", http.MethodPost, "/v1/artifact-signatures", "Create artifact signature", []string{app.ScopeEvidenceWrite}), http.HandlerFunc(s.createArtifactSignature)}, {http.MethodGet, "/v1/artifact-signatures/{id}", op("getArtifactSignature", http.MethodGet, "/v1/artifact-signatures/{id}", "Get artifact signature", []string{app.ScopeEvidenceRead}), http.HandlerFunc(s.getArtifactSignature)}, diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index 067e542..b2e3c39 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -303,6 +303,19 @@ func (s *Server) listProducts(w http.ResponseWriter, r *http.Request) { writeData(w, http.StatusOK, products) } +func (s *Server) getProduct(w http.ResponseWriter, r *http.Request) { + actor, ok := s.authenticate(w, r) + if !ok { + return + } + product, err := s.ledger.GetProduct(r.Context(), actor, r.PathValue("id")) + if err != nil { + writeProblem(w, r, err) + return + } + writeData(w, http.StatusOK, product) +} + func (s *Server) createProject(w http.ResponseWriter, r *http.Request) { var req struct { ProductID string `json:"product_id"` @@ -317,6 +330,19 @@ func (s *Server) createProject(w http.ResponseWriter, r *http.Request) { }) } +func (s *Server) getProject(w http.ResponseWriter, r *http.Request) { + actor, ok := s.authenticate(w, r) + if !ok { + return + } + project, err := s.ledger.GetProject(r.Context(), actor, r.PathValue("id")) + if err != nil { + writeProblem(w, r, err) + return + } + writeData(w, http.StatusOK, project) +} + func (s *Server) createRelease(w http.ResponseWriter, r *http.Request) { var req struct { ProductID string `json:"product_id"` @@ -471,6 +497,19 @@ func (s *Server) registerArtifact(w http.ResponseWriter, r *http.Request) { }) } +func (s *Server) getArtifact(w http.ResponseWriter, r *http.Request) { + actor, ok := s.authenticate(w, r) + if !ok { + return + } + artifact, err := s.ledger.GetArtifact(r.Context(), actor, r.PathValue("id")) + if err != nil { + writeProblem(w, r, err) + return + } + writeData(w, http.StatusOK, artifact) +} + func (s *Server) registerContainerImage(w http.ResponseWriter, r *http.Request) { var req struct { ArtifactID string `json:"artifact_id"` diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index f4c2d59..685aed6 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -141,9 +141,13 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { assertResponseRef(t, createProduct, "201", "#/components/schemas/ProductEnvelope") listProducts := operationMap(t, paths, "/v1/products", "get") assertResponseRef(t, listProducts, "200", "#/components/schemas/ProductListEnvelope") + getProduct := operationMap(t, paths, "/v1/products/{id}", "get") + assertResponseRef(t, getProduct, "200", "#/components/schemas/ProductEnvelope") createProject := operationMap(t, paths, "/v1/projects", "post") assertRequestRef(t, createProject, "#/components/schemas/CreateProjectRequest") assertResponseRef(t, createProject, "201", "#/components/schemas/ProjectEnvelope") + getProject := operationMap(t, paths, "/v1/projects/{id}", "get") + assertResponseRef(t, getProject, "200", "#/components/schemas/ProjectEnvelope") createRelease := operationMap(t, paths, "/v1/releases", "post") assertRequestRef(t, createRelease, "#/components/schemas/CreateReleaseRequest") assertRequestExampleContains(t, createRelease, "release-candidate", "1.0.0-rc.1") @@ -161,6 +165,8 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { registerArtifact := operationMap(t, paths, "/v1/artifacts", "post") assertRequestRef(t, registerArtifact, "#/components/schemas/RegisterArtifactRequest") assertResponseRef(t, registerArtifact, "201", "#/components/schemas/ArtifactEnvelope") + getArtifact := operationMap(t, paths, "/v1/artifacts/{id}", "get") + assertResponseRef(t, getArtifact, "200", "#/components/schemas/ArtifactEnvelope") createBuild := operationMap(t, paths, "/v1/builds", "post") assertRequestRef(t, createBuild, "#/components/schemas/CreateBuildRequest") assertResponseRef(t, createBuild, "201", "#/components/schemas/BuildRunEnvelope") @@ -471,6 +477,35 @@ func TestCreateProductRequiresAuthAndIdempotency(t *testing.T) { } } +func TestProductProjectArtifactReadEndpoints(t *testing.T) { + server, secret := testServer(t) + productBody := postJSON(t, server, secret, "/v1/products", "ci-read-product", map[string]any{"name": "Payments", "slug": "ci-read-payments"}, http.StatusCreated) + productID := dataField(t, productBody, "id") + projectBody := postJSON(t, server, secret, "/v1/projects", "ci-read-project", map[string]any{"product_id": productID, "name": "API"}, http.StatusCreated) + projectID := dataField(t, projectBody, "id") + artifactBody := postJSON(t, server, secret, "/v1/artifacts", "ci-read-artifact", map[string]any{ + "name": "api.tar.gz", + "media_type": "application/gzip", + "digest": "sha256:ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", + "size": 42, + }, http.StatusCreated) + artifactID := dataField(t, artifactBody, "id") + + if !strings.Contains(getJSON(t, server, secret, "/v1/products/"+productID, http.StatusOK), `"id":"`+productID+`"`) { + t.Fatalf("product read did not include product id") + } + if !strings.Contains(getJSON(t, server, secret, "/v1/projects/"+projectID, http.StatusOK), `"product_id":"`+productID+`"`) { + t.Fatalf("project read did not include product link") + } + if !strings.Contains(getJSON(t, server, secret, "/v1/artifacts/"+artifactID, http.StatusOK), `"id":"`+artifactID+`"`) { + t.Fatalf("artifact read did not include artifact id") + } + + getJSON(t, server, secret, "/v1/products/prod_missing", http.StatusNotFound) + getJSON(t, server, secret, "/v1/projects/proj_missing", http.StatusNotFound) + getJSON(t, server, secret, "/v1/artifacts/art_missing", http.StatusNotFound) +} + func TestServerRateLimitReturnsSafeProblem(t *testing.T) { ledger := app.NewLedger(app.Config{APIKeyPepper: "test"}) server, err := NewServerWithOptions(ledger, ServerOptions{RateLimitRequestsPerMinute: 2}) diff --git a/internal/app/ledger.go b/internal/app/ledger.go index e780a2b..82ef9ef 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -398,6 +398,26 @@ func (s releaseEvidenceService) ListProducts(ctx context.Context, actor domain.A return out, nil } +func (s releaseEvidenceService) GetProduct(ctx context.Context, actor domain.Actor, id string) (domain.Product, error) { + l := s.ledger + if err := ctx.Err(); err != nil { + return domain.Product{}, err + } + if err := require(actor, ScopeProductRead); err != nil { + return domain.Product{}, err + } + l.mu.Lock() + defer l.mu.Unlock() + product, ok := l.products[strings.TrimSpace(id)] + if !ok || product.TenantID != actor.TenantID { + return domain.Product{}, ErrNotFound + } + if err := l.authorizeResourceLocked(actor, ScopeProductRead, resourceRefs{ProductID: product.ID}); err != nil { + return domain.Product{}, err + } + return product, nil +} + func (s releaseEvidenceService) CreateProject(ctx context.Context, actor domain.Actor, productID, name string) (domain.Project, error) { l := s.ledger if err := ctx.Err(); err != nil { @@ -428,6 +448,26 @@ func (s releaseEvidenceService) CreateProject(ctx context.Context, actor domain. return project, nil } +func (s releaseEvidenceService) GetProject(ctx context.Context, actor domain.Actor, id string) (domain.Project, error) { + l := s.ledger + if err := ctx.Err(); err != nil { + return domain.Project{}, err + } + if err := require(actor, ScopeProjectRead); err != nil { + return domain.Project{}, err + } + l.mu.Lock() + defer l.mu.Unlock() + project, ok := l.projects[strings.TrimSpace(id)] + if !ok || project.TenantID != actor.TenantID { + return domain.Project{}, ErrNotFound + } + if err := l.authorizeResourceLocked(actor, ScopeProjectRead, resourceRefs{ProductID: project.ProductID, ProjectID: project.ID}); err != nil { + return domain.Project{}, err + } + return project, nil +} + func (s releaseEvidenceService) CreateRelease(ctx context.Context, actor domain.Actor, productID, version string) (domain.Release, error) { l := s.ledger if err := ctx.Err(); err != nil { @@ -573,6 +613,26 @@ func (s releaseEvidenceService) RegisterArtifact(ctx context.Context, actor doma return artifact, nil } +func (s releaseEvidenceService) GetArtifact(ctx context.Context, actor domain.Actor, id string) (domain.Artifact, error) { + l := s.ledger + if err := ctx.Err(); err != nil { + return domain.Artifact{}, err + } + if err := require(actor, ScopeEvidenceRead); err != nil { + return domain.Artifact{}, err + } + l.mu.Lock() + defer l.mu.Unlock() + artifact, ok := l.artifacts[strings.TrimSpace(id)] + if !ok || artifact.TenantID != actor.TenantID { + return domain.Artifact{}, ErrNotFound + } + if err := l.authorizeResourceLocked(actor, ScopeEvidenceRead, resourceRefs{ArtifactID: artifact.ID}); err != nil { + return domain.Artifact{}, err + } + return artifact, nil +} + type CreateEvidenceInput struct { ProductID string ProjectID string diff --git a/internal/app/release_evidence_service.go b/internal/app/release_evidence_service.go index 78dc81a..2edf554 100644 --- a/internal/app/release_evidence_service.go +++ b/internal/app/release_evidence_service.go @@ -22,10 +22,18 @@ func (l *Ledger) ListProducts(ctx context.Context, actor domain.Actor) ([]domain return l.releaseEvidenceService().ListProducts(ctx, actor) } +func (l *Ledger) GetProduct(ctx context.Context, actor domain.Actor, id string) (domain.Product, error) { + return l.releaseEvidenceService().GetProduct(ctx, actor, id) +} + func (l *Ledger) CreateProject(ctx context.Context, actor domain.Actor, productID, name string) (domain.Project, error) { return l.releaseEvidenceService().CreateProject(ctx, actor, productID, name) } +func (l *Ledger) GetProject(ctx context.Context, actor domain.Actor, id string) (domain.Project, error) { + return l.releaseEvidenceService().GetProject(ctx, actor, id) +} + func (l *Ledger) CreateRelease(ctx context.Context, actor domain.Actor, productID, version string) (domain.Release, error) { return l.releaseEvidenceService().CreateRelease(ctx, actor, productID, version) } @@ -46,6 +54,10 @@ func (l *Ledger) RegisterArtifact(ctx context.Context, actor domain.Actor, name, return l.releaseEvidenceService().RegisterArtifact(ctx, actor, name, mediaType, digest, size) } +func (l *Ledger) GetArtifact(ctx context.Context, actor domain.Actor, id string) (domain.Artifact, error) { + return l.releaseEvidenceService().GetArtifact(ctx, actor, id) +} + func (l *Ledger) CreateEvidence(ctx context.Context, actor domain.Actor, in CreateEvidenceInput) (domain.EvidenceItem, error) { return l.releaseEvidenceService().CreateEvidence(ctx, actor, in) } diff --git a/openapi.yaml b/openapi.yaml index 289930e..ee9dfec 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1 +1 @@ -{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CRAVulnerabilityHandlingReport":{"additionalProperties":false,"properties":{"accepted_exceptions":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"CRAVulnerabilityHandlingReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"},"require_nda":{"type":"boolean"},"reviewer_email":{"description":"Optional external reviewer email label. It is not used as an authentication secret.","type":"string"},"reviewer_name":{"description":"Optional external reviewer display name for this package access record.","type":"string"},"watermark":{"description":"Optional customer-visible distribution watermark. It is not a token or secret.","type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireAnswerLibraryEntryRequest":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"}},"required":["answer"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"review_due_at":{"description":"Optional UTC time when this decision should be reviewed again.","format":"date-time","type":"string"},"reviewed_at":{"description":"Optional UTC time when the decision was reviewed. Defaults to creation time.","format":"date-time","type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"supporting_refs":{"description":"Optional tenant-scoped first-class decision support records from the same release. Supported types are approval, exception, waiver, remediation_task, release_bundle, and incident.","items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccess":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"failed_access_count":{"type":"integer"},"id":{"type":"string"},"last_accessed_at":{"format":"date-time","type":"string"},"last_failed_at":{"format":"date-time","type":"string"},"nda_accepted_at":{"format":"date-time","type":"string"},"nda_accepted_by":{"type":"string"},"package_id":{"type":"string"},"prefix":{"description":"Non-secret portal token prefix for operational lookup.","type":"string"},"require_nda":{"type":"boolean"},"reviewer_email":{"type":"string"},"reviewer_name":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"watermark":{"type":"string"}},"required":["id","tenant_id","package_id","customer_name","prefix","expires_at","access_count","failed_access_count","schema_version","created_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"$ref":"#/components/schemas/CustomerPortalAccess"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalAccessEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccess"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CustomerPortalAccess"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"nda_accepted":{"description":"Set true to record acceptance for NDA-gated portal access.","type":"boolean"},"nda_accepted_by":{"description":"Reviewer label recorded when NDA acceptance is required. Do not include secrets.","type":"string"},"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"distribution_watermark":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"remediation":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntry":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","answer","schema_version","created_at"],"type":"object"},"QuestionnaireAnswerLibraryEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"policy_set":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlow":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["needs_evidence","ready_for_review"],"type":"string"},"steps":{"items":{"$ref":"#/components/schemas/ReleaseEvidenceFlowStep"},"type":"array"}},"required":["release_id","product_id","status","counts","steps","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseEvidenceFlowEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseEvidenceFlow"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlowStep":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"idempotency_required":{"type":"boolean"},"method":{"type":"string"},"next_reference":{"type":"string"},"path":{"type":"string"},"required":{"type":"boolean"},"required_scopes":{"items":{"type":"string"},"type":"array"},"status":{"enum":["present","missing","optional"],"type":"string"},"title":{"type":"string"}},"required":["id","title","status","required","method","path","required_scopes","idempotency_required","description"],"type":"object"},"ReleaseSecurityApprovalSummary":{"additionalProperties":false,"properties":{"approved":{"type":"integer"},"total":{"type":"integer"}},"required":["total","approved"],"type":"object"},"ReleaseSecurityExceptionSummary":{"additionalProperties":false,"properties":{"approved_unexpired":{"type":"integer"},"expired":{"type":"integer"},"total":{"type":"integer"},"unapproved":{"type":"integer"}},"required":["total","approved_unexpired","unapproved","expired"],"type":"object"},"ReleaseSecurityMissingDecision":{"additionalProperties":false,"properties":{"component":{"type":"string"},"finding_id":{"type":"string"},"scan_id":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["finding_id","scan_id","vulnerability","severity","state"],"type":"object"},"ReleaseSecurityProductSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"],"type":"object"},"ReleaseSecurityReleaseSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"state":{"type":"string"},"version":{"type":"string"}},"required":["id","version","state"],"type":"object"},"ReleaseSecuritySummary":{"additionalProperties":false,"properties":{"approval_summary":{"$ref":"#/components/schemas/ReleaseSecurityApprovalSummary"},"artifact_count":{"type":"integer"},"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"decisions_by_status":{"additionalProperties":{"type":"integer"},"type":"object"},"exception_summary":{"$ref":"#/components/schemas/ReleaseSecurityExceptionSummary"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_required_decisions":{"items":{"$ref":"#/components/schemas/ReleaseSecurityMissingDecision"},"type":"array"},"open_findings_by_severity":{"additionalProperties":{"type":"integer"},"type":"object"},"package_status":{"enum":["generated","not_generated"],"type":"string"},"product":{"$ref":"#/components/schemas/ReleaseSecurityProductSummary"},"readiness_status":{"enum":["passed","failed"],"type":"string"},"release":{"$ref":"#/components/schemas/ReleaseSecurityReleaseSummary"},"sbom_status":{"enum":["present","missing"],"type":"string"},"schema_version":{"type":"string"},"vulnerability_scan_status":{"enum":["present","missing"],"type":"string"}},"required":["product","release","artifact_count","sbom_status","vulnerability_scan_status","open_findings_by_severity","decisions_by_status","approval_summary","exception_summary","readiness_status","package_status","counts","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseSecuritySummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseSecuritySummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityUpdateEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"fixed_decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incidents":{"items":{"$ref":"#/components/schemas/Incident"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"remediation_tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"SecurityUpdateEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningCustodyReviewReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"object_retention_policies":{"items":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"type":"array"},"report_type":{"type":"string"},"signing_providers":{"items":{"$ref":"#/components/schemas/SigningProvider"},"type":"array"},"tenant_id":{"type":"string"}},"required":["report_type","tenant_id","checks","assumptions","limitations","generated_at"],"type":"object"},"SigningCustodyReviewReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningCustodyReviewReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportPreview":{"additionalProperties":false,"properties":{"advisory":{"type":"boolean"},"artifact_id":{"type":"string"},"assumptions":{"items":{"type":"string"},"type":"array"},"decisions_would_create":{"type":"integer"},"decisions_would_supersede":{"type":"integer"},"format":{"enum":["openvex","cyclonedx"],"type":"string"},"generated_at":{"format":"date-time","type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["tenant_id","release_id","format","parser_version","advisory","statement_count","status_summary","decisions_would_create","decisions_would_supersede","assumptions","limitations","schema_version","generated_at"],"type":"object"},"VEXImportPreviewEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportPreview"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"failure_code":{"type":"string"},"failure_detail":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"review_due_at":{"format":"date-time","type":"string"},"reviewed_at":{"format":"date-time","type":"string"},"sbom_component_name":{"type":"string"},"sbom_component_purl":{"type":"string"},"sbom_id":{"description":"Same-release SBOM that contained the matched component, when available.","type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"supporting_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"review_due_at":{"format":"date-time","type":"string"},"reviewed_at":{"format":"date-time","type":"string"},"sbom_component_name":{"type":"string"},"sbom_component_purl":{"type":"string"},"sbom_id":{"description":"Same-release SBOM that contained the matched component, when available.","type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"supporting_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"examples":{"release-evidence-package":{"summary":"Create a scoped release evidence package","value":{"expires_at":"2026-06-30T00:00:00Z","product_id":"prod_20260527120000","redaction_profile_id":"rp_20260527120000","release_id":"rel_20260527120000","title":"Payments API 1.0.0 release evidence package"}}},"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"get":{"description":"Lists tenant-scoped external reviewer access records without token hashes or token secrets.","operationId":"listCustomerPortalAccess","parameters":[{"description":"Optional customer package id filter.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessListEnvelope"}}},"description":"Customer portal access list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List customer portal access records","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a named, expiring external reviewer access record for a customer package and returns the portal token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/access/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped external reviewer access record; revocation is append-only and the original token cannot be used afterwards.","operationId":"revokeCustomerPortalAccess","parameters":[{"description":"Customer portal access id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessEnvelope"}}},"description":"Revoked customer portal access envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-answer-library":{"get":{"description":"Lists tenant-scoped questionnaire answer library entries with optional question, product, and release filters.","operationId":"listQuestionnaireAnswerLibrary","parameters":[{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by questionnaire question id.","in":"query","name":"question_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryListEnvelope"}}},"description":"Questionnaire answer library entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List questionnaire answer library entries","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a tenant-scoped reusable questionnaire answer draft linked to optional evidence, product, release, or control scope.","operationId":"createQuestionnaireAnswerLibraryEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireAnswerLibraryEntryRequest"}}},"description":"Questionnaire answer library entry creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryEnvelope"}}},"description":"Created questionnaire answer library entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire answer library entry","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"examples":{"release-candidate":{"summary":"Create a release for evidence collection","value":{"product_id":"prod_20260527120000","project_id":"proj_20260527120000","version":"1.0.0-rc.1"}}},"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"examples":{"created-release":{"summary":"Created release response","value":{"data":{"created_at":"2026-05-27T12:00:00Z","id":"rel_20260527120000","product_id":"prod_20260527120000","project_id":"proj_20260527120000","schema_version":"release.v1.0.0","status":"draft","tenant_id":"ten_20260527120000","version":"1.0.0-rc.1"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/evidence-flow/start":{"post":{"description":"Returns a high-level release evidence workflow plan, current evidence counts, required scopes, assumptions, and limitations. This read-only convenience operation does not create evidence.","operationId":"startReleaseEvidenceFlow","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEvidenceFlowEnvelope"}}},"description":"Release evidence flow envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Start release evidence flow","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:read"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/security-summary":{"get":{"description":"Returns a tenant-scoped release security summary for review surfaces without raw evidence payload bytes.","operationId":"releaseSecuritySummary","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseSecuritySummaryEnvelope"}}},"description":"Release security summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release security summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-vulnerability-handling":{"get":{"description":"Returns a CRA-oriented vulnerability handling evidence report without legal compliance, certification, scanner-authority, or release-security conclusions.","operationId":"craVulnerabilityHandlingReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReportEnvelope"}}},"description":"CRA vulnerability handling report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA vulnerability handling report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/custody-review":{"get":{"description":"Returns tenant signing-provider and object-lock verification metadata for deployment custody review. It is evidence metadata only, not legal compliance proof, certification, HSM custody proof, or a secure-deployment guarantee.","operationId":"signingCustodyReviewReport","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningCustodyReviewReportEnvelope"}}},"description":"Signing custody review report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Signing custody review report","tags":["evydence"],"x-scopes":["keys:admin"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"examples":{"failed-readiness-with-gap":{"summary":"Readiness report with a vulnerability decision gap","value":{"data":{"accepted_exceptions":[],"assumptions":["Readiness is based on tenant evidence recorded in Evydence."],"blocking_findings":[{"component":"pkg:apk/openssl@3.1.0-r0","decision_state":"missing","finding_id":"scan_20260527120000:finding:1","release_id":"rel_20260527120000","scan_id":"scan_20260527120000","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"generated_at":"2026-05-27T12:00:00Z","limitations":["Readiness supports technical review and does not prove legal compliance, certification, complete vulnerability coverage, or release security."],"missing_evidence":["vulnerability_decision"],"policy_set":"policy-set.v1.0.0","product_id":"prod_20260527120000","release_id":"rel_20260527120000","report_type":"release_readiness","result":"failed","schema_version":"release-readiness.v1.0.0","summary":{"headline":"Release evidence has one blocking vulnerability decision gap.","human_summary":"Required artifact, SBOM, scan, build, and bundle evidence is present, but one critical finding still needs a valid decision or approved exception.","policy_set":"policy-set.v1.0.0","result":"failed"},"template_version":"release-readiness.v1.0.0"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/security-update-evidence":{"get":{"description":"Returns a security update evidence report for release-scoped fixed decisions, incidents, remediation tasks, and linked evidence without legal or security conclusions.","operationId":"securityUpdateEvidenceReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReportEnvelope"}}},"description":"Security update evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security update evidence report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"examples":{"cyclonedx-release-sbom":{"summary":"Upload a CycloneDX SBOM linked to the release artifact","value":{"artifact_id":"art_20260527120000","payload":{"bomFormat":"CycloneDX","components":[{"name":"payments-api","purl":"pkg:oci/payments-api@sha256-ca978112","version":"1.0.0-rc.1"},{"name":"openssl","purl":"pkg:apk/openssl@3.1.0-r0","version":"3.1.0-r0"}],"specVersion":"1.6"},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx/preview":{"post":{"description":"Validates a CycloneDX VEX payload and returns advisory mapping counts without storing raw payloads, creating evidence, creating decisions, or enqueueing parser jobs.","operationId":"previewCycloneDXVEXImport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX import preview request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportPreviewEnvelope"}}},"description":"Advisory VEX import preview envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Preview CycloneDX VEX import","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":false},"x-scopes":["evidence:read"]}},"/v1/vex/preview":{"post":{"description":"Validates an OpenVEX payload and returns advisory mapping counts without storing raw payloads, creating evidence, creating decisions, or enqueueing parser jobs.","operationId":"previewVEXImport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX import preview request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportPreviewEnvelope"}}},"description":"Advisory VEX import preview envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Preview OpenVEX import","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":false},"x-scopes":["evidence:read"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"examples":{"not-affected-decision":{"summary":"Record a customer-visible not-affected decision","value":{"customer_visible":true,"evidence_ids":["ev_20260527120000"],"impact_statement":"The shipped artifact does not include the affected runtime path.","justification":"The vulnerable code path is not reachable in this release.","status":"not_affected","supporting_refs":[{"id":"exc_20260527120000","type":"exception"}]}}},"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"examples":{"generic-critical-finding":{"summary":"Upload a generic scanner finding for release triage","value":{"findings":[{"component":"pkg:apk/openssl@3.1.0-r0","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"release_id":"rel_20260527120000","scanner":"generic-json","target_ref":"pkg:oci/payments-api@sha256-ca978112"}}},"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} +{"components":{"schemas":{"APIKey":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_used_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"prefix":{"description":"Non-secret key prefix for lookup and audit displays.","type":"string"},"revoked_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","prefix","scopes","created_at"],"type":"object"},"APIKeyCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/APIKeyCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"APIKeyCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"secret":{"description":"One-time API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["api_key","secret"],"type":"object"},"APIKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/APIKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalyReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"result":{"type":"string"},"schema_version":{"type":"string"},"signals":{"items":{"$ref":"#/components/schemas/AnomalySignal"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","assumptions","limitations","schema_version","created_at"],"type":"object"},"AnomalyReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/AnomalyReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AnomalySignal":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"severity":{"type":"string"}},"required":["name","severity","detail"],"type":"object"},"ApprovalRecord":{"additionalProperties":false,"properties":{"approver_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decision":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","decision","reason","approver_id","schema_version","created_at"],"type":"object"},"ApprovalRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ApprovalRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Artifact":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"size":{"type":"integer"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","digest","schema_version","created_at"],"type":"object"},"ArtifactEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Artifact"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ArtifactSignature":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"schema_version":{"type":"string"},"signature":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","artifact_id","subject_digest","algorithm","signature","verification_status","schema_version","created_at"],"type":"object"},"ArtifactSignatureEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ArtifactSignature"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"AuditChainEntry":{"additionalProperties":false,"properties":{"actor_id":{"type":"string"},"actor_type":{"type":"string"},"canonical_entry_hash":{"pattern":"^sha256:","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"entry_type":{"type":"string"},"id":{"type":"string"},"idempotency_key":{"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"occurred_at":{"format":"date-time","type":"string"},"payload_hash":{"type":"string"},"previous_entry_hash":{"type":"string"},"request_id":{"type":"string"},"schema_version":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sequence","entry_type","subject_type","subject_id","actor_type","actor_id","occurred_at","canonical_entry_hash","previous_entry_hash","entry_hash","schema_version"],"type":"object"},"AuditChainEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditChainEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BackupManifest":{"additionalProperties":false,"properties":{"consistency_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"schema_version":{"type":"string"},"state_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","state_hash","resource_counts","consistency_checks","limitations","schema_version","created_at"],"type":"object"},"BackupManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BackupManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildAttestation":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"build_type":{"type":"string"},"builder_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"materials_count":{"type":"integer"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"payload_type":{"type":"string"},"predicate_type":{"type":"string"},"schema_version":{"type":"string"},"signature_count":{"type":"integer"},"subject_digests":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"}},"required":["id","tenant_id","build_id","evidence_id","payload_hash","payload_size","payload_type","predicate_type","subject_digests","signature_count","verification_status","schema_version","created_at"],"type":"object"},"BuildAttestationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildAttestation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"BuildRun":{"additionalProperties":false,"properties":{"collector_id":{"type":"string"},"commit_sha":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","project_id","release_id","provider","commit_sha","status","schema_version","created_at"],"type":"object"},"BuildRunEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/BuildRun"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CRAVulnerabilityHandlingReport":{"additionalProperties":false,"properties":{"accepted_exceptions":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"CRAVulnerabilityHandlingReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Collector":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"api_key_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"last_seen_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","type","version","api_key_id","status","allowed_scopes","schema_version","created_at"],"type":"object"},"CollectorCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorCreateResponse":{"additionalProperties":false,"properties":{"api_key":{"$ref":"#/components/schemas/APIKey"},"collector":{"$ref":"#/components/schemas/Collector"},"secret":{"description":"One-time collector API key secret; stored only as a peppered HMAC hash.","type":"string"}},"required":["collector","api_key","secret"],"type":"object"},"CollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector_id":{"type":"string"},"collector_status":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"latest_release":{"$ref":"#/components/schemas/CollectorRelease"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned_release_id":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","collector_status","supply_chain_status","checks","assumptions","limitations","generated_at"],"type":"object"},"CollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Collector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CollectorRelease":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"health_status":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"tenant_id":{"type":"string"},"verification_status":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","collector_id","version","artifact_digest","pinned","verification_status","health_status","schema_version","created_at"],"type":"object"},"CollectorReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CollectorRelease"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinition":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","manifest_hash","allowed_scopes","status","schema_version","created_at"],"type":"object"},"CommercialCollectorDefinitionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CommercialCollectorDefinitionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CommercialCollectorDefinition"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContainerImage":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"digest":{"type":"string"},"id":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"schema_version":{"type":"string"},"tag":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository","digest","schema_version","created_at"],"type":"object"},"ContainerImageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContainerImage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ContractDiff":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"breaking_changes":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"non_breaking_changes":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"target_contract_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","base_contract_id","target_contract_id","product_id","result","schema_version","created_at"],"type":"object"},"ContractDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ContractDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidence":{"additionalProperties":false,"properties":{"confidence":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","control_id","evidence_type","subject_type","subject_id","confidence","schema_version","created_at"],"type":"object"},"ControlEvidenceEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlEvidence"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlEvidence"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlEvidenceRequirement":{"additionalProperties":false,"properties":{"freshness_days":{"minimum":0,"type":"integer"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["type","required"],"type":"object"},"ControlFramework":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","slug","version","status","schema_version","created_at"],"type":"object"},"ControlFrameworkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ControlFramework"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFramework"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ControlFrameworkTemplatePack":{"additionalProperties":false,"properties":{"controls":{"items":{"$ref":"#/components/schemas/SecurityControl"},"type":"array"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["id","name","slug","version","controls","schema_version"],"type":"object"},"ControlFrameworkTemplatePackListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ControlFrameworkTemplatePack"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CosignVerification":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"artifact_signature_id":{"type":"string"},"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"container_image_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject_digest":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","artifact_signature_id","subject_digest","result","checks","schema_version","created_at"],"type":"object"},"CosignVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CosignVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CreateAPIKeyRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"required":["name","scopes"],"type":"object"},"CreateAnomalyReportRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"CreateApprovalRequest":{"additionalProperties":false,"properties":{"decision":{"enum":["approved","rejected","accepted"],"type":"string"},"evidence_id":{"type":"string"},"reason":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","decision","reason"],"type":"object"},"CreateArtifactSignatureRequest":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"artifact_id":{"type":"string"},"key_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"payload_media_type":{"type":"string"},"signature":{"type":"string"}},"required":["artifact_id","algorithm","signature"],"type":"object"},"CreateBuildRequest":{"additionalProperties":false,"properties":{"commit_sha":{"type":"string"},"completed_at":{"format":"date-time","type":"string"},"github":{"type":"object"},"outputs":{"items":{"type":"object"},"type":"array"},"project_id":{"type":"string"},"provider":{"type":"string"},"release_id":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"enum":["queued","running","passed","failed","cancelled"],"type":"string"}},"required":["project_id","release_id","provider","commit_sha","status","started_at"],"type":"object"},"CreateCollectorRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"type":{"enum":["github_actions","gitlab_ci","generic_ci","import_bundle"],"type":"string"},"version":{"type":"string"}},"required":["name","type","version"],"type":"object"},"CreateCommercialCollectorRequest":{"additionalProperties":false,"properties":{"allowed_scopes":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","manifest_hash"],"type":"object"},"CreateControlFrameworkRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"type":"object"},"CreateCustomPolicyRequest":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"version":{"type":"string"}},"required":["name","version","rules"],"type":"object"},"CreateCustomerPackageRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["product_id","redaction_profile_id","title","expires_at"],"type":"object"},"CreateCustomerPortalAccessRequest":{"additionalProperties":false,"properties":{"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"package_id":{"type":"string"},"require_nda":{"type":"boolean"},"reviewer_email":{"description":"Optional external reviewer email label. It is not used as an authentication secret.","type":"string"},"reviewer_name":{"description":"Optional external reviewer display name for this package access record.","type":"string"},"watermark":{"description":"Optional customer-visible distribution watermark. It is not a token or secret.","type":"string"}},"required":["package_id","customer_name","expires_at"],"type":"object"},"CreateDSSETrustRootRequest":{"additionalProperties":false,"properties":{"algorithm":{"enum":["Ed25519"],"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"description":"Base64-encoded Ed25519 public key.","type":"string"}},"required":["name","key_id","algorithm","public_key"],"type":"object"},"CreateDeploymentEnvironmentRequest":{"additionalProperties":false,"properties":{"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"}},"required":["product_id","name","kind"],"type":"object"},"CreateEvidenceRequest":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"collector_id":{"type":"string"},"deployment_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"minimum":0,"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"release_id":{"type":"string"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"title":{"type":"string"},"type":{"type":"string"}},"required":["type","title","payload_hash"],"type":"object"},"CreateEvidenceSummaryRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id","evidence_ids"],"type":"object"},"CreateExceptionRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"}},"required":["release_id","reason","owner","expires_at"],"type":"object"},"CreateGraphSnapshotRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"}},"type":"object"},"CreateIncidentRequest":{"additionalProperties":false,"properties":{"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"severity":{"enum":["low","medium","high","critical"],"type":"string"},"title":{"type":"string"}},"required":["product_id","title","severity"],"type":"object"},"CreateIncidentWebhookReceiverRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"description":"Ed25519 public key used to verify signed incident webhook events.","type":"string"}},"required":["name","provider","public_key"],"type":"object"},"CreateLegalHoldRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","reason","owner"],"type":"object"},"CreateMarketplaceCollectorRequest":{"additionalProperties":false,"properties":{"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["name","provider","version","publisher","manifest_hash"],"type":"object"},"CreateMerkleBatchRequest":{"additionalProperties":false,"properties":{"from_sequence":{"format":"int64","type":"integer"},"to_sequence":{"format":"int64","type":"integer"}},"type":"object"},"CreateObjectRetentionPolicyRequest":{"additionalProperties":false,"properties":{"mode":{"enum":["governance","compliance"],"type":"string"},"name":{"type":"string"},"object_key":{"description":"Optional tenant-prefixed sample object key used for object-level retention verification when supported by the object store.","type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"description":"When true, the sample object key must have provider-reported legal hold enabled.","type":"boolean"},"retention_days":{"minimum":1,"type":"integer"}},"required":["name","mode","retention_days"],"type":"object"},"CreateOpenAPIDiffRequest":{"additionalProperties":false,"properties":{"base_contract_id":{"type":"string"},"release_id":{"type":"string"},"target_contract_id":{"type":"string"}},"required":["base_contract_id","target_contract_id","release_id"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreatePDFReportPackageRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"title":{"type":"string"}},"required":["report_type","title"],"type":"object"},"CreateProductRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"required":["name","slug"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"product_id":{"type":"string"},"slug":{"type":"string"}},"required":["product_id","name","slug"],"type":"object"},"CreatePublicTransparencyLogRequest":{"additionalProperties":false,"properties":{"endpoint":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"}},"required":["name","endpoint","public_key"],"type":"object"},"CreateQuestionnaireAnswerLibraryEntryRequest":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"}},"required":["answer"],"type":"object"},"CreateQuestionnaireDraftRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnairePackageRequest":{"additionalProperties":false,"properties":{"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},"CreateQuestionnaireTemplateRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"version":{"type":"string"}},"required":["name","version","questions"],"type":"object"},"CreateRedactionProfileRequest":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"preset":{"description":"Optional standard profile preset. When set, allowed_types and excluded_fields are server-defined and must be omitted.","enum":["customer_safe","security_review"],"type":"string"}},"type":"object"},"CreateReleaseBundleRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"CreateReleaseCandidateRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["release_id","name"],"type":"object"},"CreateReleaseRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"project_id":{"type":"string"},"version":{"type":"string"}},"required":["product_id","version"],"type":"object"},"CreateRemediationTaskRequest":{"additionalProperties":false,"properties":{"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"title":{"type":"string"}},"required":["title","owner"],"type":"object"},"CreateReportTemplateRequest":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"report_type":{"type":"string"},"template":{"type":"string"},"version":{"type":"string"}},"required":["name","version","report_type","allowed_fields","template"],"type":"object"},"CreateRetentionOverrideRequest":{"additionalProperties":false,"properties":{"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["scope_type","scope_id","retention_until","reason","owner"],"type":"object"},"CreateRoleBindingRequest":{"additionalProperties":false,"properties":{"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"enum":["user","collector"],"type":"string"}},"required":["subject_type","subject_id","role"],"type":"object"},"CreateSBOMDiffRequest":{"additionalProperties":false,"properties":{"base_sbom_id":{"type":"string"},"release_id":{"type":"string"},"target_sbom_id":{"type":"string"}},"required":["base_sbom_id","target_sbom_id"],"type":"object"},"CreateSSOProviderRequest":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"groups_claim":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Optional static JWKS public-key material for local OIDC ID-token verification. Private keys and provider secrets must not be supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Optional PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["name","type","issuer","client_id"],"type":"object"},"CreateSSOSessionRequest":{"additionalProperties":false,"properties":{"expires_at":{"format":"date-time","type":"string"},"provider_id":{"type":"string"},"user_id":{"type":"string"}},"required":["user_id","provider_id","expires_at"],"type":"object"},"CreateSaaSEditionProfileRequest":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"isolation_model":{"type":"string"},"name":{"type":"string"},"region":{"type":"string"}},"required":["name","region","admin_tenant_id","isolation_model"],"type":"object"},"CreateSecurityControlRequest":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"title":{"type":"string"}},"required":["framework_id","code","title","objective"],"type":"object"},"CreateSigningOperationRequest":{"additionalProperties":false,"properties":{"external_signature":{"description":"Optional when a server-side signing executor is configured. The executor signs payload_hash and Evydence records only the returned signature receipt.","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["provider_id","subject_type","subject_id","payload_hash"],"type":"object"},"CreateSigningProviderRequest":{"additionalProperties":false,"properties":{"encrypted":{"type":"boolean"},"key_ref":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type","key_ref"],"type":"object"},"CreateSourceRepositoryRequest":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"}},"required":["provider","full_name"],"type":"object"},"CreateTransparencyCheckpointRequest":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"provider":{"type":"string"}},"required":["batch_id","provider"],"type":"object"},"CreateUserRequest":{"additionalProperties":false,"properties":{"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"organization_id":{"type":"string"}},"required":["email","display_name"],"type":"object"},"CreateVulnerabilityDecisionRequest":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"customer_visible":{"type":"boolean"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; excluded from customer-safe package summaries.","type":"string"},"justification":{"type":"string"},"review_due_at":{"description":"Optional UTC time when this decision should be reviewed again.","format":"date-time","type":"string"},"reviewed_at":{"description":"Optional UTC time when the decision was reviewed. Defaults to creation time.","format":"date-time","type":"string"},"status":{"enum":["affected","not_affected","fixed","under_investigation"],"type":"string"},"supporting_refs":{"description":"Optional tenant-scoped first-class decision support records from the same release. Supported types are approval, exception, waiver, remediation_task, release_bundle, and incident.","items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"vex_document_id":{"description":"Optional tenant-scoped VEX document from the same release to link to this manual decision.","type":"string"}},"required":["status","justification"],"type":"object"},"CreateWaiverRequest":{"additionalProperties":false,"properties":{"control_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"supersedes":{"type":"string"}},"required":["scope_type","scope_id","owner","risk","reason","expires_at"],"type":"object"},"CustomPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"rules":{"items":{"$ref":"#/components/schemas/PolicyRule"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","rules","schema_version","created_at"],"type":"object"},"CustomPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomPolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"input_hash":{"pattern":"^sha256:","type":"string"},"policy_id":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","policy_id","release_id","result","checks","input_hash","schema_version","created_at"],"type":"object"},"CustomPolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomPolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomReportTemplate":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"template":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","report_type","allowed_fields","template","schema_version","created_at"],"type":"object"},"CustomReportTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomReportTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccess":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"customer_name":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"failed_access_count":{"type":"integer"},"id":{"type":"string"},"last_accessed_at":{"format":"date-time","type":"string"},"last_failed_at":{"format":"date-time","type":"string"},"nda_accepted_at":{"format":"date-time","type":"string"},"nda_accepted_by":{"type":"string"},"package_id":{"type":"string"},"prefix":{"description":"Non-secret portal token prefix for operational lookup.","type":"string"},"require_nda":{"type":"boolean"},"reviewer_email":{"type":"string"},"reviewer_name":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"watermark":{"type":"string"}},"required":["id","tenant_id","package_id","customer_name","prefix","expires_at","access_count","failed_access_count","schema_version","created_at"],"type":"object"},"CustomerPortalAccessCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccessCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessCreateResponse":{"additionalProperties":false,"properties":{"access":{"$ref":"#/components/schemas/CustomerPortalAccess"},"secret":{"description":"One-time portal token; stored only as a HMAC hash.","type":"string"}},"required":["access","secret"],"type":"object"},"CustomerPortalAccessEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerPortalAccess"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalAccessListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/CustomerPortalAccess"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"CustomerPortalPackageRequest":{"additionalProperties":false,"properties":{"nda_accepted":{"description":"Set true to record acceptance for NDA-gated portal access.","type":"boolean"},"nda_accepted_by":{"description":"Reviewer label recorded when NDA acceptance is required. Do not include secrets.","type":"string"},"token":{"description":"Customer portal access token issued by createCustomerPortalAccess.","type":"string"}},"required":["token"],"type":"object"},"CustomerSecurityPackage":{"additionalProperties":false,"properties":{"access_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"distribution_watermark":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"redaction_profile_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","redaction_profile_id","title","state","manifest","manifest_hash","expires_at","access_count","schema_version","created_at"],"type":"object"},"CustomerSecurityPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/CustomerSecurityPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DSSEEnvelope":{"additionalProperties":false,"properties":{"payload":{"type":"string"},"payloadType":{"type":"string"},"signatures":{"items":{"additionalProperties":false,"properties":{"keyid":{"type":"string"},"sig":{"type":"string"}},"required":["sig"],"type":"object"},"type":"array"}},"required":["payloadType","payload","signatures"],"type":"object"},"DSSETrustRoot":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"key_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","key_id","algorithm","public_key","status","schema_version","created_at"],"type":"object"},"DSSETrustRootEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DSSETrustRoot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DataEnvelope":{"additionalProperties":false,"properties":{"data":{},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DependencyChange":{"additionalProperties":false,"properties":{"change_type":{"enum":["added","removed","changed"],"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"sbom_diff_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","sbom_diff_id","change_type","component","schema_version","created_at"],"type":"object"},"DeploymentEnvironment":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","kind","schema_version","created_at"],"type":"object"},"DeploymentEnvironmentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEnvironment"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEnvironmentListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEnvironment"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEvent":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"environment_id":{"type":"string"},"evidence_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"schema_version":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","environment_id","release_id","status","started_at","schema_version","created_at"],"type":"object"},"DeploymentEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/DeploymentEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"DeploymentEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/DeploymentEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EmptyObject":{"additionalProperties":false,"properties":{},"type":"object"},"EvaluatePolicyRequest":{"additionalProperties":false,"properties":{"release_id":{"type":"string"}},"required":["release_id"],"type":"object"},"EvidenceBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"manifest":{"additionalProperties":true,"type":"object"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"verification_text":{"type":"string"}},"required":["id","tenant_id","evidence_ids","manifest","manifest_hash","verification_text","schema_version","created_at"],"type":"object"},"EvidenceBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceBundleImport":{"additionalProperties":false,"properties":{"bundle_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"imported_count":{"type":"integer"},"result":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","bundle_hash","result","imported_count","schema_version","created_at"],"type":"object"},"EvidenceBundleImportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceBundleImport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceCitation":{"additionalProperties":false,"properties":{"canonical_hash":{"pattern":"^sha256:","type":"string"},"evidence_id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"}},"required":["evidence_id","type","title","canonical_hash"],"type":"object"},"EvidenceGraphEdge":{"additionalProperties":false,"properties":{"from":{"type":"string"},"relationship":{"type":"string"},"to":{"type":"string"}},"required":["from","to","relationship"],"type":"object"},"EvidenceGraphNode":{"additionalProperties":false,"properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"}},"required":["id","type","label"],"type":"object"},"EvidenceGraphSnapshot":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"edges":{"items":{"$ref":"#/components/schemas/EvidenceGraphEdge"},"type":"array"},"graph_hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"nodes":{"items":{"$ref":"#/components/schemas/EvidenceGraphNode"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","nodes","edges","graph_hash","limitations","schema_version","created_at"],"type":"object"},"EvidenceGraphSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceGraphSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItem":{"additionalProperties":false,"properties":{"build_id":{"type":"string"},"canonical_hash":{"pattern":"^sha256:","type":"string"},"canonicalization":{"type":"string"},"chain_entry_id":{"type":"string"},"collector_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deployment_id":{"type":"string"},"evidence_version":{"type":"integer"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"metadata":{"additionalProperties":true,"type":"object"},"observed_at":{"format":"date-time","type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_media_type":{"type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"project_id":{"type":"string"},"related_evidence_refs":{"items":{"$ref":"#/components/schemas/EvidenceRef"},"type":"array"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"source_identity":{"additionalProperties":true,"type":"object"},"source_system":{"type":"string"},"subject_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"subtype":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"title":{"type":"string"},"trust_level":{"type":"string"},"type":{"type":"string"},"uploaded_by":{"type":"string"},"verification_status":{"type":"string"},"warnings":{"items":{"$ref":"#/components/schemas/EvidenceNotice"},"type":"array"}},"required":["id","tenant_id","type","title","source_system","observed_at","evidence_version","schema_version","payload_hash","canonical_hash","canonicalization","trust_level","verification_status","chain_entry_id","created_at"],"type":"object"},"EvidenceItemEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceItem"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceItemListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEvent":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"evidence_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"replacement_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"EvidenceLifecycleEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceLifecycleEventListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/EvidenceLifecycleEvent"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceNotice":{"additionalProperties":false,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"EvidenceRef":{"additionalProperties":false,"properties":{"id":{"type":"string"},"relationship":{"type":"string"},"type":{"type":"string"}},"required":["type","id"],"type":"object"},"EvidenceSearchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSearchResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceSearchResponse":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/EvidenceItem"},"type":"array"},"next_cursor":{"type":"string"}},"required":["items"],"type":"object"},"EvidenceSummary":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"citations":{"items":{"$ref":"#/components/schemas/EvidenceCitation"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","evidence_ids","summary","citations","assumptions","limitations","schema_version","created_at"],"type":"object"},"EvidenceSummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/EvidenceSummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"EvidenceUploadRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"Exception":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","reason","owner","expires_at","approved","created_at"],"type":"object"},"ExceptionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Exception"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExceptionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Exception"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ExchangeSSOCredentialRequest":{"additionalProperties":false,"properties":{"expires_at":{"description":"Optional session expiry, capped by the server.","format":"date-time","type":"string"},"id_token":{"description":"OIDC ID token verified locally against configured public JWKS trust material.","type":"string"},"provider_id":{"type":"string"},"saml_assertion":{"description":"SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_id","subject"],"type":"object"},"ExportEvidenceBundleRequest":{"additionalProperties":false,"properties":{"evidence_ids":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"}},"type":"object"},"HTMLReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"html":{"type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","report_type","product_id","html","hash","schema_version","created_at"],"type":"object"},"HTMLReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HTMLReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HealthStatus":{"additionalProperties":false,"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"HealthStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HealthStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"HumanUser":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"deactivated_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","email","display_name","status","schema_version","created_at"],"type":"object"},"HumanUserEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/HumanUser"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Incident":{"additionalProperties":false,"properties":{"closed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"opened_at":{"format":"date-time","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"severity":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","product_id","title","severity","status","opened_at","schema_version","created_at"],"type":"object"},"IncidentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Incident"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incident_id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"linked_evidence":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"result":{"type":"string"},"tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"template_version":{"type":"string"},"timeline":{"items":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"type":"array"}},"required":["report_type","template_version","incident_id","result","timeline","tasks","assumptions","limitations","generated_at"],"type":"object"},"IncidentReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentTimelineEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"summary":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","event_type","summary","occurred_at","schema_version","created_at"],"type":"object"},"IncidentTimelineEventEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookDelivery":{"additionalProperties":false,"properties":{"timeline_event":{"$ref":"#/components/schemas/IncidentTimelineEvent"},"webhook_event":{"$ref":"#/components/schemas/IncidentWebhookEvent"}},"required":["webhook_event","timeline_event"],"type":"object"},"IncidentWebhookDeliveryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookDelivery"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"IncidentWebhookEvent":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"event_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider":{"type":"string"},"receiver_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_hash":{"pattern":"^sha256:","type":"string"},"tenant_id":{"type":"string"},"timeline_event_id":{"type":"string"}},"required":["id","tenant_id","receiver_id","incident_id","provider","event_id","payload_hash","signature_hash","result","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiver":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","incident_id","name","provider","public_key","status","schema_version","created_at"],"type":"object"},"IncidentWebhookReceiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/IncidentWebhookReceiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"InstanceAdminSnapshot":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_count":{"type":"integer"}},"required":["report_type","tenant_count","resource_counts","limitations","generated_at"],"type":"object"},"InstanceAdminSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/InstanceAdminSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LegalHold":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"released_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","reason","owner","schema_version","created_at"],"type":"object"},"LegalHoldEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/LegalHold"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"LinkControlEvidenceRequest":{"additionalProperties":false,"properties":{"confidence":{"enum":["high","medium","low","unsupported"],"type":"string"},"evidence_type":{"type":"string"},"notes":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["evidence_type","subject_type","subject_id","confidence"],"type":"object"},"LinkEvidenceRequest":{"additionalProperties":false,"properties":{"target_id":{"type":"string"},"target_type":{"type":"string"}},"required":["target_type","target_id"],"type":"object"},"LinkSSOIdentityRequest":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"},"provider_id":{"type":"string"},"subject":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["user_id","provider_id","subject","email","verified"],"type":"object"},"ManualSecurityDocument":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"document_type":{"type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"sensitivity":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","document_type","title","sensitivity","evidence_id","payload_hash","schema_version","created_at"],"type":"object"},"ManualSecurityDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ManualSecurityDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollector":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"publisher":{"type":"string"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"signature_id":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","provider","version","publisher","manifest_hash","state","schema_version","created_at"],"type":"object"},"MarketplaceCollectorEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollector"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorHealthReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"collector":{"$ref":"#/components/schemas/MarketplaceCollector"},"collector_id":{"type":"string"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"provider":{"type":"string"},"report_type":{"type":"string"},"supply_chain_status":{"type":"string"},"version":{"type":"string"}},"required":["report_type","collector_id","name","provider","version","supply_chain_status","checks","collector","assumptions","limitations","generated_at"],"type":"object"},"MarketplaceCollectorHealthReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MarketplaceCollectorListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/MarketplaceCollector"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MerkleBatch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"entry_count":{"type":"integer"},"from_sequence":{"format":"int64","type":"integer"},"id":{"type":"string"},"leaf_hashes":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"root_hash":{"pattern":"^sha256:","type":"string"},"schema_version":{"type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"tenant_id":{"type":"string"},"to_sequence":{"format":"int64","type":"integer"}},"required":["id","tenant_id","from_sequence","to_sequence","entry_count","leaf_hashes","root_hash","schema_version","created_at"],"type":"object"},"MerkleBatchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MerkleBatch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MetricsSnapshot":{"additionalProperties":false,"properties":{"customer_portal_failed_access_count":{"type":"integer"},"customer_portal_revoked_access_count":{"type":"integer"},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["tenant_id","resource_counts","customer_portal_failed_access_count","customer_portal_revoked_access_count"],"type":"object"},"MetricsSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MetricsSnapshot"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"MissingEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing":{"items":{"type":"string"},"type":"array"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","release_id","result","missing","assumptions","limitations"],"type":"object"},"MissingEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/MissingEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ObjectRetentionPolicy":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"type":"string"},"name":{"type":"string"},"object_key":{"type":"string"},"object_prefix":{"type":"string"},"require_legal_hold":{"type":"boolean"},"retention_days":{"type":"integer"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_hash":{"pattern":"^sha256:","type":"string"},"verification_limitations":{"items":{"type":"string"},"type":"array"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","name","object_prefix","mode","retention_days","status","schema_version","created_at"],"type":"object"},"ObjectRetentionPolicyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIContract":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"operations":{"items":{"$ref":"#/components/schemas/OpenAPIOperationRecord"},"type":"array"},"path_count":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","hash","path_count","evidence_id","created_at"],"type":"object"},"OpenAPIContractEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/OpenAPIContract"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"OpenAPIDocument":{"additionalProperties":true,"properties":{"components":{"additionalProperties":true,"type":"object"},"info":{"additionalProperties":true,"type":"object"},"openapi":{"type":"string"},"paths":{"additionalProperties":true,"type":"object"}},"required":["openapi","info","paths"],"type":"object"},"OpenAPIOperationRecord":{"additionalProperties":false,"properties":{"deprecated":{"type":"boolean"},"method":{"type":"string"},"operation_id":{"type":"string"},"path":{"type":"string"},"request_body_required":{"type":"boolean"},"required_request_fields":{"items":{"type":"string"},"type":"array"},"response_statuses":{"items":{"type":"string"},"type":"array"}},"required":["path","method"],"type":"object"},"Organization":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","status","schema_version","created_at"],"type":"object"},"OrganizationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Organization"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PDFReportPackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"payload_size":{"type":"integer"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","report_type","title","payload_hash","payload_size","limitations","schema_version","created_at"],"type":"object"},"PDFReportPackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PDFReportPackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyCheck":{"additionalProperties":false,"properties":{"explanation":{"type":"string"},"missing":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"remediation":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"},"severity":{"type":"string"}},"required":["name","result","severity","explanation"],"type":"object"},"PolicyEvaluation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/PolicyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"policy_set":{"type":"string"},"release_id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","result","policy_set","checks","created_at"],"type":"object"},"PolicyEvaluationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PolicyEvaluation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PolicyRule":{"additionalProperties":false,"properties":{"evidence_type":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"severity":{"type":"string"}},"required":["name","severity","required"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"request_id":{"description":"Request identifier mirrored from the X-Request-ID response header.","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Product":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","slug","schema_version","created_at"],"type":"object"},"ProductEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProductListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Project":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"schema_version":{"type":"string"},"slug":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","product_id","name","slug","schema_version","created_at"],"type":"object"},"ProjectEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Project"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ProviderVerification":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_type","provider_id","subject","result","checks","limitations","schema_version","created_at"],"type":"object"},"ProviderVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ProviderVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLog":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"endpoint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","endpoint","public_key","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntry":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"entry_hash":{"pattern":"^sha256:","type":"string"},"external_id":{"type":"string"},"id":{"type":"string"},"inclusion_proof_hash":{"pattern":"^sha256:","type":"string"},"inclusion_root_hash":{"pattern":"^sha256:","type":"string"},"inclusion_verified_at":{"format":"date-time","type":"string"},"log_id":{"type":"string"},"merkle_batch_id":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"verification_checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"verification_limitations":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","log_id","checkpoint_id","merkle_batch_id","external_id","entry_hash","state","schema_version","created_at"],"type":"object"},"PublicTransparencyLogEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLogEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublicTransparencyLogEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PublicTransparencyLog"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"PublishPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"checkpoint_id":{"type":"string"},"external_id":{"type":"string"},"log_id":{"type":"string"}},"required":["log_id","checkpoint_id","external_id"],"type":"object"},"PullRequest":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"schema_version":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","repository_id","provider","provider_id","state","schema_version","created_at"],"type":"object"},"PullRequestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/PullRequest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntry":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"evidence_type":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"question_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","answer","schema_version","created_at"],"type":"object"},"QuestionnaireAnswerLibraryEntryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireAnswerLibraryEntryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntry"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireDraft":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","limitations","schema_version","created_at"],"type":"object"},"QuestionnaireDraftEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireDraft"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnairePackage":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"responses":{"items":{"$ref":"#/components/schemas/QuestionnaireResponse"},"type":"array"},"schema_version":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","responses","manifest_hash","schema_version","created_at"],"type":"object"},"QuestionnairePackageEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnairePackage"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"QuestionnaireQuestion":{"additionalProperties":false,"properties":{"allowed_fields":{"items":{"type":"string"},"type":"array"},"control_id":{"type":"string"},"evidence_type":{"type":"string"},"id":{"type":"string"},"prompt":{"type":"string"}},"required":["id","prompt"],"type":"object"},"QuestionnaireResponse":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"question_id":{"type":"string"}},"required":["question_id","answer"],"type":"object"},"QuestionnaireTemplate":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"questions":{"items":{"$ref":"#/components/schemas/QuestionnaireQuestion"},"type":"array"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","name","version","questions","schema_version","created_at"],"type":"object"},"QuestionnaireTemplateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QuestionnaireTemplate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"type":"object"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"gaps":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"non_claims":{"items":{"type":"string"},"type":"array"},"policy_set":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"result":{"type":"string"},"sections":{"items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"questions":{"items":{"additionalProperties":false,"properties":{"answer":{"type":"string"},"checks":{"items":{"type":"string"},"type":"array"},"evidence":{"items":{"type":"string"},"type":"array"},"failed_policies":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"known_limitations":{"items":{"type":"string"},"type":"array"},"missing_evidence":{"items":{"type":"string"},"type":"array"},"question":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"status":{"type":"string"},"summary":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"summary":{"additionalProperties":false,"properties":{"headline":{"type":"string"},"human_summary":{"type":"string"},"policy_set":{"type":"string"},"result":{"type":"string"}},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","result","assumptions","limitations","generated_at"],"type":"object"},"ReadinessReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReadinessStatus":{"additionalProperties":false,"properties":{"checks":{"items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"status":{"type":"string"}},"required":["name","status"],"type":"object"},"type":"array"},"status":{"type":"string"}},"required":["status","checks"],"type":"object"},"ReadinessStatusEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReadinessStatus"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RecordCollectorReleaseRequest":{"additionalProperties":false,"properties":{"artifact_digest":{"type":"string"},"pinned":{"type":"boolean"},"sbom_id":{"type":"string"},"scan_id":{"type":"string"},"signature_id":{"type":"string"},"version":{"type":"string"}},"required":["version","artifact_digest"],"type":"object"},"RecordDeploymentRequest":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"environment_id":{"type":"string"},"finished_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"rollback_of":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"required":["environment_id","release_id","status","started_at"],"type":"object"},"RecordEvidenceLifecycleEventRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"details":{"additionalProperties":true,"type":"object"},"reason":{"type":"string"},"replacement_id":{"type":"string"}},"required":["action","reason"],"type":"object"},"RecordIncidentTimelineRequest":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"RecordPullRequestRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"provider":{"type":"string"},"provider_id":{"type":"string"},"repository_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["repository_id","provider","provider_id","title","state"],"type":"object"},"RecordSourceCommitRequest":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message is hashed before storage.","type":"string"},"repository_id":{"type":"string"},"sha":{"type":"string"}},"required":["repository_id","sha","committed_at"],"type":"object"},"RecordVulnerabilityWorkflowRequest":{"additionalProperties":false,"properties":{"action":{"type":"string"},"reason":{"type":"string"}},"required":["action","reason"],"type":"object"},"RedactionProfile":{"additionalProperties":false,"properties":{"allowed_types":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"excluded_fields":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","schema_version","created_at"],"type":"object"},"RedactionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RedactionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RegisterArtifactRequest":{"additionalProperties":false,"properties":{"digest":{"pattern":"^sha256:","type":"string"},"media_type":{"type":"string"},"name":{"type":"string"},"release_id":{"type":"string"},"size":{"minimum":0,"type":"integer"},"subject_ref":{"type":"string"}},"required":["name","digest"],"type":"object"},"RegisterContainerImageRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"digest":{"type":"string"},"platform":{"type":"string"},"repository":{"type":"string"},"tag":{"type":"string"}},"required":["repository","digest"],"type":"object"},"Release":{"additionalProperties":false,"properties":{"approved_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"frozen_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"product_id":{"type":"string"},"project_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["draft","frozen","approved"],"type":"string"},"tenant_id":{"type":"string"},"version":{"type":"string"}},"required":["id","tenant_id","product_id","version","status","schema_version","created_at"],"type":"object"},"ReleaseBundle":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"manifest":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"manifest_hash":{"pattern":"^sha256:","type":"string"},"published_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"signature_refs":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","state","manifest","manifest_hash","signature_refs","created_at"],"type":"object"},"ReleaseBundleEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundle"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleManifest":{"additionalProperties":false,"properties":{"bundle_id":{"type":"string"},"chain_checkpoint":{"additionalProperties":true,"type":"object"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"generator":{"additionalProperties":true,"type":"object"},"manifest_version":{"type":"string"},"release":{"additionalProperties":true,"type":"object"},"tenant_id":{"type":"string"}},"required":["manifest_version","bundle_id","tenant_id","release","evidence_ids","chain_checkpoint","generated_at","generator"],"type":"object"},"ReleaseBundleManifestEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleManifest"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseBundleVerification":{"additionalProperties":false,"properties":{"checked_at":{"format":"date-time","type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["result"],"type":"object"},"ReleaseBundleVerificationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseBundleVerification"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidate":{"additionalProperties":false,"properties":{"artifact_ids":{"items":{"type":"string"},"type":"array"},"build_ids":{"items":{"type":"string"},"type":"array"},"bundle_ids":{"items":{"type":"string"},"type":"array"},"contract_ids":{"items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"name":{"type":"string"},"promoted_at":{"format":"date-time","type":"string"},"rejected_at":{"format":"date-time","type":"string"},"release_id":{"type":"string"},"sbom_ids":{"items":{"type":"string"},"type":"array"},"scan_ids":{"items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"snapshot_hash":{"pattern":"^sha256:","type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"vex_ids":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","release_id","name","state","snapshot_hash","schema_version","created_at"],"type":"object"},"ReleaseCandidateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseCandidate"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseCandidate"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseCandidateTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"ReleaseEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Release"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlow":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"enum":["needs_evidence","ready_for_review"],"type":"string"},"steps":{"items":{"$ref":"#/components/schemas/ReleaseEvidenceFlowStep"},"type":"array"}},"required":["release_id","product_id","status","counts","steps","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseEvidenceFlowEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseEvidenceFlow"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"ReleaseEvidenceFlowStep":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"idempotency_required":{"type":"boolean"},"method":{"type":"string"},"next_reference":{"type":"string"},"path":{"type":"string"},"required":{"type":"boolean"},"required_scopes":{"items":{"type":"string"},"type":"array"},"status":{"enum":["present","missing","optional"],"type":"string"},"title":{"type":"string"}},"required":["id","title","status","required","method","path","required_scopes","idempotency_required","description"],"type":"object"},"ReleaseSecurityApprovalSummary":{"additionalProperties":false,"properties":{"approved":{"type":"integer"},"total":{"type":"integer"}},"required":["total","approved"],"type":"object"},"ReleaseSecurityExceptionSummary":{"additionalProperties":false,"properties":{"approved_unexpired":{"type":"integer"},"expired":{"type":"integer"},"total":{"type":"integer"},"unapproved":{"type":"integer"}},"required":["total","approved_unexpired","unapproved","expired"],"type":"object"},"ReleaseSecurityMissingDecision":{"additionalProperties":false,"properties":{"component":{"type":"string"},"finding_id":{"type":"string"},"scan_id":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["finding_id","scan_id","vulnerability","severity","state"],"type":"object"},"ReleaseSecurityProductSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["id","name","slug"],"type":"object"},"ReleaseSecurityReleaseSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"state":{"type":"string"},"version":{"type":"string"}},"required":["id","version","state"],"type":"object"},"ReleaseSecuritySummary":{"additionalProperties":false,"properties":{"approval_summary":{"$ref":"#/components/schemas/ReleaseSecurityApprovalSummary"},"artifact_count":{"type":"integer"},"assumptions":{"items":{"type":"string"},"type":"array"},"counts":{"additionalProperties":{"type":"integer"},"type":"object"},"decisions_by_status":{"additionalProperties":{"type":"integer"},"type":"object"},"exception_summary":{"$ref":"#/components/schemas/ReleaseSecurityExceptionSummary"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"missing_required_decisions":{"items":{"$ref":"#/components/schemas/ReleaseSecurityMissingDecision"},"type":"array"},"open_findings_by_severity":{"additionalProperties":{"type":"integer"},"type":"object"},"package_status":{"enum":["generated","not_generated"],"type":"string"},"product":{"$ref":"#/components/schemas/ReleaseSecurityProductSummary"},"readiness_status":{"enum":["passed","failed"],"type":"string"},"release":{"$ref":"#/components/schemas/ReleaseSecurityReleaseSummary"},"sbom_status":{"enum":["present","missing"],"type":"string"},"schema_version":{"type":"string"},"vulnerability_scan_status":{"enum":["present","missing"],"type":"string"}},"required":["product","release","artifact_count","sbom_status","vulnerability_scan_status","open_findings_by_severity","decisions_by_status","approval_summary","exception_summary","readiness_status","package_status","counts","assumptions","limitations","schema_version","generated_at"],"type":"object"},"ReleaseSecuritySummaryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ReleaseSecuritySummary"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RemediationTask":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"due_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"id":{"type":"string"},"incident_id":{"type":"string"},"owner":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","title","owner","status","schema_version","created_at"],"type":"object"},"RemediationTaskEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RemediationTask"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RenderReportTemplateRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type","subject_id"],"type":"object"},"RenderedCustomReport":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"hash":{"pattern":"^sha256:","type":"string"},"id":{"type":"string"},"output":{"additionalProperties":true,"type":"object"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"template_id":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","template_id","subject_type","subject_id","output","hash","schema_version","created_at"],"type":"object"},"RenderedCustomReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RenderedCustomReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionOverride":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"reason":{"type":"string"},"retention_until":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","retention_until","reason","owner","schema_version","created_at"],"type":"object"},"RetentionOverrideEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionOverride"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RetentionReport":{"additionalProperties":false,"properties":{"generated_at":{"format":"date-time","type":"string"},"legal_holds":{"items":{"$ref":"#/components/schemas/LegalHold"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"report_type":{"type":"string"},"retention_overrides":{"items":{"$ref":"#/components/schemas/RetentionOverride"},"type":"array"},"scope_id":{"type":"string"},"scope_type":{"type":"string"}},"required":["report_type","legal_holds","retention_overrides","limitations","generated_at"],"type":"object"},"RetentionReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RetentionReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBinding":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"resource_id":{"type":"string"},"resource_type":{"type":"string"},"role":{"type":"string"},"schema_version":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","subject_type","subject_id","role","schema_version","created_at"],"type":"object"},"RoleBindingEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/RoleBinding"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"RoleBindingListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/RoleBinding"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOM":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component_count":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"spec_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","component_count","created_at"],"type":"object"},"SBOMComponent":{"additionalProperties":false,"properties":{"hashes":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"purl":{"type":"string"},"version":{"type":"string"}},"required":["name"],"type":"object"},"SBOMComponentRecord":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"component":{"$ref":"#/components/schemas/SBOMComponent"},"release_id":{"type":"string"},"sbom_id":{"type":"string"}},"required":["sbom_id","component"],"type":"object"},"SBOMComponentRecordListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SBOMComponentRecord"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMDiff":{"additionalProperties":false,"properties":{"added_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"base_sbom_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"dependency_changes":{"items":{"$ref":"#/components/schemas/DependencyChange"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"removed_components":{"items":{"$ref":"#/components/schemas/SBOMComponent"},"type":"array"},"schema_version":{"type":"string"},"target_sbom_id":{"type":"string"},"tenant_id":{"type":"string"},"unchanged_count":{"type":"integer"}},"required":["id","tenant_id","base_sbom_id","target_sbom_id","unchanged_count","schema_version","created_at"],"type":"object"},"SBOMDiffEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOMDiff"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SBOMEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SBOM"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOCredentialExchangeResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOCredentialExchangeResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; also set as an HttpOnly cookie for browser clients.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"},"verification":{"$ref":"#/components/schemas/ProviderVerification"}},"required":["verification","session","secret"],"type":"object"},"SSOProvider":{"additionalProperties":false,"properties":{"client_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"groups_claim":{"type":"string"},"id":{"type":"string"},"issuer":{"type":"string"},"jwks":{"description":"Configured public JWKS material, when supplied.","type":"object"},"name":{"type":"string"},"role_mapping":{"additionalProperties":{"type":"string"},"type":"object"},"saml_signing_certificates":{"description":"Configured SAML assertion signing certificates, when supplied.","items":{"type":"string"},"type":"array"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"trust_material_updated_at":{"format":"date-time","type":"string"},"type":{"enum":["oidc","saml"],"type":"string"}},"required":["id","tenant_id","name","type","issuer","client_id","status","schema_version","created_at"],"type":"object"},"SSOProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSession":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"groups":{"description":"Provider group claim values captured for session-scoped role mapping.","items":{"type":"string"},"type":"array"},"id":{"type":"string"},"prefix":{"description":"Non-secret session token prefix for audit displays.","type":"string"},"provider_id":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"}},"required":["id","tenant_id","user_id","provider_id","prefix","expires_at","schema_version","created_at"],"type":"object"},"SSOSessionCreateEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSessionCreateResponse"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SSOSessionCreateResponse":{"additionalProperties":false,"properties":{"secret":{"description":"One-time SSO session bearer secret; not returned by list/read operations.","type":"string"},"session":{"$ref":"#/components/schemas/SSOSession"}},"required":["session","secret"],"type":"object"},"SSOSessionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SSOSession"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SaaSEditionProfile":{"additionalProperties":false,"properties":{"admin_tenant_id":{"type":"string"},"config_hash":{"pattern":"^sha256:","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"isolation_model":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"region":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","name","region","admin_tenant_id","isolation_model","status","config_hash","limitations","schema_version","created_at"],"type":"object"},"SaaSEditionProfileEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SaaSEditionProfile"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityControl":{"additionalProperties":false,"properties":{"applicability":{"items":{"type":"string"},"type":"array"},"code":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_requirements":{"items":{"$ref":"#/components/schemas/ControlEvidenceRequirement"},"type":"array"},"framework_id":{"type":"string"},"id":{"type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"objective":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"},"title":{"type":"string"}},"required":["id","tenant_id","framework_id","code","title","objective","schema_version","created_at"],"type":"object"},"SecurityControlEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityControl"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityReviewPackageReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"package_id":{"type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","package_id","product_id","evidence_ids","assumptions","limitations","generated_at"],"type":"object"},"SecurityReviewPackageReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityReviewPackageReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityScan":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"finding_count":{"type":"integer"},"format":{"type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"payload_ref":{"type":"string"},"product_id":{"type":"string"},"quarantined":{"type":"boolean"},"redacted":{"type":"boolean"},"release_id":{"type":"string"},"scanner":{"type":"string"},"schema_version":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","category","format","scanner","target_ref","evidence_id","payload_hash","finding_count","redacted","quarantined","schema_version","created_at"],"type":"object"},"SecurityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SecurityUpdateEvidenceReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"fixed_decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"incidents":{"items":{"$ref":"#/components/schemas/Incident"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"remediation_tasks":{"items":{"$ref":"#/components/schemas/RemediationTask"},"type":"array"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","summary","assumptions","limitations","generated_at"],"type":"object"},"SecurityUpdateEvidenceReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SignedIncidentWebhookPayload":{"additionalProperties":false,"properties":{"event_type":{"type":"string"},"evidence_id":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"summary":{"type":"string"}},"required":["event_type","summary"],"type":"object"},"SigningCustodyReviewReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"object_retention_policies":{"items":{"$ref":"#/components/schemas/ObjectRetentionPolicy"},"type":"array"},"report_type":{"type":"string"},"signing_providers":{"items":{"$ref":"#/components/schemas/SigningProvider"},"type":"array"},"tenant_id":{"type":"string"}},"required":["report_type","tenant_id","checks","assumptions","limitations","generated_at"],"type":"object"},"SigningCustodyReviewReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningCustodyReviewReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKey":{"additionalProperties":false,"properties":{"algorithm":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"kid":{"type":"string"},"public_key":{"type":"string"},"revoked_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","kid","algorithm","status","public_key","created_at"],"type":"object"},"SigningKeyEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningKey"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SigningKey"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningKeyTransitionRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"}},"type":"object"},"SigningOperation":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"payload_hash":{"pattern":"^sha256:","type":"string"},"provider_id":{"type":"string"},"result":{"type":"string"},"schema_version":{"type":"string"},"signature_ref":{"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider_id","subject_type","subject_id","payload_hash","result","checks","schema_version","created_at"],"type":"object"},"SigningOperationEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningOperation"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SigningProvider":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"encrypted":{"type":"boolean"},"id":{"type":"string"},"key_ref":{"type":"string"},"name":{"type":"string"},"schema_version":{"type":"string"},"status":{"type":"string"},"tenant_id":{"type":"string"},"type":{"type":"string"}},"required":["id","tenant_id","name","type","status","key_ref","encrypted","schema_version","created_at"],"type":"object"},"SigningProviderEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SigningProvider"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceBranch":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"head_commit_id":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","name","protected","schema_version","created_at"],"type":"object"},"SourceBranchEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceBranch"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceCommit":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"created_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"message_hash":{"type":"string"},"repository_id":{"type":"string"},"schema_version":{"type":"string"},"sha":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","repository_id","sha","schema_version","created_at"],"type":"object"},"SourceCommitEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceCommit"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepository":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"},"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","provider","full_name","schema_version","created_at"],"type":"object"},"SourceRepositoryEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceRepository"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceRepositoryListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/SourceRepository"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotBranchInput":{"additionalProperties":false,"properties":{"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"}},"required":["name"],"type":"object"},"SourceSnapshotCommitInput":{"additionalProperties":false,"properties":{"author":{"type":"string"},"committed_at":{"format":"date-time","type":"string"},"message":{"description":"Commit message supplied by the collector; Evydence stores a message hash.","type":"string"},"sha":{"type":"string"}},"required":["sha","committed_at"],"type":"object"},"SourceSnapshotEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SourceSnapshotResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"SourceSnapshotPullRequestInput":{"additionalProperties":false,"properties":{"provider_id":{"type":"string"},"review_decision":{"type":"string"},"source_branch":{"type":"string"},"state":{"type":"string"},"target_branch":{"type":"string"},"title":{"type":"string"}},"required":["provider_id","state"],"type":"object"},"SourceSnapshotRepositoryInput":{"additionalProperties":false,"properties":{"clone_url":{"type":"string"},"default_branch":{"type":"string"},"full_name":{"type":"string"}},"required":["full_name"],"type":"object"},"SourceSnapshotRequest":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceSnapshotBranchInput"},"commit":{"$ref":"#/components/schemas/SourceSnapshotCommitInput"},"project_id":{"type":"string"},"pull_request":{"$ref":"#/components/schemas/SourceSnapshotPullRequestInput"},"repository":{"$ref":"#/components/schemas/SourceSnapshotRepositoryInput"}},"required":["repository"],"type":"object"},"SourceSnapshotResult":{"additionalProperties":false,"properties":{"branch":{"$ref":"#/components/schemas/SourceBranch"},"commit":{"$ref":"#/components/schemas/SourceCommit"},"pull_request":{"$ref":"#/components/schemas/PullRequest"},"repository":{"$ref":"#/components/schemas/SourceRepository"}},"required":["repository"],"type":"object"},"SubjectRef":{"additionalProperties":false,"properties":{"digest":{"type":"string"},"id":{"type":"string"},"type":{"type":"string"}},"required":["type"],"type":"object"},"SupersedeEvidenceRequest":{"additionalProperties":false,"properties":{"reason":{"type":"string"},"replacement_evidence_id":{"type":"string"}},"required":["replacement_evidence_id","reason"],"type":"object"},"TransparencyCheckpoint":{"additionalProperties":false,"properties":{"batch_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"external_id":{"type":"string"},"external_url":{"type":"string"},"id":{"type":"string"},"provider":{"type":"string"},"schema_version":{"type":"string"},"state":{"type":"string"},"tenant_id":{"type":"string"},"timestamp_hash":{"pattern":"^sha256:","type":"string"}},"required":["id","tenant_id","batch_id","provider","timestamp_hash","state","schema_version","created_at"],"type":"object"},"TransparencyCheckpointEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TransparencyCheckpoint"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"UpdateSSOProviderTrustMaterialRequest":{"additionalProperties":false,"properties":{"jwks":{"description":"OIDC public JWKS material. Private keys and provider secrets must not be supplied.","type":"object"},"saml_signing_certificates":{"description":"PEM-encoded SAML assertion signing certificates. Private keys and provider secrets must not be supplied.","items":{"type":"string"},"type":"array"}},"type":"object"},"UploadManualSecurityDocumentRequest":{"additionalProperties":false,"properties":{"document_type":{"enum":["threat_model","security_review","pentest_report"],"type":"string"},"media_type":{"type":"string"},"payload":{"description":"Document payload or text supplied for object storage; responses expose only payload hash/ref metadata.","type":"string"},"product_id":{"type":"string"},"release_id":{"type":"string"},"sensitivity":{"enum":["internal","restricted","confidential"],"type":"string"},"title":{"type":"string"}},"required":["document_type","title","sensitivity","payload"],"type":"object"},"UploadOpenAPIContractRequest":{"additionalProperties":false,"properties":{"product_id":{"type":"string"},"release_id":{"type":"string"},"spec":{"additionalProperties":true,"type":"object"},"version":{"type":"string"}},"required":["product_id","release_id","version","spec"],"type":"object"},"UploadSPDXSBOMRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"release_id":{"type":"string"}},"required":["release_id","payload"],"type":"object"},"UploadSecurityScanRequest":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"category":{"enum":["sast","dast","secret","license","api_security"],"type":"string"},"format":{"type":"string"},"payload":{"additionalProperties":true,"type":"object"},"product_id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["category","format","scanner","target_ref","payload"],"type":"object"},"UploadVulnerabilityScanRequest":{"additionalProperties":false,"properties":{"findings":{"items":{"additionalProperties":false,"properties":{"component":{"type":"string"},"severity":{"type":"string"},"state":{"type":"string"},"vulnerability":{"type":"string"}},"required":["vulnerability","severity"],"type":"object"},"type":"array"},"release_id":{"type":"string"},"scanner":{"type":"string"},"target_ref":{"type":"string"}},"required":["scanner","target_ref","release_id","findings"],"type":"object"},"UpsertSourceBranchRequest":{"additionalProperties":false,"properties":{"head_commit_id":{"type":"string"},"name":{"type":"string"},"protected":{"type":"boolean"},"protection_hash":{"type":"string"},"repository_id":{"type":"string"}},"required":["repository_id","name"],"type":"object"},"UserIdentityLink":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"provider_id":{"type":"string"},"schema_version":{"type":"string"},"subject":{"type":"string"},"tenant_id":{"type":"string"},"user_id":{"type":"string"},"verified":{"type":"boolean"}},"required":["id","tenant_id","user_id","provider_id","subject","email","verified","schema_version","created_at"],"type":"object"},"UserIdentityLinkEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/UserIdentityLink"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXDocument":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"author":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"format":{"type":"string"},"id":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","evidence_id","release_id","format","statement_count","schema_version","created_at"],"type":"object"},"VEXDocumentEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXDocument"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportIssue":{"additionalProperties":false,"properties":{"code":{"type":"string"},"detail":{"type":"string"},"statement_index":{"type":"integer"}},"required":["code","detail"],"type":"object"},"VEXImportPreview":{"additionalProperties":false,"properties":{"advisory":{"type":"boolean"},"artifact_id":{"type":"string"},"assumptions":{"items":{"type":"string"},"type":"array"},"decisions_would_create":{"type":"integer"},"decisions_would_supersede":{"type":"integer"},"format":{"enum":["openvex","cyclonedx"],"type":"string"},"generated_at":{"format":"date-time","type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"limitations":{"items":{"type":"string"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status_summary":{"additionalProperties":{"type":"integer"},"type":"object"},"tenant_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["tenant_id","release_id","format","parser_version","advisory","statement_count","status_summary","decisions_would_create","decisions_would_supersede","assumptions","limitations","schema_version","generated_at"],"type":"object"},"VEXImportPreviewEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportPreview"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VEXImportReport":{"additionalProperties":false,"properties":{"artifact_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"decisions_created":{"type":"integer"},"decisions_superseded":{"type":"integer"},"evidence_id":{"type":"string"},"failure_code":{"type":"string"},"failure_detail":{"type":"string"},"id":{"type":"string"},"invalid_statements":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"mapping_failures":{"items":{"$ref":"#/components/schemas/VEXImportIssue"},"type":"array"},"parser_version":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"statement_count":{"type":"integer"},"status":{"enum":["accepted","parsed","failed"],"type":"string"},"tenant_id":{"type":"string"},"unsupported_fields":{"items":{"type":"string"},"type":"array"},"updated_at":{"format":"date-time","type":"string"},"vex_document_id":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"required":["id","tenant_id","vex_document_id","evidence_id","parser_version","status","statement_count","decisions_created","decisions_superseded","schema_version","created_at","updated_at"],"type":"object"},"VEXImportReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VEXImportReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerificationResult":{"additionalProperties":false,"properties":{"checks":{"items":{"$ref":"#/components/schemas/VerifyCheck"},"type":"array"},"id":{"type":"string"},"result":{"enum":["passed","failed"],"type":"string"},"subject_id":{"type":"string"},"subject_type":{"type":"string"},"tenant_id":{"type":"string"},"verified_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","subject_type","subject_id","result","checks","verified_at"],"type":"object"},"VerificationResultEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VerificationResult"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VerifyCheck":{"additionalProperties":false,"properties":{"detail":{"type":"string"},"name":{"type":"string"},"result":{"enum":["passed","failed","warning","skipped"],"type":"string"}},"required":["name","result"],"type":"object"},"VerifyCosignSignatureRequest":{"additionalProperties":false,"properties":{"certificate_identity":{"type":"string"},"certificate_issuer":{"type":"string"},"rekor_log_index":{"type":"string"},"rekor_uuid":{"type":"string"}},"type":"object"},"VerifyProviderIdentityRequest":{"additionalProperties":false,"properties":{"access_token":{"description":"Optional OIDC access token used only for live UserInfo validation. It is not persisted and must not be supplied for SAML providers.","type":"string"},"id_token":{"description":"Optional OIDC ID token verified locally against the provider's configured static JWKS.","type":"string"},"provider_id":{"type":"string"},"provider_type":{"enum":["oidc","saml"],"type":"string"},"saml_assertion":{"description":"Optional SAML assertion verified locally against configured SAML signing certificates.","type":"string"},"subject":{"type":"string"}},"required":["provider_type","provider_id","subject"],"type":"object"},"VerifyPublicTransparencyLogEntryRequest":{"additionalProperties":false,"properties":{"inclusion_proof":{"items":{"pattern":"^sha256:","type":"string"},"type":"array"},"leaf_hash":{"pattern":"^sha256:","type":"string"},"leaf_index":{"minimum":0,"type":"integer"},"root_hash":{"pattern":"^sha256:","type":"string"},"tree_size":{"minimum":1,"type":"integer"}},"required":["root_hash","leaf_index","tree_size","inclusion_proof"],"type":"object"},"VerifySubjectRequest":{"additionalProperties":false,"properties":{"subject_id":{"type":"string"},"subject_type":{"type":"string"}},"required":["subject_type"],"type":"object"},"VersionInfo":{"additionalProperties":false,"properties":{"version":{"type":"string"}},"required":["version"],"type":"object"},"VersionInfoEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VersionInfo"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecision":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"approved_by":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"customer_visible":{"type":"boolean"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"internal_notes":{"description":"Tenant-internal notes; do not include in customer-safe exports.","type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"review_due_at":{"format":"date-time","type":"string"},"reviewed_at":{"format":"date-time","type":"string"},"sbom_component_name":{"type":"string"},"sbom_component_purl":{"type":"string"},"sbom_id":{"description":"Same-release SBOM that contained the matched component, when available.","type":"string"},"scan_id":{"type":"string"},"schema_version":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"supporting_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"tenant_id":{"type":"string"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","tenant_id","finding_id","scan_id","vulnerability","status","justification","source","schema_version","created_at"],"type":"object"},"VulnerabilityDecisionCustomerSummary":{"additionalProperties":false,"properties":{"action_statement":{"type":"string"},"component":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"evidence_id":{"type":"string"},"evidence_ids":{"items":{"type":"string"},"type":"array"},"finding_id":{"type":"string"},"id":{"type":"string"},"impact_statement":{"type":"string"},"justification":{"type":"string"},"release_id":{"type":"string"},"review_due_at":{"format":"date-time","type":"string"},"reviewed_at":{"format":"date-time","type":"string"},"sbom_component_name":{"type":"string"},"sbom_component_purl":{"type":"string"},"sbom_id":{"description":"Same-release SBOM that contained the matched component, when available.","type":"string"},"scan_id":{"type":"string"},"source":{"type":"string"},"status":{"type":"string"},"supporting_refs":{"items":{"$ref":"#/components/schemas/SubjectRef"},"type":"array"},"vex_document_id":{"type":"string"},"vulnerability":{"type":"string"}},"required":["id","finding_id","scan_id","release_id","vulnerability","status","impact_statement","source","created_at"],"type":"object"},"VulnerabilityDecisionEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecision"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionListEnvelope":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/VulnerabilityDecision"},"type":"array"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityDecisionSummaryReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"decisions":{"items":{"$ref":"#/components/schemas/VulnerabilityDecisionCustomerSummary"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"product_id":{"type":"string"},"release_id":{"type":"string"},"report_type":{"type":"string"},"template_version":{"type":"string"}},"required":["report_type","template_version","product_id","release_id","decisions","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityDecisionSummaryReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityPostureReport":{"additionalProperties":false,"properties":{"assumptions":{"items":{"type":"string"},"type":"array"},"generated_at":{"format":"date-time","type":"string"},"limitations":{"items":{"type":"string"},"type":"array"},"open_critical":{"type":"integer"},"release_id":{"type":"string"},"report_type":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"template_version":{"type":"string"}},"required":["report_type","template_version","summary","open_critical","assumptions","limitations","generated_at"],"type":"object"},"VulnerabilityPostureReportEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityPostureReport"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityScan":{"additionalProperties":false,"properties":{"created_at":{"format":"date-time","type":"string"},"findings":{"items":{"type":"object"},"type":"array"},"id":{"type":"string"},"release_id":{"type":"string"},"scanner":{"type":"string"},"summary":{"additionalProperties":{"type":"integer"},"type":"object"},"target_ref":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","release_id","scanner","target_ref","summary","findings","created_at"],"type":"object"},"VulnerabilityScanEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityScan"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"VulnerabilityWorkflowRecord":{"additionalProperties":false,"properties":{"action":{"type":"string"},"actor_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"finding_id":{"type":"string"},"id":{"type":"string"},"reason":{"type":"string"},"release_id":{"type":"string"},"schema_version":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","finding_id","action","reason","actor_id","schema_version","created_at"],"type":"object"},"VulnerabilityWorkflowRecordEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecord"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"},"Waiver":{"additionalProperties":false,"properties":{"approved":{"type":"boolean"},"approved_at":{"format":"date-time","type":"string"},"approved_by":{"type":"string"},"control_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"owner":{"type":"string"},"policy_id":{"type":"string"},"reason":{"type":"string"},"risk":{"type":"string"},"schema_version":{"type":"string"},"scope_id":{"type":"string"},"scope_type":{"type":"string"},"superseded_by":{"type":"string"},"supersedes":{"type":"string"},"tenant_id":{"type":"string"}},"required":["id","tenant_id","scope_type","scope_id","owner","risk","reason","expires_at","approved","schema_version","created_at"],"type":"object"},"WaiverEnvelope":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Waiver"},"meta":{"additionalProperties":false,"properties":{"api_version":{"type":"string"}},"required":["api_version"],"type":"object"}},"required":["data","meta"],"type":"object"}},"securitySchemes":{"BearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Self-hosted API evidence and compliance-readiness ledger.","title":"Evydence API","version":"dev"},"openapi":"3.1.0","paths":{"/v1/admin/instance":{"get":{"description":"Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.","operationId":"instanceAdminSnapshot","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceAdminSnapshotEnvelope"}}},"description":"Instance admin snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Instance admin snapshot","tags":["evydence"],"x-scopes":["instance:admin"]}},"/v1/api-keys":{"get":{"description":"Lists tenant-scoped API key metadata without key hashes or one-time secrets.","operationId":"listAPIKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyListEnvelope"}}},"description":"API key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List API keys","tags":["evydence"],"x-scopes":["admin"]},"post":{"description":"Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.","operationId":"createAPIKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}},"description":"API key creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyCreateEnvelope"}}},"description":"Created API key and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create API key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/api-security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadAPISecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload API security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/approvals":{"post":{"description":"Creates an immutable approval record for a release, waiver, package, or review subject.","operationId":"createApproval","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequest"}}},"description":"Approval creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRecordEnvelope"}}},"description":"Created approval envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create approval record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/artifact-signatures":{"post":{"description":"Records detached artifact signature evidence and optional raw signature payload metadata.","operationId":"createArtifactSignature","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArtifactSignatureRequest"}}},"description":"Artifact signature creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Created artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifact-signatures/{id}":{"get":{"description":"Returns tenant-scoped artifact signature metadata by id.","operationId":"getArtifactSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactSignatureEnvelope"}}},"description":"Artifact signature envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact signature","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/artifact-signatures/{id}/verify-cosign":{"post":{"description":"Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.","operationId":"verifyCosignSignature","parameters":[{"description":"Artifact signature id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCosignSignatureRequest"}}},"description":"Cosign verification metadata request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CosignVerificationEnvelope"}}},"description":"Cosign verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify cosign-style artifact signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/artifacts":{"post":{"description":"Registers an artifact digest for release evidence and later build/attestation matching.","operationId":"registerArtifact","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArtifactRequest"}}},"description":"Artifact registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Registered artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register artifact","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/artifacts/{id}":{"get":{"description":"Returns a tenant-scoped artifact by id.","operationId":"getArtifact","parameters":[{"description":"Artifact id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"}}},"description":"Artifact envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get artifact","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/audit-chain/verify":{"get":{"description":"Verifies the tenant audit chain continuity and returns deterministic verification checks.","operationId":"verifyAuditChain","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Audit chain verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify audit chain","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/audit-log":{"get":{"description":"Lists tenant-scoped append-only audit-chain entries in reverse chronological order.","operationId":"listAuditLog","parameters":[{"description":"Maximum returned entries; defaults to 100 and caps at 500.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Only include entries at or after this RFC3339 timestamp.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject id.","in":"query","name":"subject_id","required":false,"schema":{"type":"string"}},{"description":"Filter by audited subject type.","in":"query","name":"subject_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditChainEntryListEnvelope"}}},"description":"Audit-chain entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List tenant audit log","tags":["evydence"],"x-scopes":["admin"]}},"/v1/backup-manifests":{"post":{"description":"Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.","operationId":"generateBackupManifest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupManifestEnvelope"}}},"description":"Backup manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate backup manifest","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/backup-manifests/{id}/verify":{"get":{"description":"Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.","operationId":"verifyBackupManifest","parameters":[{"description":"Backup manifest id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Backup manifest verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify backup manifest","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/build-attestations/{id}/verify-signature":{"post":{"description":"Verifies a build attestation signature against configured tenant DSSE trust roots.","operationId":"verifyBuildAttestationSignature","parameters":[{"description":"Build attestation id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Build attestation verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify build attestation signature","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/builds":{"post":{"description":"Records an immutable CI build run. Collector identity is derived from the authenticated key when present.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBuildRequest"}}},"description":"Build run creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Created build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create build run","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/builds/{id}":{"get":{"description":"Returns a tenant-scoped build run by id.","operationId":"getBuild","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildRunEnvelope"}}},"description":"Build run envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get build run","tags":["evydence"],"x-scopes":["build:read"]}},"/v1/builds/{id}/attestations":{"post":{"description":"Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.","operationId":"uploadBuildAttestation","parameters":[{"description":"Build run id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSEEnvelope"}}},"description":"DSSE envelope.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildAttestationEnvelope"}}},"description":"Created build attestation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload build attestation","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["build:write"]}},"/v1/collectors":{"get":{"description":"Lists tenant-scoped collector metadata without API key hashes or one-time secrets.","operationId":"listCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorListEnvelope"}}},"description":"Collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List collectors","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.","operationId":"createCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectorRequest"}}},"description":"Collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorCreateEnvelope"}}},"description":"Created collector and one-time key secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create collector","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/collectors/github/source-snapshots":{"post":{"description":"Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitHubSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitHub source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitHub source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/gitlab/source-snapshots":{"post":{"description":"Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.","operationId":"uploadGitLabSourceSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotRequest"}}},"description":"GitLab source snapshot upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceSnapshotEnvelope"}}},"description":"Created source snapshot resources envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload GitLab source snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/collectors/{id}/health":{"get":{"description":"Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.","operationId":"collectorHealthReport","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorHealthReportEnvelope"}}},"description":"Collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/collectors/{id}/releases":{"post":{"description":"Records collector release supply-chain evidence for a tenant-scoped collector.","operationId":"recordCollectorRelease","parameters":[{"description":"Collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordCollectorReleaseRequest"}}},"description":"Collector release record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectorReleaseEnvelope"}}},"description":"Created collector release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record collector release evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/commercial-collectors":{"get":{"description":"Lists tenant-scoped commercial collector definitions.","operationId":"listCommercialCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionListEnvelope"}}},"description":"Commercial collector definition list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List commercial collector definitions","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped commercial collector metadata without installing external code.","operationId":"createCommercialCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommercialCollectorRequest"}}},"description":"Commercial collector definition request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommercialCollectorDefinitionEnvelope"}}},"description":"Created commercial collector definition envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create commercial collector definition","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/container-images":{"post":{"description":"Registers OCI/container image metadata and digest evidence linked to an optional artifact.","operationId":"registerContainerImage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterContainerImageRequest"}}},"description":"Container image registration request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerImageEnvelope"}}},"description":"Registered container image envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Register container image","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/control-evidence":{"get":{"description":"Lists tenant-scoped control evidence links with optional control, product, and release filters.","operationId":"listControlEvidence","parameters":[{"description":"Filter by security control id.","in":"query","name":"control_id","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceListEnvelope"}}},"description":"Control evidence list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control evidence","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs":{"get":{"description":"Lists built-in control framework template packs available for explicit tenant installation.","operationId":"listControlFrameworkTemplatePacks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkTemplatePackListEnvelope"}}},"description":"Control framework template pack list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control framework template packs","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/control-framework-template-packs/{slug}/install":{"post":{"description":"Installs a named control framework template pack into the tenant as ordinary framework/control records.","operationId":"installControlFrameworkTemplatePack","parameters":[{"description":"Control framework template pack slug.","in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Installed control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Install control framework template pack","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/control-frameworks":{"get":{"description":"Lists tenant-scoped control frameworks.","operationId":"listControlFrameworks","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkListEnvelope"}}},"description":"Control framework list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List control frameworks","tags":["evydence"],"x-scopes":["controls:read"]},"post":{"description":"Creates a tenant-scoped versioned control framework.","operationId":"createControlFramework","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateControlFrameworkRequest"}}},"description":"Control framework creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlFrameworkEnvelope"}}},"description":"Created control framework envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create control framework","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls":{"post":{"description":"Creates a framework-owned security control with deterministic evidence requirements.","operationId":"createSecurityControl","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecurityControlRequest"}}},"description":"Security control creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Created security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create security control","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:admin"]}},"/v1/controls/{id}":{"get":{"description":"Returns a tenant-scoped security control by id.","operationId":"getSecurityControl","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityControlEnvelope"}}},"description":"Security control envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get security control","tags":["evydence"],"x-scopes":["controls:read"]}},"/v1/controls/{id}/evidence":{"post":{"description":"Creates an append-only link between a security control and tenant-scoped evidence or related release resource.","operationId":"linkControlEvidence","parameters":[{"description":"Security control id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkControlEvidenceRequest"}}},"description":"Control evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlEvidenceEnvelope"}}},"description":"Created control evidence link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link control evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["controls:write"]}},"/v1/custom-policies":{"post":{"description":"Creates a deterministic custom policy definition for tenant-managed release checks.","operationId":"createCustomPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomPolicyRequest"}}},"description":"Custom policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEnvelope"}}},"description":"Created custom policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/custom-policies/{id}/evaluate":{"post":{"description":"Evaluates a tenant custom policy against a release and records the input hash.","operationId":"evaluateCustomPolicy","parameters":[{"description":"Custom policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Custom policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomPolicyEvaluationEnvelope"}}},"description":"Custom policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate custom policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:read"]}},"/v1/customer-packages":{"post":{"description":"Creates a scoped customer security package manifest using an explicit redaction profile.","operationId":"createCustomerPackage","requestBody":{"content":{"application/json":{"examples":{"release-evidence-package":{"summary":"Create a scoped release evidence package","value":{"expires_at":"2026-06-30T00:00:00Z","product_id":"prod_20260527120000","redaction_profile_id":"rp_20260527120000","release_id":"rel_20260527120000","title":"Payments API 1.0.0 release evidence package"}}},"schema":{"$ref":"#/components/schemas/CreateCustomerPackageRequest"}}},"description":"Customer package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Created customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer security package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-packages/{id}":{"get":{"description":"Returns a tenant-scoped customer security package manifest by id.","operationId":"getCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Customer security package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get customer security package","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-packages/{id}/download":{"get":{"description":"Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.","operationId":"downloadCustomerPackage","parameters":[{"description":"Customer package id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Download customer security package ZIP","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/customer-portal/access":{"get":{"description":"Lists tenant-scoped external reviewer access records without token hashes or token secrets.","operationId":"listCustomerPortalAccess","parameters":[{"description":"Optional customer package id filter.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessListEnvelope"}}},"description":"Customer portal access list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List customer portal access records","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a named, expiring external reviewer access record for a customer package and returns the portal token once.","operationId":"createCustomerPortalAccess","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerPortalAccessRequest"}}},"description":"Customer portal access creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessCreateEnvelope"}}},"description":"Created portal access and one-time token envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/access/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped external reviewer access record; revocation is append-only and the original token cannot be used afterwards.","operationId":"revokeCustomerPortalAccess","parameters":[{"description":"Customer portal access id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalAccessEnvelope"}}},"description":"Revoked customer portal access envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke customer portal access","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/customer-portal/package":{"post":{"description":"Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"accessCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSecurityPackageEnvelope"}}},"description":"Scoped customer package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Access customer portal package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/customer-portal/package/download":{"post":{"description":"Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.","operationId":"downloadCustomerPortalPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPortalPackageRequest"}}},"description":"Customer portal token request.","required":true},"responses":{"200":{"content":{"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"Customer security package ZIP archive."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Download customer portal package ZIP","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/deployments":{"get":{"description":"Lists tenant-scoped deployment events by optional release and environment filters.","operationId":"listDeployments","parameters":[{"description":"Deployment environment id.","in":"query","name":"environment_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventListEnvelope"}}},"description":"Deployment event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Records append-only deployment evidence for a release/environment/artifact set.","operationId":"recordDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordDeploymentRequest"}}},"description":"Deployment event creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Created deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record deployment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/deployments/{id}":{"get":{"description":"Returns a tenant-scoped deployment event by id.","operationId":"getDeployment","parameters":[{"description":"Deployment event id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEventEnvelope"}}},"description":"Deployment event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment","tags":["evydence"],"x-scopes":["deployment:read"]}},"/v1/dsse-trust-roots":{"post":{"description":"Creates a tenant-scoped DSSE trust root using public verification key material only.","operationId":"createDSSETrustRoot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDSSETrustRootRequest"}}},"description":"DSSE trust-root creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DSSETrustRootEnvelope"}}},"description":"Created DSSE trust root envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create DSSE trust root","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/environments":{"get":{"description":"Lists tenant-scoped deployment environments, optionally filtered by product.","operationId":"listDeploymentEnvironments","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentListEnvelope"}}},"description":"Deployment environment list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List deployment environments","tags":["evydence"],"x-scopes":["deployment:read"]},"post":{"description":"Creates a tenant-scoped deployment environment for release deployment evidence.","operationId":"createDeploymentEnvironment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeploymentEnvironmentRequest"}}},"description":"Deployment environment creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentEnvironmentEnvelope"}}},"description":"Created deployment environment envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create deployment environment","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["deployment:write"]}},"/v1/evidence":{"get":{"description":"Lists tenant-scoped evidence by optional release and evidence type filters.","operationId":"listEvidence","parameters":[{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemListEnvelope"}}},"description":"Evidence item list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.","operationId":"createEvidence","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceRequest"}}},"description":"Evidence creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Created evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence-bundles":{"post":{"description":"Exports a portable evidence bundle manifest with hashes, signatures, and verification text.","operationId":"exportEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEvidenceBundleRequest"}}},"description":"Evidence bundle export request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleEnvelope"}}},"description":"Created evidence bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Export evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:read"]}},"/v1/evidence-bundles/import":{"post":{"description":"Imports a portable evidence bundle manifest and records deterministic import metadata.","operationId":"importEvidenceBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundle"}}},"description":"Evidence bundle import request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceBundleImportEnvelope"}}},"description":"Evidence bundle import result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Import evidence bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/evidence-graph-snapshots":{"post":{"description":"Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.","operationId":"createGraphSnapshot","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGraphSnapshotRequest"}}},"description":"Evidence graph snapshot creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceGraphSnapshotEnvelope"}}},"description":"Created evidence graph snapshot envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence graph snapshot","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/evidence-summaries":{"post":{"description":"Creates an evidence-backed summary with citations, assumptions, and limitations.","operationId":"createEvidenceSummary","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEvidenceSummaryRequest"}}},"description":"Evidence summary creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSummaryEnvelope"}}},"description":"Created evidence summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed summary","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/evidence/search":{"get":{"description":"Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.","operationId":"searchEvidence","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"description":"Maximum returned records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence source.","in":"query","name":"source","required":false,"schema":{"type":"string"}},{"description":"Filter by a single evidence tag.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Filter by evidence type.","in":"query","name":"type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceSearchEnvelope"}}},"description":"Evidence search result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Search evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}":{"get":{"description":"Returns a tenant-scoped immutable evidence item by id.","operationId":"getEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get evidence","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/evidence/{id}/lifecycle-events":{"get":{"description":"Lists append-only lifecycle events for a tenant-scoped evidence item.","operationId":"listEvidenceLifecycleEvents","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventListEnvelope"}}},"description":"Evidence lifecycle event list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List evidence lifecycle events","tags":["evydence"],"x-scopes":["evidence:read"]},"post":{"description":"Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.","operationId":"recordEvidenceLifecycleEvent","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordEvidenceLifecycleEventRequest"}}},"description":"Evidence lifecycle event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceLifecycleEventEnvelope"}}},"description":"Created evidence lifecycle event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record evidence lifecycle event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/link":{"post":{"description":"Creates an append-only relationship from evidence to another tenant-scoped subject.","operationId":"linkEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEvidenceRequest"}}},"description":"Evidence link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Linked evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/evidence/{id}/supersede":{"post":{"description":"Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.","operationId":"supersedeEvidence","parameters":[{"description":"Evidence item id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupersedeEvidenceRequest"}}},"description":"Evidence supersession request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceItemEnvelope"}}},"description":"Superseded evidence item envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Supersede evidence","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/exceptions":{"get":{"description":"Lists tenant-scoped exceptions, optionally filtered by release.","operationId":"listExceptions","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionListEnvelope"}}},"description":"Exception list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List exceptions","tags":["evydence"],"x-scopes":["verify:read"]},"post":{"description":"Creates a scoped, expiring release/finding/control exception that is inactive until approved.","operationId":"createException","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}},"description":"Exception creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Created exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/exceptions/{id}/approve":{"post":{"description":"Approves an unexpired exception as an audited append-only transition.","operationId":"approveException","parameters":[{"description":"Exception id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionEnvelope"}}},"description":"Approved exception envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve exception","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/health":{"get":{"description":"Returns low-detail liveness status without touching tenant evidence or secret material.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusEnvelope"}}},"description":"Liveness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Health","tags":["evydence"]}},"/v1/incident-webhooks/{receiver_id}":{"post":{"description":"Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.","operationId":"receiveIncidentWebhook","parameters":[{"description":"Provider event id used for replay detection.","in":"header","name":"X-Evydence-Webhook-Event-ID","required":true,"schema":{"type":"string"}},{"description":"ed25519=\u003cbase64 signature\u003e over timestamp, event id, and raw body.","in":"header","name":"X-Evydence-Webhook-Signature","required":true,"schema":{"type":"string"}},{"description":"RFC3339 timestamp included in the signed payload.","in":"header","name":"X-Evydence-Webhook-Timestamp","required":true,"schema":{"type":"string"}},{"description":"Incident webhook receiver id.","in":"path","name":"receiver_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedIncidentWebhookPayload"}}},"description":"Signed incident timeline event payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookDeliveryEnvelope"}}},"description":"Accepted webhook event and timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Receive signed incident webhook event","tags":["evydence"]}},"/v1/incidents":{"post":{"description":"Creates an append-only incident record linked to tenant-scoped product and optional release evidence.","operationId":"createIncident","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentRequest"}}},"description":"Incident creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentEnvelope"}}},"description":"Created incident envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create incident","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/timeline":{"post":{"description":"Appends an incident timeline event and optional evidence reference.","operationId":"recordIncidentTimeline","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIncidentTimelineRequest"}}},"description":"Incident timeline event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentTimelineEventEnvelope"}}},"description":"Created incident timeline event envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record incident timeline event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/incidents/{id}/webhook-receivers":{"post":{"description":"Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.","operationId":"createIncidentWebhookReceiver","parameters":[{"description":"Incident id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIncidentWebhookReceiverRequest"}}},"description":"Incident webhook receiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentWebhookReceiverEnvelope"}}},"description":"Created incident webhook receiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signed incident webhook receiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/legal-holds":{"post":{"description":"Creates an append-only legal-hold marker for a tenant-scoped retention subject.","operationId":"createLegalHold","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLegalHoldRequest"}}},"description":"Legal hold creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LegalHoldEnvelope"}}},"description":"Created legal hold envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create legal hold","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/marketplace-collectors":{"get":{"description":"Lists tenant-scoped marketplace collector package metadata.","operationId":"listMarketplaceCollectors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorListEnvelope"}}},"description":"Marketplace collector list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List marketplace collector records","tags":["evydence"],"x-scopes":["collector:read"]},"post":{"description":"Creates tenant-scoped marketplace collector package metadata and evidence references.","operationId":"createMarketplaceCollector","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarketplaceCollectorRequest"}}},"description":"Marketplace collector creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorEnvelope"}}},"description":"Created marketplace collector envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create marketplace collector record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["collector:admin"]}},"/v1/marketplace-collectors/{id}/health":{"get":{"description":"Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.","operationId":"marketplaceCollectorHealth","parameters":[{"description":"Marketplace collector id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketplaceCollectorHealthReportEnvelope"}}},"description":"Marketplace collector health report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Marketplace collector health report","tags":["evydence"],"x-scopes":["collector:read"]}},"/v1/merkle-batches":{"post":{"description":"Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.","operationId":"createMerkleBatch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMerkleBatchRequest"}}},"description":"Merkle batch creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerkleBatchEnvelope"}}},"description":"Created Merkle batch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create Merkle checkpoint batch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/merkle-batches/{id}/verify":{"get":{"description":"Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.","operationId":"verifyMerkleBatch","parameters":[{"description":"Merkle batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Merkle batch verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify Merkle checkpoint batch","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/metrics":{"get":{"description":"Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.","operationId":"metrics","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsSnapshotEnvelope"}},"text/plain":{"schema":{"type":"string"}}},"description":"Tenant metrics envelope or Prometheus text metrics."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Safe tenant metrics","tags":["evydence"],"x-scopes":["admin"]}},"/v1/object-retention-policies":{"post":{"description":"Creates an object retention policy record for storage immutability verification.","operationId":"createObjectRetentionPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateObjectRetentionPolicyRequest"}}},"description":"Object retention policy creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Created object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/object-retention-policies/{id}/verify":{"post":{"description":"Records verification metadata for a tenant object retention policy.","operationId":"verifyObjectRetentionPolicy","parameters":[{"description":"Object retention policy id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjectRetentionPolicyEnvelope"}}},"description":"Verified object retention policy envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify object retention policy record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/openapi-contracts":{"post":{"description":"Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.","operationId":"uploadOpenAPIContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOpenAPIContractRequest"}}},"description":"OpenAPI contract upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"Created OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenAPI contract","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/openapi-contracts/{id}":{"get":{"description":"Returns a tenant-scoped OpenAPI contract metadata record by id.","operationId":"getOpenAPIContract","parameters":[{"description":"OpenAPI contract id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIContractEnvelope"}}},"description":"OpenAPI contract envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get OpenAPI contract","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/openapi-diffs":{"post":{"description":"Creates a deterministic OpenAPI contract diff for release contract checks.","operationId":"createOpenAPIDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenAPIDiffRequest"}}},"description":"OpenAPI contract diff request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractDiffEnvelope"}}},"description":"Created OpenAPI contract diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create OpenAPI contract diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/openapi.json":{"get":{"description":"Returns the generated OpenAPI 3.1 document served by this process.","operationId":"openapi","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAPIDocument"}}},"description":"OpenAPI document."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"OpenAPI","tags":["evydence"]}},"/v1/organizations":{"post":{"description":"Creates a tenant-scoped organization record for human identity grouping.","operationId":"createOrganization","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Organization creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationEnvelope"}}},"description":"Created organization envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create organization","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/policies/evaluate":{"post":{"description":"Evaluates built-in deterministic release policy checks for a release.","operationId":"evaluatePolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluatePolicyRequest"}}},"description":"Policy evaluation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyEvaluationEnvelope"}}},"description":"Policy evaluation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Evaluate release policy","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/products":{"get":{"description":"Lists tenant-scoped products visible to the authenticated actor.","operationId":"listProducts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListEnvelope"}}},"description":"Product list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List products","tags":["evydence"],"x-scopes":["product:read"]},"post":{"description":"Creates a tenant-scoped product. Product slugs must be unique per tenant.","operationId":"createProduct","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProductRequest"}}},"description":"Product creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Created product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create product","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["product:write"]}},"/v1/products/{id}":{"get":{"description":"Returns a tenant-scoped product by id.","operationId":"getProduct","parameters":[{"description":"Product id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductEnvelope"}}},"description":"Product envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get product","tags":["evydence"],"x-scopes":["product:read"]}},"/v1/projects":{"post":{"description":"Creates a tenant-scoped project under a product.","operationId":"createProject","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"description":"Project creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Created project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create project","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["project:write"]}},"/v1/projects/{id}":{"get":{"description":"Returns a tenant-scoped project by id.","operationId":"getProject","parameters":[{"description":"Project id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectEnvelope"}}},"description":"Project envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get project","tags":["evydence"],"x-scopes":["project:read"]}},"/v1/provider-verifications":{"post":{"description":"Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.","operationId":"verifyProviderIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyProviderIdentityRequest"}}},"description":"Provider identity verification request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVerificationEnvelope"}}},"description":"Provider verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify stored provider identity metadata","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/public-transparency-log-entries":{"post":{"description":"Records publication metadata for a checkpoint submitted to a configured public transparency log.","operationId":"publishPublicTransparencyLogEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log entry publication request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Created public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Publish public transparency log entry record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/fetch-proof":{"post":{"description":"Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.","operationId":"fetchPublicTransparencyLogEntryProof","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Fetched and verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Fetch and verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-log-entries/{id}/verify":{"post":{"description":"Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.","operationId":"verifyPublicTransparencyLogEntry","parameters":[{"description":"Public transparency log entry id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPublicTransparencyLogEntryRequest"}}},"description":"Public transparency log inclusion proof verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEntryEnvelope"}}},"description":"Verified public transparency log entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify public transparency log inclusion proof","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/public-transparency-logs":{"post":{"description":"Creates tenant metadata for an optional public transparency log trust root.","operationId":"createPublicTransparencyLog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicTransparencyLogRequest"}}},"description":"Public transparency log creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTransparencyLogEnvelope"}}},"description":"Created public transparency log envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create public transparency log record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/questionnaire-answer-library":{"get":{"description":"Lists tenant-scoped questionnaire answer library entries with optional question, product, and release filters.","operationId":"listQuestionnaireAnswerLibrary","parameters":[{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by questionnaire question id.","in":"query","name":"question_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryListEnvelope"}}},"description":"Questionnaire answer library entry list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List questionnaire answer library entries","tags":["evydence"],"x-scopes":["package:read"]},"post":{"description":"Creates a tenant-scoped reusable questionnaire answer draft linked to optional evidence, product, release, or control scope.","operationId":"createQuestionnaireAnswerLibraryEntry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireAnswerLibraryEntryRequest"}}},"description":"Questionnaire answer library entry creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireAnswerLibraryEntryEnvelope"}}},"description":"Created questionnaire answer library entry envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire answer library entry","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-drafts":{"post":{"description":"Creates an evidence-backed questionnaire draft with limitations.","operationId":"createQuestionnaireDraft","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireDraftRequest"}}},"description":"Questionnaire draft creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireDraftEnvelope"}}},"description":"Created questionnaire draft envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create evidence-backed questionnaire draft","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:read"]}},"/v1/questionnaire-packages":{"post":{"description":"Creates a questionnaire response package from a template and scoped evidence package.","operationId":"createQuestionnairePackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnairePackageRequest"}}},"description":"Questionnaire package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnairePackageEnvelope"}}},"description":"Created questionnaire package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/questionnaire-templates":{"post":{"description":"Creates a tenant questionnaire template with explicit evidence/control mapping fields.","operationId":"createQuestionnaireTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuestionnaireTemplateRequest"}}},"description":"Questionnaire template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionnaireTemplateEnvelope"}}},"description":"Created questionnaire template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create questionnaire template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/ready":{"get":{"description":"Returns low-detail process readiness without tenant evidence or secret material.","operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessStatusEnvelope"}}},"description":"Readiness status envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Readiness","tags":["evydence"]}},"/v1/redaction-profiles":{"post":{"description":"Creates an explicit redaction profile for customer and report package generation.","operationId":"createRedactionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRedactionProfileRequest"}}},"description":"Redaction profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactionProfileEnvelope"}}},"description":"Created redaction profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create redaction profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["package:write"]}},"/v1/release-bundles":{"post":{"description":"Creates an immutable signed release bundle for a release.","operationId":"createReleaseBundle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseBundleRequest"}}},"description":"Release bundle creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Created release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release bundle","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["bundle:write"]}},"/v1/release-bundles/{id}":{"get":{"description":"Returns a tenant-scoped immutable release bundle by id.","operationId":"getReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleEnvelope"}}},"description":"Release bundle envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/manifest":{"get":{"description":"Returns the deterministic release bundle manifest by bundle id.","operationId":"getReleaseBundleManifest","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseBundleManifestEnvelope"}}},"description":"Release bundle manifest envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release bundle manifest","tags":["evydence"],"x-scopes":["bundle:read"]}},"/v1/release-bundles/{id}/verify":{"get":{"description":"Verifies a tenant-scoped release bundle and returns a deterministic verification result.","operationId":"verifyReleaseBundle","parameters":[{"description":"Release bundle id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Release bundle verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify release bundle","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/release-candidates":{"get":{"description":"Lists tenant-scoped release candidates, optionally filtered by release.","operationId":"listReleaseCandidates","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateListEnvelope"}}},"description":"Release candidate list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List release candidates","tags":["evydence"],"x-scopes":["release:read"]},"post":{"description":"Creates an immutable release-candidate snapshot of selected release evidence references.","operationId":"createReleaseCandidate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReleaseCandidateRequest"}}},"description":"Release candidate creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Created release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}":{"get":{"description":"Returns a tenant-scoped release candidate by id.","operationId":"getReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release candidate","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/release-candidates/{id}/promote":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"promoteReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Promote release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/release-candidates/{id}/reject":{"post":{"description":"Records a release-candidate lifecycle transition without mutating the original snapshot.","operationId":"rejectReleaseCandidate","parameters":[{"description":"Release candidate id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateTransitionRequest"}}},"description":"Release candidate transition request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCandidateEnvelope"}}},"description":"Transitioned release candidate envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Reject release candidate","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases":{"post":{"description":"Creates an append-only release record under a product and optional project.","operationId":"createRelease","requestBody":{"content":{"application/json":{"examples":{"release-candidate":{"summary":"Create a release for evidence collection","value":{"product_id":"prod_20260527120000","project_id":"proj_20260527120000","version":"1.0.0-rc.1"}}},"schema":{"$ref":"#/components/schemas/CreateReleaseRequest"}}},"description":"Release creation request.","required":true},"responses":{"201":{"content":{"application/json":{"examples":{"created-release":{"summary":"Created release response","value":{"data":{"created_at":"2026-05-27T12:00:00Z","id":"rel_20260527120000","product_id":"prod_20260527120000","project_id":"proj_20260527120000","schema_version":"release.v1.0.0","status":"draft","tenant_id":"ten_20260527120000","version":"1.0.0-rc.1"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Created release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}":{"get":{"description":"Returns a tenant-scoped release by id.","operationId":"getRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get release","tags":["evydence"],"x-scopes":["release:read"]}},"/v1/releases/{id}/approve":{"post":{"description":"Approves a release as an append-only transition.","operationId":"approveRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Approved release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/evidence-flow/start":{"post":{"description":"Returns a high-level release evidence workflow plan, current evidence counts, required scopes, assumptions, and limitations. This read-only convenience operation does not create evidence.","operationId":"startReleaseEvidenceFlow","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEvidenceFlowEnvelope"}}},"description":"Release evidence flow envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Start release evidence flow","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:read"]}},"/v1/releases/{id}/freeze":{"post":{"description":"Freezes a release as an append-only transition.","operationId":"freezeRelease","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseEnvelope"}}},"description":"Frozen release envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Freeze release","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["release:write"]}},"/v1/releases/{id}/security-summary":{"get":{"description":"Returns a tenant-scoped release security summary for review surfaces without raw evidence payload bytes.","operationId":"releaseSecuritySummary","parameters":[{"description":"Release id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseSecuritySummaryEnvelope"}}},"description":"Release security summary envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release security summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/remediation-tasks":{"post":{"description":"Creates an incident or release remediation task linked to optional evidence.","operationId":"createRemediationTask","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRemediationTaskRequest"}}},"description":"Remediation task creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemediationTaskEnvelope"}}},"description":"Created remediation task envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create remediation task","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["incident:write"]}},"/v1/report-templates":{"post":{"description":"Creates a tenant-defined deterministic report template with an explicit allowed-field list.","operationId":"createReportTemplate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReportTemplateRequest"}}},"description":"Report template creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomReportTemplateEnvelope"}}},"description":"Created report template envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/report-templates/{id}/render":{"post":{"description":"Renders a tenant report template for a scoped subject using allowed fields only.","operationId":"renderReportTemplate","parameters":[{"description":"Report template id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderReportTemplateRequest"}}},"description":"Report template render request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderedCustomReportEnvelope"}}},"description":"Rendered report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Render report template","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/anomaly":{"post":{"description":"Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.","operationId":"generateAnomalyReport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnomalyReportRequest"}}},"description":"Anomaly report creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyReportEnvelope"}}},"description":"Created anomaly report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Generate deterministic anomaly report","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/control-coverage":{"get":{"description":"Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.","operationId":"controlCoverageReport","parameters":[{"description":"Control framework id.","in":"query","name":"framework_id","required":false,"schema":{"type":"string"}},{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Control coverage report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Control coverage report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness":{"get":{"description":"Returns a CRA-oriented readiness report without legal compliance or certification conclusions.","operationId":"craReadinessReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"CRA readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-readiness-html":{"get":{"description":"Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.","operationId":"craReadinessHTMLPackage","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTMLReportPackageEnvelope"}}},"description":"CRA readiness HTML package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA readiness HTML package","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/cra-vulnerability-handling":{"get":{"description":"Returns a CRA-oriented vulnerability handling evidence report without legal compliance, certification, scanner-authority, or release-security conclusions.","operationId":"craVulnerabilityHandlingReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CRAVulnerabilityHandlingReportEnvelope"}}},"description":"CRA vulnerability handling report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"CRA vulnerability handling report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/custody-review":{"get":{"description":"Returns tenant signing-provider and object-lock verification metadata for deployment custody review. It is evidence metadata only, not legal compliance proof, certification, HSM custody proof, or a secure-deployment guarantee.","operationId":"signingCustodyReviewReport","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningCustodyReviewReportEnvelope"}}},"description":"Signing custody review report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Signing custody review report","tags":["evydence"],"x-scopes":["keys:admin"]}},"/v1/reports/incident-package":{"get":{"description":"Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.","operationId":"incidentReport","parameters":[{"description":"Incident id.","in":"query","name":"incident_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentReportEnvelope"}}},"description":"Incident package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Incident package report","tags":["evydence"],"x-scopes":["incident:read"]}},"/v1/reports/missing-evidence":{"get":{"description":"Returns a deterministic missing-evidence report for a release with assumptions and limitations.","operationId":"missingEvidenceReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MissingEvidenceReportEnvelope"}}},"description":"Missing evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Missing evidence report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/pdf":{"post":{"description":"Creates a deterministic PDF report package record and payload metadata.","operationId":"createPDFReportPackage","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePDFReportPackageRequest"}}},"description":"PDF report package creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PDFReportPackageEnvelope"}}},"description":"Created PDF report package envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create reproducible PDF report package","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["report:read"]}},"/v1/reports/release-readiness":{"get":{"description":"Returns a deterministic release-readiness report with gaps, assumptions, and limitations.","operationId":"releaseReadinessReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"examples":{"failed-readiness-with-gap":{"summary":"Readiness report with a vulnerability decision gap","value":{"data":{"accepted_exceptions":[],"assumptions":["Readiness is based on tenant evidence recorded in Evydence."],"blocking_findings":[{"component":"pkg:apk/openssl@3.1.0-r0","decision_state":"missing","finding_id":"scan_20260527120000:finding:1","release_id":"rel_20260527120000","scan_id":"scan_20260527120000","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"generated_at":"2026-05-27T12:00:00Z","limitations":["Readiness supports technical review and does not prove legal compliance, certification, complete vulnerability coverage, or release security."],"missing_evidence":["vulnerability_decision"],"policy_set":"policy-set.v1.0.0","product_id":"prod_20260527120000","release_id":"rel_20260527120000","report_type":"release_readiness","result":"failed","schema_version":"release-readiness.v1.0.0","summary":{"headline":"Release evidence has one blocking vulnerability decision gap.","human_summary":"Required artifact, SBOM, scan, build, and bundle evidence is present, but one critical finding still needs a valid decision or approved exception.","policy_set":"policy-set.v1.0.0","result":"failed"},"template_version":"release-readiness.v1.0.0"},"meta":{"api_version":"v1"}}}},"schema":{"$ref":"#/components/schemas/ReadinessReportEnvelope"}}},"description":"Release readiness report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Release readiness report","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/reports/retention":{"get":{"description":"Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.","operationId":"retentionReport","parameters":[{"description":"Optional retention scope id.","in":"query","name":"scope_id","required":false,"schema":{"type":"string"}},{"description":"Optional retention scope type.","in":"query","name":"scope_type","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionReportEnvelope"}}},"description":"Retention report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Retention report","tags":["evydence"],"x-scopes":["admin"]}},"/v1/reports/security-review-package":{"get":{"description":"Returns a redaction-aware security-review package report with assumptions and limitations.","operationId":"securityReviewPackageReport","parameters":[{"description":"Customer package id.","in":"query","name":"package_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityReviewPackageReportEnvelope"}}},"description":"Security review package report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security review package report","tags":["evydence"],"x-scopes":["package:read"]}},"/v1/reports/security-update-evidence":{"get":{"description":"Returns a security update evidence report for release-scoped fixed decisions, incidents, remediation tasks, and linked evidence without legal or security conclusions.","operationId":"securityUpdateEvidenceReport","parameters":[{"description":"Product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityUpdateEvidenceReportEnvelope"}}},"description":"Security update evidence report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Security update evidence report","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-decision-summary":{"get":{"description":"Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.","operationId":"vulnerabilityDecisionSummaryReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionSummaryReportEnvelope"}}},"description":"Vulnerability decision summary report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Customer-safe vulnerability decision summary","tags":["evydence"],"x-scopes":["report:read"]}},"/v1/reports/vulnerability-posture":{"get":{"description":"Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.","operationId":"vulnerabilityPostureReport","parameters":[{"description":"Release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityPostureReportEnvelope"}}},"description":"Vulnerability posture report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Vulnerability posture report","tags":["evydence"],"x-scopes":["security:read"]}},"/v1/retention-overrides":{"post":{"description":"Creates an append-only retention override for a tenant-scoped retention subject.","operationId":"createRetentionOverride","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRetentionOverrideRequest"}}},"description":"Retention override creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionOverrideEnvelope"}}},"description":"Created retention override envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create retention override","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["admin"]}},"/v1/role-bindings":{"get":{"description":"Lists tenant-scoped role bindings visible to the identity administrator.","operationId":"listRoleBindings","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingListEnvelope"}}},"description":"Role binding list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List role bindings","tags":["evydence"],"x-scopes":["identity:admin"]},"post":{"description":"Creates a tenant-scoped role binding for a user or collector subject.","operationId":"createRoleBinding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleBindingRequest"}}},"description":"Role binding creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleBindingEnvelope"}}},"description":"Created role binding envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create role binding","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/saas/profiles":{"post":{"description":"Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.","operationId":"createSaaSEditionProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaaSEditionProfileRequest"}}},"description":"SaaS edition profile creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaaSEditionProfileEnvelope"}}},"description":"Created SaaS edition profile envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SaaS edition profile","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["instance:admin"]}},"/v1/sbom-components":{"get":{"description":"Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.","operationId":"listSBOMComponents","parameters":[{"description":"Filter by artifact id.","in":"query","name":"artifact_id","required":false,"schema":{"type":"string"}},{"description":"Maximum returned component records.","in":"query","name":"limit","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer"}},{"description":"Exact package URL filter.","in":"query","name":"purl","required":false,"schema":{"type":"string"}},{"description":"Case-insensitive component name, version, or PURL search.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by SBOM id.","in":"query","name":"sbom_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMComponentRecordListEnvelope"}}},"description":"SBOM component result envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List SBOM components","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/sbom-diffs":{"post":{"description":"Creates a deterministic SBOM diff between two tenant-scoped SBOM records.","operationId":"createSBOMDiff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSBOMDiffRequest"}}},"description":"SBOM diff creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMDiffEnvelope"}}},"description":"Created SBOM diff envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SBOM diff","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:read"]}},"/v1/sboms":{"post":{"description":"Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.","operationId":"uploadSBOM","requestBody":{"content":{"application/json":{"examples":{"cyclonedx-release-sbom":{"summary":"Upload a CycloneDX SBOM linked to the release artifact","value":{"artifact_id":"art_20260527120000","payload":{"bomFormat":"CycloneDX","components":[{"name":"payments-api","purl":"pkg:oci/payments-api@sha256-ca978112","version":"1.0.0-rc.1"},{"name":"openssl","purl":"pkg:apk/openssl@3.1.0-r0","version":"3.1.0-r0"}],"specVersion":"1.6"},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/spdx":{"post":{"description":"Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.","operationId":"uploadSPDXSBOM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSPDXSBOMRequest"}}},"description":"SPDX SBOM upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"Created SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload SPDX SBOM","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/sboms/{id}":{"get":{"description":"Returns a tenant-scoped SBOM metadata record by id.","operationId":"getSBOM","parameters":[{"description":"SBOM id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SBOMEnvelope"}}},"description":"SBOM envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get SBOM","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/security-documents":{"post":{"description":"Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.","operationId":"uploadManualSecurityDocument","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadManualSecurityDocumentRequest"}}},"description":"Manual security document upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManualSecurityDocumentEnvelope"}}},"description":"Created manual security document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload manual security document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/security-scans":{"post":{"description":"Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.","operationId":"uploadSecurityScan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSecurityScanRequest"}}},"description":"Security scan upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityScanEnvelope"}}},"description":"Created security scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload security scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/signing-keys":{"get":{"description":"Lists tenant signing public-key metadata without private key material.","operationId":"listSigningKeys","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyListEnvelope"}}},"description":"Signing key list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List signing keys","tags":["evydence"],"x-scopes":["verify:read"]}},"/v1/signing-keys/rotate":{"post":{"description":"Rotates the active tenant signing key and returns public-key metadata only.","operationId":"rotateSigningKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key rotation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Rotated signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Rotate signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-keys/{id}/revoke":{"post":{"description":"Revokes a tenant signing key as an audited lifecycle transition.","operationId":"revokeSigningKey","parameters":[{"description":"Signing key id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyTransitionRequest"}}},"description":"Signing key revocation request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyEnvelope"}}},"description":"Revoked signing key envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke signing key","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-operations":{"post":{"description":"Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.","operationId":"createSigningOperation","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningOperationRequest"}}},"description":"Signing operation creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningOperationEnvelope"}}},"description":"Created signing operation envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider operation receipt","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/signing-providers":{"post":{"description":"Creates signing provider metadata for external signing operations. Production private key material must not be supplied.","operationId":"createSigningProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSigningProviderRequest"}}},"description":"Signing provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningProviderEnvelope"}}},"description":"Created signing provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create signing provider record","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/source/branches":{"post":{"description":"Records or updates source branch metadata and protected-branch snapshot hash.","operationId":"upsertSourceBranch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertSourceBranchRequest"}}},"description":"Source branch upsert request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceBranchEnvelope"}}},"description":"Source branch envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source branch","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/commits":{"post":{"description":"Records immutable source commit metadata and stores only a hash of the commit message.","operationId":"recordSourceCommit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSourceCommitRequest"}}},"description":"Source commit creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCommitEnvelope"}}},"description":"Created source commit envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record source commit","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/pull-requests":{"post":{"description":"Records pull-request review metadata linked to source repository evidence.","operationId":"recordPullRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPullRequestRequest"}}},"description":"Pull request record request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PullRequestEnvelope"}}},"description":"Created pull request envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record pull request","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/source/repositories":{"get":{"description":"Lists tenant-scoped source repositories, optionally filtered by project.","operationId":"listSourceRepositories","parameters":[{"description":"Project id.","in":"query","name":"project_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryListEnvelope"}}},"description":"Source repository list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List source repositories","tags":["evydence"],"x-scopes":["source:read"]},"post":{"description":"Creates a tenant-scoped source repository record.","operationId":"createSourceRepository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceRepositoryRequest"}}},"description":"Source repository creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceRepositoryEnvelope"}}},"description":"Created source repository envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create source repository","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["source:write"]}},"/v1/sso/identity-links":{"post":{"description":"Links a verified provider subject to a tenant-scoped human user.","operationId":"linkSSOIdentity","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSSOIdentityRequest"}}},"description":"SSO identity link request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentityLinkEnvelope"}}},"description":"Created SSO identity link envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Link SSO identity","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/logout":{"post":{"description":"Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.","operationId":"logoutSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked current SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Logout SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true}}},"/v1/sso/providers":{"post":{"description":"Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.","operationId":"createSSOProvider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOProviderRequest"}}},"description":"SSO provider creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Created SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO provider","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/discover-oidc":{"post":{"description":"Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.","operationId":"refreshSSOProviderOIDCTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Refreshed SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Refresh SSO provider OIDC trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/providers/{id}/trust-material":{"post":{"description":"Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.","operationId":"updateSSOProviderTrustMaterial","parameters":[{"description":"SSO provider id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSSOProviderTrustMaterialRequest"}}},"description":"SSO provider trust material update request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOProviderEnvelope"}}},"description":"Updated SSO provider envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Update SSO provider trust material","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/session-exchanges":{"post":{"description":"Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.","operationId":"exchangeSSOCredential","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeSSOCredentialRequest"}}},"description":"SSO credential exchange request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOCredentialExchangeEnvelope"}}},"description":"Created SSO session, verification receipt, and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Exchange SSO credential","tags":["evydence"]}},"/v1/sso/sessions":{"post":{"description":"Creates an admin-managed human SSO session record and returns a one-time bearer secret.","operationId":"createSSOSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSSOSessionRequest"}}},"description":"SSO session creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionCreateEnvelope"}}},"description":"Created SSO session and one-time secret envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/sso/sessions/{id}/revoke":{"post":{"description":"Revokes a tenant-scoped SSO session as an audited lifecycle transition.","operationId":"revokeSSOSession","parameters":[{"description":"SSO session id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SSOSessionEnvelope"}}},"description":"Revoked SSO session envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Revoke SSO session","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/transparency-checkpoints":{"post":{"description":"Records an external transparency or timestamp checkpoint reference for a Merkle batch.","operationId":"createTransparencyCheckpoint","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTransparencyCheckpointRequest"}}},"description":"Transparency checkpoint creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransparencyCheckpointEnvelope"}}},"description":"Created transparency checkpoint envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record external transparency checkpoint","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["keys:admin"]}},"/v1/users":{"post":{"description":"Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"description":"Human user creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Created human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/users/{id}/deactivate":{"post":{"description":"Deactivates a tenant-scoped human user as an audited lifecycle transition.","operationId":"deactivateUser","parameters":[{"description":"Human user id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HumanUserEnvelope"}}},"description":"Deactivated human user envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Deactivate user","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["identity:admin"]}},"/v1/verify":{"post":{"description":"Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.","operationId":"verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySubjectRequest"}}},"description":"Subject verification request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResultEnvelope"}}},"description":"Subject verification envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Verify subject","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["verify:read"]}},"/v1/version":{"get":{"description":"Returns the API process version string.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfoEnvelope"}}},"description":"Version information envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"summary":"Version","tags":["evydence"]}},"/v1/vex":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadVEX","requestBody":{"content":{"application/json":{"examples":{"openvex-fixed-decision":{"summary":"Imported OpenVEX fixed decision","value":{"artifact_id":"art_20260527120000","payload":{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://example.test/vex/payments-api/1.0.0","author":"security@example.test","statements":[{"action_statement":"Ship the fixed artifact after operator review.","impact_statement":"Patched before this release candidate.","justification":"fixed_in_release_candidate","products":[{"@id":"pkg:apk/openssl@3.1.0"}],"status":"fixed","vulnerability":{"name":"CVE-2026-0002"}}],"timestamp":"2026-05-27T12:00:00Z","version":1},"release_id":"rel_20260527120000"}}},"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload OpenVEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx":{"post":{"description":"Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.","operationId":"uploadCycloneDXVEX","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX upload request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"Created VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload CycloneDX VEX document","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vex/cyclonedx/preview":{"post":{"description":"Validates a CycloneDX VEX payload and returns advisory mapping counts without storing raw payloads, creating evidence, creating decisions, or enqueueing parser jobs.","operationId":"previewCycloneDXVEXImport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"CycloneDX VEX import preview request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportPreviewEnvelope"}}},"description":"Advisory VEX import preview envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Preview CycloneDX VEX import","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":false},"x-scopes":["evidence:read"]}},"/v1/vex/preview":{"post":{"description":"Validates an OpenVEX payload and returns advisory mapping counts without storing raw payloads, creating evidence, creating decisions, or enqueueing parser jobs.","operationId":"previewVEXImport","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceUploadRequest"}}},"description":"OpenVEX import preview request.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportPreviewEnvelope"}}},"description":"Advisory VEX import preview envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Preview OpenVEX import","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":false},"x-scopes":["evidence:read"]}},"/v1/vex/{id}":{"get":{"description":"Returns a tenant-scoped VEX document metadata record by id.","operationId":"getVEX","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXDocumentEnvelope"}}},"description":"VEX document envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX document","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vex/{id}/import-report":{"get":{"description":"Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.","operationId":"getVEXImportReport","parameters":[{"description":"VEX document id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VEXImportReportEnvelope"}}},"description":"VEX import report envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get VEX import report","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-decisions":{"get":{"description":"Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.","operationId":"listVulnerabilityDecisions","parameters":[{"description":"When true returns active decisions; when false returns superseded decisions.","in":"query","name":"active","required":false,"schema":{"type":"boolean"}},{"description":"Filter by affected component.","in":"query","name":"component","required":false,"schema":{"type":"string"}},{"description":"Filter by product id.","in":"query","name":"product_id","required":false,"schema":{"type":"string"}},{"description":"Filter by release id.","in":"query","name":"release_id","required":false,"schema":{"type":"string"}},{"description":"Filter by decision status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Filter by vulnerability identifier.","in":"query","name":"vulnerability","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionListEnvelope"}}},"description":"Vulnerability decision list envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"List vulnerability decisions","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/vulnerability-findings/{id}/decisions":{"post":{"description":"Creates an append-only vulnerability decision for a tenant-scoped scan finding.","operationId":"createVulnerabilityDecision","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"examples":{"not-affected-decision":{"summary":"Record a customer-visible not-affected decision","value":{"customer_visible":true,"evidence_ids":["ev_20260527120000"],"impact_statement":"The shipped artifact does not include the affected runtime path.","justification":"The vulnerable code path is not reachable in this release.","status":"not_affected","supporting_refs":[{"id":"exc_20260527120000","type":"exception"}]}}},"schema":{"$ref":"#/components/schemas/CreateVulnerabilityDecisionRequest"}}},"description":"Vulnerability decision creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityDecisionEnvelope"}}},"description":"Created vulnerability decision envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create vulnerability decision","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-findings/{id}/workflow":{"post":{"description":"Records an append-only vulnerability workflow event for a tenant-scoped finding.","operationId":"recordVulnerabilityWorkflow","parameters":[{"description":"Vulnerability finding id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVulnerabilityWorkflowRequest"}}},"description":"Vulnerability workflow event request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityWorkflowRecordEnvelope"}}},"description":"Created vulnerability workflow record envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Record vulnerability workflow event","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["security:write"]}},"/v1/vulnerability-scans":{"post":{"description":"Uploads a generic vulnerability scan JSON payload and records normalized findings.","operationId":"uploadVulnerabilityScan","requestBody":{"content":{"application/json":{"examples":{"generic-critical-finding":{"summary":"Upload a generic scanner finding for release triage","value":{"findings":[{"component":"pkg:apk/openssl@3.1.0-r0","severity":"critical","state":"open","vulnerability":"CVE-2026-0099"}],"release_id":"rel_20260527120000","scanner":"generic-json","target_ref":"pkg:oci/payments-api@sha256-ca978112"}}},"schema":{"$ref":"#/components/schemas/UploadVulnerabilityScanRequest"}}},"description":"Vulnerability scan upload payload.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Created vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Upload vulnerability scan","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["evidence:write"]}},"/v1/vulnerability-scans/{id}":{"get":{"description":"Returns a tenant-scoped vulnerability scan by id.","operationId":"getVulnerabilityScan","parameters":[{"description":"Vulnerability scan id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VulnerabilityScanEnvelope"}}},"description":"Vulnerability scan envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Get vulnerability scan","tags":["evydence"],"x-scopes":["evidence:read"]}},"/v1/waivers":{"post":{"description":"Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.","operationId":"createWaiver","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWaiverRequest"}}},"description":"Waiver creation request.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Created waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Create waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}},"/v1/waivers/{id}/approve":{"post":{"description":"Approves an unexpired waiver as an audited transition.","operationId":"approveWaiver","parameters":[{"description":"Waiver id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}},"description":"Empty JSON object.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverEnvelope"}}},"description":"Approved waiver envelope."},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Bad Request"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unauthorized"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Forbidden"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Not Found"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Unprocessable Entity"}},"security":[{"BearerAuth":[]}],"summary":"Approve waiver","tags":["evydence"],"x-idempotency-key":{"header":"Idempotency-Key","required":true},"x-scopes":["policy:write"]}}}} diff --git a/sdk/openapi-route-catalog.json b/sdk/openapi-route-catalog.json index 8ca8662..8f679ed 100644 --- a/sdk/openapi-route-catalog.json +++ b/sdk/openapi-route-catalog.json @@ -1,5 +1,5 @@ { - "route_count": 178, + "route_count": 183, "routes": [ { "idempotency_key_required": false, @@ -154,6 +154,23 @@ "201" ] }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "getArtifact", + "path": "/v1/artifacts/{id}", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/ArtifactEnvelope", + "#/components/schemas/Problem" + ], + "scopes": [ + "evidence:read" + ], + "success_statuses": [ + "200" + ] + }, { "idempotency_key_required": false, "method": "GET", @@ -1468,6 +1485,23 @@ "201" ] }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "getProduct", + "path": "/v1/products/{id}", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/ProductEnvelope" + ], + "scopes": [ + "product:read" + ], + "success_statuses": [ + "200" + ] + }, { "idempotency_key_required": true, "method": "POST", @@ -1485,6 +1519,23 @@ "201" ] }, + { + "idempotency_key_required": false, + "method": "GET", + "operation_id": "getProject", + "path": "/v1/projects/{id}", + "request_schema": "", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/ProjectEnvelope" + ], + "scopes": [ + "project:read" + ], + "success_statuses": [ + "200" + ] + }, { "idempotency_key_required": true, "method": "POST", @@ -2854,6 +2905,40 @@ "201" ] }, + { + "idempotency_key_required": false, + "method": "POST", + "operation_id": "previewCycloneDXVEXImport", + "path": "/v1/vex/cyclonedx/preview", + "request_schema": "#/components/schemas/EvidenceUploadRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/VEXImportPreviewEnvelope" + ], + "scopes": [ + "evidence:read" + ], + "success_statuses": [ + "200" + ] + }, + { + "idempotency_key_required": false, + "method": "POST", + "operation_id": "previewVEXImport", + "path": "/v1/vex/preview", + "request_schema": "#/components/schemas/EvidenceUploadRequest", + "response_schemas": [ + "#/components/schemas/Problem", + "#/components/schemas/VEXImportPreviewEnvelope" + ], + "scopes": [ + "evidence:read" + ], + "success_statuses": [ + "200" + ] + }, { "idempotency_key_required": false, "method": "GET", From 198d42d967ccba827095d9b9f60b6c1425807781 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 17:49:53 +0300 Subject: [PATCH 231/287] test(ci): add local evidence simulation --- .productization_next_steps_missing.md | 4 +- Makefile | 7 +- docs/how-to/integrate-ci.md | 19 ++ .../end-to-end-release-evidence/README.md | 12 + internal/app/ledger.go | 1 + internal/app/ledger_test.go | 2 +- scripts/local_ci_simulation_check.sh | 235 ++++++++++++++++++ 7 files changed, 276 insertions(+), 4 deletions(-) create mode 100755 scripts/local_ci_simulation_check.sh diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index 68ebcd7..5801a07 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -343,7 +343,7 @@ Implementation rules: - Update worker/outbox docs. - Run `go test ./cmd/evydence-worker ./internal/app` and `make docs-check`. -## Epic E5 - Make CI Evidence Ingest Embarrassingly Simple [ ] +## Epic E5 - Make CI Evidence Ingest Embarrassingly Simple [x] Description: Reduce the first CI integration to one obvious release-evidence path before users learn the full domain model. @@ -377,7 +377,7 @@ Implementation rules: - Add CLI tests and safe error-message tests. - Run `go test ./cmd/evydence` and `make docs-check`. -### Ticket E5-T3 - Add a checked one-command local CI simulation [ ] +### Ticket E5-T3 - Add a checked one-command local CI simulation [x] Description: Add a local script that simulates the GitHub Actions quickstart against a local API using non-sensitive fixture SBOM/scan/VEX data. diff --git a/Makefile b/Makefile index 68380a1..95dd69c 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ GOVULNCHECK_VERSION ?= v1.2.0 TAG ?= -.PHONY: help tools fmt lint vuln gosec test test-race fuzz-smoke coverage coverage-check openapi-check openapi-precision-check meta-check docs-check deploy-check sdk-check demo-check black-box-demo-check benchmark-check package-viewer-check restore-rehearsal-check fast-check finalize release-acceptance release-check production-check release-candidate-check public-release-verify migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean +.PHONY: help tools fmt lint vuln gosec test test-race fuzz-smoke coverage coverage-check openapi-check openapi-precision-check meta-check docs-check deploy-check sdk-check demo-check local-ci-simulation-check black-box-demo-check benchmark-check package-viewer-check restore-rehearsal-check fast-check finalize release-acceptance release-check production-check release-candidate-check public-release-verify migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean help: ## Show help @awk 'BEGIN {FS=":.*## "}; /^[a-zA-Z0-9_.-]+:.*## / { printf " %-18s %s\n", $$1, $$2 }' $(MAKEFILE_LIST) @@ -256,6 +256,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'SBOM inventory tools' docs/commercial/category-comparison.md >/dev/null @grep -F 'Trust centers' docs/commercial/category-comparison.md >/dev/null @grep -F 'release upload-evidence' docs/how-to/integrate-ci.md >/dev/null + @grep -F 'make local-ci-simulation-check' docs/how-to/integrate-ci.md examples/end-to-end-release-evidence/README.md >/dev/null @grep -F -- '--dry-run' docs/how-to/integrate-ci.md >/dev/null @grep -F 'upload validate-manifest' docs/how-to/integrate-ci.md >/dev/null @grep -F 'evydence-upload-manifest.v1.0.0' docs/reference/upload-manifest.md schemas/upload-manifest.v1.schema.json >/dev/null @@ -345,6 +346,7 @@ sdk-check: ## Validate SDK helper and generated route-catalog coverage against O demo-check: ## Validate checked end-to-end evidence demo fixtures @test -x examples/end-to-end-release-evidence/run-local-demo.sh + @test -x scripts/local_ci_simulation_check.sh @test -f examples/end-to-end-release-evidence/README.md @test -f examples/end-to-end-release-evidence/release-evidence-manifest.json @test -f examples/end-to-end-release-evidence/sample-readiness-report.json @@ -365,6 +367,9 @@ demo-check: ## Validate checked end-to-end evidence demo fixtures @grep -F 'escalation_path' examples/end-to-end-release-evidence/sample-customer-package-manifest.json >/dev/null @grep -F 'sbom_component_purl' examples/end-to-end-release-evidence/sample-customer-package-manifest.json >/dev/null +local-ci-simulation-check: ## Run local one-command CI evidence simulation without external services + @scripts/local_ci_simulation_check.sh + black-box-demo-check: ## Run live PostgreSQL black-box API/worker demo; requires EVYDENCE_TEST_DATABASE_URL @scripts/black_box_demo_check.sh diff --git a/docs/how-to/integrate-ci.md b/docs/how-to/integrate-ci.md index 0fbe169..c06e7e5 100644 --- a/docs/how-to/integrate-ci.md +++ b/docs/how-to/integrate-ci.md @@ -180,6 +180,25 @@ go run ./cmd/evydence upload validate-manifest \ The manifest schema and supported request kinds are documented in [Upload manifest](../reference/upload-manifest.md). +## Local CI Simulation + +Run the checked local simulation before copying the workflow into another +repository: + +```sh +make local-ci-simulation-check +``` + +The target starts a local in-process Evydence API on a random loopback port, +creates non-sensitive product, project, release, and artifact records, uploads +GitHub Actions-style build provenance with a structural DSSE/in-toto +attestation, generates the same upload manifest shape used by the quickstart, +runs `evydence ci preflight`, uploads SBOM and vulnerability scan fixtures, +creates a customer package, and verifies release-readiness and audit-chain +outputs. All generated files are written under `tmp/local-ci-simulation/` during +the run and removed afterward unless `EVYDENCE_LOCAL_CI_KEEP_ARTIFACTS=1` is +set. + The full workflow also shows a scanner handoff path: - produce CycloneDX JSON with `syft`; diff --git a/examples/end-to-end-release-evidence/README.md b/examples/end-to-end-release-evidence/README.md index 3014e71..2698db8 100644 --- a/examples/end-to-end-release-evidence/README.md +++ b/examples/end-to-end-release-evidence/README.md @@ -84,6 +84,18 @@ vulnerability decision, release bundle, redaction profile, customer package, readiness report, and audit-chain verification output. It expects a local API that already has a tenant and scoped API key. +To exercise the GitHub Actions-style CI path without external services, run: + +```sh +make local-ci-simulation-check +``` + +That checked target starts a temporary loopback API, creates the required +product, project, release, and artifact IDs, uploads build provenance and a +structural DSSE/in-toto attestation, runs `evydence ci preflight`, uploads the +manifest, and verifies readiness, customer-package, and audit-chain outputs +under `tmp/local-ci-simulation/`. + ## Inspect The Result The generated files under `tmp/end-to-end-release-evidence/` map the buyer diff --git a/internal/app/ledger.go b/internal/app/ledger.go index 82ef9ef..58aa02d 100644 --- a/internal/app/ledger.go +++ b/internal/app/ledger.go @@ -889,6 +889,7 @@ func (s releaseEvidenceService) UploadSBOM(ctx context.Context, actor domain.Act BOMFormat string `json:"bomFormat"` SpecVersion string `json:"specVersion"` Components []struct { + Type string `json:"type"` Name string `json:"name"` Version string `json:"version"` PURL string `json:"purl"` diff --git a/internal/app/ledger_test.go b/internal/app/ledger_test.go index 8b09e57..3c95c06 100644 --- a/internal/app/ledger_test.go +++ b/internal/app/ledger_test.go @@ -124,7 +124,7 @@ func TestUploadSBOMEnqueuesParserVersion(t *testing.T) { if err != nil { t.Fatalf("artifact: %v", err) } - if _, err := ledger.UploadSBOM(ctx, actor, release.ID, artifact.ID, []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","components":[{"name":"api"}]}`)); err != nil { + if _, err := ledger.UploadSBOM(ctx, actor, release.ID, artifact.ID, []byte(`{"bomFormat":"CycloneDX","specVersion":"1.6","components":[{"type":"application","name":"api"}]}`)); err != nil { t.Fatalf("upload sbom: %v", err) } if len(outbox.jobs) != 1 { diff --git a/scripts/local_ci_simulation_check.sh b/scripts/local_ci_simulation_check.sh new file mode 100755 index 0000000..c5f6a0f --- /dev/null +++ b/scripts/local_ci_simulation_check.sh @@ -0,0 +1,235 @@ +#!/usr/bin/env sh +set -eu + +repo_root="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)" +cd "$repo_root" + +for tool in curl go jq python3; do + if ! command -v "$tool" >/dev/null 2>&1; then + printf '%s\n' "local-ci-simulation-check: missing required tool: $tool" >&2 + exit 2 + fi +done + +workdir="${EVYDENCE_LOCAL_CI_SIMULATION_DIR:-tmp/local-ci-simulation}" +api_pid="" + +cleanup() { + if [ -n "$api_pid" ] && kill -0 "$api_pid" >/dev/null 2>&1; then + kill "$api_pid" >/dev/null 2>&1 || true + wait "$api_pid" >/dev/null 2>&1 || true + fi + if [ "${EVYDENCE_LOCAL_CI_KEEP_ARTIFACTS:-}" != "1" ]; then + rm -rf "$workdir" + fi +} +trap cleanup EXIT INT TERM + +rm -rf "$workdir" +mkdir -p "$workdir/.evydence" + +port="$(python3 - <<'PY' +import socket + +with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: + sock.bind(("127.0.0.1", 0)) + print(sock.getsockname()[1]) +PY +)" +api_url="http://127.0.0.1:$port" + +go build -o "$workdir/evydence-api" ./cmd/evydence-api +go build -o "$workdir/evydence" ./cmd/evydence + +EVYDENCE_ADDR="127.0.0.1:$port" \ +EVYDENCE_API_KEY_PEPPER="local-ci-simulation-pepper" \ +EVYDENCE_BOOTSTRAP_TENANT="Local CI Simulation Tenant" \ +EVYDENCE_PRINT_BOOTSTRAP_SECRET=true \ +"$workdir/evydence-api" >"$workdir/api.stdout" 2>"$workdir/api.stderr" & +api_pid="$!" + +for _ in $(seq 1 80); do + if curl -fsS "$api_url/v1/ready" >/dev/null 2>&1; then + break + fi + if ! kill -0 "$api_pid" >/dev/null 2>&1; then + printf '%s\n' "local-ci-simulation-check: API process exited during startup" >&2 + sed -n '1,120p' "$workdir/api.stderr" >&2 || true + exit 1 + fi + sleep 0.25 +done + +if ! curl -fsS "$api_url/v1/ready" >/dev/null 2>&1; then + printf '%s\n' "local-ci-simulation-check: API did not become ready" >&2 + sed -n '1,120p' "$workdir/api.stderr" >&2 || true + exit 1 +fi + +if ! api_key="$(jq -er '.secret' "$workdir/api.stdout")"; then + : >"$workdir/api.stdout" + printf '%s\n' "local-ci-simulation-check: bootstrap secret output was not parseable" >&2 + exit 1 +fi +: >"$workdir/api.stdout" + +api() { + method="$1" + path="$2" + idem="$3" + body="$4" + if [ "$method" = "GET" ]; then + curl -fsS "${api_url}${path}" \ + -H "Authorization: Bearer ${api_key}" + else + curl -fsS -X "$method" "${api_url}${path}" \ + -H "Authorization: Bearer ${api_key}" \ + -H "Idempotency-Key: ${idem}" \ + -H "Content-Type: application/json" \ + --data "$body" + fi +} + +product="$(api POST /v1/products local-ci-product '{"name":"Local CI Product","slug":"local-ci-product"}')" +printf '%s\n' "$product" >"$workdir/product.json" +product_id="$(printf '%s' "$product" | jq -er '.data.id')" + +project_payload="$(jq -cn --arg product_id "$product_id" '{product_id:$product_id,name:"api"}')" +project="$(api POST /v1/projects local-ci-project "$project_payload")" +printf '%s\n' "$project" >"$workdir/project.json" +project_id="$(printf '%s' "$project" | jq -er '.data.id')" + +release_payload="$(jq -cn --arg product_id "$product_id" '{product_id:$product_id,version:"1.0.0-local-ci"}')" +release="$(api POST /v1/releases local-ci-release "$release_payload")" +printf '%s\n' "$release" >"$workdir/release.json" +release_id="$(printf '%s' "$release" | jq -er '.data.id')" + +artifact_digest="$("$workdir/evydence" hash "$workdir/evydence")" +artifact_size="$(wc -c <"$workdir/evydence" | tr -d ' ')" +artifact_payload="$(jq -cn --arg digest "$artifact_digest" --argjson size "$artifact_size" '{name:"evydence-cli",media_type:"application/octet-stream",digest:$digest,size:$size}')" +artifact="$(api POST /v1/artifacts local-ci-artifact "$artifact_payload")" +printf '%s\n' "$artifact" >"$workdir/artifact.json" +artifact_id="$(printf '%s' "$artifact" | jq -er '.data.id')" + +cat >"$workdir/.evydence/sbom.cdx.json" <"$workdir/.evydence/grype.json" <"$workdir/upload-build.stdout" + +python3 scripts/github_release_evidence_manifest.py \ + --out "$workdir/.evydence/upload-manifest.json" \ + --release-id "$release_id" \ + --artifact-id "$artifact_id" \ + --target-ref "pkg:github/aatuh/evydence@0123456789abcdef0123456789abcdef01234567" \ + --idempotency-prefix "local-ci-1001-1" \ + --cyclonedx-sbom "$workdir/.evydence/sbom.cdx.json" \ + --grype-json "$workdir/.evydence/grype.json" \ + --include-release-bundle + +"$workdir/evydence" upload validate-manifest \ + --manifest "$workdir/.evydence/upload-manifest.json" \ + >"$workdir/validate-manifest.stdout" + +"$workdir/evydence" ci preflight \ + --url "$api_url" \ + --api-key "$api_key" \ + --product-id "$product_id" \ + --project-id "$project_id" \ + --release-id "$release_id" \ + --artifact-id "$artifact_id" \ + --manifest "$workdir/.evydence/upload-manifest.json" \ + >"$workdir/preflight.stdout" + +"$workdir/evydence" upload manifest \ + --url "$api_url" \ + --api-key "$api_key" \ + --manifest "$workdir/.evydence/upload-manifest.json" \ + >"$workdir/upload-manifest.stdout" + +profile_payload='{"preset":"customer_safe"}' +profile="$(api POST /v1/redaction-profiles local-ci-redaction-profile "$profile_payload")" +printf '%s\n' "$profile" >"$workdir/redaction-profile.json" +profile_id="$(printf '%s' "$profile" | jq -er '.data.id')" + +package_payload="$(jq -cn --arg product_id "$product_id" --arg release_id "$release_id" --arg profile_id "$profile_id" '{product_id:$product_id,release_id:$release_id,redaction_profile_id:$profile_id,title:"Local CI release evidence",expires_at:"2026-06-30T00:00:00Z"}')" +package="$(api POST /v1/customer-packages local-ci-customer-package "$package_payload")" +printf '%s\n' "$package" >"$workdir/customer-package.json" +jq -e '.data.id and .data.manifest.limitations and .data.manifest.non_claims' "$workdir/customer-package.json" >/dev/null + +readiness="$(api GET "/v1/reports/release-readiness?release_id=${release_id}" "" "")" +printf '%s\n' "$readiness" >"$workdir/release-readiness.json" +jq -e --arg release_id "$release_id" '.data.release_id == $release_id and .data.result == "passed"' "$workdir/release-readiness.json" >/dev/null + +audit="$(api GET /v1/audit-chain/verify "" "")" +printf '%s\n' "$audit" >"$workdir/audit-chain-verification.json" +jq -e '.data.result == "passed"' "$workdir/audit-chain-verification.json" >/dev/null + +if find "$workdir" -type f \( -name '*.json' -o -name '*.stdout' -o -name '*.stderr' \) -exec grep -I -l 'evy_' {} + | grep -q .; then + printf '%s\n' "local-ci-simulation-check: generated artifacts leaked an API key-like secret" >&2 + exit 1 +fi + +printf '%s\n' "local-ci-simulation-check: local CI preflight, upload, readiness, package, and audit-chain flow passed" From 8e075d5d599d135759da60e1e0d2d2ec2f34f1fa Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 17:51:43 +0300 Subject: [PATCH 232/287] ci(container): scope image signing permissions --- .github/workflows/container-image.yml | 56 ++++++++++++++++++++++++++- .productization_next_steps_missing.md | 7 +++- RELEASE_EVIDENCE.md | 5 ++- docs/reference/release-candidate.md | 7 ++-- docs/reference/release-validation.md | 5 ++- 5 files changed, 70 insertions(+), 10 deletions(-) diff --git a/.github/workflows/container-image.yml b/.github/workflows/container-image.yml index f85b2e8..34d3931 100644 --- a/.github/workflows/container-image.yml +++ b/.github/workflows/container-image.yml @@ -14,12 +14,18 @@ on: permissions: contents: read - id-token: write jobs: publish-image: - name: Publish Container Image + name: Build And Push Container Image runs-on: ubuntu-latest + permissions: + contents: read + outputs: + image: ${{ steps.image.outputs.image }} + digest: ${{ steps.image.outputs.digest }} + commit: ${{ steps.image.outputs.commit }} + created: ${{ steps.image.outputs.created }} steps: - name: Check out repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -61,6 +67,7 @@ jobs: printf '%s' "${EVYDENCE_GHCR_PUBLISH_TOKEN}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin - name: Build and push image + id: image shell: bash run: | set -euo pipefail @@ -87,6 +94,44 @@ jobs: COMMIT=$commit CREATED=$created EOF + { + echo "image=$image" + echo "digest=$digest" + echo "commit=$commit" + echo "created=$created" + } >> "$GITHUB_OUTPUT" + + sign-image: + name: Sign Container Image And Upload Evidence + runs-on: ubuntu-latest + needs: publish-image + permissions: + contents: read + id-token: write + steps: + - name: Check out repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: ${{ github.event.inputs.ref }} + persist-credentials: false + + - name: Set up Go + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.1.0 + with: + go-version-file: go.mod + cache: true + + - name: Log in to GitHub Container Registry for signing + env: + EVYDENCE_GHCR_PUBLISH_TOKEN: ${{ secrets.EVYDENCE_GHCR_PUBLISH_TOKEN }} + shell: bash + run: | + set -euo pipefail + if [[ -z "${EVYDENCE_GHCR_PUBLISH_TOKEN}" ]]; then + echo "EVYDENCE_GHCR_PUBLISH_TOKEN secret is required to sign container images" >&2 + exit 2 + fi + printf '%s' "${EVYDENCE_GHCR_PUBLISH_TOKEN}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin - name: Install cosign shell: bash @@ -99,6 +144,13 @@ jobs: shell: bash run: | set -euo pipefail + mkdir -p tmp/container-image + cat > tmp/container-image/image.env </`. GitHub release and GHCR publication use explicit repository secrets instead of broad `GITHUB_TOKEN` write permissions: `EVYDENCE_RELEASE_PUBLISH_TOKEN` for draft release publication and `EVYDENCE_GHCR_PUBLISH_TOKEN` for container image -publication. Those secrets are external repository settings and are not release -evidence artifacts. +publication. The container signing job is the only container-image job with +`id-token: write` for keyless cosign signing. Those secrets are external +repository settings and are not release evidence artifacts. Release-candidate tagging is documented in [`docs/reference/release-candidate.md`](docs/reference/release-candidate.md). diff --git a/docs/reference/release-candidate.md b/docs/reference/release-candidate.md index d6639ee..7348089 100644 --- a/docs/reference/release-candidate.md +++ b/docs/reference/release-candidate.md @@ -83,9 +83,10 @@ Creating or updating the draft GitHub release requires the `EVYDENCE_RELEASE_PUBLISH_TOKEN` secret with only the release-publication scope the maintainer account approves for that workflow. The container image workflow also keeps `GITHUB_TOKEN` from receiving package-write permissions; publishing -to GHCR requires `EVYDENCE_GHCR_PUBLISH_TOKEN`. Both secrets are external -repository settings and must not be printed in logs, committed to files, or -included in release evidence. +to GHCR requires `EVYDENCE_GHCR_PUBLISH_TOKEN`, and only the separate signing +job receives `id-token: write` for keyless cosign signing. Both secrets are +external repository settings and must not be printed in logs, committed to +files, or included in release evidence. ## Deployment Constraints diff --git a/docs/reference/release-validation.md b/docs/reference/release-validation.md index 20e637b..f9d1b40 100644 --- a/docs/reference/release-validation.md +++ b/docs/reference/release-validation.md @@ -179,8 +179,9 @@ verified. Manual runs can upload only the workflow artifact unless The container image workflow similarly keeps `GITHUB_TOKEN` from receiving package-write permissions. GHCR publication requires `EVYDENCE_GHCR_PUBLISH_TOKEN`; keyless image signing still requires GitHub OIDC -through `id-token: write`. These secrets are repository settings, not release -evidence artifacts, and must not be logged or committed. +through `id-token: write`, but that permission is scoped to the image-signing +job rather than the build/push job. These secrets are repository settings, not +release evidence artifacts, and must not be logged or committed. The canonical artifact map is [Release evidence index](release-evidence-index.md). Keep that page aligned From 04b060fd344566aefb25313c10c59ee08fd794ac Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 17:54:19 +0300 Subject: [PATCH 233/287] ci(release): split publishing permissions --- .github/workflows/release-artifacts.yml | 22 +++++++++++++++++++--- .productization_next_steps_missing.md | 10 ++++++++-- Makefile | 1 + RELEASE_EVIDENCE.md | 10 +++++----- docs/reference/release-candidate.md | 5 +++-- docs/reference/release-validation.md | 21 ++++++++++++--------- scripts/release_acceptance.sh | 1 + 7 files changed, 49 insertions(+), 21 deletions(-) diff --git a/.github/workflows/release-artifacts.yml b/.github/workflows/release-artifacts.yml index 79859ba..574635b 100644 --- a/.github/workflows/release-artifacts.yml +++ b/.github/workflows/release-artifacts.yml @@ -23,6 +23,10 @@ jobs: package: name: Package Signed Release Artifacts runs-on: ubuntu-latest + permissions: + contents: read + outputs: + tag: ${{ steps.release.outputs.tag }} services: postgres: image: postgres:16-alpine@sha256:16bc17c64a573ef34162af9298258d1aec548232985b33ed7b1eac33ba35c229 @@ -98,8 +102,21 @@ jobs: path: dist/${{ steps.release.outputs.tag }}/ if-no-files-found: error + publish-draft-release: + name: Publish Draft GitHub Release + runs-on: ubuntu-latest + needs: package + if: github.event_name == 'push' || github.event.inputs.upload_draft_release == 'true' + permissions: + contents: read + steps: + - name: Download packaged release evidence + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: evydence-release-artifacts-${{ needs.package.outputs.tag }} + path: dist/${{ needs.package.outputs.tag }}/ + - name: Require release publishing token - if: github.event_name == 'push' || github.event.inputs.upload_draft_release == 'true' env: EVYDENCE_RELEASE_PUBLISH_TOKEN: ${{ secrets.EVYDENCE_RELEASE_PUBLISH_TOKEN }} shell: bash @@ -111,13 +128,12 @@ jobs: fi - name: Create or update draft GitHub release - if: github.event_name == 'push' || github.event.inputs.upload_draft_release == 'true' env: GH_TOKEN: ${{ secrets.EVYDENCE_RELEASE_PUBLISH_TOKEN }} shell: bash run: | set -euo pipefail - tag="${{ steps.release.outputs.tag }}" + tag="${{ needs.package.outputs.tag }}" if gh release view "${tag}" >/dev/null 2>&1; then gh release upload "${tag}" dist/${tag}/* --clobber else diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index 974a623..1b7955e 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -42,7 +42,7 @@ Implementation rules: - Keep tenant isolation, append-only evidence, safe redaction, release evidence integrity, and non-claim language intact. -## Epic E1 - Close Public Trust And Release-Integrity Gaps [ ] +## Epic E1 - Close Public Trust And Release-Integrity Gaps [x] Description: Remove the highest-impact public trust issues that prevent the repository from cleanly exceeding the production-readiness score target. @@ -71,7 +71,7 @@ uses `EVYDENCE_GHCR_PUBLISH_TOKEN` for GHCR publication, and scopes `id-token: write` to the signing job. Live workflow execution and alert closure remain external repository-state verification. -### Ticket E1-T2 - Split release packaging from release publishing permissions [ ] +### Ticket E1-T2 - Split release packaging from release publishing permissions [x] Description: Refactor `.github/workflows/release-artifacts.yml` so package generation and validation run read-only, while draft-release creation/upload is @@ -93,6 +93,12 @@ Implementation rules: - Verify the related Scorecard code-scanning alert closes or document a remaining external requirement. +Repo-local status: complete. Release package generation and draft-release +publication are separate jobs, both keep `GITHUB_TOKEN` read-only, and draft +publication uses `EVYDENCE_RELEASE_PUBLISH_TOKEN` only in the publication job. +Live workflow execution and any alert closure remain external repository-state +verification. + ### Ticket E1-T3 - Make coverage gate behavior deterministic [x] Description: Fix the mismatch where public CI `make production-check` passes diff --git a/Makefile b/Makefile index 95dd69c..d4c8124 100644 --- a/Makefile +++ b/Makefile @@ -275,6 +275,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'EVYDENCE_RELEASE_SIGNING_PRIVATE_KEY_B64' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'EVYDENCE_RELEASE_PUBLISH_TOKEN' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'scripts/release_candidate_package.sh' .github/workflows/release-artifacts.yml >/dev/null + @grep -F 'actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'evydence-release-manifest.sig.json' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'evydence-release-manifest.sig alias' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'gh release create' .github/workflows/release-artifacts.yml >/dev/null diff --git a/RELEASE_EVIDENCE.md b/RELEASE_EVIDENCE.md index 6361478..1ced505 100644 --- a/RELEASE_EVIDENCE.md +++ b/RELEASE_EVIDENCE.md @@ -35,11 +35,11 @@ migration checksums, coverage output, release-check summary, checked release notes, a signed release manifest, and a manifest signature under `dist//`. GitHub release and GHCR publication use explicit repository secrets instead of -broad `GITHUB_TOKEN` write permissions: `EVYDENCE_RELEASE_PUBLISH_TOKEN` for -draft release publication and `EVYDENCE_GHCR_PUBLISH_TOKEN` for container image -publication. The container signing job is the only container-image job with -`id-token: write` for keyless cosign signing. Those secrets are external -repository settings and are not release evidence artifacts. +broad `GITHUB_TOKEN` write permissions: `EVYDENCE_RELEASE_PUBLISH_TOKEN` for the +separate draft-release publication job and `EVYDENCE_GHCR_PUBLISH_TOKEN` for +container image publication. The container signing job is the only +container-image job with `id-token: write` for keyless cosign signing. Those +secrets are external repository settings and are not release evidence artifacts. Release-candidate tagging is documented in [`docs/reference/release-candidate.md`](docs/reference/release-candidate.md). diff --git a/docs/reference/release-candidate.md b/docs/reference/release-candidate.md index 7348089..a436c21 100644 --- a/docs/reference/release-candidate.md +++ b/docs/reference/release-candidate.md @@ -78,8 +78,9 @@ evidence, and record that image digest with deployment evidence. If no image workflow evidence exists for a tag, operators must build and publish images into their own registry for Helm or air-gapped deployment flows. -The release packaging workflow keeps the repository `GITHUB_TOKEN` read-only. -Creating or updating the draft GitHub release requires the +The release packaging workflow keeps the repository `GITHUB_TOKEN` read-only and +separates package generation from draft-release publication. Creating or +updating the draft GitHub release happens in a separate job and requires the `EVYDENCE_RELEASE_PUBLISH_TOKEN` secret with only the release-publication scope the maintainer account approves for that workflow. The container image workflow also keeps `GITHUB_TOKEN` from receiving package-write permissions; publishing diff --git a/docs/reference/release-validation.md b/docs/reference/release-validation.md index f9d1b40..1147706 100644 --- a/docs/reference/release-validation.md +++ b/docs/reference/release-validation.md @@ -140,10 +140,14 @@ published through GitHub code scanning when that service is available. ## Signed Release Artifact Workflow The checked-in `.github/workflows/release-artifacts.yml` workflow calls the -same release-candidate package script used locally. It packages self-contained -release archives for the CLI, API, worker, and migration commands on Linux, -macOS, and Windows targets. The script runs `make production-check` against -disposable PostgreSQL before building artifacts. +same release-candidate package script used locally. The package job has +read-only `GITHUB_TOKEN` permissions and the release signing secret only; the +separate draft-release publication job downloads the packaged evidence artifact +and uses `EVYDENCE_RELEASE_PUBLISH_TOKEN` only when publishing is explicitly +enabled or a release tag is pushed. It packages self-contained release archives +for the CLI, API, worker, and migration commands on Linux, macOS, and Windows +targets. The script runs `make production-check` against disposable PostgreSQL +before building artifacts. The workflow requires this repository secret: @@ -168,11 +172,10 @@ checksums, `coverage.out`, `release-check-summary.txt`, checked release notes, release SBOM/provenance metadata, the Scorecard-compatible in-toto provenance statement, the release manifest, and the manifest signature. Tag pushes create or update a draft GitHub release only when the external -`EVYDENCE_RELEASE_PUBLISH_TOKEN` secret is configured. The packaging job keeps -the repository `GITHUB_TOKEN` read-only; the publish token should be a -maintainer-controlled fine-grained token or GitHub App token with the minimum -release-publication scope needed for the repository. Maintainers publish a draft -as a prerelease only after the workflow artifact and release assets are +`EVYDENCE_RELEASE_PUBLISH_TOKEN` secret is configured. The publish token should +be a maintainer-controlled fine-grained token or GitHub App token with the +minimum release-publication scope needed for the repository. Maintainers publish +a draft as a prerelease only after the workflow artifact and release assets are verified. Manual runs can upload only the workflow artifact unless `upload_draft_release` is enabled. diff --git a/scripts/release_acceptance.sh b/scripts/release_acceptance.sh index f2d7580..4d7a12f 100755 --- a/scripts/release_acceptance.sh +++ b/scripts/release_acceptance.sh @@ -81,6 +81,7 @@ require_text .github/workflows/codeql.yml "security-and-quality" require_text .github/workflows/ci.yml "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" require_text .github/workflows/release-artifacts.yml "contents: read" require_text .github/workflows/release-artifacts.yml "EVYDENCE_RELEASE_PUBLISH_TOKEN" +require_text .github/workflows/release-artifacts.yml "actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c" if grep -F "contents: write" .github/workflows/release-artifacts.yml >/dev/null; then printf '%s\n' "release-acceptance: release artifact workflow must not grant GITHUB_TOKEN contents: write" >&2 exit 2 From ce7dc736840157e44573231df2d06489ca0174f6 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 17:55:30 +0300 Subject: [PATCH 234/287] docs(production): refresh exit review --- .productization_next_steps_missing.md | 2 +- docs/reference/production-exit-review.md | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index 1b7955e..39b745b 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -406,7 +406,7 @@ Implementation rules: Description: Keep production positioning honest while closing repo-local hardening that affects controlled self-hosted adoption. -### Ticket E6-T1 - Refresh production exit review after trust fixes [ ] +### Ticket E6-T1 - Refresh production exit review after trust fixes [x] Description: Update `docs/reference/production-exit-review.md` after release workflow token-permission and coverage-gate fixes land. diff --git a/docs/reference/production-exit-review.md b/docs/reference/production-exit-review.md index 474172e..ffd9e58 100644 --- a/docs/reference/production-exit-review.md +++ b/docs/reference/production-exit-review.md @@ -12,10 +12,13 @@ SaaS-ready, legally compliant, certified, or secure-release-guaranteed. ## Repo-Verified Strengths -- API contract has 171 precise `/v1` operations and zero broad operations. +- API contract has 183 precise `/v1` operations and zero broad operations. - `make production-check` is available and requires live PostgreSQL, coverage, migration compatibility, release validation, race tests, security scans, and release-signing smoke checks. +- `make coverage-check` now fails early without `EVYDENCE_TEST_DATABASE_URL` so + local no-database coverage cannot be mistaken for production release + evidence. - Production API startup rejects in-process state, default pepper, unsupported writer modes, writer replicas above one, local plaintext signing-key mode, and bootstrap secret printing. @@ -32,6 +35,15 @@ SaaS-ready, legally compliant, certified, or secure-release-guaranteed. templates, Dependabot, and Scorecard workflow files exist. - CODEOWNERS and the maintainer review policy document expected review ownership for high-risk code, release, deployment, and public-claim surfaces. +- The release-artifacts workflow keeps `GITHUB_TOKEN` read-only and separates + signed package generation from draft GitHub release publication. Draft + publication uses `EVYDENCE_RELEASE_PUBLISH_TOKEN` only in the publication job. +- The container-image workflow keeps `GITHUB_TOKEN` read-only, uses + `EVYDENCE_GHCR_PUBLISH_TOKEN` for GHCR publication, and scopes GitHub OIDC + `id-token: write` to the keyless cosign signing job. +- `make release-acceptance` and + `make public-release-verify TAG=v0.1.0-rc.5` have passed against the current + repository state. ## Remaining Exit Blockers @@ -40,6 +52,10 @@ SaaS-ready, legally compliant, certified, or secure-release-guaranteed. plus cosign evidence. Operators who mirror or rebuild images for Helm or air-gapped workflows must record their own image digest and verification evidence. +- GitHub private vulnerability reporting, secret scanning, branch protection, + Scorecard alert closure, and workflow execution history are external + repository-state checks. They remain required before changing the public + status beyond a controlled self-hosted production candidate. - Native PKCS#11/HSM module custody requires operator hardware, drivers, and provider-specific validation. - Broad WORM/object-lock proof requires object-store policy, IAM, lifecycle, From a5d336ca1e96ab610fa8b78465302f7ba59dc5b6 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 17:57:01 +0300 Subject: [PATCH 235/287] docs(production): add external controls matrix --- .productization_next_steps_missing.md | 2 +- Makefile | 3 ++ docs/README.md | 1 + docs/how-to/pilot-deployment-checklist.md | 5 ++- docs/kubernetes.md | 3 ++ docs/reference/external-controls-matrix.md | 36 ++++++++++++++++++++++ docs/reference/production-readiness.md | 4 +++ 7 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 docs/reference/external-controls-matrix.md diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index 39b745b..27c3881 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -418,7 +418,7 @@ Implementation rules: - Cite current release, CI, CodeQL, Scorecard, and production-check evidence. - Run `make docs-check` and `make release-acceptance`. -### Ticket E6-T2 - Add external controls matrix for regulated deployments [ ] +### Ticket E6-T2 - Add external controls matrix for regulated deployments [x] Description: Add a concise matrix of external controls required for regulated or high-trust deployments, including KMS/HSM, WORM/object lock, TLS, identity diff --git a/Makefile b/Makefile index d4c8124..acb1d6d 100644 --- a/Makefile +++ b/Makefile @@ -143,6 +143,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @test -f docs/reference/benchmark-results.md @test -f docs/reference/production-readiness.md @test -f docs/reference/production-exit-review.md + @test -f docs/reference/external-controls-matrix.md @test -f docs/reference/release-candidate.md @test -f docs/reference/release-evidence-index.md @test -f docs/reference/release-notes-template.md @@ -186,6 +187,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod "reference/benchmark-results.md" \ "reference/production-readiness.md" \ "reference/production-exit-review.md" \ + "reference/external-controls-matrix.md" \ "reference/release-candidate.md" \ "reference/release-evidence-index.md" \ "reference/release-notes-template.md" \ @@ -242,6 +244,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'make restore-rehearsal-check' docs/runbooks/backup-restore.md >/dev/null @test -f docs/how-to/pilot-deployment-checklist.md @grep -F 'Required: external PostgreSQL' docs/how-to/pilot-deployment-checklist.md >/dev/null + @grep -F 'external controls matrix' docs/reference/production-readiness.md docs/kubernetes.md docs/how-to/pilot-deployment-checklist.md >/dev/null @grep -F 'Required: object paths are tenant-prefixed' docs/how-to/pilot-deployment-checklist.md >/dev/null @grep -F 'Required: public API access is behind TLS' docs/how-to/pilot-deployment-checklist.md >/dev/null @test -f docs/commercial/design-partner-pilot.md diff --git a/docs/README.md b/docs/README.md index 5124062..7ef05a0 100644 --- a/docs/README.md +++ b/docs/README.md @@ -37,6 +37,7 @@ This documentation is organized by reader task. Implementation claims should be - [Benchmark results](reference/benchmark-results.md): current local benchmark command and interpretation. - [Production readiness](reference/production-readiness.md): self-hosted production profiles, production gates, and exit criteria. - [Production exit review](reference/production-exit-review.md): current release-positioning decision and unresolved blockers. +- [External controls matrix](reference/external-controls-matrix.md): owner boundaries for regulated or high-trust self-hosted deployments. - [Release candidate checklist](reference/release-candidate.md): required evidence before tagging a controlled self-hosted release candidate. - [Release evidence index](reference/release-evidence-index.md): release artifact map, generation commands, and verification commands. - [Release notes template](reference/release-notes-template.md): checked wording used by release-candidate packaging when a tag-specific note file is absent. diff --git a/docs/how-to/pilot-deployment-checklist.md b/docs/how-to/pilot-deployment-checklist.md index 106a413..414cde7 100644 --- a/docs/how-to/pilot-deployment-checklist.md +++ b/docs/how-to/pilot-deployment-checklist.md @@ -10,6 +10,10 @@ record. The checklist supports deployment readiness review only. It is not legal compliance proof, certification, complete SBOM proof, authoritative scanner coverage, auditor acceptance, or a secure-release guarantee. +Use the [external controls matrix](../reference/external-controls-matrix.md) to +assign repo-owned, operator-owned, provider-owned, and legal/review-owned +controls before accepting pilot traffic. + ## Required Before Pilot Traffic ### Environment @@ -137,4 +141,3 @@ Record final decision: - [ ] Go - [ ] No-go - [ ] Go with documented limitations: - diff --git a/docs/kubernetes.md b/docs/kubernetes.md index a3f8d2b..af6d4e0 100644 --- a/docs/kubernetes.md +++ b/docs/kubernetes.md @@ -20,6 +20,9 @@ The Helm chart lives at `deploy/helm/evydence`. It deploys the API, worker, serv profile documented in the configuration reference. The chart does not create databases, buckets, KMS keys, or secrets. +Use the [external controls matrix](reference/external-controls-matrix.md) to +track which of those production controls are repo-owned, operator-owned, +provider-owned, or legal/review-owned for the deployment. ## Create Secrets diff --git a/docs/reference/external-controls-matrix.md b/docs/reference/external-controls-matrix.md new file mode 100644 index 0000000..3e68451 --- /dev/null +++ b/docs/reference/external-controls-matrix.md @@ -0,0 +1,36 @@ +# External Controls Matrix + +This reference separates what Evydence implements from what operators, +providers, and reviewers must configure or assess for regulated or high-trust +self-hosted deployments. It supports readiness review only. It is not legal +compliance proof, certification, complete SBOM proof, authoritative +vulnerability coverage, auditor acceptance, or a secure-release guarantee. + +Owner labels: + +- `repo-owned`: implemented, documented, or checked by this repository. +- `operator-owned`: deployment team must configure, run, or retain evidence. +- `provider-owned`: cloud, identity, registry, KMS, storage, or CI provider + supplies the authoritative control surface. +- `legal/review-owned`: counsel, auditor, customer, or internal risk owner must + review suitability. + +| Control area | Primary owner | Evydence repo evidence | External evidence required | +| --- | --- | --- | --- | +| PostgreSQL durability | operator-owned | Production startup requires `EVYDENCE_DATABASE_URL`; migrations and restore rehearsals are checked by project gates. | Backup schedule, retention, restore test logs, access controls, encryption settings, and target RPO/RTO acceptance. | +| Object storage durability | operator-owned/provider-owned | S3/MinIO adapter, tenant-prefixed object keys, object digest checks, and object-lock receipt records where configured. | Bucket policy, versioning, lifecycle, replication, encryption, retention, object-lock/WORM configuration, and provider audit output. | +| KMS/HSM signing custody | operator-owned/provider-owned | Signing executor ports, AWS KMS, GCP KMS, Azure Key Vault, HTTPS signing gateway, and custody review records. | Key policy, hardware or service custody proof, rotation procedure, break-glass procedure, provider logs, and role separation review. | +| TLS and network exposure | operator-owned/provider-owned | Helm/Compose docs require external TLS and protected diagnostics. | Ingress/TLS config, certificate lifecycle, firewall rules, private network boundaries, and authenticated metrics/admin access proof. | +| Identity provider and SSO | operator-owned/provider-owned | OIDC/SAML trust material records, local assertion/token verification, session records, and audit entries. | Provider tenant config, issuer/audience ownership, MFA policy, group lifecycle, disabled-user sync, and provider availability evidence. | +| CI provider provenance | operator-owned/provider-owned | GitHub Actions build metadata, structural DSSE/in-toto/SLSA parsing, collector keys, and CI upload examples. | Branch protection, required workflow policy, runner trust, OIDC token policy where used, protected environments, and provider audit logs. | +| Container registry trust | operator-owned/provider-owned | Optional maintainer GHCR workflow, image digest evidence, cosign verification output, and release evidence index. | Registry access policy, image admission policy, mirror/rebuild evidence, vulnerability scan evidence, and deployed immutable digest records. | +| Backup and restore operations | operator-owned | Backup/restore runbook and repository-owned restore rehearsal checks. | Deployment-specific restore rehearsal, credential recovery procedure, object/database consistency checks, and escalation ownership. | +| Monitoring and alerting | operator-owned/provider-owned | Safe metrics, readiness endpoints, starter Prometheus rules, and dashboard assets. | Scrape authentication, alert routing, on-call schedule, log retention, incident escalation, and dashboard review for the deployment. | +| Incident response | operator-owned/legal/review-owned | Incident resources, signed webhook-safe ingestion, incident package reports, and runbook guidance. | Incident commander ownership, disclosure policy, customer notification process, evidence retention, and post-incident review. | +| Retention, legal hold, and WORM | operator-owned/legal/review-owned/provider-owned | Retention markers, legal hold records, tombstones, object-lock receipts, and audit-chain entries. | Applicable retention schedule, legal-hold approval, provider-enforced retention proof, and deletion/exception review. | +| Customer package sharing | operator-owned/legal/review-owned | Redaction profiles, package manifests, package downloads, viewer, portal access, and package verification commands. | Recipient authorization, NDA or sharing policy, package expiry, customer-specific redaction approval, and legal/commercial review. | +| Audit/legal sufficiency | legal/review-owned | Tamper-evident records, release bundles, reports, limitations, assumptions, and verification receipts. | Auditor/customer acceptance criteria, legal interpretation, framework-specific control mapping review, and sign-off outside Evydence. | + +Evydence can record external evidence and verify the local records it generates. +It cannot independently prove provider-side configuration, legal sufficiency, +regulatory acceptance, scanner completeness, or that a release is secure. diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 685270f..430f664 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -90,6 +90,10 @@ Known hardening work remains: | Air-gapped production | Requires transfer controls | All small-production controls plus signed offline artifacts, import/export verification, local registry or package mirror, offline docs, and explicit backup/restore procedure. | | Hosted SaaS production | Out of scope for this profile | Requires separate hosted tenancy, SLO, abuse, billing, privacy, support, and cloud operations controls before any SaaS production claim. | +Use the [external controls matrix](external-controls-matrix.md) to separate +repo-owned checks from operator, provider, and legal/review responsibilities +before applying these profiles to regulated or high-trust deployments. + ## HA And Concurrency Contract The current self-hosted production profile supports one API writer replica. From 9bb4fac8ad95028386c27b4c908b799abe130ca1 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 17:58:05 +0300 Subject: [PATCH 236/287] docs(production): clarify single writer stance --- .productization_next_steps_missing.md | 2 +- docs/reference/capacity-and-failures.md | 25 ++++++++++++++++++++++++- docs/reference/production-readiness.md | 8 ++++++-- docs/reference/roadmap.md | 11 ++++++++--- 4 files changed, 39 insertions(+), 7 deletions(-) diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index 27c3881..539e4ad 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -433,7 +433,7 @@ Implementation rules: - Link from production readiness, Kubernetes, and pilot checklist docs. - Run `make docs-check`. -### Ticket E6-T3 - Decide the long-term single-writer stance [ ] +### Ticket E6-T3 - Decide the long-term single-writer stance [x] Description: Decide whether one API writer replica is an acceptable long-term self-hosted profile, or whether multi-writer API HA must become a production diff --git a/docs/reference/capacity-and-failures.md b/docs/reference/capacity-and-failures.md index b956251..53076b4 100644 --- a/docs/reference/capacity-and-failures.md +++ b/docs/reference/capacity-and-failures.md @@ -8,8 +8,31 @@ production candidate profile. It is not a benchmark claim. - API writer replicas: `1`. - Worker replicas: may scale horizontally when PostgreSQL outbox locking is enabled. +- Single API writer mode is an intentional supported profile for controlled + self-hosted deployments with reviewed recovery procedures and worker scaling. - API multi-writer HA remains unsupported until a reviewed concurrency design - replaces the current single-writer stance. + replaces or extends the current single-writer stance. It is a blocker for any + future broad production or hosted SaaS claim, not for the current controlled + self-hosted production candidate profile. + +## Single-Writer Decision + +Evydence keeps one API writer as the supported long-term profile for the +current release line. This is acceptable for small internal deployments and +design-partner pilots when the operator has: + +- a supervised API process managed by systemd, Kubernetes, or equivalent; +- a working PostgreSQL writer lease and startup refusal for extra writers; +- worker replicas scaled separately for parser, signing, and report backlog; +- backups and restore rehearsals for PostgreSQL and object storage; +- documented maintenance windows for API upgrades and migrations; +- monitoring on readiness, outbox backlog, database connectivity, and object + storage failures. + +The multi-writer backlog remains technical hardening work: finish focused +repository decomposition, add optimistic concurrency or transaction-scoped +resource locks where needed, test concurrent writes per resource family, and +re-run the production exit review before changing the supported HA claim. ## Practical Sizing Inputs diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 430f664..a413abf 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -114,8 +114,12 @@ Worker replicas may be scaled because persisted outbox jobs are claimed with PostgreSQL row locking. Scaling workers increases parser/signing/report throughput; it does not make API writes multi-writer safe. -The roadmap records the future decision point for multi-writer API HA; see -[Roadmap and release cadence](roadmap.md). +The current decision is that one API writer is acceptable for controlled +self-hosted deployments with monitored process restart, backup/restore +rehearsal, and maintenance-window expectations. Multi-writer API HA is required +before any future broad production or hosted SaaS claim. The roadmap records +that backlog; see [Roadmap and release cadence](roadmap.md) and +[Capacity and failure modes](capacity-and-failures.md). ## Machine Gate diff --git a/docs/reference/roadmap.md b/docs/reference/roadmap.md index 2d34d85..5a97457 100644 --- a/docs/reference/roadmap.md +++ b/docs/reference/roadmap.md @@ -10,7 +10,10 @@ security. The current release line is a controlled self-hosted production candidate. The supported API deployment profile is one API writer replica with scalable worker replicas through PostgreSQL outbox locking. Multi-writer API high availability -is not part of the current supported profile. +is not part of the current supported profile. This single-writer stance is +acceptable for the current controlled self-hosted release line; multi-writer API +HA becomes a blocker before any future broad production-ready or hosted SaaS +status. ## Near-Term Focus @@ -31,8 +34,10 @@ is not part of the current supported profile. ## Later Production Hardening -- review whether the single API writer profile remains the supported long-term - posture or whether a multi-writer design is justified by operator demand; +- keep one API writer as the supported profile for the current release line, + while designing multi-writer API HA only after focused repository + decomposition, optimistic-concurrency or resource-locking tests, and operator + demand justify the added complexity; - harden provider-specific KMS/HSM, object-lock/WORM, SSO/group-sync, and transparency-proof profiles with deployment-specific evidence and tests; - publish immutable container image digests if container images become a From 8ca83bd9406c573872b1c5a7c97c5fc01171f164 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 18:00:18 +0300 Subject: [PATCH 237/287] docs(production): add gate troubleshooting --- .productization_next_steps_missing.md | 4 +- Makefile | 3 + docs/README.md | 1 + .../production-gate-troubleshooting.md | 137 ++++++++++++++++++ docs/reference/production-readiness.md | 4 + docs/reference/release-validation.md | 7 +- 6 files changed, 153 insertions(+), 3 deletions(-) create mode 100644 docs/reference/production-gate-troubleshooting.md diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index 539e4ad..a15d11f 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -401,7 +401,7 @@ Implementation rules: - Add the script to `demo-check` or a separate checked target. - Run the new target and `make fast-check`. -## Epic E6 - Clarify Production Candidate Versus Broad Production [ ] +## Epic E6 - Clarify Production Candidate Versus Broad Production [x] Description: Keep production positioning honest while closing repo-local hardening that affects controlled self-hosted adoption. @@ -448,7 +448,7 @@ Implementation rules: - Do not change Helm defaults without tests. - Run `make docs-check` and `make deploy-check`. -### Ticket E6-T4 - Add current production-gate troubleshooting [ ] +### Ticket E6-T4 - Add current production-gate troubleshooting [x] Description: Document how to diagnose failures in `make production-check`, including PostgreSQL URL setup, migration compatibility, coverage, black-box diff --git a/Makefile b/Makefile index acb1d6d..7784a47 100644 --- a/Makefile +++ b/Makefile @@ -144,6 +144,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @test -f docs/reference/production-readiness.md @test -f docs/reference/production-exit-review.md @test -f docs/reference/external-controls-matrix.md + @test -f docs/reference/production-gate-troubleshooting.md @test -f docs/reference/release-candidate.md @test -f docs/reference/release-evidence-index.md @test -f docs/reference/release-notes-template.md @@ -188,6 +189,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod "reference/production-readiness.md" \ "reference/production-exit-review.md" \ "reference/external-controls-matrix.md" \ + "reference/production-gate-troubleshooting.md" \ "reference/release-candidate.md" \ "reference/release-evidence-index.md" \ "reference/release-notes-template.md" \ @@ -245,6 +247,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @test -f docs/how-to/pilot-deployment-checklist.md @grep -F 'Required: external PostgreSQL' docs/how-to/pilot-deployment-checklist.md >/dev/null @grep -F 'external controls matrix' docs/reference/production-readiness.md docs/kubernetes.md docs/how-to/pilot-deployment-checklist.md >/dev/null + @grep -F 'Production gate troubleshooting' docs/reference/production-readiness.md docs/reference/release-validation.md docs/README.md >/dev/null @grep -F 'Required: object paths are tenant-prefixed' docs/how-to/pilot-deployment-checklist.md >/dev/null @grep -F 'Required: public API access is behind TLS' docs/how-to/pilot-deployment-checklist.md >/dev/null @test -f docs/commercial/design-partner-pilot.md diff --git a/docs/README.md b/docs/README.md index 7ef05a0..f7035d4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -38,6 +38,7 @@ This documentation is organized by reader task. Implementation claims should be - [Production readiness](reference/production-readiness.md): self-hosted production profiles, production gates, and exit criteria. - [Production exit review](reference/production-exit-review.md): current release-positioning decision and unresolved blockers. - [External controls matrix](reference/external-controls-matrix.md): owner boundaries for regulated or high-trust self-hosted deployments. +- [Production gate troubleshooting](reference/production-gate-troubleshooting.md): safe diagnostics for `make production-check` failures. - [Release candidate checklist](reference/release-candidate.md): required evidence before tagging a controlled self-hosted release candidate. - [Release evidence index](reference/release-evidence-index.md): release artifact map, generation commands, and verification commands. - [Release notes template](reference/release-notes-template.md): checked wording used by release-candidate packaging when a tag-specific note file is absent. diff --git a/docs/reference/production-gate-troubleshooting.md b/docs/reference/production-gate-troubleshooting.md new file mode 100644 index 0000000..f1c3aa9 --- /dev/null +++ b/docs/reference/production-gate-troubleshooting.md @@ -0,0 +1,137 @@ +# Production Gate Troubleshooting + +This reference helps diagnose `make production-check` failures in disposable +readiness environments. Do not run these commands against production databases +or object stores unless your deployment runbook explicitly approves that action. + +`make production-check` is stricter than local development gates. It expects a +throwaway PostgreSQL database, signing smoke-test material generated by the +repository scripts, coverage at the configured threshold, migration +compatibility, release validation, black-box demo proof, and package +verification. + +## PostgreSQL URL + +Symptom: the gate exits early with `EVYDENCE_TEST_DATABASE_URL is required`. + +Use a disposable database URL: + +```sh +export EVYDENCE_TEST_DATABASE_URL='postgres://evydence:change-me@localhost:5432/evydence_test?sslmode=disable' +make live-postgres-check +``` + +Expected result: the target connects and verifies the schema can be used for +tests. If it fails, check network reachability, credentials, TLS mode, and that +the database is not a production database. + +For the local Compose profile: + +```sh +make release-check-local-postgres +``` + +This starts the repository Compose PostgreSQL service and runs the release +check with local test settings. + +## Migration Compatibility + +Symptom: migration compatibility fails for a migration prefix. + +Run the migration check against a disposable database: + +```sh +EVYDENCE_TEST_DATABASE_URL="$EVYDENCE_TEST_DATABASE_URL" make migration-compatibility-check +``` + +Expected result: every committed migration prefix can migrate forward to the +current schema. If a prefix fails, inspect the named migration and add a forward +migration rather than editing shipped migration history. + +## Coverage + +Symptom: `coverage-check` fails before running tests or reports coverage below +the threshold. + +The production coverage gate requires live PostgreSQL: + +```sh +EVYDENCE_TEST_DATABASE_URL="$EVYDENCE_TEST_DATABASE_URL" make coverage-check +``` + +Expected result: total statement coverage is at or above the default 80 percent +threshold. For local no-database exploration only: + +```sh +make coverage +``` + +Do not treat no-database `make coverage` output as production release evidence. + +## Black-Box Demo + +Symptom: `black-box-demo-check` fails during API startup, worker startup, +readiness, package generation, audit-chain verification, or restart checks. + +Run the demo directly with preserved artifacts: + +```sh +EVYDENCE_BLACK_BOX_KEEP_ARTIFACTS=1 \ +EVYDENCE_TEST_DATABASE_URL="$EVYDENCE_TEST_DATABASE_URL" \ +make black-box-demo-check +``` + +Expected result: `tmp/black-box-demo-check/` contains API logs, worker logs, and +demo JSON outputs for inspection. These files are local diagnostic artifacts and +must not contain bearer secrets or raw production evidence. + +## Release Signing Smoke + +Symptom: release packaging or signing smoke tests fail because signing material +is missing or invalid. + +Generate temporary local signing material for a disposable check: + +```sh +mkdir -p tmp/release-signing-smoke +go run ./cmd/evydence release keygen \ + --private-out tmp/release-signing-smoke/private.key \ + --public-out tmp/release-signing-smoke/public.key +``` + +Expected result: the private key is used only for local smoke testing and is not +committed. Real release signing material belongs in the release workflow secret +`EVYDENCE_RELEASE_SIGNING_PRIVATE_KEY_B64` or an approved signing environment. + +## Package Verification + +Symptom: package or public release verification fails. + +Verify the current public release-candidate package: + +```sh +make public-release-verify TAG=v0.1.0-rc.5 +``` + +Verify the checked local package fixture: + +```sh +go run ./cmd/evydence package verify \ + --archive examples/end-to-end-release-evidence/sample-customer-package.zip \ + --expected-package-id csp_example \ + --expected-product-id prod_example \ + --expected-release-id rel_example +``` + +Expected result: checksums, signed manifest material, package manifest fields, +and limitations validate. A passing package verification proves the exported +bytes match their manifest and verification material; it does not prove legal +compliance, certification, complete SBOM coverage, authoritative vulnerability +coverage, or release security. + +## Safe Escalation + +When reporting failures, include command names, exit codes, sanitized logs, +release tag, commit SHA, and whether the database was disposable. Do not include +API keys, bearer tokens, private keys, database URLs with credentials, customer +data, raw evidence payloads, object-store credentials, or provider secrets. diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index a413abf..f564e3a 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -162,6 +162,10 @@ output as production release evidence. `make finalize` for routine local development. Use `make production-check` for self-hosted production readiness evidence. +If the gate fails, use +[Production gate troubleshooting](production-gate-troubleshooting.md) with a +disposable database and sanitized logs. + ## Exit Criteria Do not describe an Evydence build as broadly self-hosted production-ready until: diff --git a/docs/reference/release-validation.md b/docs/reference/release-validation.md index 1147706..9f25429 100644 --- a/docs/reference/release-validation.md +++ b/docs/reference/release-validation.md @@ -94,7 +94,12 @@ For the scripted local profile, run: make release-check-local-postgres ``` -The target starts the Compose PostgreSQL service, waits for readiness, loads `.test.env` when present or `.test.env.example` otherwise, runs `make release-check`, and preserves `tmp/release-check-summary.txt`. +The target starts the Compose PostgreSQL service, waits for readiness, loads +`.test.env` when present or `.test.env.example` otherwise, runs +`make release-check`, and preserves `tmp/release-check-summary.txt`. For +production-gate failures, use +[Production gate troubleshooting](production-gate-troubleshooting.md) before +changing release status or weakening a gate. You can also run the sequence manually: From c7fc70bd06092be9d74f39167ea8352d83dd2799 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 18:03:49 +0300 Subject: [PATCH 238/287] docs(ux): define reviewer surface boundary --- .productization_next_steps_missing.md | 8 +++++++- docs/how-to/view-packages.md | 20 ++++++++++++++++++++ docs/reference/customer-package-manifest.md | 20 ++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index a15d11f..66f4ed9 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -466,7 +466,7 @@ Implementation rules: Description: Decide and implement the smallest browser-facing surface needed to make customer package review credible without building a broad UI. -### Ticket E7-T1 - Define UI boundary for reviewer and operator surfaces [ ] +### Ticket E7-T1 - Define UI boundary for reviewer and operator surfaces [x] Description: Decide what remains API/CLI-only, what belongs in the local package viewer, and whether a server-hosted customer portal page is in scope for the @@ -480,6 +480,12 @@ Implementation rules: - Document the boundary in package viewer and customer portal docs. - Run `make docs-check` and `make package-viewer-check`. +Repo-local status: complete. Operator workflows remain API/CLI-first, the local +viewer is documented as offline and non-authoritative, and the only +browser-facing server surface in scope is a minimal package-token-backed review +page that reuses existing portal exchange, expiry, NDA, scope, watermark, and +audit controls. + ### Ticket E7-T2 - Add server-hosted customer package view if approved [ ] Description: If the UI boundary allows it, add a minimal server-hosted customer diff --git a/docs/how-to/view-packages.md b/docs/how-to/view-packages.md index a7f33ae..c2baeff 100644 --- a/docs/how-to/view-packages.md +++ b/docs/how-to/view-packages.md @@ -4,6 +4,26 @@ Evydence is API-first, but the repository includes a local package viewer at `site/package-viewer/index.html` for customer-package and release-evidence review. +## Reviewer Surface Boundary + +Evydence intentionally keeps operator workflows API/CLI-first. Operators create +products, releases, evidence, redaction profiles, customer packages, and portal +access records through the API or CLI so tenant authorization, scopes, +idempotency, audit entries, and package expiry stay server-side. + +The local package viewer is an offline inspection helper. It reads files that a +reviewer already has on disk, renders package-scoped JSON as text, and never +grants or checks access to tenant resources. Do not treat the viewer as a +customer portal, identity provider, access-control layer, or evidence source of +truth. + +The only browser-facing server surface currently in scope is a minimal +customer-portal review page backed by the existing package-token exchange and +download endpoints. That page may collect a portal token and optional NDA +acceptance fields, but all access decisions must remain in the API. It must not +expose raw evidence payloads, object-store paths, internal notes, token hashes, +private keys, or customer data outside the scoped package. + Open the file in a browser, then select a JSON package, readiness report, evidence bundle, or package manifest from disk. The viewer runs entirely in the browser and does not upload data. To inspect a non-sensitive fixture without diff --git a/docs/reference/customer-package-manifest.md b/docs/reference/customer-package-manifest.md index 41d257c..7238a96 100644 --- a/docs/reference/customer-package-manifest.md +++ b/docs/reference/customer-package-manifest.md @@ -148,6 +148,26 @@ watermarking, and audit triage only; the portal token remains the credential and is returned once, stored only as a hash, and omitted from package manifests, archives, logs, and list responses. +## Reviewer UX Boundary + +The package review surface is deliberately narrow: + +- operators use the API and CLI to create packages, access records, downloads, + redaction profiles, and audit evidence; +- local reviewers may use `site/package-viewer/index.html` or archive + `report.html` after they already possess package files; +- browser-facing server review must reuse the same customer portal token + exchange, expiry, NDA, package scope, watermark, and audit behavior as the + JSON and ZIP endpoints. + +The local viewer and static reports are not authorization mechanisms. They do +not verify that a reviewer should receive a package and they do not grant access +to tenant data. Server-hosted review pages must accept portal tokens in request +bodies rather than URLs, disable caching of package responses, escape +operator-provided package text, and omit raw payloads, object-store references, +internal notes, token material, signing private material, and unrelated customer +data. + ## Redaction Leakage Guard Customer package generation is tested with canary values for API key secrets, From c20c87f6b2240a8d4192a8cb9560be2494f860fa Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 18:15:37 +0300 Subject: [PATCH 239/287] feat(portal): add token-scoped package review page --- .productization_next_steps_missing.md | 9 +- docs/api.md | 3 + docs/how-to/view-packages.md | 6 + docs/reference/api-contract-matrix.md | 5 +- docs/reference/customer-package-manifest.md | 6 +- .../adapters/httpapi/openapi_operations.go | 38 ++ internal/adapters/httpapi/portal_handlers.go | 331 ++++++++++++++++++ .../adapters/httpapi/route_registration.go | 3 + internal/adapters/httpapi/router.go | 2 + internal/adapters/httpapi/router_test.go | 119 ++++++- openapi.yaml | 2 +- sdk/openapi-route-catalog.json | 44 ++- 12 files changed, 560 insertions(+), 8 deletions(-) diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index 66f4ed9..bc7ea0b 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -486,7 +486,7 @@ browser-facing server surface in scope is a minimal package-token-backed review page that reuses existing portal exchange, expiry, NDA, scope, watermark, and audit controls. -### Ticket E7-T2 - Add server-hosted customer package view if approved [ ] +### Ticket E7-T2 - Add server-hosted customer package view if approved [x] Description: If the UI boundary allows it, add a minimal server-hosted customer portal page for token-scoped package review and download. @@ -499,6 +499,13 @@ Implementation rules: - Add frontend/security tests and redaction leakage tests. - Run focused HTTP tests, `make package-viewer-check`, and `make finalize`. +Repo-local status: complete. `/v1/customer-portal/package/view` now renders a +minimal no-store HTML review form and scoped package review page using existing +portal token exchange, expiry, NDA, watermark, package scope, and audit +behavior. Tokens are accepted only in form bodies, are not copied into returned +HTML or URLs, and the form-backed ZIP download reuses the existing portal +archive export path. + ### Ticket E7-T3 - Add reviewer export/download workflow proof [ ] Description: Prove that a reviewer can open a package, inspect limitations, diff --git a/docs/api.md b/docs/api.md index b6d747e..6ea9734 100644 --- a/docs/api.md +++ b/docs/api.md @@ -452,6 +452,9 @@ Source snapshots capture submitted provider metadata. They do not call provider | `POST` | `/v1/customer-portal/access/{id}/revoke` | Revoke an external reviewer access record. | | `POST` | `/v1/customer-portal/package` | Exchange package token for scoped manifest. | | `POST` | `/v1/customer-portal/package/download` | Exchange package token for scoped ZIP package download. | +| `GET` | `/v1/customer-portal/package/view` | Render public token-entry page for scoped package review. | +| `POST` | `/v1/customer-portal/package/view` | Exchange package token from a form body for scoped HTML package review. | +| `POST` | `/v1/customer-portal/package/view/download` | Exchange package token from a form body for scoped ZIP package download. | | `POST` | `/v1/questionnaire-templates` | Create questionnaire template. | | `POST` | `/v1/questionnaire-packages` | Generate evidence-backed responses. | | `POST` | `/v1/questionnaire-drafts` | Create evidence-backed draft answers for review. | diff --git a/docs/how-to/view-packages.md b/docs/how-to/view-packages.md index c2baeff..63eff72 100644 --- a/docs/how-to/view-packages.md +++ b/docs/how-to/view-packages.md @@ -24,6 +24,12 @@ acceptance fields, but all access decisions must remain in the API. It must not expose raw evidence payloads, object-store paths, internal notes, token hashes, private keys, or customer data outside the scoped package. +When the API is running, open `/v1/customer-portal/package/view` to use the +server-backed review page. It accepts portal tokens only in form bodies, sets +no-store browser cache headers, and renders the same scoped package data exposed +by `POST /v1/customer-portal/package`. The page includes a separate ZIP +download form so the token is never copied into the returned HTML or a URL. + Open the file in a browser, then select a JSON package, readiness report, evidence bundle, or package manifest from disk. The viewer runs entirely in the browser and does not upload data. To inspect a non-sensitive fixture without diff --git a/docs/reference/api-contract-matrix.md b/docs/reference/api-contract-matrix.md index 777faff..1672716 100644 --- a/docs/reference/api-contract-matrix.md +++ b/docs/reference/api-contract-matrix.md @@ -3,7 +3,7 @@ This generated reference inventories Evydence `/v1` route contract precision from `openapi.yaml`. It is a planning aid for production contract hardening; `broad` means the route still uses a shared envelope, unspecified body, or generic schema where an endpoint-specific contract should be considered. -Generated from 183 operations: 183 precise, 0 broad. +Generated from 186 operations: 186 precise, 0 broad. | Method | Path | Operation | Auth | Scopes | Idempotency | Params | Request | 2xx Response | Precision | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -52,6 +52,9 @@ Generated from 183 operations: 183 precise, 0 broad. | POST | /v1/customer-portal/access/{id}/revoke | revokeCustomerPortalAccess | Bearer | package:write | required | path:id | application/json:EmptyObject | 200:application/json:CustomerPortalAccessEnvelope | precise | | POST | /v1/customer-portal/package | accessCustomerPortalPackage | public | - | not required | - | application/json:CustomerPortalPackageRequest | 200:application/json:CustomerSecurityPackageEnvelope | precise | | POST | /v1/customer-portal/package/download | downloadCustomerPortalPackage | public | - | not required | - | application/json:CustomerPortalPackageRequest | 200:application/zip:string/binary | precise | +| GET | /v1/customer-portal/package/view | customerPortalPackageViewForm | public | - | - | - | - | 200:text/html:string | precise | +| POST | /v1/customer-portal/package/view | customerPortalPackageView | public | - | not required | - | application/x-www-form-urlencoded:CustomerPortalPackageRequest | 200:text/html:string | precise | +| POST | /v1/customer-portal/package/view/download | downloadCustomerPortalPackageView | public | - | not required | - | application/x-www-form-urlencoded:CustomerPortalPackageRequest | 200:application/zip:string/binary | precise | | GET | /v1/deployments | listDeployments | Bearer | deployment:read | - | query:environment_id, query:release_id | - | 200:application/json:DeploymentEventListEnvelope | precise | | POST | /v1/deployments | recordDeployment | Bearer | deployment:write | required | - | application/json:RecordDeploymentRequest | 201:application/json:DeploymentEventEnvelope | precise | | GET | /v1/deployments/{id} | getDeployment | Bearer | deployment:read | - | path:id | - | 200:application/json:DeploymentEventEnvelope | precise | diff --git a/docs/reference/customer-package-manifest.md b/docs/reference/customer-package-manifest.md index 7238a96..69b0bee 100644 --- a/docs/reference/customer-package-manifest.md +++ b/docs/reference/customer-package-manifest.md @@ -156,9 +156,9 @@ The package review surface is deliberately narrow: redaction profiles, and audit evidence; - local reviewers may use `site/package-viewer/index.html` or archive `report.html` after they already possess package files; -- browser-facing server review must reuse the same customer portal token - exchange, expiry, NDA, package scope, watermark, and audit behavior as the - JSON and ZIP endpoints. +- browser-facing server review at `/v1/customer-portal/package/view` must reuse + the same customer portal token exchange, expiry, NDA, package scope, + watermark, and audit behavior as the JSON and ZIP endpoints. The local viewer and static reports are not authorization mechanisms. They do not verify that a reviewer should receive a package and they do not grant access diff --git a/internal/adapters/httpapi/openapi_operations.go b/internal/adapters/httpapi/openapi_operations.go index d2c141e..07d12f8 100644 --- a/internal/adapters/httpapi/openapi_operations.go +++ b/internal/adapters/httpapi/openapi_operations.go @@ -844,6 +844,23 @@ func withCriticalOperationDetails(operation specs.Operation) specs.Operation { operation.Security = nil operation.Scopes = nil operation.Responses[http.StatusOK] = binaryResponse("Customer security package ZIP archive.") + case "customerPortalPackageViewForm": + operation.Description = "Public HTML form for reviewing or downloading a scoped customer package with a portal token. It does not accept tokens in URLs and does not use bearer authentication." + operation.Security = nil + operation.Scopes = nil + operation.Responses[http.StatusOK] = htmlResponse("Customer portal package review form.") + case "customerPortalPackageView": + operation.Description = "Public HTML package review endpoint backed by the customer portal token exchange. Tokens are accepted only as form body fields." + operation.RequestBody = formRequest("Customer portal token form request.", "#/components/schemas/CustomerPortalPackageRequest") + operation.Security = nil + operation.Scopes = nil + operation.Responses[http.StatusOK] = htmlResponse("Scoped customer package review HTML.") + case "downloadCustomerPortalPackageView": + operation.Description = "Public HTML-form package ZIP download endpoint backed by the customer portal token exchange. Tokens are accepted only as form body fields." + operation.RequestBody = formRequest("Customer portal token form request.", "#/components/schemas/CustomerPortalPackageRequest") + operation.Security = nil + operation.Scopes = nil + operation.Responses[http.StatusOK] = binaryResponse("Customer security package ZIP archive.") case "securityReviewPackageReport": operation.Description = "Returns a redaction-aware security-review package report with assumptions and limitations." operation.Parameters = append(operation.Parameters, queryParam("package_id", "Customer package id.", "string")) @@ -925,6 +942,17 @@ func jsonRequest(description, schemaRef string) *specs.RequestBody { } } +func formRequest(description, schemaRef string) *specs.RequestBody { + return &specs.RequestBody{ + Description: description, + Required: true, + ContentTypes: []string{"application/x-www-form-urlencoded"}, + Content: map[string]specs.MediaType{ + "application/x-www-form-urlencoded": {SchemaRef: schemaRef}, + }, + } +} + func addJSONRequestExamples(body *specs.RequestBody, examples map[string]any) { if body == nil || len(examples) == 0 { return @@ -1093,6 +1121,16 @@ func binaryResponse(description string) specs.Response { } } +func htmlResponse(description string) specs.Response { + return specs.Response{ + Description: description, + ContentTypes: []string{"text/html"}, + Content: map[string]specs.MediaType{ + "text/html": {Schema: map[string]any{"type": "string"}}, + }, + } +} + func queryParam(name, description, typ string) specs.Parameter { schema := map[string]any{"type": typ} if name == "limit" { diff --git a/internal/adapters/httpapi/portal_handlers.go b/internal/adapters/httpapi/portal_handlers.go index 4d155d9..fcc68c5 100644 --- a/internal/adapters/httpapi/portal_handlers.go +++ b/internal/adapters/httpapi/portal_handlers.go @@ -1,13 +1,21 @@ package httpapi import ( + "fmt" + "html" + "io" "net/http" + "net/url" + "sort" + "strings" "time" "github.com/aatuh/evydence/internal/app" "github.com/aatuh/evydence/internal/domain" ) +const maxPortalFormBody = 64 << 10 + func (s *Server) createCustomerPortalAccess(w http.ResponseWriter, r *http.Request) { var req struct { PackageID string `json:"package_id"` @@ -67,6 +75,7 @@ func (s *Server) accessCustomerPortalPackage(w http.ResponseWriter, r *http.Requ writeProblem(w, r, err) return } + setPortalNoStoreHeaders(w) writeData(w, http.StatusOK, pkg) } @@ -90,9 +99,331 @@ func (s *Server) downloadCustomerPortalPackage(w http.ResponseWriter, r *http.Re writeProblem(w, r, err) return } + setPortalNoStoreHeaders(w) + writeArchive(w, archive) +} + +func (s *Server) customerPortalPackageViewForm(w http.ResponseWriter, r *http.Request) { + writePortalHTML(w, http.StatusOK, customerPortalPackageFormHTML("")) +} + +func (s *Server) customerPortalPackageView(w http.ResponseWriter, r *http.Request) { + req, err := readCustomerPortalForm(r) + if err != nil { + writeProblem(w, r, err) + return + } + pkg, err := s.ledger.AccessCustomerPortalPackageWithAcceptance(r.Context(), req.Token, app.CustomerPortalAcceptanceInput{NDAAccepted: req.NDAAccepted, NDAAcceptedBy: req.NDAAcceptedBy}) + if err != nil { + writeProblem(w, r, err) + return + } + writePortalHTML(w, http.StatusOK, customerPortalPackageHTML(pkg)) +} + +func (s *Server) downloadCustomerPortalPackageView(w http.ResponseWriter, r *http.Request) { + req, err := readCustomerPortalForm(r) + if err != nil { + writeProblem(w, r, err) + return + } + archive, err := s.ledger.ExportCustomerPortalPackageArchiveWithAcceptance(r.Context(), req.Token, app.CustomerPortalAcceptanceInput{NDAAccepted: req.NDAAccepted, NDAAcceptedBy: req.NDAAcceptedBy}) + if err != nil { + writeProblem(w, r, err) + return + } + setPortalNoStoreHeaders(w) writeArchive(w, archive) } +type customerPortalFormRequest struct { + Token string + NDAAccepted bool + NDAAcceptedBy string +} + +func readCustomerPortalForm(r *http.Request) (customerPortalFormRequest, error) { + if strings.TrimSpace(r.URL.RawQuery) != "" { + return customerPortalFormRequest{}, app.ErrValidation + } + contentType := strings.ToLower(strings.TrimSpace(r.Header.Get("Content-Type"))) + if !strings.HasPrefix(contentType, "application/x-www-form-urlencoded") { + return customerPortalFormRequest{}, app.ErrValidation + } + body, err := io.ReadAll(io.LimitReader(r.Body, maxPortalFormBody+1)) + if err != nil || len(body) > maxPortalFormBody { + return customerPortalFormRequest{}, app.ErrValidation + } + values, err := url.ParseQuery(string(body)) + if err != nil { + return customerPortalFormRequest{}, app.ErrValidation + } + for key := range values { + switch key { + case "token", "nda_accepted", "nda_accepted_by": + if len(values[key]) > 1 { + return customerPortalFormRequest{}, app.ErrValidation + } + default: + return customerPortalFormRequest{}, app.ErrValidation + } + } + token := strings.TrimSpace(values.Get("token")) + acceptedBy := strings.TrimSpace(values.Get("nda_accepted_by")) + if token == "" || len(token) > 4096 || len(acceptedBy) > 256 { + return customerPortalFormRequest{}, app.ErrValidation + } + accepted := false + switch strings.ToLower(strings.TrimSpace(values.Get("nda_accepted"))) { + case "", "false", "0", "off": + case "true", "1", "on": + accepted = true + default: + return customerPortalFormRequest{}, app.ErrValidation + } + return customerPortalFormRequest{Token: token, NDAAccepted: accepted, NDAAcceptedBy: acceptedBy}, nil +} + +func writePortalHTML(w http.ResponseWriter, status int, body string) { + setPortalNoStoreHeaders(w) + w.Header().Set("Content-Type", "text/html; charset=utf-8") + w.Header().Set("Content-Security-Policy", "default-src 'none'; style-src 'unsafe-inline'; form-action 'self'; base-uri 'none'; frame-ancestors 'none'") + w.WriteHeader(status) + _, _ = w.Write([]byte(body)) +} + +func setPortalNoStoreHeaders(w http.ResponseWriter) { + w.Header().Set("Cache-Control", "no-store") + w.Header().Set("Pragma", "no-cache") + w.Header().Set("Referrer-Policy", "no-referrer") + w.Header().Set("X-Content-Type-Options", "nosniff") +} + +func customerPortalPackageFormHTML(message string) string { + var b strings.Builder + writePortalHTMLHead(&b, "Evydence Package Review") + b.WriteString("

Evydence package review

") + if strings.TrimSpace(message) != "" { + b.WriteString("

") + b.WriteString(escapeHTML(message)) + b.WriteString("

") + } + b.WriteString("

Review package

") + writePortalTokenFields(&b) + b.WriteString("
") + b.WriteString("

Download ZIP

") + writePortalTokenFields(&b) + b.WriteString("
") + b.WriteString("

Package review supports technical evidence review and compliance readiness only. It is not legal compliance proof, certification, complete SBOM proof, an authoritative vulnerability result, regulator acceptance, or a secure-release guarantee.

") + b.WriteString("
") + return b.String() +} + +func writePortalTokenFields(b *strings.Builder) { + b.WriteString("") + b.WriteString("") + b.WriteString("") +} + +func customerPortalPackageHTML(pkg domain.CustomerSecurityPackage) string { + var b strings.Builder + writePortalHTMLHead(&b, "Evydence Package "+pkg.ID) + b.WriteString("

") + b.WriteString(escapeHTML(pkg.Title)) + b.WriteString("

This page is generated from a scoped, redacted customer package. It omits raw tenant evidence payloads and internal notes.

") + b.WriteString("

Scope

") + portalDefinition(&b, "package_id", pkg.ID) + portalDefinition(&b, "product_id", pkg.ProductID) + portalDefinition(&b, "release_id", pkg.ReleaseID) + portalDefinition(&b, "state", pkg.State) + portalDefinition(&b, "manifest_hash", pkg.ManifestHash) + portalDefinition(&b, "expires_at", pkg.ExpiresAt.UTC().Format(time.RFC3339)) + if pkg.DistributionWatermark != "" { + portalDefinition(&b, "distribution_watermark", pkg.DistributionWatermark) + } + b.WriteString("
") + for _, section := range []struct { + Key string + Title string + }{ + {"readiness_summary", "Readiness Summary"}, + {"vulnerability_decisions", "Vulnerability Decisions"}, + {"customer_decision_export", "Customer Decision Export"}, + {"customer_safe_gaps", "Customer-Safe Gaps"}, + {"artifact_digests", "Artifact Digests"}, + {"evidence_ids", "Included Evidence"}, + {"verification_material", "Verification Material"}, + {"reviewer_checklist", "Reviewer Checklist"}, + {"limitations", "Limitations"}, + {"non_claims", "Non-Claims"}, + } { + portalManifestSection(&b, pkg.Manifest, section.Key, section.Title) + } + b.WriteString("

Download ZIP

") + writePortalTokenFields(&b) + b.WriteString("
") + b.WriteString("

Review output supports technical evidence review and compliance readiness only. It is not legal compliance proof, certification, complete SBOM proof, an authoritative vulnerability result, regulator acceptance, or a secure-release guarantee.

") + b.WriteString("
") + return b.String() +} + +func writePortalHTMLHead(b *strings.Builder, title string) { + b.WriteString("") + b.WriteString(escapeHTML(title)) + b.WriteString("") +} + +func portalDefinition(b *strings.Builder, key, value string) { + if strings.TrimSpace(value) == "" { + return + } + b.WriteString("
") + b.WriteString(escapeHTML(key)) + b.WriteString("
") + b.WriteString(escapeHTML(value)) + b.WriteString("
") +} + +func portalManifestSection(b *strings.Builder, manifest map[string]any, key, title string) { + value, ok := manifest[key] + if !ok || portalValueEmpty(value) { + return + } + b.WriteString("

") + b.WriteString(escapeHTML(title)) + b.WriteString("

") + portalHTMLValue(b, value, 0) + b.WriteString("
") +} + +func portalHTMLValue(b *strings.Builder, value any, depth int) { + if depth > 5 { + b.WriteString("nested content omitted") + return + } + switch typed := value.(type) { + case nil: + b.WriteString("not recorded") + case string: + b.WriteString(escapeHTML(typed)) + case bool: + if typed { + b.WriteString("true") + } else { + b.WriteString("false") + } + case float64, float32, int, int64, int32, uint, uint64, uint32: + b.WriteString(escapeHTML(toString(typed))) + case []any: + if len(typed) == 0 { + b.WriteString("none") + return + } + b.WriteString("
    ") + for i, item := range typed { + if i >= 100 { + b.WriteString("
  • additional entries omitted
  • ") + break + } + b.WriteString("
  • ") + portalHTMLValue(b, item, depth+1) + b.WriteString("
  • ") + } + b.WriteString("
") + case []string: + if len(typed) == 0 { + b.WriteString("none") + return + } + b.WriteString("
    ") + for i, item := range typed { + if i >= 100 { + b.WriteString("
  • additional entries omitted
  • ") + break + } + b.WriteString("
  • ") + b.WriteString(escapeHTML(item)) + b.WriteString("
  • ") + } + b.WriteString("
") + case map[string]any: + keys := make([]string, 0, len(typed)) + for key := range typed { + if portalSensitiveManifestKey(key) { + continue + } + keys = append(keys, key) + } + sort.Strings(keys) + if len(keys) == 0 { + b.WriteString("none") + return + } + b.WriteString("
") + for _, key := range keys { + b.WriteString("
") + b.WriteString(escapeHTML(key)) + b.WriteString("
") + portalHTMLValue(b, typed[key], depth+1) + b.WriteString("
") + } + b.WriteString("
") + case map[string]string: + keys := make([]string, 0, len(typed)) + for key := range typed { + if portalSensitiveManifestKey(key) { + continue + } + keys = append(keys, key) + } + sort.Strings(keys) + b.WriteString("
") + for _, key := range keys { + portalDefinition(b, key, typed[key]) + } + b.WriteString("
") + default: + b.WriteString(escapeHTML(toString(typed))) + } +} + +func portalValueEmpty(value any) bool { + switch typed := value.(type) { + case nil: + return true + case string: + return strings.TrimSpace(typed) == "" + case []any: + return len(typed) == 0 + case []string: + return len(typed) == 0 + case map[string]any: + return len(typed) == 0 + case map[string]string: + return len(typed) == 0 + default: + return false + } +} + +func portalSensitiveManifestKey(key string) bool { + normalized := strings.ToLower(strings.TrimSpace(key)) + switch normalized { + case "payload_ref", "payload_refs", "object_key", "object_keys", "object_url", "object_urls", "raw_payload", "raw_payload_bytes", "private_key", "private_keys", "token", "tokens", "token_hash", "token_hashes", "api_key", "api_keys", "secret", "secrets", "internal_notes": + return true + default: + return false + } +} + +func toString(value any) string { + return fmt.Sprint(value) +} + +func escapeHTML(value string) string { + return html.EscapeString(value) +} + func (s *Server) createQuestionnaireTemplate(w http.ResponseWriter, r *http.Request) { var req struct { Name string `json:"name"` diff --git a/internal/adapters/httpapi/route_registration.go b/internal/adapters/httpapi/route_registration.go index 96ba152..cb137d8 100644 --- a/internal/adapters/httpapi/route_registration.go +++ b/internal/adapters/httpapi/route_registration.go @@ -183,6 +183,9 @@ func (s *Server) packagePortalRoutes() []routeDef { {http.MethodPost, "/v1/customer-portal/access/{id}/revoke", op("revokeCustomerPortalAccess", http.MethodPost, "/v1/customer-portal/access/{id}/revoke", "Revoke customer portal access", []string{app.ScopePackageWrite}), http.HandlerFunc(s.revokeCustomerPortalAccess)}, {http.MethodPost, "/v1/customer-portal/package", op("accessCustomerPortalPackage", http.MethodPost, "/v1/customer-portal/package", "Access customer portal package", nil), http.HandlerFunc(s.accessCustomerPortalPackage)}, {http.MethodPost, "/v1/customer-portal/package/download", op("downloadCustomerPortalPackage", http.MethodPost, "/v1/customer-portal/package/download", "Download customer portal package ZIP", nil), http.HandlerFunc(s.downloadCustomerPortalPackage)}, + {http.MethodGet, "/v1/customer-portal/package/view", op("customerPortalPackageViewForm", http.MethodGet, "/v1/customer-portal/package/view", "Customer portal package review form", nil), http.HandlerFunc(s.customerPortalPackageViewForm)}, + {http.MethodPost, "/v1/customer-portal/package/view", op("customerPortalPackageView", http.MethodPost, "/v1/customer-portal/package/view", "Customer portal package review page", nil), http.HandlerFunc(s.customerPortalPackageView)}, + {http.MethodPost, "/v1/customer-portal/package/view/download", op("downloadCustomerPortalPackageView", http.MethodPost, "/v1/customer-portal/package/view/download", "Download customer portal package ZIP from review form", nil), http.HandlerFunc(s.downloadCustomerPortalPackageView)}, {http.MethodPost, "/v1/questionnaire-templates", op("createQuestionnaireTemplate", http.MethodPost, "/v1/questionnaire-templates", "Create questionnaire template", []string{app.ScopePackageWrite}), http.HandlerFunc(s.createQuestionnaireTemplate)}, {http.MethodPost, "/v1/questionnaire-packages", op("createQuestionnairePackage", http.MethodPost, "/v1/questionnaire-packages", "Create questionnaire package", []string{app.ScopePackageWrite}), http.HandlerFunc(s.createQuestionnairePackage)}, {http.MethodPost, "/v1/questionnaire-drafts", op("createQuestionnaireDraft", http.MethodPost, "/v1/questionnaire-drafts", "Create evidence-backed questionnaire draft", []string{app.ScopePackageRead}), http.HandlerFunc(s.createQuestionnaireDraft)}, diff --git a/internal/adapters/httpapi/router.go b/internal/adapters/httpapi/router.go index b2e3c39..b120303 100644 --- a/internal/adapters/httpapi/router.go +++ b/internal/adapters/httpapi/router.go @@ -2577,6 +2577,8 @@ func defaultSuccessStatus(operationID, method string) int { "approveWaiver", "accessCustomerPortalPackage", "downloadCustomerPortalPackage", + "customerPortalPackageView", + "downloadCustomerPortalPackageView", "revokeCustomerPortalAccess", "approveException", "verifyObjectRetentionPolicy", diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 685aed6..97eebd8 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -228,6 +228,23 @@ func TestOpenAPICriticalRoutesHavePreciseContracts(t *testing.T) { if _, ok := portalDownload["security"]; ok { t.Fatalf("public portal download should not advertise bearer security: %#v", portalDownload["security"]) } + portalViewForm := operationMap(t, paths, "/v1/customer-portal/package/view", "get") + assertMediaResponseType(t, portalViewForm, "200", "text/html") + if _, ok := portalViewForm["security"]; ok { + t.Fatalf("public portal view form should not advertise bearer security: %#v", portalViewForm["security"]) + } + portalView := operationMap(t, paths, "/v1/customer-portal/package/view", "post") + assertRequestMediaRef(t, portalView, "application/x-www-form-urlencoded", "#/components/schemas/CustomerPortalPackageRequest") + assertMediaResponseType(t, portalView, "200", "text/html") + if _, ok := portalView["security"]; ok { + t.Fatalf("public portal view should not advertise bearer security: %#v", portalView["security"]) + } + portalViewDownload := operationMap(t, paths, "/v1/customer-portal/package/view/download", "post") + assertRequestMediaRef(t, portalViewDownload, "application/x-www-form-urlencoded", "#/components/schemas/CustomerPortalPackageRequest") + assertMediaResponseType(t, portalViewDownload, "200", "application/zip") + if _, ok := portalViewDownload["security"]; ok { + t.Fatalf("public portal view download should not advertise bearer security: %#v", portalViewDownload["security"]) + } createAnswerLibrary := operationMap(t, paths, "/v1/questionnaire-answer-library", "post") assertRequestRef(t, createAnswerLibrary, "#/components/schemas/CreateQuestionnaireAnswerLibraryEntryRequest") assertResponseRef(t, createAnswerLibrary, "201", "#/components/schemas/QuestionnaireAnswerLibraryEntryEnvelope") @@ -1415,6 +1432,62 @@ func TestEnterprisePortalRetentionAndCommercialCollectorHTTPFlow(t *testing.T) { postJSON(t, server, secret, "/v1/users/"+userID+"/deactivate", "ent-user-deactivate", map[string]any{}, http.StatusOK) } +func TestCustomerPortalPackageViewHTMLSafety(t *testing.T) { + server, secret := testServer(t) + productBody := postJSON(t, server, secret, "/v1/products", "portal-view-product", map[string]any{"name": "Portal Product", "slug": "portal-product"}, http.StatusCreated) + productID := dataField(t, productBody, "id") + releaseBody := postJSON(t, server, secret, "/v1/releases", "portal-view-release", map[string]any{"product_id": productID, "version": "1.0.0"}, http.StatusCreated) + releaseID := dataField(t, releaseBody, "id") + digest := "sha256:ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb" + postJSON(t, server, secret, "/v1/evidence", "portal-view-evidence", map[string]any{"product_id": productID, "release_id": releaseID, "type": "security_review", "title": "Review", "payload_hash": digest}, http.StatusCreated) + profileBody := postJSON(t, server, secret, "/v1/redaction-profiles", "portal-view-profile", map[string]any{"name": "customer", "allowed_types": []string{"security_review"}}, http.StatusCreated) + profileID := dataField(t, profileBody, "id") + packageBody := postJSON(t, server, secret, "/v1/customer-packages", "portal-view-package", map[string]any{"product_id": productID, "release_id": releaseID, "redaction_profile_id": profileID, "title": "Customer ", "expires_at": time.Now().UTC().Add(time.Hour).Format(time.RFC3339)}, http.StatusCreated) + packageID := dataField(t, packageBody, "id") + accessBody := postJSON(t, server, secret, "/v1/customer-portal/access", "portal-view-access", map[string]any{"package_id": packageID, "customer_name": "ACME ", "reviewer_name": "Rita Reviewer", "reviewer_email": "rita@example.test", "require_nda": true, "watermark": "ACME review", "expires_at": time.Now().UTC().Add(time.Hour).Format(time.RFC3339)}, http.StatusCreated) + portalSecret := nestedDataField(t, accessBody, "secret") + + form := getRawNoAuth(t, server, "/v1/customer-portal/package/view", http.StatusOK) + if ct := form.Header().Get("Content-Type"); !strings.HasPrefix(ct, "text/html") { + t.Fatalf("portal view form content type = %q", ct) + } + assertNoStoreHTMLHeaders(t, form) + if strings.Contains(form.Body.String(), portalSecret) { + t.Fatalf("portal view form leaked token") + } + + values := url.Values{} + values.Set("token", portalSecret) + values.Set("nda_accepted", "true") + values.Set("nda_accepted_by", "rita@example.test") + view := postFormNoAuthRaw(t, server, "/v1/customer-portal/package/view", values, http.StatusOK) + assertNoStoreHTMLHeaders(t, view) + htmlBody := view.Body.String() + for _, want := range []string{packageID, "Customer <script>alert(1)</script>", "ACME <b>review</b>", "manifest_hash", "limitations"} { + if !strings.Contains(htmlBody, want) { + t.Fatalf("portal view missing %q: %s", want, htmlBody) + } + } + for _, forbidden := range []string{portalSecret, " Date: Mon, 1 Jun 2026 18:21:44 +0300 Subject: [PATCH 240/287] test(packages): add reviewer workflow proof --- .productization_next_steps_missing.md | 12 +- Makefile | 9 +- docs/README.md | 1 + docs/how-to/review-customer-package.md | 103 +++++++++++++ docs/how-to/view-packages.md | 2 + .../end-to-end-release-evidence/README.md | 12 ++ .../sample-customer-package.zip | Bin 4639 -> 6572 bytes scripts/reviewer_package_workflow_check.sh | 137 ++++++++++++++++++ 8 files changed, 273 insertions(+), 3 deletions(-) create mode 100644 docs/how-to/review-customer-package.md create mode 100755 scripts/reviewer_package_workflow_check.sh diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index bc7ea0b..22caa4b 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -461,7 +461,7 @@ Implementation rules: - Link from release validation and production readiness docs. - Run `make docs-check`. -## Epic E7 - Turn Reviewer UX Into A Minimal Product Surface [ ] +## Epic E7 - Turn Reviewer UX Into A Minimal Product Surface [x] Description: Decide and implement the smallest browser-facing surface needed to make customer package review credible without building a broad UI. @@ -506,7 +506,7 @@ behavior. Tokens are accepted only in form bodies, are not copied into returned HTML or URLs, and the form-backed ZIP download reuses the existing portal archive export path. -### Ticket E7-T3 - Add reviewer export/download workflow proof [ ] +### Ticket E7-T3 - Add reviewer export/download workflow proof [x] Description: Prove that a reviewer can open a package, inspect limitations, download the ZIP/report, and run verification instructions without maintainer @@ -519,6 +519,14 @@ Implementation rules: - Keep output language free of compliance/security guarantees. - Run `make demo-check`, `make package-viewer-check`, and `make docs-check`. +Repo-local status: complete. `docs/how-to/review-customer-package.md` now gives +the reviewer workflow for manifest/archive verification, local viewer +inspection, static `report.html`, server-hosted portal review, and escalation. +`scripts/reviewer_package_workflow_check.sh` validates the checked sample +manifest checksum, package verifier output, safe ZIP extraction, report +contents, and absence of raw payload/object key/token hash/internal-note/script +markers. + ## Epic E8 - Gather External Market And Adoption Evidence [ ] Description: The remaining strongest productization gap is not code. It is diff --git a/Makefile b/Makefile index 7784a47..8d0cd52 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ GOVULNCHECK_VERSION ?= v1.2.0 TAG ?= -.PHONY: help tools fmt lint vuln gosec test test-race fuzz-smoke coverage coverage-check openapi-check openapi-precision-check meta-check docs-check deploy-check sdk-check demo-check local-ci-simulation-check black-box-demo-check benchmark-check package-viewer-check restore-rehearsal-check fast-check finalize release-acceptance release-check production-check release-candidate-check public-release-verify migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean +.PHONY: help tools fmt lint vuln gosec test test-race fuzz-smoke coverage coverage-check openapi-check openapi-precision-check meta-check docs-check deploy-check sdk-check demo-check local-ci-simulation-check reviewer-package-workflow-check black-box-demo-check benchmark-check package-viewer-check restore-rehearsal-check fast-check finalize release-acceptance release-check production-check release-candidate-check public-release-verify migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean help: ## Show help @awk 'BEGIN {FS=":.*## "}; /^[a-zA-Z0-9_.-]+:.*## / { printf " %-18s %s\n", $$1, $$2 }' $(MAKEFILE_LIST) @@ -154,6 +154,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @test -f docs/reference/worker-outbox.md @test -f docs/reference/release-validation.md @test -f docs/reference/upload-manifest.md + @test -f docs/how-to/review-customer-package.md @test -f schemas/upload-manifest.v1.schema.json @test -f docs/explanation/trust-model.md @test -f docs/collectors/source-snapshots.md @@ -171,6 +172,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod "tutorials/getting-started.md" \ "how-to/install-and-operate.md" \ "how-to/view-packages.md" \ + "how-to/review-customer-package.md" \ "how-to/integrate-ci.md" \ "api.md" \ "operations.md" \ @@ -354,6 +356,7 @@ sdk-check: ## Validate SDK helper and generated route-catalog coverage against O demo-check: ## Validate checked end-to-end evidence demo fixtures @test -x examples/end-to-end-release-evidence/run-local-demo.sh @test -x scripts/local_ci_simulation_check.sh + @test -x scripts/reviewer_package_workflow_check.sh @test -f examples/end-to-end-release-evidence/README.md @test -f examples/end-to-end-release-evidence/release-evidence-manifest.json @test -f examples/end-to-end-release-evidence/sample-readiness-report.json @@ -373,10 +376,14 @@ demo-check: ## Validate checked end-to-end evidence demo fixtures @grep -F 'reviewer_checklist' examples/end-to-end-release-evidence/sample-customer-package-manifest.json >/dev/null @grep -F 'escalation_path' examples/end-to-end-release-evidence/sample-customer-package-manifest.json >/dev/null @grep -F 'sbom_component_purl' examples/end-to-end-release-evidence/sample-customer-package-manifest.json >/dev/null + @scripts/reviewer_package_workflow_check.sh local-ci-simulation-check: ## Run local one-command CI evidence simulation without external services @scripts/local_ci_simulation_check.sh +reviewer-package-workflow-check: ## Validate offline reviewer package verification, extraction, and report inspection + @scripts/reviewer_package_workflow_check.sh + black-box-demo-check: ## Run live PostgreSQL black-box API/worker demo; requires EVYDENCE_TEST_DATABASE_URL @scripts/black_box_demo_check.sh diff --git a/docs/README.md b/docs/README.md index f7035d4..6c8d10f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -17,6 +17,7 @@ This documentation is organized by reader task. Implementation claims should be - [Air-gapped installation](air-gapped.md): build, sign, transfer, verify, and import an offline package. - [Release signing](release-signing.md): create and verify local release artifact manifests. - [View packages locally](how-to/view-packages.md): inspect package, readiness, and evidence-bundle JSON without uploading it. +- [Review a customer package](how-to/review-customer-package.md): verify, inspect, and escalate a scoped package with checked fixtures. - [Production hardening review](production-hardening.md): review production configuration, backups, ingress, diagnostics, and customer package controls. - [Pilot deployment checklist](how-to/pilot-deployment-checklist.md): copy-paste checklist for the narrow design-partner pilot profile. - [Backup and restore runbook](runbooks/backup-restore.md): rehearse paired database/object-store restore and verification. diff --git a/docs/how-to/review-customer-package.md b/docs/how-to/review-customer-package.md new file mode 100644 index 0000000..67b27a1 --- /dev/null +++ b/docs/how-to/review-customer-package.md @@ -0,0 +1,103 @@ +# Review A Customer Package + +This how-to is for a customer reviewer or internal product-security reviewer +who received a scoped Evydence customer package. It uses the checked sample +fixture so the workflow can be tested without a running API or maintainer +access. + +Evydence packages support technical evidence review and compliance readiness. +They are not legal compliance proof, certification, complete SBOM proof, +authoritative vulnerability results, regulator acceptance, or secure-release +guarantees. + +## Inputs + +Use the checked sample files: + +```sh +examples/end-to-end-release-evidence/sample-customer-package-manifest.json +examples/end-to-end-release-evidence/sample-customer-package.zip +``` + +For a real review, use only package files received through an approved sharing +path. Portal package tokens are bearer secrets. Do not paste them into URLs, +public issues, logs, chat transcripts, or screenshots. + +## Verify The Manifest Or Archive + +Verify the manifest directly: + +```sh +go run ./cmd/evydence package verify \ + --manifest examples/end-to-end-release-evidence/sample-customer-package-manifest.json \ + --expected-package-id csp_example \ + --expected-product-id prod_example \ + --expected-release-id rel_example +``` + +Verify the ZIP archive and its embedded manifest/report metadata: + +```sh +go run ./cmd/evydence package verify \ + --archive examples/end-to-end-release-evidence/sample-customer-package.zip \ + --expected-package-id csp_example \ + --expected-product-id prod_example \ + --expected-release-id rel_example +``` + +Expected result: `customer package verified` with package, product, release, +manifest hash, and evidence-bundle status. + +## Inspect The Package + +Open the local viewer at `site/package-viewer/index.html`, then load +`examples/end-to-end-release-evidence/sample-customer-package-manifest.json`. +The viewer runs locally in the browser and does not upload files. + +For ZIP packages, unpack the archive and open `report.html`. The static report +is generated from the redacted package manifest and local inline styles. It +does not require a running Evydence API. + +When an Evydence API is running and the package owner issued a portal token, +open `/v1/customer-portal/package/view`. The portal page accepts tokens only in +form bodies, uses no-store cache headers, and reuses the same server-side +package scope, expiry, NDA, watermark, and audit controls as the JSON and ZIP +portal endpoints. + +## Review Checklist + +Confirm these sections before relying on the package for a customer or internal +review: + +- package scope: package ID, product ID, release ID, expiry, and redaction + profile; +- included evidence: artifact digests, SBOM metadata, vulnerability scan + metadata, VEX or manual vulnerability decisions, release bundle, approvals, + exceptions, and waivers when present; +- excluded evidence: anything omitted by the redaction profile or outside the + package scope; +- verification material: manifest hash, release bundle hash, audit-chain + summary, and verifier output; +- vulnerability answer: whether the relevant CVE is affected, fixed, + not affected, or under investigation, plus customer-visible impact/action + statements; +- gaps and limitations: missing evidence, stale evidence, assumptions, and + explicit non-claims. + +Escalate to the package owner when the package is expired, verification fails, +the relevant vulnerability or artifact is absent, the VEX/decision explanation +is incomplete, or the requested evidence is outside the redaction scope. + +## Checked Workflow + +Run the deterministic reviewer workflow check: + +```sh +make reviewer-package-workflow-check +``` + +The check verifies the sample manifest checksum, runs the package verifier on +the manifest and archive, safely extracts the ZIP under `tmp/`, confirms +`report.html` contains verification and limitations sections, and fails if the +fixture exposes raw payload references, object-store keys, private-key markers, +portal-token hashes, internal notes, or script tags. diff --git a/docs/how-to/view-packages.md b/docs/how-to/view-packages.md index 63eff72..0a5fd69 100644 --- a/docs/how-to/view-packages.md +++ b/docs/how-to/view-packages.md @@ -29,6 +29,8 @@ server-backed review page. It accepts portal tokens only in form bodies, sets no-store browser cache headers, and renders the same scoped package data exposed by `POST /v1/customer-portal/package`. The page includes a separate ZIP download form so the token is never copied into the returned HTML or a URL. +For the full reviewer workflow, see +[Review a customer package](review-customer-package.md). Open the file in a browser, then select a JSON package, readiness report, evidence bundle, or package manifest from disk. The viewer runs entirely in the diff --git a/examples/end-to-end-release-evidence/README.md b/examples/end-to-end-release-evidence/README.md index 2698db8..48073e4 100644 --- a/examples/end-to-end-release-evidence/README.md +++ b/examples/end-to-end-release-evidence/README.md @@ -133,6 +133,18 @@ go run ./cmd/evydence package verify \ --expected-package-id csp_example ``` +The deterministic reviewer workflow is checked by: + +```sh +make reviewer-package-workflow-check +``` + +That target verifies the manifest checksum, validates the manifest and archive, +safely extracts the ZIP under `tmp/`, and checks the generated `report.html` +for verification and limitations sections without exposing raw payload refs, +object-store keys, token hashes, private-key markers, internal notes, or script +tags. + To verify the release bundle through the API, read the bundle id from `release-bundle.json` and call: diff --git a/examples/end-to-end-release-evidence/sample-customer-package.zip b/examples/end-to-end-release-evidence/sample-customer-package.zip index aeb3d84452513cafbe86c7a179ea13a2c5a32262..5c275c26efdc5aee5e4c30216b73637ec82634ee 100644 GIT binary patch delta 2106 zcmZ{lXHXM}630U*K?p|?q!|cGF%)Tr5)rBD1p|R#2nYz$1wsx20wMv7NKNQcr56p= zfZ#zmlp+YBB>Dj5!5!@sA|R1qp*;1ynK$pl+nw2&-Tlvh_uH>rwb8KkwFHS@KpFr5 z2m=5TDuC5aX|fgw0H}}w07Sn}!~FHl7B7ZHxvDat$$k!c$S_2NKzR6Avvvy!*X1$7IMvWCPTkq-rhMzL z`p4}MOYvh|;%&nOq6JB`PtaVdwNy}YT8P7hc2=HMd^HMl_|v~Ne=7?X3erYDyemDT zRMR?@na~98)A2m6jtNqudK}%7!>g+fAQk(!dD$ASVC~_|D@OwB5^Wx5fE0U^2OCt+ zUX|oCps&CeX)0ELjZ`JvKb6#+(ig_D#{i2TEviH>=N>yZDEl=tRG>>!(>v zBxmpjf?-A?d1fHl6UVAGHJ1g_rk2_B*2Q$&p`=2^2*Xn=;ss$Rg9_V@FJ#?${(|5w z1`EVnwxVg|Sz!WZD*?*`Ip?@O$H*tOSw{sFjTlN@FT4vystpxZDgjx58=28*R??bU zF;8Dkp}fGDpq_63$CH2^AN|H`hGlV3t<^ojiY5}+(P*#_cBBv3eYnQlg^M}JPlVRA ztG<2G_ax@BQIoIshhN0uF(Ht+W^UotT6uBcur_2#FV;_P$^8yZMF^kJ6wz#22M5bm zXXLbAPFy*$U9g+@a=3p!T%{qI?13HsSc}Wpic}de&?^%6%OjwiiEgQ8ttf=s+EHxm z8Pbv89y+*O?5B36@@hn1cGRYJ88b>J#%)ja%;tA>6{G51*j%W<#8FGV?k%h=9Y&55 zbYV|l0!#GvcDctq8?+(M4{~;vMbL>>Zjr0PsG)(zxv8iz2ipOCmn7jNly;^LBk!c0 z_I=!lTkZM^^@@5Ci~4%4R3=_#OcVQ*lnTFXJ*DNtCXg{|nl~&4DhF~VXT9&|wAjyG zu+VF$aj>rMK9drWSU>&#?Ii7uVFu>JV$kJb_}4iYCQHweFj{8MQdz9UL60o6-GgrAMExiIl8bImqjE?WER|n2&g1 z_8#B5@gVWM^yZC#XC}fj$lT2{1>SQ0^SHfjVPP3@r!kXE=_9F$>h>E z#x=C7)$YD6HvLr6=qyr;;$qxyZ%NbH*!8N`v$i-!^GFK1ZNj%XVKzcaX&)bUj8_0I zbZ%$&>9Skn5I!94LWEySI`LyV5hlBuVYL1MXo6yJgWLKw)A(iJUU24-Hv4O7RX$ZhGt% zl=m_D-Ad@4M@^O;hm|M6j&-@y-;(fKj+A(l{*6M-bzjJnEYhQ1+*qaRuP^*p@&o^r zMMwbJccSk%!GXd%>IH7^6jq~Cpi~puQ2|$uCvnQXK<*qzRgH>``V_L z4?Kv$z`$+aPw-UokjdTp6^p>FY$Sx&>_!8jY=JG`E?mz@qL0 zK}E5}a}$`0$wRyvVQNu`J?1<_KFgpty{*0xq}K6OOeQkO6TyKL6*s=|+A)c4o;%^U zJeA^0`Ngg})=AUE(?C}Siy76Wx$?X$K0u3=ex=DpssY6EjtNEb-NC=*Uk^Pe`qvC5 z?u7T;KNeC%GJS!%fp<%M>`&qbH5y34EYrg1-GxI6am>4VEqA_QPwATm+Kvw>ojW6; z4EYXJKuzM08tRP?^7o4%p1u(ghW{zx&m9w1Q2w#|5jBa!-+@f<_6hb5@cXYQ7bU68 z2gnVTRN|A)&5%@9__tOL3;;OUTH2s&PZOhw|FH`eQxN>=mAfpdf%^Ue|NqDQPuEGYKH5%D=*Lp%dxr4=02*>Xx__X8;05AYRgVf`fsfATc>RF+Ei; zt2jR|z#F7tAy~sf2{}f&$qzv6Ns{6qz1h4{tYE#9EhN=NSlK{qRvI0A diff --git a/scripts/reviewer_package_workflow_check.sh b/scripts/reviewer_package_workflow_check.sh new file mode 100755 index 0000000..29b2ed7 --- /dev/null +++ b/scripts/reviewer_package_workflow_check.sh @@ -0,0 +1,137 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$ROOT" + +fail() { + printf '%s\n' "reviewer-package-workflow-check: $*" >&2 + exit 1 +} + +workdir="${EVYDENCE_REVIEWER_WORKFLOW_DIR:-tmp/reviewer-package-workflow}" +case "$workdir" in + tmp/*) ;; + *) fail "EVYDENCE_REVIEWER_WORKFLOW_DIR must stay under tmp/" ;; +esac + +manifest="examples/end-to-end-release-evidence/sample-customer-package-manifest.json" +manifest_sum="examples/end-to-end-release-evidence/sample-customer-package-manifest.sha256" +archive="examples/end-to-end-release-evidence/sample-customer-package.zip" + +for path in "$manifest" "$manifest_sum" "$archive" "docs/how-to/review-customer-package.md"; do + [[ -f "$path" ]] || fail "missing $path" +done + +rm -rf -- "$workdir" +mkdir -p -- "$workdir" + +( + cd "$(dirname "$manifest")" + sha256sum -c "$(basename "$manifest_sum")" >/dev/null +) + +go run ./cmd/evydence package verify \ + --manifest "$manifest" \ + --expected-package-id csp_example \ + --expected-product-id prod_example \ + --expected-release-id rel_example \ + >"$workdir/manifest-verify.txt" + +go run ./cmd/evydence package verify \ + --archive "$archive" \ + --expected-package-id csp_example \ + --expected-product-id prod_example \ + --expected-release-id rel_example \ + >"$workdir/archive-verify.txt" + +python3 - "$manifest" "$archive" "$workdir" <<'PY' +import json +import pathlib +import sys +import zipfile + +manifest_path = pathlib.Path(sys.argv[1]) +archive_path = pathlib.Path(sys.argv[2]) +workdir = pathlib.Path(sys.argv[3]) +extract_dir = workdir / "extracted" +extract_dir.mkdir(parents=True, exist_ok=True) + +manifest = json.loads(manifest_path.read_text()) +required_manifest = [ + "reviewer_checklist", + "readiness_summary", + "verification_material", + "limitations", + "non_claims", + "vulnerability_decisions", +] +missing = [key for key in required_manifest if key not in manifest] +if missing: + raise SystemExit(f"manifest missing reviewer sections: {', '.join(missing)}") + +checklist_ids = set() +for item in manifest["reviewer_checklist"]: + if not isinstance(item, dict): + raise SystemExit("reviewer_checklist entries must be objects") + checklist_ids.add(item.get("id", "")) +for key in ("package_scope", "included_evidence", "excluded_evidence", "hash_signature_verification", "non_claims", "escalation_path"): + if key not in checklist_ids: + raise SystemExit(f"reviewer_checklist missing {key}") + +for forbidden in ("payload_ref", "object_key", "private_key", "token_hash", "internal note", "raw scanner payload"): + if forbidden in json.dumps(manifest, sort_keys=True).lower(): + raise SystemExit(f"manifest leaked forbidden marker {forbidden}") + +with zipfile.ZipFile(archive_path) as zf: + names = set(zf.namelist()) + required_archive = {"manifest.json", "package.json", "verification.json", "report.html"} + missing_archive = sorted(required_archive - names) + if missing_archive: + raise SystemExit(f"archive missing {', '.join(missing_archive)}") + for info in zf.infolist(): + target = extract_dir / info.filename + resolved = target.resolve() + if not str(resolved).startswith(str(extract_dir.resolve()) + "/") and resolved != extract_dir.resolve(): + raise SystemExit(f"archive path escapes extraction root: {info.filename}") + if info.file_size > 2 * 1024 * 1024: + raise SystemExit(f"archive entry too large for reviewer fixture: {info.filename}") + if info.is_dir(): + continue + target.parent.mkdir(parents=True, exist_ok=True) + target.write_bytes(zf.read(info.filename)) + +report = (extract_dir / "report.html").read_text() +report_lower = report.lower() +for expected in ("limitations", "non-claims", "verification", "vulnerability"): + if expected not in report_lower: + raise SystemExit(f"report.html missing {expected}") +for forbidden in ("payload_ref", "object_key", "private_key", "token_hash", "internal note", "/dev/null +grep -F "customer package verified" "$workdir/archive-verify.txt" >/dev/null +grep -F "reviewer package workflow passed" "$workdir/summary.txt" >/dev/null + +printf '%s\n' "reviewer-package-workflow-check: passed" From 6d07749ad35f4ff412a76abc87254a0947c99fbf Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 18:35:38 +0300 Subject: [PATCH 241/287] test(productization): preserve portal coverage gate --- internal/adapters/httpapi/router_test.go | 53 ++++++++++++++++++++++++ internal/app/productization_flow_test.go | 11 +++++ 2 files changed, 64 insertions(+) diff --git a/internal/adapters/httpapi/router_test.go b/internal/adapters/httpapi/router_test.go index 97eebd8..3e09c70 100644 --- a/internal/adapters/httpapi/router_test.go +++ b/internal/adapters/httpapi/router_test.go @@ -1488,6 +1488,59 @@ func TestCustomerPortalPackageViewHTMLSafety(t *testing.T) { } } +func TestCustomerPortalPackageFormValidation(t *testing.T) { + server, _ := testServer(t) + valid := url.Values{"token": {"secret"}, "nda_accepted": {"true"}, "nda_accepted_by": {"reviewer@example.test"}} + for _, tc := range []struct { + name string + path string + contentType string + body string + }{ + {name: "missing content type", path: "/v1/customer-portal/package/view", body: valid.Encode()}, + {name: "query string rejected", path: "/v1/customer-portal/package/view?token=secret", contentType: "application/x-www-form-urlencoded", body: valid.Encode()}, + {name: "unknown field", path: "/v1/customer-portal/package/view", contentType: "application/x-www-form-urlencoded", body: "token=secret&extra=true"}, + {name: "duplicate token", path: "/v1/customer-portal/package/view", contentType: "application/x-www-form-urlencoded", body: "token=secret&token=other"}, + {name: "invalid checkbox", path: "/v1/customer-portal/package/view", contentType: "application/x-www-form-urlencoded", body: "token=secret&nda_accepted=maybe"}, + {name: "empty token", path: "/v1/customer-portal/package/view", contentType: "application/x-www-form-urlencoded", body: "token=%20"}, + } { + t.Run(tc.name, func(t *testing.T) { + rec := httptest.NewRecorder() + req := httptest.NewRequest(http.MethodPost, tc.path, strings.NewReader(tc.body)) + if tc.contentType != "" { + req.Header.Set("Content-Type", tc.contentType) + } + server.Handler().ServeHTTP(rec, req) + if rec.Code != http.StatusBadRequest { + t.Fatalf("status=%d want=%d body=%s", rec.Code, http.StatusBadRequest, rec.Body.String()) + } + if strings.Contains(rec.Body.String(), "secret") { + t.Fatalf("validation error leaked token: %s", rec.Body.String()) + } + }) + } + + var b strings.Builder + portalHTMLValue(&b, map[string]any{ + "string": "value", + "bool": true, + "number": float64(3), + "list": []any{"a", false}, + "empty": []any{}, + "object": map[string]any{"nested": "ok", "token_hash": "forbidden"}, + "too_deep": map[string]any{"a": map[string]any{"b": map[string]any{"c": map[string]any{"d": map[string]any{"e": map[string]any{"f": "omitted"}}}}}}, + }, 0) + htmlBody := b.String() + for _, want := range []string{"string", "value", "true", "3", "nested", "nested content omitted"} { + if !strings.Contains(htmlBody, want) { + t.Fatalf("rendered value missing %q: %s", want, htmlBody) + } + } + if strings.Contains(htmlBody, "forbidden") || strings.Contains(htmlBody, "token_hash") { + t.Fatalf("rendered value leaked sensitive key: %s", htmlBody) + } +} + func TestFutureExtensionAndReadAdminHTTPGaps(t *testing.T) { ledger := app.NewLedger(app.Config{APIKeyPepper: "test"}) _, _, secret, err := ledger.BootstrapTenant(t.Context(), "Tenant", "admin", []string{"*", app.ScopeInstanceAdmin}) diff --git a/internal/app/productization_flow_test.go b/internal/app/productization_flow_test.go index ea9f863..422e828 100644 --- a/internal/app/productization_flow_test.go +++ b/internal/app/productization_flow_test.go @@ -214,6 +214,17 @@ func TestVEXFirstReleaseEvidenceFlowEndToEnd(t *testing.T) { t.Fatalf("decision export leaked unsafe content: %s", decisionExport) } + flow, err := ledger.ReleaseEvidenceFlowPlan(ctx, actor, release.ID) + if err != nil { + t.Fatalf("release evidence flow: %v", err) + } + if flow.Status != "ready_for_review" || flow.Counts["sboms"] != 1 || flow.Counts["release_bundles"] != 1 || len(flow.Steps) == 0 { + t.Fatalf("release evidence flow incomplete: %#v", flow) + } + if !strings.Contains(flow.Steps[0].NextReference, "/v1/artifacts") || !flow.Steps[0].IdempotencyRequired { + t.Fatalf("release evidence step metadata incomplete: %#v", flow.Steps[0]) + } + auditVerification, err := ledger.VerifySubject(ctx, actor, "audit_chain", "") if err != nil { t.Fatalf("verify audit chain: %v", err) From c1c267193c3b26014a31c42d89cf35c781ba4ba5 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 18:40:21 +0300 Subject: [PATCH 242/287] docs(product): close productization audit loop --- .productization_next_steps_missing.md | 36 ++++++++++++++++++------ README.md | 2 +- docs/reference/production-exit-review.md | 12 ++++---- 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index 22caa4b..5b4c195 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -527,13 +527,13 @@ manifest checksum, package verifier output, safe ZIP extraction, report contents, and absence of raw payload/object key/token hash/internal-note/script markers. -## Epic E8 - Gather External Market And Adoption Evidence [ ] +## Epic E8 - Gather External Market And Adoption Evidence [e] Description: The remaining strongest productization gap is not code. It is evidence that a non-maintainer can use Evydence on a real release to answer a customer/security review question. -### Ticket E8-T1 - [e] Run one design-partner pilot [ ] +### Ticket E8-T1 - Run one design-partner pilot [e] Description: Use Evydence with a non-maintainer team on one real release and generate a customer-safe release evidence package. @@ -551,7 +551,7 @@ External reason: - Requires an external organization or design partner and permission to use the outcome. -### Ticket E8-T2 - [e] Publish an anonymized pilot report or case study [ ] +### Ticket E8-T2 - Publish an anonymized pilot report or case study [e] Description: Publish a sanitized report showing one real release-evidence workflow, verification path, limitations, and accepted gaps. @@ -567,7 +567,7 @@ External reason: - Requires external customer/design-partner approval. -### Ticket E8-T3 - [e] Update public GitHub description to VEX-first positioning [ ] +### Ticket E8-T3 - Update public GitHub description to VEX-first positioning [e] Description: Update the repository description so the public GitHub first impression matches the README's sharper VEX-first release-evidence story. @@ -586,12 +586,12 @@ External reason: - GitHub repository description and topics are provider settings. -## Epic E9 - Re-Audit And Close Productization Loop [ ] +## Epic E9 - Re-Audit And Close Productization Loop [x] Description: Re-run audits after the repo-local tickets are complete and only raise product claims when evidence supports them. -### Ticket E9-T1 - Re-run production readiness public repo audit loop [ ] +### Ticket E9-T1 - Re-run production readiness public repo audit loop [x] Description: Re-run `production-readiness-public-repo-audit-loop` after E1-E7 repo-local work is complete. @@ -603,7 +603,14 @@ Implementation rules: - Treat `[e]` external items as tracked dependencies, not local failures. - Do not run remediation in the audit turn unless explicitly requested. -### Ticket E9-T2 - Re-run product-code audit focused on the VEX-first buyer path [ ] +Repo-local status: complete. The current audit is recorded in +`.audits/production_readiness_v2/analysis.md` with an overall score of `8.3/10` +and verdict `Production-usable with caveats` for the controlled self-hosted +candidate profile. It explicitly keeps public Scorecard alert closure, GitHub +security settings, public description changes, and design-partner proof as +external dependencies. + +### Ticket E9-T2 - Re-run product-code audit focused on the VEX-first buyer path [x] Description: Re-audit whether the implemented product now fulfills the VEX-first customer-question workflow without overclaiming production or @@ -615,7 +622,13 @@ Implementation rules: customer package verification path. - Turn findings into a follow-up backlog rather than broad feature expansion. -### Ticket E9-T3 - Decide release status wording after audits [ ] +Repo-local status: complete. The current product-code audit is recorded in +`.audits/product_code_audit_v4/audit.md` with an overall score of `8.4/10` and +verdict `Production-usable with caveats`. The audit verifies the VEX-first +release-evidence flow, customer package viewer, portal review page, reviewer +workflow proof, public rc5 verifier, and production gate. + +### Ticket E9-T3 - Decide release status wording after audits [x] Description: Decide whether the next release remains a controlled self-hosted production candidate or can adopt a stronger narrow self-hosted production @@ -630,3 +643,10 @@ Implementation rules: secure-release claims out of scope unless independently proven. - Update README, changelog, release notes, production readiness, release evidence index, and commercial docs together. + +Repo-local status: complete. The release status remains `controlled self-hosted +production candidate`. The audits do not justify stronger broad production, +regulated production, hosted SaaS, legal compliance, certification, +complete-SBOM, authoritative-scanner, or release-security guarantee wording. +The production exit review now references the audit closeout and keeps the +existing conservative status. diff --git a/README.md b/README.md index b1091b2..5503eef 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![OpenSSF Scorecard](https://github.com/aatuh/evydence/actions/workflows/scorecard.yml/badge.svg)](https://github.com/aatuh/evydence/actions/workflows/scorecard.yml) [![License: AGPL-3.0-only](https://img.shields.io/badge/license-AGPL--3.0--only-blue.svg)](LICENSE) ![Go Version](https://img.shields.io/badge/go-1.25+-00ADD8.svg) -![OpenAPI](https://img.shields.io/badge/OpenAPI-171%20precise%20operations-brightgreen.svg) +![OpenAPI](https://img.shields.io/badge/OpenAPI-186%20precise%20operations-brightgreen.svg) ![Coverage Gate](https://img.shields.io/badge/production%20coverage-80%25+-brightgreen.svg) Evydence is a self-hosted, API-first release evidence ledger for product diff --git a/docs/reference/production-exit-review.md b/docs/reference/production-exit-review.md index ffd9e58..62b986e 100644 --- a/docs/reference/production-exit-review.md +++ b/docs/reference/production-exit-review.md @@ -12,7 +12,7 @@ SaaS-ready, legally compliant, certified, or secure-release-guaranteed. ## Repo-Verified Strengths -- API contract has 183 precise `/v1` operations and zero broad operations. +- API contract has 186 precise `/v1` operations and zero broad operations. - `make production-check` is available and requires live PostgreSQL, coverage, migration compatibility, release validation, race tests, security scans, and release-signing smoke checks. @@ -70,7 +70,9 @@ SaaS-ready, legally compliant, certified, or secure-release-guaranteed. ## Decision The current repository can support controlled self-hosted evaluation, pilots, -and internal production after operator review. It should not be marketed as -broad production-ready for most uses until the external controls above are -closed and a fresh product, codebase, security, documentation, and test audit -confirms the change. +and internal production after operator review. The productization audit closeout +in `.audits/production_readiness_v2/` and `.audits/product_code_audit_v4/` +supports keeping this controlled candidate status, not strengthening it. It +should not be marketed as broad production-ready for most uses until the +external controls above are closed and a fresh product, codebase, security, +documentation, and test audit confirms the change. From efcb324e9b52335794fb3dc53d4cb0916cce0c0b Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 18:41:33 +0300 Subject: [PATCH 243/287] docs(product): mark external backlog dependencies --- .productization_next_steps_missing.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index 5b4c195..d7beb87 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -132,7 +132,7 @@ Implementation rules: possible. - Run `make docs-check` and `make release-acceptance`. -### Ticket E1-T5 - [e] Configure external publishing credentials if required [ ] +### Ticket E1-T5 - Configure external publishing credentials if required [e] Description: If least-privilege release publishing requires a fine-grained PAT, GitHub App token, or registry credential, create and configure the external @@ -148,7 +148,7 @@ External reason: - GitHub repository secrets and app/PAT creation are provider/account settings. -### Ticket E1-T6 - [e] Verify GitHub private vulnerability reporting and secret scanning [ ] +### Ticket E1-T6 - Verify GitHub private vulnerability reporting and secret scanning [e] Description: Confirm GitHub private vulnerability reporting, secret scanning, and push protection are enabled where available. From 47b905fb555f18285a45de875ebae27cf3a52444 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 18:43:50 +0300 Subject: [PATCH 244/287] docs(product): record provider backlog status --- .productization_next_steps_missing.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index d7beb87..3ec86d5 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -148,7 +148,7 @@ External reason: - GitHub repository secrets and app/PAT creation are provider/account settings. -### Ticket E1-T6 - Verify GitHub private vulnerability reporting and secret scanning [e] +### Ticket E1-T6 - Verify GitHub private vulnerability reporting and secret scanning [x] Description: Confirm GitHub private vulnerability reporting, secret scanning, and push protection are enabled where available. @@ -162,6 +162,13 @@ External reason: - These are GitHub account/repository security settings, not source files. +Provider status: complete. `gh api repos/aatuh/evydence --jq +'.security_and_analysis'` shows Dependabot security updates enabled, secret +scanning enabled, and secret scanning push protection enabled. `gh api +repos/aatuh/evydence/private-vulnerability-reporting` returns +`{"enabled":true}`. `gh api repos/aatuh/evydence/secret-scanning/alerts` +returned zero alerts at verification time. + ## Epic E2 - Make The First Ten Minutes Reviewer-Obvious [x] Description: Convert the already implemented VEX-first flow into an evaluation @@ -567,7 +574,7 @@ External reason: - Requires external customer/design-partner approval. -### Ticket E8-T3 - Update public GitHub description to VEX-first positioning [e] +### Ticket E8-T3 - Update public GitHub description to VEX-first positioning [x] Description: Update the repository description so the public GitHub first impression matches the README's sharper VEX-first release-evidence story. @@ -586,6 +593,11 @@ External reason: - GitHub repository description and topics are provider settings. +Provider status: complete. `gh repo edit aatuh/evydence --description` updated +the public description to `Self-hosted VEX-first release evidence ledger for +customer CVE, SBOM, provenance, and release-review questions.` and `gh repo +view aatuh/evydence --json description,repositoryTopics` verified the result. + ## Epic E9 - Re-Audit And Close Productization Loop [x] Description: Re-run audits after the repo-local tickets are complete and only From 356273d52ae19dbe2853299bc2a7ae82cb5706d4 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 18:44:50 +0300 Subject: [PATCH 245/287] docs(product): document publishing secret dependency --- .productization_next_steps_missing.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index 3ec86d5..710447f 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -148,6 +148,14 @@ External reason: - GitHub repository secrets and app/PAT creation are provider/account settings. +Provider status: external. `gh secret list --repo aatuh/evydence` verifies +`EVYDENCE_RELEASE_SIGNING_PRIVATE_KEY_B64` is configured. The least-privilege +workflow publication secrets `EVYDENCE_RELEASE_PUBLISH_TOKEN` and +`EVYDENCE_GHCR_PUBLISH_TOKEN` are not listed, and their values cannot be +created from repository source. Configure them in GitHub with appropriately +scoped secret values before relying on the refactored release/container +publication workflows. + ### Ticket E1-T6 - Verify GitHub private vulnerability reporting and secret scanning [x] Description: Confirm GitHub private vulnerability reporting, secret scanning, From 085e35c86552defc131389a0b9dc93feb6592b23 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 18:56:05 +0300 Subject: [PATCH 246/287] docs(product): refresh public backlog evidence --- .productization_next_steps_missing.md | 20 +++++++++++++------- docs/reference/production-exit-review.md | 9 +++++---- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md index 710447f..a6ea58b 100644 --- a/.productization_next_steps_missing.md +++ b/.productization_next_steps_missing.md @@ -68,8 +68,10 @@ Implementation rules: Repo-local status: complete. The workflow keeps `GITHUB_TOKEN` read-only, uses `EVYDENCE_GHCR_PUBLISH_TOKEN` for GHCR publication, and scopes -`id-token: write` to the signing job. Live workflow execution and alert closure -remain external repository-state verification. +`id-token: write` to the signing job. Public Scorecard SARIF rerun +`26765714988` on commit `77ab18e5ad8b3ba3a9f4745e7f6437e5e3e1f596` closed the +related code-scanning alert. Live container publication still depends on the +external `EVYDENCE_GHCR_PUBLISH_TOKEN` secret. ### Ticket E1-T2 - Split release packaging from release publishing permissions [x] @@ -96,8 +98,10 @@ Implementation rules: Repo-local status: complete. Release package generation and draft-release publication are separate jobs, both keep `GITHUB_TOKEN` read-only, and draft publication uses `EVYDENCE_RELEASE_PUBLISH_TOKEN` only in the publication job. -Live workflow execution and any alert closure remain external repository-state -verification. +Public Scorecard SARIF rerun `26765714988` on commit +`77ab18e5ad8b3ba3a9f4745e7f6437e5e3e1f596` closed the related code-scanning +alert. Live draft-release publication still depends on the external +`EVYDENCE_RELEASE_PUBLISH_TOKEN` secret. ### Ticket E1-T3 - Make coverage gate behavior deterministic [x] @@ -626,9 +630,11 @@ Implementation rules: Repo-local status: complete. The current audit is recorded in `.audits/production_readiness_v2/analysis.md` with an overall score of `8.3/10` and verdict `Production-usable with caveats` for the controlled self-hosted -candidate profile. It explicitly keeps public Scorecard alert closure, GitHub -security settings, public description changes, and design-partner proof as -external dependencies. +candidate profile. Follow-up GitHub verification pushed the backlog commits, +confirmed CI/CodeQL/Scorecard success on commit +`77ab18e5ad8b3ba3a9f4745e7f6437e5e3e1f596`, closed open code-scanning alerts, +and verified GitHub security settings plus public description updates. The +remaining dependencies are publishing-token secrets and design-partner proof. ### Ticket E9-T2 - Re-run product-code audit focused on the VEX-first buyer path [x] diff --git a/docs/reference/production-exit-review.md b/docs/reference/production-exit-review.md index 62b986e..94da11f 100644 --- a/docs/reference/production-exit-review.md +++ b/docs/reference/production-exit-review.md @@ -52,10 +52,11 @@ SaaS-ready, legally compliant, certified, or secure-release-guaranteed. plus cosign evidence. Operators who mirror or rebuild images for Helm or air-gapped workflows must record their own image digest and verification evidence. -- GitHub private vulnerability reporting, secret scanning, branch protection, - Scorecard alert closure, and workflow execution history are external - repository-state checks. They remain required before changing the public - status beyond a controlled self-hosted production candidate. +- GitHub private vulnerability reporting, secret scanning, push protection, + Dependabot security updates, public CI, CodeQL, Scorecard, Scorecard SARIF, + and zero open code-scanning alerts have been verified for the current public + `master` state. Branch protection admin bypass state, repository secret + values, and workflow publication credentials remain provider/account checks. - Native PKCS#11/HSM module custody requires operator hardware, drivers, and provider-specific validation. - Broad WORM/object-lock proof requires object-store policy, IAM, lifecycle, From d4155b4007a4daf8ed0bd908e90792c69ade188e Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 19:06:40 +0300 Subject: [PATCH 247/287] docs(product): remove productization dotfiles --- .gitignore | 1 - .productization_next_steps.md | 1319 ------------------------- .productization_next_steps_missing.md | 678 ------------- 3 files changed, 1998 deletions(-) delete mode 100644 .productization_next_steps.md delete mode 100644 .productization_next_steps_missing.md diff --git a/.gitignore b/.gitignore index 1aecafe..dc73eb8 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,6 @@ !.env.example !.api.env.example !.test.env.example -!.productization_next_steps.md coverage.out bin/ diff --git a/.productization_next_steps.md b/.productization_next_steps.md deleted file mode 100644 index 587f4a8..0000000 --- a/.productization_next_steps.md +++ /dev/null @@ -1,1319 +0,0 @@ -# Evydence Agent Handoff: Current Situation, Target Direction, and Backlog - -## 1. Current Situation - -Evydence is already a serious self-hosted, API-first release evidence ledger. It is not an empty prototype and should not be treated as a greenfield rebuild. - -The current project already has: - -* Go implementation under `github.com/aatuh/evydence` -* HTTP API under `/v1` -* OpenAPI contract committed as `openapi.yaml` -* tenant-scoped API keys -* idempotency support for create/action endpoints -* products, projects, releases, release candidates, artifacts, evidence records, SBOMs, VEX documents, vulnerability scans, vulnerability decisions, exceptions, waivers, approvals, controls, reports, release bundles, evidence bundles, customer packages, package manifests, and audit-chain concepts -* PostgreSQL-backed durable state -* object storage via filesystem or S3/MinIO-compatible storage -* worker/outbox processing -* parser side effects for key evidence formats -* release bundle and readiness report paths -* customer-safe package export -* local package viewer -* Docker Compose and production-like Compose -* Helm chart -* air-gapped package manifest -* CLI helper -* Go, TypeScript, and Python SDK wrappers -* GitHub Actions/GitLab CI examples -* AGPL licensing and commercial licensing/support documentation -* current release candidate line with signed archives, checksums, OpenAPI/migration checksums, production-check summary, SBOM/provenance metadata, and signed release manifest - -The repo is currently best understood as: - -> A controlled self-hosted production candidate for release evidence, not yet a broad production or regulated-production system for every use case. - -The project is technically ahead of its market packaging. The biggest gap is not “more backend features.” The biggest gap is making the product immediately understandable and useful to a specific buyer. - -## 2. Target Direction - -The target product direction is: - -> Evydence should become a VEX-first self-hosted release evidence product for software vendors that need to answer customer CVE, SBOM, provenance, and security-review questions with signed, customer-safe evidence bundles. - -The target buyer is: - -* product security lead -* AppSec engineer -* release engineering lead -* platform/security engineer -* CTO or security-conscious founder at a B2B software vendor -* team selling software into enterprise, regulated, EU-facing, public-sector-adjacent, or security-sensitive customers - -The painful buyer question is: - -> “This CVE appears in your SBOM. Are you affected, why or why not, who approved that answer, and can you give us proof for this exact release?” - -The core product promise should be: - -> Stop answering customer CVE and release-security questions with spreadsheets, screenshots, scanner exports, and Slack threads. Evydence creates a signed release evidence bundle that links SBOMs, vulnerability findings, VEX decisions, provenance, approvals, limitations, and customer-safe outputs. - -## 3. Product Principle - -Evydence should not try to become: - -* a generic vulnerability scanner -* a replacement for Dependency-Track or Anchore -* a generic GRC platform -* a trust-center SaaS clone -* a legal compliance certification tool -* a full API governance platform -* a privacy/DSAR deletion platform -* a generic evidence database for every possible event - -The v1 wedge is narrower: - -> Release-scoped VEX decisions and customer-safe release evidence. - -The system may ingest many evidence types, but the visible product path should be: - -1. Create product/release/artifact -2. Upload SBOM -3. Upload vulnerability scan -4. Record or import VEX decision -5. Attach provenance/build evidence -6. Approve/waive/except where needed -7. Generate release readiness report -8. Export signed customer-safe evidence package -9. Verify package offline - -## 4. Current Product Gap - -Evydence already has many primitives, but the first-time evaluator still has to understand too much. - -The current gap is: - -* the README is accurate but still too broad -* VEX is present but not yet the obvious center of the product -* vulnerability decisions need to become the buyer-facing hero object -* customer package flow exists but should feel like the killer feature -* package viewer exists but should become reviewer-grade -* the first demo path should be shorter and more emotionally obvious -* docs should lead with CVE/SBOM/provenance customer questions -* production limitations are honest, but should be organized into a pilot-readiness path -* commercial docs exist, but need a clear “design partner/pilot package” offer -* broad feature expansion should pause until the VEX-first flow is excellent - -## 5. North-Star User Story - -As a product-security or release-engineering owner at a B2B software vendor, I want to produce a signed customer-safe evidence package for a specific release, so that I can answer customer questions about SBOM contents, CVE exposure, VEX decisions, provenance, approvals, and known limitations without manually assembling files from CI logs, scanners, tickets, and Slack. - -## 6. Non-Goals For The Next Iteration - -Do not build these next: - -* generic SBOM scanner -* hosted SaaS mode -* broad trust center -* AI questionnaire responder -* privacy deletion/retention/DSAR engine -* OpenAPI governance product -* multi-writer HA unless required for production gate work -* giant admin UI -* large connector marketplace -* full compliance certification language -* legal conclusions -* claims that Evydence proves secure releases, complete SBOM coverage, complete vulnerability detection, CRA compliance, auditor acceptance, or regulator acceptance - -Keep existing non-claim language intact. - -## 7. Recommended Milestones - -### Milestone 0: Stabilize Current Baseline - -Goal: - -> Ensure the agent understands the existing implementation before changing product direction. - -Tasks: - -* Run existing tests. -* Run `make production-check` if available and practical. -* Inspect current OpenAPI contract. -* Inspect current domain models for product, release, artifact, SBOM, VEX document, vulnerability scan, vulnerability decision, release bundle, customer package, redaction profile, and report. -* Inspect current example under `examples/end-to-end-release-evidence`. -* Inspect package viewer under `site/package-viewer`. -* Inspect release candidate docs, roadmap, and production-readiness docs. -* Do not remove existing documented production limitations. - -Acceptance criteria: - -* Current test suite passes. -* Current generated OpenAPI contract is not accidentally broken. -* Agent produces a short internal note listing the current files/packages involved in VEX, vulnerability decisions, package export, reports, and viewer rendering. -* No public claim is added that exceeds the current non-claim boundaries. - ---- - -Checklist status: `[ ]` means the item is not yet complete against its -acceptance criteria. `[x]` means the current repository has implementation, -documentation, and tests/checks that satisfy the item. - -### Milestone 1: Reposition README And First Evaluation Path - -Goal: - -> Make the first 60 seconds of the repo explain the VEX-first product wedge. - -Backlog: - -#### [x] EVY-001 — Rewrite README opening around VEX-first release evidence - -Priority: P0 - -Description: - -Rewrite the top README positioning so it leads with the buyer pain: - -> Answer customer CVE, SBOM, provenance, and release-security questions with signed release evidence bundles. - -Keep the broader release evidence ledger language, but move it below the concrete wedge. - -Acceptance criteria: - -* README first paragraph explains the buyer pain in plain English. -* README clearly states Evydence is self-hosted and API-first. -* README names the target user: product security, AppSec, platform, release engineering, compliance-readiness. -* README preserves non-claims: not legal compliance proof, not certification, not complete SBOM proof, not authoritative vulnerability result, not secure-release guarantee. -* README includes a short “before Evydence / after Evydence” example. - -#### [x] EVY-002 — Add “What question does Evydence answer?” section - -Priority: P0 - -Description: - -Add a section near the top showing examples of the questions Evydence is designed to answer: - -* Are we affected by CVE-X in release Y? -* Which SBOM was used? -* Which scanner result raised the finding? -* Who approved the VEX decision? -* What evidence supports “not affected”? -* What package can be safely shared with a customer? -* How can the customer verify the package? - -Acceptance criteria: - -* Section is concrete and buyer-facing. -* Each question maps to existing or planned Evydence objects. -* Avoid internal architecture-first language. - -#### [x] EVY-003 — Reorder quickstart around VEX-first release bundle - -Priority: P0 - -Description: - -The primary quickstart should become: - -1. create product/release/artifact -2. upload SBOM -3. upload vulnerability scan -4. record VEX decision -5. generate readiness report -6. export customer-safe package -7. view/verify package - -Acceptance criteria: - -* README “Fastest Proof Path” points to this flow. -* Existing end-to-end example is updated or supplemented. -* A new evaluator can understand the demo without reading all docs. - ---- - -### Milestone 2: Make Vulnerability Decision The Hero Object - -Goal: - -> Make the vulnerability decision / VEX decision the central operational object. - -Backlog: - -#### [x] EVY-010 — Audit current VEX and VulnerabilityDecision models - -Priority: P0 - -Description: - -Inspect current schemas and domain models for VEX documents and vulnerability decisions. Identify what exists and what is missing for a buyer-facing VEX workflow. - -Evaluate whether the model supports: - -* vulnerability ID -* source scanner or advisory -* affected component/package/purl -* product/release scope -* status -* justification -* human-readable impact statement -* evidence links -* approver -* supersession -* expiry/review date -* visibility/customer-safe flag -* internal notes -* link to source SBOM -* link to vulnerability scan finding -* link to VEX document/import -* audit history - -Acceptance criteria: - -* Document current model gap. -* Do not redesign before mapping current implementation. -* Produce concrete migration/API changes only where current model is insufficient. - -#### [x] EVY-011 — Add canonical VEX decision lifecycle - -Priority: P0 - -Description: - -Define and implement a lifecycle for vulnerability decisions. - -Suggested statuses: - -* under_investigation -* not_affected -* affected -* fixed -* accepted_risk -* false_positive -* will_not_fix -* superseded - -Exact values should align with current implementation and VEX formats where possible. - -Acceptance criteria: - -* Status transitions are explicit. -* Invalid transitions are rejected or clearly handled. -* Decisions have audit events. -* Superseding a decision preserves old decision history. -* Customer package can show only the active decision unless history is requested. -* Internal notes are not leaked into customer-safe outputs. - -#### [x] EVY-012 — Add customer-safe impact statement - -Priority: P0 - -Description: - -Add or expose a field intended for customer-safe explanation of the decision. - -Examples: - -* “This release is not affected because the vulnerable class is not included in the shipped artifact.” -* “This vulnerability is present in a build-only dependency and is not present at runtime.” -* “This issue is fixed in release 1.2.4.” -* “This issue is under investigation; current mitigation is documented in the linked exception.” - -Acceptance criteria: - -* Field is separate from internal notes. -* Field can be included in customer packages. -* Field is required for customer-visible decisions. -* API validation prevents empty customer-visible “not affected” decisions unless explicitly allowed by policy. - -#### [x] EVY-013 — Link decisions to concrete evidence - -Priority: P0 - -Description: - -Each vulnerability decision should link to supporting evidence. - -Possible evidence links: - -* SBOM document -* vulnerability scan finding -* source/build/provenance evidence -* code review note -* exception/waiver -* approval -* remediation task -* incident package -* release bundle - -Acceptance criteria: - -* API supports evidence links on decisions. -* Links are tenant-scoped. -* Links are validated to refer to existing objects. -* Customer package export can include public metadata for links without leaking raw payloads. - -#### [x] EVY-014 — Add decision history endpoint - -Priority: P1 - -Description: - -Add endpoint to retrieve all decisions for a vulnerability/product/release over time. - -Possible endpoints: - -* `GET /v1/vulnerabilities/{id}/decisions` -* `GET /v1/releases/{release_id}/vulnerability-decisions` -* `GET /v1/products/{product_id}/vulnerabilities/{vuln_id}/decision-history` - -Acceptance criteria: - -* Supports filtering by product, release, vulnerability ID, component, status, active/superseded. -* Includes decision timestamps and supersession chain. -* Respects tenant and scopes. -* OpenAPI updated. - -#### [x] EVY-015 — Add customer-safe decision summary endpoint - -Priority: P1 - -Description: - -Expose an endpoint that returns only customer-safe VEX decision summaries for a release. - -Acceptance criteria: - -* Raw internal evidence payloads are excluded. -* Internal notes are excluded. -* Non-claims and limitations are included. -* Output is suitable for package viewer and exports. - ---- - -### Milestone 3: Improve OpenVEX / CycloneDX VEX Import - -Goal: - -> Make VEX import operational, not just uploadable. - -Backlog: - -#### [x] EVY-020 — Verify current OpenVEX parser side effects - -Priority: P0 - -Description: - -Inspect current worker-owned parser side effect behavior for OpenVEX. Confirm whether imported OpenVEX creates vulnerability decisions idempotently. - -Acceptance criteria: - -* Behavior is covered by tests. -* Import idempotency is verified. -* Duplicate import does not create duplicate active decisions. -* Parser failures are visible and actionable. - -#### [x] EVY-021 — Add import report for VEX parsing - -Priority: P1 - -Description: - -When a VEX document is imported, return or generate a parser report: - -* number of statements parsed -* number of decisions created -* number of decisions updated/superseded -* unsupported fields -* warnings -* invalid statements -* mapping failures - -Acceptance criteria: - -* Import report is persisted. -* API can retrieve import report. -* Worker terminal failure contains useful problem details. -* End-to-end example shows report. - -#### [x] EVY-022 — Add VEX mapping tests - -Priority: P1 - -Description: - -Add fixture-based tests for key VEX statuses and justifications. - -Test cases: - -* not affected -* affected -* fixed -* under investigation -* multiple products/releases -* duplicate statement -* superseded decision -* unsupported/unknown status -* component identity missing -* malformed document - -Acceptance criteria: - -* Tests cover parser and resulting decision records. -* Error messages are useful. -* OpenAPI examples include at least one imported VEX document. - -#### [x] EVY-023 — Add manual decision authoring fallback - -Priority: P0 - -Description: - -Even if VEX import fails or is not available, user must be able to record a VEX-style decision manually through the API. - -Acceptance criteria: - -* Manual decision API supports required fields. -* Manual decision can be exported into customer package. -* Manual decision can be later linked to imported VEX. -* Manual decision requires justification/customer statement when customer-visible. - ---- - -### Milestone 4: Customer-Safe Package V2 - -Goal: - -> Make the customer evidence package the killer feature. - -Backlog: - -#### [x] EVY-030 — Define package v2 manifest schema - -Priority: P0 - -Description: - -Define a clear manifest schema for customer-safe release evidence packages. - -Package should include: - -* package ID -* package version -* generated timestamp -* tenant/org/product/release metadata -* artifact digests -* SBOM metadata -* vulnerability scan metadata -* active VEX decisions -* approvals -* exceptions/waivers where customer-visible -* provenance metadata -* readiness summary -* limitations and non-claims -* redaction profile used -* verification material -* audit-chain verification summary - -Acceptance criteria: - -* Manifest schema is documented. -* Manifest has stable version field. -* Manifest excludes raw secret/internal evidence payloads by default. -* Manifest can be loaded by package viewer. -* Tests verify sensitive fields are absent. - -#### [x] EVY-031 — Add package contents policy / redaction profile presets - -Priority: P0 - -Description: - -Define standard package profiles. - -Suggested profiles: - -* internal_full -* customer_safe -* security_review -* public_summary -* auditor_review - -Acceptance criteria: - -* At least `customer_safe` and `security_review` are implemented. -* Profiles are explicit and test-covered. -* Customer-safe profile excludes raw payload bytes, secrets, internal notes, internal URLs unless marked safe, and internal-only evidence. -* Package manifest names the profile used. -* API refuses unsafe export without explicit scope/permission. - -#### [x] EVY-032 — Add customer package verification command - -Priority: P1 - -Description: - -Provide CLI command to verify a package offline. - -Possible command: - -`evydence package verify --manifest package.json --bundle evidence-bundle.json` - -Acceptance criteria: - -* Verifies hashes/signatures where available. -* Verifies manifest structure. -* Verifies package was generated by expected instance/signing key if configured. -* Outputs human-readable summary. -* Exits non-zero on failure. -* Example package verification is documented. - -#### [x] EVY-033 — Improve package viewer for reviewer workflow - -Priority: P1 - -Description: - -Upgrade the local package viewer so it is no longer just a minimal JSON inspector. It should become a reviewer-friendly view. - -Viewer sections: - -* Release summary -* Artifact summary -* SBOM summary -* Vulnerability / VEX decision table -* Approvals and exceptions -* Readiness gaps -* What is included -* What is excluded -* Verification status -* Non-claims and limitations - -Acceptance criteria: - -* Viewer runs locally in browser without uploading files. -* Viewer handles sample manifest. -* Viewer clearly labels customer-safe vs internal-only data. -* Viewer highlights active VEX decisions. -* Viewer is usable from bundled demo. -* No server-side authorization assumptions are introduced. - -#### [x] EVY-034 — Add downloadable sample customer package - -Priority: P1 - -Description: - -Include a realistic non-sensitive sample package in examples. - -Acceptance criteria: - -* Sample package loads in viewer. -* Sample includes SBOM metadata, vulnerability finding, VEX decision, release bundle, readiness report, and audit verification. -* Sample avoids real secrets and raw sensitive payloads. -* README links directly to this sample path. - ---- - -### Milestone 5: Readiness Report V2 - -Goal: - -> Make readiness reports say what a customer/security reviewer actually needs to know. - -Backlog: - -#### [x] EVY-040 — Redesign release-readiness report around buyer questions - -Priority: P1 - -Description: - -Report should answer: - -* Is there an SBOM for this release? -* Is there a vulnerability scan? -* Are critical/high findings triaged? -* Are VEX decisions present for blocking findings? -* Are exceptions approved? -* Is provenance/build evidence attached? -* Are artifact digests present? -* Is the customer package safe to share? -* What gaps remain? -* What limitations apply? - -Acceptance criteria: - -* JSON report has structured sections. -* Human-readable summary is easy to convert to HTML/PDF later. -* Report distinguishes “missing evidence” from “known limitation” from “failed policy.” -* Report includes non-claim language. -* Example report updated. - -#### [x] EVY-041 — Add policy-based readiness checks - -Priority: P1 - -Description: - -Introduce or tighten configurable readiness policy checks. - -Possible default checks: - -* release has artifact -* artifact has digest -* release has SBOM -* release has vulnerability scan -* all critical/high findings have decision -* customer-visible decisions have customer-safe statements -* not_affected decisions have justification -* exceptions have approver and expiry -* release has provenance/build evidence -* package redaction profile is valid - -Acceptance criteria: - -* Policy checks are deterministic. -* Default policy is documented. -* Users can see failing checks and remediation hints. -* Tests cover pass/fail examples. -* Readiness report includes policy version. - -#### [x] EVY-042 — Add “customer-safe gaps” section - -Priority: P2 - -Description: - -Customer package should include a carefully worded gaps/limitations section. - -Acceptance criteria: - -* Gaps are factual, not legal conclusions. -* Gaps are safe to share only if marked customer-visible. -* Internal-only gaps remain internal. -* Viewer renders gaps clearly. - ---- - -### Milestone 6: CI/CD Evidence Ingest Path - -Goal: - -> Make it easy to wire Evydence into one release pipeline. - -Backlog: - -#### [x] EVY-050 — Create GitHub Actions quickstart workflow - -Priority: P0 - -Description: - -Add a minimal GitHub Actions example that: - -* builds artifact -* computes digest -* generates or attaches SBOM -* attaches vulnerability scan output -* uploads provenance/build metadata -* optionally uploads VEX document or decision file -* creates/updates release evidence bundle - -Acceptance criteria: - -* Example works against local or configured Evydence URL. -* Uses scoped API key. -* Does not require secrets beyond documented variables. -* Produces output visible in release bundle/readiness report. -* README points to this as the first CI example. - -#### [x] EVY-051 — Add CLI command for one-shot release evidence upload - -Priority: P1 - -Description: - -Simplify the CLI path. - -Possible command: - -`evydence release upload-evidence --product X --release Y --artifact path --sbom path --scan path --vex path` - -Acceptance criteria: - -* Command creates missing product/release/artifact if configured to do so, or fails with clear errors. -* Command prints next-step URL/API references. -* Command supports dry-run. -* Command has examples. - -#### [x] EVY-052 — Add manifest schema for bulk upload - -Priority: P1 - -Description: - -Formalize the bulk upload manifest used in examples. - -Acceptance criteria: - -* Schema documented. -* Validation command exists. -* Manifest supports artifact, SBOM, scan, VEX, provenance, approvals, and package export. -* Tests cover invalid manifest errors. - ---- - -### Milestone 7: Domain/API Cleanup Around VEX-First Product - -Goal: - -> Make the API feel designed around the target workflow. - -Backlog: - -#### [x] EVY-060 — Add high-level workflow endpoints if current API is too low-level - -Priority: P1 - -Description: - -Current API may already expose low-level resources. Add workflow endpoints only if they dramatically simplify evaluation. - -Possible endpoints: - -* `POST /v1/releases/{id}/evidence-flow/start` -* `POST /v1/releases/{id}/triage` -* `POST /v1/releases/{id}/customer-packages` -* `GET /v1/releases/{id}/security-summary` -* `GET /v1/releases/{id}/vex-summary` - -Acceptance criteria: - -* Workflow endpoints compose existing domain services. -* They do not duplicate business rules. -* They are optional convenience APIs. -* OpenAPI examples are included. - -#### [x] EVY-061 — Add release security summary endpoint - -Priority: P0 - -Description: - -Expose one endpoint that summarizes release evidence status for UI, package viewer, or quick checks. - -Suggested output: - -* product/release -* artifact count -* SBOM status -* vulnerability scan status -* open findings by severity -* decisions by status -* missing required decisions -* approvals/exceptions -* readiness status -* package generation status - -Acceptance criteria: - -* Endpoint is tenant-scoped. -* Output is stable and documented. -* Does not expose raw evidence payloads. -* Used by example/demo. - -#### [x] EVY-062 — Add API examples for VEX-first flow - -Priority: P1 - -Description: - -OpenAPI should include examples showing the main flow. - -Acceptance criteria: - -* Example request/response for create release. -* Example upload SBOM metadata. -* Example upload vulnerability scan. -* Example create VEX decision. -* Example generate readiness report. -* Example create customer package. -* Examples are non-sensitive and realistic. - ---- - -### Milestone 8: Minimal Admin/Reviewer UI - -Goal: - -> Add just enough UI to make the product demo understandable. - -Backlog: - -#### [x] EVY-070 — Decide UI boundary - -Priority: P0 - -Description: - -Make a decision: enhance static package viewer only, or add minimal server-backed admin UI. - -Recommended near-term: - -* keep API-first -* improve static package viewer -* add generated HTML outputs before building full app - -Acceptance criteria: - -* Document chosen UI boundary. -* Avoid starting a broad frontend unless necessary. - -#### [x] EVY-071 — Add generated HTML customer package report - -Priority: P1 - -Description: - -Generate a static HTML report from customer package manifest. - -Acceptance criteria: - -* HTML is self-contained or uses local static assets. -* Shows release summary, VEX table, readiness, verification, limitations. -* Does not require server. -* Can be attached to package export. -* Clearly says it is not certification/legal proof. - -#### [x] EVY-072 — Add internal demo dashboard only if needed - -Priority: P2 - -Description: - -If the existing viewer and API examples are insufficient, add minimal dashboard. - -Pages: - -* Releases -* Release detail -* Vulnerability decisions -* Readiness report -* Customer packages - -Acceptance criteria: - -* No broad app shell. -* No complex auth UI unless already available. -* Uses existing API. -* Demo-focused, not enterprise UI. - -Decision: - -The internal demo dashboard is not needed for the current VEX-first product -path. The repository now has API examples, an end-to-end release evidence demo, -a local package viewer, and generated `report.html` package exports. Keep the -demo surface static/offline until a pilot proves a server-backed dashboard is -necessary. - ---- - -### Milestone 9: Production/Pilot Hardening - -Goal: - -> Prepare Evydence for design-partner pilots without pretending broad production is solved. - -Backlog: - -#### [x] EVY-080 — Finish production-readiness gap review - -Priority: P0 - -Description: - -Review current production-readiness document and convert known gaps into tracked tasks. - -Known areas: - -* remaining relational persistence paths -* aggregate decomposition -* startup load modes -* single API writer profile -* worker scaling -* object-lock/WORM proof -* signing provider behavior -* KMS/HSM support -* provider-specific validation -* group sync -* backup/restore rehearsal -* monitoring/alerts -* incident response runbook - -Acceptance criteria: - -* Each known gap is either tracked, explicitly deferred, or documented as operator responsibility. -* Docs distinguish evaluation, pilot, controlled internal production, regulated production, and unsupported hosted SaaS. - -#### [x] EVY-081 — Add backup/restore rehearsal docs - -Priority: P0 - -Description: - -Design partners need to know how to back up and restore Postgres/object storage/signing material. - -Acceptance criteria: - -* Document backup scope. -* Document restore rehearsal. -* Include failure modes. -* Include verification after restore. -* Do not claim backup correctness without user rehearsal. - -#### [x] EVY-082 — Add monitoring recommendations - -Priority: P1 - -Description: - -Add practical operator metrics/logs checklist. - -Monitor: - -* API health -* worker health -* outbox queue depth -* failed parser jobs -* failed package generation -* signing failures -* object storage errors -* Postgres errors -* audit-chain verification failures -* package access failures - -Acceptance criteria: - -* Metrics/log events documented. -* Production-like Compose or Helm exposes enough signals. -* Alerts suggested but not vendor-specific unless already wired. - -#### [x] EVY-083 — Add pilot deployment checklist - -Priority: P0 - -Description: - -Create checklist for a design partner. - -Checklist sections: - -* environment -* database -* object storage -* API keys -* signing mode -* TLS/reverse proxy -* backups -* restore rehearsal -* image digest verification -* migrations -* worker count -* package retention -* redaction policy -* scoped access -* support contact - -Acceptance criteria: - -* Checklist is copy-pasteable. -* Distinguishes required vs recommended. -* Fits one narrow pilot profile. - ---- - -### Milestone 10: Commercial/Pilot Packaging - -Goal: - -> Make the project sellable as a narrow pilot, not just open-source code. - -Backlog: - -#### [x] EVY-090 — Add “Design Partner Pilot” offer doc - -Priority: P1 - -Description: - -Create `docs/commercial/design-partner-pilot.md` or similar. - -Offer: - -> We wire one product release into Evydence, ingest SBOM + vulnerability scan + VEX/provenance evidence, produce one signed customer-safe evidence bundle, and review the self-hosted deployment profile. - -Acceptance criteria: - -* Clear deliverables. -* Clear non-deliverables. -* No legal compliance guarantees. -* Mentions AGPL/commercial license path. -* Mentions support boundaries. -* Includes ideal customer profile. - -#### [x] EVY-091 — Add product landing copy - -Priority: P1 - -Description: - -Add concise copy usable for README, website, or outreach. - -Acceptance criteria: - -* Headline. -* One-sentence pitch. -* Problem section. -* How it works. -* Why self-hosted. -* What it is not. -* Pilot CTA. -* No unsupported claims. - -#### [x] EVY-092 — Add comparison page: Evydence vs scanners/GRC/trust centers - -Priority: P2 - -Description: - -Create docs page explaining category boundaries. - -Compare against: - -* vulnerability scanners -* SBOM inventory tools -* broad GRC tools -* trust centers -* DIY scripts/spreadsheets - -Acceptance criteria: - -* Fair and non-hostile. -* Explains Evydence focus: release-level evidence, decisions, bundles, audit chains, customer-safe packages. -* Does not claim competitors are bad. -* Helps buyer understand why Evydence exists. - ---- - -### Milestone 11: Tests and Quality Gates - -Goal: - -> Keep productization from weakening technical reliability. - -Backlog: - -#### [x] EVY-100 — Add end-to-end VEX-first integration test - -Priority: P0 - -Description: - -Test complete flow: - -1. create product -2. create release -3. create artifact -4. upload SBOM -5. upload vulnerability scan -6. create VEX decision -7. approve/record exception where needed -8. generate release bundle -9. generate readiness report -10. export customer package -11. verify audit chain/package - -Acceptance criteria: - -* Test uses realistic fixtures. -* Test runs in CI or documented integration mode. -* Output fixtures are stable or regenerated intentionally. -* Catches regressions in main product path. - -#### [x] EVY-101 — Add redaction leakage tests - -Priority: P0 - -Description: - -Ensure customer-safe outputs never leak forbidden fields. - -Test forbidden data: - -* API keys -* internal notes -* raw payload bytes -* internal-only evidence fields -* internal URLs unless marked safe -* object storage paths -* signing private material -* tenant secrets -* scanner raw output if excluded - -Acceptance criteria: - -* Tests fail on leakage. -* Customer package fixture passes. -* Redaction rules documented. - -#### [x] EVY-102 — Add OpenAPI contract stability check - -Priority: P1 - -Description: - -Ensure API changes are intentional. - -Acceptance criteria: - -* CI checks OpenAPI generation. -* Changes require committed contract update. -* Breaking changes are noted in changelog or release notes. - -#### [x] EVY-103 — Add fixture golden tests for package manifest - -Priority: P1 - -Description: - -Protect manifest format from accidental drift. - -Acceptance criteria: - -* Golden manifest exists. -* Intentional changes require fixture update. -* Manifest version changes are explicit. - ---- - -### Milestone 12: Future Expansion Backlog - -These are valid later, but should not block the VEX-first product. -Parent items in this section stay unchecked until every listed sub-item is -implemented, documented, and covered by tests or release checks. Checked -sub-items record existing repository evidence so future work does not repeat -already-built surfaces. - -#### [x] EVY-200 — Artifact exchange / trust package portal - -Potential later expansion: - -* [x] NDA-gated customer access -* [x] package access logs, counters, and failed-attempt tracking -* [x] time-limited package links through expiring portal tokens -* [x] watermarking -* [x] customer-specific packages through scoped customer package records -* [x] answer library -* [x] security questionnaire drafts - -Only do this after customer-safe packages are strong. - -#### [x] EVY-201 — OpenAPI governance integration - -Potential later expansion: - -* [x] ingest OpenAPI contracts and deterministic OpenAPI diffs -* [x] attach API breaking-change evidence to releases through `ContractDiff` - release links and audit-chain entries -* [x] export API contract evidence into the customer/release package manifest - as a first-class package section - -Do not turn Evydence into the OpenAPI governance product itself. - -#### [x] EVY-202 — CRA-readiness templates - -Potential later expansion: - -* [x] CRA evidence mapping template pack -* [x] vulnerability posture report -* [x] CRA-specific vulnerability handling report template -* [x] security update evidence report -* [x] incident package report - -Keep language as readiness support, not legal conclusion. - -#### [x] EVY-203 — Advanced signing/HSM/WORM profiles - -Potential later expansion: - -* [x] external signing provider records and operation receipts -* [x] HTTPS signing gateway executor -* [x] AWS KMS, GCP Cloud KMS, and Azure Key Vault signing executors -* [x] native PKCS#11/HSM module profile beyond gateway-backed `pkcs11-hsm` -* [x] object-retention policy records and configured object-store verification -* [x] object-lock proof packages for customer/release export -* [x] public transparency proof records, verification, and optional proof fetcher -* [x] deployment-specific custody review tooling - -Do this when a real pilot requires it. - -#### [x] EVY-204 — Customer portal server mode - -Potential later expansion: - -* [x] external reviewer accounts -* [x] package tokens -* [x] access counters and failed-attempt counters -* [x] expiry -* [x] package ZIP download endpoint -* [x] detailed package download history events - -Do this only after static/offline package flow is excellent. - -## 8. Suggested Implementation Order - -Recommended first sequence for coding agent: - -1. Baseline repo/test/doc inspection -2. README and quickstart repositioning -3. Audit current VEX/vulnerability decision models -4. Make vulnerability decision the hero object -5. Improve VEX import/manual decision workflow -6. Define customer package v2 manifest -7. Add redaction leakage tests -8. Improve package viewer around VEX/reviewer workflow -9. Add release security summary endpoint -10. Add GitHub Actions quickstart -11. Add end-to-end VEX-first integration test -12. Add pilot deployment checklist -13. Add design-partner pilot doc - -Do not start by adding broad new feature families. - -## 9. Definition Of Done For The Next Strategic Stage - -Evydence reaches the next stage when a new evaluator can do this in under 30 minutes: - -1. Start Evydence locally or in production-like Compose. -2. Create a product/release/artifact. -3. Upload SBOM and vulnerability scan evidence. -4. Record a VEX decision explaining one CVE. -5. Generate a readiness report. -6. Export a signed customer-safe package. -7. Open the package locally in the viewer. -8. Verify what is included, excluded, signed, and limited. -9. Understand that Evydence is not a scanner, not a legal compliance tool, and not a certification authority. - -The product should feel like: - -> “Here is the release. Here is the SBOM. Here is the vulnerability. Here is our VEX decision. Here is the evidence. Here is who approved it. Here is the customer-safe package. Here is how to verify it.” - -That is the target. - -[1]: https://github.com/aatuh/evydence "GitHub - aatuh/evydence: Self-hosted API-first evidence ledger for software release compliance readiness · GitHub" -[2]: https://github.com/aatuh/evydence/releases/tag/v0.1.0-rc.4 "Release Evydence v0.1.0-rc.4 · aatuh/evydence · GitHub" -[3]: https://www.cisa.gov/topics/information-communications-technology-supply-chain-security/sbom?utm_source=chatgpt.com "Software Bill of Materials (SBOM)" -[4]: https://cyclonedx.org/capabilities/vex/?utm_source=chatgpt.com "Vulnerability Exploitability eXchange (VEX)" -[5]: https://digital-strategy.ec.europa.eu/en/policies/cyber-resilience-act?utm_source=chatgpt.com "Cyber Resilience Act | Shaping Europe's digital future" diff --git a/.productization_next_steps_missing.md b/.productization_next_steps_missing.md deleted file mode 100644 index a6ea58b..0000000 --- a/.productization_next_steps_missing.md +++ /dev/null @@ -1,678 +0,0 @@ -# Evydence Productization Missing/Partial Backlog - -Project: Evydence - -Purpose: Track the partial or non-fulfilled productization items identified from -`.productization_next_steps_doc.md`, the current repository evidence, and the -first production-readiness public repo audit in -`.audits/production_readiness_v1/`. - -Current baseline: - -- Evydence already has a credible VEX-first release-evidence core, public - `v0.1.0-rc.5` release evidence, OpenAPI, CLI, customer packages, local package - viewer, and production-candidate docs. -- The remaining work is productization, reviewer UX, trust hardening, - decision-model depth, production-profile clarity, and real market validation. -- Product language must remain conservative: compliance readiness, technical - evidence organization, tamper-evident records, reproducibility, gaps, - assumptions, exceptions, and limitations. Do not claim legal compliance, - certification, complete SBOMs, authoritative scanner results, secure releases, - or auditor/regulator acceptance. - -Status legend: - -- [ ] not done -- [x] done -- [e] external dependency, not fully implementable in this repository - -Implementation rules: - -- Implement tickets in dependency order. -- Keep changes small enough to test, document, and commit independently. -- Run the validation commands listed on each ticket. -- Prefer `make finalize` as the final local gate for source changes. -- Use Conventional Commits after each completed ticket. -- Update OpenAPI, docs, examples, migrations, and tests together when behavior - changes. -- Mark a ticket `[x]` only after implementation, docs, tests/checks, and commit - are complete. -- Mark an epic `[x]` only when all child tickets are complete or explicitly - external. -- Keep tenant isolation, append-only evidence, safe redaction, release evidence - integrity, and non-claim language intact. - -## Epic E1 - Close Public Trust And Release-Integrity Gaps [x] - -Description: Remove the highest-impact public trust issues that prevent the -repository from cleanly exceeding the production-readiness score target. - -### Ticket E1-T1 - Remove broad token permissions from container image workflow [x] - -Description: Change `.github/workflows/container-image.yml` so `GITHUB_TOKEN` -does not carry top-level `packages: write`. Use job-level least privilege only -where needed, or move registry publication to a narrowly scoped external token -with documented operator/maintainer requirements. - -Implementation rules: - -- Preserve container image build, digest capture, cosign signing, cosign - verification output, and image manifest generation. -- Keep `id-token: write` only for the signing step that needs keyless cosign. -- Avoid broad workflow-level write permissions. -- Update release evidence docs if the publishing trust model changes. -- Run `make docs-check`. -- Run or inspect a `Container Image` workflow execution before marking complete. -- Verify the related Scorecard code-scanning alert closes or document a - remaining external requirement. - -Repo-local status: complete. The workflow keeps `GITHUB_TOKEN` read-only, -uses `EVYDENCE_GHCR_PUBLISH_TOKEN` for GHCR publication, and scopes -`id-token: write` to the signing job. Public Scorecard SARIF rerun -`26765714988` on commit `77ab18e5ad8b3ba3a9f4745e7f6437e5e3e1f596` closed the -related code-scanning alert. Live container publication still depends on the -external `EVYDENCE_GHCR_PUBLISH_TOKEN` secret. - -### Ticket E1-T2 - Split release packaging from release publishing permissions [x] - -Description: Refactor `.github/workflows/release-artifacts.yml` so package -generation and validation run read-only, while draft-release creation/upload is -isolated behind the narrowest possible permission boundary. - -Implementation rules: - -- Preserve signed archives, checksums, OpenAPI checksum, migration checksum, - SBOM/provenance metadata, release notes, and signed manifest outputs. -- Move `contents: write` to the smallest job or workflow that actually needs to - create/upload a draft release. -- Prefer a fine-grained maintainer token or GitHub App token if needed to clear - Scorecard while preserving release publication. -- Update `docs/reference/release-candidate.md`, - `docs/reference/release-validation.md`, and `RELEASE_EVIDENCE.md` if release - publication steps change. -- Run `make release-acceptance`. -- Run `make public-release-verify TAG=v0.1.0-rc.5`. -- Verify the related Scorecard code-scanning alert closes or document a - remaining external requirement. - -Repo-local status: complete. Release package generation and draft-release -publication are separate jobs, both keep `GITHUB_TOKEN` read-only, and draft -publication uses `EVYDENCE_RELEASE_PUBLISH_TOKEN` only in the publication job. -Public Scorecard SARIF rerun `26765714988` on commit -`77ab18e5ad8b3ba3a9f4745e7f6437e5e3e1f596` closed the related code-scanning -alert. Live draft-release publication still depends on the external -`EVYDENCE_RELEASE_PUBLISH_TOKEN` secret. - -### Ticket E1-T3 - Make coverage gate behavior deterministic [x] - -Description: Fix the mismatch where public CI `make production-check` passes -coverage with live PostgreSQL, but local `make coverage-check` fails at 67.9% -when `EVYDENCE_TEST_DATABASE_URL` is unset. - -Implementation rules: - -- Preserve the 80% production coverage gate. -- Either make `make coverage-check` fail early with a clear live PostgreSQL - prerequisite, or add a separate local-only coverage target with explicitly - lower scope. -- Update `scripts/coverage_check.sh`, `Makefile`, and release/production docs. -- Avoid implying no-DB local coverage is production release evidence. -- Run `make coverage-check` without `EVYDENCE_TEST_DATABASE_URL` and verify the - intended deterministic behavior. -- Run `make docs-check` and `make release-acceptance`. - -### Ticket E1-T4 - Document maintainer branch-protection bypass posture [x] - -Description: Document that branch protection can be bypassed by maintainers if -admin enforcement remains disabled, and state compensating controls without -overclaiming enforced PR-only changes. - -Implementation rules: - -- Update `docs/reference/maintainer-review-policy.md`. -- Mention required checks, CodeQL, production-check, release evidence, signed - artifacts, and audit visibility as compensating controls. -- Do not claim all changes must go through PR if maintainer bypass remains - possible. -- Run `make docs-check` and `make release-acceptance`. - -### Ticket E1-T5 - Configure external publishing credentials if required [e] - -Description: If least-privilege release publishing requires a fine-grained PAT, -GitHub App token, or registry credential, create and configure the external -GitHub secrets. - -Implementation rules: - -- Keep secrets out of source files, logs, release notes, and audit artifacts. -- Record only the secret purpose, required scopes, and rotation expectations. -- Validate with public workflow runs and release/container evidence. - -External reason: - -- GitHub repository secrets and app/PAT creation are provider/account settings. - -Provider status: external. `gh secret list --repo aatuh/evydence` verifies -`EVYDENCE_RELEASE_SIGNING_PRIVATE_KEY_B64` is configured. The least-privilege -workflow publication secrets `EVYDENCE_RELEASE_PUBLISH_TOKEN` and -`EVYDENCE_GHCR_PUBLISH_TOKEN` are not listed, and their values cannot be -created from repository source. Configure them in GitHub with appropriately -scoped secret values before relying on the refactored release/container -publication workflows. - -### Ticket E1-T6 - Verify GitHub private vulnerability reporting and secret scanning [x] - -Description: Confirm GitHub private vulnerability reporting, secret scanning, -and push protection are enabled where available. - -Implementation rules: - -- Record the setting state in a maintainer-only or sanitized security audit note. -- Update public docs only with statements that can be maintained. - -External reason: - -- These are GitHub account/repository security settings, not source files. - -Provider status: complete. `gh api repos/aatuh/evydence --jq -'.security_and_analysis'` shows Dependabot security updates enabled, secret -scanning enabled, and secret scanning push protection enabled. `gh api -repos/aatuh/evydence/private-vulnerability-reporting` returns -`{"enabled":true}`. `gh api repos/aatuh/evydence/secret-scanning/alerts` -returned zero alerts at verification time. - -## Epic E2 - Make The First Ten Minutes Reviewer-Obvious [x] - -Description: Convert the already implemented VEX-first flow into an evaluation -path a skeptical product-security buyer or customer reviewer understands without -reading architecture docs. - -### Ticket E2-T1 - Add a one-page evaluator walkthrough [x] - -Description: Add a concise "evaluate in 10 minutes" walkthrough that starts -from the current public release, sample package, local package viewer, and -public release verifier. - -Implementation rules: - -- Keep the walkthrough buyer-facing, not architecture-first. -- Show the exact customer question: "This CVE appears in your SBOM. Are you - affected, why, who approved it, and what can I verify?" -- Link to the sample customer package, package viewer, release verifier, and - end-to-end demo. -- Avoid asking the evaluator to understand every evidence family up front. -- Update `README.md`, `docs/tutorials/getting-started.md`, or a new focused - docs page. -- Run `make docs-check`, `make demo-check`, and `make package-viewer-check`. - -### Ticket E2-T2 - Add a visual reviewer journey using existing fixtures [x] - -Description: Add a static, checked reviewer journey that shows the package -viewer states for release summary, VEX decisions, evidence contents, -verification, gaps, and limitations. - -Implementation rules: - -- Use non-sensitive sample data only. -- Do not upload data or require a running server for the visual path. -- Keep `site/package-viewer/index.html` local-only unless a later ticket adds a - server mode. -- Update `docs/how-to/view-packages.md` and docs assets. -- Run `make package-viewer-check` and `make docs-check`. - -### Ticket E2-T3 - Reduce first-screen feature sprawl [x] - -Description: Keep the README first screen focused on products, releases, SBOMs, -vulnerability scans, VEX/manual decisions, provenance, release bundles, and -customer-safe packages; move broad evidence/report families to advanced docs. - -Implementation rules: - -- Do not remove implemented capability documentation. -- Keep advanced features discoverable under docs/reference or architecture. -- Keep VEX-first buyer language dominant near the top of the README. -- Run `make docs-check` and `make release-acceptance`. - -### Ticket E2-T4 - Add a proof-path checklist to the sample package [x] - -Description: Make the sample customer package and package viewer show a -reviewer-oriented checklist: package scope, included evidence, excluded -evidence, hash/signature verification, non-claims, and escalation path. - -Implementation rules: - -- Update sample fixtures only if their hashes and golden tests are updated. -- Ensure redaction leakage tests still prove raw payloads and secrets are absent. -- Run `make demo-check`, `make package-viewer-check`, and targeted package tests. - -## Epic E3 - Make Vulnerability Decisions Fully Buyer-Facing [x] - -Description: Close the documented decision-model gaps so vulnerability -decisions become a durable customer-review object, not only an operational API -record. - -### Ticket E3-T1 - Decide and document risk-status taxonomy [x] - -Description: Decide whether `accepted_risk`, `false_positive`, and -`will_not_fix` belong as vulnerability decision statuses, exceptions, waivers, -or a separate risk outcome model. - -Implementation rules: - -- Update `docs/reference/vulnerability-decisions.md` with the final taxonomy. -- If new statuses are added, update domain validation, OpenAPI, tests, package - exports, readiness reports, and docs. -- If deferred, explicitly state how exceptions/waivers represent those cases. -- Run targeted app/API tests and `make openapi-check` if schemas change. - -### Ticket E3-T2 - Add decision review date or explicit freshness semantics [x] - -Description: Address the current gap that customer-visible decisions have no -review date or expiry. - -Implementation rules: - -- Prefer append-only/versioned decision metadata over mutable historical edits. -- If implementing fields, add `reviewed_at`, `review_due_at`, or equivalent - semantics and expose freshness in customer-safe summaries. -- If deferring, document that expiry lives on exceptions/waivers and add report - limitations explaining decision freshness assumptions. -- Update package/report tests. -- Run `make openapi-check`, targeted app/API tests, and `make docs-check`. - -### Ticket E3-T3 - Link decisions directly to source SBOM context [x] - -Description: Add first-class linkage from a vulnerability decision or finding -summary to the SBOM/component context that supported the answer, instead of -requiring reviewers to infer it through release/artifact relationships. - -Implementation rules: - -- Preserve tenant and release isolation for every link. -- Avoid duplicating raw SBOM payloads in customer-safe exports. -- Include safe SBOM/component identifiers in package summaries. -- Update OpenAPI, tests, and docs. -- Run targeted app/API tests and `make openapi-check`. - -### Ticket E3-T4 - Add first-class supporting links for non-evidence resources [x] - -Description: Let decisions link to approvals, exceptions, waivers, remediation -tasks, release bundles, incident packages, or other first-class records without -forcing everything through generic evidence wrappers. - -Implementation rules: - -- Keep links append-only. -- Validate tenant ownership and release scope before linking. -- Exclude internal-only linked content from customer-safe exports unless the - redaction profile allows it. -- Add negative tests for cross-tenant and wrong-release links. -- Run targeted app/API tests, `make openapi-check`, and `make docs-check`. - -### Ticket E3-T5 - Add package-specific customer decision export [x] - -Description: Extend customer package/report output so the canonical decision -view is package-scoped, customer-safe, and directly reviewable, not only a -release-scoped JSON summary. - -Implementation rules: - -- Include vulnerability ID, component/PURL, status, justification, - customer-safe impact/action statements, approver, supersession state, source - VEX/import info, supporting links, assumptions, and limitations. -- Exclude internal notes, raw payload bytes, object-store refs, tokens, hashes - of secrets, and private review context. -- Update package viewer, static `report.html`, package verifier/golden tests, - and docs. -- Run `make demo-check`, `make package-viewer-check`, targeted package tests, - and `make docs-check`. - -## Epic E4 - Improve VEX Import Depth And Parser Feedback [x] - -Description: Make VEX import behavior operationally clear for both OpenVEX and -CycloneDX VEX without claiming authoritative vulnerability truth. - -### Ticket E4-T1 - Add CycloneDX VEX import report details [x] - -Description: Extend CycloneDX VEX ingestion to produce format-specific import -issues, warnings, mapping failures, created/superseded decision counts, and -safe parser metadata comparable to OpenVEX import reports. - -Implementation rules: - -- Use strict structured parsing. -- Do not expose raw VEX payload bytes, object-store refs, tokens, or internal - notes in import reports. -- Preserve idempotent worker replay behavior. -- Add malformed, unsupported, duplicate, and mapping-failure fixtures. -- Run targeted VEX/parser tests and `make openapi-check` if schema changes. - -### Ticket E4-T2 - Add VEX import preview/dry-run mode [x] - -Description: Add a way to validate a VEX document and see safe mapping -warnings before committing decisions, if it fits the API model. - -Implementation rules: - -- Treat preview output as advisory, not evidence. -- Do not store raw payloads during dry-run unless explicitly requested. -- Enforce body size, strict JSON, and safe errors. -- Update OpenAPI and docs if a new endpoint is added. -- Run API input validation tests and `make openapi-check`. - -### Ticket E4-T3 - Improve worker parser failure visibility [x] - -Description: Make VEX parser failures visible in persisted import reports and -worker job status with safe error codes and no raw payload leakage. - -Implementation rules: - -- Preserve retry and terminal-failure behavior. -- Add tests for malformed payload, missing object, digest mismatch, and mapping - failure. -- Update worker/outbox docs. -- Run `go test ./cmd/evydence-worker ./internal/app` and `make docs-check`. - -## Epic E5 - Make CI Evidence Ingest Embarrassingly Simple [x] - -Description: Reduce the first CI integration to one obvious release-evidence -path before users learn the full domain model. - -### Ticket E5-T1 - Add a minimal GitHub Actions setup guide [x] - -Description: Add a short guide that starts from existing product/release/artifact -IDs and wires one build to upload SBOM, vulnerability scan, provenance, optional -OpenVEX, and a release bundle. - -Implementation rules: - -- Use `docs/github-actions/quickstart-release-evidence.yml` as the canonical - example. -- State required secrets and variables exactly. -- Avoid live GitHub API calls beyond the runner environment. -- Include expected output and troubleshooting for common 401/403/404/idempotency - errors. -- Run `make docs-check`. - -### Ticket E5-T2 - Add a preflight CLI command for CI configuration [x] - -Description: Add a CLI command that verifies API URL, API key scope, product ID, -release ID, artifact ID, and manifest paths before a CI upload runs. - -Implementation rules: - -- Do not print API keys, bearer tokens, or secrets. -- Return stable exit codes for missing config, auth failure, wrong scope, wrong - tenant, and invalid manifest. -- Add CLI tests and safe error-message tests. -- Run `go test ./cmd/evydence` and `make docs-check`. - -### Ticket E5-T3 - Add a checked one-command local CI simulation [x] - -Description: Add a local script that simulates the GitHub Actions quickstart -against a local API using non-sensitive fixture SBOM/scan/VEX data. - -Implementation rules: - -- Keep fixture IDs explicit or create them through the API. -- Write outputs under `tmp/`. -- Verify readiness, package, and audit-chain outputs. -- Add the script to `demo-check` or a separate checked target. -- Run the new target and `make fast-check`. - -## Epic E6 - Clarify Production Candidate Versus Broad Production [x] - -Description: Keep production positioning honest while closing repo-local -hardening that affects controlled self-hosted adoption. - -### Ticket E6-T1 - Refresh production exit review after trust fixes [x] - -Description: Update `docs/reference/production-exit-review.md` after release -workflow token-permission and coverage-gate fixes land. - -Implementation rules: - -- Keep the verdict conservative unless evidence supports a stronger claim. -- Separate repo-local fixed items from external/operator responsibilities. -- Cite current release, CI, CodeQL, Scorecard, and production-check evidence. -- Run `make docs-check` and `make release-acceptance`. - -### Ticket E6-T2 - Add external controls matrix for regulated deployments [x] - -Description: Add a concise matrix of external controls required for regulated -or high-trust deployments, including KMS/HSM, WORM/object lock, TLS, identity -provider configuration, backups, monitoring, incident response, and legal/audit -review. - -Implementation rules: - -- Mark each item as repo-owned, operator-owned, provider-owned, or legal/review - owned. -- Do not imply Evydence can verify controls it only records as evidence. -- Link from production readiness, Kubernetes, and pilot checklist docs. -- Run `make docs-check`. - -### Ticket E6-T3 - Decide the long-term single-writer stance [x] - -Description: Decide whether one API writer replica is an acceptable long-term -self-hosted profile, or whether multi-writer API HA must become a production -roadmap blocker. - -Implementation rules: - -- If one-writer remains supported, document capacity/failure expectations and - operational mitigations. -- If multi-writer is required, create a separate technical backlog for - concurrency design, optimistic locking, or focused repository decomposition. -- Do not change Helm defaults without tests. -- Run `make docs-check` and `make deploy-check`. - -### Ticket E6-T4 - Add current production-gate troubleshooting [x] - -Description: Document how to diagnose failures in `make production-check`, -including PostgreSQL URL setup, migration compatibility, coverage, black-box -demo, release signing smoke, and package verification. - -Implementation rules: - -- Keep commands exact and safe for disposable local environments. -- Do not suggest running destructive commands against production databases. -- Link from release validation and production readiness docs. -- Run `make docs-check`. - -## Epic E7 - Turn Reviewer UX Into A Minimal Product Surface [x] - -Description: Decide and implement the smallest browser-facing surface needed to -make customer package review credible without building a broad UI. - -### Ticket E7-T1 - Define UI boundary for reviewer and operator surfaces [x] - -Description: Decide what remains API/CLI-only, what belongs in the local package -viewer, and whether a server-hosted customer portal page is in scope for the -next release. - -Implementation rules: - -- Keep tenant authorization server-side. -- Do not rely on frontend visibility for access control. -- Keep local viewer explicitly non-authoritative. -- Document the boundary in package viewer and customer portal docs. -- Run `make docs-check` and `make package-viewer-check`. - -Repo-local status: complete. Operator workflows remain API/CLI-first, the local -viewer is documented as offline and non-authoritative, and the only -browser-facing server surface in scope is a minimal package-token-backed review -page that reuses existing portal exchange, expiry, NDA, scope, watermark, and -audit controls. - -### Ticket E7-T2 - Add server-hosted customer package view if approved [x] - -Description: If the UI boundary allows it, add a minimal server-hosted customer -portal page for token-scoped package review and download. - -Implementation rules: - -- Use existing portal token exchange and package scope controls. -- Do not expose raw tenant evidence payloads or internal notes. -- Add CSRF/cache/header considerations if browser sessions are introduced. -- Add frontend/security tests and redaction leakage tests. -- Run focused HTTP tests, `make package-viewer-check`, and `make finalize`. - -Repo-local status: complete. `/v1/customer-portal/package/view` now renders a -minimal no-store HTML review form and scoped package review page using existing -portal token exchange, expiry, NDA, watermark, package scope, and audit -behavior. Tokens are accepted only in form bodies, are not copied into returned -HTML or URLs, and the form-backed ZIP download reuses the existing portal -archive export path. - -### Ticket E7-T3 - Add reviewer export/download workflow proof [x] - -Description: Prove that a reviewer can open a package, inspect limitations, -download the ZIP/report, and run verification instructions without maintainer -knowledge. - -Implementation rules: - -- Use checked fixtures and deterministic commands. -- Add a docs walkthrough and, if practical, a simple smoke script. -- Keep output language free of compliance/security guarantees. -- Run `make demo-check`, `make package-viewer-check`, and `make docs-check`. - -Repo-local status: complete. `docs/how-to/review-customer-package.md` now gives -the reviewer workflow for manifest/archive verification, local viewer -inspection, static `report.html`, server-hosted portal review, and escalation. -`scripts/reviewer_package_workflow_check.sh` validates the checked sample -manifest checksum, package verifier output, safe ZIP extraction, report -contents, and absence of raw payload/object key/token hash/internal-note/script -markers. - -## Epic E8 - Gather External Market And Adoption Evidence [e] - -Description: The remaining strongest productization gap is not code. It is -evidence that a non-maintainer can use Evydence on a real release to answer a -customer/security review question. - -### Ticket E8-T1 - Run one design-partner pilot [e] - -Description: Use Evydence with a non-maintainer team on one real release and -generate a customer-safe release evidence package. - -Implementation rules: - -- Use the existing design-partner pilot scope. -- Do not publish customer data, raw evidence, tokens, private keys, database - URLs, or provider credentials. -- Capture what worked, what was missing, and whether the package answered the - customer/security-review question. - -External reason: - -- Requires an external organization or design partner and permission to use the - outcome. - -### Ticket E8-T2 - Publish an anonymized pilot report or case study [e] - -Description: Publish a sanitized report showing one real release-evidence -workflow, verification path, limitations, and accepted gaps. - -Implementation rules: - -- Get explicit permission before publishing. -- Avoid legal compliance, certification, secure-release, complete-SBOM, or - authoritative-scanner claims. -- Link the report from commercial/pilot docs if public. - -External reason: - -- Requires external customer/design-partner approval. - -### Ticket E8-T3 - Update public GitHub description to VEX-first positioning [x] - -Description: Update the repository description so the public GitHub first -impression matches the README's sharper VEX-first release-evidence story. - -Suggested wording: - -`Self-hosted VEX-first release evidence ledger for customer CVE, SBOM, provenance, and release-review questions.` - -Implementation rules: - -- Verify with `gh repo view aatuh/evydence --json description`. -- Keep topics aligned with `vex`, `sbom`, `release-evidence`, and - `supply-chain-security`. - -External reason: - -- GitHub repository description and topics are provider settings. - -Provider status: complete. `gh repo edit aatuh/evydence --description` updated -the public description to `Self-hosted VEX-first release evidence ledger for -customer CVE, SBOM, provenance, and release-review questions.` and `gh repo -view aatuh/evydence --json description,repositoryTopics` verified the result. - -## Epic E9 - Re-Audit And Close Productization Loop [x] - -Description: Re-run audits after the repo-local tickets are complete and only -raise product claims when evidence supports them. - -### Ticket E9-T1 - Re-run production readiness public repo audit loop [x] - -Description: Re-run `production-readiness-public-repo-audit-loop` after E1-E7 -repo-local work is complete. - -Implementation rules: - -- Use target score `8`. -- Preserve prior audit directories. -- Treat `[e]` external items as tracked dependencies, not local failures. -- Do not run remediation in the audit turn unless explicitly requested. - -Repo-local status: complete. The current audit is recorded in -`.audits/production_readiness_v2/analysis.md` with an overall score of `8.3/10` -and verdict `Production-usable with caveats` for the controlled self-hosted -candidate profile. Follow-up GitHub verification pushed the backlog commits, -confirmed CI/CodeQL/Scorecard success on commit -`77ab18e5ad8b3ba3a9f4745e7f6437e5e3e1f596`, closed open code-scanning alerts, -and verified GitHub security settings plus public description updates. The -remaining dependencies are publishing-token secrets and design-partner proof. - -### Ticket E9-T2 - Re-run product-code audit focused on the VEX-first buyer path [x] - -Description: Re-audit whether the implemented product now fulfills the -VEX-first customer-question workflow without overclaiming production or -compliance outcomes. - -Implementation rules: - -- Test the primary VEX-first flow, package viewer, public release verifier, and - customer package verification path. -- Turn findings into a follow-up backlog rather than broad feature expansion. - -Repo-local status: complete. The current product-code audit is recorded in -`.audits/product_code_audit_v4/audit.md` with an overall score of `8.4/10` and -verdict `Production-usable with caveats`. The audit verifies the VEX-first -release-evidence flow, customer package viewer, portal review page, reviewer -workflow proof, public rc5 verifier, and production gate. - -### Ticket E9-T3 - Decide release status wording after audits [x] - -Description: Decide whether the next release remains a controlled self-hosted -production candidate or can adopt a stronger narrow self-hosted production -profile. - -Implementation rules: - -- Require current audits, release evidence, CI, CodeQL, Scorecard, production - check, and package/demo proof. -- Keep regulated production, hosted SaaS production, legal compliance, - certification, complete SBOM proof, authoritative scanner results, and - secure-release claims out of scope unless independently proven. -- Update README, changelog, release notes, production readiness, release - evidence index, and commercial docs together. - -Repo-local status: complete. The release status remains `controlled self-hosted -production candidate`. The audits do not justify stronger broad production, -regulated production, hosted SaaS, legal compliance, certification, -complete-SBOM, authoritative-scanner, or release-security guarantee wording. -The production exit review now references the audit closeout and keeps the -existing conservative status. From 650be76e77330aa4c4217ae580d9e14d0cc943ce Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 19:27:24 +0300 Subject: [PATCH 248/287] ci(release): fix draft release publishing --- .github/workflows/release-artifacts.yml | 7 ++++--- Makefile | 1 + scripts/release_acceptance.sh | 5 +++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release-artifacts.yml b/.github/workflows/release-artifacts.yml index 574635b..975d63b 100644 --- a/.github/workflows/release-artifacts.yml +++ b/.github/workflows/release-artifacts.yml @@ -134,8 +134,9 @@ jobs: run: | set -euo pipefail tag="${{ needs.package.outputs.tag }}" - if gh release view "${tag}" >/dev/null 2>&1; then - gh release upload "${tag}" dist/${tag}/* --clobber + repo="${GITHUB_REPOSITORY:?}" + if gh release view "${tag}" --repo "${repo}" >/dev/null 2>&1; then + gh release upload "${tag}" dist/${tag}/* --repo "${repo}" --clobber else - gh release create "${tag}" dist/${tag}/* --draft --title "Evydence ${tag}" --notes-file "dist/${tag}/release-notes.md" + gh release create "${tag}" dist/${tag}/* --repo "${repo}" --draft --title "Evydence ${tag}" --notes-file "dist/${tag}/release-notes.md" fi diff --git a/Makefile b/Makefile index 8d0cd52..7f253d2 100644 --- a/Makefile +++ b/Makefile @@ -287,6 +287,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'evydence-release-manifest.sig.json' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'evydence-release-manifest.sig alias' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'gh release create' .github/workflows/release-artifacts.yml >/dev/null + @grep -F -- '--repo "$${repo}"' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'contents: read' .github/workflows/release-artifacts.yml >/dev/null @! grep -F 'contents: write' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'Container Image' .github/workflows/container-image.yml >/dev/null diff --git a/scripts/release_acceptance.sh b/scripts/release_acceptance.sh index 4d7a12f..b2dfd2b 100755 --- a/scripts/release_acceptance.sh +++ b/scripts/release_acceptance.sh @@ -14,7 +14,7 @@ require_file() { require_text() { file="$1" text="$2" - if ! grep -F "$text" "$file" >/dev/null; then + if ! grep -F -- "$text" "$file" >/dev/null; then printf '%s\n' "release-acceptance: $file missing text: $text" >&2 exit 2 fi @@ -22,7 +22,7 @@ require_text() { reject_text() { text="$1" - if grep -R -i "$text" README.md docs COMMERCIAL.md GOVERNANCE.md CONTRIBUTING.md SECURITY.md SUPPORT.md TRADEMARKS.md RELEASE_EVIDENCE.md CHANGELOG.md >/dev/null; then + if grep -R -i -- "$text" README.md docs COMMERCIAL.md GOVERNANCE.md CONTRIBUTING.md SECURITY.md SUPPORT.md TRADEMARKS.md RELEASE_EVIDENCE.md CHANGELOG.md >/dev/null; then printf '%s\n' "release-acceptance: forbidden claim found: $text" >&2 exit 2 fi @@ -82,6 +82,7 @@ require_text .github/workflows/ci.yml "actions/checkout@de0fac2e4500dabe0009e672 require_text .github/workflows/release-artifacts.yml "contents: read" require_text .github/workflows/release-artifacts.yml "EVYDENCE_RELEASE_PUBLISH_TOKEN" require_text .github/workflows/release-artifacts.yml "actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c" +require_text .github/workflows/release-artifacts.yml "--repo \"\${repo}\"" if grep -F "contents: write" .github/workflows/release-artifacts.yml >/dev/null; then printf '%s\n' "release-acceptance: release artifact workflow must not grant GITHUB_TOKEN contents: write" >&2 exit 2 From 61f0f1e1acfc226a2c1eb4dc10bd7f21f2bd5c84 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Mon, 1 Jun 2026 19:52:22 +0300 Subject: [PATCH 249/287] feat(site): add Astro marketing site --- .gitignore | 1 + Makefile | 5 +- site/marketing/astro.config.mjs | 17 + site/marketing/package-lock.json | 5170 +++++++++++++++++ site/marketing/package.json | 15 + site/marketing/scripts/check.mjs | 130 + .../src/components/ConsentBanner.astro | 172 + .../src/components/DossierVisual.astro | 27 + site/marketing/src/data/site.ts | 781 +++ site/marketing/src/layouts/BaseLayout.astro | 609 ++ site/marketing/src/pages/[...slug].astro | 15 + site/marketing/src/pages/docs.astro | 16 + site/marketing/src/pages/github.astro | 16 + site/marketing/src/pages/index.astro | 66 + .../src/templates/MarketingPage.astro | 84 + site/marketing/tsconfig.json | 12 + 16 files changed, 7135 insertions(+), 1 deletion(-) create mode 100644 site/marketing/astro.config.mjs create mode 100644 site/marketing/package-lock.json create mode 100644 site/marketing/package.json create mode 100644 site/marketing/scripts/check.mjs create mode 100644 site/marketing/src/components/ConsentBanner.astro create mode 100644 site/marketing/src/components/DossierVisual.astro create mode 100644 site/marketing/src/data/site.ts create mode 100644 site/marketing/src/layouts/BaseLayout.astro create mode 100644 site/marketing/src/pages/[...slug].astro create mode 100644 site/marketing/src/pages/docs.astro create mode 100644 site/marketing/src/pages/github.astro create mode 100644 site/marketing/src/pages/index.astro create mode 100644 site/marketing/src/templates/MarketingPage.astro create mode 100644 site/marketing/tsconfig.json diff --git a/.gitignore b/.gitignore index dc73eb8..40ae042 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ coverage.out bin/ dist/ tmp/ +node_modules/ release-evidence/ backups/ __pycache__/ diff --git a/Makefile b/Makefile index 7f253d2..a29423f 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ GOVULNCHECK_VERSION ?= v1.2.0 TAG ?= -.PHONY: help tools fmt lint vuln gosec test test-race fuzz-smoke coverage coverage-check openapi-check openapi-precision-check meta-check docs-check deploy-check sdk-check demo-check local-ci-simulation-check reviewer-package-workflow-check black-box-demo-check benchmark-check package-viewer-check restore-rehearsal-check fast-check finalize release-acceptance release-check production-check release-candidate-check public-release-verify migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean +.PHONY: help tools fmt lint vuln gosec test test-race fuzz-smoke coverage coverage-check openapi-check openapi-precision-check meta-check docs-check deploy-check sdk-check demo-check local-ci-simulation-check reviewer-package-workflow-check black-box-demo-check benchmark-check package-viewer-check marketing-site-check restore-rehearsal-check fast-check finalize release-acceptance release-check production-check release-candidate-check public-release-verify migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean help: ## Show help @awk 'BEGIN {FS=":.*## "}; /^[a-zA-Z0-9_.-]+:.*## / { printf " %-18s %s\n", $$1, $$2 }' $(MAKEFILE_LIST) @@ -417,6 +417,9 @@ package-viewer-check: ## Validate local package viewer and walkthrough @grep -F 'Gaps' docs/assets/reviewer-journey.svg >/dev/null @grep -F 'Limitations' docs/assets/reviewer-journey.svg >/dev/null +marketing-site-check: ## Build and validate the static marketing site + @npm --prefix site/marketing run check + restore-rehearsal-check: ## Run repository-owned backup/restore rehearsal tests @$(GO) test ./internal/app -run TestBackupRestoreRehearsalPreservesLedgerAndObjectPayloads -count=1 @$(GO) test ./internal/adapters/postgres -run TestPostgresBackupRestoreRehearsalPreservesLedgerAndObjects -count=1 diff --git a/site/marketing/astro.config.mjs b/site/marketing/astro.config.mjs new file mode 100644 index 0000000..04e2ef3 --- /dev/null +++ b/site/marketing/astro.config.mjs @@ -0,0 +1,17 @@ +import { defineConfig } from "astro/config"; + +const site = process.env.PUBLIC_SITE_URL || "https://aatuh.github.io"; +const base = process.env.PUBLIC_SITE_BASE || "/evydence"; + +export default defineConfig({ + site, + base, + output: "static", + i18n: { + defaultLocale: "en", + locales: ["en", "fi"], + routing: { + prefixDefaultLocale: true + } + } +}); diff --git a/site/marketing/package-lock.json b/site/marketing/package-lock.json new file mode 100644 index 0000000..3b72625 --- /dev/null +++ b/site/marketing/package-lock.json @@ -0,0 +1,5170 @@ +{ + "name": "@evydence/marketing-site", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@evydence/marketing-site", + "version": "0.1.0", + "devDependencies": { + "astro": "6.4.2" + } + }, + "node_modules/@astrojs/internal-helpers": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.10.0.tgz", + "integrity": "sha512-Ry2R3VPeIN4uPCSA4xQc+e+vsJXkalKpEbDc07hV+a/o5Bs2N/s/uDcPJH/05L19DKh9tAy7e6JM3YZ6Cxfezw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.4", + "@types/mdast": "^4.0.4", + "js-yaml": "^4.1.1", + "picomatch": "^4.0.4", + "retext-smartypants": "^6.2.0", + "shiki": "^4.0.2", + "smol-toml": "^1.6.0", + "unified": "^11.0.5" + } + }, + "node_modules/@astrojs/markdown-remark": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-7.2.0.tgz", + "integrity": "sha512-+YxmVQu1Bd+MFfSzjq1rOJvD9+nIOJzz5YIIhdIH01RrxRkKbyKoEgyIqP3yv51MhzMDgd79QaPv+kCVPT8vHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@astrojs/internal-helpers": "0.10.0", + "@astrojs/prism": "4.0.2", + "github-slugger": "^2.0.0", + "hast-util-from-html": "^2.0.3", + "hast-util-to-text": "^4.0.2", + "mdast-util-definitions": "^6.0.0", + "rehype-raw": "^7.0.0", + "rehype-stringify": "^10.0.1", + "remark-gfm": "^4.0.1", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.1.2", + "remark-smartypants": "^3.0.2", + "unified": "^11.0.5", + "unist-util-remove-position": "^5.0.0", + "unist-util-visit": "^5.1.0", + "unist-util-visit-parents": "^6.0.2", + "vfile": "^6.0.3" + } + }, + "node_modules/@astrojs/prism": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@astrojs/prism/-/prism-4.0.2.tgz", + "integrity": "sha512-KTivpmnz6lDsC6o9H4+DNm2SrE/GHzw8cNAvEJwAvUT+eoaEnn/4NtbDNfRRaxaJHdp15gf+tfHAWiXR4wB3BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "prismjs": "^1.30.0" + }, + "engines": { + "node": ">=22.12.0" + } + }, + "node_modules/@astrojs/telemetry": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.3.2.tgz", + "integrity": "sha512-j8DNruA8ors99Al39RYZPJK4DC1bKkoNm93mAMuBhY9TCNC4R8n1q7ovFnJ5qhGh5Lsh7pa1gpQVpYpsJPeTHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ci-info": "^4.4.0", + "dset": "^3.1.4", + "is-docker": "^4.0.0", + "is-wsl": "^3.1.1", + "which-pm-runs": "^1.1.0" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@capsizecss/unpack": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@capsizecss/unpack/-/unpack-4.0.0.tgz", + "integrity": "sha512-VERIM64vtTP1C4mxQ5thVT9fK0apjPFobqybMtA1UdUujWka24ERHbRHFGmpbbhp73MhV+KSsHQH9C6uOTdEQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fontkitten": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@clack/core": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@clack/core/-/core-1.4.0.tgz", + "integrity": "sha512-7Wctjq6f7c1CPz8sPpkwUnz8yRgVANkpNupb81q432FjcJg4l+Sw7XANdNSdWfAKq0IHI0JTcUeK5dxs/HrGPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-wrap-ansi": "^0.2.0", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 20.12.0" + } + }, + "node_modules/@clack/prompts": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-1.5.0.tgz", + "integrity": "sha512-wKh+wTjmrUoUdkZg8KpJO5X+p9PWV+KE9mePseq9UYWkukgTKsGS47RRL2HstwVcvDQH+PenrPJWII8+MfiiyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@clack/core": "1.4.0", + "fast-string-width": "^3.0.2", + "fast-wrap-ansi": "^0.2.0", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 20.12.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", + "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", + "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", + "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", + "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", + "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", + "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", + "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", + "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", + "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", + "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", + "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", + "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", + "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", + "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", + "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", + "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", + "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", + "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", + "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", + "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", + "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", + "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", + "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", + "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", + "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", + "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/colour": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.7.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@oslojs/encoding": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@oslojs/encoding/-/encoding-1.1.0.tgz", + "integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/pluginutils": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.4.0.tgz", + "integrity": "sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.61.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.61.0.tgz", + "integrity": "sha512-dnxczajOqt0gesZlN5pGQ1s1imQVrsmCw5G2Ci4oM+0WvNz3pyRnlWrT7McoZIb8VlFwCawdmbWRmxRn7HI+VQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.61.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.61.0.tgz", + "integrity": "sha512-Bp3JpGP00Vu3f238ivRrjf7z3xSzVPXqCmaJYA9t2c+c8vKYvOzmXF7LkkeUalTEGd6cZcSWe+PFIP3Vy48fRg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.61.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.61.0.tgz", + "integrity": "sha512-zaYIpr670mUmmZ1tVzUFplbQbG7h3Gugx3L5FoqhsC2m/YnLlR1a7zVLmXNPy+iY1tFPEbNG+HHBXZGyId0G5w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.61.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.61.0.tgz", + "integrity": "sha512-+P49fvkv2dSoeevUW+lgZ/I2JHSsJCK1Lyjj7Cu6E4UHG4tS9XIefzIjo5qhgELjAclnen1rLzK2PMKJdo+Dyg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.61.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.61.0.tgz", + "integrity": "sha512-l3FAAOyKJXH2ea6KNFN+MMgC/rnE94YGLXs2ehYqDcCoHt1DpvgWX75BhUJxN38XojP7Ul+4H8PRn7EdyqSDrw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.61.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.61.0.tgz", + "integrity": "sha512-VokPN3TSctKj65cyCNPaUh4vMFA8awxOot/0sp+4J7ZlNRKQEhXhawqPwajoi8H5ZFt61i0ugZJuTKXBjGJ17Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.61.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.61.0.tgz", + "integrity": "sha512-DxH0P3wxm+Yzs/p3zrk9dw1rURu8p0Nv5+MRK/L7OtnLNg5rLZraSBFZ8iUXOd9f2BlhJyEpIZUH/emjq4UJ4g==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.61.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.61.0.tgz", + "integrity": "sha512-T6ZvMNe84kAz6TBWHC7hGAoEtzP1LWYw/AqayGWEF6uISt3Abk/st06LqRD9THd7Xz3NxzurUpzAuEAUbZf+nw==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.61.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.61.0.tgz", + "integrity": "sha512-q/4hzvQkDs8b4jIBab1pnLiiM0ayTZsN2amBFPDzuyZxjEd4wDwx0UJFYM3cOZzSf5Kw8fnWSprJzIBMkcR44Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.61.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.61.0.tgz", + "integrity": "sha512-vvYWX3akdEAY6km+9wAqFDnk6pQsbJKVnj7xawcvs/+fdlYBGp+U+Qq/lLfpIxYIZvZLHMAKD9HLdacSx/r3dw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.61.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.61.0.tgz", + "integrity": "sha512-DePa5cqOxDP/Zp0VOXpeWaGew5iIv5DXp9NYbzkX5PFQyWVX9184WCTh3hvr/7lhXo8ZVlbFLkz8+o/q1dU6gA==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.61.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.61.0.tgz", + "integrity": "sha512-LV8aWMB8UChglMCEzs7RkN0GsH29RJaLLqwm9fCIjlqwxQTiWAqNcc7wjBkH31hV0PU/yVxGYvrYsgfea2qw6g==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.61.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.61.0.tgz", + "integrity": "sha512-QoNSnwQtaeNu5grdBbsL0tt1uyl5EnS8DA8Mr3nluMXbhdQNyhN+G4tBax7VCdxLKj8YJ0/4OO9Ho84jMnJtKA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.61.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.61.0.tgz", + "integrity": "sha512-/zZp5MKapIIApE8trN8qLGNSiRN9TUoaUZ1cmVu4XnVdd5LQLOXTtyi+vtfUbNnT3iyjzpPqYeKXmvJ+gJGYWw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.61.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.61.0.tgz", + "integrity": "sha512-RbrzcD3aJ1k3UbtMRRBNwojdVVyXjuVAFTfn/xPa6EEl6GE9Sm/akPgFTb9aAC9pMKGJ6CtWxaGrqWcabH+ySg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.61.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.61.0.tgz", + "integrity": "sha512-ZF+onDsBso8PJf1XaG9lB+O9RnBpKGnY6OrzC4CSHrtC1jb6jWLTKK4bRqdoCXHd22gyr2hiYmEAm8Wns/BOCw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.61.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.61.0.tgz", + "integrity": "sha512-Atk0aSIk5Zx2Wuh9dgRQgLP0Koc8hOeYpbWryMXyk8G8/HmPkwPPkMqIIDhrXHHYqfUzSJA/I7IWSBv8xSmRBA==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.61.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.61.0.tgz", + "integrity": "sha512-0uMOcf3eZ5K+K4cYHkdxShFMPlPXCOdfDFEFn9dNYAEEd2cVvmOfH7zFgRVoDgmtQ1m9k5q7qfrHzyMAubKYUA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.61.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.61.0.tgz", + "integrity": "sha512-mvFtE4A/t/7hRJ7X8Ozmu8FsIkAUat2nzl12pgU337BRmq87AQUJztwHz2Zv5/tjo9/C95E66CK03SI/ToEDJw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.61.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.61.0.tgz", + "integrity": "sha512-z9b9+aTxvt8n2rNltMPvyaUfB8NJ+CVyOrGK/MdIKHx7B+lXmZpm/XbRsU7Rpf3fRqJ2uS6mBJiJveCtq8LHDg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.61.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.61.0.tgz", + "integrity": "sha512-jXaXFqKMehsOc+g8R6oo33RRC6w07G9jDBxAE5eAKX7mOcCbZloYIPNhfG9Wl+P9O9IWHFO4OJgPi1Ml2qkt7w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.61.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.61.0.tgz", + "integrity": "sha512-OXNWVFocS2IA4+QplhTZZ2a+8hPZR7T8KuozsNmJKK8y7cp83StHvGksfHzPG3wczWTczyWHVQuqeiTUbjiyBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.61.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.61.0.tgz", + "integrity": "sha512-AlAbNtBO637LxSldqV43z0FfXoGfl2TW1DgAg/bs7aQswFbDewz2SJm3BUhiGfbOVtW571xbc9p+REdxhyN/Eg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.61.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.61.0.tgz", + "integrity": "sha512-QRSrQXyJ1M4tjNXdR0/G/IgV6lzfQQJYBjlWIEYkY2Xs86DRl/iEpQ4blMDjJxSl7n19eDKKXMg0AmuBVYy8pQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.61.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.61.0.tgz", + "integrity": "sha512-tkuFxhvKO/HlGd0VsINF6vHSYH8AF8W0TcNxKDK6JZmrehngFj78pToc8iemtnvwilDjs2G/qSzYFhe9U8q+fw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@shikijs/core": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-4.1.0.tgz", + "integrity": "sha512-jLJtSJeuFffqX6/inRE1zqU5aFv2hrszvYgq3OjbAgFRZiWv7abKMDdQzYxuSDfmUPQozZvI/kuy6VMTvnvqTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/primitive": "4.1.0", + "@shikijs/types": "4.1.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4", + "hast-util-to-html": "^9.0.5" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@shikijs/engine-javascript": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-4.1.0.tgz", + "integrity": "sha512-YquhawCUgaBfhsS72e2Y/dI59gCBNPHu3fEO/tvLaXrTssxZrY5ddjtNLTwndrMgPo8b3IscE+xoICDzpTmlFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "4.1.0", + "@shikijs/vscode-textmate": "^10.0.2", + "oniguruma-to-es": "^4.3.6" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-4.1.0.tgz", + "integrity": "sha512-axLpjVs45YBvvINa+dJF+NPW+KtFkNXsFr4SDw2BMj9GdeMnGxVB9PQb2xXlJYovslt/nz6giedAyOANkfc7hg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "4.1.0", + "@shikijs/vscode-textmate": "^10.0.2" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@shikijs/langs": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-4.1.0.tgz", + "integrity": "sha512-nwOMruEkbgdZfQ/b8CgpNBVOpvG1k0N5tbmgiFeqsan401+x3ILqlzZJowSla4Agmq4hG2Uf2wh5jLTEhR8VSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "4.1.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@shikijs/primitive": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@shikijs/primitive/-/primitive-4.1.0.tgz", + "integrity": "sha512-zx2/2Uwj2q9X3KSyYREEhXO23xBw5WUhP4orK2lE4r+t9JGITmEe0JH+wPmJhqHpOT2bRRs6lAL945+LDvOAGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "4.1.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@shikijs/themes": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-4.1.0.tgz", + "integrity": "sha512-emCcTnUM7yO2wltYbaxm+yLvcCI4+h8XBKc4KmJ7EZUXoSGjcCHifkI//R4OFit9ewpg7H2/9tjOuXrT2v/Knw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "4.1.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@shikijs/types": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-4.1.0.tgz", + "integrity": "sha512-3EQWX54fMpniOrDblzAhiwiJwpiTMW6+B9DWyUd9ska483tbayFYuw47UxwuPknI31bKnySfVQ/QW+jFL4rFdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/debug": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", + "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/nlcst": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/nlcst/-/nlcst-2.0.3.tgz", + "integrity": "sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.1.tgz", + "integrity": "sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-iterate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-2.0.1.tgz", + "integrity": "sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/astro": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/astro/-/astro-6.4.2.tgz", + "integrity": "sha512-8H89CH2dKL5SCU99OCqdU9BGjmPkSJqaPurywj5XMo7eMFGUFD3vsNhdEKnEh4mK4LgGje3/QDTTSIIGst0G0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@astrojs/compiler": "^4.0.0", + "@astrojs/internal-helpers": "0.10.0", + "@astrojs/markdown-remark": "7.2.0", + "@astrojs/telemetry": "3.3.2", + "@capsizecss/unpack": "^4.0.0", + "@clack/prompts": "^1.1.0", + "@oslojs/encoding": "^1.1.0", + "@rollup/pluginutils": "^5.3.0", + "aria-query": "^5.3.2", + "axobject-query": "^4.1.0", + "ci-info": "^4.4.0", + "clsx": "^2.1.1", + "common-ancestor-path": "^2.0.0", + "cookie": "^1.1.1", + "devalue": "^5.6.3", + "diff": "^8.0.3", + "dset": "^3.1.4", + "es-module-lexer": "^2.0.0", + "esbuild": "^0.27.3", + "flattie": "^1.1.1", + "fontace": "~0.4.1", + "get-tsconfig": "5.0.0-beta.4", + "github-slugger": "^2.0.0", + "html-escaper": "3.0.3", + "http-cache-semantics": "^4.2.0", + "js-yaml": "^4.1.1", + "jsonc-parser": "^3.3.1", + "magic-string": "^0.30.21", + "magicast": "^0.5.2", + "mrmime": "^2.0.1", + "neotraverse": "^0.6.18", + "obug": "^2.1.1", + "p-limit": "^7.3.0", + "p-queue": "^9.1.0", + "package-manager-detector": "^1.6.0", + "piccolore": "^0.1.3", + "picomatch": "^4.0.4", + "rehype": "^13.0.2", + "semver": "^7.7.4", + "shiki": "^4.0.2", + "smol-toml": "^1.6.0", + "svgo": "^4.0.1", + "tinyclip": "^0.1.12", + "tinyexec": "^1.0.4", + "tinyglobby": "^0.2.15", + "ultrahtml": "^1.6.0", + "unifont": "~0.7.4", + "unist-util-visit": "^5.1.0", + "unstorage": "^1.17.5", + "vfile": "^6.0.3", + "vite": "^7.3.2", + "vitefu": "^1.1.2", + "xxhash-wasm": "^1.1.0", + "yargs-parser": "^22.0.0", + "zod": "^4.3.6" + }, + "bin": { + "astro": "bin/astro.mjs" + }, + "engines": { + "node": ">=22.12.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/astrodotbuild" + }, + "optionalDependencies": { + "sharp": "^0.34.0" + } + }, + "node_modules/astro/node_modules/@astrojs/compiler": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-4.0.0.tgz", + "integrity": "sha512-eouss7G8ygdZqHuke033VMcVw5HTZUu+PXd/h06DGDUg/jt5btPYPqh66ENWw/mU78rBrf/oeC4oqoBwMtDMNA==", + "dev": true, + "license": "MIT" + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true, + "license": "ISC" + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/ci-info": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/common-ancestor-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-2.0.0.tgz", + "integrity": "sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">= 18" + } + }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cookie-es": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-1.2.3.tgz", + "integrity": "sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw==", + "dev": true, + "license": "MIT" + }, + "node_modules/crossws": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/crossws/-/crossws-0.3.5.tgz", + "integrity": "sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==", + "dev": true, + "license": "MIT", + "dependencies": { + "uncrypto": "^0.1.3" + } + }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", + "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.27.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", + "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/defu": { + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.7.tgz", + "integrity": "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/destr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz", + "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", + "dev": true, + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/devalue": { + "version": "5.8.1", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.8.1.tgz", + "integrity": "sha512-4CXDYRBGqN+57wVJkuXBYmpAVUSg3L6JAQa/DFqm238G73E1wuyc/JhGQJzN7vUf/CMphYau2zXbfWzDR5aTEw==", + "dev": true, + "license": "MIT" + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/diff": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.4.tgz", + "integrity": "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dset": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.4.tgz", + "integrity": "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-module-lexer": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz", + "integrity": "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", + "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.7", + "@esbuild/android-arm": "0.27.7", + "@esbuild/android-arm64": "0.27.7", + "@esbuild/android-x64": "0.27.7", + "@esbuild/darwin-arm64": "0.27.7", + "@esbuild/darwin-x64": "0.27.7", + "@esbuild/freebsd-arm64": "0.27.7", + "@esbuild/freebsd-x64": "0.27.7", + "@esbuild/linux-arm": "0.27.7", + "@esbuild/linux-arm64": "0.27.7", + "@esbuild/linux-ia32": "0.27.7", + "@esbuild/linux-loong64": "0.27.7", + "@esbuild/linux-mips64el": "0.27.7", + "@esbuild/linux-ppc64": "0.27.7", + "@esbuild/linux-riscv64": "0.27.7", + "@esbuild/linux-s390x": "0.27.7", + "@esbuild/linux-x64": "0.27.7", + "@esbuild/netbsd-arm64": "0.27.7", + "@esbuild/netbsd-x64": "0.27.7", + "@esbuild/openbsd-arm64": "0.27.7", + "@esbuild/openbsd-x64": "0.27.7", + "@esbuild/openharmony-arm64": "0.27.7", + "@esbuild/sunos-x64": "0.27.7", + "@esbuild/win32-arm64": "0.27.7", + "@esbuild/win32-ia32": "0.27.7", + "@esbuild/win32-x64": "0.27.7" + } + }, + "node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-string-truncated-width": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz", + "integrity": "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-string-width": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fast-string-width/-/fast-string-width-3.0.2.tgz", + "integrity": "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-string-truncated-width": "^3.0.2" + } + }, + "node_modules/fast-wrap-ansi": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/fast-wrap-ansi/-/fast-wrap-ansi-0.2.2.tgz", + "integrity": "sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-string-width": "^3.0.2" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/flattie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flattie/-/flattie-1.1.1.tgz", + "integrity": "sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/fontace": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/fontace/-/fontace-0.4.1.tgz", + "integrity": "sha512-lDMvbAzSnHmbYMTEld5qdtvNH2/pWpICOqpean9IgC7vUbUJc3k+k5Dokp85CegamqQpFbXf0rAVkbzpyTA8aw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fontkitten": "^1.0.2" + } + }, + "node_modules/fontkitten": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fontkitten/-/fontkitten-1.0.3.tgz", + "integrity": "sha512-Wp1zXWPVUPBmfoa3Cqc9ctaKuzKAV6uLstRqlR56kSjplf5uAce+qeyYym7F+PHbGTk+tCEdkCW6RD7DX/gBZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tiny-inflate": "^1.0.3" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-tsconfig": { + "version": "5.0.0-beta.4", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-5.0.0-beta.4.tgz", + "integrity": "sha512-7nF7C9fIPFEMHgEMEfgIlO9wDdZ8CyHw27rWciFZfHvHDReIiPhsYuzPRXsfvBCqFy1l8RRyyWV7QLM+ZhUJsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "engines": { + "node": ">=20.20.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/github-slugger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", + "dev": true, + "license": "ISC" + }, + "node_modules/h3": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/h3/-/h3-1.15.11.tgz", + "integrity": "sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cookie-es": "^1.2.3", + "crossws": "^0.3.5", + "defu": "^6.1.6", + "destr": "^2.0.5", + "iron-webcrypto": "^1.2.1", + "node-mock-http": "^1.0.4", + "radix3": "^1.1.2", + "ufo": "^1.6.3", + "uncrypto": "^0.1.3" + } + }, + "node_modules/hast-util-from-html": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz", + "integrity": "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.1.0", + "hast-util-from-parse5": "^8.0.0", + "parse5": "^7.0.0", + "vfile": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", + "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^9.0.0", + "property-information": "^7.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", + "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-html": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", + "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.1.tgz", + "integrity": "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-text": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", + "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "unist-util-find-after": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", + "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/html-escaper": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", + "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/iron-webcrypto": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz", + "integrity": "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/brc-dd" + } + }, + "node_modules/is-docker": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-4.0.0.tgz", + "integrity": "sha512-LHE+wROyG/Y/0ZnbktRCoTix2c1RhgWaZraMZ8o1Q7zCh0VSrICJQO5oqIIISrcSBtrXv0o233w1IYwsWCjTzA==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-inside-container/node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz", + "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/js-yaml": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz", + "integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/lru-cache": { + "version": "11.5.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.1.tgz", + "integrity": "sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/magicast": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.3.tgz", + "integrity": "sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.3", + "@babel/types": "^7.29.0", + "source-map-js": "^1.2.1" + } + }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-definitions": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz", + "integrity": "sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.3.tgz", + "integrity": "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", + "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", + "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/neotraverse": { + "version": "0.6.18", + "resolved": "https://registry.npmjs.org/neotraverse/-/neotraverse-0.6.18.tgz", + "integrity": "sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/nlcst-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/nlcst-to-string/-/nlcst-to-string-4.0.0.tgz", + "integrity": "sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/node-fetch-native": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz", + "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-mock-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/node-mock-http/-/node-mock-http-1.0.4.tgz", + "integrity": "sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/obug": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", + "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT" + }, + "node_modules/ofetch": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ofetch/-/ofetch-1.5.1.tgz", + "integrity": "sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "destr": "^2.0.5", + "node-fetch-native": "^1.6.7", + "ufo": "^1.6.1" + } + }, + "node_modules/ohash": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz", + "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/oniguruma-parser": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.12.2.tgz", + "integrity": "sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==", + "dev": true, + "license": "MIT" + }, + "node_modules/oniguruma-to-es": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-4.3.6.tgz", + "integrity": "sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "oniguruma-parser": "^0.12.2", + "regex": "^6.1.0", + "regex-recursion": "^6.0.2" + } + }, + "node_modules/p-limit": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-7.3.0.tgz", + "integrity": "sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.2.1" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-9.3.0.tgz", + "integrity": "sha512-7NED7xhQ74Ngp4JP/2e0VZHp7vSWfJfqeiR92jPgxsz6m0Se4P03YoTKa9dDXyZ3r6P616gUXttrB6nnHYKang==", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^5.0.4", + "p-timeout": "^7.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-7.0.1.tgz", + "integrity": "sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-manager-detector": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.6.0.tgz", + "integrity": "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==", + "dev": true, + "license": "MIT" + }, + "node_modules/parse-latin": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse-latin/-/parse-latin-7.0.0.tgz", + "integrity": "sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "@types/unist": "^3.0.0", + "nlcst-to-string": "^4.0.0", + "unist-util-modify-children": "^4.0.0", + "unist-util-visit-children": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/piccolore": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/piccolore/-/piccolore-0.1.3.tgz", + "integrity": "sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw==", + "dev": true, + "license": "ISC" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.15", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", + "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prismjs": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", + "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/property-information": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.2.0.tgz", + "integrity": "sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/radix3": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/radix3/-/radix3-1.1.2.tgz", + "integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/regex/-/regex-6.1.0.tgz", + "integrity": "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-recursion": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz", + "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-utilities": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz", + "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==", + "dev": true, + "license": "MIT" + }, + "node_modules/rehype": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/rehype/-/rehype-13.0.2.tgz", + "integrity": "sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "rehype-parse": "^9.0.0", + "rehype-stringify": "^10.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-parse": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-9.0.1.tgz", + "integrity": "sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-from-html": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-raw": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-stringify": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-10.0.1.tgz", + "integrity": "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-to-html": "^9.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", + "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-smartypants": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/remark-smartypants/-/remark-smartypants-3.0.2.tgz", + "integrity": "sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==", + "dev": true, + "license": "MIT", + "dependencies": { + "retext": "^9.0.0", + "retext-smartypants": "^6.0.0", + "unified": "^11.0.4", + "unist-util-visit": "^5.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/retext": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/retext/-/retext-9.0.0.tgz", + "integrity": "sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "retext-latin": "^4.0.0", + "retext-stringify": "^4.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-latin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/retext-latin/-/retext-latin-4.0.0.tgz", + "integrity": "sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "parse-latin": "^7.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-smartypants": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/retext-smartypants/-/retext-smartypants-6.2.0.tgz", + "integrity": "sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "nlcst-to-string": "^4.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-stringify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/retext-stringify/-/retext-stringify-4.0.0.tgz", + "integrity": "sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "nlcst-to-string": "^4.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rollup": { + "version": "4.61.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.61.0.tgz", + "integrity": "sha512-T9mWdbWfQtp0B5lv/HX+wrhYsmXRlcWnXXmJbXqKJhlRaoS6KMhq0gpyzW4UJfclcxrEdLnTgjT2NjruLONu0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.61.0", + "@rollup/rollup-android-arm64": "4.61.0", + "@rollup/rollup-darwin-arm64": "4.61.0", + "@rollup/rollup-darwin-x64": "4.61.0", + "@rollup/rollup-freebsd-arm64": "4.61.0", + "@rollup/rollup-freebsd-x64": "4.61.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.61.0", + "@rollup/rollup-linux-arm-musleabihf": "4.61.0", + "@rollup/rollup-linux-arm64-gnu": "4.61.0", + "@rollup/rollup-linux-arm64-musl": "4.61.0", + "@rollup/rollup-linux-loong64-gnu": "4.61.0", + "@rollup/rollup-linux-loong64-musl": "4.61.0", + "@rollup/rollup-linux-ppc64-gnu": "4.61.0", + "@rollup/rollup-linux-ppc64-musl": "4.61.0", + "@rollup/rollup-linux-riscv64-gnu": "4.61.0", + "@rollup/rollup-linux-riscv64-musl": "4.61.0", + "@rollup/rollup-linux-s390x-gnu": "4.61.0", + "@rollup/rollup-linux-x64-gnu": "4.61.0", + "@rollup/rollup-linux-x64-musl": "4.61.0", + "@rollup/rollup-openbsd-x64": "4.61.0", + "@rollup/rollup-openharmony-arm64": "4.61.0", + "@rollup/rollup-win32-arm64-msvc": "4.61.0", + "@rollup/rollup-win32-ia32-msvc": "4.61.0", + "@rollup/rollup-win32-x64-gnu": "4.61.0", + "@rollup/rollup-win32-x64-msvc": "4.61.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/sax": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", + "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/semver": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", + "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.2", + "semver": "^7.7.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" + } + }, + "node_modules/shiki": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-4.1.0.tgz", + "integrity": "sha512-l/ABZPUR5v70jI10EzqfMS/I96vjSGv2y0ihUV+WYFzv0EfvW4s54m0Lg8wCrrL+2IkwBzFTuxkZjPf8b2NX9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/core": "4.1.0", + "@shikijs/engine-javascript": "4.1.0", + "@shikijs/engine-oniguruma": "4.1.0", + "@shikijs/langs": "4.1.0", + "@shikijs/themes": "4.1.0", + "@shikijs/types": "4.1.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/smol-toml": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.6.1.tgz", + "integrity": "sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 18" + }, + "funding": { + "url": "https://github.com/sponsors/cyyynthia" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "dev": true, + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/svgo": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.1.tgz", + "integrity": "sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^11.1.0", + "css-select": "^5.1.0", + "css-tree": "^3.0.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.1.1", + "sax": "^1.5.0" + }, + "bin": { + "svgo": "bin/svgo.js" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/tiny-inflate": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", + "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyclip": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/tinyclip/-/tinyclip-0.1.13.tgz", + "integrity": "sha512-8OqlXQ35euK9+e7L68u8UwcODxkHoIkjbGsgXuARKNyQ5G6xt8nw1YPeMbxMLgCPFkToU+UEK5j05t2t8edKpQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^16.14.0 || >= 17.3.0" + } + }, + "node_modules/tinyexec": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz", + "integrity": "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/ufo": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.4.tgz", + "integrity": "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ultrahtml": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ultrahtml/-/ultrahtml-1.6.0.tgz", + "integrity": "sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==", + "dev": true, + "license": "MIT" + }, + "node_modules/uncrypto": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/uncrypto/-/uncrypto-0.1.3.tgz", + "integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unifont": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/unifont/-/unifont-0.7.4.tgz", + "integrity": "sha512-oHeis4/xl42HUIeHuNZRGEvxj5AaIKR+bHPNegRq5LV1gdc3jundpONbjglKpihmJf+dswygdMJn3eftGIMemg==", + "dev": true, + "license": "MIT", + "dependencies": { + "css-tree": "^3.1.0", + "ofetch": "^1.5.1", + "ohash": "^2.0.11" + } + }, + "node_modules/unist-util-find-after": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", + "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", + "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-modify-children": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-modify-children/-/unist-util-modify-children-4.0.0.tgz", + "integrity": "sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "array-iterate": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", + "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", + "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-children": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-children/-/unist-util-visit-children-3.0.0.tgz", + "integrity": "sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unstorage": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/unstorage/-/unstorage-1.17.5.tgz", + "integrity": "sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "^3.1.3", + "chokidar": "^5.0.0", + "destr": "^2.0.5", + "h3": "^1.15.10", + "lru-cache": "^11.2.7", + "node-fetch-native": "^1.6.7", + "ofetch": "^1.5.1", + "ufo": "^1.6.3" + }, + "peerDependencies": { + "@azure/app-configuration": "^1.8.0", + "@azure/cosmos": "^4.2.0", + "@azure/data-tables": "^13.3.0", + "@azure/identity": "^4.6.0", + "@azure/keyvault-secrets": "^4.9.0", + "@azure/storage-blob": "^12.26.0", + "@capacitor/preferences": "^6 || ^7 || ^8", + "@deno/kv": ">=0.9.0", + "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", + "@planetscale/database": "^1.19.0", + "@upstash/redis": "^1.34.3", + "@vercel/blob": ">=0.27.1", + "@vercel/functions": "^2.2.12 || ^3.0.0", + "@vercel/kv": "^1 || ^2 || ^3", + "aws4fetch": "^1.0.20", + "db0": ">=0.2.1", + "idb-keyval": "^6.2.1", + "ioredis": "^5.4.2", + "uploadthing": "^7.4.4" + }, + "peerDependenciesMeta": { + "@azure/app-configuration": { + "optional": true + }, + "@azure/cosmos": { + "optional": true + }, + "@azure/data-tables": { + "optional": true + }, + "@azure/identity": { + "optional": true + }, + "@azure/keyvault-secrets": { + "optional": true + }, + "@azure/storage-blob": { + "optional": true + }, + "@capacitor/preferences": { + "optional": true + }, + "@deno/kv": { + "optional": true + }, + "@netlify/blobs": { + "optional": true + }, + "@planetscale/database": { + "optional": true + }, + "@upstash/redis": { + "optional": true + }, + "@vercel/blob": { + "optional": true + }, + "@vercel/functions": { + "optional": true + }, + "@vercel/kv": { + "optional": true + }, + "aws4fetch": { + "optional": true + }, + "db0": { + "optional": true + }, + "idb-keyval": { + "optional": true + }, + "ioredis": { + "optional": true + }, + "uploadthing": { + "optional": true + } + } + }, + "node_modules/unstorage/node_modules/chokidar": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^5.0.0" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/unstorage/node_modules/readdirp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", + "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vite": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.5.tgz", + "integrity": "sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vitefu": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.3.tgz", + "integrity": "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==", + "dev": true, + "license": "MIT", + "workspaces": [ + "tests/deps/*", + "tests/projects/*", + "tests/projects/workspace/packages/*" + ], + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/which-pm-runs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", + "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/xxhash-wasm": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-1.1.0.tgz", + "integrity": "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yocto-queue": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", + "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", + "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/site/marketing/package.json b/site/marketing/package.json new file mode 100644 index 0000000..f1f6bad --- /dev/null +++ b/site/marketing/package.json @@ -0,0 +1,15 @@ +{ + "name": "@evydence/marketing-site", + "version": "0.1.0", + "private": true, + "type": "module", + "scripts": { + "build": "astro build", + "check": "npm run build && node scripts/check.mjs", + "dev": "astro dev", + "preview": "astro preview" + }, + "devDependencies": { + "astro": "6.4.2" + } +} diff --git a/site/marketing/scripts/check.mjs b/site/marketing/scripts/check.mjs new file mode 100644 index 0000000..5607686 --- /dev/null +++ b/site/marketing/scripts/check.mjs @@ -0,0 +1,130 @@ +import { existsSync, readFileSync } from "node:fs"; +import { join } from "node:path"; + +const root = new URL("..", import.meta.url).pathname; +const dist = join(root, "dist"); + +const requiredFiles = [ + "index.html", + "en/index.html", + "fi/index.html", + "en/product/index.html", + "fi/tuote/index.html", + "en/use-cases/customer-security-review/index.html", + "fi/kayttotapaukset/asiakkaan-tietoturvakatselmus/index.html", + "en/use-cases/release-evidence-package/index.html", + "fi/kayttotapaukset/julkaisun-evidence-paketti/index.html", + "en/commercial/index.html", + "fi/kaupallinen/index.html", + "en/status/index.html", + "fi/tila/index.html", + "en/resources/glossary/index.html", + "fi/resurssit/sanasto/index.html", + "en/resources/cra-readiness-evidence/index.html", + "fi/resurssit/cra-valmiuden-evidence/index.html", + "en/contact/index.html", + "fi/yhteys/index.html", + "en/privacy-cookies/index.html", + "fi/yksityisyys-evasteet/index.html", + "docs/index.html", + "github/index.html" +]; + +for (const file of requiredFiles) { + const path = join(dist, file); + if (!existsSync(path)) { + throw new Error(`missing built page: ${file}`); + } +} + +const rootPage = readFileSync(join(dist, "index.html"), "utf8"); +const english = readFileSync(join(dist, "en/index.html"), "utf8"); +const finnish = readFileSync(join(dist, "fi/index.html"), "utf8"); +const privacy = readFileSync(join(dist, "en/privacy-cookies/index.html"), "utf8"); +const consentSource = readFileSync(join(root, "src/components/ConsentBanner.astro"), "utf8"); +const layoutSource = readFileSync(join(root, "src/layouts/BaseLayout.astro"), "utf8"); + +const requiredRoot = [ + 'lang="en"', + "url=/evydence/en/", + "Continue in English", + "/evydence/fi/" +]; + +for (const text of requiredRoot) { + if (!rootPage.includes(text)) { + throw new Error(`Root page missing English default routing marker: ${text}`); + } +} + +const requiredEnglish = [ + 'lang="en"', + 'hreflang="fi"', + "Stop scrambling when customers ask for release security evidence.", + "Cookie preferences", + "Evydence is not a legal compliance service" +]; + +for (const text of requiredEnglish) { + if (!english.includes(text)) { + throw new Error(`English homepage missing: ${text}`); + } +} + +const requiredFinnish = [ + 'lang="fi"', + 'hreflang="en"', + "Lopeta kiireinen selvittely", + "Evästeasetukset", + "Evydence ei ole juridinen" +]; + +for (const text of requiredFinnish) { + if (!finnish.includes(text)) { + throw new Error(`Finnish homepage missing: ${text}`); + } +} + +const consentChecks = [ + "analytics_storage: \"denied\"", + "ad_storage: \"denied\"", + "https://www.googletagmanager.com/gtag/js?id=", + "data-consent-accept-all", + "data-consent-reject-optional", + "Accept all", + "data-cookie-preferences" +]; + +for (const text of consentChecks) { + if (!consentSource.includes(text)) { + throw new Error(`Consent implementation missing: ${text}`); + } +} + +const layoutChecks = [ + "class=\"mobile-nav\"", + "mobile-nav__panel", + "font-size: clamp(2.7rem, 5.4vw, 5.25rem)", + "min-height: min(760px, calc(100vh - 4.8rem))", + ".nav,\n .header-actions {\n display: none;" +]; + +for (const text of layoutChecks) { + if (!layoutSource.includes(text)) { + throw new Error(`Layout implementation missing: ${text}`); + } +} + +for (const forbidden of ["innerHTML", "Start free trial", "100% secure", "automatically compliant"]) { + if (english.includes(forbidden) || finnish.includes(forbidden) || privacy.includes(forbidden)) { + throw new Error(`forbidden site text found: ${forbidden}`); + } +} + +for (const forbidden of ["Accept analytics", "Manage choices", "data-consent-manage"]) { + if (consentSource.includes(forbidden)) { + throw new Error(`forbidden consent choice found: ${forbidden}`); + } +} + +console.log("marketing-site-check: passed"); diff --git a/site/marketing/src/components/ConsentBanner.astro b/site/marketing/src/components/ConsentBanner.astro new file mode 100644 index 0000000..9e180ca --- /dev/null +++ b/site/marketing/src/components/ConsentBanner.astro @@ -0,0 +1,172 @@ +--- +import type { Locale } from "@data/site"; + +type Copy = { + title: string; + body: string; + acceptAll: string; + rejectOptional: string; + note: string; +}; + +const copy: Record = { + en: { + title: "Cookie choices", + body: "Evydence uses necessary local preferences for language and cookie choices. If you accept all, we also allow aggregate site measurement.", + acceptAll: "Accept all", + rejectOptional: "Reject optional", + note: "You can change this choice from Cookie preferences in the footer." + }, + fi: { + title: "Evästevalinnat", + body: "Evydence käyttää välttämättömiä paikallisia asetuksia kieleen ja evästevalintoihin. Jos hyväksyt kaikki, sallimme myös kootun sivustomittauksen.", + acceptAll: "Hyväksy kaikki", + rejectOptional: "Hylkää valinnaiset", + note: "Voit muuttaa valintaa alatunnisteen evästeasetuksista." + } +}; + +const { locale } = Astro.props as { locale: Locale }; +const text = copy[locale]; +const measurementId = import.meta.env.PUBLIC_GA_MEASUREMENT_ID ?? ""; +--- + + + + diff --git a/site/marketing/src/components/DossierVisual.astro b/site/marketing/src/components/DossierVisual.astro new file mode 100644 index 0000000..628e5a8 --- /dev/null +++ b/site/marketing/src/components/DossierVisual.astro @@ -0,0 +1,27 @@ +--- +const items = [ + ["01", "Artifact digest"], + ["02", "SBOM inventory"], + ["03", "Vulnerability decision"], + ["04", "Signed package"] +]; +--- + +
+
+ Release dossier + verify-ready +
+
+ {items.map(([number, label]) => ( +
+ {number} +

{label}

+
+ ))} +
+ +
diff --git a/site/marketing/src/data/site.ts b/site/marketing/src/data/site.ts new file mode 100644 index 0000000..b16d9ef --- /dev/null +++ b/site/marketing/src/data/site.ts @@ -0,0 +1,781 @@ +export type Locale = "en" | "fi"; + +export type PageKey = + | "home" + | "product" + | "customerReview" + | "releasePackage" + | "commercial" + | "status" + | "glossary" + | "cra" + | "contact" + | "privacyCookies"; + +type Section = { + eyebrow?: string; + title: string; + body?: string[]; + bullets?: string[]; + cards?: Array<{ title: string; body: string }>; + table?: Array<{ left: string; right: string }>; +}; + +export type PageContent = { + key: PageKey; + title: string; + navTitle: string; + metaTitle: string; + description: string; + eyebrow?: string; + heroTitle: string; + heroBody: string[]; + primaryCta: string; + secondaryCta: string; + sections: Section[]; +}; + +export const localeNames: Record = { + en: "English", + fi: "Suomi" +}; + +export const routes: Record> = { + home: { en: "/en/", fi: "/fi/" }, + product: { en: "/en/product/", fi: "/fi/tuote/" }, + customerReview: { + en: "/en/use-cases/customer-security-review/", + fi: "/fi/kayttotapaukset/asiakkaan-tietoturvakatselmus/" + }, + releasePackage: { + en: "/en/use-cases/release-evidence-package/", + fi: "/fi/kayttotapaukset/julkaisun-evidence-paketti/" + }, + commercial: { en: "/en/commercial/", fi: "/fi/kaupallinen/" }, + status: { en: "/en/status/", fi: "/fi/tila/" }, + glossary: { en: "/en/resources/glossary/", fi: "/fi/resurssit/sanasto/" }, + cra: { + en: "/en/resources/cra-readiness-evidence/", + fi: "/fi/resurssit/cra-valmiuden-evidence/" + }, + contact: { en: "/en/contact/", fi: "/fi/yhteys/" }, + privacyCookies: { + en: "/en/privacy-cookies/", + fi: "/fi/yksityisyys-evasteet/" + } +}; + +export const orderedPageKeys: PageKey[] = [ + "home", + "product", + "customerReview", + "releasePackage", + "commercial", + "status", + "glossary", + "cra", + "contact", + "privacyCookies" +]; + +export const navItems: PageKey[] = [ + "product", + "customerReview", + "commercial", + "status", + "glossary", + "contact" +]; + +export const externalLinks = { + github: "https://github.com/aatuh/evydence", + docs: "https://github.com/aatuh/evydence/tree/master/docs", + commercialEmail: "mailto:aatu@example.com?subject=Evydence%20Commercial%20Self-Hosted%20inquiry" +}; + +const en: Record = { + home: { + key: "home", + title: "Home", + navTitle: "Home", + metaTitle: "Evydence - release security evidence without the scramble", + description: + "Evydence helps software vendors answer customer release-security questions with organized, verifiable evidence.", + eyebrow: "Self-hosted release evidence", + heroTitle: "Stop scrambling when customers ask for release security evidence.", + heroBody: [ + "Evydence helps software vendors organize the proof behind a software release: what was shipped, what was inside it, which vulnerabilities were reviewed, what decisions were made, and what can safely be shared with customers.", + "Run it self-hosted, keep technical truth on GitHub, and use commercial terms when your organization needs them." + ], + primaryCta: "Ask about Commercial Self-Hosted", + secondaryCta: "View GitHub", + sections: [ + { + eyebrow: "The problem", + title: "Customer security reviews are becoming more detailed.", + body: [ + "A customer may ask what third-party components are inside a release, whether known vulnerabilities are present, whether a CVE affects your product, who reviewed the decision, and what proof can be verified.", + "For many teams, the answer is scattered across scanner exports, CI logs, tickets, chat, spreadsheets, object storage, and one-off PDFs." + ] + }, + { + eyebrow: "The outcome", + title: "Evydence gives each release an evidence trail.", + bullets: [ + "software component inventory", + "vulnerability scan results", + "vulnerability decisions", + "approvals and exceptions", + "build and artifact proof", + "release-readiness reports", + "signed bundles", + "customer-safe packages" + ] + }, + { + title: "Before and after Evydence", + table: [ + { left: "Evidence scattered across tools", right: "Evidence linked to a release" }, + { left: "Manual customer answers", right: "Repeatable customer package" }, + { left: "Decisions hidden in tickets or chat", right: "Decision trail with actor context" }, + { left: "Hard to explain not affected", right: "Reviewable vulnerability decision" }, + { left: "One-off PDF work", right: "Package generated from structured records" } + ] + }, + { + title: "What it is not", + body: [ + "Evydence is not a scanner, firewall, legal compliance engine, certification service, or guarantee that a release is secure.", + "It helps organize technical evidence and release-security decisions so teams can answer review questions more clearly and repeatably." + ] + } + ] + }, + product: { + key: "product", + title: "Product", + navTitle: "Product", + metaTitle: "Product - Evydence", + description: "A self-hosted evidence system for software releases.", + eyebrow: "Product overview", + heroTitle: "A self-hosted evidence system for software releases.", + heroBody: [ + "Evydence keeps release evidence connected to the product, version, artifact, vulnerability, decision, approval, and customer package it belongs to." + ], + primaryCta: "Ask about Commercial Self-Hosted", + secondaryCta: "View GitHub", + sections: [ + { + title: "Capture release evidence", + body: [ + "Collect proof material around a release: component inventories, vulnerability scans, build metadata, artifact digests, source records, deployment events, and supporting files." + ] + }, + { + title: "Record vulnerability decisions", + body: [ + "When a known vulnerability appears, record whether it affects the release, why, who reviewed it, and what evidence supports the decision." + ] + }, + { + title: "Generate customer-safe packages", + body: [ + "Create packages that include evidence a customer can review without exposing unnecessary internal detail." + ] + }, + { + title: "Verify the package", + body: [ + "Use manifests, hashes, signatures, and audit-chain records to make the package reviewable instead of just another static document." + ] + }, + { + title: "Self-hosted by design", + body: [ + "Evydence is designed for teams that want to run the evidence system in their own environment, close to release, security, and CI/CD systems." + ] + } + ] + }, + customerReview: { + key: "customerReview", + title: "Customer security reviews", + navTitle: "Use cases", + metaTitle: "Customer security reviews - Evydence", + description: "Turn customer security review questions into a repeatable release evidence workflow.", + eyebrow: "Use case", + heroTitle: "Customer security reviews should not require a scavenger hunt.", + heroBody: [ + "Enterprise customers increasingly ask software vendors to explain what is inside a release, which known vulnerabilities are present, which ones actually affect the product, and what proof supports the answer.", + "Evydence helps turn that review from a manual scramble into a repeatable release evidence workflow." + ], + primaryCta: "Ask about a release evidence pilot", + secondaryCta: "View GitHub", + sections: [ + { + title: "The question that triggers the scramble", + body: [ + "A customer asks: This CVE appears in your software bill of materials. Are we affected?", + "Without a system, the answer may require checking the SBOM, vulnerability scanner, CI logs, build artifacts, internal tickets, approvals, release notes, and previous customer responses." + ] + }, + { + title: "A clearer answer", + bullets: [ + "yes, affected and fixed", + "yes, affected and accepted with an exception", + "no, present but not exploitable in this product context", + "unknown, with documented gaps and next steps" + ] + }, + { + title: "Before and after", + table: [ + { + left: "We think this is not exploitable. Let us check with engineering.", + right: "For this release, the finding was reviewed, marked not affected, linked to supporting evidence, and included in the customer-safe package." + } + ] + } + ] + }, + releasePackage: { + key: "releasePackage", + title: "Release evidence packages", + navTitle: "Packages", + metaTitle: "Release evidence packages - Evydence", + description: "One release, one organized evidence package.", + eyebrow: "Use case", + heroTitle: "One release. One organized evidence package.", + heroBody: [ + "An evidence package is a structured set of proof material for a software release.", + "It can include what was shipped, what components were inside, which known vulnerabilities were found, how those findings were handled, who approved the decision, and what a customer can verify." + ], + primaryCta: "Ask about Commercial Self-Hosted", + secondaryCta: "View GitHub", + sections: [ + { + title: "Suggested package contents", + bullets: [ + "product and release identity", + "shipped artifact references", + "artifact hashes or digests", + "SBOM/component inventory", + "vulnerability scan summary", + "vulnerability decisions", + "exception or waiver records", + "build/source provenance", + "approval trail", + "package manifest", + "limitations and assumptions", + "customer-safe redactions" + ] + }, + { + title: "Important boundary", + body: [ + "The package does not mean the release is perfectly secure.", + "It means the team can show what was checked, what was decided, what is still unknown, and what evidence supports the answer." + ] + } + ] + }, + commercial: { + key: "commercial", + title: "Commercial", + navTitle: "Commercial", + metaTitle: "Commercial Self-Hosted Licensing - Evydence", + description: "Commercial self-hosted licensing, async support, deployment review, and integration support.", + eyebrow: "Commercial Self-Hosted", + heroTitle: "Commercial Self-Hosted Licensing.", + heroBody: [ + "Use Evydence under AGPL when that fits your organization.", + "Buy Evydence Commercial Self-Hosted when you need private commercial terms, AGPL exception, async support, signed release/evidence delivery, or deployment review." + ], + primaryCta: "Start async commercial inquiry", + secondaryCta: "View GitHub", + sections: [ + { + title: "Community AGPL vs Commercial Self-Hosted", + table: [ + { left: "Public AGPL license", right: "Separate written commercial agreement" }, + { left: "Public GitHub issues", right: "Private async support" }, + { left: "Best-effort community help", right: "Agreed support and upgrade path" }, + { left: "Self-evaluation", right: "Optional deployment-readiness review" }, + { left: "AGPL obligations apply", right: "Extra permission for agreed use cases" } + ] + }, + { + title: "Paid options", + cards: [ + { title: "Commercial Self-Hosted License", body: "Private commercial terms, procurement-friendly licensing, and an agreed support path." }, + { title: "Async Support", body: "Private written support for troubleshooting, upgrade planning, deployment questions, and release evidence workflows." }, + { title: "Deployment Readiness Review", body: "Written review of configuration, backup/restore, evidence handling, deployment architecture, and known limitations." }, + { title: "Release Evidence Package Review", body: "Written review of one evidence package, including gaps, assumptions, limitations, and customer-safe sharing concerns." }, + { title: "Custom Integration", body: "Collector adapters, evidence workflows, report templates, CI/CD integration, or deployment hardening." } + ] + }, + { + title: "Commercial boundary", + body: [ + "Commercial terms do not turn Evydence into a legal compliance guarantee, security certification, vulnerability scanner, or managed SaaS service." + ] + } + ] + }, + status: { + key: "status", + title: "Status", + navTitle: "Status", + metaTitle: "Current status and limitations - Evydence", + description: "Current status and supported self-hosted deployment profile.", + eyebrow: "Status and limitations", + heroTitle: "Current status and supported deployment profile.", + heroBody: [ + "Evydence is intended for evaluation, pilots, and controlled internal self-hosted production after operator review.", + "It is not marketed as a hosted SaaS product or a broad regulated-production platform." + ], + primaryCta: "Ask about deployment fit", + secondaryCta: "View GitHub", + sections: [ + { + title: "Deployment fit", + table: [ + { left: "Local technical evaluation", right: "Good fit" }, + { left: "Pilot with one product/release", right: "Good fit" }, + { left: "Controlled internal self-hosted use", right: "Candidate after review" }, + { left: "Regulated production", right: "Requires extra review" }, + { left: "Air-gapped production", right: "Requires transfer controls" }, + { left: "Hosted SaaS by Evydence", right: "Not currently offered" } + ] + }, + { + title: "Why this page exists", + body: [ + "This page filters out bad-fit use cases and increases trust with good-fit evaluators by stating limitations plainly." + ] + } + ] + }, + glossary: { + key: "glossary", + title: "Glossary", + navTitle: "Glossary", + metaTitle: "Plain-English glossary - Evydence", + description: "Plain-English terms for release evidence, SBOMs, CVEs, VEX, and customer-safe packages.", + eyebrow: "Resources", + heroTitle: "Plain-English glossary.", + heroBody: [ + "Short explanations for people evaluating release evidence workflows without needing every implementation detail." + ], + primaryCta: "Ask about Commercial Self-Hosted", + secondaryCta: "View GitHub", + sections: [ + { + title: "Terms", + cards: [ + { title: "Evidence", body: "Proof material around a software release: scan results, component lists, build records, vulnerability decisions, approvals, artifact hashes, release reports, and customer-safe files." }, + { title: "Evidence package", body: "An organized bundle of release proof that can be reviewed internally or shared with a customer." }, + { title: "SBOM", body: "A software ingredients list. It describes the components used inside software." }, + { title: "CVE", body: "A public identifier for a known software flaw." }, + { title: "VEX", body: "A structured way to explain whether a known vulnerability actually affects a specific product or release." }, + { title: "Customer-safe package", body: "A package that contains useful review evidence without exposing unnecessary internal details." }, + { title: "Release readiness", body: "A structured view of whether the release has expected evidence, decisions, approvals, and known limitations before it is shared or shipped." } + ] + } + ] + }, + cra: { + key: "cra", + title: "CRA-readiness evidence", + navTitle: "CRA readiness", + metaTitle: "Technical evidence organization for CRA readiness - Evydence", + description: "Technical evidence organization for CRA-readiness work without legal compliance claims.", + eyebrow: "Resources", + heroTitle: "Technical evidence organization for CRA readiness.", + heroBody: [ + "The EU Cyber Resilience Act is increasing attention on vulnerability handling, technical documentation, and product-security processes.", + "Evydence does not provide legal compliance or certification, but it can help organize technical release evidence that product-security and compliance-readiness teams may need to review." + ], + primaryCta: "Ask about a release evidence review", + secondaryCta: "View GitHub", + sections: [ + { + title: "Careful wording", + body: [ + "Evydence can support CRA-readiness work by helping teams preserve release-level technical evidence, vulnerability decisions, SBOM records, package manifests, and known limitations." + ] + }, + { + title: "Wording to avoid", + bullets: [ + "Evydence makes you CRA compliant.", + "Evydence certifies your releases.", + "Evydence guarantees regulatory acceptance.", + "Evydence proves your software is secure." + ] + } + ] + }, + contact: { + key: "contact", + title: "Contact", + navTitle: "Contact", + metaTitle: "Async commercial inquiry - Evydence", + description: "Start an async commercial self-hosted inquiry.", + eyebrow: "Async-first contact", + heroTitle: "Async commercial inquiry.", + heroBody: [ + "Evydence commercial support is async-first. Send context, deployment assumptions, release workflow notes, or commercial licensing questions. You will receive a written response." + ], + primaryCta: "Send async inquiry", + secondaryCta: "View GitHub", + sections: [ + { + title: "What to include", + bullets: [ + "your intended use", + "target deployment model", + "AGPL or commercial concerns", + "support expectations", + "target release workflow", + "preferred next step" + ] + }, + { + title: "Do not send sensitive evidence", + body: [ + "Do not send raw evidence payloads, bearer tokens, private keys, database URLs, customer data, or unreleased package contents through the public contact path.", + "A short scoping call can be requested after async context is shared." + ] + } + ] + }, + privacyCookies: { + key: "privacyCookies", + title: "Privacy and cookies", + navTitle: "Privacy", + metaTitle: "Privacy and cookies - Evydence", + description: "How the marketing site handles necessary preferences and optional measurement.", + eyebrow: "Privacy", + heroTitle: "Privacy and cookies.", + heroBody: [ + "The marketing site uses only necessary local preferences until you choose to accept optional site measurement.", + "Optional measurement, when enabled, is limited to aggregate marketing-site events." + ], + primaryCta: "Manage cookie choices", + secondaryCta: "View GitHub", + sections: [ + { + title: "What may be measured after acceptance", + bullets: [ + "page views", + "outbound GitHub clicks", + "docs clicks", + "contact clicks", + "language switches" + ] + }, + { + title: "What is not measured", + body: [ + "The site must not track raw form text, email addresses, customer names, company names, evidence package data, tokens, query parameters containing secrets, or support content." + ] + }, + { + title: "Changing your choice", + body: [ + "Use the footer cookie preferences link to reopen the consent panel and change your optional measurement choice." + ] + } + ] + } +}; + +const fi: Record = { + home: { + ...en.home, + title: "Etusivu", + navTitle: "Etusivu", + metaTitle: "Evydence - julkaisun tietoturvaevidence ilman säätöä", + description: + "Evydence auttaa ohjelmistotoimittajia vastaamaan asiakkaiden julkaisun tietoturvakysymyksiin järjestetyllä ja todennettavalla evidencellä.", + eyebrow: "Itse ylläpidettävä julkaisuevidence", + heroTitle: "Lopeta kiireinen selvittely, kun asiakas pyytää julkaisun tietoturvaevidenceä.", + heroBody: [ + "Evydence auttaa ohjelmistotoimittajia järjestämään ohjelmistojulkaisun taustalla olevan evidencen: mitä toimitettiin, mitä se sisälsi, mitkä haavoittuvuudet arvioitiin, mitä päätöksiä tehtiin ja mitä voidaan jakaa asiakkaalle turvallisesti.", + "Aja järjestelmää itse, pidä tekninen totuus GitHubissa ja käytä kaupallisia ehtoja, kun organisaatiosi tarvitsee niitä." + ], + primaryCta: "Kysy Commercial Self-Hosted -ehdoista", + secondaryCta: "Avaa GitHub", + sections: [ + { + eyebrow: "Ongelma", + title: "Asiakkaiden tietoturvakatselmukset ovat yhä yksityiskohtaisempia.", + body: [ + "Asiakas voi kysyä, mitä kolmannen osapuolen komponentteja julkaisu sisältää, onko tunnettuja haavoittuvuuksia mukana, vaikuttaako CVE tuotteeseen, kuka arvioi päätöksen ja mitä näyttöä voidaan todentaa.", + "Monessa tiimissä vastaus on hajallaan skannerivienneissä, CI-lokeissa, tiketeissä, keskusteluissa, taulukoissa, objektitallennuksessa ja kertaluonteisissa PDF-tiedostoissa." + ] + }, + { + eyebrow: "Lopputulos", + title: "Evydence antaa jokaiselle julkaisulle evidence-polun.", + bullets: [ + "ohjelmistokomponenttien inventaario", + "haavoittuvuusskannausten tulokset", + "haavoittuvuuspäätökset", + "hyväksynnät ja poikkeukset", + "koonti- ja artefaktievidence", + "julkaisuvalmiuden raportit", + "allekirjoitetut bundle-paketit", + "asiakkaalle turvalliset paketit" + ] + }, + { + title: "Ennen ja jälkeen Evydencen", + table: [ + { left: "Evidence on hajallaan työkaluissa", right: "Evidence on linkitetty julkaisuun" }, + { left: "Asiakasvastaukset ovat käsityötä", right: "Asiakaspaketti voidaan toistaa" }, + { left: "Päätökset ovat piilossa tiketeissä tai chatissa", right: "Päätöspolku sisältää tekijäkontekstin" }, + { left: "Not affected -päätöstä on vaikea selittää", right: "Haavoittuvuuspäätös on katselmoitavissa" }, + { left: "PDF-työ tehdään kertaluonteisesti", right: "Paketti syntyy rakenteisista tietueista" } + ] + }, + { + title: "Mitä Evydence ei ole", + body: [ + "Evydence ei ole skanneri, palomuuri, juridinen vaatimustenmukaisuuskone, sertifiointipalvelu tai takuu siitä, että julkaisu on turvallinen.", + "Se auttaa järjestämään teknisen evidencen ja julkaisun tietoturvapäätökset, jotta tiimit voivat vastata katselmuskysymyksiin selkeämmin ja toistettavammin." + ] + } + ] + }, + product: { + ...en.product, + title: "Tuote", + navTitle: "Tuote", + metaTitle: "Tuote - Evydence", + description: "Itse ylläpidettävä evidence-järjestelmä ohjelmistojulkaisuille.", + eyebrow: "Tuotekuvaus", + heroTitle: "Itse ylläpidettävä evidence-järjestelmä ohjelmistojulkaisuille.", + heroBody: [ + "Evydence pitää julkaisuevidencen kytkettynä tuotteeseen, versioon, artefaktiin, haavoittuvuuteen, päätökseen, hyväksyntään ja asiakaspakettiin." + ], + primaryCta: "Kysy Commercial Self-Hosted -ehdoista", + secondaryCta: "Avaa GitHub", + sections: [ + { title: "Kerää julkaisuevidence", body: ["Kerää julkaisun ympärillä oleva todistusaineisto: komponenttilistat, haavoittuvuusskannaukset, koontimetatiedot, artefaktien digestit, lähdekooditietueet, käyttöönotot ja tukevat tiedostot."] }, + { title: "Tallenna haavoittuvuuspäätökset", body: ["Kun tunnettu haavoittuvuus löytyy, tallenna vaikuttaako se julkaisuun, miksi, kuka sen arvioi ja mikä evidence tukee päätöstä."] }, + { title: "Luo asiakkaalle turvallisia paketteja", body: ["Luo paketteja, jotka sisältävät asiakkaalle hyödyllisen evidencen ilman tarpeetonta sisäistä yksityiskohtaa."] }, + { title: "Todenna paketti", body: ["Käytä manifestteja, tiivisteitä, allekirjoituksia ja audit chain -tietueita, jotta paketti on katselmoitava eikä vain uusi staattinen dokumentti."] }, + { title: "Itse ylläpidettävä lähtökohta", body: ["Evydence on tarkoitettu tiimeille, jotka haluavat ajaa evidence-järjestelmää omassa ympäristössään lähellä julkaisu-, tietoturva- ja CI/CD-järjestelmiä."] } + ] + }, + customerReview: { + ...en.customerReview, + title: "Asiakkaan tietoturvakatselmukset", + navTitle: "Käyttötapaukset", + metaTitle: "Asiakkaan tietoturvakatselmukset - Evydence", + description: "Muuta asiakkaan tietoturvakysymykset toistettavaksi julkaisuevidence-työnkuluksi.", + eyebrow: "Käyttötapaus", + heroTitle: "Asiakkaan tietoturvakatselmuksen ei pitäisi olla aarteenetsintä.", + heroBody: [ + "Yritysasiakkaat kysyvät yhä useammin, mitä julkaisu sisältää, mitä tunnettuja haavoittuvuuksia löytyy, mitkä niistä todella vaikuttavat tuotteeseen ja mikä evidence tukee vastausta.", + "Evydence auttaa muuttamaan katselmuksen käsityöstä toistettavaksi julkaisuevidence-työnkuluksi." + ], + primaryCta: "Kysy julkaisuevidence-pilotista", + secondaryCta: "Avaa GitHub", + sections: [ + { title: "Kysymys, joka käynnistää selvityksen", body: ["Asiakas kysyy: Tämä CVE näkyy ohjelmiston SBOMissa. Vaikuttaako se meihin?", "Ilman järjestelmää vastaus voi vaatia SBOMin, skannerin, CI-lokien, artefaktien, sisäisten tikettien, hyväksyntöjen, julkaisutietojen ja aiempien asiakasvastausten läpikäyntiä."] }, + { title: "Selkeämpi vastaus", bullets: ["kyllä, vaikuttaa ja on korjattu", "kyllä, vaikuttaa ja on hyväksytty poikkeuksella", "ei, mukana mutta ei hyödynnettävissä tässä tuotekontekstissa", "tuntematon, dokumentoiduilla aukoilla ja seuraavilla toimilla"] }, + { title: "Ennen ja jälkeen", table: [{ left: "Uskomme, ettei tämä ole hyödynnettävissä. Tarkistamme asian kehitystiimiltä.", right: "Tälle julkaisulle löydös arvioitiin, merkittiin not affected -tilaan, linkitettiin tukevaan evidenceen ja sisällytettiin asiakaspakettiin." }] } + ] + }, + releasePackage: { + ...en.releasePackage, + title: "Julkaisun evidence-paketit", + navTitle: "Paketit", + metaTitle: "Julkaisun evidence-paketit - Evydence", + description: "Yksi julkaisu, yksi järjestetty evidence-paketti.", + eyebrow: "Käyttötapaus", + heroTitle: "Yksi julkaisu. Yksi järjestetty evidence-paketti.", + heroBody: [ + "Evidence-paketti on rakenteinen todistusaineisto ohjelmistojulkaisulle.", + "Se voi sisältää mitä toimitettiin, mitä komponentteja oli mukana, mitä tunnettuja haavoittuvuuksia löytyi, miten ne käsiteltiin, kuka hyväksyi päätöksen ja mitä asiakas voi todentaa." + ], + primaryCta: "Kysy Commercial Self-Hosted -ehdoista", + secondaryCta: "Avaa GitHub", + sections: [ + { title: "Suositeltu sisältö", bullets: ["tuotteen ja julkaisun identiteetti", "toimitettujen artefaktien viitteet", "artefaktien tiivisteet tai digestit", "SBOM/komponentti-inventaario", "haavoittuvuusskannauksen yhteenveto", "haavoittuvuuspäätökset", "poikkeus- tai waiver-tietueet", "koonti- ja lähdekoodiprovenanssi", "hyväksyntäpolku", "pakettimanifesti", "rajoitukset ja oletukset", "asiakkaalle turvalliset redaktiot"] }, + { title: "Tärkeä raja", body: ["Paketti ei tarkoita, että julkaisu olisi täydellisen turvallinen.", "Se tarkoittaa, että tiimi voi näyttää, mitä tarkistettiin, mitä päätettiin, mitä on yhä tuntematonta ja mikä evidence tukee vastausta."] } + ] + }, + commercial: { + ...en.commercial, + title: "Kaupallinen", + navTitle: "Kaupallinen", + metaTitle: "Commercial Self-Hosted -lisensointi - Evydence", + description: "Kaupallinen itse ylläpidettävä lisensointi, async-tuki, käyttöönottokatselmus ja integraatiotuki.", + eyebrow: "Commercial Self-Hosted", + heroTitle: "Commercial Self-Hosted -lisensointi.", + heroBody: [ + "Käytä Evydenceä AGPL-lisenssillä, kun se sopii organisaatiollesi.", + "Osta Commercial Self-Hosted, kun tarvitset yksityiset kaupalliset ehdot, AGPL-poikkeuksen, async-tuen, allekirjoitetun julkaisu/evidence-toimituksen tai käyttöönottokatselmuksen." + ], + primaryCta: "Aloita async-kaupallinen kysely", + secondaryCta: "Avaa GitHub", + sections: [ + { title: "Community AGPL vs Commercial Self-Hosted", table: [{ left: "Julkinen AGPL-lisenssi", right: "Erillinen kirjallinen kaupallinen sopimus" }, { left: "Julkiset GitHub-issuet", right: "Yksityinen async-tuki" }, { left: "Best-effort-yhteisöapu", right: "Sovittu tuki- ja päivityspolku" }, { left: "Oma arviointi", right: "Valinnainen deployment readiness -katselmus" }, { left: "AGPL-velvoitteet pätevät", right: "Lisälupa sovittuihin käyttötapauksiin" }] }, + { title: "Maksulliset vaihtoehdot", cards: [{ title: "Commercial Self-Hosted License", body: "Yksityiset kaupalliset ehdot, hankintaystävällinen lisensointi ja sovittu tukipolku." }, { title: "Async Support", body: "Yksityinen kirjallinen tuki vianrajoitukseen, päivityssuunnitteluun, käyttöönottokysymyksiin ja julkaisuevidence-työnkulkuihin." }, { title: "Deployment Readiness Review", body: "Kirjallinen katselmus konfiguraatiosta, varmistuksista, evidencen käsittelystä, arkkitehtuurista ja tunnetuista rajoituksista." }, { title: "Release Evidence Package Review", body: "Kirjallinen katselmus yhdestä evidence-paketista, mukaan lukien aukot, oletukset, rajoitukset ja asiakkaalle turvallinen jakaminen." }, { title: "Custom Integration", body: "Collector-adapterit, evidence-työnkulut, raporttipohjat, CI/CD-integraatio tai deployment-kovennus." }] }, + { title: "Kaupallinen raja", body: ["Kaupalliset ehdot eivät tee Evydencestä juridista vaatimustenmukaisuustakuuta, tietoturvasertifiointia, haavoittuvuusskanneria tai hallittua SaaS-palvelua."] } + ] + }, + status: { + ...en.status, + title: "Tila", + navTitle: "Tila", + metaTitle: "Nykyinen tila ja rajoitukset - Evydence", + description: "Nykyinen tila ja tuettu itse ylläpidettävä käyttöprofiili.", + eyebrow: "Tila ja rajoitukset", + heroTitle: "Nykyinen tila ja tuettu käyttöprofiili.", + heroBody: [ + "Evydence on tarkoitettu arviointiin, pilotteihin ja hallittuun sisäiseen itse ylläpidettävään tuotantokäyttöön operaattorin katselmuksen jälkeen.", + "Sitä ei markkinoida hostattuna SaaS-tuotteena tai laajana reguloidun tuotannon alustana." + ], + primaryCta: "Kysy käyttöönottosopivuudesta", + secondaryCta: "Avaa GitHub", + sections: [ + { title: "Käyttöprofiilin sopivuus", table: [{ left: "Paikallinen tekninen arviointi", right: "Hyvä sopivuus" }, { left: "Pilotti yhdellä tuotteella/julkaisulla", right: "Hyvä sopivuus" }, { left: "Hallittu sisäinen itse ylläpidettävä käyttö", right: "Kandidaatti katselmuksen jälkeen" }, { left: "Reguloitu tuotanto", right: "Vaatii lisäkatselmuksen" }, { left: "Air-gapped-tuotanto", right: "Vaatii siirtokontrollit" }, { left: "Evydencen hostattu SaaS", right: "Ei tällä hetkellä tarjolla" }] }, + { title: "Miksi tämä sivu on olemassa", body: ["Tämä sivu suodattaa huonosti sopivat käyttötapaukset ja lisää luottamusta sopivien arvioijien kanssa kertomalla rajoitukset suoraan."] } + ] + }, + glossary: { + ...en.glossary, + title: "Sanasto", + navTitle: "Sanasto", + metaTitle: "Selkokielinen sanasto - Evydence", + description: "Selkokieliset termit julkaisuevidencestä, SBOMeista, CVE-tunnuksista, VEXistä ja asiakaspaketeista.", + eyebrow: "Resurssit", + heroTitle: "Selkokielinen sanasto.", + heroBody: ["Lyhyet selitykset ihmisille, jotka arvioivat julkaisuevidence-työnkulkuja ilman kaikkia toteutusyksityiskohtia."], + primaryCta: "Kysy Commercial Self-Hosted -ehdoista", + secondaryCta: "Avaa GitHub", + sections: [ + { title: "Termit", cards: [{ title: "Evidence", body: "Julkaisun ympärillä oleva todistusaineisto: skannaustulokset, komponenttilistat, koontitietueet, haavoittuvuuspäätökset, hyväksynnät, artefaktitiivisteet, julkaisuraportit ja asiakkaalle turvalliset tiedostot." }, { title: "Evidence-paketti", body: "Järjestetty julkaisun todistusaineistopaketti, jota voidaan katselmoida sisäisesti tai jakaa asiakkaalle." }, { title: "SBOM", body: "Ohjelmiston ainesosalista. Se kuvaa ohjelmistossa käytetyt komponentit." }, { title: "CVE", body: "Julkinen tunniste tunnetulle ohjelmistovirheelle." }, { title: "VEX", body: "Rakenteinen tapa selittää, vaikuttaako tunnettu haavoittuvuus tiettyyn tuotteeseen tai julkaisuun." }, { title: "Asiakkaalle turvallinen paketti", body: "Paketti, joka sisältää hyödyllisen katselmusevidencen paljastamatta tarpeettomia sisäisiä yksityiskohtia." }, { title: "Julkaisuvalmius", body: "Rakenteinen näkymä siihen, onko julkaisulla odotettu evidence, päätökset, hyväksynnät ja tunnetut rajoitukset ennen jakamista tai toimitusta." }] } + ] + }, + cra: { + ...en.cra, + title: "CRA-valmiuden evidence", + navTitle: "CRA-valmius", + metaTitle: "Teknisen evidencen järjestäminen CRA-valmiutta varten - Evydence", + description: "Teknisen evidencen järjestäminen CRA-valmiustyöhön ilman juridisia vaatimustenmukaisuusväitteitä.", + eyebrow: "Resurssit", + heroTitle: "Teknisen evidencen järjestäminen CRA-valmiutta varten.", + heroBody: [ + "EU:n Cyber Resilience Act lisää huomiota haavoittuvuuksien käsittelyyn, tekniseen dokumentaatioon ja tuoteturvallisuusprosesseihin.", + "Evydence ei tarjoa juridista vaatimustenmukaisuutta tai sertifiointia, mutta se voi auttaa järjestämään teknistä julkaisuevidenceä, jota tuoteturvallisuus- ja compliance readiness -tiimit voivat tarvita katselmuksissa." + ], + primaryCta: "Kysy release evidence -katselmuksesta", + secondaryCta: "Avaa GitHub", + sections: [ + { title: "Varovainen sanamuoto", body: ["Evydence voi tukea CRA-valmiustyötä auttamalla tiimejä säilyttämään julkaisutason teknistä evidenceä, haavoittuvuuspäätöksiä, SBOM-tietueita, pakettimanifesteja ja tunnettuja rajoituksia."] }, + { title: "Vältettävät sanamuodot", bullets: ["Evydence tekee sinusta CRA-yhteensopivan.", "Evydence sertifioi julkaisusi.", "Evydence takaa viranomaisen hyväksynnän.", "Evydence todistaa, että ohjelmistosi on turvallinen."] } + ] + }, + contact: { + ...en.contact, + title: "Yhteys", + navTitle: "Yhteys", + metaTitle: "Async-kaupallinen kysely - Evydence", + description: "Aloita async-kysely Commercial Self-Hosted -käytöstä.", + eyebrow: "Async ensin", + heroTitle: "Async-kaupallinen kysely.", + heroBody: ["Evydencen kaupallinen tuki on async-first. Lähetä konteksti, käyttöoletukset, julkaisutyönkulun muistiinpanot tai lisensointikysymykset. Saat kirjallisen vastauksen."], + primaryCta: "Lähetä async-kysely", + secondaryCta: "Avaa GitHub", + sections: [ + { title: "Mitä mukaan", bullets: ["suunniteltu käyttötapa", "tavoiteltu käyttöönottomalli", "AGPL- tai kaupalliset huolenaiheet", "tukiodotukset", "tavoiteltu julkaisutyönkulku", "toivottu seuraava askel"] }, + { title: "Älä lähetä arkaluonteista evidenceä", body: ["Älä lähetä raw evidence -payloadia, bearer-tokeneita, yksityisiä avaimia, tietokanta-URL-osoitteita, asiakasdataa tai julkaisemattomia pakettisisältöjä julkisen yhteyspolun kautta.", "Lyhyttä rajauspuhelua voi pyytää sen jälkeen, kun async-konteksti on jaettu."] } + ] + }, + privacyCookies: { + ...en.privacyCookies, + title: "Yksityisyys ja evästeet", + navTitle: "Yksityisyys", + metaTitle: "Yksityisyys ja evästeet - Evydence", + description: "Miten markkinointisivusto käsittelee välttämättömiä asetuksia ja valinnaista mittausta.", + eyebrow: "Yksityisyys", + heroTitle: "Yksityisyys ja evästeet.", + heroBody: [ + "Markkinointisivusto käyttää vain välttämättömiä paikallisia valintoja, kunnes päätät hyväksyä valinnaisen sivustomittauksen.", + "Kun valinnainen mittaus on käytössä, se rajoittuu koottuihin markkinointisivuston tapahtumiin." + ], + primaryCta: "Hallitse evästevalintoja", + secondaryCta: "Avaa GitHub", + sections: [ + { title: "Mitä voidaan mitata hyväksynnän jälkeen", bullets: ["sivunäkymät", "ulospäin lähtevät GitHub-klikkaukset", "dokumentaatioklikkaukset", "yhteydenottoklikkaukset", "kielenvaihdot"] }, + { title: "Mitä ei mitata", body: ["Sivusto ei saa seurata lomakkeen raakatekstiä, sähköpostiosoitteita, asiakkaiden nimiä, yritysten nimiä, evidence-pakettien dataa, tokeneita, salaisuuksia sisältäviä kyselyparametreja tai tukisisältöä."] }, + { title: "Valinnan muuttaminen", body: ["Avaa suostumuspaneeli uudelleen alatunnisteen evästeasetusten linkistä ja muuta valinnaisen mittauksen valintaa."] } + ] + } +}; + +export const content: Record> = { en, fi }; + +export const ui = { + en: { + skip: "Skip to content", + language: "Language", + docs: "Docs", + github: "GitHub", + footerTagline: "Self-hosted release evidence for software vendors.", + footerBoundary: + "Evydence is not a legal compliance service, certification authority, vulnerability scanner, hosted SaaS, or guarantee of release security.", + cookiePreferences: "Cookie preferences", + outboundGitHub: "View GitHub", + contactHref: externalLinks.commercialEmail + }, + fi: { + skip: "Siirry sisältöön", + language: "Kieli", + docs: "Dokumentaatio", + github: "GitHub", + footerTagline: "Itse ylläpidettävä julkaisuevidence ohjelmistotoimittajille.", + footerBoundary: + "Evydence ei ole juridinen vaatimustenmukaisuuspalvelu, sertifiointitaho, haavoittuvuusskanneri, hostattu SaaS-palvelu tai takuu julkaisun turvallisuudesta.", + cookiePreferences: "Evästeasetukset", + outboundGitHub: "Avaa GitHub", + contactHref: externalLinks.commercialEmail + } +} satisfies Record>; + +export function routeFor(pageKey: PageKey, locale: Locale): string { + return routes[pageKey][locale]; +} + +export function pageFor(locale: Locale, pageKey: PageKey): PageContent { + return content[locale][pageKey]; +} + +export function routeToSlug(path: string): string | undefined { + const slug = path.replace(/^\/+|\/+$/g, ""); + return slug === "" ? undefined : slug; +} + +export function localizedAlternates(pageKey: PageKey): Array<{ locale: Locale; href: string }> { + return (Object.keys(localeNames) as Locale[]).map((locale) => ({ + locale, + href: routeFor(pageKey, locale) + })); +} + +export function staticPages(): Array<{ locale: Locale; pageKey: PageKey; slug: string | undefined }> { + return (Object.keys(localeNames) as Locale[]).flatMap((locale) => + orderedPageKeys.map((pageKey) => ({ + locale, + pageKey, + slug: routeToSlug(routeFor(pageKey, locale)) + })) + ); +} diff --git a/site/marketing/src/layouts/BaseLayout.astro b/site/marketing/src/layouts/BaseLayout.astro new file mode 100644 index 0000000..15bb50e --- /dev/null +++ b/site/marketing/src/layouts/BaseLayout.astro @@ -0,0 +1,609 @@ +--- +import ConsentBanner from "@components/ConsentBanner.astro"; +import { + content, + externalLinks, + localizedAlternates, + localeNames, + navItems, + pageFor, + routeFor, + type Locale, + type PageKey +} from "@data/site"; + +const { locale, pageKey } = Astro.props as { locale: Locale; pageKey: PageKey }; +const page = pageFor(locale, pageKey); +const copy = content[locale]; +const basePath = import.meta.env.BASE_URL.replace(/\/$/, ""); +const withBase = (path: string) => `${basePath}${path}`.replace(/\/{2,}/g, "/"); +const canonical = new URL(withBase(routeFor(pageKey, locale)), Astro.site).toString(); +const alternates = localizedAlternates(pageKey).map(({ locale: altLocale, href }) => ({ + locale: altLocale, + href: new URL(withBase(href), Astro.site).toString() +})); +const otherLocale: Locale = locale === "en" ? "fi" : "en"; +const ui = { + en: { + skip: "Skip to content", + language: "Language", + docs: "Docs", + github: "GitHub", + menu: "Menu", + footerTagline: "Self-hosted release evidence for software vendors.", + footerBoundary: + "Evydence is not a legal compliance service, certification authority, vulnerability scanner, hosted SaaS, or guarantee of release security.", + cookiePreferences: "Cookie preferences" + }, + fi: { + skip: "Siirry sisältöön", + language: "Kieli", + docs: "Dokumentaatio", + github: "GitHub", + menu: "Valikko", + footerTagline: "Itse ylläpidettävä julkaisuevidence ohjelmistotoimittajille.", + footerBoundary: + "Evydence ei ole juridinen vaatimustenmukaisuuspalvelu, sertifiointitaho, haavoittuvuusskanneri, hostattu SaaS-palvelu tai takuu julkaisun turvallisuudesta.", + cookiePreferences: "Evästeasetukset" + } +}[locale]; +--- + + + + + + + {page.metaTitle} + + + {alternates.map((alternate) => ( + + ))} + + + + + + + + + + +
+ +
+ + + + + + + diff --git a/site/marketing/src/pages/[...slug].astro b/site/marketing/src/pages/[...slug].astro new file mode 100644 index 0000000..263a699 --- /dev/null +++ b/site/marketing/src/pages/[...slug].astro @@ -0,0 +1,15 @@ +--- +import { staticPages } from "@data/site"; +import MarketingPage from "@templates/MarketingPage.astro"; + +export function getStaticPaths() { + return staticPages().map(({ slug, locale, pageKey }) => ({ + params: { slug }, + props: { locale, pageKey } + })); +} + +const { locale, pageKey } = Astro.props; +--- + + diff --git a/site/marketing/src/pages/docs.astro b/site/marketing/src/pages/docs.astro new file mode 100644 index 0000000..0df05dc --- /dev/null +++ b/site/marketing/src/pages/docs.astro @@ -0,0 +1,16 @@ +--- +import { externalLinks } from "@data/site"; +--- + + + + + + + + Evydence docs + + +

Continue to Evydence docs on GitHub.

+ + diff --git a/site/marketing/src/pages/github.astro b/site/marketing/src/pages/github.astro new file mode 100644 index 0000000..fc274cf --- /dev/null +++ b/site/marketing/src/pages/github.astro @@ -0,0 +1,16 @@ +--- +import { externalLinks } from "@data/site"; +--- + + + + + + + + Evydence GitHub + + +

Continue to Evydence on GitHub.

+ + diff --git a/site/marketing/src/pages/index.astro b/site/marketing/src/pages/index.astro new file mode 100644 index 0000000..a11b36b --- /dev/null +++ b/site/marketing/src/pages/index.astro @@ -0,0 +1,66 @@ +--- +import { routeFor } from "@data/site"; + +const basePath = import.meta.env.BASE_URL.replace(/\/$/, ""); +const withBase = (path: string) => `${basePath}${path}`.replace(/\/{2,}/g, "/"); +const englishUrl = withBase(routeFor("home", "en")); +const finnishUrl = withBase(routeFor("home", "fi")); +--- + + + + + + + + + Evydence + + + +
+

Evydence

+

English is the default language. Continue to the English site, or switch to Finnish.

+ Continue in English + Suomeksi +
+ + diff --git a/site/marketing/src/templates/MarketingPage.astro b/site/marketing/src/templates/MarketingPage.astro new file mode 100644 index 0000000..89f786d --- /dev/null +++ b/site/marketing/src/templates/MarketingPage.astro @@ -0,0 +1,84 @@ +--- +import DossierVisual from "@components/DossierVisual.astro"; +import BaseLayout from "@layouts/BaseLayout.astro"; +import { externalLinks, pageFor, routeFor, type Locale, type PageKey } from "@data/site"; + +const { locale, pageKey } = Astro.props as { locale: Locale; pageKey: PageKey }; +const page = pageFor(locale, pageKey); +const basePath = import.meta.env.BASE_URL.replace(/\/$/, ""); +const withBase = (path: string) => `${basePath}${path}`.replace(/\/{2,}/g, "/"); +const primaryHref = pageKey === "privacyCookies" ? "#" : externalLinks.commercialEmail; +const primaryAttrs = pageKey === "privacyCookies" ? { "data-cookie-preferences": "" } : { "data-track": "contact_click" }; +--- + + +
+
+ {page.eyebrow &&

{page.eyebrow}

} +

{page.heroTitle}

+ {page.heroBody.map((paragraph) =>

{paragraph}

)} + +
+ +
+ + {page.sections.map((section) => ( +
+
+ {section.eyebrow &&

{section.eyebrow}

} +

{section.title}

+
+
+ {section.body?.map((paragraph) =>

{paragraph}

)} + {section.bullets && ( +
    + {section.bullets.map((bullet) =>
  • {bullet}
  • )} +
+ )} + {section.cards && ( +
+ {section.cards.map((card) => ( +
+

{card.title}

+

{card.body}

+
+ ))} +
+ )} + {section.table && ( +
+ {section.table.map((row) => ( +
+ {row.left} + {row.right} +
+ ))} +
+ )} +
+
+ ))} + +
+

{locale === "en" ? "Next step" : "Seuraava askel"}

+

{locale === "en" ? "Evaluate the technical truth on GitHub." : "Arvioi tekninen totuus GitHubissa."}

+
+

+ {locale === "en" + ? "The website qualifies the business problem. The repository remains the source of truth for code, docs, release artifacts, limitations, and verification evidence." + : "Verkkosivusto rajaa liiketoimintaongelman. Repositorio pysyy lähteenä koodille, dokumentaatiolle, julkaisuartefakteille, rajoituksille ja todennusevidencelle."} +

+ +
+
+
diff --git a/site/marketing/tsconfig.json b/site/marketing/tsconfig.json new file mode 100644 index 0000000..3715669 --- /dev/null +++ b/site/marketing/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "astro/tsconfigs/strict", + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@components/*": ["src/components/*"], + "@data/*": ["src/data/*"], + "@layouts/*": ["src/layouts/*"], + "@templates/*": ["src/templates/*"] + } + } +} From 31145d34f8943425a84237370817450a4d05f435 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 15:22:21 +0300 Subject: [PATCH 250/287] feat(site): configure marketing site deployment --- .github/workflows/marketing-site-pages.yml | 70 ++ Makefile | 18 +- README.md | 2 + docs/README.md | 1 + docs/how-to/publish-marketing-site.md | 108 +++ site/marketing/public/CNAME | 1 + site/marketing/scripts/check.mjs | 23 +- site/marketing/src/data/site.ts | 754 +++++++++++++----- site/marketing/src/layouts/BaseLayout.astro | 4 +- .../src/templates/MarketingPage.astro | 2 +- 10 files changed, 765 insertions(+), 218 deletions(-) create mode 100644 .github/workflows/marketing-site-pages.yml create mode 100644 docs/how-to/publish-marketing-site.md create mode 100644 site/marketing/public/CNAME diff --git a/.github/workflows/marketing-site-pages.yml b/.github/workflows/marketing-site-pages.yml new file mode 100644 index 0000000..224264d --- /dev/null +++ b/.github/workflows/marketing-site-pages.yml @@ -0,0 +1,70 @@ +name: Marketing Site Pages + +on: + push: + branches: + - master + - main + paths: + - ".github/workflows/marketing-site-pages.yml" + - "site/marketing/**" + - "Makefile" + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: marketing-site-pages + cancel-in-progress: true + +jobs: + build: + name: Build Marketing Site + runs-on: ubuntu-latest + permissions: + contents: read + env: + PUBLIC_SITE_URL: https://evydence.app + PUBLIC_SITE_BASE: / + PUBLIC_GA_MEASUREMENT_ID: G-XC2ESEHQ3W + steps: + - name: Check out repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Set up Node.js + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 + with: + node-version: "22" + cache: npm + cache-dependency-path: site/marketing/package-lock.json + + - name: Install marketing-site dependencies + run: npm ci --prefix site/marketing + + - name: Build and validate marketing site + run: make marketing-site-production-check + + - name: Configure GitHub Pages + uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5 + + - name: Upload GitHub Pages artifact + uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3 + with: + path: site/marketing/dist + + deploy: + name: Deploy Marketing Site + runs-on: ubuntu-latest + needs: build + permissions: + contents: read + id-token: write + pages: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4 diff --git a/Makefile b/Makefile index a29423f..0277b6e 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ GOVULNCHECK_VERSION ?= v1.2.0 TAG ?= -.PHONY: help tools fmt lint vuln gosec test test-race fuzz-smoke coverage coverage-check openapi-check openapi-precision-check meta-check docs-check deploy-check sdk-check demo-check local-ci-simulation-check reviewer-package-workflow-check black-box-demo-check benchmark-check package-viewer-check marketing-site-check restore-rehearsal-check fast-check finalize release-acceptance release-check production-check release-candidate-check public-release-verify migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean +.PHONY: help tools fmt lint vuln gosec test test-race fuzz-smoke coverage coverage-check openapi-check openapi-precision-check meta-check docs-check deploy-check sdk-check demo-check local-ci-simulation-check reviewer-package-workflow-check black-box-demo-check benchmark-check package-viewer-check marketing-site-check marketing-site-production-check restore-rehearsal-check fast-check finalize release-acceptance release-check production-check release-candidate-check public-release-verify migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean help: ## Show help @awk 'BEGIN {FS=":.*## "}; /^[a-zA-Z0-9_.-]+:.*## / { printf " %-18s %s\n", $$1, $$2 }' $(MAKEFILE_LIST) @@ -75,6 +75,7 @@ meta-check: ## Validate root legal, governance, support, and release-evidence me @test -f .github/workflows/scorecard.yml @test -f .github/workflows/container-image.yml @test -f .github/workflows/codeql.yml + @test -f .github/workflows/marketing-site-pages.yml @test -f .github/ISSUE_TEMPLATE.md @test -f .github/ISSUE_TEMPLATE/bug_report.yml @test -f .github/ISSUE_TEMPLATE/feature_request.yml @@ -111,6 +112,14 @@ meta-check: ## Validate root legal, governance, support, and release-evidence me @grep -F 'cosign verify' .github/workflows/container-image.yml >/dev/null @grep -F -- '--provenance=true' .github/workflows/container-image.yml >/dev/null @grep -F -- '--sbom=true' .github/workflows/container-image.yml >/dev/null + @grep -F 'https://evydence.app' .github/workflows/marketing-site-pages.yml >/dev/null + @grep -F 'G-XC2ESEHQ3W' Makefile >/dev/null + @grep -F 'actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e' .github/workflows/marketing-site-pages.yml >/dev/null + @grep -F 'actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa' .github/workflows/marketing-site-pages.yml >/dev/null + @grep -F 'actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b' .github/workflows/marketing-site-pages.yml >/dev/null + @grep -F 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' .github/workflows/marketing-site-pages.yml >/dev/null + @test -f site/marketing/public/CNAME + @grep -Fx 'evydence.app' site/marketing/public/CNAME >/dev/null @grep -F 'Evydence fork' TRADEMARKS.md >/dev/null @grep -F 'Release evidence is not a certification' RELEASE_EVIDENCE.md >/dev/null @grep -F '.refs' .dockerignore >/dev/null @@ -133,6 +142,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @test -f docs/how-to/integrate-ci.md @test -f docs/how-to/install-and-operate.md @test -f docs/how-to/view-packages.md + @test -f docs/how-to/publish-marketing-site.md @test -f docs/reference/configuration.md @test -f docs/reference/capability-map.md @test -f docs/reference/api-contract-matrix.md @@ -318,6 +328,9 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'Use one API writer replica' docs/reference/release-candidate.md >/dev/null @grep -F 'private security intake' SECURITY.md >/dev/null @! grep -R -i "automatically compliant\|certified secure\|legally sufficient\|SBOM is complete\|all vulnerabilities detected\|scanner findings are authoritative\|regulator-ready without review" README.md docs + @grep -F 'make marketing-site-production-check' docs/how-to/publish-marketing-site.md >/dev/null + @grep -F 'G-XC2ESEHQ3W' docs/how-to/publish-marketing-site.md >/dev/null + @grep -F 'evydence.app' docs/how-to/publish-marketing-site.md >/dev/null deploy-check: ## Validate deployment and air-gap skeletons exist @test -f compose.production-like.yml @@ -420,6 +433,9 @@ package-viewer-check: ## Validate local package viewer and walkthrough marketing-site-check: ## Build and validate the static marketing site @npm --prefix site/marketing run check +marketing-site-production-check: ## Build and validate the marketing site for evydence.app + @PUBLIC_SITE_URL=https://evydence.app PUBLIC_SITE_BASE=/ PUBLIC_GA_MEASUREMENT_ID=G-XC2ESEHQ3W npm --prefix site/marketing run check + restore-rehearsal-check: ## Run repository-owned backup/restore rehearsal tests @$(GO) test ./internal/app -run TestBackupRestoreRehearsalPreservesLedgerAndObjectPayloads -count=1 @$(GO) test ./internal/adapters/postgres -run TestPostgresBackupRestoreRehearsalPreservesLedgerAndObjects -count=1 diff --git a/README.md b/README.md index 5503eef..f25b56a 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ security, AppSec, platform, release engineering, and compliance-readiness teams that need to answer customer CVE, SBOM, provenance, and release-review questions with signed, customer-safe release evidence bundles. +Website: + The concrete buyer question is: "This CVE appears in your SBOM for this release. Are you affected, why or why not, who approved that decision, and what evidence can we verify?" Evydence records the SBOM, vulnerability scan, VEX or diff --git a/docs/README.md b/docs/README.md index 6c8d10f..dffa2f5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -20,6 +20,7 @@ This documentation is organized by reader task. Implementation claims should be - [Review a customer package](how-to/review-customer-package.md): verify, inspect, and escalate a scoped package with checked fixtures. - [Production hardening review](production-hardening.md): review production configuration, backups, ingress, diagnostics, and customer package controls. - [Pilot deployment checklist](how-to/pilot-deployment-checklist.md): copy-paste checklist for the narrow design-partner pilot profile. +- [Publish the marketing site](how-to/publish-marketing-site.md): deploy the Astro site to GitHub Pages at `evydence.app` with consent-gated Google Analytics. - [Backup and restore runbook](runbooks/backup-restore.md): rehearse paired database/object-store restore and verification. - [Upgrade runbook](runbooks/upgrade.md): verify release artifacts, migrations, and post-upgrade checks. - [Incident response runbook](runbooks/incident-response.md): handle operator incidents without leaking secrets or raw evidence. diff --git a/docs/how-to/publish-marketing-site.md b/docs/how-to/publish-marketing-site.md new file mode 100644 index 0000000..42ac3b7 --- /dev/null +++ b/docs/how-to/publish-marketing-site.md @@ -0,0 +1,108 @@ +# Publish The Marketing Site + +Use this guide to publish the static Astro marketing site to GitHub Pages at +`https://evydence.app`. + +The website is product positioning and project navigation. It is not release +evidence, legal compliance proof, certification, vulnerability coverage, or a +security guarantee. + +## Source + +The marketing site lives in `site/marketing`. + +Local development defaults to the project Pages path: + +```bash +npm --prefix site/marketing run dev -- --host 127.0.0.1 --port 4321 +``` + +Open `http://127.0.0.1:4321/evydence/en/`. + +## Production Build + +The production GitHub Pages workflow builds with these public client-side +values: + +```text +PUBLIC_SITE_URL=https://evydence.app +PUBLIC_SITE_BASE=/ +PUBLIC_GA_MEASUREMENT_ID=G-XC2ESEHQ3W +``` + +`PUBLIC_GA_MEASUREMENT_ID` is not a server secret. It appears in browser-side +JavaScript only after the visitor chooses `Accept all` in the consent banner. +The site must keep Google tags blocked until that choice is stored. + +Run the same production build check locally with: + +```bash +make marketing-site-production-check +``` + +## GitHub Pages + +The Pages workflow is `.github/workflows/marketing-site-pages.yml`. + +Before relying on the domain, configure repository Pages settings: + +1. Set the Pages source to GitHub Actions. +2. Set the custom domain to `evydence.app`. +3. Wait for GitHub to provision HTTPS. +4. Enable `Enforce HTTPS`. + +The checked `site/marketing/public/CNAME` file is copied into the static site +artifact and contains: + +```text +evydence.app +``` + +## DNS + +Configure the apex records at the domain provider: + +```text +evydence.app A 185.199.108.153 +evydence.app A 185.199.109.153 +evydence.app A 185.199.110.153 +evydence.app A 185.199.111.153 +``` + +Optional IPv6 records: + +```text +evydence.app AAAA 2606:50c0:8000::153 +evydence.app AAAA 2606:50c0:8001::153 +evydence.app AAAA 2606:50c0:8002::153 +evydence.app AAAA 2606:50c0:8003::153 +``` + +For `www`: + +```text +www.evydence.app CNAME aatuh.github.io +``` + +Verify DNS with: + +```bash +dig +short evydence.app A +dig +short evydence.app AAAA +dig +short www.evydence.app CNAME +``` + +## Validation + +Run: + +```bash +npm --prefix site/marketing audit --audit-level=moderate +make marketing-site-production-check +make docs-check +``` + +Do not publish a site change that loads Google Analytics before consent, +removes the `/en/` and `/fi/` routes, or introduces claims that Evydence +provides legal compliance, certification, complete SBOMs, authoritative scanner +results, or secure releases. diff --git a/site/marketing/public/CNAME b/site/marketing/public/CNAME new file mode 100644 index 0000000..1cda005 --- /dev/null +++ b/site/marketing/public/CNAME @@ -0,0 +1 @@ +evydence.app diff --git a/site/marketing/scripts/check.mjs b/site/marketing/scripts/check.mjs index 5607686..0cb65ca 100644 --- a/site/marketing/scripts/check.mjs +++ b/site/marketing/scripts/check.mjs @@ -3,6 +3,10 @@ import { join } from "node:path"; const root = new URL("..", import.meta.url).pathname; const dist = join(root, "dist"); +const configuredBase = process.env.PUBLIC_SITE_BASE ?? "/evydence"; +const normalizedBase = + configuredBase === "/" ? "" : `/${configuredBase.replace(/^\/+|\/+$/g, "")}`; +const withBase = (path) => `${normalizedBase}${path}`.replace(/\/{2,}/g, "/"); const requiredFiles = [ "index.html", @@ -41,14 +45,15 @@ const rootPage = readFileSync(join(dist, "index.html"), "utf8"); const english = readFileSync(join(dist, "en/index.html"), "utf8"); const finnish = readFileSync(join(dist, "fi/index.html"), "utf8"); const privacy = readFileSync(join(dist, "en/privacy-cookies/index.html"), "utf8"); +const cname = readFileSync(join(dist, "CNAME"), "utf8").trim(); const consentSource = readFileSync(join(root, "src/components/ConsentBanner.astro"), "utf8"); const layoutSource = readFileSync(join(root, "src/layouts/BaseLayout.astro"), "utf8"); const requiredRoot = [ 'lang="en"', - "url=/evydence/en/", + `url=${withBase("/en/")}`, "Continue in English", - "/evydence/fi/" + withBase("/fi/") ]; for (const text of requiredRoot) { @@ -57,10 +62,15 @@ for (const text of requiredRoot) { } } +if (cname !== "evydence.app") { + throw new Error(`marketing site CNAME must be evydence.app, got: ${cname}`); +} + const requiredEnglish = [ 'lang="en"', 'hreflang="fi"', "Stop scrambling when customers ask for release security evidence.", + "https://www.linkedin.com/in/aatu-harju", "Cookie preferences", "Evydence is not a legal compliance service" ]; @@ -115,7 +125,14 @@ for (const text of layoutChecks) { } } -for (const forbidden of ["innerHTML", "Start free trial", "100% secure", "automatically compliant"]) { +for (const forbidden of [ + "innerHTML", + "Start free trial", + "100% secure", + "automatically compliant", + "mailto:", + "aatu@example.com" +]) { if (english.includes(forbidden) || finnish.includes(forbidden) || privacy.includes(forbidden)) { throw new Error(`forbidden site text found: ${forbidden}`); } diff --git a/site/marketing/src/data/site.ts b/site/marketing/src/data/site.ts index b16d9ef..e1f9f7c 100644 --- a/site/marketing/src/data/site.ts +++ b/site/marketing/src/data/site.ts @@ -37,7 +37,7 @@ export type PageContent = { export const localeNames: Record = { en: "English", - fi: "Suomi" + fi: "Suomi", }; export const routes: Record> = { @@ -45,24 +45,24 @@ export const routes: Record> = { product: { en: "/en/product/", fi: "/fi/tuote/" }, customerReview: { en: "/en/use-cases/customer-security-review/", - fi: "/fi/kayttotapaukset/asiakkaan-tietoturvakatselmus/" + fi: "/fi/kayttotapaukset/asiakkaan-tietoturvakatselmus/", }, releasePackage: { en: "/en/use-cases/release-evidence-package/", - fi: "/fi/kayttotapaukset/julkaisun-evidence-paketti/" + fi: "/fi/kayttotapaukset/julkaisun-evidence-paketti/", }, commercial: { en: "/en/commercial/", fi: "/fi/kaupallinen/" }, status: { en: "/en/status/", fi: "/fi/tila/" }, glossary: { en: "/en/resources/glossary/", fi: "/fi/resurssit/sanasto/" }, cra: { en: "/en/resources/cra-readiness-evidence/", - fi: "/fi/resurssit/cra-valmiuden-evidence/" + fi: "/fi/resurssit/cra-valmiuden-evidence/", }, contact: { en: "/en/contact/", fi: "/fi/yhteys/" }, privacyCookies: { en: "/en/privacy-cookies/", - fi: "/fi/yksityisyys-evasteet/" - } + fi: "/fi/yksityisyys-evasteet/", + }, }; export const orderedPageKeys: PageKey[] = [ @@ -75,7 +75,7 @@ export const orderedPageKeys: PageKey[] = [ "glossary", "cra", "contact", - "privacyCookies" + "privacyCookies", ]; export const navItems: PageKey[] = [ @@ -84,13 +84,13 @@ export const navItems: PageKey[] = [ "commercial", "status", "glossary", - "contact" + "contact", ]; export const externalLinks = { github: "https://github.com/aatuh/evydence", docs: "https://github.com/aatuh/evydence/tree/master/docs", - commercialEmail: "mailto:aatu@example.com?subject=Evydence%20Commercial%20Self-Hosted%20inquiry" + linkedin: "https://www.linkedin.com/in/aatu-harju", }; const en: Record = { @@ -102,10 +102,11 @@ const en: Record = { description: "Evydence helps software vendors answer customer release-security questions with organized, verifiable evidence.", eyebrow: "Self-hosted release evidence", - heroTitle: "Stop scrambling when customers ask for release security evidence.", + heroTitle: + "Stop scrambling when customers ask for release security evidence.", heroBody: [ "Evydence helps software vendors organize the proof behind a software release: what was shipped, what was inside it, which vulnerabilities were reviewed, what decisions were made, and what can safely be shared with customers.", - "Run it self-hosted, keep technical truth on GitHub, and use commercial terms when your organization needs them." + "Run it self-hosted, keep technical truth on GitHub, and use commercial terms when your organization needs them.", ], primaryCta: "Ask about Commercial Self-Hosted", secondaryCta: "View GitHub", @@ -115,8 +116,8 @@ const en: Record = { title: "Customer security reviews are becoming more detailed.", body: [ "A customer may ask what third-party components are inside a release, whether known vulnerabilities are present, whether a CVE affects your product, who reviewed the decision, and what proof can be verified.", - "For many teams, the answer is scattered across scanner exports, CI logs, tickets, chat, spreadsheets, object storage, and one-off PDFs." - ] + "For many teams, the answer is scattered across scanner exports, CI logs, tickets, chat, spreadsheets, object storage, and one-off PDFs.", + ], }, { eyebrow: "The outcome", @@ -129,27 +130,42 @@ const en: Record = { "build and artifact proof", "release-readiness reports", "signed bundles", - "customer-safe packages" - ] + "customer-safe packages", + ], }, { title: "Before and after Evydence", table: [ - { left: "Evidence scattered across tools", right: "Evidence linked to a release" }, - { left: "Manual customer answers", right: "Repeatable customer package" }, - { left: "Decisions hidden in tickets or chat", right: "Decision trail with actor context" }, - { left: "Hard to explain not affected", right: "Reviewable vulnerability decision" }, - { left: "One-off PDF work", right: "Package generated from structured records" } - ] + { + left: "Evidence scattered across tools", + right: "Evidence linked to a release", + }, + { + left: "Manual customer answers", + right: "Repeatable customer package", + }, + { + left: "Decisions hidden in tickets or chat", + right: "Decision trail with actor context", + }, + { + left: "Hard to explain not affected", + right: "Reviewable vulnerability decision", + }, + { + left: "One-off PDF work", + right: "Package generated from structured records", + }, + ], }, { title: "What it is not", body: [ "Evydence is not a scanner, firewall, legal compliance engine, certification service, or guarantee that a release is secure.", - "It helps organize technical evidence and release-security decisions so teams can answer review questions more clearly and repeatably." - ] - } - ] + "It helps organize technical evidence and release-security decisions so teams can answer review questions more clearly and repeatably.", + ], + }, + ], }, product: { key: "product", @@ -160,7 +176,7 @@ const en: Record = { eyebrow: "Product overview", heroTitle: "A self-hosted evidence system for software releases.", heroBody: [ - "Evydence keeps release evidence connected to the product, version, artifact, vulnerability, decision, approval, and customer package it belongs to." + "Evydence keeps release evidence connected to the product, version, artifact, vulnerability, decision, approval, and customer package it belongs to.", ], primaryCta: "Ask about Commercial Self-Hosted", secondaryCta: "View GitHub", @@ -168,46 +184,47 @@ const en: Record = { { title: "Capture release evidence", body: [ - "Collect proof material around a release: component inventories, vulnerability scans, build metadata, artifact digests, source records, deployment events, and supporting files." - ] + "Collect proof material around a release: component inventories, vulnerability scans, build metadata, artifact digests, source records, deployment events, and supporting files.", + ], }, { title: "Record vulnerability decisions", body: [ - "When a known vulnerability appears, record whether it affects the release, why, who reviewed it, and what evidence supports the decision." - ] + "When a known vulnerability appears, record whether it affects the release, why, who reviewed it, and what evidence supports the decision.", + ], }, { title: "Generate customer-safe packages", body: [ - "Create packages that include evidence a customer can review without exposing unnecessary internal detail." - ] + "Create packages that include evidence a customer can review without exposing unnecessary internal detail.", + ], }, { title: "Verify the package", body: [ - "Use manifests, hashes, signatures, and audit-chain records to make the package reviewable instead of just another static document." - ] + "Use manifests, hashes, signatures, and audit-chain records to make the package reviewable instead of just another static document.", + ], }, { title: "Self-hosted by design", body: [ - "Evydence is designed for teams that want to run the evidence system in their own environment, close to release, security, and CI/CD systems." - ] - } - ] + "Evydence is designed for teams that want to run the evidence system in their own environment, close to release, security, and CI/CD systems.", + ], + }, + ], }, customerReview: { key: "customerReview", title: "Customer security reviews", navTitle: "Use cases", metaTitle: "Customer security reviews - Evydence", - description: "Turn customer security review questions into a repeatable release evidence workflow.", + description: + "Turn customer security review questions into a repeatable release evidence workflow.", eyebrow: "Use case", heroTitle: "Customer security reviews should not require a scavenger hunt.", heroBody: [ "Enterprise customers increasingly ask software vendors to explain what is inside a release, which known vulnerabilities are present, which ones actually affect the product, and what proof supports the answer.", - "Evydence helps turn that review from a manual scramble into a repeatable release evidence workflow." + "Evydence helps turn that review from a manual scramble into a repeatable release evidence workflow.", ], primaryCta: "Ask about a release evidence pilot", secondaryCta: "View GitHub", @@ -216,8 +233,8 @@ const en: Record = { title: "The question that triggers the scramble", body: [ "A customer asks: This CVE appears in your software bill of materials. Are we affected?", - "Without a system, the answer may require checking the SBOM, vulnerability scanner, CI logs, build artifacts, internal tickets, approvals, release notes, and previous customer responses." - ] + "Without a system, the answer may require checking the SBOM, vulnerability scanner, CI logs, build artifacts, internal tickets, approvals, release notes, and previous customer responses.", + ], }, { title: "A clearer answer", @@ -225,19 +242,20 @@ const en: Record = { "yes, affected and fixed", "yes, affected and accepted with an exception", "no, present but not exploitable in this product context", - "unknown, with documented gaps and next steps" - ] + "unknown, with documented gaps and next steps", + ], }, { title: "Before and after", table: [ { left: "We think this is not exploitable. Let us check with engineering.", - right: "For this release, the finding was reviewed, marked not affected, linked to supporting evidence, and included in the customer-safe package." - } - ] - } - ] + right: + "For this release, the finding was reviewed, marked not affected, linked to supporting evidence, and included in the customer-safe package.", + }, + ], + }, + ], }, releasePackage: { key: "releasePackage", @@ -249,7 +267,7 @@ const en: Record = { heroTitle: "One release. One organized evidence package.", heroBody: [ "An evidence package is a structured set of proof material for a software release.", - "It can include what was shipped, what components were inside, which known vulnerabilities were found, how those findings were handled, who approved the decision, and what a customer can verify." + "It can include what was shipped, what components were inside, which known vulnerabilities were found, how those findings were handled, who approved the decision, and what a customer can verify.", ], primaryCta: "Ask about Commercial Self-Hosted", secondaryCta: "View GitHub", @@ -268,29 +286,30 @@ const en: Record = { "approval trail", "package manifest", "limitations and assumptions", - "customer-safe redactions" - ] + "customer-safe redactions", + ], }, { title: "Important boundary", body: [ "The package does not mean the release is perfectly secure.", - "It means the team can show what was checked, what was decided, what is still unknown, and what evidence supports the answer." - ] - } - ] + "It means the team can show what was checked, what was decided, what is still unknown, and what evidence supports the answer.", + ], + }, + ], }, commercial: { key: "commercial", title: "Commercial", navTitle: "Commercial", metaTitle: "Commercial Self-Hosted Licensing - Evydence", - description: "Commercial self-hosted licensing, async support, deployment review, and integration support.", + description: + "Commercial self-hosted licensing, async support, deployment review, and integration support.", eyebrow: "Commercial Self-Hosted", heroTitle: "Commercial Self-Hosted Licensing.", heroBody: [ "Use Evydence under AGPL when that fits your organization.", - "Buy Evydence Commercial Self-Hosted when you need private commercial terms, AGPL exception, async support, signed release/evidence delivery, or deployment review." + "Buy Evydence Commercial Self-Hosted when you need private commercial terms, AGPL exception, async support, signed release/evidence delivery, or deployment review.", ], primaryCta: "Start async commercial inquiry", secondaryCta: "View GitHub", @@ -298,30 +317,57 @@ const en: Record = { { title: "Community AGPL vs Commercial Self-Hosted", table: [ - { left: "Public AGPL license", right: "Separate written commercial agreement" }, + { + left: "Public AGPL license", + right: "Separate written commercial agreement", + }, { left: "Public GitHub issues", right: "Private async support" }, - { left: "Best-effort community help", right: "Agreed support and upgrade path" }, - { left: "Self-evaluation", right: "Optional deployment-readiness review" }, - { left: "AGPL obligations apply", right: "Extra permission for agreed use cases" } - ] + { + left: "Best-effort community help", + right: "Agreed support and upgrade path", + }, + { + left: "Self-evaluation", + right: "Optional deployment-readiness review", + }, + { + left: "AGPL obligations apply", + right: "Extra permission for agreed use cases", + }, + ], }, { title: "Paid options", cards: [ - { title: "Commercial Self-Hosted License", body: "Private commercial terms, procurement-friendly licensing, and an agreed support path." }, - { title: "Async Support", body: "Private written support for troubleshooting, upgrade planning, deployment questions, and release evidence workflows." }, - { title: "Deployment Readiness Review", body: "Written review of configuration, backup/restore, evidence handling, deployment architecture, and known limitations." }, - { title: "Release Evidence Package Review", body: "Written review of one evidence package, including gaps, assumptions, limitations, and customer-safe sharing concerns." }, - { title: "Custom Integration", body: "Collector adapters, evidence workflows, report templates, CI/CD integration, or deployment hardening." } - ] + { + title: "Commercial Self-Hosted License", + body: "Private commercial terms, procurement-friendly licensing, and an agreed support path.", + }, + { + title: "Async Support", + body: "Private written support for troubleshooting, upgrade planning, deployment questions, and release evidence workflows.", + }, + { + title: "Deployment Readiness Review", + body: "Written review of configuration, backup/restore, evidence handling, deployment architecture, and known limitations.", + }, + { + title: "Release Evidence Package Review", + body: "Written review of one evidence package, including gaps, assumptions, limitations, and customer-safe sharing concerns.", + }, + { + title: "Custom Integration", + body: "Collector adapters, evidence workflows, report templates, CI/CD integration, or deployment hardening.", + }, + ], }, { title: "Commercial boundary", body: [ - "Commercial terms do not turn Evydence into a legal compliance guarantee, security certification, vulnerability scanner, or managed SaaS service." - ] - } - ] + "Commercial terms do not turn Evydence into a legal compliance guarantee, security certification, vulnerability scanner, or managed SaaS service.", + ], + }, + ], }, status: { key: "status", @@ -333,7 +379,7 @@ const en: Record = { heroTitle: "Current status and supported deployment profile.", heroBody: [ "Evydence is intended for evaluation, pilots, and controlled internal self-hosted production after operator review.", - "It is not marketed as a hosted SaaS product or a broad regulated-production platform." + "It is not marketed as a hosted SaaS product or a broad regulated-production platform.", ], primaryCta: "Ask about deployment fit", secondaryCta: "View GitHub", @@ -343,30 +389,31 @@ const en: Record = { table: [ { left: "Local technical evaluation", right: "Good fit" }, { left: "Pilot with one product/release", right: "Good fit" }, - { left: "Controlled internal self-hosted use", right: "Candidate after review" }, + { + left: "Controlled internal self-hosted use", + right: "Candidate after review", + }, { left: "Regulated production", right: "Requires extra review" }, - { left: "Air-gapped production", right: "Requires transfer controls" }, - { left: "Hosted SaaS by Evydence", right: "Not currently offered" } - ] + { + left: "Air-gapped production", + right: "Requires transfer controls", + }, + { left: "Hosted SaaS by Evydence", right: "Not currently offered" }, + ], }, - { - title: "Why this page exists", - body: [ - "This page filters out bad-fit use cases and increases trust with good-fit evaluators by stating limitations plainly." - ] - } - ] + ], }, glossary: { key: "glossary", title: "Glossary", navTitle: "Glossary", metaTitle: "Plain-English glossary - Evydence", - description: "Plain-English terms for release evidence, SBOMs, CVEs, VEX, and customer-safe packages.", + description: + "Plain-English terms for release evidence, SBOMs, CVEs, VEX, and customer-safe packages.", eyebrow: "Resources", heroTitle: "Plain-English glossary.", heroBody: [ - "Short explanations for people evaluating release evidence workflows without needing every implementation detail." + "Short explanations for people evaluating release evidence workflows without needing every implementation detail.", ], primaryCta: "Ask about Commercial Self-Hosted", secondaryCta: "View GitHub", @@ -374,28 +421,50 @@ const en: Record = { { title: "Terms", cards: [ - { title: "Evidence", body: "Proof material around a software release: scan results, component lists, build records, vulnerability decisions, approvals, artifact hashes, release reports, and customer-safe files." }, - { title: "Evidence package", body: "An organized bundle of release proof that can be reviewed internally or shared with a customer." }, - { title: "SBOM", body: "A software ingredients list. It describes the components used inside software." }, - { title: "CVE", body: "A public identifier for a known software flaw." }, - { title: "VEX", body: "A structured way to explain whether a known vulnerability actually affects a specific product or release." }, - { title: "Customer-safe package", body: "A package that contains useful review evidence without exposing unnecessary internal details." }, - { title: "Release readiness", body: "A structured view of whether the release has expected evidence, decisions, approvals, and known limitations before it is shared or shipped." } - ] - } - ] + { + title: "Evidence", + body: "Proof material around a software release: scan results, component lists, build records, vulnerability decisions, approvals, artifact hashes, release reports, and customer-safe files.", + }, + { + title: "Evidence package", + body: "An organized bundle of release proof that can be reviewed internally or shared with a customer.", + }, + { + title: "SBOM", + body: "A software ingredients list. It describes the components used inside software.", + }, + { + title: "CVE", + body: "A public identifier for a known software flaw.", + }, + { + title: "VEX", + body: "A structured way to explain whether a known vulnerability actually affects a specific product or release.", + }, + { + title: "Customer-safe package", + body: "A package that contains useful review evidence without exposing unnecessary internal details.", + }, + { + title: "Release readiness", + body: "A structured view of whether the release has expected evidence, decisions, approvals, and known limitations before it is shared or shipped.", + }, + ], + }, + ], }, cra: { key: "cra", title: "CRA-readiness evidence", navTitle: "CRA readiness", metaTitle: "Technical evidence organization for CRA readiness - Evydence", - description: "Technical evidence organization for CRA-readiness work without legal compliance claims.", + description: + "Technical evidence organization for CRA-readiness work without legal compliance claims.", eyebrow: "Resources", heroTitle: "Technical evidence organization for CRA readiness.", heroBody: [ "The EU Cyber Resilience Act is increasing attention on vulnerability handling, technical documentation, and product-security processes.", - "Evydence does not provide legal compliance or certification, but it can help organize technical release evidence that product-security and compliance-readiness teams may need to review." + "Evydence does not provide legal compliance or certification, but it can help organize technical release evidence that product-security and compliance-readiness teams may need to review.", ], primaryCta: "Ask about a release evidence review", secondaryCta: "View GitHub", @@ -403,8 +472,8 @@ const en: Record = { { title: "Careful wording", body: [ - "Evydence can support CRA-readiness work by helping teams preserve release-level technical evidence, vulnerability decisions, SBOM records, package manifests, and known limitations." - ] + "Evydence can support CRA-readiness work by helping teams preserve release-level technical evidence, vulnerability decisions, SBOM records, package manifests, and known limitations.", + ], }, { title: "Wording to avoid", @@ -412,23 +481,24 @@ const en: Record = { "Evydence makes you CRA compliant.", "Evydence certifies your releases.", "Evydence guarantees regulatory acceptance.", - "Evydence proves your software is secure." - ] - } - ] + "Evydence proves your software is secure.", + ], + }, + ], }, contact: { key: "contact", title: "Contact", navTitle: "Contact", - metaTitle: "Async commercial inquiry - Evydence", - description: "Start an async commercial self-hosted inquiry.", - eyebrow: "Async-first contact", - heroTitle: "Async commercial inquiry.", + metaTitle: "Contact - Evydence", + description: + "Start a commercial self-hosted conversation through LinkedIn.", + eyebrow: "LinkedIn contact", + heroTitle: "Start a commercial conversation.", heroBody: [ - "Evydence commercial support is async-first. Send context, deployment assumptions, release workflow notes, or commercial licensing questions. You will receive a written response." + "Use LinkedIn for an initial commercial self-hosted conversation, deployment assumptions, release workflow notes, or commercial licensing questions.", ], - primaryCta: "Send async inquiry", + primaryCta: "Open LinkedIn profile", secondaryCta: "View GitHub", sections: [ { @@ -439,29 +509,30 @@ const en: Record = { "AGPL or commercial concerns", "support expectations", "target release workflow", - "preferred next step" - ] + "preferred next step", + ], }, { title: "Do not send sensitive evidence", body: [ - "Do not send raw evidence payloads, bearer tokens, private keys, database URLs, customer data, or unreleased package contents through the public contact path.", - "A short scoping call can be requested after async context is shared." - ] - } - ] + "Do not send raw evidence payloads, bearer tokens, private keys, database URLs, customer data, or unreleased package contents through LinkedIn or any public contact path.", + "Use the first message only for brief, non-sensitive context. A safer private channel can be agreed separately if needed.", + ], + }, + ], }, privacyCookies: { key: "privacyCookies", title: "Privacy and cookies", navTitle: "Privacy", metaTitle: "Privacy and cookies - Evydence", - description: "How the marketing site handles necessary preferences and optional measurement.", + description: + "How the marketing site handles necessary preferences and optional measurement.", eyebrow: "Privacy", heroTitle: "Privacy and cookies.", heroBody: [ "The marketing site uses only necessary local preferences until you choose to accept optional site measurement.", - "Optional measurement, when enabled, is limited to aggregate marketing-site events." + "Optional measurement, when enabled, is limited to aggregate marketing-site events.", ], primaryCta: "Manage cookie choices", secondaryCta: "View GitHub", @@ -473,23 +544,23 @@ const en: Record = { "outbound GitHub clicks", "docs clicks", "contact clicks", - "language switches" - ] + "language switches", + ], }, { title: "What is not measured", body: [ - "The site must not track raw form text, email addresses, customer names, company names, evidence package data, tokens, query parameters containing secrets, or support content." - ] + "The site must not track raw form text, email addresses, customer names, company names, evidence package data, tokens, query parameters containing secrets, or support content.", + ], }, { title: "Changing your choice", body: [ - "Use the footer cookie preferences link to reopen the consent panel and change your optional measurement choice." - ] - } - ] - } + "Use the footer cookie preferences link to reopen the consent panel and change your optional measurement choice.", + ], + }, + ], + }, }; const fi: Record = { @@ -501,21 +572,23 @@ const fi: Record = { description: "Evydence auttaa ohjelmistotoimittajia vastaamaan asiakkaiden julkaisun tietoturvakysymyksiin järjestetyllä ja todennettavalla evidencellä.", eyebrow: "Itse ylläpidettävä julkaisuevidence", - heroTitle: "Lopeta kiireinen selvittely, kun asiakas pyytää julkaisun tietoturvaevidenceä.", + heroTitle: + "Lopeta kiireinen selvittely, kun asiakas pyytää julkaisun tietoturvaevidenceä.", heroBody: [ "Evydence auttaa ohjelmistotoimittajia järjestämään ohjelmistojulkaisun taustalla olevan evidencen: mitä toimitettiin, mitä se sisälsi, mitkä haavoittuvuudet arvioitiin, mitä päätöksiä tehtiin ja mitä voidaan jakaa asiakkaalle turvallisesti.", - "Aja järjestelmää itse, pidä tekninen totuus GitHubissa ja käytä kaupallisia ehtoja, kun organisaatiosi tarvitsee niitä." + "Aja järjestelmää itse, pidä tekninen totuus GitHubissa ja käytä kaupallisia ehtoja, kun organisaatiosi tarvitsee niitä.", ], primaryCta: "Kysy Commercial Self-Hosted -ehdoista", secondaryCta: "Avaa GitHub", sections: [ { eyebrow: "Ongelma", - title: "Asiakkaiden tietoturvakatselmukset ovat yhä yksityiskohtaisempia.", + title: + "Asiakkaiden tietoturvakatselmukset ovat yhä yksityiskohtaisempia.", body: [ "Asiakas voi kysyä, mitä kolmannen osapuolen komponentteja julkaisu sisältää, onko tunnettuja haavoittuvuuksia mukana, vaikuttaako CVE tuotteeseen, kuka arvioi päätöksen ja mitä näyttöä voidaan todentaa.", - "Monessa tiimissä vastaus on hajallaan skannerivienneissä, CI-lokeissa, tiketeissä, keskusteluissa, taulukoissa, objektitallennuksessa ja kertaluonteisissa PDF-tiedostoissa." - ] + "Monessa tiimissä vastaus on hajallaan skannerivienneissä, CI-lokeissa, tiketeissä, keskusteluissa, taulukoissa, objektitallennuksessa ja kertaluonteisissa PDF-tiedostoissa.", + ], }, { eyebrow: "Lopputulos", @@ -528,68 +601,135 @@ const fi: Record = { "koonti- ja artefaktievidence", "julkaisuvalmiuden raportit", "allekirjoitetut bundle-paketit", - "asiakkaalle turvalliset paketit" - ] + "asiakkaalle turvalliset paketit", + ], }, { title: "Ennen ja jälkeen Evydencen", table: [ - { left: "Evidence on hajallaan työkaluissa", right: "Evidence on linkitetty julkaisuun" }, - { left: "Asiakasvastaukset ovat käsityötä", right: "Asiakaspaketti voidaan toistaa" }, - { left: "Päätökset ovat piilossa tiketeissä tai chatissa", right: "Päätöspolku sisältää tekijäkontekstin" }, - { left: "Not affected -päätöstä on vaikea selittää", right: "Haavoittuvuuspäätös on katselmoitavissa" }, - { left: "PDF-työ tehdään kertaluonteisesti", right: "Paketti syntyy rakenteisista tietueista" } - ] + { + left: "Evidence on hajallaan työkaluissa", + right: "Evidence on linkitetty julkaisuun", + }, + { + left: "Asiakasvastaukset ovat käsityötä", + right: "Asiakaspaketti voidaan toistaa", + }, + { + left: "Päätökset ovat piilossa tiketeissä tai chatissa", + right: "Päätöspolku sisältää tekijäkontekstin", + }, + { + left: "Not affected -päätöstä on vaikea selittää", + right: "Haavoittuvuuspäätös on katselmoitavissa", + }, + { + left: "PDF-työ tehdään kertaluonteisesti", + right: "Paketti syntyy rakenteisista tietueista", + }, + ], }, { title: "Mitä Evydence ei ole", body: [ "Evydence ei ole skanneri, palomuuri, juridinen vaatimustenmukaisuuskone, sertifiointipalvelu tai takuu siitä, että julkaisu on turvallinen.", - "Se auttaa järjestämään teknisen evidencen ja julkaisun tietoturvapäätökset, jotta tiimit voivat vastata katselmuskysymyksiin selkeämmin ja toistettavammin." - ] - } - ] + "Se auttaa järjestämään teknisen evidencen ja julkaisun tietoturvapäätökset, jotta tiimit voivat vastata katselmuskysymyksiin selkeämmin ja toistettavammin.", + ], + }, + ], }, product: { ...en.product, title: "Tuote", navTitle: "Tuote", metaTitle: "Tuote - Evydence", - description: "Itse ylläpidettävä evidence-järjestelmä ohjelmistojulkaisuille.", + description: + "Itse ylläpidettävä evidence-järjestelmä ohjelmistojulkaisuille.", eyebrow: "Tuotekuvaus", - heroTitle: "Itse ylläpidettävä evidence-järjestelmä ohjelmistojulkaisuille.", + heroTitle: + "Itse ylläpidettävä evidence-järjestelmä ohjelmistojulkaisuille.", heroBody: [ - "Evydence pitää julkaisuevidencen kytkettynä tuotteeseen, versioon, artefaktiin, haavoittuvuuteen, päätökseen, hyväksyntään ja asiakaspakettiin." + "Evydence pitää julkaisuevidencen kytkettynä tuotteeseen, versioon, artefaktiin, haavoittuvuuteen, päätökseen, hyväksyntään ja asiakaspakettiin.", ], primaryCta: "Kysy Commercial Self-Hosted -ehdoista", secondaryCta: "Avaa GitHub", sections: [ - { title: "Kerää julkaisuevidence", body: ["Kerää julkaisun ympärillä oleva todistusaineisto: komponenttilistat, haavoittuvuusskannaukset, koontimetatiedot, artefaktien digestit, lähdekooditietueet, käyttöönotot ja tukevat tiedostot."] }, - { title: "Tallenna haavoittuvuuspäätökset", body: ["Kun tunnettu haavoittuvuus löytyy, tallenna vaikuttaako se julkaisuun, miksi, kuka sen arvioi ja mikä evidence tukee päätöstä."] }, - { title: "Luo asiakkaalle turvallisia paketteja", body: ["Luo paketteja, jotka sisältävät asiakkaalle hyödyllisen evidencen ilman tarpeetonta sisäistä yksityiskohtaa."] }, - { title: "Todenna paketti", body: ["Käytä manifestteja, tiivisteitä, allekirjoituksia ja audit chain -tietueita, jotta paketti on katselmoitava eikä vain uusi staattinen dokumentti."] }, - { title: "Itse ylläpidettävä lähtökohta", body: ["Evydence on tarkoitettu tiimeille, jotka haluavat ajaa evidence-järjestelmää omassa ympäristössään lähellä julkaisu-, tietoturva- ja CI/CD-järjestelmiä."] } - ] + { + title: "Kerää julkaisuevidence", + body: [ + "Kerää julkaisun ympärillä oleva todistusaineisto: komponenttilistat, haavoittuvuusskannaukset, koontimetatiedot, artefaktien digestit, lähdekooditietueet, käyttöönotot ja tukevat tiedostot.", + ], + }, + { + title: "Tallenna haavoittuvuuspäätökset", + body: [ + "Kun tunnettu haavoittuvuus löytyy, tallenna vaikuttaako se julkaisuun, miksi, kuka sen arvioi ja mikä evidence tukee päätöstä.", + ], + }, + { + title: "Luo asiakkaalle turvallisia paketteja", + body: [ + "Luo paketteja, jotka sisältävät asiakkaalle hyödyllisen evidencen ilman tarpeetonta sisäistä yksityiskohtaa.", + ], + }, + { + title: "Todenna paketti", + body: [ + "Käytä manifestteja, tiivisteitä, allekirjoituksia ja audit chain -tietueita, jotta paketti on katselmoitava eikä vain uusi staattinen dokumentti.", + ], + }, + { + title: "Itse ylläpidettävä lähtökohta", + body: [ + "Evydence on tarkoitettu tiimeille, jotka haluavat ajaa evidence-järjestelmää omassa ympäristössään lähellä julkaisu-, tietoturva- ja CI/CD-järjestelmiä.", + ], + }, + ], }, customerReview: { ...en.customerReview, title: "Asiakkaan tietoturvakatselmukset", navTitle: "Käyttötapaukset", metaTitle: "Asiakkaan tietoturvakatselmukset - Evydence", - description: "Muuta asiakkaan tietoturvakysymykset toistettavaksi julkaisuevidence-työnkuluksi.", + description: + "Muuta asiakkaan tietoturvakysymykset toistettavaksi julkaisuevidence-työnkuluksi.", eyebrow: "Käyttötapaus", - heroTitle: "Asiakkaan tietoturvakatselmuksen ei pitäisi olla aarteenetsintä.", + heroTitle: + "Asiakkaan tietoturvakatselmuksen ei pitäisi olla aarteenetsintä.", heroBody: [ "Yritysasiakkaat kysyvät yhä useammin, mitä julkaisu sisältää, mitä tunnettuja haavoittuvuuksia löytyy, mitkä niistä todella vaikuttavat tuotteeseen ja mikä evidence tukee vastausta.", - "Evydence auttaa muuttamaan katselmuksen käsityöstä toistettavaksi julkaisuevidence-työnkuluksi." + "Evydence auttaa muuttamaan katselmuksen käsityöstä toistettavaksi julkaisuevidence-työnkuluksi.", ], primaryCta: "Kysy julkaisuevidence-pilotista", secondaryCta: "Avaa GitHub", sections: [ - { title: "Kysymys, joka käynnistää selvityksen", body: ["Asiakas kysyy: Tämä CVE näkyy ohjelmiston SBOMissa. Vaikuttaako se meihin?", "Ilman järjestelmää vastaus voi vaatia SBOMin, skannerin, CI-lokien, artefaktien, sisäisten tikettien, hyväksyntöjen, julkaisutietojen ja aiempien asiakasvastausten läpikäyntiä."] }, - { title: "Selkeämpi vastaus", bullets: ["kyllä, vaikuttaa ja on korjattu", "kyllä, vaikuttaa ja on hyväksytty poikkeuksella", "ei, mukana mutta ei hyödynnettävissä tässä tuotekontekstissa", "tuntematon, dokumentoiduilla aukoilla ja seuraavilla toimilla"] }, - { title: "Ennen ja jälkeen", table: [{ left: "Uskomme, ettei tämä ole hyödynnettävissä. Tarkistamme asian kehitystiimiltä.", right: "Tälle julkaisulle löydös arvioitiin, merkittiin not affected -tilaan, linkitettiin tukevaan evidenceen ja sisällytettiin asiakaspakettiin." }] } - ] + { + title: "Kysymys, joka käynnistää selvityksen", + body: [ + "Asiakas kysyy: Tämä CVE näkyy ohjelmiston SBOMissa. Vaikuttaako se meihin?", + "Ilman järjestelmää vastaus voi vaatia SBOMin, skannerin, CI-lokien, artefaktien, sisäisten tikettien, hyväksyntöjen, julkaisutietojen ja aiempien asiakasvastausten läpikäyntiä.", + ], + }, + { + title: "Selkeämpi vastaus", + bullets: [ + "kyllä, vaikuttaa ja on korjattu", + "kyllä, vaikuttaa ja on hyväksytty poikkeuksella", + "ei, mukana mutta ei hyödynnettävissä tässä tuotekontekstissa", + "tuntematon, dokumentoiduilla aukoilla ja seuraavilla toimilla", + ], + }, + { + title: "Ennen ja jälkeen", + table: [ + { + left: "Uskomme, ettei tämä ole hyödynnettävissä. Tarkistamme asian kehitystiimiltä.", + right: + "Tälle julkaisulle löydös arvioitiin, merkittiin not affected -tilaan, linkitettiin tukevaan evidenceen ja sisällytettiin asiakaspakettiin.", + }, + ], + }, + ], }, releasePackage: { ...en.releasePackage, @@ -601,34 +741,107 @@ const fi: Record = { heroTitle: "Yksi julkaisu. Yksi järjestetty evidence-paketti.", heroBody: [ "Evidence-paketti on rakenteinen todistusaineisto ohjelmistojulkaisulle.", - "Se voi sisältää mitä toimitettiin, mitä komponentteja oli mukana, mitä tunnettuja haavoittuvuuksia löytyi, miten ne käsiteltiin, kuka hyväksyi päätöksen ja mitä asiakas voi todentaa." + "Se voi sisältää mitä toimitettiin, mitä komponentteja oli mukana, mitä tunnettuja haavoittuvuuksia löytyi, miten ne käsiteltiin, kuka hyväksyi päätöksen ja mitä asiakas voi todentaa.", ], primaryCta: "Kysy Commercial Self-Hosted -ehdoista", secondaryCta: "Avaa GitHub", sections: [ - { title: "Suositeltu sisältö", bullets: ["tuotteen ja julkaisun identiteetti", "toimitettujen artefaktien viitteet", "artefaktien tiivisteet tai digestit", "SBOM/komponentti-inventaario", "haavoittuvuusskannauksen yhteenveto", "haavoittuvuuspäätökset", "poikkeus- tai waiver-tietueet", "koonti- ja lähdekoodiprovenanssi", "hyväksyntäpolku", "pakettimanifesti", "rajoitukset ja oletukset", "asiakkaalle turvalliset redaktiot"] }, - { title: "Tärkeä raja", body: ["Paketti ei tarkoita, että julkaisu olisi täydellisen turvallinen.", "Se tarkoittaa, että tiimi voi näyttää, mitä tarkistettiin, mitä päätettiin, mitä on yhä tuntematonta ja mikä evidence tukee vastausta."] } - ] + { + title: "Suositeltu sisältö", + bullets: [ + "tuotteen ja julkaisun identiteetti", + "toimitettujen artefaktien viitteet", + "artefaktien tiivisteet tai digestit", + "SBOM/komponentti-inventaario", + "haavoittuvuusskannauksen yhteenveto", + "haavoittuvuuspäätökset", + "poikkeus- tai waiver-tietueet", + "koonti- ja lähdekoodiprovenanssi", + "hyväksyntäpolku", + "pakettimanifesti", + "rajoitukset ja oletukset", + "asiakkaalle turvalliset redaktiot", + ], + }, + { + title: "Tärkeä raja", + body: [ + "Paketti ei tarkoita, että julkaisu olisi täydellisen turvallinen.", + "Se tarkoittaa, että tiimi voi näyttää, mitä tarkistettiin, mitä päätettiin, mitä on yhä tuntematonta ja mikä evidence tukee vastausta.", + ], + }, + ], }, commercial: { ...en.commercial, title: "Kaupallinen", navTitle: "Kaupallinen", metaTitle: "Commercial Self-Hosted -lisensointi - Evydence", - description: "Kaupallinen itse ylläpidettävä lisensointi, async-tuki, käyttöönottokatselmus ja integraatiotuki.", + description: + "Kaupallinen itse ylläpidettävä lisensointi, async-tuki, käyttöönottokatselmus ja integraatiotuki.", eyebrow: "Commercial Self-Hosted", heroTitle: "Commercial Self-Hosted -lisensointi.", heroBody: [ "Käytä Evydenceä AGPL-lisenssillä, kun se sopii organisaatiollesi.", - "Osta Commercial Self-Hosted, kun tarvitset yksityiset kaupalliset ehdot, AGPL-poikkeuksen, async-tuen, allekirjoitetun julkaisu/evidence-toimituksen tai käyttöönottokatselmuksen." + "Osta Commercial Self-Hosted, kun tarvitset yksityiset kaupalliset ehdot, AGPL-poikkeuksen, async-tuen, allekirjoitetun julkaisu/evidence-toimituksen tai käyttöönottokatselmuksen.", ], primaryCta: "Aloita async-kaupallinen kysely", secondaryCta: "Avaa GitHub", sections: [ - { title: "Community AGPL vs Commercial Self-Hosted", table: [{ left: "Julkinen AGPL-lisenssi", right: "Erillinen kirjallinen kaupallinen sopimus" }, { left: "Julkiset GitHub-issuet", right: "Yksityinen async-tuki" }, { left: "Best-effort-yhteisöapu", right: "Sovittu tuki- ja päivityspolku" }, { left: "Oma arviointi", right: "Valinnainen deployment readiness -katselmus" }, { left: "AGPL-velvoitteet pätevät", right: "Lisälupa sovittuihin käyttötapauksiin" }] }, - { title: "Maksulliset vaihtoehdot", cards: [{ title: "Commercial Self-Hosted License", body: "Yksityiset kaupalliset ehdot, hankintaystävällinen lisensointi ja sovittu tukipolku." }, { title: "Async Support", body: "Yksityinen kirjallinen tuki vianrajoitukseen, päivityssuunnitteluun, käyttöönottokysymyksiin ja julkaisuevidence-työnkulkuihin." }, { title: "Deployment Readiness Review", body: "Kirjallinen katselmus konfiguraatiosta, varmistuksista, evidencen käsittelystä, arkkitehtuurista ja tunnetuista rajoituksista." }, { title: "Release Evidence Package Review", body: "Kirjallinen katselmus yhdestä evidence-paketista, mukaan lukien aukot, oletukset, rajoitukset ja asiakkaalle turvallinen jakaminen." }, { title: "Custom Integration", body: "Collector-adapterit, evidence-työnkulut, raporttipohjat, CI/CD-integraatio tai deployment-kovennus." }] }, - { title: "Kaupallinen raja", body: ["Kaupalliset ehdot eivät tee Evydencestä juridista vaatimustenmukaisuustakuuta, tietoturvasertifiointia, haavoittuvuusskanneria tai hallittua SaaS-palvelua."] } - ] + { + title: "Community AGPL vs Commercial Self-Hosted", + table: [ + { + left: "Julkinen AGPL-lisenssi", + right: "Erillinen kirjallinen kaupallinen sopimus", + }, + { left: "Julkiset GitHub-issuet", right: "Yksityinen async-tuki" }, + { + left: "Best-effort-yhteisöapu", + right: "Sovittu tuki- ja päivityspolku", + }, + { + left: "Oma arviointi", + right: "Valinnainen deployment readiness -katselmus", + }, + { + left: "AGPL-velvoitteet pätevät", + right: "Lisälupa sovittuihin käyttötapauksiin", + }, + ], + }, + { + title: "Maksulliset vaihtoehdot", + cards: [ + { + title: "Commercial Self-Hosted License", + body: "Yksityiset kaupalliset ehdot, hankintaystävällinen lisensointi ja sovittu tukipolku.", + }, + { + title: "Async Support", + body: "Yksityinen kirjallinen tuki vianrajoitukseen, päivityssuunnitteluun, käyttöönottokysymyksiin ja julkaisuevidence-työnkulkuihin.", + }, + { + title: "Deployment Readiness Review", + body: "Kirjallinen katselmus konfiguraatiosta, varmistuksista, evidencen käsittelystä, arkkitehtuurista ja tunnetuista rajoituksista.", + }, + { + title: "Release Evidence Package Review", + body: "Kirjallinen katselmus yhdestä evidence-paketista, mukaan lukien aukot, oletukset, rajoitukset ja asiakkaalle turvallinen jakaminen.", + }, + { + title: "Custom Integration", + body: "Collector-adapterit, evidence-työnkulut, raporttipohjat, CI/CD-integraatio tai deployment-kovennus.", + }, + ], + }, + { + title: "Kaupallinen raja", + body: [ + "Kaupalliset ehdot eivät tee Evydencestä juridista vaatimustenmukaisuustakuuta, tietoturvasertifiointia, haavoittuvuusskanneria tai hallittua SaaS-palvelua.", + ], + }, + ], }, status: { ...en.status, @@ -640,85 +853,197 @@ const fi: Record = { heroTitle: "Nykyinen tila ja tuettu käyttöprofiili.", heroBody: [ "Evydence on tarkoitettu arviointiin, pilotteihin ja hallittuun sisäiseen itse ylläpidettävään tuotantokäyttöön operaattorin katselmuksen jälkeen.", - "Sitä ei markkinoida hostattuna SaaS-tuotteena tai laajana reguloidun tuotannon alustana." + "Sitä ei markkinoida hostattuna SaaS-tuotteena tai laajana reguloidun tuotannon alustana.", ], primaryCta: "Kysy käyttöönottosopivuudesta", secondaryCta: "Avaa GitHub", sections: [ - { title: "Käyttöprofiilin sopivuus", table: [{ left: "Paikallinen tekninen arviointi", right: "Hyvä sopivuus" }, { left: "Pilotti yhdellä tuotteella/julkaisulla", right: "Hyvä sopivuus" }, { left: "Hallittu sisäinen itse ylläpidettävä käyttö", right: "Kandidaatti katselmuksen jälkeen" }, { left: "Reguloitu tuotanto", right: "Vaatii lisäkatselmuksen" }, { left: "Air-gapped-tuotanto", right: "Vaatii siirtokontrollit" }, { left: "Evydencen hostattu SaaS", right: "Ei tällä hetkellä tarjolla" }] }, - { title: "Miksi tämä sivu on olemassa", body: ["Tämä sivu suodattaa huonosti sopivat käyttötapaukset ja lisää luottamusta sopivien arvioijien kanssa kertomalla rajoitukset suoraan."] } - ] + { + title: "Käyttöprofiilin sopivuus", + table: [ + { left: "Paikallinen tekninen arviointi", right: "Hyvä sopivuus" }, + { + left: "Pilotti yhdellä tuotteella/julkaisulla", + right: "Hyvä sopivuus", + }, + { + left: "Hallittu sisäinen itse ylläpidettävä käyttö", + right: "Kandidaatti katselmuksen jälkeen", + }, + { left: "Reguloitu tuotanto", right: "Vaatii lisäkatselmuksen" }, + { left: "Air-gapped-tuotanto", right: "Vaatii siirtokontrollit" }, + { + left: "Evydencen hostattu SaaS", + right: "Ei tällä hetkellä tarjolla", + }, + ], + }, + { + title: "Miksi tämä sivu on olemassa", + body: [ + "Tämä sivu suodattaa huonosti sopivat käyttötapaukset ja lisää luottamusta sopivien arvioijien kanssa kertomalla rajoitukset suoraan.", + ], + }, + ], }, glossary: { ...en.glossary, title: "Sanasto", navTitle: "Sanasto", metaTitle: "Selkokielinen sanasto - Evydence", - description: "Selkokieliset termit julkaisuevidencestä, SBOMeista, CVE-tunnuksista, VEXistä ja asiakaspaketeista.", + description: + "Selkokieliset termit julkaisuevidencestä, SBOMeista, CVE-tunnuksista, VEXistä ja asiakaspaketeista.", eyebrow: "Resurssit", heroTitle: "Selkokielinen sanasto.", - heroBody: ["Lyhyet selitykset ihmisille, jotka arvioivat julkaisuevidence-työnkulkuja ilman kaikkia toteutusyksityiskohtia."], + heroBody: [ + "Lyhyet selitykset ihmisille, jotka arvioivat julkaisuevidence-työnkulkuja ilman kaikkia toteutusyksityiskohtia.", + ], primaryCta: "Kysy Commercial Self-Hosted -ehdoista", secondaryCta: "Avaa GitHub", sections: [ - { title: "Termit", cards: [{ title: "Evidence", body: "Julkaisun ympärillä oleva todistusaineisto: skannaustulokset, komponenttilistat, koontitietueet, haavoittuvuuspäätökset, hyväksynnät, artefaktitiivisteet, julkaisuraportit ja asiakkaalle turvalliset tiedostot." }, { title: "Evidence-paketti", body: "Järjestetty julkaisun todistusaineistopaketti, jota voidaan katselmoida sisäisesti tai jakaa asiakkaalle." }, { title: "SBOM", body: "Ohjelmiston ainesosalista. Se kuvaa ohjelmistossa käytetyt komponentit." }, { title: "CVE", body: "Julkinen tunniste tunnetulle ohjelmistovirheelle." }, { title: "VEX", body: "Rakenteinen tapa selittää, vaikuttaako tunnettu haavoittuvuus tiettyyn tuotteeseen tai julkaisuun." }, { title: "Asiakkaalle turvallinen paketti", body: "Paketti, joka sisältää hyödyllisen katselmusevidencen paljastamatta tarpeettomia sisäisiä yksityiskohtia." }, { title: "Julkaisuvalmius", body: "Rakenteinen näkymä siihen, onko julkaisulla odotettu evidence, päätökset, hyväksynnät ja tunnetut rajoitukset ennen jakamista tai toimitusta." }] } - ] + { + title: "Termit", + cards: [ + { + title: "Evidence", + body: "Julkaisun ympärillä oleva todistusaineisto: skannaustulokset, komponenttilistat, koontitietueet, haavoittuvuuspäätökset, hyväksynnät, artefaktitiivisteet, julkaisuraportit ja asiakkaalle turvalliset tiedostot.", + }, + { + title: "Evidence-paketti", + body: "Järjestetty julkaisun todistusaineistopaketti, jota voidaan katselmoida sisäisesti tai jakaa asiakkaalle.", + }, + { + title: "SBOM", + body: "Ohjelmiston ainesosalista. Se kuvaa ohjelmistossa käytetyt komponentit.", + }, + { + title: "CVE", + body: "Julkinen tunniste tunnetulle ohjelmistovirheelle.", + }, + { + title: "VEX", + body: "Rakenteinen tapa selittää, vaikuttaako tunnettu haavoittuvuus tiettyyn tuotteeseen tai julkaisuun.", + }, + { + title: "Asiakkaalle turvallinen paketti", + body: "Paketti, joka sisältää hyödyllisen katselmusevidencen paljastamatta tarpeettomia sisäisiä yksityiskohtia.", + }, + { + title: "Julkaisuvalmius", + body: "Rakenteinen näkymä siihen, onko julkaisulla odotettu evidence, päätökset, hyväksynnät ja tunnetut rajoitukset ennen jakamista tai toimitusta.", + }, + ], + }, + ], }, cra: { ...en.cra, title: "CRA-valmiuden evidence", navTitle: "CRA-valmius", - metaTitle: "Teknisen evidencen järjestäminen CRA-valmiutta varten - Evydence", - description: "Teknisen evidencen järjestäminen CRA-valmiustyöhön ilman juridisia vaatimustenmukaisuusväitteitä.", + metaTitle: + "Teknisen evidencen järjestäminen CRA-valmiutta varten - Evydence", + description: + "Teknisen evidencen järjestäminen CRA-valmiustyöhön ilman juridisia vaatimustenmukaisuusväitteitä.", eyebrow: "Resurssit", heroTitle: "Teknisen evidencen järjestäminen CRA-valmiutta varten.", heroBody: [ "EU:n Cyber Resilience Act lisää huomiota haavoittuvuuksien käsittelyyn, tekniseen dokumentaatioon ja tuoteturvallisuusprosesseihin.", - "Evydence ei tarjoa juridista vaatimustenmukaisuutta tai sertifiointia, mutta se voi auttaa järjestämään teknistä julkaisuevidenceä, jota tuoteturvallisuus- ja compliance readiness -tiimit voivat tarvita katselmuksissa." + "Evydence ei tarjoa juridista vaatimustenmukaisuutta tai sertifiointia, mutta se voi auttaa järjestämään teknistä julkaisuevidenceä, jota tuoteturvallisuus- ja compliance readiness -tiimit voivat tarvita katselmuksissa.", ], primaryCta: "Kysy release evidence -katselmuksesta", secondaryCta: "Avaa GitHub", sections: [ - { title: "Varovainen sanamuoto", body: ["Evydence voi tukea CRA-valmiustyötä auttamalla tiimejä säilyttämään julkaisutason teknistä evidenceä, haavoittuvuuspäätöksiä, SBOM-tietueita, pakettimanifesteja ja tunnettuja rajoituksia."] }, - { title: "Vältettävät sanamuodot", bullets: ["Evydence tekee sinusta CRA-yhteensopivan.", "Evydence sertifioi julkaisusi.", "Evydence takaa viranomaisen hyväksynnän.", "Evydence todistaa, että ohjelmistosi on turvallinen."] } - ] + { + title: "Varovainen sanamuoto", + body: [ + "Evydence voi tukea CRA-valmiustyötä auttamalla tiimejä säilyttämään julkaisutason teknistä evidenceä, haavoittuvuuspäätöksiä, SBOM-tietueita, pakettimanifesteja ja tunnettuja rajoituksia.", + ], + }, + { + title: "Vältettävät sanamuodot", + bullets: [ + "Evydence tekee sinusta CRA-yhteensopivan.", + "Evydence sertifioi julkaisusi.", + "Evydence takaa viranomaisen hyväksynnän.", + "Evydence todistaa, että ohjelmistosi on turvallinen.", + ], + }, + ], }, contact: { ...en.contact, title: "Yhteys", navTitle: "Yhteys", - metaTitle: "Async-kaupallinen kysely - Evydence", - description: "Aloita async-kysely Commercial Self-Hosted -käytöstä.", - eyebrow: "Async ensin", - heroTitle: "Async-kaupallinen kysely.", - heroBody: ["Evydencen kaupallinen tuki on async-first. Lähetä konteksti, käyttöoletukset, julkaisutyönkulun muistiinpanot tai lisensointikysymykset. Saat kirjallisen vastauksen."], - primaryCta: "Lähetä async-kysely", + metaTitle: "Yhteys - Evydence", + description: "Aloita Commercial Self-Hosted -keskustelu LinkedInissä.", + eyebrow: "LinkedIn-yhteys", + heroTitle: "Aloita kaupallinen keskustelu.", + heroBody: [ + "Käytä LinkedIniä ensimmäiseen Commercial Self-Hosted -keskusteluun, käyttöoletuksiin, julkaisutyönkulun muistiinpanoihin tai lisensointikysymyksiin.", + ], + primaryCta: "Avaa LinkedIn-profiili", secondaryCta: "Avaa GitHub", sections: [ - { title: "Mitä mukaan", bullets: ["suunniteltu käyttötapa", "tavoiteltu käyttöönottomalli", "AGPL- tai kaupalliset huolenaiheet", "tukiodotukset", "tavoiteltu julkaisutyönkulku", "toivottu seuraava askel"] }, - { title: "Älä lähetä arkaluonteista evidenceä", body: ["Älä lähetä raw evidence -payloadia, bearer-tokeneita, yksityisiä avaimia, tietokanta-URL-osoitteita, asiakasdataa tai julkaisemattomia pakettisisältöjä julkisen yhteyspolun kautta.", "Lyhyttä rajauspuhelua voi pyytää sen jälkeen, kun async-konteksti on jaettu."] } - ] + { + title: "Mitä mukaan", + bullets: [ + "suunniteltu käyttötapa", + "tavoiteltu käyttöönottomalli", + "AGPL- tai kaupalliset huolenaiheet", + "tukiodotukset", + "tavoiteltu julkaisutyönkulku", + "toivottu seuraava askel", + ], + }, + { + title: "Älä lähetä arkaluonteista evidenceä", + body: [ + "Älä lähetä raw evidence -payloadia, bearer-tokeneita, yksityisiä avaimia, tietokanta-URL-osoitteita, asiakasdataa tai julkaisemattomia pakettisisältöjä LinkedInin tai muun julkisen yhteyspolun kautta.", + "Käytä ensimmäistä viestiä vain lyhyeen, ei-arkaluonteiseen kontekstiin. Turvallisempi yksityinen kanava voidaan sopia erikseen tarvittaessa.", + ], + }, + ], }, privacyCookies: { ...en.privacyCookies, title: "Yksityisyys ja evästeet", navTitle: "Yksityisyys", metaTitle: "Yksityisyys ja evästeet - Evydence", - description: "Miten markkinointisivusto käsittelee välttämättömiä asetuksia ja valinnaista mittausta.", + description: + "Miten markkinointisivusto käsittelee välttämättömiä asetuksia ja valinnaista mittausta.", eyebrow: "Yksityisyys", heroTitle: "Yksityisyys ja evästeet.", heroBody: [ "Markkinointisivusto käyttää vain välttämättömiä paikallisia valintoja, kunnes päätät hyväksyä valinnaisen sivustomittauksen.", - "Kun valinnainen mittaus on käytössä, se rajoittuu koottuihin markkinointisivuston tapahtumiin." + "Kun valinnainen mittaus on käytössä, se rajoittuu koottuihin markkinointisivuston tapahtumiin.", ], primaryCta: "Hallitse evästevalintoja", secondaryCta: "Avaa GitHub", sections: [ - { title: "Mitä voidaan mitata hyväksynnän jälkeen", bullets: ["sivunäkymät", "ulospäin lähtevät GitHub-klikkaukset", "dokumentaatioklikkaukset", "yhteydenottoklikkaukset", "kielenvaihdot"] }, - { title: "Mitä ei mitata", body: ["Sivusto ei saa seurata lomakkeen raakatekstiä, sähköpostiosoitteita, asiakkaiden nimiä, yritysten nimiä, evidence-pakettien dataa, tokeneita, salaisuuksia sisältäviä kyselyparametreja tai tukisisältöä."] }, - { title: "Valinnan muuttaminen", body: ["Avaa suostumuspaneeli uudelleen alatunnisteen evästeasetusten linkistä ja muuta valinnaisen mittauksen valintaa."] } - ] - } + { + title: "Mitä voidaan mitata hyväksynnän jälkeen", + bullets: [ + "sivunäkymät", + "ulospäin lähtevät GitHub-klikkaukset", + "dokumentaatioklikkaukset", + "yhteydenottoklikkaukset", + "kielenvaihdot", + ], + }, + { + title: "Mitä ei mitata", + body: [ + "Sivusto ei saa seurata lomakkeen raakatekstiä, sähköpostiosoitteita, asiakkaiden nimiä, yritysten nimiä, evidence-pakettien dataa, tokeneita, salaisuuksia sisältäviä kyselyparametreja tai tukisisältöä.", + ], + }, + { + title: "Valinnan muuttaminen", + body: [ + "Avaa suostumuspaneeli uudelleen alatunnisteen evästeasetusten linkistä ja muuta valinnaisen mittauksen valintaa.", + ], + }, + ], + }, }; export const content: Record> = { en, fi }; @@ -734,20 +1059,21 @@ export const ui = { "Evydence is not a legal compliance service, certification authority, vulnerability scanner, hosted SaaS, or guarantee of release security.", cookiePreferences: "Cookie preferences", outboundGitHub: "View GitHub", - contactHref: externalLinks.commercialEmail + contactHref: externalLinks.linkedin, }, fi: { skip: "Siirry sisältöön", language: "Kieli", docs: "Dokumentaatio", github: "GitHub", - footerTagline: "Itse ylläpidettävä julkaisuevidence ohjelmistotoimittajille.", + footerTagline: + "Itse ylläpidettävä julkaisuevidence ohjelmistotoimittajille.", footerBoundary: "Evydence ei ole juridinen vaatimustenmukaisuuspalvelu, sertifiointitaho, haavoittuvuusskanneri, hostattu SaaS-palvelu tai takuu julkaisun turvallisuudesta.", cookiePreferences: "Evästeasetukset", outboundGitHub: "Avaa GitHub", - contactHref: externalLinks.commercialEmail - } + contactHref: externalLinks.linkedin, + }, } satisfies Record>; export function routeFor(pageKey: PageKey, locale: Locale): string { @@ -763,19 +1089,25 @@ export function routeToSlug(path: string): string | undefined { return slug === "" ? undefined : slug; } -export function localizedAlternates(pageKey: PageKey): Array<{ locale: Locale; href: string }> { +export function localizedAlternates( + pageKey: PageKey, +): Array<{ locale: Locale; href: string }> { return (Object.keys(localeNames) as Locale[]).map((locale) => ({ locale, - href: routeFor(pageKey, locale) + href: routeFor(pageKey, locale), })); } -export function staticPages(): Array<{ locale: Locale; pageKey: PageKey; slug: string | undefined }> { +export function staticPages(): Array<{ + locale: Locale; + pageKey: PageKey; + slug: string | undefined; +}> { return (Object.keys(localeNames) as Locale[]).flatMap((locale) => orderedPageKeys.map((pageKey) => ({ locale, pageKey, - slug: routeToSlug(routeFor(pageKey, locale)) - })) + slug: routeToSlug(routeFor(pageKey, locale)), + })), ); } diff --git a/site/marketing/src/layouts/BaseLayout.astro b/site/marketing/src/layouts/BaseLayout.astro index 15bb50e..15dffa3 100644 --- a/site/marketing/src/layouts/BaseLayout.astro +++ b/site/marketing/src/layouts/BaseLayout.astro @@ -85,7 +85,7 @@ const ui = { {localeNames[otherLocale]} - + {copy.contact.navTitle} @@ -101,7 +101,7 @@ const ui = { {localeNames[otherLocale]} - + {copy.contact.navTitle} diff --git a/site/marketing/src/templates/MarketingPage.astro b/site/marketing/src/templates/MarketingPage.astro index 89f786d..0f4f89c 100644 --- a/site/marketing/src/templates/MarketingPage.astro +++ b/site/marketing/src/templates/MarketingPage.astro @@ -7,7 +7,7 @@ const { locale, pageKey } = Astro.props as { locale: Locale; pageKey: PageKey }; const page = pageFor(locale, pageKey); const basePath = import.meta.env.BASE_URL.replace(/\/$/, ""); const withBase = (path: string) => `${basePath}${path}`.replace(/\/{2,}/g, "/"); -const primaryHref = pageKey === "privacyCookies" ? "#" : externalLinks.commercialEmail; +const primaryHref = pageKey === "privacyCookies" ? "#" : externalLinks.linkedin; const primaryAttrs = pageKey === "privacyCookies" ? { "data-cookie-preferences": "" } : { "data-track": "contact_click" }; --- From f8150a93da1e5a2c1fc913c2d3719147f7641d7a Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 17:29:18 +0300 Subject: [PATCH 251/287] ci(site): grant Pages configure permission --- .github/workflows/marketing-site-pages.yml | 1 + Makefile | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/marketing-site-pages.yml b/.github/workflows/marketing-site-pages.yml index 224264d..87c1a72 100644 --- a/.github/workflows/marketing-site-pages.yml +++ b/.github/workflows/marketing-site-pages.yml @@ -24,6 +24,7 @@ jobs: runs-on: ubuntu-latest permissions: contents: read + pages: write env: PUBLIC_SITE_URL: https://evydence.app PUBLIC_SITE_BASE: / diff --git a/Makefile b/Makefile index 0277b6e..afaad2a 100644 --- a/Makefile +++ b/Makefile @@ -118,6 +118,7 @@ meta-check: ## Validate root legal, governance, support, and release-evidence me @grep -F 'actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa' .github/workflows/marketing-site-pages.yml >/dev/null @grep -F 'actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b' .github/workflows/marketing-site-pages.yml >/dev/null @grep -F 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' .github/workflows/marketing-site-pages.yml >/dev/null + @grep -F 'pages: write' .github/workflows/marketing-site-pages.yml >/dev/null @test -f site/marketing/public/CNAME @grep -Fx 'evydence.app' site/marketing/public/CNAME >/dev/null @grep -F 'Evydence fork' TRADEMARKS.md >/dev/null From 0602a494fdc3aef6700b18fa9426f58d52283ace Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 18:17:43 +0300 Subject: [PATCH 252/287] fix(site): keep localized hero words whole --- site/marketing/scripts/check.mjs | 8 ++++ site/marketing/src/layouts/BaseLayout.astro | 50 ++++++++++++++++++++- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/site/marketing/scripts/check.mjs b/site/marketing/scripts/check.mjs index 0cb65ca..b055642 100644 --- a/site/marketing/scripts/check.mjs +++ b/site/marketing/scripts/check.mjs @@ -115,6 +115,14 @@ const layoutChecks = [ "class=\"mobile-nav\"", "mobile-nav__panel", "font-size: clamp(2.7rem, 5.4vw, 5.25rem)", + ".hero h1", + "hyphens: none", + "word-break: normal", + ":lang(fi) h2", + ":lang(fi) .section--split h2", + "font-size: 1.85rem", + "overflow-wrap: anywhere", + ".section--split > *", "min-height: min(760px, calc(100vh - 4.8rem))", ".nav,\n .header-actions {\n display: none;" ]; diff --git a/site/marketing/src/layouts/BaseLayout.astro b/site/marketing/src/layouts/BaseLayout.astro index 15dffa3..97187af 100644 --- a/site/marketing/src/layouts/BaseLayout.astro +++ b/site/marketing/src/layouts/BaseLayout.astro @@ -378,17 +378,38 @@ const ui = { h1 { font-size: clamp(2.7rem, 5.4vw, 5.25rem); + hyphens: auto; line-height: 1.02; letter-spacing: 0; margin-bottom: 1.15rem; max-width: 13.5ch; + overflow-wrap: break-word; } h2 { font-size: clamp(2rem, 4.5vw, 4rem); + hyphens: auto; line-height: 1.02; letter-spacing: 0; max-width: 13ch; + overflow-wrap: anywhere; + } + + .hero h1 { + hyphens: none; + overflow-wrap: normal; + text-wrap: balance; + word-break: normal; + } + + :lang(fi) h1 { + font-size: clamp(2.25rem, 3.9vw, 3.75rem); + max-width: 20ch; + } + + :lang(fi) h2 { + font-size: clamp(1.8rem, 2.9vw, 2.75rem); + max-width: 100%; } h3 { @@ -418,8 +439,23 @@ const ui = { .section--split { border-top: 1px solid var(--line); display: grid; - gap: 2rem; - grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); + gap: clamp(2rem, 5vw, 4rem); + grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); + } + + .section--split h2 { + max-width: 100%; + } + + :lang(fi) .section--split h2 { + font-size: clamp(1.75rem, 2.55vw, 2.45rem); + } + + .hero__content, + .section--split > *, + .section__body, + .table-row > * { + min-width: 0; } .section__body { @@ -591,6 +627,16 @@ const ui = { font-size: clamp(2.45rem, 12vw, 4rem); } + :lang(fi) h1 { + font-size: 1.85rem; + line-height: 1.08; + } + + :lang(fi) h2 { + font-size: 1.95rem; + line-height: 1.08; + } + .bullet-grid, .card-grid, .table-row { From cc7cad66c79d6e45be17836d768e1d0c3ed418a4 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 18:32:48 +0300 Subject: [PATCH 253/287] docs(release): sync current candidate metadata --- .github/workflows/container-image.yml | 6 +-- CHANGELOG.md | 24 ++++++++++ docs/how-to/install-and-operate.md | 22 ++++----- docs/kubernetes.md | 2 +- docs/reference/production-exit-review.md | 4 +- .../production-gate-troubleshooting.md | 2 +- docs/reference/release-candidate.md | 4 +- docs/reference/release-evidence-index.md | 47 ++++++++++--------- docs/tutorials/evaluate-in-10-minutes.md | 2 +- docs/tutorials/getting-started.md | 2 +- .../end-to-end-release-evidence/README.md | 2 +- release/current.json | 34 ++++++++++++++ scripts/public_release_verify.sh | 4 +- 13 files changed, 109 insertions(+), 46 deletions(-) create mode 100644 release/current.json diff --git a/.github/workflows/container-image.yml b/.github/workflows/container-image.yml index 34d3931..1b05a3f 100644 --- a/.github/workflows/container-image.yml +++ b/.github/workflows/container-image.yml @@ -4,13 +4,13 @@ on: workflow_dispatch: inputs: ref: - description: "Git ref to build, such as v0.1.0-rc.5" + description: "Git ref to build, such as v0.1.0-rc.7" required: true - default: "v0.1.0-rc.5" + default: "v0.1.0-rc.7" image_tag: description: "OCI tag to publish" required: true - default: "v0.1.0-rc.5" + default: "v0.1.0-rc.7" permissions: contents: read diff --git a/CHANGELOG.md b/CHANGELOG.md index 957efb7..ef917b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,30 @@ results, no secure-release guarantee, and no regulator or auditor acceptance. - No unreleased changes. +## v0.1.0-rc.7 - 2026-06-01 + +Release status: controlled self-hosted production candidate. This prerelease is +suitable for evaluation, pilots, and controlled internal production after +operator review. Broad self-hosted production readiness, regulated production, +and hosted SaaS production remain out of scope for this status. + +### Fixed + +- Release artifact publication now uses the dedicated release publication token + path after signed release evidence is generated. +- The release-candidate evidence package includes signed archives, checksums, + OpenAPI and migration checksums, coverage output, production-check summary, + SBOM/provenance metadata, release notes, and a signed release manifest. + +### Known Limits + +- No tag-specific project-owned container image evidence is asserted for this + prerelease in the repository metadata; operators must verify a separately + published image digest or build/sign their own image for container + deployments. +- Multi-writer API HA remains outside the supported production profile; use one + API writer replica and scale workers through PostgreSQL outbox locking. + ## v0.1.0-rc.5 - 2026-06-01 Release status: controlled self-hosted production candidate. This prerelease is diff --git a/docs/how-to/install-and-operate.md b/docs/how-to/install-and-operate.md index a693f5b..8717d8a 100644 --- a/docs/how-to/install-and-operate.md +++ b/docs/how-to/install-and-operate.md @@ -3,7 +3,7 @@ Use this guide for a local self-hosted development or evaluation deployment. For operator evaluation, start from the current public release candidate -[`v0.1.0-rc.5`](https://github.com/aatuh/evydence/releases/tag/v0.1.0-rc.5). +[`v0.1.0-rc.7`](https://github.com/aatuh/evydence/releases/tag/v0.1.0-rc.7). Download the release archive for your platform, then verify `SHA256SUMS`, `openapi.sha256`, `migrations.sha256`, and the signed release manifest before starting the API or worker. Source checkout remains the local development path. @@ -25,15 +25,15 @@ Configuration details live in [Configuration](../reference/configuration.md). For a release-backed evaluation on Linux amd64: ```sh -mkdir -p dist/v0.1.0-rc.5 -gh release download v0.1.0-rc.5 --repo aatuh/evydence --dir dist/v0.1.0-rc.5 -(cd dist/v0.1.0-rc.5 && sha256sum -c SHA256SUMS) -(cd dist/v0.1.0-rc.5 && sha256sum -c openapi.sha256) -sha256sum -c dist/v0.1.0-rc.5/migrations.sha256 -tar -C dist/v0.1.0-rc.5 -xzf dist/v0.1.0-rc.5/evydence_v0.1.0-rc.5_linux_amd64.tar.gz -./dist/v0.1.0-rc.5/evydence_v0.1.0-rc.5_linux_amd64/evydence release verify \ - --manifest dist/v0.1.0-rc.5/evydence-release-manifest.json \ - --signature dist/v0.1.0-rc.5/evydence-release-manifest.sig.json +mkdir -p dist/v0.1.0-rc.7 +gh release download v0.1.0-rc.7 --repo aatuh/evydence --dir dist/v0.1.0-rc.7 +(cd dist/v0.1.0-rc.7 && sha256sum -c SHA256SUMS) +(cd dist/v0.1.0-rc.7 && sha256sum -c openapi.sha256) +sha256sum -c dist/v0.1.0-rc.7/migrations.sha256 +tar -C dist/v0.1.0-rc.7 -xzf dist/v0.1.0-rc.7/evydence_v0.1.0-rc.7_linux_amd64.tar.gz +./dist/v0.1.0-rc.7/evydence_v0.1.0-rc.7_linux_amd64/evydence release verify \ + --manifest dist/v0.1.0-rc.7/evydence-release-manifest.json \ + --signature dist/v0.1.0-rc.7/evydence-release-manifest.sig.json ``` Expected result: checksum verification exits successfully, manifest signature @@ -45,7 +45,7 @@ For the same verification from a clean temporary directory, use the checked helper: ```sh -make public-release-verify TAG=v0.1.0-rc.5 +make public-release-verify TAG=v0.1.0-rc.7 ``` Expected result: the helper downloads the public GitHub Release assets, diff --git a/docs/kubernetes.md b/docs/kubernetes.md index af6d4e0..7368642 100644 --- a/docs/kubernetes.md +++ b/docs/kubernetes.md @@ -39,7 +39,7 @@ Store real values in your secret manager or sealed-secret process. Do not commit ```sh helm upgrade --install evydence ./deploy/helm/evydence \ --set image.repository=ghcr.io/aatuh/evydence \ - --set image.tag=v0.1.0-rc.5@sha256:38188044a3e5ded3c6094564ab39ce989185f65e22cf4296985ec19ba0eb1888 \ + --set image.tag='@sha256:' \ --set env.s3Endpoint=s3.example.com \ --set env.s3Bucket=evydence ``` diff --git a/docs/reference/production-exit-review.md b/docs/reference/production-exit-review.md index 94da11f..455518a 100644 --- a/docs/reference/production-exit-review.md +++ b/docs/reference/production-exit-review.md @@ -25,7 +25,7 @@ SaaS-ready, legally compliant, certified, or secure-release-guaranteed. - Release-candidate packaging generates checksums, OpenAPI checksum, migration checksum, release SBOM metadata, release provenance metadata, release notes, signed manifest, and manifest signature. -- Public prerelease `v0.1.0-rc.5` is published with signed release archives, +- Public prerelease `v0.1.0-rc.7` is published with signed release archives, checksums, OpenAPI and migration checksums, coverage output, production-check summary, SBOM/provenance metadata, release notes, and signed release manifest. @@ -42,7 +42,7 @@ SaaS-ready, legally compliant, certified, or secure-release-guaranteed. `EVYDENCE_GHCR_PUBLISH_TOKEN` for GHCR publication, and scopes GitHub OIDC `id-token: write` to the keyless cosign signing job. - `make release-acceptance` and - `make public-release-verify TAG=v0.1.0-rc.5` have passed against the current + `make public-release-verify TAG=v0.1.0-rc.7` have passed against the current repository state. ## Remaining Exit Blockers diff --git a/docs/reference/production-gate-troubleshooting.md b/docs/reference/production-gate-troubleshooting.md index f1c3aa9..397e497 100644 --- a/docs/reference/production-gate-troubleshooting.md +++ b/docs/reference/production-gate-troubleshooting.md @@ -110,7 +110,7 @@ Symptom: package or public release verification fails. Verify the current public release-candidate package: ```sh -make public-release-verify TAG=v0.1.0-rc.5 +make public-release-verify TAG=v0.1.0-rc.7 ``` Verify the checked local package fixture: diff --git a/docs/reference/release-candidate.md b/docs/reference/release-candidate.md index a436c21..7c8a3c9 100644 --- a/docs/reference/release-candidate.md +++ b/docs/reference/release-candidate.md @@ -63,8 +63,8 @@ production, and hosted SaaS production require additional review and controls. ## Public Publication -The first public release candidate, -[`v0.1.0-rc.5`](https://github.com/aatuh/evydence/releases/tag/v0.1.0-rc.5), +The current public release candidate, +[`v0.1.0-rc.7`](https://github.com/aatuh/evydence/releases/tag/v0.1.0-rc.7), is published as a prerelease. Public release readiness requires a pushed tag, a completed release-artifacts workflow run, uploaded release archives, checksums, signed manifest files, release notes, and any configured repository or registry diff --git a/docs/reference/release-evidence-index.md b/docs/reference/release-evidence-index.md index 04fda10..2e15328 100644 --- a/docs/reference/release-evidence-index.md +++ b/docs/reference/release-evidence-index.md @@ -38,15 +38,15 @@ under `dist//` after `make production-check` passes. ## Current Public Release Candidate The current public release candidate is -[`v0.1.0-rc.5`](https://github.com/aatuh/evydence/releases/tag/v0.1.0-rc.5). -It was built from tag `v0.1.0-rc.5` at commit -`d5098c635ee7b171dac3a449ba7ca2e30d8b0c16`; the public Release Artifacts +[`v0.1.0-rc.7`](https://github.com/aatuh/evydence/releases/tag/v0.1.0-rc.7). +It was built from tag `v0.1.0-rc.7` at commit +`2f759100e723554e4e68e3ada712c923e391a17a`; the public Release Artifacts workflow run is -[`26752006813`](https://github.com/aatuh/evydence/actions/runs/26752006813). +[`26769039974`](https://github.com/aatuh/evydence/actions/runs/26769039974). The release commit also has a public CI `Production Check` run -[`26748345740`](https://github.com/aatuh/evydence/actions/runs/26748345740) +[`26767778491`](https://github.com/aatuh/evydence/actions/runs/26767778491) and CodeQL run -[`26748345664`](https://github.com/aatuh/evydence/actions/runs/26748345664). +[`26767778487`](https://github.com/aatuh/evydence/actions/runs/26767778487). The public prerelease includes release archives for Linux, macOS, and Windows; `SHA256SUMS`; `openapi.yaml`; `openapi.sha256`; `migrations.sha256`; @@ -54,30 +54,34 @@ The public prerelease includes release archives for Linux, macOS, and Windows; `evydence-release-provenance.json`; `evydence-release-provenance.intoto.jsonl`; `release-notes.md`; `evydence-release-manifest.json`; `evydence-release-manifest.sig.json`; and -`evydence-release-manifest.sig`. The release assets also include -`evydence-container-image-manifest.json` and -`evydence-container-image-cosign-verify.json` for the separately published -container image. +`evydence-release-manifest.sig`. -The current project-owned container image is +Project-owned container images are separate release evidence. At the time this +index was updated, the latest verified project-owned container image evidence +for the release-candidate line was `ghcr.io/aatuh/evydence:v0.1.0-rc.5@sha256:38188044a3e5ded3c6094564ab39ce989185f65e22cf4296985ec19ba0eb1888`. It was produced by the Container Image workflow run [`26752805538`](https://github.com/aatuh/evydence/actions/runs/26752805538) from release source commit `d5098c635ee7b171dac3a449ba7ca2e30d8b0c16`. +That image is not an `v0.1.0-rc.7` image. For `v0.1.0-rc.7`, use release +archives or publish and verify a tag-specific image before treating it as +deployment evidence. A tag-specific image workflow run should attach +`evydence-container-image-manifest.json` and +`evydence-container-image-cosign-verify.json` when available. ## Local Verification After packaging, verify the evidence directory before publishing: ```sh -gh release download v0.1.0-rc.5 --repo aatuh/evydence --dir dist/v0.1.0-rc.5 -(cd dist/v0.1.0-rc.5 && sha256sum -c SHA256SUMS) -(cd dist/v0.1.0-rc.5 && sha256sum -c openapi.sha256) -sha256sum -c dist/v0.1.0-rc.5/migrations.sha256 -tar -C dist/v0.1.0-rc.5 -xzf dist/v0.1.0-rc.5/evydence_v0.1.0-rc.5_linux_amd64.tar.gz -./dist/v0.1.0-rc.5/evydence_v0.1.0-rc.5_linux_amd64/evydence release verify \ - --manifest dist/v0.1.0-rc.5/evydence-release-manifest.json \ - --signature dist/v0.1.0-rc.5/evydence-release-manifest.sig.json +gh release download v0.1.0-rc.7 --repo aatuh/evydence --dir dist/v0.1.0-rc.7 +(cd dist/v0.1.0-rc.7 && sha256sum -c SHA256SUMS) +(cd dist/v0.1.0-rc.7 && sha256sum -c openapi.sha256) +sha256sum -c dist/v0.1.0-rc.7/migrations.sha256 +tar -C dist/v0.1.0-rc.7 -xzf dist/v0.1.0-rc.7/evydence_v0.1.0-rc.7_linux_amd64.tar.gz +./dist/v0.1.0-rc.7/evydence_v0.1.0-rc.7_linux_amd64/evydence release verify \ + --manifest dist/v0.1.0-rc.7/evydence-release-manifest.json \ + --signature dist/v0.1.0-rc.7/evydence-release-manifest.sig.json ``` Use the platform-specific `evydence` binary from the release archive whenever @@ -88,14 +92,15 @@ To verify the already-published public release from a clean temporary directory, run: ```sh -make public-release-verify TAG=v0.1.0-rc.5 +make public-release-verify TAG=v0.1.0-rc.7 ``` The helper downloads the release assets with `gh`, checks the public checksums, validates the in-toto statement shape, extracts the released Linux amd64 CLI, and verifies the signed manifest with that released binary. -To verify the public container image digest and workflow identity, run: +To verify the last checked public container image digest and workflow identity, +run: ```sh docker buildx imagetools inspect ghcr.io/aatuh/evydence:v0.1.0-rc.5 \ diff --git a/docs/tutorials/evaluate-in-10-minutes.md b/docs/tutorials/evaluate-in-10-minutes.md index c50ea77..166e595 100644 --- a/docs/tutorials/evaluate-in-10-minutes.md +++ b/docs/tutorials/evaluate-in-10-minutes.md @@ -21,7 +21,7 @@ guarantee. Start by verifying the release artifacts you would install or evaluate: ```sh -make public-release-verify TAG=v0.1.0-rc.5 +make public-release-verify TAG=v0.1.0-rc.7 ``` This downloads the public release-candidate evidence and checks the release diff --git a/docs/tutorials/getting-started.md b/docs/tutorials/getting-started.md index 1b1a391..9ff2218 100644 --- a/docs/tutorials/getting-started.md +++ b/docs/tutorials/getting-started.md @@ -3,7 +3,7 @@ This tutorial runs Evydence with in-process state and records a small release evidence flow. It is for local development only; data is lost when the process exits. For operator evaluation, prefer the current public release candidate -[`v0.1.0-rc.5`](https://github.com/aatuh/evydence/releases/tag/v0.1.0-rc.5) +[`v0.1.0-rc.7`](https://github.com/aatuh/evydence/releases/tag/v0.1.0-rc.7) and verify the release evidence before starting binaries. This tutorial remains the source-checkout local development path. The release artifact map is in [Release evidence index](../reference/release-evidence-index.md). diff --git a/examples/end-to-end-release-evidence/README.md b/examples/end-to-end-release-evidence/README.md index 48073e4..bd3116c 100644 --- a/examples/end-to-end-release-evidence/README.md +++ b/examples/end-to-end-release-evidence/README.md @@ -22,7 +22,7 @@ Before running a local API flow, verify the current public release-candidate assets from a clean temporary directory: ```sh -make public-release-verify TAG=v0.1.0-rc.5 +make public-release-verify TAG=v0.1.0-rc.7 ``` This proves the downloaded public archives, OpenAPI checksum, migration diff --git a/release/current.json b/release/current.json new file mode 100644 index 0000000..3385d51 --- /dev/null +++ b/release/current.json @@ -0,0 +1,34 @@ +{ + "schema": "evydence-current-release.v1", + "repository": "aatuh/evydence", + "current_public_release": { + "tag": "v0.1.0-rc.7", + "name": "Evydence v0.1.0-rc.7", + "status": "controlled self-hosted production candidate", + "published_at": "2026-06-01T17:00:46Z", + "release_date": "2026-06-01", + "release_url": "https://github.com/aatuh/evydence/releases/tag/v0.1.0-rc.7", + "source_commit": "2f759100e723554e4e68e3ada712c923e391a17a", + "release_artifacts_workflow_run": "26769039974", + "production_check_workflow_run": "26767778491", + "codeql_workflow_run": "26767778487", + "evidence_dir": "dist/v0.1.0-rc.7", + "release_notes_path": "dist/v0.1.0-rc.7/release-notes.md", + "openapi_checksum_path": "dist/v0.1.0-rc.7/openapi.sha256", + "migrations_checksum_path": "dist/v0.1.0-rc.7/migrations.sha256", + "release_manifest_path": "dist/v0.1.0-rc.7/evydence-release-manifest.json", + "release_manifest_signature_path": "dist/v0.1.0-rc.7/evydence-release-manifest.sig.json" + }, + "last_verified_project_image": { + "tag": "v0.1.0-rc.5", + "digest": "sha256:38188044a3e5ded3c6094564ab39ce989185f65e22cf4296985ec19ba0eb1888", + "workflow_run": "26752805538", + "source_commit": "d5098c635ee7b171dac3a449ba7ca2e30d8b0c16", + "status": "last verified project-owned image evidence for the release-candidate line" + }, + "notes": [ + "GitHub Releases remains the external source of truth for published tags and assets.", + "The current public release candidate may differ from the last verified project-owned container image because image publication is a separate workflow.", + "Release evidence is not legal compliance proof, certification, complete SBOM proof, authoritative vulnerability coverage, or a secure-release guarantee." + ] +} diff --git a/scripts/public_release_verify.sh b/scripts/public_release_verify.sh index 534c944..a46df7d 100755 --- a/scripts/public_release_verify.sh +++ b/scripts/public_release_verify.sh @@ -2,14 +2,14 @@ set -euo pipefail repo="${EVYDENCE_RELEASE_REPO:-aatuh/evydence}" -tag="${1:-${TAG:-v0.1.0-rc.5}}" +tag="${1:-${TAG:-v0.1.0-rc.7}}" if [[ ! "$repo" =~ ^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$ ]]; then echo "EVYDENCE_RELEASE_REPO must look like owner/name" >&2 exit 2 fi if [[ ! "$tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$ ]]; then - echo "release candidate tag must look like v0.1.0-rc.5" >&2 + echo "release candidate tag must look like v0.1.0-rc.7" >&2 exit 2 fi if ! command -v gh >/dev/null 2>&1; then From fa8aa3ef851f9e7d30c235f8215057d7c16a2dfe Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 18:32:56 +0300 Subject: [PATCH 254/287] docs(readme): clarify current production status --- README.md | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f25b56a..3ad477a 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,18 @@ questions with signed, customer-safe release evidence bundles. Website: +## Current Status + +- Best for: evaluation, pilots, and controlled internal self-hosted use after operator review. +- Not for: broad HA production, regulated production without review, hosted SaaS, or legal/compliance conclusions. +- Current public release candidate metadata is tracked in + [`release/current.json`](release/current.json); GitHub Releases remains the + external source of truth for published tags and assets. +- See [Production readiness](docs/reference/production-readiness.md), + [Pilot deployment checklist](docs/how-to/pilot-deployment-checklist.md), and + [Release evidence index](docs/reference/release-evidence-index.md) before + running beyond local evaluation. + The concrete buyer question is: "This CVE appears in your SBOM for this release. Are you affected, why or why not, who approved that decision, and what evidence can we verify?" Evydence records the SBOM, vulnerability scan, VEX or @@ -64,7 +76,7 @@ objects instead of unsupported prose: This repository contains a Go implementation under module `github.com/aatuh/evydence`. The current public release candidate is -[`v0.1.0-rc.5`](https://github.com/aatuh/evydence/releases/tag/v0.1.0-rc.5), +[`v0.1.0-rc.7`](https://github.com/aatuh/evydence/releases/tag/v0.1.0-rc.7), published as a prerelease with signed archives, checksums, OpenAPI and migration checksums, coverage output, production-check summary, SBOM/provenance metadata, release notes, and a signed release manifest. @@ -76,9 +88,10 @@ development path. Container images for the release-candidate line are published, when the maintainer image workflow has run for the tag, as `ghcr.io/aatuh/evydence:`. Treat the digest and cosign evidence as the -operator trust input, not the mutable tag alone. -For `v0.1.0-rc.5`, the published image is -`ghcr.io/aatuh/evydence:v0.1.0-rc.5@sha256:38188044a3e5ded3c6094564ab39ce989185f65e22cf4296985ec19ba0eb1888`. +operator trust input, not the mutable tag alone. The current public release +candidate metadata distinguishes release archive evidence from the last +verified project-owned image evidence because image publication is a separate +workflow. ## Fastest Proof Path @@ -102,14 +115,14 @@ package in the [local package viewer](docs/how-to/view-packages.md). Release-candidate artifacts and their verification commands are indexed in [Release evidence index](docs/reference/release-evidence-index.md). Start with -the public `v0.1.0-rc.5` release if you want to evaluate release verification +the public `v0.1.0-rc.7` release if you want to evaluate release verification before running the API. To verify the public release assets from a clean temporary directory on Linux amd64, run: ```sh -make public-release-verify TAG=v0.1.0-rc.5 +make public-release-verify TAG=v0.1.0-rc.7 ``` The VEX-first evidence flow to evaluate first is: From 7ed39ee3b730358a55dc08560fc3865449178423 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 18:33:02 +0300 Subject: [PATCH 255/287] test(release): check release truth drift --- Makefile | 15 ++-- scripts/check_release_truth.py | 132 +++++++++++++++++++++++++++++++++ scripts/release_acceptance.sh | 3 + 3 files changed, 141 insertions(+), 9 deletions(-) create mode 100755 scripts/check_release_truth.py diff --git a/Makefile b/Makefile index afaad2a..308722e 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ GOVULNCHECK_VERSION ?= v1.2.0 TAG ?= -.PHONY: help tools fmt lint vuln gosec test test-race fuzz-smoke coverage coverage-check openapi-check openapi-precision-check meta-check docs-check deploy-check sdk-check demo-check local-ci-simulation-check reviewer-package-workflow-check black-box-demo-check benchmark-check package-viewer-check marketing-site-check marketing-site-production-check restore-rehearsal-check fast-check finalize release-acceptance release-check production-check release-candidate-check public-release-verify migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean +.PHONY: help tools fmt lint vuln gosec test test-race fuzz-smoke coverage coverage-check openapi-check openapi-precision-check meta-check release-truth-check docs-check deploy-check sdk-check demo-check local-ci-simulation-check reviewer-package-workflow-check black-box-demo-check benchmark-check package-viewer-check marketing-site-check marketing-site-production-check restore-rehearsal-check fast-check finalize release-acceptance release-check production-check release-candidate-check public-release-verify migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean help: ## Show help @awk 'BEGIN {FS=":.*## "}; /^[a-zA-Z0-9_.-]+:.*## / { printf " %-18s %s\n", $$1, $$2 }' $(MAKEFILE_LIST) @@ -128,7 +128,10 @@ meta-check: ## Validate root legal, governance, support, and release-evidence me @grep -F 'backups' .dockerignore >/dev/null @grep -F '*.pem' .dockerignore >/dev/null -docs-check: meta-check ## Validate canonical docs exist and avoid forbidden product claims +release-truth-check: ## Validate current release metadata against public docs and helper defaults + @scripts/check_release_truth.py + +docs-check: meta-check release-truth-check ## Validate canonical docs exist and avoid forbidden product claims @test -f README.md @test -f docs/README.md @test -f docs/architecture.md @@ -240,22 +243,16 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'This CVE appears in your SBOM. Are you affected, why, who approved it, and' docs/tutorials/evaluate-in-10-minutes.md >/dev/null @grep -F 'sample-customer-package-manifest.json' docs/tutorials/evaluate-in-10-minutes.md >/dev/null @grep -F 'site/package-viewer/index.html' docs/tutorials/evaluate-in-10-minutes.md >/dev/null - @grep -F 'make public-release-verify TAG=v0.1.0-rc.5' docs/tutorials/evaluate-in-10-minutes.md >/dev/null @grep -F 'examples/end-to-end-release-evidence/run-local-demo.sh' docs/tutorials/evaluate-in-10-minutes.md >/dev/null @grep -F 'Evaluate Evydence in 10 minutes' README.md docs/README.md >/dev/null - @grep -F 'make public-release-verify TAG=v0.1.0-rc.5' README.md >/dev/null @grep -F 'Capability map' README.md docs/README.md >/dev/null @grep -F 'Implemented-But-Partial Areas' docs/reference/capability-map.md >/dev/null @grep -F 'VEX/manual' README.md >/dev/null - @grep -F 'make public-release-verify TAG=v0.1.0-rc.5' docs/how-to/install-and-operate.md >/dev/null - @grep -F 'make public-release-verify TAG=v0.1.0-rc.5' docs/reference/release-evidence-index.md >/dev/null - @grep -F 'make public-release-verify TAG=v0.1.0-rc.5' examples/end-to-end-release-evidence/README.md >/dev/null @test -f docs/assets/package-viewer-preview.svg @grep -F 'package-viewer-preview.svg' docs/how-to/view-packages.md >/dev/null @grep -F 'report.html' docs/reference/customer-package-manifest.md docs/how-to/view-packages.md >/dev/null @grep -F 'Redaction Leakage Guard' docs/reference/customer-package-manifest.md >/dev/null @grep -F 'reviewer_checklist' docs/reference/customer-package-manifest.md >/dev/null - @grep -F 'v0.1.0-rc.5 - 2026-06-01' CHANGELOG.md >/dev/null @grep -F 'make restore-rehearsal-check' docs/runbooks/backup-restore.md >/dev/null @test -f docs/how-to/pilot-deployment-checklist.md @grep -F 'Required: external PostgreSQL' docs/how-to/pilot-deployment-checklist.md >/dev/null @@ -310,7 +307,7 @@ docs-check: meta-check ## Validate canonical docs exist and avoid forbidden prod @grep -F 'ghcr.io/aatuh/evydence' docs/reference/release-evidence-index.md >/dev/null @grep -F 'ghcr.io/aatuh/evydence' docs/kubernetes.md >/dev/null @grep -F 'ghcr.io/aatuh/evydence' deploy/airgap/manifest.yaml >/dev/null - @grep -F 'sha256:38188044a3e5ded3c6094564ab39ce989185f65e22cf4296985ec19ba0eb1888' docs/reference/release-evidence-index.md docs/kubernetes.md deploy/airgap/manifest.yaml >/dev/null + @grep -F 'sha256:38188044a3e5ded3c6094564ab39ce989185f65e22cf4296985ec19ba0eb1888' docs/reference/release-evidence-index.md deploy/airgap/manifest.yaml >/dev/null @grep -F 'cosign verify' docs/reference/release-evidence-index.md >/dev/null @grep -F 'github/codeql-action/init@7211b7c8077ea37d8641b6271f6a365a22a5fbfa' .github/workflows/codeql.yml >/dev/null @grep -F 'security-and-quality' .github/workflows/codeql.yml >/dev/null diff --git a/scripts/check_release_truth.py b/scripts/check_release_truth.py new file mode 100755 index 0000000..44ffa5e --- /dev/null +++ b/scripts/check_release_truth.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python3 +"""Validate public docs and helper defaults against release/current.json.""" + +from __future__ import annotations + +import json +import re +import sys +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +METADATA_PATH = ROOT / "release/current.json" + + +def read(path: str) -> str: + return (ROOT / path).read_text(encoding="utf-8") + + +def require(condition: bool, message: str, failures: list[str]) -> None: + if not condition: + failures.append(message) + + +def require_text(path: str, text: str, failures: list[str]) -> None: + content = read(path) + require(text in content, f"{path} missing release-truth text: {text}", failures) + + +def reject_current_stale(path: str, stale_tags: set[str], failures: list[str]) -> None: + content = read(path) + found = sorted(tag for tag in stale_tags if tag in content) + require(not found, f"{path} contains stale current-release tag(s): {', '.join(found)}", failures) + + +def main() -> int: + metadata = json.loads(METADATA_PATH.read_text(encoding="utf-8")) + current = metadata["current_public_release"] + image = metadata["last_verified_project_image"] + tag = current["tag"] + repo = metadata["repository"] + release_date = current["release_date"] + release_url = current["release_url"] + commit = current["source_commit"] + release_run = current["release_artifacts_workflow_run"] + ci_run = current["production_check_workflow_run"] + codeql_run = current["codeql_workflow_run"] + image_tag = image["tag"] + image_digest = image["digest"] + + failures: list[str] = [] + require(metadata.get("schema") == "evydence-current-release.v1", "release/current.json has unexpected schema", failures) + require(re.fullmatch(r"v\d+\.\d+\.\d+-rc\.\d+", tag) is not None, f"invalid current release tag: {tag}", failures) + require(re.fullmatch(r"\d{4}-\d{2}-\d{2}", release_date) is not None, f"invalid release date: {release_date}", failures) + require(re.fullmatch(r"[0-9a-f]{40}", commit) is not None, f"invalid source commit: {commit}", failures) + + current_command = f"make public-release-verify TAG={tag}" + release_link = f"[`{tag}`]({release_url})" + + required_current_refs = { + "README.md": [ + "Current Status", + "Best for: evaluation, pilots, and controlled internal self-hosted use after operator review.", + release_link, + current_command, + ], + "docs/tutorials/evaluate-in-10-minutes.md": [current_command], + "docs/tutorials/getting-started.md": [release_link], + "docs/how-to/install-and-operate.md": [ + release_link, + f"mkdir -p dist/{tag}", + f"gh release download {tag} --repo {repo} --dir dist/{tag}", + current_command, + ], + "docs/reference/release-evidence-index.md": [ + release_link, + f"tag `{tag}` at commit", + commit, + release_run, + ci_run, + codeql_run, + f"gh release download {tag} --repo {repo} --dir dist/{tag}", + current_command, + ], + "docs/reference/release-candidate.md": [release_link], + "docs/reference/production-exit-review.md": [tag, current_command], + "docs/reference/production-gate-troubleshooting.md": [current_command], + "examples/end-to-end-release-evidence/README.md": [current_command], + ".github/workflows/container-image.yml": [ + f"such as {tag}", + f'default: "{tag}"', + ], + "scripts/public_release_verify.sh": [ + f'TAG:-{tag}', + f"release candidate tag must look like {tag}", + ], + "CHANGELOG.md": [f"## {tag} - {release_date}"], + } + + for path, texts in required_current_refs.items(): + for text in texts: + require_text(path, text, failures) + + stale_tags = {"v0.1.0-rc.1", "v0.1.0-rc.2", "v0.1.0-rc.3", "v0.1.0-rc.4", "v0.1.0-rc.5", "v0.1.0-rc.6"} - {tag} + for path in [ + "README.md", + "docs/tutorials/evaluate-in-10-minutes.md", + "docs/tutorials/getting-started.md", + "docs/how-to/install-and-operate.md", + "docs/reference/production-exit-review.md", + "docs/reference/production-gate-troubleshooting.md", + "examples/end-to-end-release-evidence/README.md", + ".github/workflows/container-image.yml", + "scripts/public_release_verify.sh", + ]: + reject_current_stale(path, stale_tags, failures) + + require_text("docs/reference/release-evidence-index.md", image_tag, failures) + require_text("docs/reference/release-evidence-index.md", image_digest, failures) + require_text("deploy/airgap/manifest.yaml", image_tag, failures) + require_text("deploy/airgap/manifest.yaml", image_digest, failures) + + if failures: + for failure in failures: + print(f"release-truth-check: {failure}", file=sys.stderr) + return 1 + print(f"release-truth-check: passed ({tag})") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/release_acceptance.sh b/scripts/release_acceptance.sh index b2dfd2b..e74ad74 100755 --- a/scripts/release_acceptance.sh +++ b/scripts/release_acceptance.sh @@ -48,6 +48,8 @@ for file in \ .github/pull_request_template.md \ .github/workflows/codeql.yml \ .github/workflows/container-image.yml \ + release/current.json \ + scripts/check_release_truth.py \ README.md \ docs/README.md \ docs/reference/release-candidate.md \ @@ -146,6 +148,7 @@ require_text README.md "License, Security, Support, And Governance" require_text README.md "AGPL-3.0-only" require_text docs/README.md "Security policy" require_text docs/README.md "Release evidence" +scripts/check_release_truth.py reject_text "automatically compliant" reject_text "certified secure" From d0770a123aff2b9d9fa79f1540372d7ee8e4ac27 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 18:35:04 +0300 Subject: [PATCH 256/287] chore(deploy): pin production-like compose images --- Makefile | 4 ++++ compose.production-like.yml | 6 +++--- docs/how-to/install-and-operate.md | 4 +++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 308722e..16995c6 100644 --- a/Makefile +++ b/Makefile @@ -340,6 +340,10 @@ deploy-check: ## Validate deployment and air-gap skeletons exist @test -f deploy/airgap/manifest.yaml @test -f deploy/observability/prometheus-rules.yaml @test -f deploy/observability/grafana-dashboard.json + @grep -F 'postgres:16-alpine@sha256:16bc17c64a573ef34162af9298258d1aec548232985b33ed7b1eac33ba35c229' compose.production-like.yml >/dev/null + @grep -F 'minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e' compose.production-like.yml >/dev/null + @grep -F 'minio/mc@sha256:a7fe349ef4bd8521fb8497f55c6042871b2ae640607cf99d9bede5e9bdf11727' compose.production-like.yml >/dev/null + @! grep -E 'image:[[:space:]]+[^$$]*:latest' compose.production-like.yml >/dev/null @grep -F 'tag: ""' deploy/helm/evydence/values.yaml >/dev/null @grep -F 'replicas: 1' deploy/helm/evydence/values.yaml >/dev/null @grep -F 'writerMode: single' deploy/helm/evydence/values.yaml >/dev/null diff --git a/compose.production-like.yml b/compose.production-like.yml index bddf4e9..471a09a 100644 --- a/compose.production-like.yml +++ b/compose.production-like.yml @@ -7,7 +7,7 @@ services: postgres: - image: postgres:16-alpine + image: postgres:16-alpine@sha256:16bc17c64a573ef34162af9298258d1aec548232985b33ed7b1eac33ba35c229 environment: POSTGRES_DB: ${POSTGRES_DB:-evydence} POSTGRES_USER: ${POSTGRES_USER:-evydence} @@ -23,7 +23,7 @@ services: retries: 20 minio: - image: minio/minio:latest + image: minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: ${MINIO_ROOT_USER:-evydence} @@ -35,7 +35,7 @@ services: - minio-data:/data minio-init: - image: minio/mc:latest + image: minio/mc@sha256:a7fe349ef4bd8521fb8497f55c6042871b2ae640607cf99d9bede5e9bdf11727 depends_on: minio: condition: service_started diff --git a/docs/how-to/install-and-operate.md b/docs/how-to/install-and-operate.md index 8717d8a..2f6bc12 100644 --- a/docs/how-to/install-and-operate.md +++ b/docs/how-to/install-and-operate.md @@ -78,7 +78,9 @@ For a fuller local rehearsal, use `compose.production-like.yml`. It starts PostgreSQL, MinIO, bucket initialization, migrations, one API writer, and one worker. It is still a local evaluation stack: replace every secret, use TLS at the edge, back up PostgreSQL and object storage together, and keep production -API writer replicas at one for the current supported profile. +API writer replicas at one for the current supported profile. PostgreSQL and +MinIO service images in this production-like file are digest-pinned so the +rehearsal does not pull floating `latest` dependencies. ```sh export POSTGRES_PASSWORD='replace-with-long-random-password' From ae1107b1e6e8bd6e090bce37668b0467e5bc6760 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 18:37:29 +0300 Subject: [PATCH 257/287] docs(release): expose production check evidence --- Makefile | 3 +++ README.md | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/Makefile b/Makefile index 16995c6..ddaa7fc 100644 --- a/Makefile +++ b/Makefile @@ -246,6 +246,9 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and @grep -F 'examples/end-to-end-release-evidence/run-local-demo.sh' docs/tutorials/evaluate-in-10-minutes.md >/dev/null @grep -F 'Evaluate Evydence in 10 minutes' README.md docs/README.md >/dev/null @grep -F 'Capability map' README.md docs/README.md >/dev/null + @grep -F 'Production Check' README.md docs/reference/release-evidence-index.md >/dev/null + @grep -F 'coverage.out' README.md docs/reference/release-evidence-index.md >/dev/null + @grep -F 'release-check-summary.txt' README.md docs/reference/release-evidence-index.md >/dev/null @grep -F 'Implemented-But-Partial Areas' docs/reference/capability-map.md >/dev/null @grep -F 'VEX/manual' README.md >/dev/null @test -f docs/assets/package-viewer-preview.svg diff --git a/README.md b/README.md index 3ad477a..831ad23 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,10 @@ Website: - Current public release candidate metadata is tracked in [`release/current.json`](release/current.json); GitHub Releases remains the external source of truth for published tags and assets. +- Current release evidence links the Release Artifacts workflow, public CI + `Production Check` workflow run, CodeQL run, `coverage.out`, and + `release-check-summary.txt` from the + [Release evidence index](docs/reference/release-evidence-index.md). - See [Production readiness](docs/reference/production-readiness.md), [Pilot deployment checklist](docs/how-to/pilot-deployment-checklist.md), and [Release evidence index](docs/reference/release-evidence-index.md) before From 8badaf810250bf7f65924fa3fc2c31e8fa6b14a8 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 18:46:28 +0300 Subject: [PATCH 258/287] docs(release): define stable exit criteria --- Makefile | 6 + docs/README.md | 1 + docs/reference/production-exit-review.md | 6 +- docs/reference/production-readiness.md | 6 +- docs/reference/release-validation.md | 5 + docs/reference/roadmap.md | 3 + docs/reference/source-of-truth.md | 2 +- docs/reference/stable-v0.1.0-exit-criteria.md | 149 ++++++++++++++++++ 8 files changed, 174 insertions(+), 4 deletions(-) create mode 100644 docs/reference/stable-v0.1.0-exit-criteria.md diff --git a/Makefile b/Makefile index ddaa7fc..1ddb2eb 100644 --- a/Makefile +++ b/Makefile @@ -157,6 +157,7 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and @test -f docs/reference/benchmark-results.md @test -f docs/reference/production-readiness.md @test -f docs/reference/production-exit-review.md + @test -f docs/reference/stable-v0.1.0-exit-criteria.md @test -f docs/reference/external-controls-matrix.md @test -f docs/reference/production-gate-troubleshooting.md @test -f docs/reference/release-candidate.md @@ -204,6 +205,7 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and "reference/benchmark-results.md" \ "reference/production-readiness.md" \ "reference/production-exit-review.md" \ + "reference/stable-v0.1.0-exit-criteria.md" \ "reference/external-controls-matrix.md" \ "reference/production-gate-troubleshooting.md" \ "reference/release-candidate.md" \ @@ -261,6 +263,10 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and @grep -F 'Required: external PostgreSQL' docs/how-to/pilot-deployment-checklist.md >/dev/null @grep -F 'external controls matrix' docs/reference/production-readiness.md docs/kubernetes.md docs/how-to/pilot-deployment-checklist.md >/dev/null @grep -F 'Production gate troubleshooting' docs/reference/production-readiness.md docs/reference/release-validation.md docs/README.md >/dev/null + @grep -F 'Stable v0.1.0 exit criteria' docs/reference/production-readiness.md docs/reference/release-validation.md docs/reference/production-exit-review.md docs/reference/roadmap.md docs/README.md >/dev/null + @grep -F 'not legal compliance proof' docs/reference/stable-v0.1.0-exit-criteria.md >/dev/null + @grep -F 'make public-release-verify TAG=' docs/reference/stable-v0.1.0-exit-criteria.md >/dev/null + @grep -F 'one API writer replica' docs/reference/stable-v0.1.0-exit-criteria.md >/dev/null @grep -F 'Required: object paths are tenant-prefixed' docs/how-to/pilot-deployment-checklist.md >/dev/null @grep -F 'Required: public API access is behind TLS' docs/how-to/pilot-deployment-checklist.md >/dev/null @test -f docs/commercial/design-partner-pilot.md diff --git a/docs/README.md b/docs/README.md index dffa2f5..7232635 100644 --- a/docs/README.md +++ b/docs/README.md @@ -39,6 +39,7 @@ This documentation is organized by reader task. Implementation claims should be - [Benchmark results](reference/benchmark-results.md): current local benchmark command and interpretation. - [Production readiness](reference/production-readiness.md): self-hosted production profiles, production gates, and exit criteria. - [Production exit review](reference/production-exit-review.md): current release-positioning decision and unresolved blockers. +- [Stable v0.1.0 exit criteria](reference/stable-v0.1.0-exit-criteria.md): criteria for moving from release candidate to a stable `v0.1.0` tag. - [External controls matrix](reference/external-controls-matrix.md): owner boundaries for regulated or high-trust self-hosted deployments. - [Production gate troubleshooting](reference/production-gate-troubleshooting.md): safe diagnostics for `make production-check` failures. - [Release candidate checklist](reference/release-candidate.md): required evidence before tagging a controlled self-hosted release candidate. diff --git a/docs/reference/production-exit-review.md b/docs/reference/production-exit-review.md index 455518a..b833a75 100644 --- a/docs/reference/production-exit-review.md +++ b/docs/reference/production-exit-review.md @@ -75,5 +75,7 @@ and internal production after operator review. The productization audit closeout in `.audits/production_readiness_v2/` and `.audits/product_code_audit_v4/` supports keeping this controlled candidate status, not strengthening it. It should not be marketed as broad production-ready for most uses until the -external controls above are closed and a fresh product, codebase, security, -documentation, and test audit confirms the change. +external controls above are closed, the +[Stable v0.1.0 exit criteria](stable-v0.1.0-exit-criteria.md) pass for a +concrete candidate, and a fresh product, codebase, security, documentation, and +test audit confirms the change. diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index f564e3a..42a2f80 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -145,7 +145,9 @@ The gate requires: Release-candidate tagging additionally requires the evidence set in [Release candidate checklist](release-candidate.md), including OpenAPI and migration checksums, signed artifact manifests, artifact checksums, and release -notes with limitations. +notes with limitations. Moving from the release-candidate line to stable +`v0.1.0` additionally requires +[Stable v0.1.0 exit criteria](stable-v0.1.0-exit-criteria.md). The default production coverage threshold is 80 percent and the gate requires `EVYDENCE_TEST_DATABASE_URL` so live PostgreSQL adapter tests are included: @@ -186,6 +188,8 @@ Do not describe an Evydence build as broadly self-hosted production-ready until: - the HA story for the target profile is documented and reviewed; - production hardening review is current; - production exit review is current; +- stable `v0.1.0` exit criteria pass when moving out of the release-candidate + line; - unresolved limitations are documented in release notes. ## Remaining Production Maturity Backlog diff --git a/docs/reference/release-validation.md b/docs/reference/release-validation.md index 9f25429..499a27d 100644 --- a/docs/reference/release-validation.md +++ b/docs/reference/release-validation.md @@ -198,3 +198,8 @@ with the release-candidate package script whenever the artifact set changes. These artifacts support reproducible engineering review. They are not legal compliance proof, certification, a secure-release guarantee, complete SBOM proof, or authoritative vulnerability coverage. + +Before promoting the release-candidate line to a stable `v0.1.0` tag, also use +[Stable v0.1.0 exit criteria](stable-v0.1.0-exit-criteria.md). That reference +records the extra release evidence, documentation alignment, and hard blockers +for leaving the candidate line. diff --git a/docs/reference/roadmap.md b/docs/reference/roadmap.md index 5a97457..a3c3211 100644 --- a/docs/reference/roadmap.md +++ b/docs/reference/roadmap.md @@ -50,6 +50,9 @@ status. Release candidates should be cut only after `make production-check` and the release-candidate evidence package pass. Public releases should include a clear support window, upgrade notes, limitations, and known unresolved hardening work. +Stable `v0.1.0` should be tagged only after +[Stable v0.1.0 exit criteria](stable-v0.1.0-exit-criteria.md) pass for the +candidate being promoted. Community contributions remain selective until the public release, security intake, branch protection, and review enforcement surfaces are stable. diff --git a/docs/reference/source-of-truth.md b/docs/reference/source-of-truth.md index 34b6040..9874e02 100644 --- a/docs/reference/source-of-truth.md +++ b/docs/reference/source-of-truth.md @@ -14,7 +14,7 @@ product-boundary language across the docs. | Release validation | `docs/reference/release-validation.md` | Canonical release gate behavior. | | Release-candidate evidence | `docs/reference/release-candidate.md` | Canonical release-candidate artifact checklist. | | Release evidence artifact map | `docs/reference/release-evidence-index.md` | Maps each release artifact to generation and verification commands. | -| Production profiles and exit criteria | `docs/reference/production-readiness.md` and `docs/reference/production-exit-review.md` | Do not broaden status elsewhere without updating these. | +| Production profiles and exit criteria | `docs/reference/production-readiness.md`, `docs/reference/production-exit-review.md`, and `docs/reference/stable-v0.1.0-exit-criteria.md` | Do not broaden status elsewhere without updating these. | | Design-partner pilot checklist | `docs/how-to/pilot-deployment-checklist.md` | Narrow copy-paste checklist for one controlled self-hosted pilot profile. | | Maintainer review ownership | `CODEOWNERS` and `docs/reference/maintainer-review-policy.md` | Branch protection or repository rules must enforce this before it is a merge gate. | | Roadmap and cadence | `docs/reference/roadmap.md` | Public roadmap, supported release line, and cadence expectations. | diff --git a/docs/reference/stable-v0.1.0-exit-criteria.md b/docs/reference/stable-v0.1.0-exit-criteria.md new file mode 100644 index 0000000..a226553 --- /dev/null +++ b/docs/reference/stable-v0.1.0-exit-criteria.md @@ -0,0 +1,149 @@ +# Stable v0.1.0 Exit Criteria + +This reference defines the criteria for moving Evydence from the public +release-candidate line to a stable `v0.1.0` tag. It is an engineering and +operator-readiness decision record, not legal compliance proof, certification, +complete SBOM proof, authoritative vulnerability coverage, or a secure-release +guarantee. + +## Decision Rule + +Do not tag stable `v0.1.0` unless all repo-owned gates in this document pass, +the current release evidence is public and reproducible, and unresolved +limitations are explicitly carried into release notes and status docs. + +Stable `v0.1.0` may still be scoped to controlled self-hosted use. It must not +be used to claim broad production readiness, regulated production readiness, +hosted SaaS readiness, legal compliance, certification, complete vulnerability +detection, complete SBOM coverage, or guaranteed release security. + +## Required Repo-Owned Gates + +Run these gates from a clean checkout for the release candidate that will be +promoted: + +```sh +make production-check +make release-acceptance +make public-release-verify TAG= +make docs-check +make finalize +``` + +`make production-check` must run with `EVYDENCE_TEST_DATABASE_URL` set to a +disposable PostgreSQL database and must not record skipped live PostgreSQL +checks. The production-check evidence must include coverage threshold output, +live PostgreSQL integration results, migration compatibility, backup/restore +rehearsal, black-box restart persistence, release signing smoke evidence, race +tests, OpenAPI drift checks, docs checks, deployment checks, SDK checks, lint, +gosec, and govulncheck. + +`make public-release-verify TAG=` must verify the public release +candidate artifact set before the stable tag is created. If public artifacts +are missing, stale, unsigned, or unverifiable, stable tagging is blocked. + +## Required Release Evidence + +The candidate promoted to stable must have a public release evidence set with: + +- release archives for the supported target matrix; +- `SHA256SUMS`; +- `openapi.yaml` and `openapi.sha256`; +- `migrations.sha256`; +- `coverage.out`; +- `release-check-summary.txt`; +- release SBOM metadata and release provenance metadata; +- signed `evydence-release-manifest.json`; +- `evydence-release-manifest.sig.json` and the compatibility + `evydence-release-manifest.sig` alias; +- release notes with supported profile, install and upgrade notes, assumptions, + limitations, unresolved hardening work, and explicit non-claims; +- links to the CI production-check run, release-artifacts workflow run, CodeQL + workflow status, and Scorecard evidence where those services are available. + +Project-owned container images are stable release evidence only after the +container-image workflow has run for the same tag and produced digest plus +signing evidence. Until then, release archives remain the supported install +source for the stable line. + +## Required Documentation Alignment + +Before tagging stable, these sources must agree on the current tag, commit, +workflow run, supported profile, and limitations: + +- `release/current.json`; +- `README.md`; +- `CHANGELOG.md`; +- `RELEASE_EVIDENCE.md`; +- `docs/reference/release-evidence-index.md`; +- `docs/reference/production-readiness.md`; +- `docs/reference/production-exit-review.md`; +- `docs/reference/release-validation.md`; +- `docs/reference/release-candidate.md`; +- `docs/how-to/install-and-operate.md`; +- `docs/tutorials/evaluate-in-10-minutes.md`; +- release notes for the promoted tag. + +Run `scripts/check_release_truth.py` after any release metadata edit. The +stable tag is blocked if public docs, helper defaults, or release metadata +disagree. + +## Hard Blockers + +Do not tag stable `v0.1.0` while any of these repo-local conditions exist: + +- `make production-check`, `make release-acceptance`, `make docs-check`, or + `make finalize` fails; +- live PostgreSQL checks are skipped in production-check evidence; +- coverage is below the configured threshold; +- release evidence is missing, unsigned, stale, or not publicly verifiable; +- OpenAPI, migration, SDK, deployment, docs, or release-truth drift checks fail; +- backup/restore rehearsal, migration compatibility, or black-box restart + persistence checks fail; +- release notes omit unresolved limitations or use prohibited compliance, + certification, complete-SBOM, scanner-authority, or secure-release language; +- the supported one API writer replica stance is unclear or contradicted by + Helm, Compose, README, production readiness, or release notes; +- public release artifacts and `release/current.json` point at different tags, + commits, or workflow runs. + +External provider and account checks can also block stronger public claims. +Private vulnerability reporting, branch protection, required checks, secret +scanning, push protection, Dependabot security updates, CodeQL, Scorecard, +publication credentials, external security review, design-partner proof, and +provider-specific KMS/HSM/object-lock verification must be either verified for +the target deployment or listed as external limitations. Do not treat repository +source alone as proof of those controls. + +## Limitations That May Remain + +Stable `v0.1.0` may keep these limitations if they are visible in release +notes, production readiness, and the production exit review: + +- one API writer replica is the supported production profile; +- multi-writer API high availability and hosted SaaS production are out of + scope; +- regulated production needs operator, legal, provider, retention, signing, + SSO, and object-lock review outside repository source; +- provider-specific KMS/HSM, object-lock, transparency, SSO/group-sync, and + external security review evidence depends on the operator or provider; +- release evidence supports reproducibility and engineering review, not + compliance conclusions, certification, complete scanner coverage, or secure + release claims. + +## Stable Release Decision Record + +When stable criteria are met, update +`docs/reference/production-exit-review.md` with: + +- the stable tag and commit; +- release evidence links and workflow run identifiers; +- production-check and public-release verification results; +- supported deployment profile; +- unresolved limitations; +- external controls that remain operator responsibilities; +- explicit non-claims. + +Do not remove this reference after stable tagging. Use it as the regression +checklist for subsequent patch releases until a new release profile supersedes +it. From f0665b62ed0b944f20b1094e59f5e615b9fd0750 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 18:49:06 +0300 Subject: [PATCH 259/287] docs(packages): add package viewer screenshots --- Makefile | 11 ++++++ README.md | 3 +- docs/assets/package-viewer-desktop.png | Bin 0 -> 132872 bytes docs/assets/package-viewer-mobile.png | Bin 0 -> 55822 bytes docs/how-to/view-packages.md | 17 +++++++++ scripts/capture_package_viewer_screenshots.sh | 34 ++++++++++++++++++ 6 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 docs/assets/package-viewer-desktop.png create mode 100644 docs/assets/package-viewer-mobile.png create mode 100755 scripts/capture_package_viewer_screenshots.sh diff --git a/Makefile b/Makefile index 1ddb2eb..84bba02 100644 --- a/Makefile +++ b/Makefile @@ -254,7 +254,12 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and @grep -F 'Implemented-But-Partial Areas' docs/reference/capability-map.md >/dev/null @grep -F 'VEX/manual' README.md >/dev/null @test -f docs/assets/package-viewer-preview.svg + @test -f docs/assets/package-viewer-desktop.png + @test -f docs/assets/package-viewer-mobile.png @grep -F 'package-viewer-preview.svg' docs/how-to/view-packages.md >/dev/null + @grep -F 'package-viewer-desktop.png' docs/how-to/view-packages.md >/dev/null + @grep -F 'package-viewer-mobile.png' docs/how-to/view-packages.md >/dev/null + @grep -F 'scripts/capture_package_viewer_screenshots.sh' docs/how-to/view-packages.md >/dev/null @grep -F 'report.html' docs/reference/customer-package-manifest.md docs/how-to/view-packages.md >/dev/null @grep -F 'Redaction Leakage Guard' docs/reference/customer-package-manifest.md >/dev/null @grep -F 'reviewer_checklist' docs/reference/customer-package-manifest.md >/dev/null @@ -420,6 +425,9 @@ benchmark-check: ## Run the checked app-layer release evidence benchmark package-viewer-check: ## Validate local package viewer and walkthrough @test -f site/package-viewer/index.html @test -f docs/how-to/view-packages.md + @test -x scripts/capture_package_viewer_screenshots.sh + @test -f docs/assets/package-viewer-desktop.png + @test -f docs/assets/package-viewer-mobile.png @test -f docs/assets/reviewer-journey.svg @grep -F 'Load bundled demo' site/package-viewer/index.html >/dev/null @grep -F 'textContent' site/package-viewer/index.html >/dev/null @@ -432,6 +440,9 @@ package-viewer-check: ## Validate local package viewer and walkthrough @grep -F 'review_due_at' site/package-viewer/index.html >/dev/null @grep -F 'sbom_component_purl' site/package-viewer/index.html >/dev/null @grep -F 'examples/end-to-end-release-evidence/sample-customer-package-manifest.json' docs/how-to/view-packages.md >/dev/null + @grep -F 'package-viewer-desktop.png' docs/how-to/view-packages.md >/dev/null + @grep -F 'package-viewer-mobile.png' docs/how-to/view-packages.md >/dev/null + @grep -F 'not package verification evidence' docs/how-to/view-packages.md >/dev/null @grep -F 'reviewer-journey.svg' docs/how-to/view-packages.md >/dev/null @grep -F 'hash/signature verification' docs/how-to/view-packages.md >/dev/null @grep -F 'Release Summary' docs/assets/reviewer-journey.svg >/dev/null diff --git a/README.md b/README.md index 831ad23..9224c81 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,8 @@ The VEX-first evidence flow to evaluate first is: For a visual preview of the customer-package review surface, see the [package viewer guide](docs/how-to/view-packages.md). The preview uses -non-sensitive sample data and does not upload files. +non-sensitive bundled sample data, includes desktop and mobile screenshots, and +does not upload files. ## Why Evydence Instead Of Existing Tools? diff --git a/docs/assets/package-viewer-desktop.png b/docs/assets/package-viewer-desktop.png new file mode 100644 index 0000000000000000000000000000000000000000..8a5dc39584403f4b8971362bcc251e4d6760a523 GIT binary patch literal 132872 zcmeEt^LJeBA8p#G4co?UY^!l&Yof-DZM%(an-klb*mfqiZRgJWzW4h_+_mocY1Ub1 zopt8H-utsZ`w3By6GukCMSy~WLY9;e0YE{)W2$b9+;xwFBVHw^{#1xivxP}w#8 zWEJ)ox+Wg{MNX?=etf*L0?gOeFRiWHORH|DXLn1htMoLO-!UWn|M)v{dY+$cGyxbm zyx-SrC-_ZF3Z3syM$_+mg9}aem>_Td_ew~ig8sih6^4jAKm6}D;Ya-c-9G&PxBnZe z|EIuKwmXk3z0BR%qCE&LdL3t*j#!Sg)cKmSLn|=|sNNqfGdstM5^RAhvPqjVV zx6UNblS}uwCv-65;sP7X;wg|Y5G&edMpa)T{rkzv-k)rtUYHc8m=P1p`0QWsp#_wV zRb`tUb#&G;o-2&T+!l7PHR)5?qGJ+){syltS6B8YBBG*?fsxMtd&5EQ6_5HtO>|Nm zEtj@3%-=$R3?MMDI>%d2PtR3E*|itGt5LOldGFx2g{eZu->jaxKt*H&zdtU-C(=pq zQLT=S3|wiI>#fm~OlL-=iK3_cH;#4Z>%7++Q%YaI#`Gf-%ql0~{QJ2@FJCquGWJH3 zf16m0ygo+BSb)!Qp6wm0*6 z$cWMBkX*~?Ap&spW}!iSmo{ozl>s~nXnQx&KCr7JC+VU%~lqy#OmrFgw@hnEp!R?_nOqJDUuhVzh zaC`gvwMyMRq@iQN0&%6s4pB)q>p`Oa;v&Fn?6g}|w^OFiD{#AM-XY|YWc8miNgfyyT>}(w$d?Y*!T#$cT zRB-rwWrc}lk?zcJnf%0fO$|%<7mY^C8aGYFKcw{ZuS2Z&vCsi)PLI4$; zoa5TAcbUC4Zg*P?FOOyY5lnP+d_KFk-O|Q*NcKK6pxx3d6 zA60wow(FesHg$81&+oj~y^HtuK`@@*+th=vb?M*D(5Z_ISwHbDsZ!TKWNWWbk(Ji> zWQ2)64FIp}LwuNZbmXZ9IR%BohscK}|3d4`$XgIqv!cw-RG!Joh}>yL^8p-&g?MB} z7rSsaiRr=f1!9s7Lo$!3tY`@J!lr?VS_N2&b{_~CSKz=9YtkLz4}P2Z{2JVnNnT}c zKF^nv)LWjW5Xfe}alO2X80jfo=3t=3`6D4Io5t$XSD$tdLpl96vz?N*pK$D=!`n>! zE9-r%m6BHpO&HN3u2IKZln3oiv@qec73HmQU!uC2X=a9X3oZ8L)z5m}qt5lMt|DVO zQOim};-I$}(bE$ehLWN%9}X^n-+Swhfy(iGynb{cz13Ehsby;XF$^!ydl@uU$>Dsp zB3?1kOpUIU*QtJN;j%Z8IVj30wYzs|{&Z5{`|5rGJ-t0Wr-^=>%%Ud}RdJe9$;`=` z^BePZ>tqB1r(v)^_`Soo-w^W?I;#kDZ;4slm&*DkR(0)_4zA&X+6qydOx~xw+gs!^ zcxz05pu+PobZ(x#N!gOeriIb$DhPKbU$WXMR4KRJ7BSw!-MrYb3>X*8WLQVN>)?aOSvC&bj;8TVRX z)F(O3ScJhaeMZ3@5aooS*JxN{WD2HUp2kSSq*JHG=Kmtn*Y?!_C@v}V z^~&(0Zqe}`tCGi=06^D5T%?_bIl92>eZ+6^hHzHkrJd$fis}6hipcyS&eYP??6zEB zaqg2`qut?FdH-jsPmF#Of|KLvttV&g;^AMo>m0VGInQ{h=;+Wr@B6K=80hKA=W5i2 z#eUS;5VRs=hNFBM9v=t09P|c`wStq7j}~^yRQ{%0uvbP#;R_o+~&Po<(6c3?bT^`U#P_VxyC#5-GQ zNJ#{b3=cb=d{;PXRcV`bk>P7!yAv3w6rP#gn+swZcdZo-F+f9 z<1PG(ytt5GSk>4u?&Pu3dMyGS$z8Y!(XU9zg(lo$8RS5K9d? zxkOO(>auF37I$I5&tSueHv`L;+=_Dcu^w5UmlN2eJI~!diks5o>d&YXoGYz=1&JX% z)trQkx9GKuQU&wAN2_Xc`N9$_)Dad<;Pda2r(t(ge9UmaB~q~`!FcQs#}@gF@XOJ1 zzjxK)=FDq>i?!dORuP$A4M87fN&n_x>22pw+A{U@K#*Mi&PYzKVgs4I)sd>@5+)({ z{!Cz8w(wUEus&?5ZVw}~*1?`a<~0egHV>Odm0rC%#sgg3KJzq(2p-*Iz%oJ^6(S0aoZB`7QHq>aREiJ;>0TPrb5L7pm>4XJ-T! zrgnGaDmfjHKPzhGJ$vRgr__k$i$@}h>oukAtB;1K%2=eQpI-s&md#&1=5)nhkl$Qw z{oN&c;1U%jy`jTl{>x@L(CB1LmU`>@DMH>}3ZcAV_Vp{;K5R&Co&X8~SAa!^Aaihg z>pU$jHD=l)-rZ>jpE!&z;Irph*=NhAl>m#{ckP(8G_|8htLO8LpuyaJmYdQHu4+xi zzgXQCOUZ{brAkSeJqHUW507_yR!No4%GGsD7$*hx3%hn!c(fd{Sx?13%LE_ZsPBn* z_m-k2IUSA$efEs|Peve&J}JKard2qu1@uXb&o_jS%RN8x-Q~(^twYef<9ea3qx69V`0Q!{hSER*jI1XRae z{Za|hCkm@_8!fg8+~Q<5BF6bCVO^CzgOr?nC_d0Uhx$)<`^jo;?QbPF=vQ-JQWO~2 z4wK=ZeFhBvdKx{ZHv-Tw>&S@DD;b+F0mr^JF~*e<=o7pkG6kRM3!M_5Lt48jju4#X2lqMKZt_Y)r? z`;m{mCQ#y)3qqgj!-6==)MwkJTOmb-+(+quE5?_;N#E@#G4?w2wofS3G#=|d8^f@S z)~jzTCAk)qCS3(ZWF4kpcMh-HC+&*WfsE%Y2q0J=DAb!{a1dM@W%)7?bToNU%sp~i zD|gI_;eY+A=*#$wgx?b%F>K&V{tG2xnSkH~rf{~Q;hQH80oq8xDlG1!=0XjXkL@H; zjfYW4NJzxjMP?LOKUKyo%^G15YwI=ewc0vt00kL2Ib|V4Ei=8`QLi99K0bzoNSH70W+2E2i}<*lAJcO? zEhaHEKJ@iP;h5tz7hVYtVV_yZbhYI0P8%M~)|cEZAaZnQs`Lc<`B3RLgK#7NIqG3$ zV(|9TLHPP8<3ZeF|&$EthIqPhbD19X%u ztuU~nfkFwlt9wxmBIuI1wbj(ZTH_F0s zYxQT&SG=0+SDhIYZdI6xwqbQ~aa2ucx^F|4U*WTSjv?ZzfuS`D!XET2S79r;c}i_6 z!Tp8v2z@Z{h#0lM6?sLI!3U+75FEK~7`f>3a#sJfFxh$) zH2J#uN;cuYrRBvt{D;VOv+?lHy6u8yg(&6CQ1B{1pHZHQT66oSW?owhU-e>Cd1N z@)bf2IB?2W&?d&m8#?6R?d2B~4D?a5U@UY_MdIOZ@6s|N*z!8iwuFSp(n|+o1yh^z z3+F`S@1S>G3LY;n(|8`0T#xa55AF_-3Pt!&;J*{W{CIP8Z{b#kaX;$EV~#<{bvffZ z0+;t_|E(5+UDmg4aj_bJ{XvDxVs%B;rCIT#(VXJfWhwAY^pT60xL69qsf!vX1uSD` zXb3WWJl}IK&lR-`6yWubb^xS{iir5rMo@Z|$G!)h=%_>Rs@1vgrE*+MFol{G)9zV@ ze8MO2&T6F!^cR$wo_=x}hqcF`rD9Lr$Cw9q+0AZ3B@Nlcy=D*r3)Vd;eQWSidawB_ zW-n!4jdO)~l`<{i^XOo?T2)tmyIGFBuw>LE{x<8#Wo0)Gv8QF-wmsYjZsy4j4 zKTk8pK<-Mq{M@IBAMcd5sGlPBAjiC0TVd373m6(7ce|dyFX;4grkNEG6%tB!jvZ0+ zbs=TYh5l zKf)577nje}RQEm`k4{Ruzj+J;a4O!9ys@iQt`>A6T(d$7dy82CXmWCL?9IuEMvrA&S=oqSR7H~s zEcP8Pw>`k?lM_#a)osSJDxIa{@tvPf;0;Fl)m4H^F(U4fTAucn)VW&aIsu=4baFEG z^=f)X>TBb^?bN((hu1C86dp3F0Y)|!UXM!z9H*CC7@X#2kIE|X7Mhyvo~L~md4Fx% zJQok0ovcJe!_JhA)CN+KZAC;x6w4wqihw0rmKO^)%O9Y!4+7iLE%)UJQr@Lq&Q@}4 zpqNpp4zt=1`D5Hd4w0a8z9*TOdP`XDjWxRAJq@uy`H-$qG<;J~j^4Kp!XZlP#88*q zj~q9mpDXrb<#gRIu2pM3Bv|IbXgv*Zl103O!zp`(mxqDF!04=Tuz%C8X((&>#vYCg zd+us~vhzqe!3!}>>~Ls?Gx=Qt9>2oa#7SD5@wl$kN@0HNwO znyGCi8N~cRKtey-)0q_)V{+|^_`CJaklgM^*Mp}s3;GqjpXLI!@vbE%=01{0pYpDD z13tw24FzJ`w0+wCDZ-ikWB42A`kowbY!}o^1VqcYXn@=uhFXiF+j$l+N-J#E8!#{k zz-*jCdJsFx_glf@%3@mAO@6qTS(!!cUh~+BSLy3H{o@j0D$;ut#^dhhDEw6N~F|W0jGIvK6h$xrV0wt zy0!M+9fI47dIYgb07^Mc+oM4_1c2uR2pMNq(-u7$VrB6;dM#!DeT^$5gp@J6C#YT% zCKI|L@>IA0!`Ho4?>9jpd-!6~6p;ZR-@3wvA26JVHU4XAM16s(${5w#*dLva%S~XT ze&YJFbB(M|0Bil_IfDo4!sqPuU3Vg0{{s0Z^FE(_CTPR}YWRZe`~B5OI!gVN z8tfa#C)*b}-vDMo&nqP>tK)q`a<4EZApzWC=9cxr07e|U;N$gn z;n^rrl?OR^c@9`4GFd1{4l$SJtrv&drESOyfe7An_^e8K7}EPPnV_GxB;}M6zdfb& zek{)6@aLbOd5MFQDs?<;R$5$^@?+L(Z6a?iPc6$=Vf(L;T(Q1g6ibISH-BEn$|EB< zEm`KQ#OL+==7DNpf4ax#&a_^h;eZ%g`$;Y)G1gq=5(+-RyTM9hs`Q=8I{3>|T;i<& zhM|px>|dcX2j&+{+WIp7#tldf`JIw-WOXfIZgA>N{1n1$f3ndg?3oVW;z{{}xb9#+ zpgbVvgh}oG3@AXc(!fYtd>pA3k~Tjut<-%D(|7{dGXZOcxlfm44JBp51RN$uIV0Yn4_^3Sd9=QVakTr1KWl zb$C1Ne8&u~E;2X6;&d-@6+XM2eB}Jvn^Tl)j z8PhK>o_qwS7pO5t^vi8#ejc21>rJQjw@<4V!GnW?2W2OgG*>t{sxDQPGqsxV4y6>{JTuaJdhKh*Xd5>8ZJ6mxl*9 z5zpXU#<*O1g5`Qb0cWbdgaa%t*BwXo5f1AE+xz~*5eVrv?S3Qtih+ZXk(5-JlcTc^ z8lMzw4~vjj$CQ)|K`zB|I$};HC~T;zvKAiyk&;Z%dorq1q|u!}1U`JwwFP+_hx>pbW9IxNWs1|~p6w6DqlaBz4uTVXWS z9LMTq4)mqs7`O%Kan+Y~zAA<0$Tu4G)ad!OPv|t=%`bDZJdrNP1_+@hCK{inYt~uJ z0PaRw*H~Tx>0QqFcXTu$RUL<4LP5%JrMy6tyHV8D4^UKLt*y_~1=7$TKi1ULSXx=( zaa!|wzqoR9k7e?up_Ew6m+5(zL&KxUWNNiVC7#8JvSpRKsvpRLXm%D>;Q`#>00 z59DVsBZm$u+@@cqkD*hq78KJkUfNOYrsFq%pq@K13FPq@?g&qqCBZ(NKhcb^Go8tM*ao1qk(t z0YO9*Q3U&8Ok|qX0sBE3;@;IAE=J*1`yTlh&-OyS$hLKtTzB zb78NkG!&0C@6XrI7b@4oaadcNjwvW8oL`@A=StP?PrwdCvE&`hoz))qX9H10N$fqG zFh5kwepUaT0(4QMZzw1!nQhNHjt+L6pl?Fs4^bD_A9L|Fd5KkN(n4feSRY-uD6;N; zEg+=$JI(MuMlcq7?sr{o#TX&GDPB*Wj;|WFFJt5B9mArW5>eI!*nhG@^vyFX+nSR4 z`{9tFI?v;>vg8%Rn;rHe33w7SSS%Nr;NjtI&U2pu7?_xm*vwmZr^`=IPX_(rhf{g* zvPhpkC9_+oIy*ZX8yowN7D?=21_oVw>F4e00Jps6(CE|AFLT_QAPiwiF&<_CUE_a^{~GWaP-$K z(CIq1QMtoo-D#jgcxy`^7B)ber~YuY7VTcu-M#BoT1&8EV-0vQi3Z z=jb$h2i-{t3wvF*6`z#1{%~Yitg|`~2;)RRK*Z&=Pv&tTSw1*1kg?4AYvB3v(Lz0C zBAt7FcshP>rTTbdj0e>aQh?7tgj_{v!_06OkGdj>)km!!QGzg=`I9f`rJG` z0?R$X%Qh3K{0)(^V@*vk&tj*lbSYjCO*1%Hgi8@9jXACiQ2q_Iu|G)rWrVT!3;b@* zq`Vx+zsVGoEb#%l1DfSP_ju?Ui&oVKcH8I}7}QU;$Mf_w2DM%?cW0|< z2??SfA~|i=*evExc820kM5GjyeYYt3`}_06ql`gwE)`PRvQ}G7o3(rNj4w5h51Nb} z>eq=7x9q-mlOSwQUc1c`+U1&p1j0!T_bYAIb_31@NUKf{i{NXlN}{FK$CVI1xVc;4 zxQ3QxAjCZ7bGd%8Sw3>0bPfs-x95BZ**@;Yhmh*Fu5z#yHJAw47#_R^$+hr$I=^h( z#fdvNIGJ-8znsL+*6p`xCanK(GYop(K4t}m^Y@<99Uf!-FkdNybtp{dZgE&S=n@u} zla!Oh*o5cV+D5xO)AHDT$%(%Iss_T>B!Kcp=MLW43nOhICJTkx#SDHYa#?xIfJj7} z>xtw;b#?H04+#ms$Y(hs<~9N73(}pv9i2A&Fv4j7fZZJX==kvH=&-lH-^~^D`7`pi zab9XW;i~uWn9Bz!|C_g04>L0}j0Bc}6o`sQV$h~iY;`^@DxwNi<@J1s-onb@aRG)5 z4-c=ly0|zw$;!!r?01L5u-ektW?Fj!k&hRvNkx%&c6a%Bc^R}@c1})Ka)cFGhm;EC zkcs%UQUr9a>da=4kdb@3yGvA_bCCn0qM|l*6c7BJ>vzsR*Ot_vUm+i@|I@A-kjp$@ zc)o5gVAO7&%dgJM`M?NgWo^9mtD_=l-=ZPGpNT;W#GI|`Vnn{iw=fVz2w2W>dI*w$ zFy6#*hkL0{mbEdk?Xn#8e6?5he61iOqnw=_(u17H?2rl>S+Ir_u>nFf@n_)no|?I| zS7_fILqq=legYo19IxfXxza=H)u!-{sWdryyoEXzg9m8kl(f_p&~p{eJHwKd1}E0n zuQ_ojR?IXw1hG32aVdyc2h^~e;$lu>IGx!szSr_3$WCyZJcRmmZ(J$l8T<-1N zs7VPKuY2W;d{SO6(+`^zVh6b&p*qk4;HZpaqNB4*N;Hm;%+1X$ecMmnAt?a}uFlQP zHRG6eEiNuXO24iYGm>%+W@fw5WagHZ7Ayv>e<1C6z8vzPJoBeiHw2=_*o}=1eZ|j+ zh++2q8ylZ$ORf}$eEMR!Ug09Frs{|}nfZwYWj7EN0f2CM33T@a87-~uwt&*ZE?KvC zej%pL%S!{#;`>LytD`vUQ^WPu6_`sU9s?YL&IM3Z4ULkwbvAe2nvC2oWIO@;tW0Jv z3G_V8H#SCu$^SMuURgRhnm0zfdU^O{Q=hBv_Si%V(;1bd`#q55iE|@Ljf8?YaiEjY zA8KGdiUEDTT;tc3F(#BiNJ;3`WLLX5(&+%i<51<`;6UI0;d+t1p)IY`;q7%aTTCvU z7~dk1K%=s?wbhgqKM%QPcUEV)`1y4tLpZ+^1@J;(0h}!<4jLUD?F+*~#b)}`jmdW1 z=61cf$qSl6RZl1m(K{#1z+}+WJ)H^8L0^@SdE@jmf1<#02VQunGtW>={_9jL{&SHz)x|=u9v%F*7?H^VYNNEDZXI?lw{0M7jcST+y4l1ZQ)I+iR)%JQR!E9ptLByS~)tFu)OeeA3?-Pxk0<$ zSng?BqO_D06O@3&0)rK2h4yTRyjlrBX@RO_Vz#8@@Yh6x_`;ooiJYtJ{z~#!za~7i zk5DfR-@biAqmsXgv4&LZeZNg-R5pn*}cQm5TC(9j#EYhb`+ zI$yF*XfN%hNF@S~m5l1)719bi89_PK;B$Q-qvQ3R)>(U-SkbAooL6|LcRF0$8?3H{ zuzdU->ZjD#^H6<{x$2A=i0RE*TXVqd@OE{LWfNata%ZKP$>qXM${IE;E}yg(@gg$yjlv>@uXwI|Wj z$EmknHKETtHV&sRdT<*iv9a;_VG989OlYWw8HGQ>nwlOnKw0UetFv5<0;z;*gMsPZ znmsiIg&!VwC!;B>jaJKhr>C-Z5o_%pGdB=m8&77=Ga5-G;`hwPAmnxorjX0zbvs?E z&l8IXg;?}bQcEpPw6gfzj;8MJ?htG=)ug7Tt}CzcrPjU8QzfS-uQ%Mh0YMLNY@%}N zlmZ`z3mghZe`zWF+StFhp0Bezam5$Pg>o@A-s{vuW1F1=D9wnW5Ghzz!l53dq$cjI z;+~zI_i5ve24OiP!~G7v6-_OfB01)Q@pY?lEg9ScIZF!sR-aub7pf6dU{nW(%!p|_$f140c4?=>?8A@_%ZYFE@ z4==0MNS|_`_`JL^*tq`*Dnk7Myv)b|ll(3xiXto5j!tORwdZJd8k|uQb}(W7XeHJV!u4NV<);(N?0V z%(k6)9pz(4VXGEXsn)D@jcSI9Bx$_E;O43)cSr3TXsh7Km1;crbu5ZWMjklX-0KScOSG1{^Q3VI~?g@A#)o$6l-$hwa_)c+p zLwY^IA)ec=G77|yxEd7H&s|k*-K@v=KpQCUz!ZWVvBu~e7>vyNgg$Pt6c@Ji%}VSI zf25jRX%6{(3((LQ1uYJsAS*iy)|ggM8Z{%Y%tB1qL=9J-R@h)4sN(Wf{U4 zyZNE~k>!6Mnk9!rSwtD>9eY)8RbBBi2jF5OBR9)SvZFu0CCkT9uv+0b5L~`3$2s^+ z((@p69PUwn*p#G2aRa$w6>5s+B($Fm$|Zi=YOCCSs;y$Z_kHP!wZFQyvM`l7G%&~= zIsWc&JM@f9sat5gQ&*uTD<(xk+G=`^rc|3m;Cgu>o1dSY>{mcBR$0!VIsQ^GJi@qQ zw{{$BApy{k<3k+VJRP$#zp#eU`8Al{gywn*_Q=|Rae$t)TQ#4i7+&g$J#!Zc*L)xB z5^{KN+q=2iEFFv~C7Q&&o3PTE&qT+}4H{|_Z{<=MF9=N6#llI#d0FgaGWZyB?#N@{#oyAp*a;dsqL=xFai`wi)_fO&QZ+^H# zReAwqoUBKTGCxie$*J!W#=In`4jQP&-Ymmju0Kcm=& zq^msip4o+BCNS_6GKHBjy&L^3qfvm%G#`;(;Jv!-a?iOzSd06&Et2JN_Xv&GKVG!7 zl)9>7ZQ_WeekBMDjHI0DuCi#F07=*WRWe?#KpskY zI`k2h0;p*Xr*>S|Nk)A+Sj!V`lA&Q-;6pw)v^k$k0+;nDHm}PM_kGWNBnC4)Y%Ia@ zv}5-T z7kBt2YieO3DJCKB-xD% zU&q{b&1s5)diONdwi7yg&=BTz_Y;Pav?PwL8R@mpOcStl4BI~q<%zQ*4naV}{75xB zTIkZ(2y2?fKDoS+MT{*jA@+C4)ix}~QbZuI4TxE+9#CFJ22p>UGnntu(UlYvw3%n1 ztj+7cA2ABamT9#j@>m3USwb3YTrq!c|SvVofkIQ5}C|-eZtT? z?i$sXwdN|&i79J-fTAONQm+?GsWWw+r&Ow@axlI4hmcKv01nQoQ2TSlo~U63znlC- zUhA)jQ)5xVh$qqspwR_?WY9aLZQR?khs*jj2TVdw$QE}u)=|Gs3U%J-U3J;gC!tKL zOHBI8Ii;lGw6is7T^mwI3bS{Kgi(#n`yo zvuoI^xiDie{8zK@jpjdSEC~9>-x*ahw zAM0L{tGtH!SmT_E3@<{7!LBnnZlte-a5Fn>!8OjY@*Nc8rj1RF0H~s+2F|8gh)`k~ zUid+S-DIRxa{@)C&Xi3#7dg;N>`Ag(ay{SZ9$`hp{QEGG5)5*3mHu{Km@4XIlM8IkK;IaP8pLZpXt7lVN6 zzFCk+@qcFoO2Q$H<+~Ed2un}w^+R^ksy$+9ML~3I=JLdl|7nO4Mcu}O%9jnu?toA> zV^x8X;#VZ zyBY`Rx0X|Y9GJ=<6pys0i)A?2Z#gx&{OVT+mj#M&v+C@6qu}Aern0 zaZFpoH!e5WYDrNmdA2!MuXuCZ61g+0o^mZ|*@m)5>4Fj}S;6S|I><=~PaMhWq9!C~ z6J?A7Dlrkg$cG(EhJM9)!o){O6~ol!qqX~&?C)3-j2;b43_jjp*)|_knBWE~9k$1N zn3XV@1lG#}EXH*~V=wp(|&XU{R?`F z+d!9OZQ?ZJ@$r4+ql&)%_QA~K11w8|_#@YTH44VkPLqIx0Z9I zSp#2!5Mecyy3amsGUuPxI=@h;xEXne3evSEd(ZQwMFiTeU8m6>l!mc0Z##WDRMOQD ze4_mjsjAwhigyJdp{H}x{2VgINM}fb<~GsWmE1^(;LBD<-1VtksP%F%>)vgwt~b!f zTr-D;a=I9$@&*q#ZDMUVKP@BPAKPXy%9#UTR36kmB7^22Y2|GY;f-wQzak~d_jxBk zL#DnL_o5>%Q8o4iipr+@I+;jBB)HYvHHgfT`!&!DvcBt`isaDlbuU+4uWsY%qYS>W zrY#>S(0ymjYNVl-R9vOGI^!p5?!!~Jn7Ibgf>;{`PPv~Uk?*PT2pdn?B-_%*dmNH=dgw4JqsDAe%8SgwC^nnV|jMg!v>+Xo6x! zB3%8)?`4y+XeT*iq_xnDi_Wq4WdZ&4ry#Kn8?uz)4in@0{@fJSxjChg37Mj(ARABR z$AVsj)BeMKb@Ybp-(79v_C2Y9zv&C`{#$fde6?nr3~t5{4N$`x|4D0LdC2}O*M7?k zSpL^HwQVpipoDy%&V*J5Hp4xUE4LXbKoKQMRbPBPJA{zf4W8(=>cfv-5d=igo!4_9 z#k8L+o;j_vX?BN+bFBk|;J`V|u#_~CwFO7D3B7x%7xe4G`PMlo7`ySTtFysa*21FW zIa+4sl)l8#!rXP9{NZYQ5<=>?_2}pBB1|ukFnu9sO5-tCd*6je9+H)f&iIRw`j6SQ zUuutCBdG9|Pbo*GqX$aMLRl``n*lv1HTG9T9UYCc)(?9DWSOzbuSyD12 zHeljtZ8`Yq(un0k`g`XG3Jc zl>0dupGPf7WCYI^Kc$8hCQI*$7R~eSs6o~N->Z`(<3akFrpTp)6oXKg$VQb^Fh0Bf2-hM|3FuTIlh#i&{bWxAy#_eMK{C%VQgJ2$hWh)J{f z3qtG7N;+G6yOswY_0wMxG{m#V9lF+N)raljsTWLqqczvSEyNotu6Dt(k{c=xML|{l zUDF`ILan0+pL=||b#AGneRbT$wZk}r%ii=bLhN>n`c&Q`uX*Tns|g1^NA)b9rFH4H zN16N(TMr%?xd11puBt|QH}~j5Fq1&p@t1gcGCrk6O_?5-7Q6k;0t=VMN?qlv@)uv< znf=Q4%PV>Li6R}@LXel0yX`sX_RhuYj^qcKjF!;KXm6E#6iV#3Z|6PyD{cEy6V%1U zE!-OAX`FS%MqT3q7MrQ=4IJ9sbu< zUR?xpAc=BgcBB>;Yhha58uPH0mZbwduVy3pjE=j})7{j9T2pzs^yV6;RUu}@wV0OK zzQ!}|^n?UHt8QCoFtqqMug|6N(Su%pU>gU@SEAgc@>Tx3tT$Cmb{L3X(_;c@eejEj zNlQ!P;VE0p=Yw)UYrDtyXMCP5dVN~f4PHU=1HJtdnJl5xsD!P2?pyrst{o0oHtvrw zKNi7c1^G`;?IUBf-124G9Ga?PPe-y?jO%{}i?F%4)De}oD+n}4hA`O?!$Tik7j~(= z@TjSa`^BCzmg}eION3^0+b`|xoDh-2igI&Q8ygaouEqL5GO3#@yUW#fmnS0>$R{2y zHu53j^1NsKuCdY4%Jn6I0mYI*4P#(NnmvP+Zj3ZF`b@jyiqhwi#w&Z4Ym;y^Exqaq zA)G&|61v;XBaI(F3Ik@Q&6Ba6%@=abF^~h-MU6JE#Nw;Y%Gj6t^@npINL1#;%0f~~A`@hr@$3>`k9tGj%-960P;|{$f$mJFF}w_h>idHNKv+ z7T#vt+dKa$KUt*G8IX3fn*bFV-JXFbhSOY&lR2b$Fnrn{x1R|)SO7U<1tiFREqsT4 z{mNZO-BRwZPSm^18NG+}{v{>TbIhQ2c^pkJyW7 z>o@bw{tCf4{oehV;q7wypnBCj5h)v;lmwibu04z-<@f}-R*quRI)&5qddT)m|9#KrA9FMi0tNMkDQ z5qbk{!$X6%cy~7`PlMT1f3cZ}2wMPaQ{(V@5acjoD{6W^V~V$e5}Ka}YUUbfe>ncx zZ#t+z0!I`E?)H>~l=gZZw4HMmheB6x${7p$tvJOvz{~Sa7b52ST zJMr@~S2HZngol!2&s52g00BLSTL9Fr`&nDryCZt?Q>gW5I-5{O3qyOEl@&EPwbR`e zG7YViwB%aT^<=Mv&+O!uOGh5~pbLn6>$Fb~-XOx>`fZ~0)*!U*gUwN8vMR4lQ&bfn zlgVW=Y-(h*_6q~y>IyzGvp}CRp@LDTRobHuv-Wj8K%uyPXSf&ufoggg*`h&ly^pMD z!jQzjktVyv!Rhe?2TjglKinJ{d50;)26#+&PF_4Z~l>Mr#V85?7RaGQ9-a`@WI=g@sk~@5epOd#z{3^UnC!sJxAj z0i>FZmZKas8>vpVp08^Jyzb7n?`JDXGAW*GH`SJ@^O8g>%Z$;l6qW1Vzx9lTSZmK! z7iNHTy}*&j@1G?l(XmQxOnNvDzPz3Plf70zfrJYbV|;yul+!&0b;Pu)Dy1GFN>hXx zYJkyy^y&HW0bWX4x_SyZF`(Jb+L|z7v!_Uqh@ra9IRM7Gf zT5J*+fmB-CC$Z)%>-KuE7UZL#tejnhFn3WqQ`{z%wy|{N<7B68B@64;-06~Yb9JjJ zK$E1QKL7CLHYRkQEg-bP7}$sS`zGelZRn_+Au1C~wd(x$F(z_ARJ4-g(63AK)Y zp|fd!>Fet=*Tlj|rlwJ>4;2$}RjwBGPmfTT4a`)UaV1)BN$h*BLLFH+rE*S-s_|CZ zEA7K`MX<}cdS+-r?6^e+70o6lrjgi^sd`u!*x36|)A1#zki2Gv{8%W{D;KfK;sDfMUJn#FF+ydI>=^&FbG6+)R$X{YI1Uv z$?4VWhf$Ij4i0%w!G>5h_dFf(4}Kn%(Y5a?4E|LtK=qtgx!xjgt6vQ#0;zmPA{Fa$ zcH(oJ^wi&*;@Q@i&aV*c3o0&Vn@dUBRHb!ABu$YU&jo-2g9A-42u3Vf8k3VYBJcP5 zS&^sQ%5U&FV4ytiz*j!8x+mvAR5vS^OzFl@RVPp~FG?_c>h^{dtc0 z!h*Q-@>$U>5ZTaH7A`iSDT%c^drZKYK=ze@W5N@u>_E%XE zHJKY1j%a}SX?ogcxw39XlKFD&>z(FOh)l-7*kNI*Jz6N$&gqktMUvNT%1lnie`TKU zAC{3(jz7xP^?2Uh*#&rZ{mgDg5Z9KicWJzXNdA`hgU1LS)V^Mk<$CLWT97vmXlSr( z(W>r_ke}ci?%I4Yb)TxEQwac^hNmE`p~1q+TDtgRd08VV>~Wl`iv-LrE>?UC+-*UhTdkAb!1Xao%aEukU`t z8i~Oaa~2x8(cL#X#yT#ER>AQj*UUtx%;fILEyFiXd;M!jysE`~AuN3w=1fV6$k%&G zTun|hs{)Psd<>WML*gttnZObj@KY-H4JJJR6ngCj2fw!L$S!olf7`Mt7ml$@YizOx*>3B5cdTX`S+qSi?O=%ZslUq_>ek;up`qy{OUv3n`iRx+9tE3iU?=FCB&=Gc!{`Pzc`P2WkW7WcY(se zS|HmjrD!9Gh%#4P{9l)BXEm#8Ou*jbGAbDtFAL-*too1%`fM%=5hTXmy zOvbxeIDuV;)|t4GB^U8DGafM}+~p-6x(D^YA375M#^xew4H| zu{C4|Fr_aV(kfBn|Li_KE{~0mulJvi5x1Dd%UDax^DBSX+Dos0jIZa1Xm_qa>Xna6 zeA?3B8}1Wdnp`w_GN$I@X!f3tng~Dk_&VN5`?2x6i7!7NulbC#@s(#}rNxIa#W6kI zH5WU}jQkAI4SE6i8(X%u@rrZ3oZ{y*i5YRK1H?{Ems(8@;^kr&c9qUt1=&wkh;yjR z?z^5}R!zEMC8^4X8JQ*1SA3i>RGO&RQ^K;0^G%4!_6te5!g_9cG~cieTXeZYX$~Ep z8jFdF$h3O%k^PS;j1YS6CmA|r#bZ3yIEg%cMVfz3u=cz1W@2&Cdt)DPLdr?ddAf8{+gY z@)^hupuC?Lg{9}d5tmA8a%xPrD2&jHeg1cTye1}kW-|#Tkv&(f{j0X7@TYr`C?O6A zHl;g-(b&kS+vX!H3$41SI_+E5&BgYdc}4IqWmrWBbH7bbKi>!p2q@b)I4%DbcBfh` zI{<)-1#4%`zESCKby4*LQ-v1xkEa77-9z>V>wm)IFIKbg-EZdWg%3p}Ku?;)TfyUc zLfz?TI>8W}xbGJ4THOGJm8d_R?BLjgeCyQ2c0QYl!-z%b&A(~ZV z|AqqAnEdNvP@!hfigQo<5??z&DS@X8Eew0HVeQRT1gh}d6jS=v2_^6|4v_bH@4E~N{5K-(B(AZlE% z4tl8=I%ol(^Ke`3r#f$(nVTfyC^(vg_{~()$g^6sl?19CY1Uu-Oh-7EncNB$5u)(- z*Fz@fb3U2gkt$;yRe|N&2DA1~HAa?uHO%|7#g>=b0xW`-f3y}NwW%?J8A>vGckZ)y zMb1}$x9snmK!>Y6AQSW}rO>`l?1>PCEncCX6W8M~@tGW)D!-~sYGY%=`3AY}lZ%$T z{CEAY?xWKb`!6#$;Mu~5#L3B=iI0wP@-bit?-j%{Dg;$9Qo9)PU zYFpJ1Iym{%WL_TN#BR|SqZC=*+}toE;9xyh3|md1XpAYGvA!G))`H9_B(Dc^*j|ML z#h^wG^m_J?}38Qu06jn~twLI_QW@ zEAr3B*cz4tpSn+IlinbK#U%K}Tq#6&G5Fv!+BH`Jjs9m;c&Ojj%U5YfzpidXj7m(*c{G{+2L4A1LY3BSsbk!(o_EJw!uYrdKLt8TW8Vu= z=!hY^fJ^P|+YGBEkAk#pQv;J;@OtHrpU4q?j0V&O%m`VE5jw~m5xNMEJpX2i_q28} zRbVIdFhNZ2>(RdO4VV`3aF?%PfJWtcaZ>O)-%-P!l`Y}VQ7|1@(L}>1IL2=y_^$_+ zM_TyZ=z`Z-*%<*sNYux%X=yhlIO=@V%hcCGKmRp42+K!yU3^>Dk^3dTo(6HF+9*nM zsEj;fWYtYe0@)VrvycB?1RklQ?GWYvehI!7`R@;d@9FsdZ!h`({nOY+%dyWxCBOgo zjV!}MlVj)*1ya7a7-Awes|xApNPaW4w1iq(YC(l45L=ja)8D>+z504pR}z)=?c2Bg z)xw8f5!3Tjw2axgZ|+Fr1O11-U`m8Y3=DqxD>3wUNDqNPOi@}>K~YvgQdL_*Nk-NG zM)jkEki%2p6opl*bj3y18DENhmVOQSrLwJ=7!`ea?j8Ck%Fcq6lJ*1@MSL0l zS=BOR%g>R!w)S$?uy^#djp?@@{&Pelv1{kB`sJ;gs(GX(MDL(S9-NJV!B*>+O|sQ6 zNmW@(F~h3kz&DPbVRjtRI{^j4we%l0G72)IMC@&Wij8FSbwtQ5-YDSa>HN}0?Ph%W zdNAnt?2TjV&>2Q8S`#*ye0>3*kFE`mfi<$=^C*?o$Wb&jpWS}{c_duLw0YdvaFPfd z74fNGPhNTjhba8eRaR6@U}jsJM#A-CqrCsr135lZrg3b&68X7?FCj6Ytd=Jj2|>WX zy@{%j*4g}g=oRpq-?33HWJG1Mnz05-X;cfjvdicsX|MTlmx*d8Q`GG%R zL}Dxxm1p9qFwz&vfUWgSG`9CP_{veowSllz6$4yCgtWX~y3BR`=WOpoAo2?TvjReo z!P_DK_jW8TlcU~Y`p7>SjaZGc_!W;`i$*7TJugb7!l90YENBd~LCu?KL;Cn*-wXAB ze}2D)Ajc2KTlb=;XsFglG`TN(nS~eSN&ow!fHuX%;8`k~_EeuLv+T^)Cmy?-F_-2K z;mVfKp;wCdHTZ0>82-5Kuu1>R3&0jdM++eSWGJhnLqRn@q5NSW$kow;lAd0K z>8R!tpWEqcDjIJE&b7^Ec+WxJUH+90`TDy4fJ|^*h1Jf<=-zdFJ^-9eN2Vz_7~Bsd zWPp2^)Rs&^dXeOr)q;CJxV8#y=MtRLpK>4X7NS@+A})%5miQeAItAmUx)&A(Yat>` zOV>7M(xhCOF$NgObcGVwv1PSVGLX*x@l?p2VUz{G+i&$oQ+%$_rl!GlT9KLaM|UIb z#?$cdX!RyH)L4z0=;5*il?jbX)9*Su(oFaavk@;-ItI%P7Ye*l2Avx*NJ zb#>XTyF)T`jxtmW{)p|&lusHyC&8Ms`XkjX5_>n4{K-9@Af+Hftx{pFuFAfktjv~C zyYB8XSQ`}M;ntNg48+RCMFTD5dE^!k0n+Q{XeswvY`- zYDK&M4$`q5`Kd*!!C5HhpBi@DnO}Xivp85QD&i6!7bUFD^M;06Lh=h5h3O z)aoBT~+PW*g}n@_C&2qWze6y}n;QL1P_N#B|{Fm-uVd_~3WB*H-8! zo15rBCMzpJ%9Tz|ywLM^!2MvOTSHDPJNAh8@U8h(>sZmyr+>KJR9R~5Vv{GLtK<6Q zSb+i`z?8#8%L9lIqyGd2*?A+|x3#5{30!8HohxMAm5t?_nvPd&ZlK`eQaPY*;E|^Y zCJ3-mjtwz&w6%TtL4`p)BPIqtzeK%fqA_1yX2c01;4J9Av=9d(QL)fN@hScNKN9}5 zV3?Tk=F4Bcv^AYIY6tU#5I-_9tD%(U!kiofBki#{US=M;nCuh**Rz>&waS8l4$;nr zhNnavu)Y@Zf^j|k(ma#w^n&%9*+j-M{C*OV4V31VumLz}8a5yvSH=nZVw!0+d7fp5 zvU28jF{Wn}s{4^2fq^3Ry@YDLDXs?bqL6fn!;?o$FEx2nI!WbObaWTFtSR zXZ#0McVTo?<*3nWz?y^h*5iEKAV3%W#xDKC9&G{Cq|D;@o&?GJ7@#{PWjb!=4^EP4kK^W1$g9_~YLKtXRj4tbzmw#B+RXIdo9wed- z?mTdY*#z1q-f|TQxLu6i1tRzru=AF0Nga9L4MA$%Ql663)v0W37|;Seon_Bpb}mh9 zini0%rJi{AtW64C!AIqam-D(mz_kvJlZ9yrWKF5XdRG5 zOMj+@{TQ0!#~|I6zX_9d;0S_^`4@~Aj8>`W(IqKH>2!HjG8S2q&avyEEs`gW+xyPS{i)l%_Xp`DzMhT__O|^Ziz=mUQLw4^$~QnH$=aksULNv&MDs}eC&CRM zT?^?`0=i%GX)VPFHEh{5cNk-8oeY@QP1ihwJxld}JQ4;SsYw7}(&3z@>=Za}WTPeB z-(KyvG>Qsg_-aq53U+}D00{|c|IfK}XHXdt*J90H@8(=XgBvnkZNt2#2YmVNDmgpH zXnWh(W{i?jK&#d!lx%VFXqvWI>t@)N!K|E4Wqh&W#K=~P#okmyas4d?zyB_$R1-ZN z9S}aW7ZmL8O_9gAaq;r{Ev#nvHOxXuAq+13&i4U{bHsJ4`devbPmoR>4tQ4fh&u$S zD4h0nMaA6R)<^|o_oIOCq=@rhCgxuOwlYL`94jV^xn#KT+=>>rlw+)s{Z?Q(B7o=- ztE(n|X>ZEfkjq!Rz^|e`Mq756BM()l$^C}{z6j8cs*_cXM0V(vM4dYNq}vzvM@_3C z4&ui-@LAH#6ELxR@noC^*wb~L3MXKDremd+?U&xl=7!7oF66Hy-qQvMMiVW3@BIj~ zGg*pA4ozxO+RJ~MB>`0cCWu&~8vLDCFc+jgLONQMqh2ZfKuoG>m-ce%_ z@g?Sc7uT*!ZFXz-S?Sgsd3@O`Y`-in3xOV<_%b^7n;p}&&$RrKkzs>HyBtqH#CH>W z@7Cp+?64~+Wt>}54&4NP0q%T(fu%~hoXNY&(Ks7<-+scLZ@Yv9kW>t!Ln$??zWv;b zoX@j3DRWYyyhcPQ(W;dwCD%4* zqfpKAa2U=Nyr5*g)msk^MHkRDvoPpw(axO4jq-08CwqiD zflPUnj3X02#J(Asmk7s|wiCl%=#?M0l2{2_l#6oO{#2^gLHCgMsEBffQ%k z(J8TV6Q@Z$mGjLe51%V(6rk01_Oe14F0}9IMFhB_>1p64(JN7@ z!*o7+S^U8+Ey1lihPpKOnB(Pz9EMKh$d6)F#i_fKRXmP24&Q$eB<zmtYJH4u+pDmC7;@q zl~ZGQkdxKwE&1aYH&`urXqLT16Yws3%`{gMt7wOihA?@-8~V(M<|0=(K2zMt2vuSj zNhLo!q;ruWo{*;Rfi1VYYN30(Uqe(RdOZ>c9Z_$FMwCc*M<+KqBlPvsj!bw;kR1};^4ft)c+dXi@ex$6wvu`8uko@ zH!%$ncwG6D3fM*m;PvNlk}8apR*=;}b*~*+QtOzix|SE)w<`QYED|QF%MF*ALbkSPz#eEG6Ty}PS=Fp*D6Ra0Nll9D%F8n|M_?Mq&` zy->)Yg8rxJN91n5NqW4$kgCJr#hfUTztq&xn7zk^X^K^N`=vmRU$oB)P}I6=XhmX7 zhJE>OAagk-~eu8%%2l3HDhU~=k+rvw)qmzV^Qg7dq zU`g1X3D!Y38hdva6`(>Io8~G+tyIRs{d(eVFF65;?4^wmYHp>;%CbcauDR|oyI<2%k9FwhdiB4~++6m><2&imQd%DB5VT^g`UiQjZviXzdU;)o z4Ps;duP%OwWe6;jVcE%)jW5?)_%_71 z*#EU8hOXmn20z}MC$S@B#$vP9~jA+xyb!f3Se}eIez%?vF&} zM80*i3Cj6$Oan6X!#`d$p(O2WKiwHV2}Dz~EYH`Ya+-Rr$}Nry!?v-u&v41m4aDg~ zpO3FDRKgDUtl4DUEa6>e0GTBu+>Wly2c=d{R6;Dm2K@!Rj>+;~Z7*>am{~Us2KnmcvU1LN5RRsy<^y%= zUWxhO!0PJqBCU*S4{jBjt*|gP&-6I!YQH+7oETS0;3!_IvcOKTR1|?95PJkvDNl@U z&*UdrkkSL>gR_um4C(g3HB^J6&`PWQ$NX=opPZ(y)t@}jm~={syCy2)f4F#;7#`o5 zB$rnqfg&iDTKx(4H9$Q3qFj(vx@T8=W$^iuVEYR!ea&PUXWvn_vj6q`m4mt(`%C4B z6XYeLO1=UvZRamULIJsjXsx7(S-fTU$YICV-^YhdH8X`mgc# z&jk4s$7ep`RB=SctO&R(XTfhwK4-Q%otOdO zoz>6(!5^Q;*Dv4cp#Rf%{d?q||1U8MAhStgJ^BCm>1&Zn^QmH((85jN6sy2e_Q9Qr z2A=)5GA516qoKL;2zzNHK1UBxw9)pyZtb`mdl?er&4oKT=3_I4uXUaeSkAW51V}K&3X3a*@KN+4Bzf3Sik+Kv_A0%#;1pT#v}|< zYBFj?OAPjV6%4&Y70C3wISSaD4JW5-i|LJY4jdm1HeVyBMqq;jCzV~|FYV;TAKpsG z*#-v+L(ghA-IsV0Wt3t9P&mYSb(3$rAY$oL$HxuGGbdAY*Yi{q)=K=>Lk zJ)Pd}TD?(v>pd?^y4WQ+({D;3L%`>>mVk6v6pOf6Bb~_ZwPJ(?qcB2flDjbFu{SRO z^TsL0l)KxT;502l47W<<1MDg3JJqryVNNI~qQR(|f<7p*aUa^Y4o#U?K5dk-XA8yB%=d zC$_gUU$h4+3NTGJj*t%!3tNZFUJVG`Eva~otZF!tgB>w6TD37gBUO%+Fc%%5JH2ol z#F{r@H~c$qvFQmb>!`4$@#AXcxj!Z;uN3Zwb3FIAx0*P0(8EUQpxk~- zs8xlO*M6jSOz@K78?I{-%EsK~5(OvaNPM)Gp}ygS#dNZkBI(mRo3YD>s4BB@PiRI6 zpD($9yFVmsm&&+m_G0c9>6!fjTbZxDQi9RwxoBRVi7kFn+8;x$`p&TMvD{P7q?Cd5 zC_-T6t00!;NE=yRTdjP4_Q2+VSGZJT7|GZuKHu<=TEGn<<4^qPu7jPEoIN>UtR|OI zFNvMguPL0EQP4IZ79W=V!+A4)PO3LDDmag^`YP3WKda^N;eGC?_v@TNEuCgOPW+9{ z%@OTl>wK~bHqtt*3@Pk{x7W2@(h1@(ZncN2$8!xFZ}&vIJIV^>cJkx6t*9olp%)pY z+O!rvO_v_A1v#V{OaXc5b#_FCsu?F^@5$cFY3|OrXJ&|WcLs9)AWePyHeI!FezAUQ z8~K8FqIk-ByeIz9vbe^8Z(ci;kj)RzWWJ>DSVt+8lu!H74j6uJ3?}(bmYN*Q*O6P$ zC@gQ=!56V-3BQ>>HcW79^YRE8oS;3fNzWLC1(5B#1f0%; zl4M=^oz^RS8S2MOO4Sn==_f67Dp~F?pJ!0_8*HUTn-R~H`@CHV&4T-F_7hCiyQ1)s zGKeDG7zXc+;n31bsH+nqFW&*$z`=CI{){);!=2qoK{~&wlYoN@YxBi3(y{GY?V~}! z=SiC5jgKc{Yv}WLJ^y6g|ME&ac59FzCts=3YDo5W!aiQkf^oZ94*xGONh5iX^FR&h ziK$87{A6dJVMHbBv*PUvMt11?Q^8t`H4i^6*djWb-zcc5=^#A5%`Jb(AQi9=&*z(N zJo=bqmm^0+yIzLlQe$_)sd0XK`6AUXAi$>B@?eJwGFP}LKaLYwkO>7ZKEb)s$DP_b;R>rWK| z&_Otysoifb-67(yKK?YbM%flj(Vs zXB;@>`-@iW26`girZ^&*QW!8pLe|voe6B_F#e7(vj;^`jix*IuAHxDlhkQ=LRudKM z7sqaEkE<6NOaimyj2WZaN2}3u=H#<2slz_N+iuDJ7sH#8jh@yFBbrjvoew(vMA3@W z(vX%IY4-7nxL&=<{tXtEl->aGp}xL8+4x>whmFnk!zD++djm#HF3vag^B%XWopbq9 zm}+_HmzRZ0%R-Sme#2bD8RTsj;q^e%zXXN!Cdiu2Rqk!yR>Bq9T1vh-eSK%qGuH>7 z_P03KxV}XWA?FI^<4NMT-&kDeMhEoxO@YS=w%^Cyb>yeyOSa1$4WbQCY75K~Jbnjd zw@Z27+Rs#z@jKL8_le4>Nr{LIOdXN(+1T2`llWNPFvpo8NJ;^zOfHNL&Evy^fH*!K zufy5yuUx^evbC=Soj^d5=55}b6sJOaM;N2$bnmCSbA$H@6U>>ynE6H! zbFOe+ct&IW-UgevV~HPK9iIL*N~Hz-gs!rGASk6)vj)173S7w4>HTjAs&)FbBnvcI z_f8hd$%Gzh zVDoGKWndAtku2fH2Gk6Y(9s1dgg6+A9Ebk!mnB_#W`mL0-($1fNsDY`Z@ai7$Eh-T?huz%Dz;qPbmPKa1mnV}Ub1c!~va*Yw-o%U$zV8-#t;e(KnmVBn9RKMm_Zg*X`kbLd z9vgEs83`E)*FpGJ9iNAUz^|&1%?UF<%LRVu#qElEd3O}s!&>)s(j1n;>XMIA(b7ko zt4G>^hz97vnoY_T;=!D2L`;NQ*iyB}0$=P{ObiD>?me{CL$inNci4Y+hDVQpqvOH4 zbjnrX9mDN@W1ZvoB_aWr;{$r}+>qG8f3{y^QM^}9-RqYY-^|sU`$5^2)BTi&la8X__bU#ZjLWp7 zu5LFKx-dfvGF{S-Z8MNB0cVo=p5{e8orC%AW219Q;AYM!b-P*meSl{%*jb!zKbRyx zXjX;4l~?w>84BZ{ug4(SHC5?=)(ZU(7Embs;ugv5TLNpt55{I*Vj5ZSI?D)jicdAbDaXFmL&U5gw7y8%< ze~!bSQ77+^q>R>jyvN{Ua`FA|68i(~huw-y)6s_c2Add{^NytCz40ntt`$&lH@%gt zsr3l27sEIbr{9??$2Jgfk>De7Ll5e$b=L5I}{Gh+*#Wy53G_2a`@0=av~S zf1OHeVo;I8*fh$?%v^U&dF%tsYF&C!3kx#^8CI&*>)M|FAhl+k8;WdbV@O|&W%lbl z9=IQk*)3Wq*S-)X_3heaA<9s4Q!kk!aHNtOvbshrue4ekE%i*Qs@jaR_9o0-hYtMT zmT)!mnv8(siP(c7Bo{$RMlF$;F-kU%gJFO`YYyAmRl`j3b2JUU^{-DcPk{k@Jg3o2 z_GmyL!cx$#J*evN32{YER0BSZ;=K4f%Im)cb=Io~{n~upS=erhDnmTgU+s6E0{SK{ zV$`Ca_);_t=5$Cuxm2ygdUyQ>Emtq2GnB0f2-h7>#*W>ov#`OPz4Qs0YH_V zN)(Ax$3Q{(f#A--IYMO;gCFA}zw`wzu7L~V2O1nr@8lxR#Nmkv-QJeUaC(OXBdh}R zb2YW<-5gw~78dR&bOvH;Cdg5;e{dlFJPjmRLHgHTuI8g}z@<_>9fRl#6BAm8fEZO= z&Q@94^-zU2&J}EI>@}iiFq$)dsP1bkm4kW=aC^7Q=G?|V8lX5nx+pJZC-g^*bq5jj z0Pn*6Tu;p*G$wL*BZ{ozlXd~-j|>crpWQwbdu>k+piC7lqM>4IJnw}R2vRBcr>TB`wjl# zaW*+@@aJ>2r!jL`&#B*ds6GpP;`VM~c#JGTL>pN4z3=i)tj z3s^UyLvf!JMIfM2dZ0*K`BxjW_Iqf=fJA}!)KtI?`p+^CYW>fyT z(~#Zv_cGcQx&u`}n5w9s^5ojmu8`lnKWOesGf!)4Jt-dbU|5IbIbDC&j5EHI2 zZp;HDL7UzCn7K6gNd+bYii(uehPC`q&)A~H%`WEM$=ZP`j2g!e%G97V5MP7U*SgqT zwuKz%c4Jr&K*WNBKbt6MRLY6==E_aY*YG?oTq^UE8rum* zOTi%IKDgeIQr>8CdW`y4dvFoZi>>x8eUaX$7bjrUD?edUiB{}o*x&JJ+ivwD^d{>p z>ZwH*GQas8_M4`78RQ%FH39oYI@OBox-r+OkQCk%?W9@N^U3?pJs?_$AEh}f=2lc3 zt)VryPDr=+D#z{1*G6UR=CHbL!zU93Yb#n_zdc zFwzykGbnjBkD7LRCknS-8GIv5wg>I;_%nD74)@a^jnW1|bVR$#5A_b%#n=O0S;UWX zuIwLH+kdfm(|WZpCZv%FlSz42Y+haI^ct%@msha+Ldc@qXR73#8?8; zFHn%nUs#fVoJ}#s=p#?WS{?#SJ@SJcTRBcA>&sPp-=$qoKC)7gBw%WqMj$RE)LI+J z^-DVkoDfy=)~EfrJj;fL2GQkCk-irMP?>R%tW$o1LwBfn9dFTUrr%>mVY60+=4xxz z`UJ-q+iOa$%lFn7xqAWaNf9DGkUtK8X*M+btP#;T3p2UwOgA~ub6(pM8a zKL09rlfgXB%tFJB#hdVO!WLUw-zx6*+u@96aiymxmBh$p4g(c)TKo-j4W-^@%28qDg{&@*_f*8K4Q@A_?E(&j1lvd`%|`i^aKe#d_d8Xf z`uD2c9w1&4gmU4z-pxi*V;J#2yflz;v|CrnA4OGTTpGd!I^#l(VYMeQi z_36KX%12I*r!rM0wumSizK%5YoE|6NZq2N|K3K^;LY{s!M?dU{r*Eauv18}$IQpZT zTAWi<^lksN9$ezIw0}WT95|VWeYkjyNQvnK%t6AURg06$?U;xJ);UiLmj7*?2 zTemH}&>2Rq-LU9JXiQv``P#Abv&vFRlv0boL|i2vr~61MAI8l_X_=S=czF{swL0kv zdWA<;9~R$kucwjt&vPVJ3CkY(8D)$DgEkRs@g^cQ-^6 z4b8r%z3us2`|SBT9nBa|iUYj)nTVeiXw+{8YcL)%X{oVo;G!RD^39gI)6eR_Ow!EF z4HVk@-v7+5HlF=Ss$P=*>)tr}l@Bfv4;1swBU@QYSy{wjj_N~StkuZmWP{5_Q9=Uh zlvn>n+T7-Vt63ZY%p@22xEslMq>SRMf?ydf`_JK7z zQg%R}I^RyySob3k_X`R7kwmnNb!GOrW>;|MX%zOaYp&WG&giyusG77(_vmVd3!^+5 z^DAFw%Og#&$Ricc1x`Ilp)>T@9lS5(|J*seV|5zT>4i-jHH5kS{Ftw3vBvT8X>l?u z1PPGS;RuZ!X3H&1S>-%#tC4S)P-*mHL6)!;4sn^R43s(HU!tv1 zooCr4?S4;`wf^0N83?A4VwmXg@6{#;ZR$$moV!DgT8d88>8xHMlz{p>L371#efQS zQRlq#n@IAbcDeb*WXbO@geE(2(xA-UEW zmY+Z33-a~`nnaz;w2KGL8)-Id?KxBeu(Upw{_FG8)8B%kLpe)&3LC|-_|9~}B<~m8 zI9j$_RyG8~X@!lRevHFxOD2vvXaxh`^po?cfU>mv^65D!+s-!S2$bx0_82=bTLd%I_OF}1|bY069WzgVwjf)%n`*&GM!N_cF-aB}z5cU?F*FQum zijy4%T|Vw2x_4a@%DMz_XFnF7_k9@L3G{b7CW<(|ZG=F(qhNqAM{F>7UK)eP0cr-C zU081Jvd!5$SKIuQIyMjbI+xP5(9zywt9}Xfz|)peM2+e2W`rj38{9CEis*M`nJUO2 z3c7N!}g#_g{5!v&o3_7@)M88No^Ugr7_qE ze+C?5`Hzg3}pXg@K38?SH_k}>5fc;NOK&k(ayWhi(aL;L=CM!tgmx7nN`s|3m zYj-STt;}capRL48%>U-cH!n4sbqC6<9IB#$XWIn-qj*`q8Y?d91K+ne{(Ayi33~p| zeooBCTs$7uO#czo9P=(S(t%g}d&vJk2%xvbMnhOS94;-VpE@+2oz}VQ%95rU$$-a+ zhc4V+?pHu3+@#>H0{?|!s#5-_37Bd&%ZhsLSeK!H_> z&_f-AW>x8UW$pY&9YfRpY%YtrYMX_Swl?9R_iB}u>@)sFa(tL%+-nEKFY!~pTbYfO zLO=@UY-}AJh%rs9KDs(~(`ZbP1sPdgAp~!zsk@p$Oh>up*r8u&%2*U=?PSRWG-Xt3 z)9GpV7{C}0M0HcC*@Ldn#eoyd!i0XV!9^8q0_^#=K*Ta-*x2yZ_ zueB@%ZelP{2$uVzt6k^Zklu|rwPh4~@WJdAk~8Bc&{KkuSkga&33nSZ55}prdq5)26fZG1?0y6{E)d7+VSTXqu)j}&yzEEBWjfqXo55MA-tzAk zZHa}cjpga-Wx>)L9B$^PhOE#@rz5HPoiA4ltD9}}vjJE(Ps!R-2!OiAxmuAuh4#C0 z>}rdzZADwba~KW*@p;x?KkMg^wbRy7Flsdv%{CRuT$t9W;$`DVI&Iptjqdec3V3I_~tbV~2hlDRP-iCMu7+=e5*ksZ^#Uv(H+YXJW z>^Tlu^~qRlje$uOsPchlNlZQ% zXy?AL1y~u~jm5C`PtG(w&7-0|Jr{|bV=x04)$WH`(g*S|pr9w7pVz+UI;&qE9&CI} zv*55;2z-nKx~&^ z9=~<3kuY2ir|QeAVhll*VO|{z4%Lw}5j8Fs%f<2VHmYoDUodt`k5#ieUVIIu+GwEq z&4{!U5T#3EYZRo10DT6wg$Sh1#i*lZNK}$;xzc#|dLj#WN9=%s327TT2JD}KRk+X7 zE)nE&r;Dz{gELhXrS^{LpRd8=yuo10(;&Y}(d%g=#Zfz`|Bn9GOz2}7eI})BtQO_# z$Ozh`hzN(({*8L9WDq`4ex%jBamq*&^|n4eJ>72GZkPED54GwyNlB@E)aVyGrSRrT zi$4ivY$y$AD+!|}x%n)|^$I0BrxfT|GpX(!2w(o+2QQmm}LSw1V=+XgTxiMI?MFj|1URO;neh1s zD&FSAZZm*PeQ>)U_Xb$^bZlMzS`K4sL1(r}H_rOT=JAl1V#I5ZnTZzqyR0HNJnBy` z=bf^WinZy;??p(7UHhW<``Ty_gp_?7rfb$@zqNAC-SEw4Ldxi0J^Q+ryA~%TJR*Xf zizD0Wrzvr=YlDm39r_Wrfx!jY$B;>pa)ss4HWpM=ZT7bed%WvB89&(E+T!eb2gzHbNkB#jmLQmAN%9k=5t(=0a{$jkgtYj306QSXWF=zJej{y4PM zWjiEtFW2ZYLjnxpke9{(Wf_mp2E#{e`FIn}wy?m3INxAbqp`)Q4cYx$j;~xbK9P63 zeYs=Ah)=e_U2eRnpU`B{{+jNIV!Cy^OHQbHj$c68X!mrDJ+Rj5_&+ldK1kv4)vLZK zb6m}wgoNG&v+kll3pr`6fs*oedW-!h#mNwm*TK-3c}k~oI$vVIL`B1MxB7SD{nen% zKmG!i`@0$#@TZU_VO#HLE##}O(pz@S*hWtJjJ5ym?r7g1@F2GFGyOrY;^KBy;J0VM z!|T#?TIYVG0CHNlGvi`nKxaxjuzWx)*y<`7l|X^dI48&*21A=Chd?jxUHS|$Oj_ZW zWaZ3UY334apVq2r|KZd!V2I${KIcf zk5A4B;~PrzXnvGf4|v7O6)!Zp?B95!;WX=AFUah~+fah+HyEPhRG&iYq46KhNBiUes`}LoKJHqm-{y0+dni zvtiL5aJbX5K+nIsSkBf!?>HHFDlBGd(%dB_>3Bm6g3uGcuc5Kr=et}&7+2p6$;lVK zpZM~kHsW+@C_TSEuiRN=d~Cxwe-nf7C;77{Ap#0tKffd0q&Wd-zP-5<70+J6W?O|z z2|Jh0HOB;C8Vzbxa58Zf|H=9{ap)b){tRD)Y^y^c6SXSXzG^SvqHIvQf^P{^xf(e! zdW}5iiW*Y3`#qk@5hU}?yu66S%TCwV+@82w zcDXE1T*wq~eh$QYt**WXhh5q;A9Qd@*62-zyFEH{Et3|1(B<6Gzr2jx)&uQ|tI4y&8LLi8!%gif0E^41#KB|)F;Fz}z2$)W$ z{`L*orM1ir&8h<9$?O3PP=;XSmGs_V{;OoK;bK#t^r!~{g96g%$YCEo{9ojKWl&vR zuw{%01PBhnf;)uZ5Fo+bCAho0LkRBf?(XgqoC^eZcXzkheDdbKs+nI?BUN*LrEV_g z9_`(|di7ct2gNSk=&lil^=rDWuV(&i`JIw}pX4;oLROjGn{GC|td5dG{g< zv4JPxZ$A$uw34~CRm|GWR=?lfLsUwio7_^Uv#8N=+KdSKY?hRNv!LiKY#>H7qceOH zmk$sXI2Lw9UP>*;Cjzs6Q`^>!8Jl2+6WtX<+&uOrbSj~n|5CW3+=jB_c0ScyEuQt% zy0^qHHScs?<#;37TCgg&IUrtnxZ3TmIj=_d1M$E~$^@%ZIGWbs0w=O2ZnDqa#Dl6= zn&|l*JgR6pe6af=$&E)qzYb=I>1?E}IoL0ZgJ@2zG0pzXZ!^`7NcUTUAIF&Zw0F@w zXCg2M?B?O=?ho#51_s-|0!s1T^%dlk3uP5Y%nCZNurLZ&JeBdwCqUF z>zI+8fr{lb@>f*M4?NI!{%RZ2@422(WI~V){evREHkz4QUZ`5# z6uaX;hy05o3(xzPe>wcX9koAq8~|&wwQUG9NPN701<};Z+Qhi{#t3?XZOf_Kc=oSo zj1;b@Ub(?BFrawj!o59rqP#jSQ%O{;F;36U7oqh64lPZ`E3j_!9*f`e0E!^XXaPXo zwy3#UdtYKk%eA1A@0-FkXpI(35YZqb#W+c4sv{NO7$$JHa@|!F8v6K9W5tW;V#V=7 zK$3_JC{SWG0h{71R@OcqE+(c3)#tBx7XiyDs%l1X)!Q#10Qak-cSFCT#L?}tmM+kV z$qBAn?;3whW^a}T6BG$4^SLFht@Xx3A2ph}|9UHU&}IRxr^#kB&A%K`g}~yslzDJ+ zZD?E+FGH{jD+}FX5Ve@&1ul0CJ>V9=9jKDn6a5YgkJNT5X@P;($+?0$nwk9wAZdHi z_G>e!7QIF2C3y6q3E{s&pSW7j8ip|G)@ZIfJKKBmR(Q`Bn<)UMjjxU-CIZdV(6BgJ z35liUYw!GK3{@=mNsW-5f@#N9aM_@#1x`zuip&f3*qnCIg@8O?c}=3aQ?r++w{)Wi z{znXqI8hGSSX@@y;N?r2+P0QMza?gi&&1PU!uApq0Tqvzuk-CS_Fw4^ zUj66T&n9@XS-JV7DPJ3dg0SDF?>b*dHHr@f8^cc@hK0vZShb>)!;O`HVXJqGSh~u# zUgkmjdZv!qRBha~`_p-EtrKvGHfa{M%>t)>x+y7K6y3rnH``xF%h_!2m^dn=EXp^5 zLiW5U$tl?J`bv6Qd%n-%eQO9%PDt_fcLNzidf)!$LCJfnkA|4jHHVC6?dwXAoLLcV zy-jAu!x>NvK?yUNj{~(;fw7J}J>Y^3n4NTvE6UzX@!yab&6R3wMZG7nmuwhDZvagY z^!cqT3of>Y!-%OBo6A6H12<4FVIe7>vy-^JXc?2;yXu3nwJS;FmN4j%$OcVEadR`FGxu@d2-X4k{5%znN(((eegtd~rMX7VS=l!;fKnenzo z1s})QAuTV!K-0LpgfmalqQ2(l0fDf*iNW63DYrI#jjsZ1#=ASbD%(RgF_@9ZT&G1z z*XJpiY7+A=*u~N5V(}fVt8rLd;W`OwH-v#xUIK%gjtA=elxXSe^W8x{+w4JA#rZLd zsjY3G^x5v_176gl#|=OwHZGa+>>$j6yWfuYbPU4q{ZZ#AtW2hmxUi>keafPbwZ<;ph_U5oDxgvZC$~~C0G(bv z9~CR>QU=(i3whISs zOdwd6mZ(V2>Y#4~aw1Ti0ftT`kO`A^Qbl3q6|X5&(pG8!G9sqN%IzCfFg|CGb4n%I zQ5fUKqiJh#2{}OS**DEa{s~HCxJh{cS%_};$5caG8wS-Mp8gpC5(Vbvrx))eWaZLX z_Y-1*bMst<`I%vDstPtQMp2Dsf4pvl2@8vU653f~jy&p4$0~Q4?E_>sUfxci>`Hd_ zZ90Ua6|`q7sL07wC(=~<%jH&n3|*{jvjZMbmOxy|W5dq4bpn&cSV?w&^K7lgu!?%! z^GYBIb$ce)WO)%J*E9GnrwdSeAhBQllbQkM+Se4hc(KPhT(7e_%5VFYnnACtcD!Gg z$zUxt^^sRzS*QgSlc5IXKKTJ~bY*iaF? z>Z4F1R1c)ae*=-AxD%Wd01|%>7&Dt4X+`Pjjpb>XnH{~qXZ2&Y$P4_v9RU`OCbka- zN|gXEaxSN+$hzaYl!GWZ!~=JW@?SAVsrwycH;V(q>Ee`_5Y8mz7)VOrokn?i1uO&; z7`PowRaOdj3YW)h}uve}27u_F#W! zLF>wfyVx3}ba``gd{YN(*9sMDJg`fD&%LiU;AGY>sfsi0Le-I$FZa@R_{&|?3+*WXG@!; zeI9^p!TZ0C;#q45!QityazN&s<`)tIay5wm{PK|p(7bO6wkjZg98AtlD^_fZr~dc9 zR#OA|aPtAi1L)fvj(fIOQ+0satuRxacz>AR*!cBgzSOq|U?|nQtR4RaM5&=1u-%%P zPRqzvnzSnZ?*L4lpH>d_2(fkG?!1kI2n`S+6isY?B7TDjf+?m0dWWu+BY4R<$l)(; zw#%FDKjo4jI*X+=+yD@>Jk)&st@*LPC@A-R z0YI6P$ZS<7e24&I_b$`!7t6an(3&h8wX!;mE}WaIm4%;)gPZqxg6~8%7V9nVsZAV# zb3MFDO3nV4sn$k36N}Acf`2aC9WFO0p+9!MNY~N?(jmWdPymtuLFeC|OH?Kw5f&7T zPx#p4y6beCylWLA4_J4ATP$`cRj6^;7BMFTEIa`^)G`%sHt)dfGH5AOsLI;FJNi2E ztuvYlV-@*~xIX`mluacg5sIWdyM!Qp z2pFyJtmw2rN5=7wDNQn`7ujU;OOg#LMd5d#Uc<%Dpi!-xPjywfDEj^=l7<5O?*23X zwdMY?D2t5u*6nf_sEtnNzG>h^L0MOwpP~Ev0XcGe2Xa$=KqJ-*J}|FyC>JxKaCEr3 zx(qp`QMbtS~ z-cBBHbA#fUnK(J0*c0@aY)w{ga=4usubLX|9&h}nN4rOmhhkI#ZG_C?;?9P#zD(=% z3+@mb2t_#q78H#Rx6h#nGP5#G)mXUtN8m;~RBnU8=t|V%HekMHY!)XanyIqhP25jZ zoxX9jIczNoMT{BR%YwIm=%Dt-9cFg8fUYq%G*l$uce?pm$pY|@_!Hk2#=lSY>JgY% z;uZ=1c7(;=e`4SLNA35aqj`NUKd&&5o@j4(M#9`35vWUUUH{LDKS)o{9w1&~_NYt7 zwgMuwq@-%J{#70kFNA-Am0itYm<~#z-dZ21a(=Z|AIgvaIQPpqk&Bmi`$A&g_2X>$+~5Q&C4TsVtdz{shRm{C zG{8FBIstji#WCiR3I!DzSW`c3M~~1?Pn@x~`?436KO*wUTWD8KX9%Q!@&E|R&DGv4 zR&?6|pIY+(Qu3ZrI$qLOK5waXM`|@d4;#GEb>PiqTknYL7nU=1UAk$syM%l5pwwV{ zt=x7!%^Xnj$Ogzj&iFBM^0FFNu!8B_Uti%47R7&A2aP&x#@ra6-F2{v$_z_{1o|s9 z_)X69DF}uw+tn{`h=_<}>tXNb{|XQm5cvG}!9H^axyA5PQmuuhM{^RdA|T+4i6IC7 zlpFs5lQe(l#=n8jx@nlBZPj$g!F~5O3jtmKc^*IDQk#04Ce1?PSsnYXmLro{jSPMO zmFlZEuSP3u$H|dz_2={b(!cG#(=^T$AF{A`$1kqjGuT^abBO>&P-~Y!Z<(rhiB=Ml z(%c~iEUonpAzX6Bv$TfoiA<`lM4UGKcKs5S$U z{sctv6eo}=)7_N`Jb@2j`#JIy*{L}2^0HNo4v2W^Wg?@_tgEJDK>jy6p6B>5A_{C6 ziUqx%a>tA}W(yYTm(8nZ>LfT*RdPVGJwdm-F7~tTQBeatP+JD*{NOsB6OaH!f0)

P!0+Tajs2llhxJa)w+t#r}ezZ z`S#Z{PS^1!V0y%0b1pF(m)Ww5^YhwRmjG1pCJ=Gd3LrAq2WZS8>W)o z-BHb+pPn2)>glHto#uRTiv_YIpx5W+kFAa?O=QXpGiB zhwO?K*!Em4CN{Cravsj{t=QgJbCd!s0p6rJSS}@3H%qs>VE2iLEM6l2{RdZJAC`WC z2eNqP&+x&qbO`8(0#+($nKBk70PIlyih-1Z9LRAL^S(=I z$m}32Ke0rAmL}<)W=sG{1bT$L%aFI6@Rn$IU)wjSuUtXYdD1ylU~zc=^AG870U_W2 z5VI3jP~>2tOM3o6QHqaM2UBCCqYQ=|`d_s_1de|M^}>+R`g=RmK9GMRAra?N&gI7Y zM+;9VpG*M*>@~b%#PhxR5>Vsw`j2VY6fg}7_~}oPw}Uv7_8C`zsED*oD5|d58c?lU zwu*6=8ozu;>j0%60K?TgFcc!-PbX1K4uSlS&j2XP<@Z@44Ew$R`Jp`nX*_bBboMRX zY0g|!$FsL-Ty?_Vg(ki!^wWI}1rmY$wJl-g)xR>xz9nVp&&#MQmB;8>Evg}#6_I$HJLH; zVS1HIUM%T^&naukVlT%4%|6c#PC6mEJBTm%3!f+XM<$@bD2BfsSF3)X1^U^m5hDyT zYeYnySww#;Kt62sfxE!M;!x&ifV_TRz52-#Ei#|fZhfPhI5R)5r(a0;3reI~=pptc z2QzJ-fQqmJpDM51cd7R(g6<@AOl(9H1Y{Icq>OzM3jIvtB%WL%>r_3Kv=g66WpA{BP# zv(&c~5whhI5_1&e=#qbl18qYl)OTF}h0Gwomz;JHXf~3*`}euHmINY)uzwRNz*{D< z{eN=knGKDD_+KpGuUGv4f#K?ZV$**;k`9b3B2b5-{}YEEGjg)}T8BvfbxD5uSVs5B z_WkcI3gr2vQI8UEP^GGqj@4@hJmG?whR z{!ylVa77;Mq4+>U%JUA{^>d#hGL05==LrTa@b$15{;FNR2=&jr{Z)eGHC+mH3e;9I zJSR5qAIlS>4jz~eo)d(PtMen0l1RCtSyO%06r5Q*?5Fk_7z}^k=#6>3;%nMk!gC#D ziR~dK(Sijs0oF@p9C%#zASXcd%*o12%gGtd(nv;8Py4>|%S}{hU5ZC?W$3f1gIYn!R!Xg|20 zy@k$dw(pXXC;|YhomJ)f8p^iUy`fy0AD8_i|*vV_WMmzwYj;8 zim2Y!FeAUPakG_HsKs%W0DY;}etlv&Lk}QR~H3xc9{;}K=}|85^rxCCZKOmR+Nm^ z$fFgr33^@Z4`AXlT4*mu$IIy&v(l2q?S@-j-z51-Z%C($?rzL7QfrZL*fzq*PfmQ;5)Hc;X3tq4R1ec%qVWMxmsru&&p>l&T!<)pcrWc#zV z_+g)V&OR4rtu*K@D&$y?q6QQ5f2O5}u|fq`XWa87`l_=&=_yP+Pf(lI`jPhu zL27R7h7Cc9Fl}vYjOB%MP+!YvsP49Q#bT=|B&4YR$9*d{#7G{3rhMeSTcP@re{`Xo z=5WC-%g0Uq2#or!tRPMMg{0Ij z!(htVNja!m%cwOdbrZgwRT(K0LcKrzto#19Sox<1V>chunRO+?{L|xjfby+AupzvI|Q{qyo7F){H4*=%&Fu)Wpaf} zOOe$N*M|KLb!Rt#-Rl66ql<*F%F1-1z=74>m(p=*&(VWE&B0X9+Y(b0R9Yx->pq48wOQ}(-NgTIz`fJOiwj9TMr+zlV zvZ?nWs{H2)_OrG= zuSDNN!;b#B(xhl|vQ=!>MdTUGFzc2Q+ zgI2(T)3L^;gW0Cz_*hhCTuZ;N80wk&sM~S(+MQkR?Gi%^ag~j6;5ZE@oQlI*=kj$* zLv%NZp7_ifpj@x)N!+(*gc>N};$GKeEv*3aS(kh2W@!Qs{t|o=Q~Ry*s(@e0+XMTw zBl|QS&$8$%OTSf>H0A`sdD1LQPfqp~5=a+R3a=ET2gUiHRA3 zXrqyM7!VO10sx2@)kn1k2O17)jipk*@iXfjk-Hr3S-CmX7L7&yBqb)wCcDM+KgSgz z$|;+hn<>mT#~V~JMG4XGx?XtdnVPoqG5H$65-_$7r#55rGLhnulN;(9cD!arL<;w( znk{X{PDpjA^`lavCs(Yj&sd|NLBIBX zj4H&81HPrQzR0h5WLU{v7~UR&sa%s1(Yu`Rd@{Ki-abX&AeS*WC@j%Vq1jm7yi0=7rRVRs6(6+*rS&uqfkK;sJw`bvIT;`_~Z^UYWbXtsP__E8r`H#F4v)NX-oX~78_Ui9T3e)m>0?OG*$HKl;H{%{$sigLXgkccQ%UY&I6xO_>A$IxI4dv4%jm>?^k?Qo%dF>lkW zB>TPIi7vyYTTOJ^L{!a&Pj12gck)@DPG*PF#CXz7O?9C5@Fz-(UIo!E)zUxmEKQXR zO>=ggb^~SdbhneqQyFp;Z0r{`_SndqNQs|f1rHoOM_F?&$}kq%5`|dL20VFlWDCfL znlV2{38kcmRZa8_!<|heCJmW#!0#^1`MNJci|V+(6o!$`-%0uUfP0a(D{XgB1iHw% zTe0P+nIjBPZ-vCrEXlx1mQZ;Bn!etvBs6nY4tH01w}6(ZNmruEQDOzcW#X^)R}tA% z`qR}+Y|$Mx`-~o5|cHqW5-Sq8nK-&1`SosH9wu8l7HayezM` z+N#ds@;Nrr;R4N0%1Buf(q9QLr)=FzbCHER``PK5@)1N>L&HvD9Y4Ql4l5bwt`iR$ zXc*|2K=VH`QDG5Lp)pZ^t)H3r`u)ia7RtsyO*eoX8ZbKf>1DLJGNfjh#!8Ij){hgm267hvd=+ofB+bR6CO6bm)!FnKLff=@aI)QS zl>ip=qK3N?AM}QZa1W?#h_-K{<11etlQrTn!K?B5`}k==qIF6 z@0gcy9T?)f?m`UO-TG-L%f{@Cjux~2yq89O|K_wH6{_2;b%D2YVPa$FoDI0enl3t+ zuTHpJppr|4hl9TM^mHS4!fZyt&Q5-Np+rv>7_LUb?G6xv!=9S0vytA7j|Rk1rE*P= zrLX1XUv}kb5;+{sf@Y~VsZ}p8jsg4)1fV8Xoi>-q-AX6BrQSWrQ*Qh^zQ#)nvA2_!T---t~#$9zRe?NuNECj5?SsQcbzNz_F zNCAqpTmt=&tb&1SkA388><^IqyjR{Nmsa^2ib3*)?5l`8L;Pr!QgWf0vF&*chd3=k z)$~iUX_9Z%Cn4E*VRVT&vhhiBJvw>WkRODES^iG(!bTm->oYa```!VHA15I$ zIef48l#I1Ovoo;$8yN;mH)?f$dOIezxT4fvho?RacO#N-Ge1Ht9S=~29QzVz+U&E%p@i2VjOU9*$uffi^+9iA-dWLh;D9=Mjl zp~fpuV%{(lOnyz>tn=7`cBMmhUf%aWKEzLXA^W~$v~LqZ(DM4Q?_JJ@d1GqsNvp(*uPN&!-Y{%$ba<*uHyRg z9{fdDY*-mbs85?+kxkW+6b;KqZ>D%Uv&0wnW;9nib5yhF^&Vouje!ReWA*jKC68Q| zij22%z#+qNVku_ahTa|)zoU~UlZeOadN)LHP318}^|ZC|(8AyJ$dpstNs1E#;y0w-dQ`B?tX@n?>#ZfsVU4s_+qf|R7<*}g)cBi+m|N7>2hjSnu6W#Vm*;yM|OMPTw zA{LvTqobpMeyqD|6>tGhWVTT?CjzE$F0X?uN(-ciimTJZxwxE1oLrT;!BD)R?10%+ z4Fpm+$nLWvKUq;$O`lsF6B%xKxv+W!A9fZUY%A+1(cY0uYQDR^@3wSACM}&YHFaf$ zRzm0Y%)u+2AUnkDXP%#i^;vh2(uIsRRA6{IS3@<`U~-G?^^QrkFx*YfQx<&(jqjy% z4)aH1gBR-;f%Geq@_XiTOM5h91lkmSCCrJoMzh_IvxCj^PScl1qK`Ln@y4Ue?c$<5 zGALOFvUwPF(B+86v`R|cV&+LH7dcmh`lQFUT86lo!XD|CRb|EDFfGd-wLc`;t<^}7 z9L)m?u@9N6N(LGqlR1z5n=j7TX9GObapvPOEO3KNVn40rtnSNW48#Svh){6LYGG&H zCL`WtYrm%8oO$l#P36oW8%YrueOgQ^x~70G)JCbw#z`?0q%g zlG(f%WGI5fGZ=gZ1kxy@8cBz%o@1-CC0*5Ob6thq>m8{bLvrM5`-6us1OycTt=Lnt zF*fY#bhDr%1VF=C>Nk(24vUP}72Ni&v&~-3@Hsw9$o{c~iX0)LK-6lXMO@xiHXsJ= zJSOckzp}A23%0E5Q={(s=Hwvyi_HeUqeObXE(*I!(vdHGdr78Jj4kq#IzNf5w5;h| zF2~=CR9vorhAYN%I31{7*6feT4`nW>3ydRj?*jzc=v%y~TN>*ht|*MOs;uCDO|iIe zA=M;17%8g6QEm1gQyfh%Ajv2*{gJ|&Ey|W=Z!*zqA~v(EqL*QJV3H7*Zcfh96>)xj z%CP@YhSQQ_338u$M!67+y^T?a%uc5Fuv+u7i5n4QAjs?XCU4fRxs6GC1Zx{_BzR@{ zgrq1rTSA4l+uiCSxD9F93ct|AK|iFeeZ)&@cx zEdx*{?Cf+*^yE=VMOjG;plX4+tYg0n^79uplWuXOaII~tjPJ`-op{g?q^2P-@OBj= zuB3u)*)k#nWr?Mdfr9+y*t{JDe2e|^<#E^PXIp$1L;iw%<2innIC)Fjg06sM$jtFx zojAm=Q!JkR%Rc6gn#;{YSH))%C-&;9&S*L_@kJOZ=|~O>rcfMuowg4RP4dpuyoxj1 zBT8&Ej?$G|=|;KvzmUDsx8$d+ZwCA&;RbfL=qtwS9#>wPtPE4A!kUh<>M(jDAn*du zrSE7_i;%I7Ql*&c_cY9k%zEF4YZC~(&lhWL!@L||ZE*mcIWr*#Xa^=^xvDG$H#<@Z zlT-(z1y<*VjaosCjaXUm`}1S9VJ~Z5vna%Qoo2IE8Ea~0(hyJ;WvEnrcWFpck`qH` z6S*pSD0LLJ{vq_WrwB|J9lyr zZ;wr-rj|+wagEifR!O1d=@f1(Uk-Pka#J|XlQlVLX$0;WE6mEcoDat!bEKO2B@MJm zSt-}VdqH`j;Q}p&O$oxR(j%*Dx6a%fa%idDke1A!J$uiqKa!WPGJQ?|DJk!Yi!sup z7=TJcx;EcaU3I_7uE5yW*2Wd_g6~Wgs|n>3br+18ZW)Z!SJDu)*CTp4UtKW= zj&2(pj{n%hZqa0x=U&TL78(mPtzo`}Tci^C^t;)fO#FiRm*TzKaUfoPP=lK z?epctSqe;wippMWB{>na$NmbL^iRF+*>f87h!%d(AMh@)nP(bB<>zP1v;4(AGIfka zo>Dv=^a>Zs9kp^I;`LVBa~|KV;eE)!02LLLRF;Tpfn(=K*?y!a6xP>yBm2SiJL-4( zbOOsb{nO-MJ-qOL$r-ybw|qNo{d8mTDLgjzl>*}Y6*kxt_>(1gJ&hfj=fOX}(NW8P z_xvLJ3nKDTM0D%RnbY5*$VZzItT}mcEn{piJw(<~ka@6?TfF_M`@Qo7QyYC#?p6Qx z9lWE;d@#^OB&C6B#r0{x`MXz^!T(Pe2%Y_(mRai-!V>sZuHfJ*d+?!~Z)E521&!w2YK6<_8xY91_0H2lGmK9wt4;suUoX#B96 zA(9fN1u@$FLP|&xC2)QnK>j9qcmI;(=B9u8IBV01|BceDzFglWfgPTVnx%Xz#gH8> z_MUNu0{LRdoR@^f9#;pR9Ukx`{9xfKc+d_{(29`P$mx8uwi)wTOa$uf?CPfKL^LWR z) zK%~4h_Y$+OS(xD(zgi1CM@l;#f;xOYsUeu z1oEf3M6H=7mqVmvvR;)d)y0?wEMpY#q2`R`9@nd7h_5gA0awR6w}bW}aJGVXcP|Sm z?R8>@y8yuYHKLIWK_OlL`678Oz=kp#*Y zYo}3SjOLD}G@08xE=vQS;xOxxj(7ejeMQ0b7P||+78PR#nygbf0@1a6>rxh4Y`sc0 z2EgHBFo`{)vB~;;qeXfnhBUm!bpZN=@zW>ufozpYQxJ2{c=x8tzGMop+g%*tn>(L(5sH6hj@D11kw4Ml2Cd2kK z-c1^n$)^30X2CA&Ji_y(UcG;@faAT+g5;Oog6VSOUvz|#WxAW4*UL2LFA65jrl)}; zeMGs?^$Hwq`V(9C)+5C9-Dx%)9UalsjgRk2ozdn3!EH$5$&q~$p~c;b*Xa~b0C9Jd zy4rX4LeaRUJ)q}lxs=43U6Pl#y)-;}Fz1xXsc=(CW+Y37bmBzji=KAy%M?4_dv4Wo zM(R@7LlH%XMwm-Ca(Y*WM!x=st4+E3t-SY^r9n^KN_P;p9Eapl&fBUvBC|^@=4K!m zC-{D6T(wWWemm=r&E1*T8~Bu|nVC!rQM~RHFh)eFR#ByqB-9DL;d;5yFcj(sWTZdN zT&7Hk1qDfM^o zmD2XX`RaJnmXUMV#7QU~F97$2r92bk1tlvxDH(CNE#0I$SlGrS-&OJd7Zt97Vkza*S1iU{9cFO&9RY=u>k@Tqh zo=Yw;7OBZ%C$n(x#KO@Isx*?n$#~8_()9mcIuyoV9>X?<;47zjP>%obG% zmv`(?`XP1IUV=GvS_jziPyY_B(?}e6GWguV(!88(vVs`8dYQi*LM3C zq2NH&XjG!gbxxKwvd>)M4gSbIHivCmWa)KIjR!MneyqxU$J1YOqIf9z-~1L1o!&QQ z@M>W$)5_x(OKi@iRw$1vhGx}0aW0uOJK2D&94yrEpKiyJrxgF zT^{_23$C0axx%Ph%MSnadi68$R8;pR5maD#QLEV)DVF$~vPg|5GHV?J36GhY!W=%P z_CCuBv|ktkz^-V+c4`s;6V^6 zkI_*RZXYKy=&~*@4>{{+PfO+@M59t^;mOGQkeun4%vz z#U=s`K)%4OQaHI=1FZnl<@bz#j7Y{Gr zqx8g7lNoRhMRHUj!?HImFn0ywiT)Vrq88PtKS~U)ib7G?5=Q~IabWfm+2poS_@txW zJq>39XkYB@?#fpyx4|l1g0`8UA%WDMbmf4)RKs9AnaT1U3yMj?qn!)QU7&=WJNX!U z@@H49yjzobhg8MR@HRe`T5E!-2ZpcmSeri*A0A%g^@AC9hlct37&;|y@Fpj7*k#F~ zh)N2LcG|3p@y_-oec?r%-y=?WOembL-JM8!6Rwrzr;3eY7!7n_o5!58BF9Ud5+pFY zxN+VA8fKky?knbSLjMwqG#4{k_^{rgA+>$(;WF8KPuj%1pzss6L*83AxGaK@|9&{c)c4cATb{V-w8J+zmmR2PN{;^=)V)p=1@;JAgBnQ5uYy712UP+^P%| zG1T(;p{z05Vg`P)l|e6e)(@_QZ9K z721uiwC)AEA&DSvmrgL=Ey5rWjKqn1~0G{&-4F>XMTy-``m?{Ri>EMKktu|G9xgah%($|rQLkm%qLPL8mI-4c%0=HUok|WzR?!c`&KGHu zM^TYyvDtK~^K%hlwJSilwQo}AD-6Ad=Xbd9;hG*NrIMZ=Y>*W+D=P#if2E<39$k_@ z@rGcgB|C5rw7!;;bt`M*3#(G+d27z2V!07fk(vm1x;dENu%Rq4v$;yb^18QIYGG!E zC*oH#7CR9{BfaV32cl(sq;!F-FH8vgSG9h(+pX#owWe-aiPV|3)Lc6fsgP7g#tHw8 zAJ<}SxI$mV1Na!g7$foiR9Vtv!RmTnbeYL1>#{;S7;8Rj;7?|?Q+NPg12QMEYk~$u zp5F?KNJKML+_xh5&gG6s{DI4GaOk;VWQj!mQ6tfA zrf;48b(aKqIOCxDJ~)A^ML0gjgba#xZrFp*}Z z%XX%Dv-IH=SQyrR$YfX=yb~0tCX-|~D=ou2acLQV|%Zj4#qw--+zya6OrCzCB%j^2V^V77k~2 z?a?`yvy*wq5s#1>?($xLjL=JIuob@h@i04UBvwOK8TBfU@fG@BELZ>>x<*E%`VNQ! zHmoj>z>8LTVwK!vf4*0jJ-Gq~tunFCn`($#-S)=3Lc(e8?+BCF__M!s!U(KnHRSx_ zRFoN1F>EMsv2F-1+7W*HLyl&wckK0#Yl-Vxu!54$bjv_lex?_*$&ZP6+^snnhJ82m z0Ly~*@Vc!}MXE-o@}7pUKmZ~txRX0&M&+tYdx8F^!J)L>AuW^WrTfT_G~sHhvsArqFkq3WBBG;!Iz;b=e(e^?^!_PDqC)MHGeY z{l6*F7sB#pbqBVa!x5Xd)r>n$0u?$!6h2}sJAw_lQBhHe zrt4R^3m+(?9Yyu3K}b2n`O2YU7=u>wb#LETi6Jj*Dda;YkzY9xOfQDfY4E+*iH;}c!^YOQX{!EI(IRNSPC~UvhCP>x3*kEpz$fK%MJe)mNnLqV|E5#VboZ;iRuh zX-Dbht^DIPRNF@TqTv3*VuLV+d`xEeRM{p_g_spftos3yk3B_~_H;^7{%|7h z6#IsuQl4*MTYes6|HLu|?&aI*+i+M^szqk=wJ|J((Ou3e9-SpZ{IHUj{9<{Mt}bmS ze7SlHrC&-q*2| zYVS{=t1#7MA@A)U8>3e%rj(_K4m8c#hSxMP8Lu(g?WACuZ**A%qYZ--P^UWbPT9RI zwU>{IeF&n1Z6$L}AYlOHQOMV2iZ8}4W?3yE>xaxewN$I+ZwQLJuM`mo>ZA4DD3qn`80Nj10dTSgJ1V0d>)() zn?F4}+Z(n6%C6(pt_io#5&4>N>6X?rc2}98j(rVBW|A=88#{R3b6g?iXJhRf2GXl@ zR<@{zFbTA!P>f6Lk@qnKo522{TzllJD*e+v3)Y0PA`$ywcANZLk47~>*MtazFFm)u z?6nxa<*$gV=9>?wE@>OEyoZnm?Q_(Z7|ey|V`_ztDJtctfnk0%Atk?jFSp`yjLMmz zkJ#r9ngoy!XNNFJ?3Uj=!6^U05>HT#7_$|cE6(N8U%=D<1)%Dw=*Mn=Q?9ZNh`04e zp;H*?s4|ktmCi`d+g3w}0OW$c_?o$jO&TKhT(eENft_u>`G!YQ@i213nfCUtf-9a1 zbUBAJc{(ee$KuJ&5_!5-^O3`aMTaV!>7U-06D3q{+unEWzqTm|#+YCmGvIK&p?A3X zRm67D;AFos6wzeT?~O5<1837mw@ED;&-e(b>lZ{MA(hS-Xo!XdffBj(N;Hwtts^!s zm=?P@X*Of2=HqAUJ4l_d2duO6u4kP?Bq_vrzN|zc;UGM;5Fdj$(Tc%z+@`zuC7ur( zTX(&)Va^L4RPmC@Ts~^Vf3X0A3e=d6x$TVpDC+#B$uPtitOhU*e73Y4QJE)=N|9J2 zd+InLC$}?IDkO2Z(3HaN*6IG6WX^QK4~-@m`S(m^ZptTD<$29{_C{1{1<>p66pk_L zIY^*0k-7fT$>mz_UamakN`OYGkils&A0O2fw3G9!EAW{QLg;EtqgYDQ)m85)&ZAKg zx*r|^iD**Y*44v#Z#c13^JpF&8c{u-j+~p@qY2yP?i=Q_>+9>qW-B#Sr%POxMm^ES z+QAbAOH|43jln41@91#2?BnGwG@v?tFV3hx<#`<-U$70EV7EVIW8RrgR%i8kv9x@^ zh{5=9|Ni@Mbm*X3qvH+4tJ8{v^w~24nPS5T`I4`|5iIlB6^q>=d!a;Ap3kPy`93&~ zHJhWJ-l~4x*w|Q4*O++rKxDjZOvdC6pGk@0(Wz|0mF1*XtQU?Ike&`jH! z8^V4Khr>;K2FVbYScUq;R6-2g9b0-y$M>~LTBC)N4nIV!nJQL;aL+H*szrVMXd-eS z;=!IKjsJ+HV|pjB&zsK64*7Dwv2L=|wOg2*&O}hZxLe1|!J^a1PE3%_5wbX#n!t$g z=??|rRJqxa`}t2bDjok!OWm=ibb-qt+-miWALjw|xk|DN*|s*4iw|7~m{O~(P7mcT zmgEJ(nZHj!wz0KX1F;u2S9-BUF()G3yTuZloX17qHM}C?ul|zdFYqdpJE2Q2*jUm@ zw$XXLS?5-j7ZX}C1M{V$9c!u8`n(bUS}KC!CG2ks)rug-eqgQdfPuGMy{22!Rwk;?@lI90Phg`>w2o7z{!>^>{R{nRA^F(n13 zu1D9g^fnwAU$h1h{ay&*3n!N|nJ(lh=E&xYcv&Im{>ht7wL4t6#9$`YbN4qWM>ZPC zFW~XD!KLCKLEU%kqol@wmd%^D+&u8uF`rK-Jp1IXryw)sJ~!_4fNz4s^H@7E_fn^CF4 znv}@xV)rUyUek}#(sy>48Z%oyS_Mb9Y6r`uXF{qvU$f4!Xgi+TTfc4!AAfCZY%Hpz zyj=Zh04V4r#>a<}&x+{A9ih_*IIqN9hQB9oa9^HMDE+`)peaAMJK?QlV>Sp~7{oYZ zy%5#GV}P;JKX7)x;CRMDSX>gO5KIHvj!l1C$zQlyGgRax!nY8UJ0ql@>rUa{hz}Mz3k1?ZA?|I~ zKty>Ai6Wvaqcew$Y!sc%&`>0v#<0}Vk(WWEs7U-OqgL*Oxm`YiG7t<-%2!C@9~f>C zeT(1*t!kI`JO}kIs>wqbta|u5w=tR5rZIzBwQILXEB)+XG*y7cYtLfHo(!A5z{&hH znGY(X!DQ0j67K}Fn1Uzjper@H;A=d-#=#n3>}x?Kx~RZ@*p31XG`;UbKG@ZW&AXpb zT>2b%k&nwgW;Lj{(;!X1j7*llk%=sC1aY{$fJS($6?cj3k{JYuyh4yNXww-SkXS0q zCl`QY5&3L;r|#syb##h3RM({s?Ef;(vyhlvp%2@fU8BgDww}>w`T_l#;VdI^?W}^@ zg5G7?0Rk3%N<(q%Z?Tr#u$G_vrHifB(gESof6>xA$fxpd|Ne!A+ENR`oz8VR9B7D| zH}`cwmsPr{uyH)!UlX34rj>hIZQCbnc`xN$AeM<@C^UFAxY|P5(2tUPsG#-Sxz(h0 zd@7}0L4gf#;YkZMLp#OGmrC;D+4&zW^Wl8dpL_&aC##AF1k1fu=fm9>&>qx z`V~~trYcXAvL0I)cYh94l+Ms-X&%jwQHAYqpYg0{n)O%m}v?cU;J|Xi&b&HYK zd5?dZhVGKjRCXf}M}5;!YDP}C>!sMrSoM0h(oAcr;xmqpIC^cZ>Kyji7kSxE+K3r{ zMsF`+*^QIkE2+JTY~x4{Pg8A06ho{p91CE6!t3Q>+@q+i>SFz-(VDlR5r)Tz_z;z% zDDf0MZM)f8)@Ye{m9T~Pwn@!svvF_Tz7bCrn~cDRQ%c;<`0qvMQZS6G(IcusXr#%h z&9(rh7P53jBWa=^|2U42ixliyr&pzhoi{HJp3g3X6O0YX$hsi!gF$?Qq&zEc)asN2 zmoLU4xm$P@#9R_M zn1_wV0G5=~Sic&X1xm-uN0Ve;|*o4B~lTE2*wTjP^$gMN=h_+ytjKXBB$t zRPE(@GJZ<=;LjyR)+zx5N=L;ce#8E6QFERPIbT}2i{pvMq`p*&Ws*X4P$mSOX_n(T zZddI#mE>Cy*ZLV0QaJ4KoR?Ixgaea&ao=KLsi}rH1~(gVOr?0UT-g^-$XHb~BU$dH z3VJUtWo`wY6v@QAOyU2%|6U{Y(=t_Kh)@3XAJz3y@w}L>CT+i{!GMICn}t%6-&B#q z)bVM|3_Uk9eB}z?*-wUJiK7%T@jxuB7Zg#A4kR!p@c{`Pcwt3U2^z9v1R9d*`^l;d{A z6h@37>QtdB)I_6;zCdNnr{R>`CXXsmY)(q|95XQMv#QW=Ay23uz1$=)>-g1Z>`E67jKM%@h}%}s{akP* z2B$mnZc+cC@vc&Ve6?*fa zjzM-RIYZg1t%aT|KQ5ZGxe1q(oUKGLTSym{B3Sa40Zj#yMA%fe{U|q6oF$!VD&PE( zQ(eWwR%9%f6rY7O3^cmtUG22Xd@q8zAlW_5+J|v6Z&kCB_?>>HF%PElmH;W9zhjK* z)7VZK*&XedtQG|t6<8T696W4nk(e1t&$9-GIX^?U5bO?V_mLAAM(9Z*jW&B@CbUm% zzY=$7qwh}Mj56o6y6dQUb3Dm!al+=ZUMTsaf}W#YSYNSZz+2nk7J0ch?>UfEC+C}> zG|(c;>l5_8Z@SSX{lyf14ngJ9PCO zwNqC=LoPExu2m-GVw6OAM>2nfazm+KfqE=vCRGSFa$0+6&gcL!Ze?=%I-lJ>No_xU z#hwjm*cWH5RGs&`w#Cp7DdL=zl(OQcQWUdxT@0-}Nla`qAMNzbhGfXKlmXjGJg1FM zry{3b+#^KQGkBe6_YD|fdMV)G8saL1*WCGR;p;Gq9z5=~$u80busx&eNd?lvpD!Sk zGa=741Tt28Q?whNluxnMWpOt6#U_!W8duo2h5k-QY|#?bY^JD8XQd zfDjXjD9BlWVdk4P&W{VJF*CJt5nYqLCrx(N;moCcP{+-T%pdheyn zXL5HEnVC&hmSD?fqq3QJHcmO0U>s`uZi5tvL(;kZgLJF+MBI->!;GSKC$b!dsW8fo zWygOg;5|@INm5GSDatfQM&No0`@}r0HRhPr3i=4yQN{tO6nln~I;Z=vnD4QD3ckzZ z_4n#-{XfyAW5pVhWc%|}O_^eHLZ|fqfI$B|nuzz2?;-3|-)vtb@p-)MTw}KRNx>9a z1ijdc%Ea%BX%K5O+AgZ7_vomrnPLh=?+-7lK-o%-4|GvLY}z+!#k0Dz@xHHnm=Sb zKrd#oY-X1kQk*o0I_l32&0mxDiJ-t4g**Fu=KQL02nu$Hh|)f}sT^~8IRiJE59q7Q zkl&oU3QQF~Ln>}Y30hnWPJ)xT+-UsMx6Kjh__?_`7Og-nixo9ojj558r0=6OK`2Q^T+l1cT!073BPH#!)CY4bS7QC^c~}_s`C)+N;+@D&__c9qWwb@s(V5pnJyc6SA=@_IrT1f!WM^lgxlCF2o%2FXLrpH1fpN9`uwfv= zUy&a|7>#TUTl(r-q>iJmLpOiKk8f3Gt!OsL)&htY5Et#Y_X!}WHyr;`x2i>YhpZ~4 z*FBe@=155N^{IDA`|@X0yoL3locJ?(RVpEne0DC{=yE3s`T8f=j>CWM%8Y6j)%NL^ zsN@yfR`1HXV!FgH3Nj-J`&$|Atq;DF8dA!ISq4`US8Y8xIXFjdYQ9hQZ#{%u7IB=W z?ySPjn`~7#2wC78wgyjohTb|xlEnB)L^?OtiuJ(gC~F% zc|83~5yNt+;w-(rFXG-5Nc$Z#vWmU`Qwvz_EWlQSR*0L9y6KGsa8>W|zZ8HhnQuD9 zAo@Iw_g;Wd74)YOK+M6IA7?pUWyND_GX>Xeu}9`u#`egOiiqF&_E3m7jT1%BaKP{D zrJMXB)st?f_Tq>8G#Qu$-IYK;`(@|~4AQ1BW4)@i%-M;nd$J>7uZ9!b4MPZ7>YDs< zVQTJWIQdgFsS7-o&v_8I`Q+|sA9c2Alf(N;t56_DgArZ&_Vx1GNmv7RP6 zPo^I*tk3hj&bRzkFaS+4eC@ODu0L{$l?pAR!DWkHTuf1{a zPE4SWras&4xYs)2eYgR9Q7KK1<5bQPHdmjzVG8Arr^8Ji+Ba^i3qR=Z$~xujwpUwr z>4wU8zW=Ee=@qtuS2sXNmzY%|itW08{ zPuSWGn8;8cU(M%{k&MC}OvoG&6W-9lII&RfuqV^-UnjBrScKVN{fp{q5^Ak?G@20T zijTd{I^;*Z;qy%BeBI~5azZV2F)f6J{nf))P~a4MW&Bkf)kn(k=?NE{LZf&-%hPA( znVS!3NW73-2c3~C-Z z%oc!orTp|)#z*S552%#0;Tanf6M8HGC;S5YlYO0xopU;y2T^r`f`&K69Z%hJXWbFD zp*yqufsXJk?p>v)tE7CcI^Kl8_utOi*w_>q)bYLbtbW8N znX5i#sosq!)RsvjZd$R}3OFo5n)UyD<$wfS`I^h+1oywx1R+A=OXy*hB=z9)Us1aZSIM-PiW zWho;Ua3!T9l6m!$kw6hd60z4>_o#EYwyIIYf*P)Ur$bj(mc*R{82~Ltq)> zD2`59Mi5n47I~5n1#WhqrpTY@;=QkIBhPnirr6D-r>mtN&Wdg{-boiL z_E}Ef;$>cM`GT=jG+&`AT6n(tgpXUD$xt-d100*(7+i?4y#0-tpYcgx@Vsu8W4avC zu$xDN`{{;EzA4Jlbl|ejU0;g|doMn5j)NvlTi$Ne)4- z2A!s!Z_#pge{NycIrK2DJ=)8?46^6~^rI^EulIj~TK&$9O^HWF9A!=R_*T~qw#vRx zR<9mNi*}^KQ#Du&RTwa08DnBB4d&k(t!63=7R9awwUr6P6;9Cw;k04KfHavVg$p_v zng}ghIhzq>APMOFn;{TOc%m$3h{_mo}KQf zRsiBe#y=V|FeU?~scLU;?}yllFGr=j&_EKL7jNIbO|60(k$k<@^I6R|U{SE(Jl-kC za%C_D_2Pz-Ei&l=gAB)B!^M-;0{FWzEz~b#^e=}n!Z?ztIzeet0V9PzA*+C+y{R-A zo7Hf@d=++-9-t|NrwDpexK9nxvQBDivu9qI4rMB&W5b;rXC_?~*D<=9v3I7-YM$#* zbq=RHZB0YTrBfm)7cblLsYQC`VhAV0W*=ry-ykMKc0qKpY( z1^e@*qM}91lBh@d_o>;6vGvjErcS?Z-*wM5qOK;HZ)$uyo9DP&=X#|vm!|IW=rUV> zBqG)J2h+*%jzE{1<&$Tz_f^qPt_({;I>2}G3HCDO&v^s=>FzGA?s=RiWZXcc@2i8J zm^B7_Q|vJShHh>@x7vcAF$3mk6yGe6#H4BK0tJm~!^B=<2Ip(&IU#COqbx6;-I65{ z_Bzn_V-o_PoZV@d?>VYy+9hO`+jRK2oWC*@DUu6?>cJgb?R!Sc%~-=zPQ60hETom~ zG=lfixD{8ghR;6qmIyoEjeD(qwBcHI0_#uJDympJp0yashza;>XXl*L^R>Jstj(zd z@>a>usw5sWn8WhE?#@Wy!Ia?BYlq z+8JzS@+QNts?fI`qJW+uX!tHG1Gr^QT>bTVI8 zplg)X&|SKL8XDGX>6E!KSy{O9zLHNf_+U%3U*l;d7O{}T-5JL@BDS2mv<5|EOHBfc z(aY@VmuDhAM`&FXj`)cjzW$t^MF#BpXBPjSdwKP>Wj1<3*&eZFj_eJ)t^%NY;>azR zz`Mv}_W1Vrn=CU{5@?~DLNjE5Wpo?9xr@t4ARp-`n>3-I(igoP?y;xdDnT%*5%n;` zUr@QlP3U^u`b5F zsFqiU`@CD1MajGop%e_%ZtalyVyMOQOW9xD?*MhkVXsKSS68SbD9;?#^$mwRncdcY z2Z<+|%v(^Vmo(Ae7P2ys!j-o$+_tuEIL=yI2FVnqfs8F@UO zkT3^z7%i?I&4ryWDp^Z`b{tj-dvt(QICc2PCFAxom(!PcpR`>jpnGZOf=^JiTg(pV$j2kC@ho*wg2fV>j+-u zyAQyRMM^YC#ok3bCB6MMMaj$Bd1z^A2PVNnO;DPG(oz!A$KM{L0iPA2Z!E=CT{nb{ z;r2ye2yVMU+Dl->J$@ zWNNe?&&`oj?QEjX!FicIpr<9MiK~9LvNfF}0Ry_$9Myj9k`Lo4V$(by9C-%+h_(sf2#peC_I%3JOY`Hd?CaWZ)egs8@r=1@Nm$o_Khy zt1XFR7+Zt$K!>Ne7(0pI=PNu3lI@x!rcwt7T9^uz&^4Ud*E~<=G?FOkSw<*0-)!lg?dlDa4QVZmvY?XMIy1BS^l7 z(88#i0Iwx@=ya161v+S|`iP$t0`lxrP_H4P(`~1AS9x%1@sC|$VVr}5BT?94BIq+Q zay%D@wn}wt4TV^=o2$p-UIjNKxvux-+F?0s-E z7^!;DWWHFB!{Q(xUk`Hh1J^C=zMOs5-_3O1Vp8%x$CsJEdC#5giqV?x{$r!~`qb66 z>Ud}earB?!=x6yV`%RrQ!%7v4j_>m|DwJYygjHO>R?~+#eRG0x>2G3bRF>z6%|{0! zE_u%Zn{Is8cD~_6$$)2Ox5m@W-NT|NK_*f#h~EUMmVk0Ez|x%ob!-j>?GIP#-lrS6 zmrvG3AF~>+gNQq%V&3DZWUi`;8*`u0{vS8WS1r)LB}eT!%iMPNTArS#gZc&ZG$(6b z{4>9LYdIatH0jf)JLp+_(8caDbzS0&(I+Bz7wmQkx z2v|*wXE)$ZoqhT~TVBxfnw^f0F6ogn?CIEndSj!Hz6X|i1zR$>cNm*l|0R>XibzfM zomTKp750pL{dT5Ni2pvZfYluPS*mcM6)0ZC8om|I=@ap$RxYq_1UV&Lg4SnLl0`bA z6eyQ}_OGt*6%$!K>(&ag^*TUd{rz^iTw8kUPRRJ%oeBAW&SB_);o>9l_-#?5;3@T3*<>iGcxfKT^GeY&2V|JdP*;o)i!kTnd z94cQCF`}idlLbkX#i`z#(F~laao4=2g+xhTXG79ST~0pnBiESwa$@MC0(>a~V64O$ zPA3#NNAwY_*&f7d3k0wJaq%=6C@Cp{j(@fF{1)NJ`_-jf%k4LYAY(`~*`iX;HkC*; zAL|})zu5KeL$?9V;=b>~sNpkQ)Sl@1+D;d(Q|Etb0d*`wf!$kIo_6lK^>^R57f9` z#Zj^7*GAGn*k<>Gj2`Of=rHNmz8w<2snpv{i|v6W{U`XQ&sT`17fV>0O7vdqOTKMp zSMScSYE}mEGh~T<1D62g!~8F!MLlV)bgKIt9+!_LJcnfa@8Y2}4K&K|N%{9j{xM~N z*O#r>7(fdub)lE65v*n)yNO9XX4?+$Nunq;k_*%d!zSX$h^)3ysbfkJ5Qbzq0})~r zEo3ImA{hi>-xDm60XUf2wQhL@QRPkrphX8Vh?x>gS5S)tN89^QkDIxR#OeE|M8J@= zQqsBqKk8xz{v<|6*6rW>Z$V zwsUI?Vq)qQIX`E7QzH`q9HdYF=N_NGf4HyD>x%dJlECTtx$gJCEhXvQmXq_w83{J* z`Q_+ha$t{o`X77L{yNL0;9Zi)-@+ahnkjq0n`GeLP#tbd`d@~n`cC~*FsNpZr0(fk zUXE9P+p}6y>-GlkQw{*r`D=p=ac9pfa8Ag*thelgxl5+6D!Fm=`Z zHzm@48KlB(I2jokAz=ZhG+k6f1x(gy+Wx-yHoIjnp^J&Y*kxlRzbpFXbjXOnOwucn z8>$^u_w?EAM<)_dw;wH6@9l*ro(4Qzf(D)f9TnvjoYhsFV7{&@+Rkh&SgDKi^QHq2 zR^>Tz0c`Ndyn)&t)`i&hIxV&x>jLK3J*i#M9A4Ldyk@t*wF&sF0-r6MVgU;9T>XFd z#O+XaFfsQsGxcuoq+Q98b2}1u*!{Fq=;8flh_}3)rMYH($=GM2Ghg_uAm1}t; z8=?L2gQ+Esu`P0->Ovnx`+r|@Ra;=HKpV*<`#=(VH{$59O$yYcLz8)z=Vk-R3=BYW z+8@sh2`}1VVw%{yUERi4cqp{o%!iKTpUG)IQOu(~;uv|u5slVD5*Z%6YX>fXiGJH0_CqT!sFv626(B}z}xCXXfOfucbdwOPe4O`Ug5Rco?Le_@40{48u$cbxkEmR zO8Ju)U%mzlao?2A?bU z>H<`;=$k|VZEt@_l}aU=PWkRV;Qsyi5#I(*D&(WX^LuAZ-(AL@3X*jMa($KC)e^rW z&f~*8`Q7K!+TXV7XMkS%ZX{0sKt#2@0=g^gb~ERBI5xZZ#QxOlvIaW87}46-+k1X| zE@g0jZ@%6=pC(U}MKj++Vs)I)X*Wuor;%@R3Tqm%5l~>T=;t0qEx+x$)j#P3`-g0* z9H`b7WP9nDKq&Pw-e3EpU+0Iv(^;HkVb4;HtFb8a>AXK+3BfbJd;i|&U|%DU@EC59 zH)`u}y@ZD$^O$_bsXeI;L}GBa&8gGU&nh&E-0wOkK%$0ZEfJku!o49~+S^NIXkEu9 zg%*>apiqgNF1vY^i69s{q7`;GFE1~Tp6(L>1y#65-_F^gChP3%a$9ILpV5>8X#%Z6 zjFRsXsOZ^F)k8#as%__;ob9DS>GeMSi?RGhn~phUqii9M12x|zFzuN;N0)g5wj*GE zRED=jJ(MlgVH&!Xb5F$Q{Ag-Rex|0B`U)BAS>%UDwMaO!*jswTUqz)DEhRrw?=>+q zGc$c57O>s6va@hKi@7$y2mKWso!#HybHM@)D?n{&^rdi(lt!Cr7EZYxA+(7Zx2&}} zoVR9Z3_wPSBN>*=Z?zl6>yQ+_J6+;284oSAkR6&DQ&XHtQ(HzczIlP=4E; z)!o}H#|K0jg+|CvKX@f*m;Z?G!LRMLq>-c9DAjA-S2FOD0|T}Q_Br(Jig=HY+7&^sY0 z4%o_42v`m0s~k#WGc#@530MtAZ4kSN_(w=x46)9w;ngiLZo}nH`XhqkZpPQIOH3;< zkxw!H$R)9BR!0Cwp)sFSSc)De^uu*MA4=1Dz33jt8p|L1lNjgAQwJ;c;veX|ReQp( zOY8`6apidh>FCVI=fsdl>Ws0s*n^LB%_5z0K}>xCdr;p)hvgjhC|A!@kLDy*%{_OW z@9|_w8r1Mm{|}En26#)a2OID{Lrfim@KQES4s{ajf67uVqSr>seju85-HsK1e6jK1 zV3k1=o}+_`4ff~^nw{B|b{3-nLpveJz*v%A6;~A|eo5ky z{6@&0_r3v%oCf`ZJlr08_vsQJ7ubr7E|(qP2LITMmVD0gT@&5Iqaj7eE}s925gPuh zwLO1RjipP6vv9mtEX2#*5mBJhKQ$#Ar&?hTrj1^3%a2mS2J0xkDh$0!r3E;Mz<%!{ z{ifW@Bw`+0-}4pSTG3o&8I4B5Mo?2zlQ<8R8Y0Ih^n=7fel(CcD-p;JMs7$>apop) z<)zp0n~tY^#+mI*=CF#EtXyilnprlwPK$+W1C@S~aI#h53p}aEn_STL2^uV`yw(o+ z1U&1-R!RA&4N18`LU$(AbrwC>adZ!3$hG~~TR6d~|J~1W zel0$)3W|N-4Q$d5BlLwmN4Qo4PtP7I=y}Wdy+BSAy2kZmr;>BM?5TH~PB-os$Lh(# z_H|x9UascgxnAhL#4mGqU$f2l`A{l@-+m*zy8#h)JOK67s!f zH_qgF@8@O}*B4AWEyJ?{y8M{7Q!r1+HX4?GN|zBYB|52D1X+ z2!*tVb)nnQn!oPW3RGI9@QsAeZ#kbX7^pME#fe*L!oYUQyGPI;|DDD~R>paU%Xl`x zCd$qJ=6wl~zG~(~iDeORCw+-Oc%Jw24k?jVmD&(JZh%bM+hj`#h}9ASIGF$X>#x@w zBVS5QmgKGQH{xEh>&j~PFd+jR+HhJEh4Tn3ei$M8v zG-|gMg*B=qqTy$UE8nZl+p2ahsLUNV_A%Ty=cATAWn$jSOMeuTr-CGCh1!1QG(`7k z@WHii2MK8|1;&{qs6Q#CKYZk@1XB8^E+LQ((cY-_0+IT?czIbrxWaD7u7i)w?hV?sbv|CNF7=Tk_tQjWPVfR z0x?#)3KXVZ$f*ztW=B-KizrRejH**z!&VP6W}~9(u&<;1&?-#dXYqhkes4_?#NVx2qwUik;vWyPxUyLwNFa>QS^IBu_&l#nncYxlr9HyL)sTBMtrM#{a` z_q6&=)+r?{$x269{;Hy@vI84tZ;$ z?^L!&b)EE9|EUGwY8rks@VNd}UahU#VXMxjf6UoW0n;eYfi!8;o}{?1M7@@jyBH8s z^76U|`ajMqOXceZmvVH0fCbsC|5u|zaOfo!c8E?WrG!Tmo#xf)H;Dy10L>35$- zGBB7^kHW&xzdux)8$`ES zc}-8HXUb1NNg~?0F0Woaq-}5=*c$ZDj$4CexiII1<#D{zj7WRl71i9|{;Dy0r%=ky z^11vo#(>J}ZJ8x;sO#6`;ht=;FXC1C0^t=sP$A;Sb4C{Lb+{FAf&#P>5^3zKLQGBY zpFTy@=vitzmZ(oT94wxTov6^dO2@x$FVnB4vQ~cWbm>L3tf1vkdh!i7q%jrHId&5>nwNam{Uw`@iOfL;U24A{fq4> zERGRF-=Q zgK#$}dj04g36A_=rjTIErIJ(OyL%P^^r-&?*gh1O&;j^z)9g1T0f)d-d5 zF_Xg*FNkK^Rf`z|!+x`hVi#yPMBV45D!o~F7R{%VmmD!GJD-U zJNRgQEY6e>-AcA9_3|zUkIvafn=i9JJuYAGjyj@SR8>?VnK$b`FEUmRuK@b_i=f6{ z9rK;A<58gQu^6LR8RjO1udkEyW=QnQK8V^hO{za14ph9pL39#2#@2gZWk}{fRiBtBTb)=HofsmT-0HPbKR?^Tp22$j_{AWV+2%~pf$`UA zmxIzisonfL*jJfYhB=#84H>=|fg5pmKD`xC6ppG!1~~a1DvJ^WAsUAg<02VJq(7R} z%4FHqA&MS|V&qbof^1LY4`JBkeDpy;vh91g_8g8`+cf`VF6d-wmDn30-34X%SmlYO$$A^?|FHfJns`mPg_4D2_=Stgxj%meWgNuntt&KF|gz)`gFY#fw z1Tfu-H{qsu-WRi$bD)}h$A*~-POHN6&}wYt4s+{LK`86jox0;} z+4z~MDdgFs6PB9_wU$1X^Y!_|$}OHu^y|yB9*pSq`-xd{xv!k?%~Nt-#U5g+6XUbQ zC~916{80rWkYqmhjK|Pm)Y)(>2+6xJo7~QZC%bZWRu{sBNrgQQLI_yPP5WZnN81L* z_kQO(!KH$YhXNc6n3%z}ZeQmvHJskAP^ea__U_HX@26Xby5iLrGoh>PebaaD+yPGK z&jFz$dlookqj@pWHg22Ul`nUcVyZj@A^?6|T|b+0VPXMKIB*6QCAEsuRZl zL!?`;7+UTT4gX>1Etvxe+4&JfFyno|Z8QA+{Ly1fBL^A}Z@Ld{CC45&7CJD$IQ-On zO}2DhK0YnbI9SVsg|py1gLsOCuBVWz&^ov+=3=;R6nPC9CZso@3Onos=e&aPT9LVR z)%=4kGtSn5_4-KDU4g@uQpSO5Qs2QEYviD&+*_(ew$e!B!($=j-fPV;CO|^CH4xAO z=T>v;A?lM@2No+Ww7+Lj)qPNlUzW$+Z#WQY&XnZ>o2Bx=lM+jFQ)NPXS*IBon$7~*E_vyLq zoZHM_T*5%xLn_>Mop$J%jV4T1FBRMgAL-gw9@Y`uzmG0+|D{F!#=31I`|J1@vV_%3 zEng+p=R7XF$A^R0rKxTn_6v;K_2;fp9v2J!sBQk;MUlW{Hh4LrI%dGOUu$wmh5h)k zPQ~mF0!47(=(%BH@?M8iSCmNIZoxLbVeW?z4|xMiEJT%&sNrbl_b9BLsqUSvsfzNR zBVjVQxI1qo#ZH`4+?=;cA0nGq>+Dd;E{>y()5lc_DWtAr??pDpz6g^n!L^T z2GtW?z|1|_=T{`o6J<8li>uOF@4-nuS!T|{7XrjIzaj-|%fY&fCDI7NE97BgqjLH7 zzv>xba{21%q9t8$S6d;AnZa*F!#Q?9+0-4wFjZp9g(`#`WJF(+76eGF_<|gDB>NFH z)liXoI;aZeS`a6i1FdANKU0E0sZpIN+=3yFna!zN`b^T*H9;$v3cr`kutC;+71{%% z4YallqRTzGAInSw?gQPxJ)N&!R;UAf3C|ua?XQ2|#za{nIw!lMFB6^Q60w(`H0_@% zRVp2n(Bx}&k8+i^E`|(@k-{$;AkihF7nVeRcRzEJ!B57fHA7>ai(={H8c@Nr)ry9m z@85lr@5#>9;5~~cW;H8l;~x4%?k7 z^ec7(3MAcTWb|*#j$he9nsa%#Hh}+w_V;t#<*y`13uvzf zqq7IbttZmV>*myolw@zS_%xhcw?s$W-mg@Nunox!3XO-C9-zI(vCb6tI{`I4*ElM; zoM)NI-mg%4+q{1ne9PL)z?J&K#&OXI1_hYe2Vw4SxqJF{Ml^iiwPAo6_Yf#*lKb5@ z)5W>2KbhWnd$fCl>Xp0OCy!w-PIlL&x!BColwtAP$=qC56jgUBk7mbl9}r;DgGaoH zp^DxA@g}&Blu2=p4Z{07>en2mP3X6oC!91RWYk?KwJ%jl19%HQ};orS;tn}_!m_lo6T zNL{K08Hv>zE8bD_OI7y=50tfU&~a^GSgO%)+@Il}H~d@DZv2quefMkq^JceyJDzC& zN099PpVqMl^xkHGquS$Qu490;d0;@~w2`PoA7^Y_T#=vI@-$@J~!hma9As0u2&|y(d8CeMbEaSM~4TeOXH;a#B`R z0k{?I&)jPsO0E1kK0E4y-BKI@c=!ybJ@jm7eDCuB?StD$g$m;_=7GmDv-Usb<;w>d zcQ^h_3DA8dW|hPNU7M910rKqcuD9_4+CuRn$;j@GC;5X&Kk&#uhfhk%7UH>X|7)M1 zw1V>l^+@R{eU76P4j5?52&wveknE*I0drp_d(KN0rPVMh5H$%t!@qsRHG>LPO!p5z z>0keTh5na2V{UTRYR)UaYbPIRLRxxzt-HTB0z)3P_fl`$rjw?03qT2kITgrl>gUI> z+5(V3nvt)eh{)9> z=HLol-H70Ff+wiULe3|;4mk)4hUK|UrKDbCY>Sn z?4AT?uBOTOwGnXB52iwV5}99&4PLpa0~lR&dG=kj$dF|PHRs(Wt~2t!DTbFX7g|<{ zf3?fXY@I<)NIk=Q4Jv2~s52ltOV1gzs4__61U$1!XgrTrYQ=e0K68?LY{G3%$Mhd& zzHvW1_Qr?-3JVL_KpGm%eIAUz9(!%>)&f`)Tl8Aj^y!}u5IhOeST0qa+zDxU>xIr- zoT>=kAE`|@jL-o)B{fS(t(!8A+ zaOY#rCt#rqYw~Sgwc-J43Z)cgfhS3PzSMU8z3@`NuKVm!36mWM#E+E%N-U8>A$p>?vJ8r`CCNHG6VTHYB$hyN-7FtquT`LH zGO0RWR`|15sV^s}jA~bSrC;J_xaY|q^2ZO?CL|=t&PwjsW$H@r-BhZL;7~ut#2f}? zrcEnbQyP&5kS#iI4XR1@>69Qhx(2Ne*b39K}F@C8M85l#uTk{E}P#$nW(1)$5)(x*FTV z-DJ=3?(nP6105SfHjw9i`8PxEj>fwj#(o87T-5@|H`?2N7Oi;AZhE8bxZsE|09+bC zg%S4Jk37`Rr{T)vWoYezF(e6Eq%B_Y=i(M?)!6`s22c!GYOrML`W1!0M!Up6TKMV+ za+~duBclbzTnIU!N;uO)hIn?PlNvPYK<$JuAN=a{c6QmyCROdqoSbbw@^e zVhNmQ6a*{)rM1Hff7iI}80LA>f3cSQP?k4_-k`aEYz<_lI43dHco1-qmz-K+;!?k+ zlO8(8SAN*ZpTkK1N9n<9^n*uHH$c=6S_pNO$9efBS@qs~Kfhp85B<<+BRsxA8IZ8q z#;u&qiP6xZ?F&2wE7Nc8sh$CeX0LK80QNPU?HcD%c^(aBW>OKCw^RO9HAP<8T*S~k ze`b0vQ1H8WLrm8dBkTg_Wa);v1#-f2aXZFRRz5bxU3N#&1Q%~y(H+U)7F|M}zy2AX zRlU+C%4wIjD)*2=I~xj3tty!>kpZGAH}J5W2s5Xh2=)eA^E;}^%l$Iy*oR#w6RIU5cU{khAA?{by5(8I83 zr;7V;Rjdde5vIdOdnN&6OJ%7_Kal@~ta82ij}mQkRrT$46EFbIQXeTJw9}m$acav* z)i!sVm_@*8IZ%0+0=BJHRt4MwV5Y#_=viv_C4k&v5Lv9KY6?he7|2P8$b*Rst^Cev zMD2SO8o(c4R?hkEN8aFAKIZGDNvI4=t3TK;d(ER5|0?K`;j_LQdBG!Z0PK>*@2kGq z@45<96!N;1^I6CYAy7iw7%`wEMmldC~z< z7G(^;W95d>2@w53=PP~Z2sk!2ojoxkLJB0@u5N|a-}@nfB~1{-gbDnBdhR(x1)2vo#e?NLtqx`xjI z@YN42SnG$O7jv!p7vVB#77YvlJcWrSP7MwN9Ymdv?A7}G&sl1U(nH&;4q1tf^S(N` z#fqLvsoan{u`82yC7<^Tf~zeums=>O0rFL0H{-a?c+)_R?28&(bJ%3T+e$xoE}o0; z!qB!L4gwIF&=ht{V6Mb;e?M2rPUZ7?ms6Fj-w zpTJXK(5SXZN!x#RevW#_DAUB3^QK}Qb>Y-yZrkbXIVxT0^715>+u*@(Z+(x|?uK-%wQJ}t zPO?YnzQ+}qMaU>qF`j;?`@ijQYH?qE* z&0)x5+30ywDo#9q@X{Df`TPHfTDlF97wnc?_axHX1e+?pXjn((~tAVY?VLK88r|70azxD z{R_aDWU(#V=9#e#B*D9GP=%|s0;mw7J{{Vlt7pQ%$u3xr~;F?LIp|yNQd)OFW7pMtPEwNu?*z}R&7|V>2*R{>X zID~|}4pWycnO3xlnr|3JA)2;>p$tI8sD^MU29@?rNt=0>AMzc-?!js@3sDf?( zWZgtK@L{UaDK}o%$T$g~op(2z zsK^XJPdWD(tcU0e&IB@k+)MVe(jV$D3cvORGpO^D&vAyRO^9bcwbt z8+YoenY!Yr#ZJv)e)QgWJdX5m>Hg*qSW3Q^D|{}ekw)2DJUcPvZ`z)3KGG;2H@*3} zeC|Xl=q2jh{rTNk=7%2olSQ04VqFiN|JFe)63SFX@}woSZA?V z84#pq@6IG?;mI~HGzrXTrB(&H#zt<~0z5p<4RE5Ozy0*eHar-5!|N~j^lIV`7TT-S z+PhxifDT3ftN?m)+`V_Ix1d?;yxI;vnvTa?s|gHkz^hhw{KC}CN*5U2iBR3MPSQ6; z79%w|s#%a|S$XNF#=r&j`TWZ6-F&|amgmWw?wK-%0PN%Q_TOph#{ypaG4#&fa<{B^5Xd$pYGcUazB=qJ}^_Z2`pq!y4y8 zo9xCvOTV#?pZ&zX0p!!QdK1!VPQdRN0bcM6>=#?hhYqJdcDtcEb?-d~uG2I43A%Z4 zqm|6qltsy}A%Y&4oKEc(XNPM_jU#!Lx<6l7lMg;gnoMAdw!H_7mgjz zo>A*|<^evdxdv~M_q}Kmy8exheKso*DXy;EpQYq1hx4|oP>))421;C$KCKdya&VLb zMhwIJ=5n^8iY}vW-d9`cob2qqSDx;zYsn)t*y@cV1HPP3f&c$&INEsBVSu`rTL*HOEK;h2lf-}qM4;hX6dI4Nu zmI%AL4}GQnd74-q3DL|`KJbm{UJTmZ7?_NmqYm*}D3Q=k+%J%!N+^nmlt@S;EiD2f-CasI5|d5^6qN3kX42iEbhmU$NjFIE!9Uj8 z>s;%cv#)dZm(53!3G;W5{n_4haP4s zU=_$zpqI;jQ#)Y5(7pv!Fwnx_(1kwJ+E`oZAn~q2kLcvHtK`}BY=lwH#F*%2)j z74_I7L6BuHkPbG9o`)&~PtZg;>{sUamZrZ3>e|9^`UO|m?~mdfHZPT^97RjiR}g^9 z3dxM7RXMEKsdQfO&Q|;I$FgMlc!6&{Iz?nXnAQ5YH0Lp|{hr`iBP?LWhO+6x5i@b= zuL#X`?wd{SM3H~N{knWtfVWI@of;^<(!y=HvAj+`r}7JjQM(lRrW-)mYD-FK&%q~3xz;uuK^HPMt;%i_Y>lz>YL-SCp%{8* zW~njcvG~@&1DK=e2||q{Am+3s%rJDSYQ3kxOQ|fmwdY93Az1rmt?*o+xh?RagfZ6d zNh&Z*K>yPbVP>Ld4<6x}geTyZ|zw$>>%|)5+R;c2ehy$<5|g9<#yve9`z|Eg8e~_RNwO;>qz8 z>SL5sXqhHGrPBDBqjJ<4)CGLDz>G#DL)bNgCFPIDw!9ASljUQhOIHqlEa?Qja!6KD zTOYGlj++7Y!A_>EjGPmn+x7~q=EHfBtQL!rptlqAfxeC4r^D>!-n0V2r{;kng#Y#e zCIB{9{4?h@T_rRWFR45;t`};>HtUT>yFZ26*066ya_M|6J`u4rp6T6YlFk&cQVhxL z+jTMkdLgO6*hQXJU;U9J@f3^R#0==*<~?zDRz20t5Pz~AI%2h(Cdyoz_Cy*|a^9|F zH@!0p3`{V2TX4C}G;eKOnDCgsRhrZfD%7u04eKEsA1gG9OH8I%4R_u=zNeB_?PzNh zLT{D{vM8L>$=6@wjLr1OM_n7*N5PW%1-C_ou-0k%9+%p0Voz=(?gTAC*etIT&PqqNTWEcQ7uF zmu;rhl7-PDKZtU_B3xMBr+EHc8XJq4CkQXKnb-JD&p8hlg;comjj^#2pe(sIM!e*NP0JB*7J(g~hmvf~L9O4bXJ0SJ>&eLEC-uj$KT#EqAzF&oqO zTo!~0SC|&Qu{cZHMG0MHMBv-mU!*2-aVdrXY8)5h{3=BH3w2HVr+%}v-% z>n>)t!zETF3AmoS#jpJs0u5zD)!`HnEC(^rZruuO$o8ZIK&|hC_GFbSYB63#=LjpS zP^nJ)ZF)?AR2%MA0&MYxv`u8hF>W)Bxmkz9Ok z?O^k4!Fif+29nj$G>0=H7hz3cCbAoM9k2hS4r63w+}__e>8-W~hldow$a6dZXx!GAhBiih@GQTnNs{#QMZ4d~ljm0@=JyN4(PvHwUtD(EQd&GvnUeKgLC7$j ze6Nj@OM62tb97viMZiPUp0iKJy91v6(D+my(dgUw!+At2!)O&_D_i!K+IE{0s){0G zg($G$nQzq3(0ZEm92XwQM>&pMlB= z6c)YDrG;dCKdY3mA{gYv`_vl>`$pR=e`LFLgi}9dW!%@l8>};4V*ERr$pL(gWcKN7 z`C@lsD!h)szJ#-0g9Eh~4c|{Yt!bWj8}(rv*1D206sgCyZ!YL~rou|s{AYHq8!KlLV9t6vXkCMQ0$H&YNQS zhm0-mxprw9Qs_;rGH4Uq;M-7(<*}`muCL5e_C1XnLS21gfbS0m0DE4Xk!z`Y{ z=gEl)ooeX;xDHo@q^3{(kGbfx7lezY%knc3yN-oLy24l+Cwy9bZW=cNUFaCEM#yH=)ea81znlAG1f5BfOBDhh>GPU zVmn75?o?cTXLkDu_UZg(!T;cJ=Cg0`vy(iQkY@%%q#za;%X$hD(gLGZBIF&BHTAxU zE8W6;V|{6Oa4`LkTHs93?;ZCKhj{9)(Eg*8VEHZ`$M^Zx*U& zqG4+6?aLiJBd|!_cdJNH32sCq`|#wto>5=FmJ~7-op>at=X(JVJ#*xWl0qNoeSo`S zpXj-2vncue$|%pfoYDgmiXl2`rS480iq23Ua@}Olj~-2n?NLJO2YI9l!pNQFsWgc= zS>RxuaUMRJC{&r;Gt$60-3O1rRH@vw_QDEVhFl4F;wwKypW`(7+;192e1>ZC0=&L? z)8(lLz6^jhJnzROTgz$CWxvq`bjBJTN(WLEcFe_7I$ErlOG9y>9dA1=b zRZV4y*;MJLYlPww7hm|rP+e=eNB2Kbj;&-gE|Q%CvJ~~mOVp$Y-RA3ZzVnY1z!YNQ zvy!W_tg_MJw=QwMI6X`bY-j?tdivLkO}0;;0^)g{_fi^f!@iaU$L>iSj}vvX1j&UY3&@JyK+V(7t1d+>q4c>a^~g_yFO+h*%~W z;KBPN#8P*V&}C&ww;bWC{fAxu4R&iJr}ga7m*GKb8=s`;@$9KeYpo%E)j5GUz5c!H zP#ceyn%A1YIiDCEri}slO%~T7(V)?UW!nTAwx>cp#Z6s~uUSUO=N*_ePMb2?W_({P zNl!!{tqj(6zY)=`SW##YzDD9e3W&QzdabMeJFA!%pS)M5&RVqM z6#G*k;9}`V!?Tr_XhO@cMa0|1oaz;d3DK=}ds1>Ev#WLA96ep3oLslJIgfkMK^3l} z%%7UicKvRj>$&?4lzYA?!txIu{n09W2~iYk2=9QXLhGJHdP21atq~2QREpK}37hs2 zTn6FxmO2*Gh?mjyfFWkHXnuq!4_(}kFnULHTpND7A&AH16=vD+)YX|7>QFk(OnVZv zZ1K1X!~WvyYC~Ni^)^3FqocnfeUKhMhnyv9FgL;z;i_YQ}&qKJg2W4ScTVaV7}$~y_xvwa7Vg5u+qt36=!?^G$b>IqM!csHTU zo-J`jFhk4gC93-^=$y;+0pS+03>Jw@B@O@{)B+~@Cv}9+`dW$!gfe)g03kx;^SezC z9SCF!AZGB#HkY*y5fT}tKP`ImgY(H&)`!s4RG}uTCid*;GccjZr8B%}%(oNCt;iQz z|8{T4_zQscmiytTD-rwLRaqj9gm3t}wm|U8uP(KVN%xm_<8QWMQw_S1jQQR~^(Xp4 zcbe2=3bPz2+@C*>D)tn6afyI6E?P&e$p)nroF2~E5%qy-S}V*X8Wpy3HS1qY+8;m+ zTClAZ;?FwQA>1pt+5Vw0%3gJpvcQ4P5ue?xC@`Z_OH@=X8&*QD~G&+4cqC0+(oNKzuYO@`qH zL5=BlheK!v8rq3wjV(=E1kwGnI&>wL!-)zy*7qEdtyo&Mb6s4AHd^X-0UwE{B5@fs zLVOqUJtnP;tI&RLG_M3dZ96*&c*QHEaQhf6Pm|@wr5?X(A<@TYnLYmM?)E@>i`GFa zuw!5b972IPrPipW*2Kz;;i?+3Rd(%z)ncpZ43~H1Tz$o<7ELx?cIDZ^@3Xey!~UQ6 zmFP3TD=%|_M5{Z9liw*eB91^QdheQ1>PHf)EaE#aVm?uw?Buk5EHP?MLhP2j+0I&4 zbx0h}pds%P^Frp->5vG?b2ltc>T_@nyvzO?>nv#oNg1yaD)-O3S(t_>cN0MgA_P$N z$x5AsLECx3LIBVnm(b9R-Qk2YUYJ!t@fs!`hlty8`+^t&5U$c_(`yv@PIs2N;vu1q zZ}NtS(I$)lfk7mbK=Jma?|gL9EEuFxU((VroA<{?*G=iT&9$wVr$jBFn_+#Um3+LRmQNAHhTB!DpLRO8AFoP#Lq@KUqXiY|jv+GR+enaGvnLw+~e7+}*k zb}_?sJTp~K*C$6-v@!DYN~+rFF`fLj?U&A*%G11rq6V2a4bpGR(u60BB&C{gl~|0y;{*V=VmIxq)|O=Z zzybekOo1%eetQRTR09MHQCB$bayC4qQ-dCXo=WR)OXkzFGn(+TQ*m-EEC!X&=n)0X zi?j+@6tbW4WJ)Gl3kJZH?+RSVO^;**fB)tfOnOp!rwSDCpNG{{n9nW!Q99@52!19t z0S&JxCAK;6n&5Qp-{NvSApTh-rpECZsRo0-t}coe@koc$`HClIhannHSesLJ<*&o6 zyz9#0__c=HMpT%111mu}MVbhC-2P4rk*^f>Z!ZATBv=M#J%m*kD;!u;ewH0-9Ng`~ ztvg%@;=u|5YozO^eZqz@%Nyaumi1%x)GEZIP1vEELr(V6Z@_^1vpp5pS{i; zf0i9!s9tv*ys&D!!TV=p@&ulzHuW34ED+a+h_QY1=&ABvrg@idu$O+17CpXb{cEVV zjQfiHRX&^ZA1mgKE7saDPO?&6-&wS=wIz6NT3uC@u3LXkCw)0B^lnNcJNc=>TcgX8 z^22F8v`hpk>1BL;0T4>J5TkEanQn`SVlvM!rfU1{Zx%CX($DB2mJ42fGu6SvtEMQ23q3ffB#oH1{U3h91f7#JwvIF?tc!}v0`@v)!!%6K6e&12svXq0xIt|3Q-q#0v7sJZFiZUSY|3T+3jB)x24mD|P7 zcs@530Mb)si9GlQ;Bg4Cc>dfHNQJP6Msr%rpy|rz$to(5s8pNg$g8G|r1Nc`;R{0} zNMuqZ$2Z*)5yhngtgh%5vsMPnruw#EtW}ncjBD2wkn*aB*1dXjDI(Yab24j=CExiN zW_;9pMFT*q?BAr)yC-kht@DUuUahGtU7wiSz4!LVub=Ry#Y4u()xy#7m3rDjN&Gm~ zYlmSZaEafT)}snfZivo@GuXA*5= zk});q!qfMF#%?VUrLIVoEn(melm%BFE*6V%fzo*ALj|$474s|OXKpzR8Wr?6?;~B| zIecBV?~U<$%xNZ)x8PJE1@K<%8*%U3c2RY1Ta^z{%)zx(yx0T0P8cWEDun`73DZF{P?#@*{V@uVa#Uk>=G<}KL zZJW`Jn*G+4&c)Wa1}~e6U)~Y(!1*gSzcfG7s396KK%uC$Yk8@=&z70oA>s=}w&&x# zs8#rXK2zg}-Mn$5OQSeb?~`UJ8`~X&3z~7ZY^?Rs)UFFhOp&148Q7q}vj-{~ILr*w z#__rw{DSC&=C63kR$jqy(qi69bag!kS4`}4eRuQEr;QJL@TLuBM%1C;hs;u`!via9 z7}Ipy9B%b%I37ujQ^0}ZPU-i{f|cKO_VPRy`acgI-?KW0zWE|}SV?O9lWx~g6aD9GpP=B^pPr}Bze*L=3@E&L`fbxl^Gc)InT{%g2GzX}ZEpTgRX0Ul?~&N>gLT5>dM<&$J~urWKmw)*?6+sL zXHJ_Q4b3MfH-Br%V_g=4(STqMGchl$04Pbm?$Pmz!iXY@`?OKxh|x32I5&{r!C4wQ zimFAb4m4t7Fta?pw(;ZLgzY9@f392|H%Ad|G_(JbyJu5-`%Z749O*@zxw-j9@Kd9* z?i^_Eq=4S>1ek`ont6V8b#Bm(5Pe9~Tjk_*`AP&EKkkXtyZue<`A+=N>Am3NzsXJi z3*pVT24HH!G*6p)8VhcYCW-Jf?{Tw*GSzY$38XKEt^^>@NiBc?DE-YI;ZS9L$iEP< zD`u-c_~7o{-mHrZsM=b@;xA(qL1CATE=B(EqCK%S_6Mh7YokoC zZghPY2BqEpZ>~bE9{-|r|Kie8=y2>oiVbcjK@5u#fOhB1$0~&%A|}^u;kLEX>zPP* za#B;nM>GS9p50=cR8xKFGPC7I-99v7FNSsAJGx^9|REL3r-hP0`Vp%8$KKu~O6NlbtYO z?1WWn0Dg)jnwRTDyQ+6r* zMUs_1y9?ds_Hy71lxExSceqbTu%;nPrr;`{Phj!{3r60L?f@)etLP!EiuKY4>Vj~S z-)gp2I>v2uXoX!;2CrV+Avixd3fXh{QxrlD^pNiFZv_Sb0|H71RTdkN70EGks?{S<3kM6^;3gl zN~X&B_9f1OP_4qFLqS|%w_2EQJBqc|uCzfE#hkW2oR!S^1-e&F-+;f_zIQqDbbXcY zV(LF7PotLc9yzOXO;61_EC$00vNDI zaH@~ZgY$S`&Mjvj*9sn4RgCc}T}t_K@YSxCEeAxuKxjs_`^ly-P=1kRU<`a*TRgt1 zshKxDGBzULYwH{sZIENU@Z~`#Y1je(8RyB-5ue++taqMjnZiojnWJrIAbkm(lEBbh zxd59@qUd_~a#6(Z5yTAio^@M+a|EdjQF>UK z)y^6qLjRlzdj9WjWY7CxiVYr|c)r?oH^S&V%{m2k`qEmyYE0C_J)`vg{;rNeF@ zMUj-4_}UoB`VsN%hUDc9CfTiX$>!`VeQu~DJ#H8Eo)ArRUCpD|+EOiac7dS}x@jex zc{(GDY>pe>Q8*G_i|27usWVEKZMs7=SyrmK-tMPr6J#%(@6{7smTj0=jU9iB?LWsY z^3%1>%dUVHYqDA;iQ(uN^k}LFhDHP?2MaGb7;EdvtGrD=NSePyY#b-xn?`uCa%XFd!hUe?V`ZKS z=b0N}44>0>;p>`G(4)&1|G*v9&ZP+ogjjrRcc&v%tg@Fxb*SJU<3K^Pr%?C(CuYA#X$HA1i@@= z161w$?!sV#eQRqQ%;;5Fvv5sGu!wjqMdAfl!dJ#Gsobwc8sEWzLNAL&GN|@#eQ1SV z>rGS*pcrUtid1yZ&yfXeCC-f~Y2X2+;J7cBRb1TaNTOFoLOgXtBy ze|rHRYs?E_g{g7fRg{pzV}CKCL5HqZ=dk4aGsf0bb^g&nqG(e;bViT^84VCjQ6J5l zZIQE@Q3ybP`|V#37=oqT=+7kV_K&-)m-1S(U=9Q+g5UkJSbFlpzI`8=b$NAW2oD9= z#Mx}#mc4CQqE%*e>&r~trGUt~J`8l*5E&JZC**IivF)QzH=iKh0u%9gjaBET)&kcaQh+N2M#vNbFRU8yZw=&(*OpM1o)ZpfP)%WZ98>aA51=Xww=)1Ada> z$1Lk9p0AUzgb%XOmbUT_G=2$gH$>eOmypoSx^%_;ed|m8^4w*53 zSRtN2n~7%~{$^ixcpr#(n?M=A?NZTVkaTUkP){U}_w*@Xpa%@-A2RG5aee?a!ctex z@?apfULmYCu1f9=>x+}%)%;DpF1rv9>Kr&{DECxhtg2-RK-=3z2q5yN4(4B1Qf zpNW3sI|UIKl#Wu7FRdd6V#+olo$=Y3l@n&%dKKmyGadu~&Kqoq16sUpjdIzSbp8~ogCh}|x)E5DrLG=hZ40x>&qNJnVL&|qS`=z1wYSh= z_n^}#AQ|NTRvWf2uS5!FpOq3doZ6}L%WHo#A_M9LV?_qHy+2Vx9YdlR)*xx?P&AYO zBsSm(t+m(ZTRkX|0>{65d{8*X`3<}xfQ_T#*FIzLuu{&}HJdr0IAeG4(@2G?hz6ywYp$32x zJcabvsZc-UDHn}SHkg2d30BZN`CLzQi>dMh*hf+m&-Y`>WRsySA3wax?pcXAmULwC>a0g+nLbNpvI_{Hm_Z$ z>5i=;qnUSk0*H(*ic~)UH6+~Ig2O)9`Wg!pIq#_K~}SB zUpfpdh;s}#m8m4QX%sEOsqLC=kP&o|*;A|hV^cs`Bcp%9_yHEtrJfLtS46)2*LRnq z+1|BIcx4@95Us8~$O2UGG0%hAFM=3poysFA{1{>#dGzaO7inU#ls~+~iXd=K5%NZ1 zNLHEh20DpL9m-_7TL&#S)joh^?})nm8})6>~pCAdb7dhn|sTH72`ATnWx$!mVcI*EfER4GN)Gw3Hy=` zscm@@>9rt$Zn62ym|9(r;<&%DE`XB$vAQuH?FS3;w zRtFRvApE2J5&c`}*P&LNX_EGoZu}7H+rKe;4wuy@4TDzYbj8Wr?bz)qHU?Kf1AU@D z!@2x%8KTRg#uoxUP>*dygSbVYCvo#&qZs5)Fb%&vn4%=HT^{UlAg2-3{m5mA4g{#G6 z!ketswyA!x9 z8wT=*sGc-`%9H=Z!d`yEz0O-6m5vT#mTzC;T>B?FhXYV9d0!}}La-;%b%OW&(lY!n z==JhD-?iq#hMi7+58Zxx9grT{+S1ArvS9wzbr$St)uzvv2l*HxYX2&l2qVnMg8?k&jGV>h1liH#pO)P zp(bGAt(XmI@PA8Nz5J`1dpZXj`|Bs_>pQ3DA1kE^^8N<})bj7f-T&Ff^M5`Tl>cWK zDtwT>!adx7JtW_!pUH3wU%%JWINqZ4myaCfx&A*KZj`T=PtfJp|Iu#z|GX%Rf4SLF zK-5j?!JoEs`!*Ar?6=6)4zkupvffUzUcn!mf`2bkTV~kZTUabu=t&PRa7JmdS7knQ zUVXqU7xKhf&W){i^B*Ys+s}ius3}*8Tj?-s`IGo+uRPRG^U$Zb;>q!p`0q>iGLnUm z{c0yF4)xkBdC<2fO^x+~31$!5U~HQS{j;JaIxg3pHPFP-c6QCR1jIa52@Y<$6GkmF z(%7gA7{{)0a88=Odq>1B8Cz}{3nOr)D*XlU3VdW(4?BU=m~|opul6j%^o1gUEexZX?bBtogry zSlw#bepb1Cru*gSdbC>P5zS}8YcHPme8J759yX@9KnQSiYeC}C+}8Gh(Cww7!eVr` znuLTp$i7A#uQfr3i7t{AdMURjM<7NGgWx!??C|E~T_C;AmzXz{s{W)o*c{-<{@gHy zD*W;K3rs@Z+%M*j?m}-nNums{&BdV)Bn+7Vy%0{;QZW<|T>&Pko~I=?N%(xP@6X+O zUi2IY1S)V*;|uN^Wc2v~f3rQ5R$JfP7I2j?g=EdpU{$su)leOt;^B1OI^b~qwFVip znl)B#NBu7Kp`*+c0rJn3>x_iUGzA8W1s{^t0-(@!ZV13xdaaOoFjeQq=Wv=Yt)z3| zk&K=BoSAt5W3=|f9UBu{7V@!~EdCoXt6R$VC-=>%j+w9G41E9gQZAnD{$GEhSVS(; z2g)6THwmf|FwNF6etfFPa{y{ZEBz3`f~QAC1|1^@2~)wfu5+cFLtuCG5V%knfZ~9d z%gWuWY3YnI(GQ@VZ?sqaT@+}D>0~Jr&b6)edz@D~uOBsnf^(rGM1b)3>S~$A#XXVv z_MnCNcRiM_S4T$MRa<6}4iF2uuR!GbaGk`D*l5ayYLaRe8-UjyAYqAdH=WKTJIEMbIMUFq2wi7DD*a8 zUEl4FFO&CX&rmayuDi%3S@{J4b+ytAigF6x;LfcZtHkH9CX4EDjm^4HUvahCu=!0>`l^VZ9Lm{VasoPiwm zS%9J*5_6B)ZDr7ZxBS!U0~4F5s3@G)gpT*_4P&xp=YKI%eeu~#cLa{H9$%(DvI4ZW z%9H4T=!GoEg~>aHk*L$PE^e#cAK*Iq6ZT2DHGdSA95fzTJlj>5h-uNIdeth?VdgUG0o>TzdjRiFFxD(U5{aQvCOL7`QR+Z^4jjf z*$LbdM7&m3?RyRauf^qW4&|vSNT`DtNMgP{icYypJ(OBSSz_XS6`|>1O91f~T&gEN zJWiOaH!_FQA5g{ibnf9tB^n0xtTL3GVaA=PSGmd^abQn=zTZ+|`7zq-&Z5F6Zu>vV zN%-K*G#kq=%?;_O#2D9H_VV-;)FrEw$$z;4u+nyH8~D~!&iauBfBL7wP# zZVQPw0vapsL`;@=5TW6m{f##LTzK_ktqi|%^{zg^@>Rcb-nAM`A~av9GV2=BRrpBa zR7&VZDUg<36P&hT<)CL?Tqv5iF0hzzw6$$r=Urn!R7QY!;MmKvNj$I{9w z>KwPyD4Wj>31|zn*;k@$o{Le#uDi|i;;GapHVFtjtaDl71)>VluScys>2=8t^!ft` z$Eij_mGUZ(5r_-|9nQUtDSkTxX)Gxz)}SY@v4IJ}pps?X{^jMA4}^MW--li720sdg zrQ%_Nz-pal1ABneq0tAzR9{@j(|M$}G>oO45S!1n_jHAv(7slaH9lEo=#X(8%uHp* zCjZRf!$#<|KIpBAP4T(Rb>A5>C_Fqogv5p&|NJgMuZGil(XNsj(zZ*q;pTp*Ab{)O z)Rm37Hk=jWDMl7VZhai@@=5F$a8D{#WdAFJHO(;htOCcXsq%E7&@8Lj*Z@POM6?1% zDWcjvwWKP{27!&WXTm>aaN5Hz%Tsqge-EcG$2YHC^0MY;of7>gt@eHZxvT$~UAFS` z(eomy4Q_{Id<8PK4}#scHyOA!N>3EmBKuSoB<+rmI}YYBW1^!&J3`3bpamPY28s2A zV;yI@HO}7Yi4Gs;reb>X{P%aSXTAlq^f^J^Z)E2g+1V4ATz{`2lkd#;q#B;!W-FHz zh^HRI`pC+id>K7Auq5{8)e#Xt{|_#Hm!18NAl48dGy5K>Q2S2pQ#E~gcnkg1HXZp; zV#QpeE(5$SSYA8;SA;cliC#JPG?2weHnR_7HhN_jReNWljie7lBr-aBCI0c;!V%|4 z^--O=cJhU8)UT%7&YFcL?LEwnXY9#>;%sK)Ji3kcXlX2lW0q^>cq?0Wo6|Sd%0sNP z!@C{>g)d1xN*h~0xY1wZ=TKk+u#_gFR38 zA0fWAlk#vMI0Is-HF?yS_!K z>Q%}BEr+ZSGhWBK*}$67=v;H=#c!2YpXJtOj5!IHQe?q%^?va?*SYC%%Xia0i6V2K`(Y*^hI^CGv#r!IbQMz)14s?2IZyntO9kkqi z%U{si~@F_(U>ZaH*=e;60N4`Y2(Eby#))U_&?5qW!C?3>Km#xDd;H z(DH=79Rcv;?FvNR4hzt&baq+1<=nIRwkV*5bFVMcA_CeY|x7)X1h%*hmZ-kb9(<|KSA_ufO(w;Ex@5^c(-~aNpw1QZiS%s|0nz zi{i`Soe9_-BD)d6u+-^V7{oaaqJ04+-Znb zw$o8^Va-yKy$=EgnX;G+<=T|X+Vj*0-EOP<*UE#!p7KoN*?GTq0C@b7$isVfFLfWmB~t9{iG+Lqp*S#KYKK{j}jVC7wbycE3Mw>f%qg zEq*&_4|Q20!tDz0?csYq*t37IoiLU9E^+_@1wc?xaC(C~-5WdH-ZSl!D z)rws9ne-~rh6S&vp^obC2gWs8oKthC=G$PjYHa_irN6(vd1ZG%3K77Mv3#@}5w8{B zkf~WElkt{_i%X)jA8g63TiZKY?AyKy_z0!KP+G<3gVz^3AXV|EL7hkPbhV3to}LQ# zSE`R3w!gl*&cEuj`SE9BQ^4ir*SUyi_1q4};_O|c*0^DmGyh^x9|9Pi?OXcrA%X-X zV%*@V4IZi5{B3LYKqQG91O=DzAMSj8ScjZ}wk`4dMFdeYsfMN3$`Y#a3TM8W%kSPc zqCijwK68m>9@g?xwqf(mNfkeB9#_Jp4toDlkcVvVt&UkPo6C(GRM(3d`JA_-#v6vE zCiz0!gDA6Gzxaiz%+e+>c(^U>%bXjSRB}p8F2Dm3y5LlOwzpCe5a%aUt$cwfv7g=N zKY!+zjvOZQNj|zbK1&Z2+jTzan;NPosig1>deOZkDqT@6(!L;KHQ!&9)^HfMTDcEM z&JWXmF<)O}6DI_KlwKm5Oa|`xU~-YY<8?LUGrs<*VP^i*a_3e%8ed~)8U$V9 zqz~(A9}5|`CVL-Zu#Gkd2LLS~hp(}*aei6`RlJV7twiKwG^CrVRJq0^(uNpS zq%h`sj%SYHtTXnE^Z-;=vh`h{pW5KLxsb}2FL$!o7EGa7%<~vx?<#eVIEAc5TI~_p zo*WZe4v)&E$*msHsLvcDx&~w`_a2ckh&1}$=aQ+v7C_|IA`uB0;=HDVDIk=#E68fx zznob8v5tzqcKuY^J-KCXZnN42mWSPmfu&@Nmj^5bh-BLY*S)Q#DwD%%vN+~Aeft>d zW%BQgj>|`|xSSl_)EJz)nk;E4(UCirP1#lBz|`ocZ&V8V^@@mQ0CXbFAJKBz@d~!hLzb^+ZLr*dJ zr#>z=Rk?9$Ssp0&21qW$3RVU)tIg(qLDHxfM?{Ur${>A-vHV2oyMjyq2{|p3zI`2p zDZng9!R`3k_T0fn-@BjvQ9mj@ugRrIYwq78DU98^`C_cZI7Kr#(J+B1m`SLgDb<($ zUzq9f!P;Pr7(SY@vT~%Fno1bGitf}N;F-H~Pt6I(SeE-z%_@s?^;O~Yp;4i$3b6>a zCL}vKG~p)%gMnvH#r`U!_(GA`8K;48Ggt9A^H|T7ShH)f(j}w`pIxlb!mb=uaK3W3 zWT7T6KAs$}Z{J;9@XWTIm`lGHRwxl0(%O)&&qEa*OJYfNFU70}VwZotNm4%WoK?Sh zG-2!&l2EZN%WFQ=Y+_Nv8en3m!e|CNe|))<1+SIXn7_{JvT!Nlab62<;c=mH^AXjU zo^=Hlz4}Lqv^lTFJiANn;;U=+|CDSbK8M|Xo##XuY_I{ZRDLPZhjM3!F`o3%`E2T4 zw);_TB_xtkbgLD=!mg>bGwe&r{cC%xIK6CH#iQ)ViHAM8!|Vp!Mvj9YB|dbDqoQ6l!oA=x+!wECFeLkhjWdH^UBjo_swsZR21@aTFX=F{Nc?MQxk4|0 z#Hb#NeFQ;o&L5FcNKa-keL=V$rQ4J`;W+!9rH=^cTDtSOS0L-O0)_4p-mCrOV_QY_ zSsj?HmtW2wwZ1vLy?geez6sc+!M~d~U;ZP}WLJ(n7IP^wc#b^0fB$unYbwoCl#LMn<3de6z< z9n{zV*>d~`gZjTKsq4aElYS=2e(Z%i!z9&{H=nNBzQv_}s_pJKN$6H}`NdUG!1eO+ zg9p-q8{UT%Y8pMLk}nq)<`2)d`f4U?YHB8<;-U=n5C6I}jYR)+zhNqI@XwouZxnp` zySYz3-%a~(F981eGtWQo1%@DNB;Wsjrzj}eSpW2h;lDclJH|nA9})Ox+Jl1f|MF}8 zdTFB@qUw_7=C5Rp_4RG_^%ZR;>Hi)Uq5P5(m3{U4wd!kCQ3)abSFb*J1d|8FM*nz; zCMqcr;3qZIFC88d6dn>59v-g!*V{sQd8((Um#(KPBXuwwNhX0HC%?{dL-g)d0&;2& zavmP$j&IeR|GfG|ZtrJh2Ru9>p~e@YnDIYktSG}nJ^n_fqP)a=E3HXN$4o((nHME53F14#|tW5!d@B z_~g6Ht3sxtdEG5;nZJLKNl@`MH8b-U4{VPFA374e2Qz_9eSd*kQ78rG^-`Jd&QMYr zT15n|#j2k^g^vNgUPis@dTET#B>nXLm%kg?|Gz#ISBlcXij$eqxRah*Phn~*s>qnf z9Aze{iD{hrE84cm!eH&|JaLsJS)*l!f(+Ky)(lmZ6;4N9o~|;ovMg-bGb5EMLe@H} z#ha}hWuJPClFV~5b-ee}e2VwJ2HnSs6y|ud*{?mFSr%R)9S*O(?`gb2PC)tHL`m>+dBR(Cx zDx3O@bJi>s4J!nf%WP$@=DISwmZqlv6-rb=+z-Z??cq2QR5y*n2JW`!gr*zvLR8f5 z?`qH8= z+tPvI1xvye6ie@W1gT>3;u9V^xV&DjZJq7DU!E%PR8luSp?SgBvXkBR5KVq=-^V>fkf`VJLEXs6?A+7kw0 zx{MjAcQ*qx076e1W>VL>(K- zX!OyfbWKWJJdJa`u!PHE+U+s+!+2RBlpMB7A z2NUHp>DL)bjcONEr0KVCg&(L-U(Nb^lxfj4~{k+5Vp0q-%=dR z@PBhrYCN^IgD7L)bf!G9d!L_LcT-Apo!36vYBksI4xT%cfDOqDonQGqTD3$kY~zo^ z?}yZOrMSLrcUiMhRXz5~vNKG|LP#El&H$eIJ9ssAp5-wC!$XV1XIo>47 z>QpbIckMswwJa7u^|`q6xb9JJ0i0fh8GQG~gx&*zjU`X4J< zN6LERrTKnHl(np{#Vk##*@lvHb!k!>y7>!_b)~l& zm*56UBf;zUq4WzS9gL@22fq}?d8$uWhjJ;(_jo)<)N@?Mz1vvRG%@&j_ESHeX4AIIbqzveEk+b+L$5YN&-#aJ?^SU0$j#G` zJ|t(W3;3;DRi*aU*UT}*L`3%Qpr`rh`B>GH0yY`TM@R_CgeQ#mBh+8=Hjm8>h)3RO@illycTGmOblhT#u#YH2khE zJ)kmJGBM6Tle|^i)Hx^(JCCX&JaqSh`oeNLsq(u}+~2_SY#Qfd%ng@9z779)dSdG{ zWo8mbv2lG@L{K=};P5`itt51@(ZDpE2lExFc|6Wm&?z^{lq2k@494qnXsgq?{;d;R z;}*SImGyLxHH%DB`-jReyR~unLy5_$Z747M3OI7rD-xP{&XBjCHIb(EXvM_Di0P#& zkQWUWvv^;;CG^=m3F!D7)aZ~Pw z0Iz{M(|7#qG&&8pJ&1V=%8r#vaw9uXUf%oMZAiPqB!Z_ggX(o2`uv~`?e&k>ku zH;A3=w#nnjzgbwyVz4QtUvQY-t4|fY^XEt{+SRA!{mZClNq2Sag<`HDdNA>O<6;CP zLQ%)V`-t~zWj`@>YgNR#=VQaaPtMb4d$!aF~1!Q2#BNMmv<+C~#mZ+k>Ys$MNB zBFZ_!n(C9qzA3io5bqzNBgS@O?ZC&y)zaA*NZ4q(u|rp(g`xKF^1WNa)Mt6;^e5MC z8Iy>C_seUoy!&zZHZ8J>=eB)4u$s-3g@!(mNZ?+2j32Re5VvW9rRmh>JB`!Hnw;Sx zRMQxdH=XQAQj+%w%6 z-V6O_YH`qq={)rw95rqAzRP|5z0Xd&wR*U-0tRhg<7WPb+PZ8RI(>YRgy^``6Jf@6 zWljD$_wL_w4?4$Cu>il&_|A@$(Swg6b*dL%WG;j)3=;Xe$|qSOi(} z=w5*$!8H2o6S7d9-KW3>2ntJJ1NOKPgC-9|x8y}$SeSFG;8bH?P=sNoV?b-i4>>#x z-wDYKv3X!KS!7on*AwKQ)mQUf0oFpTcB9m6Max)#fZ{!fzI~1G1;@^wV#XdW4@u^D2?tZjdSOJTXD( zryUFU+%{`r|850JpWtcClvoAb!vIYWCH~FgGGCDE@i}>2y{F@`8!si;OPyvVJ>Onl zgJ|&EXw-6Zaa_G1mpjZBaWzNNPxBNJ!4%ih>gg!o-o~6cZQTm+DSvmvRki3n|Mr~C z-4i{yjlG$eh#ZCS?wwzbGe@C{fuVBH8ZKU`=91@Tw^1OnX>ojX1doIyiC`$4A#4X? z)Z_I-{Za`>1K%OiVSHjLT@d_^?Azw!ollGUjMO+N0cQhYJvbHnQ)NPu+=Vp*=NIDO zC+M0#n2$61l{^yi8||t^Fyvd+7M0)sAU#dL9A2(}tilU~KFl1q`U}@O>^Zf_kGel( z6~Yt2Bb!dSqkGpYr5*m9zn!|j#a8y6?* z(*YOX2R~GlyeJ7rX5XVm+Hc+=Rotv2|73_LA9Q{b;TshOp?^+%61Mv9YyTsm2cG{w zn#BKK*9YTRaX=`3_HUvK(3&0tfjA=1%HuyT0Bt;%MB>HlzqR7u$NxRG#sBqb{m+yw zFHnJn)|AiN=KED4DLU#$_f7x(Aqh&=_;lk#n|Q$wcoCMti+|1<1NEPZh*2^oRy{Bx z9c;ZM(JeRwZU`smD>3@6gd{wtdha=m(oQ8gS1GBN$R;FR$<9@c7Gv~HN7WZ?qA zx7k-SgN5>;=o?DVRaDex;IQ{r5TO=5Hv}*ho545@@c0F^OO1Mou3O4`7{^ex)?^-3 z6zJqSi9G)LMq?u2?x(7*J_mOi`UA4C)~Z*Tdv(uOxWX{Jn1Y`s;MS7x_Fw;T(tUCJUr%;*%bG4o zMduVPLD8yXIXxr!`+zr=Amq3Safr>EY*1rFWL7>OKCfAEsowMahFnSCG%jV{g|gvt zRTixNmCCQEH>^7HGw=1w`*_a#M){e!M8MJ}FRah}Bg(O)juoOkeS$um(Grb0M5|(@ z(PJq)VTde#W-KNyPD5SO2%xY46cT$0Q;iv=h{e<_RQ=5%a)@T%C%uxzu)dsiQ?r#O zFAfxxJlx0Rc>_V2$~Bu6$-EA^HxoAM^jLhHh3%}_t3QFkl^ILTD$V9o2B78VxjnAYdjI(+ODK(*|+_dY5#TV1;DV7cjJ z9=kr)f{h4cshSb&0@^-cl>x>d5UstPWUPn?RZ+#*(bCVI>?@ zRSuTK!OUP;U~WV*Ptn7s-MzzQSlHkz3$_VqjWS!=vId8or^~IE-;!N1PELS%ss{B| zBT1(-I8-9_#>ZH7vs^qJdrMt9^)0SKDalIv`>ic^4T@t0v-Q?;(f6WvUMl?NXGiz= z$s8QKh`qhnvorgn^K~X5&<=EWrbK?C=R6|4;WbR2+d}2x0ADKWP}q0ywe{Xo@BZ}B z47q@VsGhvj!!S==7UPs^eu?VPeCOcR?|8jE4E)GUeEC;^ABx-dywO;yY@Fu8{KAg* zD8b@zS1df&I^VNTfjZ3 z1pDN=YWXH8_b$GVsKmrX05(Re&qOtsbUobjPow3W)KirEZ%4tus$Oj!EVaooTC-d3 zmWu;Wb&^$l>s!Aos(d$4m=^gS+qp-m6d^Z)nlhe#(RLyDM~G85tQz`yB>;E@tM0WnixG z{(=5NWcoXc`EI<)d}AUHcO-buVKuy&@7!xb9;5d5%9-nxYv-@Z$CvDo&P*{_`_Pnm zJ|INs@~ov2_ILx62X>RgMX&eJK2LB2!mH+yZ!aK`CgX!e$K5hrE&Oa`g|tXLP*yn{ zN2a%=^0;6Po#8&)S*URmUATU6+t=M4MW&opo^NfNs|>NyfaA25UI{@sZ%ak9UIfmt z@5?Xnl}>)qlfc79Uj8X~7h0(@>7S-klwGunUZx}59N_;wJG--Wmx1^T=WAZxwod}# zRWwgWxh0=lD3I`&PQoOe7@nKyp)fMFyCvjR2ET0X)0hVNivycx#+RL+3d z(pc%Js#;4e&X!RY8dk*baLTjJoi ztTaR6YeX=QeX$NQ(MR{pR!mG;0%?MEI&J29GP8+6k%m8#h#i--)W+4&>}Y9dSPm7~ zh*aKFuehnIoUD~ih;h-;(moN9k&=?Kw=$Qa-*A2|CH9Wx(QTK8MjU{1G$!JAD9g$! z%FDAe>OK1K#^d@5?)yg;8f*S`(|jj+{u6&=v#-8E;=;jQFCaVdFg<+AB993~3k@+h zX)B4eR`I6|dka;_(JH5H5|TZIosZ@Wj89fKC_dW`HlIf$9ewVWogily*p)93By3M# z(V$xUw|f3bavKANr9gmvcKa-y!YiU$S-|D;Xt=LWhZ8CXEcWs7ajI*7{!r#4@ppW8 z(@QLetZ8QyE32YfDr$p@;oi63dihkVZ9l^6cCqWdaMN8^S2Dzyb$?vpzk3Rg=;rNU*a-Q;@EtbUWQi^TOLAr1?*OjCL%ZH|8X~2G z?8ni-iYo(9Q+-BP-?MeJI=a)7bC8g}9eDj`M~;PIs|V35vU-g=}ccC zAi%ku4tIU)&MlcaOy~DW^0~06Vq#&zMohTO?XXTp$;-+4UeEjc3>w*fy6v|5PB@Zg ztJ&wh^KA{#Nz2MB188u*FBcqT8G#H^Hb`$>?Z;o*Z;mW)Sk5YDj!!-#KsNAWmVH=3 zAVM&ul~M~_yzf>Zv(<^Nfsd|0o~~}5TN~0v(c=psc0;y?=_>u*1#l!|&rFsbi!07X zTvzX~0o;R~gCoQdgUHX6$I4WEtOuBa5EvK$y~P(a84lIuDXtXyjFwfeQCEEh>3s@3< zTQ|yW&b%85%yh#%xlp~NI4NWdaqPr6p^BqlXDy%M2O&iL(wQUo`Oj0{#f+kmtm05k z#ZmYcTa!{ovoSJP704_pg?wb8l<93i(z@-hry)n=ACxW}Y zhgr`syPyqBcOaYl;^KJLwE24TEfrd`x#BWRb7f-T1~(_KWsJHZQeal$cEkcrelVkN z6%ZvlXbJ$`ysbgA%25?f>4lx1tgI{r$i?A4=6o{7c6@Y`&z~QKTBQx-;=T)v(*h*C z@*ELAPwCYoa<1`bfRr>mDdY_wTfMq;P-^O;5V|rB8Ax1K^|-y9XEThWp2Es%+XS5# zJX>91bBG5#8A_R6sW+)bMCRA0^1}jz-PW(>fLeic$2#sO@qIWekac8mxS6F%?H8ta zE`a1kmmnZDMRdxohr()U*Whk{QWRym%VSBDhy7`9QaU8Fk5=q zGviftnOQyD!?Il>u7BR4!u+OPHQ%GP=_dev0WhX2N7btWR>y}A?C{ll{xMx7^7z|(-x>AJyY37(cT2L+#F8WmN3GilVSy3e=B|?t>d=V%m&mI1{DFMMcF(cE=T`4UoDJ@f5H31ho2|hXE$K(&_fS%=8wkRoS4oEZS z1RAma{p?^7CfVmYBvvFOOqynBi%DuH|NAbTh5di7-T!K{?Y|f0|A9W<|5pwjYn~|q zAS3^6#qDuSPMEG9#>yxSeg4lyL+K^~tN!=y`)|t=_}l->2+98p6!G70@PGSR=aT&A z(1CqsKTf&?1znwZ*8V<*23ozCJMg_ebs*#IP{kkl9+#4lpovMle!# zugjTnsl~i(9FNiA4}M^8kd*x7vM(?=*!1SE)q8(9j^1sNvI@ledG-ljN!dzEvzE`z zMcNJY`eny(-%a>QIVu#$rnYeOpU!eyH+w8B!>fe3fc%cxYjhEyF^HW@rJ;thqY zU^?-`3H0xJ&60Y(;0e9ENE@Y2?qbV!`N7$Bj!e7yCIO*(Nc6x7M!2-J+yNsjyl#e3 zH%GQXmgE!!Vcpv;a+$iJL#j^c4!};Uy-nJ0UT-RUoleI_*elpB63l?0 zCO&`9n^Dt!EZlZ`kDMFpfmSfxS%c(>fE@X_!*i>Jd^C{5pJ|^gNnqnKVIZf_oGDjKV!3=$}TD{=2U#| zeg=$^(6PsB%}wGKWf`@G-^TU*k^VtUHr`F~J~*o&~^7$yYABlZdIDSL)B! z@C*TAV%=6dM-WacV9f9m$j@#Cuy>}x3;B6f(H*0rtq(oOzh6M5SOxSxsG~hxBr?L< z94Gym>bQM3Hv*>oUo1dA7^uKYX6!87A4PagFhml5l5m=RUT|?SC?X-Y9#E~fb#c}k z9Osrc34@7%T>VqwtNl1d_B*pumeFBhFrSjmf)Rb7?Up?;IX4%rx9&L+ZaywS2GY}2 zJkobAS5ypZNOZB*E`S0ly!P9qshp8#$p*FH6rU3F`FUN+LvI`^(17pg$xk4^_EiN2 z7)%b2W{R0=z$#X55-XOh>Xp-4Q`6I{e9s?m;*O1t%~$*Ot?2!uE|tTz{z}tye0gL{ zKBva1HU~hH!1f@6CbT42TMSfqc()wg69X021oEzJ%|VyF%30h->djBf#9!H^A+N6C z1t9|#xEgik-R0A6qYcu^2BY0stz=|;r74Hf&JHBVo~4>t^#z`Rt%GIgx2qNO+ zvvgs%ABerf%6j+bllp-7evdwo`e0yUCdMXm@o?@f*P`;I2k=hi*!1RM7C=^f5S#lq zu#8zsjVmCR3g-6p%HV;{`%IWZg zgc$3|%HeDeb%6UZn+M2AJWg&26v+iD8;x28uYGBG6y-7d5$9pY1N4uSQQie=Z9^J_a?$%YYtz zcDBDk)&GeJHJZcDXdvjOobLcQ2L=%6=65_94EMry2n~LfMN=RW@GalMl$01zYdP({ zSNPSjy4r6gnVKe&3Vwv?PWAFa(y*c>K2H*m4{d)?<;>}p+8sq#H8z=n-tJ9pb0sn^ z1qS+zO-%v7M5%VYRQ)i;fK~BUvoJs=|5)ca&>NYhsyep0*%MASy*p7;P@}05UBKXR9_HZl&qnSmu2lYnvgx>f<6VqEqd?4+WO58J z7`HD=ixG{V*mvOvroDX^-+bLQ*JVMA`?YKTprpmHzL_Bs`E=aS*?BOPWQFoNDLtCw z^RFul_T@_U*qE4{9Akqv*Gqu(3py?6^=tFl0t`uqfnioP>;&uXtn0v1rV#WD)C>B} zbLRH2R%1hiYhx4t%KPT#QWS6rkW(J{Y&gy)Dc!rjR29fnK6k3E63c&hOE^TPIv}v; z#E)k9SmcS`kEF`e!)2deO8m7f_LhSaL>2yiA{@6yMAtZ(nSn4Zf$&1atk-2mZhjuq zuK})G|BItHhxhoplewxw`J?#?#M`b9OaYYcsszuUV~~t0*zAUOJ-svw{ngPX`LMin zLHS;3qE}ge{V_Sq40xe!_jP@8q%z8#kmt#5ch-J&HRs-->;z$@5rtO!&1YnZ?o{$) zau1PT`}co3Xy~0ru#HBpcIzp9yj)o=R~R(`iwbsDp)?;^!`OSq4O@fykBsl$2sWx+ znO`A_fZqGYbY%GVf{!V63H1Lmncz$;+M!IMmn**MP3L`k_q_XLWL$8I&5MGq19S>Q zOT(`0Pj6PLufw)N^d6ya%_eE7;OXKMWK6pxl=$d(CEe}5gFd3L&kj&`|Tj^ZHFitYIKs0L=iqmL*p?6&4K&*JrzLj-+#2e}uXw*LkeBn++Sh zo8UB$(_z%Q^8>_asMZV5f!bX+KD(uXJIUT|hwnfeG?6W}M=1l2==VK~@tF7qc4W%+ zbg`*^wfFk9m_<}LSf$YTyjlQX#d0d<()$Gl2H>0*tiJ^mUu;cdl?G`XH0a@!98pRR z77V@KA{#)n!PeR2{G>6x;^32D4fNvdp(m0=ZiQ~;eEUX?F*G6)20H`x95*|Co(8D0 zpd5hk{-GbnLyD4*^-T>dWQ2o9F_ahCgqxvOBNtObUi{6@PX81!t9jc7}Qvuyxq)F2Rp5+KAr?;9?VeWih$t*oU&Sk0b+6OjYyg+eA0d#q2SOk-Wo9DSr4u#Rlp|J&LK7N z(rW<$fkb^sbF-K4{YgCavroH;x|L#wwROe6r1*k?T*daw9}^kkQzBxG(HgsH#6hcc z#j?Bi9jWAvcS^HJ-l}xHnllYYbp66G1%-rdi|EpP(}qhYP1~}o*N^Dvq_o(5*GQs? ztfX^WYfj0y)YOxm^GL(ip?poOk3Zn^ zLoa+%l}0F)6yCt9?QQ{dCiw@4#T+1?0MJiRB^=YMM5*oZ3VO{e9viI<^XYQUeOi&q z-+zc0VQse z-ilB!i#n`G*`&t1ZHYwEr-J>j_=HJUEhVdPJ!gV7FArL;yIN?og@I$t~U()NL*-DcwhKEP=a=7;dD{xb+KQ9BjiSot&G(Y;DioG zU@pUoel<*LxnL1u6-ghO9aVV0qGY6H?!JuL%#^;RaenNcJ{ZrRgo`^2(Wv|HGohoD%m6SM6kXnmicO%IO-~0|| z>MIg+0_KlAF_e=0sRDAk&27BFNpJC;2>0W;7RL9_V|)h|lfGHFiu?8JcclHRGMfU3 z+sDNQpA6lT^4p*km0a;|F3#B$3CpxP>PV4?r_=@tiN>#h-d3~Q!*eoPN9NTk3J@>* z!|Lg`n?LE#J9QgfZDeLG4mJRsE8qZ&xg|1dC0i0naAv7I&c)gGjmX`X316~^k%yJ_ z&6*x#=woh$H&}=TpZQ$XJw{@|#{lAKIo_G%(`nPzDI8Su%9^=}=_BNl%x%A`iMQ)qe1O*^jE}u7v?jl`xD)9kEgfRH=g=JepbLPmD;XYSP)N7bH0 zqa*3yiqTB9&h^PW9$vKDp-{Q8K2s=_>^3mTdlXWk7Podhk;pxkWoIKPi8e+C*&4OJ z6kZmWGH7uexfcfenR7~>?foRX025g^jid<}&A(m7EmcaZy4txGXMVi)MXbrUD?IHp zddx4N*y`)6R(A2ZUky!2Fkh~hk(X!rH2_3|e7KZU5-}NPz&mf56=9*~#g^06(B1t7 zH_GmwpCifeZ1ZsDX)S`&@^C-fXE5H}0g)G$&DOr7LmPYoRWfKG_fb(P^RgzK#^xO{Bp@O4@KBIIy!(c zrdh8U?C$y=U-2CBC%ID?YQ)gy8;)@$y!XJDltNM?GD%8IJa|uR7u^6qHDkzEAU9hm zjjpa%3;TdC9-LTDb%RQ`-ZKQ@`-9NFD!VzDCF79M%0Eh@;N%?Fzl!YhzPg(0JB&=S z-x&{AnaQvCZk>}pJg@D}Tc}S_1nyIrduP%44uVvHExx2225U#Ys8x}Hi=G1ZNOb{q2U{4 zHHV?>tpV9&+!O?fa$aJuHVGzA?hvlwVGBImzKCP9(Q(i|y`fQkdq}Wi7F6*nl7?p! zD)(u;9zB||Usl!GpWd0jC^l|$qgUm?JOTm~<};7gDp%lYPI9{XY<$vA6GUcae(ClBFv-D}@(0Wo_S}t-!{ScA5eYEV=X1=&U7k zW6|V}O-#g$4E{|SHCHBoQwG8vt!i~Xr*AFQ$-%hE9BQ#lo7nQuZr_c8;qB((yDZEs z*H>54-r?1C#j_y~g?K^JbqBX79f0QFiiVe$=lAd50J(_25_LmH!%W9YLZP!C_s8>WjrWkZ>1G^NW($ zAIXg;zsOwM5}Ld}$h_w{nY$3_f{&%Foeyr*L?hz|5@$5rSMTRUXoq`rQ#z>~LRyS| zZ6b?nkPDT&jJLNn^vT61kFt)(j<+`^*M+6&oT%g;)Z((_ze9X%=XWq{iGO!(eY!*MemNnNdL82X~-;Qc7z~O-NTN8x=nn-WQ=m!y6?hNUm zo$Z8&my}fiu?4II3QE|kh{D$c_#i_H;Z_etcP*wrrIN)Tk+QWL*_w_vsI~%Lmo-DH zI1y!-^AQVo(uVMpgM26Jhut-@w-_H(zWBF3`sV!hYA#O{v!wTGoSA0kGwb|C;*>acHs~>6GhLcbcS4vxu~q(TXnUr4cTzT|F_ATyFJ0K< z>|{!>x~2w~3M3C*%%(eq-@V^&_hq}JeD8z2<>`VJ|76cVc}Yg(cG&Ui!h6W zhiKV#!o#+ZQd@&=F)b-IL+R^w9z(G2fZ$X7RfN!kd2F)hea7!C>}sZwNaxh1SHvk% z)36?85gi#9qu#)tpig&}HeG@z$el?|Q!>pdv#uw$vz`5jf=~y4<_)IyG3aqw=+m9@ zk+$$xkWY%rlCnMfc0VHW{ZdOcTwTF8Jw33Z`Gon3J8G|CxRrtExw^!7hk(fZ>t66v zceJ0DHjIVL$4~tk2L_(`VxWN{ma#s1tk-&do~&ia$jze_1AVcVf7NS&vERrMOijhE%Nqu;|ucYWwXQH8nN8Y4&T#;Ae~v zl}%p0t zB3bOc6)5;I57=sJcd}S%VuO3issfYogH(ri;J1nZ}Wgur6xaoq0tQOreV>$7G~$YaVt6>Tdet(DSM{UfMWh@ zigqN?Igx?QNscx?EITu#C6)YV9ix=%{W@jnUw#P?OUP*HLg&`&c(o3M zvF0B7y;M3HQtrY}_ds^LFycYcxTgI5$qdzGR`u7qmv*eLxg)%IgJS&75<-SxllVaC zmFK1py_YozoC$!tTi*54lS1xtC_TN$v>vv%9@`O_A`ca%~-p z^B+>4$#UowNajBI!=$koA9C3?35Z1~Pig@k|3_EapWxfPj*D2yl{QnhTbl&` zHX7HXV_Bk;{MT;jB(yl?#U672B{d%T(cv!uS;A2_uut z=n*@=$L342`OjC84oj7uZ!Z0-|M}0T#9WE;I8!B8oZ=xU9)(d@9Fy!b`*!#TasSIb zDj>T|o+@Lw=WCHsM)@1&Q5aKl>8hPbLdf&^MG79nC9<#uJF((kzc>9WN<~4*4C@~< z<8(4}3M(Jk+IAe0=a=)2=K;ynil$YXXlRcm}Nd9wd zluU)#=)wNJ_+P`(o%_si*_gigm_ey_!~@!Yq>f*zBQCqD)O04-O zBBtVM)Is+zsE`l;v4=xJaWC{?ql*@YVtpa*Hae>47L+$fPso6G35+MFd z%Km;uT5JE4o<`hMM`)@=$%;(!eKGeDN^>Ncw;5)XvkwN~<Je zCoKG#B6F*^Q6JGJFb~wnLdmIghG5g%$8}D?1qu4E%s-VKW7dM05O6& zec*L@LR_jNva^<^fNi<)l3S2>cyaKfu5Re2VUz3D=<#Vd>7aV6`!5vei;C=$Pj&%(qw1|U7lULSq*2x8lhCkI*5cu@6 zL}%f0HU;^`hqu?z*2P}EvpSL>RtO2fb2w8rBTAo9NDt|wuZEA8t6HS_cG%?DwA z+OvTlMn1(KwX+kSB0axrgD;M~41YFdmxd|CK6L@Fcr7-XkR|`ct1~~oSiOQr$HZ}S zkKQ18LVd0Qe)TyBcYEbqw?y$7%xW&z{JejUdS}_e>u9iRf)8O*n4j<2)x@)}$3w7) zUrS!MC-{;QPv9K>2H57FKMw&!Nj_9(Ouubl5efN<`_>T`b&JUiBl{GxuKtb;EMy zkjs zY~HXI&hK0tc^nm}Q0zPM))vp#uTxCP&l~{QgZ(gUY%h(%S%auzerJ6)^syR@Z1N(f ziRpaUr(G3150MZh9(@N8HyoHV^}o zfEjWzo?@Xkn}U+Z!Jy!x%xYy;5?DB}4pni_Eg=UOYMS6I^cnJOc!8ZxU}{zd?z51v z=%FkxFXFWw2>qa9tfodMSg^0Vy<@r6yj7Ao_-nYInei*Y6|;iC+sW#we4pJ*px0T< z;4IE%DUR_CEm&sN5K@rwx!hJJLf&6e3DCHI6b^!Fs%lY!TG;DPl1|GnGg>~@x_d73 zez5#_wH8Yx3=Mh5I|*6Ju8NDBWLM_fO-o$qDyTrL$_&WpX>#w*m7&^wvWK*KKW3B+ z_~tV_+|SEdI9e$BSJwTUUf&gjO9{`tkX2AfEiZR98wjN!*Q;hqP{T=EG*|+q3%bRt z#TAFjgUDpbda*jBR5l|PAzp|zgGv$6^b*1bep`{{h>MrNzq&PW;k7YoP? ze$t*5_rb8vi$NN!yF6W{;gi43 zQiiag#Ge&x$@TpZuUVLxF%0|~ylG*OPhxrBcajyo7<(Mn*CmlG1x2FUM}X+(OtEoL z%)@B+fF`yFXPC?b-~H2eYW`e1r?0kOddut#!_+yZqvS*^=Q1RdN5FZn)dJPQ?4b_@aF)1h- zPEJmis+|Ic_o<^V9rzbC`0fGzFTk9zRwv?(m-ee82M8pKj(_GuYpt++$fZP9bsq7bmh2;5OA%%lOEa8W`xXSbKG!pGMi8J z2m!m%&4qojt(hqHn}gYL;nF3Tw7hz&VZ|_O@^k^D6+9r^K_k8Z2PiGW1C@`2m^Hbr zW_l9L)jpXl{<^o@b1$Pns%caK7~-qN5g@%S!acfX!3E=J_BuH_kbif4k9B$Sl1~@$uwUGzQx|1J~_tBrRgd={k;zgz1s)})6&ybEVTrY z$~!Lus&LYDnw9&I}=HMX5U;Jt;ojh5jsmS=@LY}((J#`FKR$=djkTeToMX+N6wS=@Frf?VAh2pYSJ4;LcfY>LAgwEJZ3NM)z2pL^ZF0ijYR6TW4H$k5H zwhCHVTQjn-V1RYbcoJTg^;{b3K4B(3>$h=YXJS*%szmU|&JmQOV|Q zzw2cegxQVdYjWvoG)oZx`9g{tytbOr{sSvp@nO@E8(JU4jpM@fSP%S(nX-L_AA@Xgs9uUc1&YuVr`9!7DW>Nx)(7bsd2m zMF@~K=YBxtdkPYwak@Y}+8Zm>`soN10&TvBr#OB2<{lmttUD=rBiVNfO0o{E9u;Oa zPbbAFCku8@TtMk<&Le}ro?&BVaJg`6Q{~ke_SUh^^Lxw6nv)P&iu1kH(UCPShRAhrV8JNL;inW*V3v#N7R+jDvVZ(jp?aFG zj`Pb5xa;BK@j`o0B4k;WB^ukDAS5Q{Wv%t>q1gU6JFf^|j5}K^qn!ugS@u=beSsTE z1YncfuzCMy>w-0Ty?G0bt`gEKB4pAD`>LU6akccriLe6huw^t-PJvMqvDUEx8tUKB`-IC8+gE3fGt_Rn)_xe{W-P+)t@KH#c{;?1o@SQ3`8E zXVla#q#bJ$3u{& zwb^aZEr@B|VQt55{uS@V8WFL?ZjD8;jKn7o30e_d(p!$O0iU;mihEBej;$eC-leY)!!P_6iyCOdK2^5?k^qekF?8ab5%a@)v zXuem(oF>1YT||u|@xhrbBWwf?|6_SZ1P8}NC*&iZgJu~Z_jfcivoIJpT0q8ul&XqK z@OR}Gx~z1p`l3qr1yk!Aoix;qiGfJZy$=k)*2+i;v=&q~_$UO7fT>A8+OB|-(ErA* z;)g{re-;jRu_N7yS6R_h<+6aC>m_Ef-4^%LgPt_>oS^e50tD!#nnCj?H8swzL)`*o zi3=UDPn+#hP24{c#dpmbRsiFib4}=-fZqXCL|(x2OSMW-He(v(2HQ5|RqXX9C zCK>NPq84}5gU8nQ&}L2(A%gRK1qmUmUPUt+s|!g!IFSl#k&Q>VSk*7DC`hd3iOF_q zF2}rYTs6xiL}FtETUj;|DR*YdWXq73w{;R?V$`)Hr%qA(rgWm*AM zt(DEx6`^DHft)_Y{%90?z@ih|*D6@QRdu*Rph#+4c0k{uvy7T}y}9NtK)$SD&wx7@ zXrV7iWX1K|SA7?L;*bqW!!11pFnaC)n!d>WiP^~w}|Sa z{patm<xa#)g!slHRk7do{#s?#8)aURMM7G?q)P~4_w4GQMW26A z@fLdts`J~}qM|kYQ2kcM2#083f&BwuMidUNM1;mACDFOh6`7iMDyc~2e=_X5?Iq&o zm{gXLTjMnYn-9{p^e42uI_6mKHOo>gq4%R={o&3iIp%Uj_s~PKdGjLB_`P3lCQBru z1iS0|@1l@k6$HYPj-CN?xC)=2BCfDOUgem(P;X#??+XR(#{F<2^;kIR(ZNf(2jAe? zoU{8b20}B1=p=&1veIUX4HX;-qqc zq`!9xs3UnnO#6|dfOWCuCfM9JJTzx29%$ERMBpQ z@1`CXMHJ@dGG661EUZe}N^}#gsc4twH_gYBfywGAGLxOZ=VPB-%1n4re8U zU0r!=sb~Kb6`rX-5bql-%dxs#jKlYoFEB>7q`Btnz^()P(Q&z^yM&70mRV+RP2lbd zw%&l&Zr^{^Xl?&TO!n$2=hUP|l5tkuquP#ixMM-h?b(K&V0x|1eG`okyCfPKIQcF~ z_TpD=ZoV1_I+%Oy$6|wV+x~SlohYvTquA1q{?O1#b8}zR^AfnXSCr=;>@$~@1}~mc z?Udo|2_gvK=sQsUd8OK_0H>i?01;G9-V+RdDf~@-glk;*30eCQm1e4WD0be z2!<7#Dsk|PmF;@Z6og$5;D1zk{6b=1PhgH}L`z0NPECz@-b57Bso`Us!xOiVH8aL# zi|5OEbnbj#bK`PH@yy!}p^lEa_8P=LBhc!lo~NWtk6uOdGH$3KjS2vd75S_}pv<5W za$#Z;2zdMoP>H7S6^-EQi)yDE8rV%j@2l(u(STgp;qojzEX=&3@I*wUP)&99wSD62 zd8ho3I}4NVeeUOLh#-3PwkN-9(e>TuEH{5^>gBWrk=2#y5ff!(=3c4qs1eH8QkTC8 zkQIXuK8DA(FdcEbA%EzBBbC#eJ^u`gGphqXDBIZr3=R#?D^axGQRef`%gcLC2MN^n zW(@FoPLvv(oKQ|1<+#4F4hYEp3KtmJ0RFaa+aJJgC9rG>R^S@Wte-|Ps1RQG`_~jc z!L{bXdTyK}X(zl;y0-qlRZ#um)NH1CI)Si9s>NKyrMc`QTwYzg)@2|cs52(h+I)9? zU41lt_f_oGWto^3r)TG_Gbok(SoN|Bf;d-b@ckgUORGrSf9_s9iSq%6uA8w(jjp?t zwc@Z^?f~ni$TNI&%Z24}mAr_fBz8@Swc}?YjgO)(l8|cClOaUM~p7WRxtmPt+>oPp{?%`kv`w)he)Tq?#J&s zr}QS%$wjQctYY-v24SkH08w&#_djcor2is*>7#gcDx!1Q>rPDnc`_@+*H2Z<&8K=Y-Huu@BB^Wz|PA7D^|+ z?m%~aXZu;{Zh_!S^AnDrbnFcBR@>MCF3HoE7ue3=mE<&$28ebC1NU)PfJokx4kH@i zenq2uBl`D-O={WZ+!)XENl8#V6n5YA+--}CqxEw8k?B`n6(BK_!T#7SnHDIk=;;z? z@RYvduLcJPzf?HQ5RoP(*>PZ@rDtHdC#L}b&o9&+tju|S70}mrpvwP^xU-I``fJ;~ z1t=g$9FSI!7Lb;fmX31(X^`#)X#@c!rKP*OyF|L-&<)au?w-x>d7pPZv)0UCGqdLW zsr32oz3+YB*L8iYCbpCcbCN`E3};_q;OIThd**z3zJ4XP#bvcOB&4F^I+!|2aBZ1f z!h{7wvp1cnYm#}+a0^9m5)&(@-`)fg5I3aV+x_F)QdK)vJz5Egt*rDH=x5aSp8Rch z2l!hHN0?97*3QqH*W1B)9V~XSYz)QTx5w-OC*mAvraOn|^Mnc1m7eSwH}GeXG-> z&Ir1iV=)S!M^4gl0vTLVDbEC{`4GJmZYq|aim4Kn^KSgzLteNw&{T2@wRsSy$+g!x z&*Y`io{;x^ltLp#ZF_X8A@WF1R7|w9-M#)OVe8=bYpaV3w{+?%-`hy@jdG9|$II(Z zzp+^o>MyUPP-JZR`?i!BsRs%E_Ad)YWm64Nj7Wl|sfdEh>504cFZc8;o$?L`i+DJ` zd3Q+;gJkzu+h}O~%7CYJ`r-|KngVf&8l)Fc6-R4ztmd+xVNsm=jx&j&_Qm+s(IEky zP1DKi`1qG2r#{}kWE|2aN#hrUCp+-bAGg<(LdJ;={!(g+lGbeengknplwSnm{A0)( zrNq@EXww4LvMN~ZNnY?aBeg5`ZX4VD@VDTCdX)hH$~2A>lK|@qS!lb0k}@h*mv&^8 z=z@I&)36GdYsYh%80&$?=Bl9Nwa`W2#Rc|X{Qa*1LBH?Lch9a*MlrqF%;o(btukph zryqUVyDIjOA6X5-ZmSo~;RO$BCl?wX%2qM z+uxLp#2iBgpaV@kps~5VT#%nm$-uC>a+XAh$yHms&N%;3>S}yYEU_CtUt`-QQ=Z^g zP{B5~mg^ZcgHcHj=b4P-63!i@a<%&e@edp-*}YyCvqu4k!VwJt(mCxa!} zvs3sz`1&yL1uDI~zkrfHokK2)caK-@yV%Qm%TOIebm>*<7tF9<7?=$83ix+k{+@bKpV#Qj;&q5=O z;)B1^%Bw0;nCfk=zODsttCYP9iw?thb|sY9dBOim3@j1__4~<;#f5<1^6rxGaNWa3 z9#-Gzvy!1+;3Jk7;K z{xUO|yVIU&%Kda8nI)2?o~s%{TrZ;FcZI3Fp+Zxfl@*>8eT&F+HIQ1e`E*^0EUDW^-1F9W@G z*7p$H#%Bjv@qfC!)M~#9l1+7fg6Apts#(sQl9rZRi1gnME@{)!j^`>x4e+n}nsM$b zWMw_TX@5w&Ue<4p<)063X-;wr)ui*bhqhTAe(=e3j{Q<-jAmU$dISUlIojCV*1BHU zFbK$T=h0vRnb;CC&*0REdA=Vl3sQ)GNJOUxBGcQoa4nVrh9|A~B82`Bt#e zuMZ!k{;+4Hym?b|;2mC(@|oI-PLkgZot?Sh6+JkI5W?0^k%~=jeL)`*m~}MoS1jH) z$pB|5&aJJ;cs>X8M)Ua^Qi$}7BU!1%_$z+KrQcEN$L&)uN)}NL9*G%tfH(qsa|@~U ziIX*Vndc6Yt_Y4?!u{9h5s4PVhxc)^Pl4tLmZMgSeWGABYx8qyF0^pEScSUvG%CHZ zumQwFRwtd2@(&ISSdKM>4b9}D)!B7&bPj41DK)ZKujdUztsGtKE_Jok3- zrkb>wG;v0u{4c!L3{I0dKk(JP&T`7(*9^v3J}6IsTjyf=glGCWXk=#vZ?Dd&2fWQN z(g%D*y4TFZzxy&g2M0Kt?iMpQ?w7HAb7Qug*Nl%50#hl3j8A^!VKTaaG^;b>#ijTC z^?>Q4!!qsN^D%nuZ_JP0nmXTdnzn$<*^s2VoSaw1>FEZBpFbXjCf0qdUmDq&DfT$t zo-&yqd7eF}y*(CuhJ$XeRma66e-i0ZOM5P)z9{q#Fdnk#5L1DiIkd9^=%>7DB~cP07JHAWPw98aF`^3e74{SCoI8?pRrlUsP>AFTYQXT<_q>Yu9?Ru_*;V z&#qebn%7jZnC!;Ivamk?5CdH=Rw&p4OdT5#3GGfsXkTvP(~j5Ep!o*73H=Aj7-jb@B?)W`EEZG7-;5n}HQH2@>VvxC# z&6JsKB%kgZS2iH9Fbn&6{zqh?1v9339t8SURI%;NjK4%xB4JL8KF>2`fpQKY!YWmU`ZAMQJ4rQZV*^!EhUh%FrzeWj7 zR50GPIvm1sQQdFrI-JGI$}Dye{JOSj#G;|>p)Au2bP5iIq~bK=SuA*A=nj z>?0v&Wl2}uy^Wz=^#@WLJ|GH6W(gjsV#R#@niR|r?f9O6J~QZ)f|1qz)mvTzBnXI- zTBF?sr7R9b5jn~xze{lUK>6;tH+%%%KPy#MfxUEzMXU6EZDp~wKczmgEI(vi<0txJ zF0V{NKR-Dm3#NpPIDL$w1^oH9Jsx`oUpf700c=NmOvs!)ys`-t>%-(;ZYShk%la^ zE!E-3@w5v4gNeh&_cYI zWqbxf!965pZO}$)Bp2v@dYhu=oWyXS^4;$BA2|zc|4%eLk+1uA>VBzm@&akpeU!x= z9=OQL>cfu1SBYjE5t{v3QF_@;c6bGc$A^00|9jqLTRx_pEwS6fYK;{J6!O@>7>krm z;74a;I6vFyM$>LSi!z%YIR;@dQ`KOXo#d(;O87B~_wKH)=KPzC`dJzt`0KrT@-PHD zJU)KLX>pPdCBz-$POba*+xIkoyAH~+u(ZKj>cvtZTt9xicS2-2n~;$Ka7W2QBAutF zv(i#hM;*_%%RKYw=#-<^pj06l7rn}s0Y8G%e*mx%7>j>uYB)_GSc&zV%Po(Yu$W%m z*}l)H^m+i2-bFUnnQp%dvf11$V`*yMTf^0z$f`;#`WW3Wrf=Y}y}P7ZAb6U?!4#cf z60oPA-?d-@H_iV3@x?K%bajJlKAucR2r=j%fw@=+ z5nO#km^QD>;HnAq1~1Q%jLl5Oa+M0zV@^Rp92vjkWxx6v^656eQO6Ut;JRjjde+a; zUYajtMRY)+(1~KL5|eHIX%rHR!sx1C^(x~A-BC+9D*+0M8?CuS*LwRbc0djnFuM&f zi4b!KB7ozI`15b)J<3tQLg#eY*NzgJ)Y;z7X#$I(O9A$5^yYe#v-$Kvt%hf)w{K_} z#xlP4d+PbUBs##8N#MQ%j%r}H&XTRA=o}oLaK4%L!5FRz?wziv%7o1FHSnCgd`n5W z>bOz?9LnI*cncZWA&D-Wz3!M}1TR}@0s>I`vt7D<11C=C zH%<_1(heyg{gO$m^y`d{kdPvNOzJI}Hv|_Kh{L{;)nbd6HS0QAC#!|+|``S z%)rI%7vfm^8)4xlv|J-$M?sNp636|=agT@FWw!5(%zG8`*WK+AKwX|}1*23SjwhlF zYSmCNQ480DXJh+T_?E{FQPAK`Z1Fc>I}wQ6OY>=I>9lMb87L{Irn-m!40(|g3X92N zT@U4!<1v98V7fSDi2c2yl`E!bRv%xp$tCbM^95!a5!fGIf_KMIhVWg3)J?S+zj}hh z4&uD`tVoN)UkDxMrMQ^%dl^?7Br@vGj~VuxY#ymzOTEWq;3L z)EnZEd!j<5;C(C)$X)xf;y3!I$%k5<>-1N>HH0T4+I+Sy=JI<24>zx4{g>^n1CXpB zALYBI!p3>xv0Y_%6c9Vw5kk_w_ts^Tu|@`vd{C+f=56@8i{u(V36Wi1uohz&S$>8W z%f$dw%E&l4ePVy-Y84(PZc|%n^U1o(GSRD4x!IpB@8nZU2R+|h1#^p9_S^v{owLjB zn9%10lYv?t9qnY(^#{`zZFWY7e*V0!w{eB}-CZ9S8a=koQ!S1i#*35W>}Wm<-8jrT z=9HU_m2vH9%_p&2Xe`WYnhaP}`@`@v76%Mew7k;ACoq6?;@YlhF4K0Kw2et*SHMjy z*lzt4!+Tpgfjik18HKal&3T6a+A;E^^6tdGcQAp2aj&DTt+~wR>xmg2;05f@2eYb9 zsm_k@p~%V;r>ZICXP+_6HQ1WZZnU!59i6(v7)O&3T-HHaj0rre9Z`A}zrW5AWn`kU zA6LGkq<~nvo*q>-+imw4pcw(%wYHMd)La`68-leu(GBfVW;+_3o5O!vZW$}4p6U4; z8W{Nc9Y|g~VlZUO5y&_^n|=k3BKcE*uCN6grN`Drh(}|+Vq>t2iOUHQ1V8zM5=~zJ zkRmX9m{;bOIZ!&fGg&nsM66XAj|S7(MVyC9OMR5Yp4FM*U|7{R0P!8$V}+tjxmJ=J zI5XT8FlFU59g#qeIh5zg_D826TVQ&UJtjPSWPF^3W4T>~a6DfW3l*eVf+_4V3)N+( zk%>u+8N9`h3c!KH?nbJ0w5Q=kf_I8BYM<{XV3fdYW}&{$Kh6%iCsRM%t*||@@)v_-C<6qesfob!AM`wlpTo>|B!DfuS;j0)>NTj`ULVN9O$+_{{y z!!N3x^OW|?kM2)>jqas`=CNfX+Rw;^4kG zuC3H4D@!b|=sPPCRRT-H`Ai|~hzQ>`+$??R!7d$Y<77w_r1oMw8dAHdjdz?NYM0Gs zrg1kuhl0ncJa+De3azLbxC_VwiLf`nq>+s%njIxv86IKhu z&621M9&|;n>+QXqecE_fSQ5j}<5Cu7#XHB5eQTf{RjTO$YgE7s4z9C8va(fX)U(Nt z9_$ZpZFB`1H@K||8f1b<2BP}4W;ZDqtgnI6%;fXrBL560Q?}Dw)6pWxM-j>=INV!% zg-Ir0bnf%Y?dEZ9W;9-dAOVwBvjGZ}*Zm;imK}(+6=dUr>;=Xr|TD zm#UX1C$3~9kTzUR(95vB9`H$#dkw_Ox_5MO@wxdob$?$%FCu=Dvn@w#-r1Y zVbMXd`>KA^KW zG5?~cVK$!QayxPYqKPx!tbB??54)T!*}&(qy~nDTu$~nWOr|jJClUL^QN1fElaFam^T*W z+)G=gV`9Q@Gy6_eH5TlyeX1p<7kT|B+vA`2vh+8%w&Z*7E@i4s%A<+7U8vX)flrR~ zUW$SZTsE;DaWIe#4Q&M%&_S(z@>@MIj114p%F4@QgxmS#lE!M4%(rrX$+ zdXEdO8&nsV`llwt-mz^bkoy_Un4r*XQjdJH4Xdm|fA%~bLZ|v`YctB|zRZ7lU*&-6 zk)zT~9%%yva${+y=ae~sGYhZZSpa9I$RgjJXQIk#hVBi*?z52Mil2iF`g4#tJ4qcu z!ees_9C%Xr(wv;Epw%hHzFkpakD7>>^6Z$(9_cLe>q1?cB26q?C$*P1O*H6Ooa}0-O524C_>oisJP!(8Iq+9 zhu!rly!P1^v9up)Y2@y+;H*=dVF&pyJa)HRDG&MlFm~H;d;dP8P-ci<(OFmqY11G%_~h`w z>i7sp43)*;_tQMs8!D=UP_Z(wa3aJ`$oO4km%^R2JSy($oeF?-^+6BmkH2tq;HOw+kd13QulxO(c9fG^HH)NxN7_QdIq`; zz<2!<9GUSA1aAdZM8*YpfBW|2h&sjX$%6+rXPiCaG`#=(`jYatrY`1gWzl|R2|*PJ z1r-$)xL{j-Wm#5MHp)^)gMGkGB>~lxkPr;H;G-dX_+XK2zq41I1{>U3VYZSkE{0ix z&i88mMQtoXQhFx(^qf!E+{8WNU=^QTdt5vf^)&*)D_ilBgCBOl75kPQxsK3;AeJ_F zQ@Zs2r}6R}v5F3rM+fEN&xG08$#Z?lWl&DF2>7GcY}EXnoh27||9F)G6j*Hmn*2fs z_joOAY-lB0ENfjdkc~q=@7rjg)RUQ{jO>`DpZ~~M=|mrBG)p>{Ws6~mHs<~ zmOL`_-gio`b@8+vM4$fGd;5QYNZV&E%^a9R83f61rG)Q>0)B4F3d(urCcA$p74s92`xhJ*;XwFp^83$6&(*RNmN;b#F&c19bJ|syaRAiUX=aw68l_#t0Ev3c1Y>85)1HqIU_jBa z+0E|r0}=(6ySKi6#>q(!r%@P zqbXEp%TpK&$J-HbneXL%N5vrv6`rdLR|Vvb3al*iK)H{zb{psh-!d|Adnh93HoR*s z_71X{X7m3Ag;FzGzl{h@YSh)Xjm`O=*=0kz*(NbqZKV~7W|7vqJftG@yFX$x=TWf*j5AEs(uS6{OWN zL#?s8NgO2~s4EZZR&zLQQq}2p zoeA%6hTbK(7a{)L3n0>H?;+=+bb!B^C!!7}_|zy#iS^?v&t`adIP556+dBKy@x4uR zWVKtyw&H8EJftxb*7CALtusl4sRX6rJa+QKF3fwZl>)O3N{D94tQ3A&&G{b{tHzO0 zR^!_!qO+Xv9kQ3wOu5L8cL!3Y{=;r`*t2{$#zKNxjOWmokS!si3^mQ6&LMAp+2fIh z;}iRw3z?X_OfyIQqxdJU;x=$ZSZO6ik1$E=KSWviY5M>?0UA zQ#xQe$8EG?J5Wg%6qsM00qJ+1IE%sjCK@M==P+}2pHPfUvsa2x)9@&@R|rR2 zGx8d)HSN*jy2kPj5luzT$BVe-VdbbkkuTuuf^fFq5}90& zvDLx_i)Skn&f~Vd->LhV+dKaC7)geUDyZ80w`H^nA3d*3RT0=^J+DB4qnSe`gHOoC zr5X?>B_*NID*X^~U#OUljO2|&{ExQ@Nr=STYooKc`wu+t!pJdjM>vKiGNZH`4l1mM zzt0f1Pv^36yKatWFh4%@h~CHqVsj%|;tpA8ethD_#Aqy|CtO{qHD-VR;|=O6!D71C z@mGu999YtOGo;3hMYjIbXU#1-Skzr0E1yI^zz$jw?{b(MxH7w{j@uF*9!boVVH8Xk z4cA`UzWchvp!+NdKUxQc{c-bG9y9&(mR;QJlpm)S=DC5t3JptD*QWbXP8kT--Rr-7 z`;#OSm~&Wt)Iz((#pQU}Gjux#wlTGcx-*kB;Tb%P!Z>++%EpX==W$0N0tGeMGzUx4rnMLdD0D=CGm`T%ELF z9>Bo5Cc5PE4sjIg2!)7fe>qy)wv@HNE1VWHiU{`)U2s*)mJ)YG4lo0lFZ-|zJghMr zFx#s)Jb=|9mle)pU{u+U1D~2?;#YX?`Sn;mNOnwk?-YzW4h(~L!5j3{^jAG|`9L)6 zd+|z=j{la7Mp7u|vsLq%P`B68`sIy!3~D3&LRn=BOPVy++w7c-db>MK9}}}6W#GqlNa_{IRuDJk`Fi6h<9SC&^C@Pb#|*S7j-l7PW<+#w7Nsd zi!_gsQT@}l%w41Sl3=pzd1rx$Hd3wD*9t)&WLS!Szd`OXLo*DrX*^k+jLkQm!V{Z6 z9EMM(?6Z%#O=MumW_fLEJ=0*wO^=~<`GIMGbH7U<+{s|oS`DW4{xP0&(_y{Zn6MmHSPVEAv$h&kYh5O@&l{81x8WnO_C(uyH`TQK^t=J}&ikYDXIj z9X9SpwTzX0q2!O00VN?LTwozX(87;Q{8RNwO9CZPE=1(3l4CB0fEC*3V#%>Q*yp{G zY(i&AQ^M*B?<5TMe14}3JYSgaJiUua6R0z4*M|t=Ql18a82iV~3>fiZT<| zfydnG$ruG~4zuo>?I~hVqaw+$suBzZi=}Yj6nw4+eip8wtS#>v>#FV{mhb+6?V7qz zLqUE~;(KiFYZ6^kd<7J&lSfKbEZL-QS|Kzk(yY0%a$J#~F+WAxldY&}O`E9Z5~kl> z^UxZb;kJBUtd4ajdx(|%GcvA&=N52J%|HB%9EItfbF#c~XZldtYr-P>$K#1o)0FkE zOkWAzd8MGT%AoyY3>_vjxF--z4h+EI@;C`8(2l}nD`j%rtL*L9t2|qOvxB5ZQ6H@k zYrCGybJ}vrIBYSOtu2t8V&6P$UZQNSRd25&Z=a$K9QF+(F*!$pP%)SEuTT#zD3W$Y z;G?GRucmKc7ygu7G*xW?TRYWkn&KAv&O(2a!3vPi%(?GhLpNf8EWyMx)J)zX!M%ir z{@Csx!l36Y36DRj7dW`%I11XD`UZg7mraQl9M!lG$T$9v$0Kf53aL#@d8S=GUG{r_ zTUv^*51)W|((bM<`7^!zwdWg?BgCRe7sh@+fO3xqC%X)8$(i7r@di9z#xI&p7!~+#Y?8SfTCH=2iI@z2#-!s#on)QF}{;(zh0p zaON)8R=H=&cv&iM_M9(}%UZEaS2Sx}#D#RwE->owG^-v3Zhy-Tc+R5}+^_6CC_4}z z_2!(~PgWH|ANaFm-!)WgsNUREDfpbQy)m#+z?Va6N7oU9eHf^XTRsdc__?$RB*E}A z1ss7S%4{O%EknPVp!Jl0Bbi`GKR@|1KK)2qjnA*@xYb~^W$#$?2KP=;h7TFYj*3ou zu^E__wzVWQ8PG0*AKW)FEOK0562pv z$cD2TT>7(5dc|r3eW2E5+nE$RWj+xU&nzsgQ$$N2*s!R-TNo1%ZHB&t`z)RP6+cWK zXyIo~n1;b$bGaUV-@0D%mSh`Obe3D#abSi)IHoI%CBJVWnQsi{|i6#uJ2C^+bLXjG?O|aQ~z81Azz`BiNR(69D=)Oei2h5I+{{AuGgp2u?b6Rvq0IGOODAWPvmcXBI1RoWQObK3ZF|Fi3;8T37smmafa z;z|^|2Q9>=&8zM&XmOF-^^c<2?aOND8DMksELz8YUdhdQg!OGB6OCAUmfyR4qHfX=JQ5heK{A~W7!RzqLAr|aWHJ~Z+3 zB=AJ0x1d~gGESFT-V$Mw#Tmnz$M+x35zO!P@&l0o@z|!XWhi0|?q`S^+UuBJjJzXJ?02i4d0P=?AzVb9W`s_>mjc;09Ilr!36 zG=~gpciOjk%n7`EJ&o{TM*oFHoi8%u_&^ADoPp0Rv?TLP1uspv1714>Kj>z z>E7)Al{@BbPPYhyE*g}=xs_4;7PW$KY;5Bx%0AGON=s7vs%O5uh^x1Hbo<@F%*l3C z^Wy9lo?|M}>J(r!Yywu8!ac?Edi@iy0Dc}Fpnx5ba$7Ri8-v?7AoeQc?H}Cjb6sy& zT$oK>;42*CfzIvw~D4oX{EG4u^#vUy=btY@8P8jH+pk%v9iN9U@(_*&Y$g$ z&kt0+CR#E)KdVys%W{shS8BSpK=!wd<4cY)$X*b)j;9j4Bqzs8i}8rKTJg*iDf4;k zMEX9q!}FN-Zy=o(xvczdb;##=&&ImSY%{hf)S_y#=uueqHh<+%4$(JBr^dr+K=h=C z>?(_$Luu@6+zH|O*ygh=*V?nj^e+x^gtE)N$^?s+-=$lNDO3xypXA;>w=|o8!zVw8 zsl{zYMjD#JmgaDzy1jx!H;hdb&)UKD9&~5Wo7baBuw=fzrtXYxJ3nD%@Sp;qTa~ol zoP+`g%JQiQ@sdIGWp39R4B@S%JCnc#aqD;2>MAd9HPK(Tg3+N}Hd^46w3HG)9Q zU&=%sN&?F^gjkxK&_$0@qw892RplxO1o%FFh;#pwPHh?NMt~qu8N)gaxrs3=e0e!btaHj*Q4 z#YN$VB>I9J_szD>ga}j^OsgF_n8I{oBBTh z(~y5&-}!)4B|uyL3Fv)35D>oa0zUA(2f%cWRPcg-+ux(p%6arp8*=7F4-@mh(}O^h zmGoa}t!wLnCR%N%7g6?6{_v*I0xdkbX2cJ_XV`fK~ zUNcKfz&j@H_#Qu?eDn~*%hNwBtf?~7cQL^^a6%@b>O1X8TAE({F>&kl-5cs`bP~Qf zc-^zd%Z4jeHzA2A3H(kc9feoX>}o>^q&FP}^Cjg!t?>KUS=Wlb>~C=K6s8r39934b z#V%tv3c%u%-#MhpM4Ym3@kqxty=P^WGWHemNStgNb-G#O({v5hN4;SP$ook41Tc}F zYT2S`Q+5pu@Y}2%ZalLyC()o&uFiB~(5QONLKpY2$rUq6xzeQ3`RXBZ%3DFN$BPTY zxx(?SH?G!9x!v|)JjIwe&5}6}Ml-+el7Yy$kmvZvj~{v;W_dj?95;LV`RW}JLj$s) z*JT5o4D61$-t&73BmWqMzX7`4A)(uQf+8#DC=0Yui` zA}z!qK#s?e@SXdBt)s7#Ruh$S@TPX$>EQtxhoMWMUkDuKz0uMZyn@Y<d_!%TCKJo^*hCcB)nhfHh9_Y)hUxi zhD#jo?<}kE5e{g#Q+vaNYT;%SGi{AR9;mzSK)>` zsLQTVw|Bm3;Kqb=qf5Z0hvyJ}B+XR&SHyhgIED1VDG#ZDdoIBF!r5gO!dy~2r4!U^ zt4Ma1k{(mnoa9k}X}l$tB{Q4=(h19Gvwvu+ zn4$p2#XC-E+Hua8^bEEG++7`_BcjHJH_9A%FYXP6lvxSG_@K23zvTQjvS-X5Akm7y`e`Lw+8C zM}#jIV<4I4%p_CLaMfmD(W3##m>Ek%$VnlCZi_VSmU_kGHPOQzEZx$zEfkiQ0iTkP)$?oy#8AAaqSAL^|}6~9xDH) z{q=l=%20aisK>0`=PlUxp`EOi_sWSJk()VGA36*5s$aw6thF^nrXu%jXmW^C(Pi^(_A=R|FD7QFy}AJq zgVs6Hrc+iEF>Ci;Q;vpmZ{9N@G1dxe@UK&1h91AcxS}OeUX;REWFlT(p-qfNDxIJp z1Uv2}x1metsbepmY&wF&4I!Nu9hCUq>UiG+i0$Gkb=a#tmT*1@5;T0HAM+Fu6GM&) z4Yf=jrc=4L`TpQDDqt=fbqC0RvTUZt<+fW`o!L+q`r7i*9w+ag9N1rdlP2+G&u(RNe@FKGmyYrP*YB zS=cKcjvWzGIQ_d&Ou-N66KN5AIoh12xr$CXL$~s6u5D|LE8>`SPAic=!X8$B&Fz0x zF;F(94xE!kNi%YqVE|b=OkdpJWV7Fu+tGon&iR&Fo^mgH8SGyS?W*%e~` z0=UyaFlax-&}z2P80uP8oVEkK;PgDG)82i_{sU;2EI+Xqhe}arJsB>VZ@Sv(ntyJe zusIu?$fjcKOUoJqEM4XcH6n_NBNKNwDOgaKGi#5V^PUnxKH7lR!sxiT4)+^TdJcY< zL))v4%rmQm0&|Pu%!#LY)x+0vuXO?D8G6s&CEG&qM zs%S%yxN4jRfI`6ASEp8YOk{U9AEE2xV)2QuSwfh|kzL^K3@3}x-qOnRbP_{#%4#nv zI=abqr^dVCI=4-omIQ-jgZ!NK!jO|vR8-gp)wQZH<2orinqO}KHPszwnoR7K+0{9+ z;+a~a+8BuL7|)d@!o+oDMU@wd3{c4MN^_QujEy9&m?#=vH>8TqUY zstBz{y#F{VrD8EWI!eIOLb=etrXE>gIrRr*zMqLFpfwI8%1?bLiIX+1<3! z&^d==Kj|FT=uCTTQ6_xA=+Epr6Bh1nX|RAz+=n0%Yj>fZ9*Kuhv$4{m4O>lH6kMOXN#MmOnmCiPS>%)tum~F7fW`hT zJbd|Uq8Z41*z^MIQglG2MH`cmOQ_|w>)8Oj%3$=9&S1iil}BAU#`%(KFrzfdi!6() z%{1Q4=2XNb{6w5Vf6Fc32pU1>sWtC0n*|unRttH#Rm!yht^9_PGL&?_83d=mws#PS z7K|(%u8OLi$pKjzrA+N&Mj4_B9+zeBA;#eZ!JB&Ec1Xy&JZJXFQS`XG;@cvoL(VzP z%1sr!688O8R)*c5@v&KI0wZuu+H|-;SKU?p2DL8D>DQ%>3DwU2FRUB#CNU%rGGrkh z0ngKKK+%L}NCkVse>o4K`rO$QHTtRA*0OgkSn`Vw=?+~b%?8g%Z9LDB0JjrtzC4ho zr^MvSW2=*=!HJJO?WNZ7l4;vzWv+<~O0&%N+5m|M@3qxILw9vCvBCLV!xd&?9KVVF zNuDzNF|XsF2izFh16qb(_#WWrTvT|j69Sm^#w%+EN({(O^)4@h&e~H_aJ^2&iJJQm zww}ac^F#?xzym!hENpkt*s1-5quzV_IcI=-iP6s{3J0E1f{Y&VQ89-~Hg+2J5!#KZ z!gLVoHpXL;2+q4)SEJpa1D87P3cW^`_lfmi5_v=}l4Jy7&XQ7tDbduF8F6Fum>Z)} z4{07K&ArKNg6MCV=9Om$XFjXz8d}|5T8ROm(@60RA(8GVLKTGR5>{B?nrs>s^rns- z?c#oUN~Xb;i~&gHkf)tyj?ewuJY|JI(1-DmKsk9OrL3TiB8k_$k~{WuIMcu549YjP zO<$jFUKE}thlfi};9+rX05Wx07&Ck;g;+B^j$J9eHmmY`HJba2)m2O_%;{>2_DCvt zhK=XCFax8XCuObc9&@D$8XemviD=C}$3aK$Oz@Z&rT4Kqm{%g@a*pI(wYhOPW08n+V z_a`_B1Q3W+3>Jl=K%BDRiV3f9;D{Q0xP_r-RtA&N}~-?&(%nktAy=l}ug z%afg{S~F^KAWfZjdiFFeMo1l}v<;@JOKo3K30Tf6%h;1Kwzg&F*$r!*Zeo=(hffY>xxuq%Pv^DFn!B5&KH*}2+UaV zNv-R|X*zXZ>QLcgyYfdt(P!%P$X zDP!Nripa%!k-d^Mq1*n)N=lHd2hL7GnJMz$qC3dmyiZdHa*)f%WzB=Bzr*vowmEhz zhYKFgB>Y@l8IQT*hiSv*W(4GJ3Wgl|XKzqB-kyElax4GfVCE0V6YX;@C%VVt8v*m{y4cJlcPza7E_W zfiDlrXV@F!LsY%n?B>X%Wc(z8xCI>Tl|+^49q1?X_!S{AkIjf8%=V4K{`fg$^!S3j zJYKWuNwE{N=7arR9%EjpF?>*>-?qp=DvU6%K4xWNSoF#O+?KGMmIS=tL=}jsMe+@{eX{Et z0hmb)Mg~UDAVcmhj%tnect@Ds)o)iU8R>IK6^CqSXb7CPCJpD-_~3sUzpPUEX4VKk zOdGUvq^*bKSHvY$|5 zI$v_W@(CR#S#yqhcE{$?#Kt$p1mA(TzI1QtJ9O@FKyj4V3De3{fhkrXlhm`MrE||o7*_(=`ztjm8 ztgVbP1F{hADBkcf80{|^PwzwpT#SV(8wt&LLV)vTY1n;>L$>gt)#)aT1g}x=P8+Di z5sz73&X?=ln#(mP?Ur;>8Z=Xr}m|7kWt6=`@TH(zr9-ADzJ zz!!Z>)4wbDpN5j;i`V=Y<$zBbb)fG|1B7d3Ibp6d4p=x;RC){CetGg>hxNoy;rmk6 z%nH?Wivas_Oy6o_DDEKLwR%QoW|^Hw9twzMvo|+#y8TLBB}G7!MFoK3FP-`6iq zlW?%r&vUvOs6uMLT5PTvc3}Z8eu<0wJEVjB;a9;vfeg)==%(ARyL)cCHGGDyHlnz3 za2c1CQy;19GsL7_5P4zi0ARsY#$ z9{6dm60x)xEQE~tha{#On+uA%HH~3!)h{Fe#cnnAdkQL4u+>C*OuEKW2N4}2R%fNGiyWfr$_SfrM)KLUN)l08?I?f^qGCL+x|u-!k&+b|z7%6ff+o zEWfRI6lE$dr}5r)nYU0F68T*H)E4t#8Nv4@+~S*f=O6d;eFg2%i3l<6zx$=-0CJmd zjqZ*Wkb4(K!Z;EV^^Oh;|E;Fn0(^#A=Q3dxfFRh|m!2#4t)}B$MOOwo?yNj_&^-?w zPV@QD7zWx#AWa~H>9>XdRW6bwrn?5Wg7lxZ(HNIZ4vPgjn->A%LupBKi8OvfM!`+D zJWSfDhllW~eDKuSw82#`lFah3MhH@6{UYHNqP?7`MSHVN>?Z+3aXSHD=shCDIHC&Q z-o}@CDI#6%OlIc>e%RqtyErIUfwiS1s@B_ZIyAp)Sn&BmhM%01o!$1}T3S}Q$~ERR zk_7d#G!!H)#KjWy$2AB14j~ip1t&BjW~M-2*X1;gUKHiqZ*u4Ic%U>mp($$~{xD-i zrhF!)F`gCYlpWGQHvIJ26*ew$nf;idi-Zinnnn>FKzm=z_q2fK*NJ zmeE7)GmlhYFFl0w3mbQ4Ma|4jRrJ&`kRWj|V(Ek`~aw+%6+?|_k zsxQjz2OM4e{=`4HB$}qxJKW|<<^Q9xYmbI<-NU1z5=kf`cI1956B@&aj))9$CztJ> zOXQYvne6SZP?V4m#+`~9m*g(Dp(J-kh#dwM%@8x^H}*bjopaVXYwho!nKkR3dEf7w z_j`Ze`+I)R^Lz%`2&D>}j!ApT829~<^I+&bP2i7vjjb{A(8{GLT!OTh`HlvocZ-$E zt{#w^P&xJbR#ZzfD*1xMXk3Rs(cxA9cV^z)dbryMHqUawWc&q{U#CPGd<#QVHtDSGaZ5s)B6{4Ru1T=OIUsc>H}9NKR9wrAiMb1P;6-4==xU zl>BxiosB-kS8VpmDQompq1_D>s>ZqGTjKhxb&7!Mt@b{8OKFj#TO_2UHrJOm^|MP$ zOC28jpCAiZ?b#b`QtqYfJl8)d*9%gKJXYbXo8QF)FJ~0k%!daYBNUho(iidF>M>7^ z3KBhYSB+;L+O%WSUA>1=MxT!NhjinoAtxSK1}gBz9I8KMPT_C=Il+wv0>H8xKd3K3 zTtWGSv@C2~YJ$~ysPoB$3Oo{((ci^Z&4G?=wd-uWn1!hQ{A^j0VVnJ04DERBLHwbf zV44WB5PkPnFZOYbOm&g4=xtKp6fO?}d&5Oxu;&PGke}7NlYcdq_Eh`VvuD@+z6^3U zT>h$EJ?WpJ;(=N}ajMPtYggHZ-e7%LNaO}O?nZeLrRS}Dl2t6*xgu~TzZrM9)>Z;* zZvDk+s9gCa)9C1!0#4J!ge~%s&?Lsj!AP?qd*69AqHuk_|HDLF%j>p9a3dRib$$PC zQjXxR$Q19$*->@^ag4*zL`zq)_|`j-s~;vGC$4jr2WPp86Nq7tNbft4We#G}FT9MtL5S6FC;ES*&~MoH{*- zd?ol& z&W4ELG0{O}7Xoxgr6(mP=U2CXQyhcG5!oJnut1(HspB$M0i{EqH7W{dRw~uOWu-F9 z2O}?g(MrF5*VFfTb|xnF?&4^$6Ogj+<-7?k!6P>~?!*2@yD$lH&gc`LfN0**xFc{H zoR2(d0xEveQ7{{JSd|8z^v>}&VZ&A2Oh2xt6Pe18Ux0(^1u*Is32F(Q-3-H-Zj*dg znm)klrR=TV_~sH8TSOYaxs}2U@sz<%J@FUhW-RmSpd7f>u^}2s0Dm^pi9JP*#|A5i zh;z@KTwG+W-drDk#K*H1w$)Jx&rzEX{IcEzRbCwnV^Gl}AllSXvQD)fUd0R#$tN)( zBsdv^IL-fR$!l?(^x7RcFL+)^Ewr=uF(GJTfgKHr9<$sxySHU6Ytj~5eS8)OEAJ#( z5OJa+A|k6TZ?y@1ZV!HbiT*5k?T>*;+IDmzW2{QW1jBVPs-qhLlk2bV1v(vAWD6$R z0N_R`r9V-YlXWgwY%jn(OX#&Cla|4JI&WMol{v&`K`G)0pNZ$WmG!kBjxb~hAqa5X zBl{k3F$fA=(VS3GWMPNgOL}`RsfJPr9@yxi1n;qGcyRHv4it1iOc5j{B?X6TF6ikY zQ#*OAPKry%e|iUKa0D0^Pk6iqa;w4d$zy_RzJHuc9UmX3ofn5MRNJ1d_UUc?UAxzF zxHfT6HEgqgJGxJ)%tj|5M-J;15Ksj^dB;a96OKf(sOD45$~-&aM4`eFE?#{t`XhKQ zJ->66OS@J4WY`vOSMQK?1u~#H25NFaqMA?T+5CI1qr3=eMqb`YKR=iNRDLjnV5dLHsSK&@iPbs;M1Asz% z+m~q?Z7gTRMHL^|zy`Lp%&ftd2wC?kh2038e%Ucoknab(0ehhJ7(mj1pZ}=0MeL2C z{o6#FDkUkEsJS}-#X>s`!o`wuFnZshN~XY6xXw5mKFAMag4UL%XlhT!)qZ|%Inbnq z+GW!TS@D{h8p{zz8!ck`Ko;8ZN@hFxD^Dsa8G&F{yZ8?clSll3i#9cnpH%%rlrq0D z%|bLWNm8%&Aa8J?EB$;u$EqKraCf06%YHV*)_#Mm2CyBeiTATkKgfEJ^9uJN-d6pF z>l6ir!t7t<`w)$GGc){WuWvrxsB9-(8-XF-CW*<4WM*czV1aDDpT>Jkkh93z7QK@0 zg1-PcKiPt!>uasd#YX`Scz=oYX7)!WgeXD;E*+ax@AfW?ldEe%9v*HHBcJzB%Fk|1 zX=`ntsQu})Jy%~J90+sAyEd49k+@(Q#j)&_UC|9}u;*1P3T~ZU#3g^x10O1n+9W3% zA3mI%e&$7yr}I}*3NyEUf`Lxn0F@sw;?7X{`)dD3eA_H@EHrchJr$i~&f`wTID=_L{+8HuS9RaK!z%Kbz zoU&ZNcQ$^sOUNvmuEXG%-|RG^Ql?DK+3hN6^ZdE5%PC3@_*9NKFA7_jfHfBtr^Jln(_%*9EetWc z;DcB@OxKaRkO+q)9W2p4dry8IUi+=6hlfOWmu`2ruAZJA!~bkrOj;T(Dudahk zn_(fM*@V!Up(E9i$g-QCzOkoIzV`C27fZ0dA!r|F;D2cxmppfdu&8NWZc3t!u0vVJ zcGMl$I0>rbKCf_^+cd|r;LcDGDN2lg0_1gy((3<1UdO&wH$<}^rf?P}a?XaErU+zT zC1K(Fp?pWPKr6=9Kwcdm^J7^(@XJEkyFR;xk%3a|6A4t1~?J~~I)NB*maEhMC_ zIggLN44eNFyd5?6Orw4T1>9T8vU*Nz0-2oFFGb3_7U=H1V$z6_f1><=R-FnV)0S}6 z9L#}DODq($ICEB&Z7&-swC*4Zi? z9=vzDJ9Mb!<2h<=Y&hpUXYxVD(>NX1AG5hx^hRN@gRIDW@V zAjDxLQi+8|=2BsZ{rpTFhW?e3PBsvoKvec?;4p$5CWVC5|4lc;i?>JKKe7~RkHC6NRg?Ur?vwYABq?M4+AHq^WCtQ}ICwbZ(m-XRj|l=zO$)Hs2l5IE zx7YVq*M3z`vkhs;K*q#L`y6fZT|oR}JeS#SZe39Xa-FoiygYf1TA9f*!Fx2$EE<^* zDUZ|3PD%E*iHApj^je72mlIm_Yvz#|9ksvh+Sw&@hS+9kMXfYh#ZThe zuXi<@Z^Q{eNS_`af{ zfztBr7OE*`QO8`BhR7nC6>Fm>cSN;IJKhJ4jR_EvNX$x|`p2t;gY0b9&W(rtu?!*_ z^M79_Nx(e3TwLffgTrdFb#+`I-Oia>G_d3Gt)%|>NM%y}0gJrX=X9QOENtwrvNP?! z{*Kx40>@IcfUpd1Z!b8OwYob`@uXW~r#CAyM_Mrv`vdYIq34+BXXn%+PaX>3f<2h; z&L3H&HPQKXpTwu>e5u)KV!vAoRdx(tBCV$8@-D;u&3?gz9t(rO$8NRFdw+E=$eE@j zF>)GW{A2LV`|yx{UZH_3htZA~jab-mX9fcZB)Q8-am*yX!EifYaf(Q; z0=Aim*Zt$iSHJl5M@TT6M8x$iruheig^sKCuhb^DrN&dOroaaiypdOCPS)-EDm{o+_r;eOb^^zRR~kQ`3)NwYth zknH@*z?bd%i%s^!xf;>#Cd*|Vasu*-9f4SUderAV@Pxn!Ql_A@s9fKAnP!1pJr8MB#gXN+0Rv&-__lsE7@ zgjcxBvP#%!$*>$cDDFo|^96q_6Be*YF~l(bD2^eDXhCb9k{kLie*Y0GYUo<0bt@`r z^&BmMr~3N!>pP*y>(LF~$TeuKWwyaI=BHPoTmf8T;FROlb))K!_axl0Bzksdu*coX zg8e1FrcnGhuNQ@}`)&kF=ZC|xd*BmwM3?Nte5RUV6%{z_)~;_GR>kq({oWnQXCs2+ss(ttY`}A~kN*>-~wMC+qs+yG`S~ zvP-%QuFACvKnM#7U<*MW)*&ZV$iDTM;Zo`uji8{s@X5>Tn;{EJ^tNn|VyW?Kx>#F_ zx8RA0N969C0RJwa&M3Xyz#q6`WYjCAJ|T*F*)yPid2jn&?<~NU+w{rD@*j(KG=}(d zwI09o>0w?AVbM!B?IemKfI3WKU%>8+AEKBRmN56eXeaaC1iE+_qv&!3eT~P51Jr6O z7VUam;&G|H;iWDX&Yt@l4&OHQFz|kum>5&bRy0_s87geH8Mb=WC!)Eg3j7fJ;}t$8 z#7|>3ec4^Kq|TA+j`f~J$;@M|@4j$*m7fC(!itDWcgKmUt3P1vzP_GJSYes>%B8PJ zp2GZrOB$2odM4DrA#zkFwH*b@!Jce!7(u0=vXqpFPG)^0)561Z?K+(XHfrgo2K$O$vER++xv*6GOL zVEC1;#cftQnz)$wtXH;{Jb>b)tIOW|o`6R8yGm5jm|2=Br=r#aBN$Fv*;Vz<*zsFf z!TTGYF%1PbE(@^2BUm1B5**Durl^R`yLPM@^yMtQ(P9PJ+)%}!xu)r`%QyLgjg1vC zDi>wiOYqUdwA9NM-#$2vyg2T=zWCG8Qdmsa%43A~R&JQ(t-@heYM0;6mkx?De6gc^ z(vL#GHOqv-!=s`%iR%RO>{vm|THlrZa!0aNOJqE!c-$NzfBM3YEEcjZnMnM%&qWc( zAdrDC*R}fvU**&6Exo_27Zn}IY5wF}eR>LmLulJA@m%qb91~M(_hX*FYp-Qi6OC3H za$4(+Vg&QTtaQqvRfI`J0|%@fRL*eu_0AU*N3@l6M;Oy{b4-vn{kjW+qrkUj2yp8Eb#Wv$#S`}>sas58{tFP(Vq}y zxu*HBS+dTi@+8KeQ+AZaufmND0503yw$Nv*c?KMH?!=BxUky9~mowHvR2GhTYo$*@ z6OCfJ^TaLM|NDijctT6$U#eBqyEXUKx28qY9f^fcSd4HJjwyC3PBKPrf7q^~ZK*?c zO_xmYk<*+Na<-U)T;y&(}V_I(U)I=E-QG6gQ2l3X)_(Hy@P{R zkG=24Yy!G(VF?GtlloL^dcqMKEAHhHUmm+p%j8>{OQ!q;7i;v7=gYFSwpeXfGI(?J znOmKxn>#8+J|D$jy*%QTqF}3#=j=QSGK7h8$;PvN#=^(8F}5o{ZtOWuJ|)3e>O(zV z4Af?2Ary(RD7w`1j~930bx+TQrgn1;oBRSCy;CNNrtXW?xPl_54rVRq z{BwO$k>t}JXOU;lz$kcTa1@i@pxN#YJkMC-QwbMPE({}0O=K>UGaWmv%yU(yeW$B& zhj1$5Q7N6$RBlktZ;SlpO`=^Lu4H^-Tn%_NK|~htlVRh)zPa_xNs~#N@S}#PB~9ix z*Dl)%8d}Z#x$^sHiIe0gD%szD6hEu^1+}}CQ0IqBi{@#yeTgLU zAr!3yi5r4FKbxjf{-Mr`yu>Jc!+K~Xviz@^W8@{HY+nNN(`9KGQ7xlBE&XMt{>S_% z&e_c#4+qC;hwD_%PDzpe*zK&}o03q%N5ADwjGg;4ovc$8=w4hY%>A3qAg%Jdk61@6 z;RtC9kj*>(L7)23s%zzaQe)^2LpLzvbu%xdB{Ws?PaC&dwOXDHJ^gW@DoP|>j{Nf1jkutZ#ea{_XXdrraBlYlJe3(_S zW>aq?l5TG^v@w5;1NW}yiNvfDALmX4Jq`;mqv#DzcSIytt2g9C5Yq1^0$QhD)tKOSB3JR66#^j98O(4P-fIUjKTpGarbjAI!<;hl_=C-_# z>1(r{h>YvN%j5MD*so)T?egpEd$145hGINAk=1Qazb_toi!)?sYinQeq@+=+o`&q5 zsm}I5l%6cwppGJbTN1hKP1EWQ%#1ILH;Yf*v!tkZFVpksQB!(|$9B#4X!P!<=_dE) zw)`Xd{h}(!je9;_z>Un|aCnGOKv2+R;>i|TzFs@iQ{sR2;i0XG2!}@j#;Q9*)Pd0U zp`uH!25oeucEx_iFz7E4*+v;Bu9&GBu+t|^&E(+S`*s@I=*U0r(7Y($)gFPYGn$&3 zj&DBl+O1`AobAlUc;Az))p(Y~4k~e5zx)#%`n9=jYORjjSFHK|CN@KH^Fvm>cuM|m zkBTv6T;V>{b|=`?p>E*z4(**OfLb5gxim0@Ty5kkp&S7n@a&?d?J#3935z>&s z)0uwH;BQiI{%G4oywYX=YQNrrTqZX8_e}`)nvcUUo=q^vO4v)jF4Ibr;rp+6 z&m%>mdByieiYh%GIkSosdQIZ1>qKgSChJCL6leDOe>mW&*be3v!g$yCKse6DIhQ%OYdBIz0qDMh3}kY zhV|nNKKc>naEF_1RUENdmhPRo8RISxh-_X+TQ#Bh(+;-lrB<)^_h*+A0%%i+*eM`FAUIH}jICS3l^w z$dqH7=C)FoMu<#c^sp%$PyK0=1=#5(KheZ&CUiL13|xON5@8o=MHiV%zA+MTL;c) zlGRFiSVVn6tmp2;k7o0gQLK_l%5%mp2l(}(+FI4HZAtzn+vMxozf5)p9Qurje0BCa zx4IEz!d|DZV0d_}r=d&2sb-g|^j#_Q7jTvu|Rq2g7q&F6JO0753{ zu(-I$sy|$&7$MbYrIl816l67$c#-T_GZixHe%?FZ`5YtYw;#5(Iju54c4gF^!lYH| zS^u(=v={jA)sjnEQz=rD7SZU4plmXOG`52T-@B%r+QlCfiJ72IPy*mhblF{ zI=Sqh((3U5Tva)BOO%k3a%aK0vaFwgy~(7T+kYhHQ-%xE)1`W?zl&ha>1cM%rPnTb zdS_yCs`oqs^WLQMZj>ZHaEqHLR3#)-WyHqTIF6kInlFU>uZ~*} z7>TSI;X{02k#{eqn=B`Zmy1j$R_+tcT92lyA9t_(OBYniO@thOyT!cT%9;?`wtL={W>=r5@O=MyJ?9C1*SIIGXKwn^(gIMb^jb^;t)*8UFDOS7C%8$h z05$T!!hp8;-R;v<-k7y9?e*>LGETe%*_oB*k5En*i+fTUm?J!P!rMhD_38|j2lVje zkky;LD=c&E%Jro(;MkV@X)A}Er_|nBjI!8VP{vpTcjMClCks^ z>I8E$AQSYBJ-g0ot!X~jGyMC&vntZasC9xhi(G!a3utD@$nY#^6{wZ- zNS43cT&(79qO(UKXn^cUl36o_U1w7D81kD;?r2mUM-y41In>?;75?vjw z1N~6KRb-eWcyoK_&B&}(t#N-sNS@Cy^sbcSf1`fJ$vZX}_7_1mN5R93NGZ1bB6wJJ z1XHsA_8DTFqB%#gW3X~mkEfh1hZNq|1a2}ei*WwvSPPZr&?egbyqO?(|z*VoTXl^Uv6uMdx9 zzdskDDH=(IJ{gW8hRcI-H&|j>k)n!3ohzOu!X09?*Jl56I4SnRbr(R~Y zTNIX4n;+eqxBM<=V^jI%3@GyKkEPda5jgA%Olm}+D2wNNcdXDZdCE7n9%yKPRtGKG zI~|OM-CE*+s?6?KFTv27C3A#~2ikWpOVyG+3M-Mr5qZ)N{Z5(r)7IAYOe&s-j~|?o zj-SGydfRf%>Ka>E9Ch3~#qa)4QBR(m{0;|IW+bNoPTmZUf{OBIbdp9xD5npvGZMU_qCz@))t0IbauAggjEuU z4h|d`W*rvMP>DLJyKq%asu9#ejp~s^rv+_dOCnkj*pa>Yb5D?(l}lm>zK9=)2<86sjJBF1?4MU>XL(1I8{V`4@wq~#cvt0^ zkYg~YjNNUQlpb2`gvi`o<*;6ZjSR`zn3#n<@4x&JJu+KvbM46k>ih{=2@ia&UB0D1rjeOT}S4&i8{sps!UlVKY zNj))!4b2|RkSQ`~GL;k+CDEgj2bPMP4GPF%vu0AZSH*zHX57z(6R)k!9~`N|%9F-Y z7}a~vyk@%Rl`;hvyW~Yi=Dgm8UwXu2#_YmF*xKD}%Gyi@kc#kFbeW5%GUW*`7!4X? zHF7Pss65*|j&?4)D@HH7)BpQtXhMvL=0S}n6Hr3R>LsQo1^{?(t@^LHoqM?=r-dwWwQZQ-He>1ky9rz_~x@J!IBjI^Zk_@|M30S=TGZ=PD@B> zbI`BC|Fe!Ni9r>+E5j<9|2?0Ln>|~^`?{K$5vps$JYwfVc)h{x&cW%+1TiL1zT@wJa&$84pC@sbxi%<0Y>!enxh`3y6#V zF^jT7-XMK<4`9w%UYp?V_`O32)jVKq&++&)&*M`k{QEdZcjSl zN%5*zJb0*^aR3@XYzXP%$OV*-%j;0T$h*gLLq6S@7hAQP_94tPNl=zVUy*d>VY zdoFU06NA;va6ev6f=bH>0n5}IM7eCK{BGs-Wh07o z0S{V?)+P>big9AMv(Ex%3X(GZyGC{BXw}K&ipO?r; z6l6Xei{*ywxV!+JjF^p;1ap=hi@@M6*3DRuX8}K-^Ah>{{aT1QOG~H6p6w4?-Qu5d zZS=*K-vfZpF@3VDtq?lld4?qGjW+h{DZ@6u>(ipYe>YE;tC0Elcr10)1y%g)VFup? z?7B*J#tO}~Mhj!wt?nsa6nl_f z^Xq;VJa>8G#d?`(^yvao)A>Lip8s!BX1!Wfaq$9R#b9H3D-9J*xU>ix-8T-7ayQq- zY7#vwgx+x16;2L$!l$M9qzoss=780ug9+3jzx8y1S2@+nN|HgL@iTC9f_?=vUdE?WAKfM<1?zn$o%8E7#HvrRR7K!9b~!wP zkMCAA7xkLFBA$0jCI}a-X7jhqA+UV%TDDz&H+BQp)YF3RzucjFNJO~Op6%EXw)fq! zVv`Mx%2qL|b@%-hu-2_2)&FoQ?S%INs)6&Br@lOB%FEA6@Zm`69dP|2Vm2(6(DCS} zjEOOBJZU~()&p!wW!T&Wjq!9`d(Ae8R>8SeczZvK{VL3vvF`)CyN@l}42TXQx;iz8 zxZYo1spAE@DAT#&LU=+|o1>XgP*9Vr!7tlI&6gVo0A1N^){Z=Bf0RdVLxX|JRj7Hk zFgw4}3PG5x?#gEQy&e7K@#+3F)`l6oPg>z%${e!Tzf7tuXiQVsU4_SL2ss8fjl)aB z9MFFibQ-VmGcyZMjR>o~N{`C>!W0M|QdibDr)L!L+*d2F=;L4Nyujz@ zv1v2U2G!VQ5hjrdUR(StjLtp1Wc%&nD$;uO^ay)sVZB(UJF+B`C&2ULtE*= z6a=Igj=K-b>6(l(?tVtLreSE9JX*=yP5A{sz7X@x7m7xCHI|!TR6z;;;%`$T22CFt zZW0f@)7KEGk~<4yFV`F^XsovXEm7Lf7Pq$+(rLGJkIsCuK0 zmX5A}Rd5CH{y|>;20X7{8}lGrr!&i6;^}lSzA44bJnjg?c&etdx*-5rBPvW)f6IeE z#b-@zGifxH!%pM&-&3E`Ca@HTa)dD&*MSNQ+PRa)n4z76sN;E=lfZn`>B>l8esTAoBA8H3!aW453y07<|zZQa}CEz~86&Z3);)S8i2XCe)b{)r2JtgSraHdpLNcy@4B>}&1ks8gB`lkyp@52LrQqn+R!^^;Z|v-~ zp;B80Q8n%@PWjHSXel;29)))yBU!>tBKoRueu3qTaf$XxlWu|Tay{G}PaX^uR%}oC zUki$e>urh&Ht>jLZx2594OQUQ$go=^`PEwUUI4qiZlX2-9zo@>=$1`vV{VsAX`T^_ zVuV&2W#nLzqs&_%YN(1zm;j;i$xz8h^m`?3USmkCsS$rxKH9wPi=AZqzM?T5UZpy9M6fV)ll!(w)q+e8<*LnA$?NMM}oN$ z#_FOz+R5s*hB5GHuc#w)kteiBt0Jhpb+p=Vc!$R3w-2dD4kFOA@$iH{+?H$k8XVQz zPEXIFt5MElF@ysT+$J>U_2=Q=FRrVoM#_E(`2d%u@&k~J6v@MX{;>T>NtTD?4ly6; zg-3|nZkJA3$Pb6@Kpt<&D-19A^SWov>wGYp=M{q);6VO8LW?4R5k+epugYL}fZgr+ z%{iqyPdq$t!Xzjw*AW^!K(LYD&cJN>fUhMTi1|-ZlwGpxq}{1!*8$Qt5y^^lE}8To`~p9E?Wq)Ayst?x(h8S;I}yGAGs6-Y z)n7JiXW3%&NE`yxafj3TcsLmJxFzNfjV_#w+Pg1xSJXtln_S4Y)(3GRQ6$n|m;15(rlrL+MkBsGQ$@BB`zGpky zZ63xh@mdqdQ@{o@Xk&qITvNvp6BXurb?iDD+&Hs=-q0>rR0oB5lW~1;#ncPnE{Mb9 z%z)b9CP!$5dVq;!<^i)Vpi0g2TQ8U&9Qy0;l4vUHp8==6nog%P++Y*qRwEsfFO>}o zN6y*~R1{r=>FM7dY6#hIDSXc3hmBUC*|YGgSuArFT*lMNcgvsBpFd8lJ;zk9bX1tu zKh?xQGf^>rSYOk7cnYbiu)rO%Sy|pOVsQ~Tt^uC#WIQ}PP2twMTOvv{GMIMP4r@h{ zE=`j4G@IU=AfWr1NSnhWoIb&_ZB?7Qo#uXDCoJBmeYe}7%t3LLx8si>HYgZnNAzZ?3C^LlyH@w7Io)(!`tw;n9%RrVvz|B{Bm~8MWM9hP{{1 zaN(?rdMyN3KjW2XNXgs(88*l#hMu6B9C?m5W10Z!J}z@#F+#;b{*EsL5U zwLHHnhUUZtX*kQ-j;)#b4ET3;j3LyIbzPnOEILgFFNiZdCMuv#cx7UKH{4fT>AHN5 z>`xd3tKH8~RLE<)0ssCP!*S$NHfLetn6kRtbjUBVOE)z`^j~_#RX+{kYKgS>LpPN7 z@p;~3qG+NVw14CO*`Whvd88sY#GJ;(x%kNwYwszOSS8Hpi{TLw?eB+(a9EpoebM;W z05tZ8tT(<1qm}71V;b?JbZ!M-h$BPD?M0U@WNWXYIn{JbtFn|c`Xyd7W5AGeDLApv zRm@r&^fMRKeel<@zbV$zIJ-)&$f?(#OzE#8G_2}_1#RO0KSxr<4B~eoTI{w;bs|@o zVt%9+)c-5(I_JwbGTOLudwT~>Ir^OL!cO5CEG*!X=<&uG6emnl$si&knok;bdT*@V z6g3A0=?>IUA1}xWhfIxdrrZ+?3YQwX550Jbi*Jy9^Lk1I<~K58;@@yw_8JFst&ER1d&%q9NeinSXrw}-vQRL$y|aC@wC7T#(q= zp~9*x1h|vhEc@kpU>ra*SE=c#CXKbKfDiGl6u@65E)`s&G63b7 z3<$K%Unr4=m)>K1<7#Zk?!IJDud@KLRGm4QZTLUT-2os2@eopvN~nPIU)Ns~Xl4NB z4@0*AO+&35=-ogIv&_lSQIq9*jXT6`AfnB}@}C*iu0R4J$RQ#$l90PH=G(H;(RR>~ zVw(Hu9PE;u7&w7k^vk4yONDlOxy5i{rpR^N^DMOIal2U6ONR_D4PSyb{IOH^+XR`t{>SCi$T*>**V)P+WDlpbwnq~<$8FxRQ z6mb-C&Bwp%d;eluK2Rtdn=S1Bk&iBUa5s~J;v%Jbd8WqTj>B^5qph_q0d6u^#dw4^ zD2qg7@`!Hom@oVrE@YMHDjSncc4eO8Jcye&95#~>iHamnI!YD zy2=5S`cN5OeXKWm_LS8bqVyRq2<2!42ql>!9HQ}`)+v~<7?e(7`5gRT1Pw_C3fYeo zekZa*SUr2;toZ(=spfpLPw2fQD6CqbJ z!7D~Eo7u3_bv*QK*|w4#UB`vNC?_^G^j}+PX-u&$v{EF4mc4FwTUT41$g5qRR&it% z$$2d&n0MY;E?0xBryFgS74i%6K?dFGGJIphf23nDNI+Vxt0_vJQV6O!3b9nrKCL9D zH%tays^aPe5~_G8GXVM$8wG#NLa2N?IXT(r@O?jpZGL!o(3_8+Du>g3ERt>?c?Wbj zZ^XGV6B(Bput(jE+~7Ca>on`V@@p0uVfpm2oMn*lISSJ~G&B}TE`DL=u~}i9Pk^qT zHZXsv^M?246${<)AQ)4zN*j~j>A{P4csD#_jLLQDH95%uW zuYeV>AOFJwrm-j_CZR(U8QUjXBNpv8d_x;rb(^5-NRPV$R8atp{J&W{e6oW^{5Q!I z5&!?n{EMyOt=X-#@o{{88Hm8^RhH`Vc|<{p0ymwIqlmB994U{$KYD<$~4FXn3VA zCmtRi6ay?&0j4r|S=re!9-r^eDm2RCWA_C8UX}!5SCZz+HIZRsRYbUWY<3^=O|3jT z{V4Z{g}usw2VDgEofm&qCFK_N+e}`e2`R;Fel$LR#Z+Nau+NsY5a4h%8yCD8{<7TUg%33=V-_`f}_*msBVb$Z>EtK{|m zfk*3?6cXyxtv9REt(Q_)ua}I#-5HF+O4J%JRV~ObD4?XIG?vPP6Bq9b3=CYZHz)h% z@b~-3be=e)cJ<5oTD$-ID`cif-q_f<#yS{{ESpiACDrKWU}~e&ySb@}N8-T${n;>@ zn2%#d4_{h7nTgNyy3mS-$`#yTNk~X2qnyf?r{C%%7Hs*i;SCxeaz7PbYLhJZDUt<^ z*2%vc)EG5Nd(Q6 z2aq&0H9Z}GwxA~-%9D0Z-yMxOOMlrV?mI6nS( zu!q9&A~0rVxpbgOJdgDkWU#JZ3)4M!%!?{b^cAi1bi2i6$p99?NQzEr31BkV5ESGE2bY zlAM@dhXp-Ft4h!H42;9q?smrSyg!~V8KHt{;s~9dug}ovhfAsDY%#FS1*!map@?3YX4{JemF0QfO#T_Td0*?YEQ4lPOd11Ar+DKEQ&_6ZO1Q1l)T+a`Es;5qbp*Jobg4)q1=>x%L-A z>t;HaC5O!t+e@46O4E9$_YYuU9wmCEHprl8wV}Sg-iql6x}fRD{@Pj1m8yneA`yKw zF8(SR{+%ueC4r8r_a_v12jHW`FS&2(G?rIG8}6@X+oy+mwc}7bn8V-<`UcuutZb7f zu#W;>y}nCmP-=xgp^;jz)z#J~z}S@DF&@0JcXX$s{iw1z+LnR3_q#hMDO&Q8C@AYs z@HXH!+HX``_N48w&NPg?UJZ6<<&qKKD1nVmuz0jXJG4__^9z;x<)D%hJ!XpI8$~L_ zwhxRnY;0^*pOTZ4^C>@|TSCRJ_w#*KQc{w}-`?I&0kl*vFE6o5Ru#oG5>({mx&H5O zKL#VAYZpxerg{~+HV5LTX;dwo4kk&6h#2>2VQ_V0k*MX96?EaE0vKfLT(7nVKo3LX zu>qa-Yn~3r`-d*QgrvJkkvylCYLYUnW}aGl*1Wen}a%I)#8`GaXQQFv4rGBo6v+M?>Ssnq+1 zxyZrAp`i8Ok7pvQf>b&KZnVzBQ`?7rRHNZSob{&K+JFU_2$_TNG%Q4kAS%m0VY??M zjQhNrze{ID-d|u&5X%GN{a^32i$9nDOC=TZA_r5K1_X4y^*d5Z#biA_*HGcj%=CVh z8TbhGUfdWCW3P~^Dw#I@x$V_ht3L7YB#ZXsnSd7|%o=d_^5xXCR)~@9BSG)Kc3QnR z;*{3l^o8rEMrS?+RE_Msqa%!9c7-Js78G!LTyD~<7msK1Vco;tn)U^wq9gYkQt!|a zXqIdAfDnElhm&F=P!@^)fs<*rS$2YMtQZ&=G9ZIa@Z@B*$JKUCuvVo`0P*Jz`6LEv ze(N)Eqxd&jl&8O~L>xa67_hsLTB0lv88EO_4=%fWpL^{vyNEsbaTpT~TFvTPmI_s~ zpr?8|uhmj{AY>l;j_s=LQhSk$3;C9RP&3@Z^N3@Hrlj6q?dwP+K3g4}|A|voeRyGa z8$Iuoo+)RTPbMc7`T4LhEUMD&vm76*@!!ta38{!9ZUz?iJ6SmK{ZQb~j~rqgDfV~h zAE*%b$5&gOX%*9{=+3@Gc2RIvU5Bzz*aUu(fmT(dFxf_yu`Y>=zfpRV3Q>e{E7J@ zj`*JjP^?NvZQbWFFo)>Br9xvR71YDQqV-$vb}`v-{QOx=WMJX`)D@!MT>exn-S@g3SZ3y^ zZ_E>9#}-#;)Dlv3k(9@(!94-t@^e~CiX!OH@p#jXxze8=#Z0goDE4||K2e7ae>%iy zOa9)46lD2Wup|c^gKR-o7G}b=8A2XGWvR0vMLlJvYs@HqOhhv_Wmz2N z;{(>5#_JLifX^@n5IvcS^M?>-RIAEp>o;fqnKVZ(X}owx+;pcx64CfhbrO*F_@l+X zA$}M_n@yu;hMx048Hu72KkQCJ!CnDhD-T)PpK)~7_mSewuzK`g+>qEW{-GQ=PAavaCY?fyhRIDTYerb|Gh7t*QZI)sn|nfcxrkeOw6{^{aNh zkz19)JgVI8{D@_BSssPpZ8X4*|GNLR&=7gWQrXu0G!^)~Ft(%{^0lT-tIeE>g2K@W zu;V3pw~dLZof)m~NTW91&EM0@ld-=)rdrS(Z2WIt)qK_-sk!1LKGylXmQx_DfuVxe z*1sjLODclnNoz1&`DHsfCwkSJ@~9h==84d`Emgy1&X)kadtd*ji@w)lTR=5iUXmjY zEfD#KV$S9ROmqGLSybrTrEn0g=`GwmX9LGS!2?p~OE<6g0U7^|+2zqAk%_aa#x|xe zM`17-($dP(JO55vM4CE4+6o|FNnawY33K}$?aZ(x*R!1k|1#qbL!8Y)$@Vh6XDPLu zXhGdxDVAtQ10_T$cRn{=TcI$X^%=xz^E%`?Fy|Tj{;M!=Z}A%SHRsm`#fM5CFR)x2 z0?Q})aY$U@s*#19r1J#Yz=Ve=j)=X;?;h|(%o3X6`wL|vLYJoBKY6XC3olnHVw>lh zd?e|&;}Uicd1xdk_Qx?|*&;};;Dj6Xo%P7miFD;wbE*c&E_@1Bbx!#(R0hZbKMPer5Z)m_{=LoJmfmJJ%<;Nqbim0qrLR zghyAS-kg<<1CGV?xj}rP8h6*eNO{a#i=CoU*rBidZO3Sp)}h5(ZZiQ?I8z18$Nxs) z*?%;LXgdFs+_TjDWQ{EMF#=9%G^wQaF5-mc$QWFlxn3#0CESDPYel%JA~Ar}#}h1k zAC?1Nmq<)XEbP8GvX^9nsUmB-dhJ_uoL=Z{ZE)l=N{ikgSSYU)9_Lyma`^F!YOi+g z6bQ_dzKM|>7sNI;&ucX=}M8V`ef(j*Qdf3s z&H;>XK6~@g>QjOSutWVrDJ&L3mEwrf0zp0AmosC_fQycp&@ye|n1F0036~Cysa9TyYfaSau`G6Mn1szfPe2)t%`?@tIg_t&8tmMJGpV@-+~Vr z2B7SMg@idOLLP8*Vr9DBlZdmid^2uZt@~HY(ZRh%QuNoR?x}10P%@<}|yD$-w1WBUL|6u`V zUEkwsk4C(EYbZ+98l1$JC$J~zY;(AXc^uszGB!UW^rKF3t*9=`8bADvELWFsw{b40 zBU^BtEVGcsF!hdJix74Z*e^4D=_uH;oKJY`D(S|F698>*rnh!KTF_4N5r6D6zmG$> zB443HtFsmblI(f@;*GMu_#0S%9)3-IV+Ni$W&9)?`^(@xd)@yk=*PK@8V)%QNhBYK=m1 zm6%%YmAELncpgl;(PU1$32uK+HPxOeU+C2U89c6Hs5;Vux^c1DX)cyp0)vyTi;AR0 z;5L@!>Y8QwTY4~LwarvKW^7ki5rAJw4FEgwUJgP|sn%Bh#??>(Eh{)E(?tP_F3;IGqN4tMR6|9OEo!3_7y1h^QC^Xh{GUO!9XbpoR| z|HwG&?Wt1>Q#g)|lz{aJ0kjL8Jk!B)N-GZ5CnF`MKpP%1?a$rsXMjAr)>XAf{RJrj znnk=>w%;#*3OOOk+!`Y56`FEG42W|5a9Yay4eK+C@?|Yir$Y&mLXdHDN@-?T3bk}pM+$haP>bP);N+6{AWgmj?9Jd=3hHZ0Ml7K>cNYw{OpsM7xvz} z+Uvie4WlKaE4eZ#8B02ZVln-Ln*uVHb&sFvPW4OvANJlVs;(~D*8GEeaJP*IcXxLP z?k>S0Sa5fT;BLX4jeD@50fM``yVuHp@42U{wR*Xy?rl{M)mokiu-S91J=UCk^!^Qg zi}Kxk)u9@X)q5mwk{mT^e5-iLg<3sOCjVm0ac zzJzHva#*M-X0MYvgYlgTzOC6=kzoompr-Ln6cd8PlNS9+#Y()#zkILKQJz=rPio(! z)#sA%K33MbnNoEvCwNkW%+eF2^FB;Fngl6=?gBgoxkGq77~+()0~KxKL{d&Y!Bc92 zNiP~ChJ8YvPN4;+TJsE_g)HvqkS}VA#pyF;i6T0;|5okYDDGG0UsV_tfm3PAp@*)d?R|uD)|HIb$Bv5GFICjlylG+ca(!^W zdFn`aG_U5X8A43|Fc5)kHjL?0#&^Ts_PHoGD&JwB4`w~nEr-X zm($3Z@wcERGeHDK8DT)|Kpx?9G8U(jXJR)&Xu4nJID(RXPfI_X+6s41CWw>)~??wauULGVOC)_Nt1@ z0$iR#I5^&~9h9HmK5A6)WAIq$rp>oQIg=ybumtO~CfNO9a$ZV0<=Cpw3#Va6&}waI-kXd!BuX?tV+@R(*S zMouXa>EYCV3U^i%4$n&3v6&KN5Kv}le0c8lr2DAC{L*~!4XV$Pc?4Db=df@Ro`^#r z+v)T?x}c%DwANVS>c{?%fpZ60bdvKYYV&C1_U#jbHTrY*KU;VuVU}X(c5O5U-ii$u z{L?KP(hoG4(pB|{&Xg*S9?@<@#5-(31T@mqKR7tBUk$3XK8$8t<`nK>JrjpY4E|6R zWEi}szt^oO__DJUbms9jt@63TE#EuxUD35#7d1vcTuGcfUy!E~iRf#3ff*bgaC z`&CbkLlm%Ka|LDAF%}`m^xBg#l=?86$Ld_SVBuqtpiuX2NPOrUe&;_m2ULYcV9RefH1TZ_#?jb8q&3j9uoFcDq}7t zQQR!}$JeoNQwKaKSlRobY4U(N3NkKC@3{y7A{~U1;su92Uj`Z;M%4( z&GM`?K_FQlZVMyYOxp$l!joi>u~rkUG5H`_D4n6^G+kyG{qM1N4T_Z2NdF;Z$ce>! zFs3xGgh9=9E@ydBnsi5Q7)l0$uX@0?3-gth8T1mhjwb2LjygGEn!nguZxA)z7&nZQ z!~=koKZO24vyiazMDo=P;sM?~ZsC)Cwl*3~&(!e=q0 z$CHpSC?FFN*%8@Q*;2s((!QugJWnDfF&+^ny1lu5Wl3RGNkvuF_#zbi<7GrtR9s|4 z5Y`nZ^H|^5@GvRH56%fF8HBj-*w`3w0|yR}Rij($5_xLl4GldiPi)(?TacP!`9m)1 z>vmF~DK*e9DPGR!kfD5gN)}X_vsmifrHRKXS*QLmODFEygx{b3b zk~6$@UJ8Y=E%K#p0IKNsgCpyq{y{|GYk8#8v6meGe(l&=3>%6=Sxy=7fb*;=!6o>U zmOg5c{nwUuc-pV@mgG$dP&vATIoR1P6!CdZCatziy7*hEqKTQ!=UC&Ya~i1LjjfDR zj&zJ>`+n(UsHuqh%GWWhs%YliL<&@RrF7{wz(5Jo}O*4HZ74> zcKL=9&jh{cX*zifyZ`yr=X3DD1L-qhtBi8zA&c#d zre-3Or#{n$Pv}Cv1H0=bJKf&1VQ$j|+9W}3`8JyZUkDri2)O#OF=pvfF(_psDFd(- zj=p?OgnJbEY}2I6lq*c_r3+jY!HvzsRKBo~3-ATYm;VK@uyFe1qNNyK^JXTtyIj1! zX3MjJ*#(V!74X0SZwwzDr-0Lsix9m|Hv+mX=l6Um$&qCq4dK6j5xAXhrOb&}C(f`} zmd_80!C_MDwo{$o9-n{)KdLXv7s>=AG(z-@`9;^?;g=Al43p9G$FBzmhX)5WeqiiJ-pVR^oXPB)rx?Rgi`$UgpmQV2!{bA{g^qR+z|=f4 z8%CWBz;gC9E2khNuK=o4{{Ubjj3l0k(Y>$zws9d-w35(NiaXH;Aq?VA9 zDlwb{KqOVXH?H&=oy#>p0mr|sQC@B@a&N!@an*98^HL?{1H4!8E3e-aab{efKNS>1Pk7ksz9mE_*;xEhV-D%DGTN8zS(-f;N`(gm8M z)X4nZ;RMb`^PxBFQ@;T!N8TqSLcn2xW!CpGo7n>eec6o|RVlLNaAAQvtESv_36n;r zO6J($J+lFm$3$T3@knTgiNcY&?pfWsdGPV-_WFFui-yoTt4!!E10R!+3=HM^cC}oZ zh(%Dq*|>Rd*h(rMO&moMl+Sv4DqgjW z-X4Tu_39aUEDFmvYaKqhjf|0-;x{MHe6&oetxoGArjFPu_7FoPnZxRNFTdDu>K;a( z#~*$7x|Q_AiBvUY}JTjAO1#{ICsp&lm)1d3OR7L%>Pq962# z0k&0YMmfSA;F#^EQpoh%`V-=!s4O`l@#G^V=nYF}b=}nY;XJVa=1M(NK_S|YWSTnY zSd{*bh@X-881^H{wyC}ST(!C>J-{LJc{-sqsq?d>2XJ3XB{`3BbMiS&|Gx+k z&(mbQ%K;Gd|Dgp~R~=RN?Q7Lpj2dEKCUk8{=o@rju6k{JD~>dW8aUkySlBpenu~=# zN%;Ml*0ff#N~Bw)rRW~h?91C9wJ$tJ9a6{czg3t1K|x}Sc68}AR5c~ zJ;35a%3_yTkPXT|Kju7y=uEMOTc-4b#?biuhhtK*bBgbUDh=+*XULt_=fOS>b0wv_dkOj z*4MI=X1!1PTi1u=MNFQGroiQzqGX&@*hIQYO7jC{|0o^DCnn+iAj-;?!95y_HWSUmY#4&;?#-XAPPp;5tR9bUeT<(*}#1SrJZi~#n@C; zu^hI9=lIiUOOUza0AL_5Z%Ju)Gk%Yai2}mU(B_suxfq{9dBg!zO^!Zz_pF&<+LP=qVl(MDvwsr~fq^PI{zwE?B!2;cFnG%6od~tz{ zi}~MSTuL`bOW5-!FkBQ60#Bw|>(BGCz-^+V9Qhew3ovG_)cO1*Yy7~I`kl+bWjozD zg`DMW5=4z+-{EPYWZzC0&Lsc19;imZX*!|eoyw%U_4|yYD`!6LOn1H919H502}J+=T$e;)Qm)`2lZ2nj0C*5(q9vq7E19`EXD-8OB_- z^>r+v5MPU59D@x`qunA+m41%`#5_!OwF+gFkrQw;ZOw+{@a+3-+v^LuTy6ZQu)G)6 zP4L)i?7Qi4lMp!i)5XKckh?$6S)HR>pam*ZRA5jz&|L5J+hQg7Q^OY-@z^q6sm-}P zRi(P{+PRErNzKlFvSmI%e7fSJ^`~&)nrgc*jsMO4g+iT%m^b|V5|TiXWGxVe+ zp!DE-x=n5Hp~d8C7fh$!;h2iTFkSwE69AM@pbHB6Ufcp;7Mt>u7a$t~U0fD;o}zGE zn9%ywf<*8k)dim%+wJREoKGDy*R#(T!_QKz^&m7;)4~rv?Yi39F2{d##tvtz^aEZV z%hhN#yX4_T%4|&3Kg;6OJ9`cI=JU7lqHC_GTr%Y))_#hAD3%ISp~MuxcoiZV6)lKw zFcG`~GGaZS(we`x61Qi0wzXMd3Hlx4cTHUnD5%kBqVEx)+vm3N`*^wc{ore|3*|IL z8?V+LpPd33Zij+v9|rHMv`$tADgsUV1h>HiZo)bJoo@FJJADT;725~veia5_QP6J3 zX_-pZR}VdcmbRxml{6k@@57^VwS4*56Hed<-PzL614R$kH=j>JDog@cxj3Q6sfg59l4D&EeH0LKhv9QLJQR-FH6$d~J&mEE-|o?(klI5XvEKKK zmtu(p*0&GmYFy=og~(XW_un!SkSW1zmTr}lG}Nn@&KphP@GR7y@oa*IKr{}w@wG*( zT&gF&%C!aMgH@h=8aUUM@{co%zeMD9&5YhA($eBYjuXV5wRE+|^jns$LvXUzfvU)u zEmREH3(Bf#GQy@8F~9rBE4LYy4_xg`P*Ne?V(DvQLJzDRe!`{{!ZE1IQ!|()MN!iN zbE-#SZDM_TgD&sCXkdDHr0`qvpWan40oa$;F9yg)WeW z;ZT#P|AQ&2@s^a!&WNVVvMfmazW_v{iA3p0U>Ha+l}>`ZTWy9zPCmF2QvIomC0S${W-tM{|kazGH z8H6M!!Ve8lq109pU=EcVs;f~>Vkd|&(UOKg8Vi1gb#j)hg{cqk(i{NOe`O}7or|8K z6;z;wiRk){uZ}fS@32-!LSAKp!tW&RI8FOLPXbx2pCV7;uN+${Tds){4LvnxJ6rGp z6UsNHh$xV3OG8DT-mp_!ITrAAdF$WukP^mx{`rhdut0FQSxB`ROG#63o5S58jdU_k zwEa;L`l@11y9bn;$FG13iinL6(Sp4Ky+$rTccBHONWL1iL==7toTdp{IOTDq-!&+4 z4P?F7^ET`XN`|`c5)X;XpId)&5v#-m9$zE+ZC@c3zdc%yZ*6U{JjK>UBMBlx#^H-# zL&2fd_TyIN)n-oLXm8BM5wMx{edjsmJmYuSQOn_PMQ!N0-ErDyw@t4m(#;n1!h8Kt zID9w{$=hhf>a~U-jig5{viM;`OU75^i2%I|YUK?0pGZ1f@acjxoIOgDNh%#*AIT@g zpUfh{L~b9l@?Jt{qte6OK>eXX{9bPegzEDd3}`MtYl%epTSf+05mT$ghB0FQiS76z z&i+}_TR1&YB94$R$l&{sOg<4@9haRREXpB}L9RW&NIavXW|YMI;Tjd%m&)d1#DqjD zdd2J;7mJCD8JH8tnW_r&hZV)1LSoc6Ym>+mWT1~5FtBR!>k4^Nz>tX7lb3=*jW(zU zqp|^rJQ=;*v=c=A8!LN@CkvgtLUkdOxC(Ma%V0e946&a$__=D#e z*;3g^p1s6@L;i`ITO$Sgpwz30{-<#Mj~|0#_tebeFz<8Dr&sBQTmrnJ8?f$GZ(z$I zAdEx4WtvwL_D?r%i1|DR!1nNN)(sg1NbO>TY|W6K~4a7qhHYQ4CdDQ z=5Ur}n}hT&xb`#P`9JD4$~_`)5#o#n5*e%*g8-FW2<88ESB|wzV#*ImJ-rTLIFKwU zTs*W0@}EQsBBImMH15A5l`yJ{Ya=uuQYE^8!6qi3WP;-7KwOo8y2}Qg| zSZV&Zu#)n}zo0D*Hf<8yg$=;CK?E=o(N?%wNH6LF(u@AznKX z3LOJOtdGppbQ|~w=w<-QDGp`unWgJTVWGLTZQhS=ssyXQ66Mj)lK=Em|IaS7^6{%f zIRyn(=#@ir@QeHxE9--UFUMbO%-Iqa*X@6j7Y2#;RgJ~mx-{NCd<9ZADE+BPJqR8I zxE971W)w-ONx@R$QbU7Fiy4Rjp$f}kozzF4NKDLCU1n7a{iN^!_XrIn#OJm+UT9)M zPF4tg3#>1yP+)iHkH17KV(H%Yjf;M9uqdFJsT@2@_s9K(KAG6rM;kN#dwrs-4iC+i z(uhDi-LcixZt|5nY(^E7G~tb=-U_6_sFY7_OLa#ITooyK{nQj+J91IUK8Pq^*NF>u z{tXuW&#uN_Y0>puNYdLWAi3DXcpu_a7wG=8_iRP5rOrF7hV=(eL0;|tqD&U@Sv$P~ zFEbf-0#HsDr>|e8TJC@-4%a#N0$8j;N1d+YBjUUB)=KHYfs7w=Q(e9ABlIYje!Is< zSH_oh!;B1)*}ILphI?Xu-^0_w!YcJzf1hp7+1g~DsQJ~lXK7kCZ{awT5JZIF_;Xne zT^Ybwjcl!nhfr?xA6h^}T%3^C|zo&_Dj=~dIGWkm3NONdtZV+Hwc{|iU`Moe3FEv{)wD{hN_{q2WOcL>&uZMZ@ zU(#!~9gJ!^09=RlY6(a)(FV5@0a}_E9I3F5=_7oZb$mc0^}0HtgetcEMYg5XeBL(H z-_L2Q<~rG%WY2XLNj14$!o;Z8YGrH2?Pk_}!m06TS+!eZ_oPV!0whlCovW4D)Fg`F z>gozrYz~!F;_pLDE#>v@FASu_hi|?;k@1tE^OSo+^>^cn^`Q_7Bn>f2?KdeD<*t0k z)&QQyL=HvdL~^qkM92;M_-sVdyEkHCoyDhlM+W47 zvf7?ESdOB@qx)(Ki2nFJ2*vYIWN=h2*2@q%4FJjC$cVw)@@omYU~l(&y+pFYJRH>6 z5iD7bN>z>M8Z018;DzkLR3RN&P&vdC}j=kNz}@Ae&Jo0Rtu~A0}$busWMqem-+!4Ttq7VC-|9 z^SkUmWh>g@r_!loin4k3*@i0u_y>UNfO~>tDia}EkQ}02*rt9@B-rV5kJdkWzIG2d zE%e#99i|@9VIR&{?rF5gioMfKE-<8GGXt1s2y&Z$;rnYP)+O|jRcz@{F$g7~CYpOs zN>PH?aXHvnSZE(Wp~%;;>jj{h206OmVjx<9W)%2HzQk9~Zl^r6GIsOlvEl-16O2W7 zLIE8#lFS(DAWhKqe1CKy*USm$klVU}eZdHKdG+%6RW6w{1?ndP2@v>$5*@ymtXj11 z^oGbjv4a+cd-M-0F+3y0?wjuu`i}a)V6ui;8AVJcJ72p`x>;^Z3%3X{A^%rdTNNYa zTH*R&*GxBTTJ`q#_-=sIW5;_xB*A(T7Xk4I^IJBNycd-3k*yCKgUj@C@QvR$mY~PA z>nO>4gReta@6IAF!-? z<)tk$kg=A_?+$7OhtM-l=r`gY0#fY`lU}h^<{H4e!O--^!HqVdq~mn)d#N-J6NHY^ zlu8G6D}8$xJejw=AG+8`PTw)#UokuZeBqZ7RQ9&i~2Vh@U*m z_$FP4MR*6`=|z7!<|Urea|W;qb~$KPE~*rYJgZd4^uGXjlP!895;?UmzZ=faiIs8? zNjh!|c8?-3h=R6D7{i}kpU-{*%cPhIHoIv#RM{=l2=o#0uoByP+hVg?@@6TS?3vP% zx6+J#wS>7UnKbx%IdY4#3R|$GC;$W7fr##>us;m}_o=5woWK#)QRI$@eeVdoEQ-Ks zw;ZLgL#zC@lOCnzz58nMvctoDC^7Pj=?U4{1~p3$$CdpT93IP}`vuS@elR%Nf-Z%b1^KN~sI-NWM< zlTnSCd#7{xcKHF|Ld{pHOXv~#6iT!k4!mLG<2M1Vh9pa-$7kx!mb;5OHl^H7ZZF$R zcFN}Em}TS)SF9Sj%Gs{vp3xHbZG-Ge_5Y?S2O3n>l%$e}Av4l@YcOR`<=NkwQT~V8 zz4aJn4=!&<$b}@TcP;U4IlEromywqCF9ov8w+GXEcdM{EI+0v=7R_KcdZW1D*jSUk zcKdE5KG!>RUs|07_}9Co7{2?n_Cf&@W5<)7$4=PTp&>e|BH+mb%{y3NP9VoE3xN!Xwx4wEG3%MIWo7SgofN^^3mfgC+BRz<`QNJsuv#s`QcB*5pq|J>%`+83ZI zV_=ZaE&)&hHjgC;3c{;>pT{E(`_H8x6p|G$Cwts$6CKrM>g-lp;)BQqZI-lc~;sa#GIlId{vBbac+;)+MREQTUf-P23*>W37XGj7AF?3HBA`)uhO#f zS)ckRxrwv}%=O*T6z)c^n410D!sod{5`^6C>12WfFSpkET%oSlk#qq^3+fjR%tu5^ zCGn3U1=hP)z>%wOXoa4j688X&)hU2@vEBYY#XL|YsOgNKR2>%^+n`$!>@^>|WfaM? ziH4RrHzqa?1fFS{zX@!&y8#59-d8VM?e;voQOU9<63;*N+OHg=7B2#x%-BOpIWenN z%jK8g>t_c;0ljuf^G3_V5ru(BZZV(lRRYvB`z(?T313z_j7NB9%8TNo$Wbs6^ginl zrq-~O9$YxR+mB{jW|Nki|x*V7`Gp8gq8cZ$5J*s*b?QrSyf z-EPL+lh-x`nv)@+vaZ(FR-)ZcC~p{E>_F-q6XQCcikm9VKD*CqsokzMuR|d+veo(C z_;VcgWai7o9y~j|kPOySCvuO6h{;j^XB?%o4qsy-wUfQmXP`-e<4d)JzBU-L-0sCE z;`DiPsz(wP(|3s4;e1F!Z=u*IU1dNo`F=Bt$JXz7 z21`@xexhmsqC62wnPxy)@00HM8t;37OBaY9q22K!!A!4H%XF z{DFE*uP(|$!2RT>lM+H3lAJlnfpGm+1JAZ)vOTSR{8DW5z^Gmy-V%YZE4zgX+Po{H z`{0F<>|(n-HX?g@WlEzqZe7hxhtE|RGQid4z}98s}CK1SwFB-LPCPi&|6`n{`PxGam zrPb`YPqt~!6J#!RDgeo}wCi;{X`Wngvsw`e17uh|_!e5K7Y_Ncgo$rDsdI~nGS0EF zk3Pac&*rz$6kMV|+I+=339wCWdEF2$dkZ!-`H~kW4kQ)diN-ijU<`pAmlaQ_aj*in0*YpyV>+hIeCmtM;LHRW`)O&IPNN99X6kN!ncNbF_e(!2Or~`KCX_zo);Y8J3*gJA; ze^9AR=$iY%U}IbK?T1G^;x<-m6hqj?`~8@ZfJFVS-R&{IGyMhkAM!$qK&eWBP9q~fzeyw$S9%%^I zDi9cznZf42_l9=ZO;brD{jRdiswI;=vTHQ9)^@!ys4yU|8y>zbijGM&sjmkLoG!(j z?iryybO8XBn<@b%RMz6WsVQ3jXeNYQahHf&7u6*se5;E9b~@IRZ>G#+0)`#3oRXU) zc`aknNXW&61U7Pq7Kg7(Qu3r7#cdi!8~6+`BR}J1f(Q1;B{{r=jD& z_Qz(>S-Q=dEd7cNvN#$7W$Sz0=R}3KzC}>;h^ok5B}>!__Wh# zpB_1%;!CNnhvh_ekg<#`@dB5C{}9yTAmDN2@g5+W2sDf6iUM4g{a>+A^BgbxpQV76 z`jWq)7@C0k^4%IN26NLF5=lzLx!MxYhw>MfaQ^0J#DH5K^z7bTR|oXPOTRoz6ZqU1 z*FsANxQXC-qkbnl00jOoy02No15WLZhf7Zi?eS@>#uO0CABhEX3X$wKx~dM20)LlF zKxSER(@(=|gaHppcm&g4T|(qf2VZjQhU;Awx_|)HCKo3PRMnuXzF(pOAz4HMhMpoE@(MAd$&3ja*T1ioa@*-? zV8~+0>HUL~3dNpMH6H6J2l}sOGog1ERzgPS4Lfd95PA#=I6BsA13D9k1+Ay)m_jxm zchXC~#C<%O@06H%`fr-Hu+?0z&}xghl8Zc&i8b7UT(^d*j)xY}Hq4e5EhCKhkZ~u1 z5XL%B2ZLZ|i~+SEqHeRBI`=|1U13!VOa8Vv09@UUe}H1KePY_m>?FoRfk#=TQs8C-^whv z_P~i3+8mQJPE{g|Og*>z+iar~(Pg0I?rnx!Z!P9@xPAEL5))-m`<(=!x{e4NlC)`5 z%d)Z819uFvuFL(mM9kd2Y7q``JPD&w;X_SdD*&FF(t8iEy~Ft<%VVI_uvS~X4%GAV z9;Uw#wITQ8opWhjrg4vvMVA%(S@Gbw_+v%%12zjl2ev(q^;sqHV|To9alI5M^>gp< z$hY@_iS13!dJYnR4s!pqPzD${REU0^&Xs`=s!>P;KGh`I)cAIr8Ywa4X?W!CtQPo zpWP<6DW2d8`}JBaWrFCT&1%G4L`X_%6kB-?`pB`Mc8&L?2Gd{YA$6{hKAp75BN0=( zW*bjyZT27J-Gj%BzX1fle-&q`75BF>csR(P?$;mTvbapW<0kBiz>(Nag9k``beb#n zI@;PMVlz}R*nWZHZr1a9(aJrJ0P{;2cA>!>&!jOU1OMY{ZVx-bi|!g63g}N zLiN#QDOA-TBjznmc$(zrlf6Oa4ZG@7Dt5=xVUiU2PS`P2Gr}L``fpca!35JC=@@yT zwFV_G4j|E_La7@ms?bvuLcs_Y@Me%-GQv+h{w6=4)L4ekAVwi1l<+ur>5UF1LvFCh z>QP39PEE&}u%pxGvXQyTo=J{nhHCVdCut)%&e;dF$6nm$Nu=m>OokKhmmU}qiyra@ z_cA05hszb2i>qJ~=n1!H4hkxSoqf<};(Y?K3g8nSydA-A5<6qTh)uA!bwU&WarjF= zpgL#%r|L{X;zSqV?GLET*v6@BUgq=l0HQI>DR_fd5*PnZ#Z-x=R6yy4^8g?yujBv! zvhx4eW#x`2xJ#rd=>MKZQTIk>*6cZ6empZd3zpkYW=}LL3exNI+--+<3S1J|!(ujL- z(7J>(H$N3Z3U>q;jG@JY`9EHLGT)~Geu1a#64p2D2bi3sJQ!=4=~2|~mA$!WLNw8T zib$JV#~bpv0`Y-}ZM+zwnCjn_ffjB?@Sr%{zy8-{>`?2FdZ5#Rjx9-bUO1ab0nU+& zlna;AlKZPuhw^$(UDgHSUmV)~7rd6@KRORM$&v8*KLKDAcsV*}OX_FI7#mzXye{8U zE}tdVGWjm=)=-q=Pd_wkmOP&C#303jKBt@d_ep{C-z+x$sQLxP8Pcy^XviT-`eGWYngK~pZ( zw#(^Skk#wf8Ztq&z_44fjaTMe4ju(T!1YMBoMCEa2CF$d?nmh0?J+>d5{$(fO`*fb z#63CQj$>_iC+>87^IY?GQ-nTUB@v8@jl~9vMIu1u^bg4QP5J?j$7S=}yWTfY@tw%x zj3Jm;V|d(HOG-;yctWNn=J7tetAY(d;3?H0!|w7p?p>N~M>!EfjvAa`Y_F>W*^*eM zzL>D6sun&x^kWP$wY8;S&dOp*Cmvzv+dtUPwsm!OW`93?>?6R&?pFko?eKuAJTNfm z`Hf%5=jbaySgF=)QhCeda`;Hd9WogNt298^V*9|Tv9dTgcy*>92XJ7%gOh2sadja5 zkg3#13^$KwD>Qj%X`e1Ooj>`-#KxjEe|uZupx>(>4LGmL{MgdE8WW?CVLZTSc?Up` z%txE}J#XXzvEHj*Cs9=FCl13(i{&JIaKKWt1O4vv(<6zH8ybnbyTpE&&&|dgMj8*` zL*(VzkBg4>d|-C{%*>(QQTvIXo^@AgYN{@|A_ZK_-tKZqWk$ES0v}J|6qU-f-bY4X zW<5Ll{P5(kQtLi=gZ1Hq$gu6~j~r7GuST<9TMBfV_EHsqeA-M=LBv%mKcqN5SGfi+ z*FUnPHxkx4Qza#5b@}!>ROjS`9coc)A}YE@zCTw5D-lWI_ls+5^1=m zHMBE`(r^e z2tOHEcM+IO!x8UJ=ITDHwtg-ahsSyLc58MJ@;ts*l+FZbG~StMxa41p3af~4ammcd zWM`}O$tjA^1Vo3q$mFVu#3`l!RPK7-MK51&*G~b-7 zbGXkoDNO4Kqr00yB@&U?{U&DOn1g$r9p3!>nB-0|`07LV$6UU~#%QG^)wvA~K}T-7 zjpbZ6d$K~^|A>h}eo~F5j5w5xv92`ihMmQxNn@fo5I|yw4dWlqeVFWni1l#Zsr9{+ zM~h%mX08Ez<1!kBt`2+~bTzY;?(e75%> zozU`&F{l|u;z$XDU|d~k@{}X7Mw>xqvHe>TnTZnZ*L&mI1>*T;cJU@M4?xop+j01Q z?{+z9h{^bSmE?FNgU*};-caBpX-J8pUTkcn{c<(h;O*ZVK^)N0n}v9nE5j>*_AAMP z*SiWqs`dXeAze8!_;~)D7pF3EvQSD1ctQ6Npfmd4`+vjJIIB%x<`5^QjyM_&Iz1bl zheRA4a)E|g^rLfLQ&Rz+)=G=ik1qC+K=5&Q-SpBYS__0B^o8|0LRkOp| z{M;Pv!S`;9@ev|EurxJ^?Q)yn%#YO?gRZ7J@K;v`Hb>=;&dzL?B{L~(Ih3Iz0W;_}In6~EOE2tCZr>gu zbKY!p4gFw11UEL4MnS^9gn%!O@9ba|vpayt+D@-~d{J6j3x|!Ru2y>7tMgO#^2cU7 zf#1!3Tw;(uUxxZ5lIS#Oqi$jd-1%H_F9g|7j%G6zGX6NVdmD0wy4h zr6{oY=;}N=tas_we<4EmizAtF$+0T3%bdKloo_1XIL2G!|L4Eo&W!r~(!KmqZB z#YPmt7Te)*s#)hf^DAjjM7gq(e&$!V)2qFBut~j)(0X$ecI9g8YhFZzXnBsHPsDk< zI~E%&hrQl1SY}phI9qyc<;y?Mmwh`Is-iu_>WWR7Zcn@HuGA=SZtjT&C2^+J}NVD)Q z>l%hEr(OTNSqJ!0K$_-igOA((90FoMyeAAweB}DEqBrPG5jgg)wtdd+BC4ulc)rDB z(BUOZuJ~T1XAaI>u1aT1>05nvzk1nYI66K$D#~y$E=!Zr6cgK?TQw~J7e^L@Lz?Fa z-kW9E6kxg#(f@rBEg8+4H3T^2;a;G2URD(r+BxJtKVGM9RVH=6ER{KJ^Fk9|l^sp3 zw#VhrWVe6al|{juCWuH|&}y-=+6DUM$`fWht|Jg;q%mVNB}`E%shyofT}nCpB)Fw% zoo>%}LH~AIVd>ySl^4MwjSq6UiWU}&Ul(^#aZ2RV;~pk@A*mS{#@Bsn4H>hXgRVm^ zFp#o_h$o>W{*=|{=Zok(K19D1zTa3yHQBCty)5vwukhsX-vtl0>I=aYmg%=!>`%6W zAa-@~KWWs}GGqMrccqXy>snP*YZ8g+^t2w`4TF3{Ndqwp9g6ZQp{x6Rl0FJY`^w?= z+ky78WojQZ3-SHKuj}J^dtEIZm*X|Jl?UU)ouHh~rO9-@e79`cjEs!6HNg-BoJ!5^ zw(1;4U(vmV?yw$IG2U*mHICzb;XhEK;Yh>Ni}nLjl(Q z?mvF^f6uo99*Ubrmx3*mzh(&t5&yj0h|vGg0_gwUj;0?Hgo%eD0)`a|ZZg7p(o$e9 z6(&9w2ncN@#+TNff0DUdtnWtfCP+mE2J-lNnrv@(1VNmP*Z&P}QKTQ>?Xive&ODa^ z&yT~_&D;K7{*s95{5+VW*cKk`z1Zm3uB$Dy?G<1{o%c*9PRjYiUxHCYfW41=HaYPj z_yP6m z31CV=s!B>+ar&{6t`*7jdt@oyPS3rE*Y->XosztUIeOr7byPpk-BUKVEB-PaYN=br!1wWpxUEvTtB)*3hD0CKPtw6f3(P6gM z>Gde+E$!=bPWyL5V5SN!mfZfBaf8$Hn-uXRNX82#OW3!BGv@e@qeP!z?&=;9Ea2MV z@fQB*l)Tbf|2G|2o*y1X-o-H1VBQRtE&1?k4k!na=NNL+a~jh5)zz`zuLt)}S7GCr z^tu9EfMI9o=;%h2Kvzw@LQjKUxk1*0L18=$D5JL*o~P}m=bydLR_=ja11ot&RZ)2O zF!J)9VW%&bpx|1uk?*JX-sC85Bdt6Hj-2twlAh&f;8l3FACuwC&DjT(3qQ~&EfQOs&ZIxqVgqJn&^mVA{E z8yzX=^G0h17bO`QX_cR6h)U(;3sCyV$y^)3XwW#C2_`ZVv5#zP{#V6Ox96)Oq`||9 zl_?a_;Ii1j51*a#nBb`OyWG5(HFKb{(fZ~L5NL(I+E36h zQwxtLi93JK(7CMp$NTvBaIQw(126)$qhuZYE;nwF1e40>x|4Ky+=E2rCiy#+D>cB8 zRec$?FKB<)y|^a0b1y^@8R4aST92DueG7WcAS&q1rh?MW{J$APiDn$C;9<^ z=u%sdrBLi;X@*Y2gX%^9x0*n_-|s0C8o9mRMqVgwNcg>N&CCG#E&;mXeQIVF3+^%h z(Lq<{|K#^@>>nBeSe$Qt#Wo_nptTwwG0}C^xZ%kjzhzlomzzd*zMhYv>&yOt;X?X_ z%}wk4?39D!&?G50u(Ip-WL7)t!~Ny#QIjjJL7~F_+p;^6_+G6Ll|?htOsVm`b^P_dq6LZM!kvH{m`V2+ktBBw_Ctcg7oOq2Mp`;i+wk2rB%?EojaPc z3Hkr>;vHCqqb7fWN#SPi<3%YGT#*Rfp70$g)gjSN9x9&!W|Twr(0Gzi z;P?-u{QgbU{dbRnuUi$6_-s1+!^FtQ*zJ=O91Inn0SpF>W3&TsyLrXMArL^;mk4oz zJijo@*y=5jBdLTzxIh|2J(+6okwk#U=j>|Dj?UID@kiFprO$G~YK>!fJPI;$kUW?1y7uLRF5Sm($$>CoYv^>JjJR*71JLzwU=|AkTQI-RUCvH&@s9I~MRDM0gt8 znWtMn1D=zs`CvS0Os1o&rfifZ%=ZUXovG2~q5kUksIg3Fk?_0(9 z-`^ROt7fLBUv}~pVBM+%v5n9?Z~oH~Ko3m9gAgEz0J{HVn26(jpdP%0^e-wz`on|DxFHZia~&% zo$^V24D9`hes9e9SvR-3wh0&qz<`ZPc?e{y9wscTJKTPv&_HbQX}P?+46X`x^2WZs zHXo_eVX8E-QHEq;J+|Kw2h4LiOdSC!?_yzalIdGPNH%ncPl>bvrpj|eCyqg^5$AZfy7gVF3OEHU#)(HBkLqM0mjVp&L0#`$ssC2f0+X2S{ zzXE|x1(%>N+a9gns8f;!lYZ-E^8K;MYrB}Umz!OtuK=DE66oEvUNMpIGMCxWGIWFs5Y6sSsg0v$r=EOm7NK-1XFEZjkh zM49G`vbeYzctoZ_qI$Uzas9)G0IBakfw6H|=v`SrT!u~C9*E0;+*n}W3IVs1p&IRML*#^-p1gQXgPN(mujaC59f={MbH=u4IT<-QXMkgF*lM~qC69fDlu;@+_wn8j zan*hW4eLmkD-<<7shAuX0j0hOG`d2Qn2A3Y<|&SkjN{LvVWxdgs&UbvkN9b!woHy>-T(xN?8_e<|H>TP~3zD zwGI9Qt;QdZl{8R69OvHsI9cQ<*maiuBaIbkb?*|qq3fG`#*?# z>!3K_Fk3JQ34suTySrPk;6Z|0a3@IchTsmt-Q5W;!QF!gcZcBa(75fJ-|SS)t)1PG zn!ER3s*9Gd`+J{ro+AToOGcD82&xkCFibXQ*UPVj#CtNyzfxjjO2?D&g?xnTgNw}> zd|3fzf-Km3Ppu*>^yOTiA zjGbMzbQt0!bcXzY0GgS#JjuiXY$pGB7$2Dd|8Ejc-rp@ioDA*c#p~l5D$>Ji33X+K zevfzoKY|*G6-+1nU}&h}nN9Rb;Lgsh8jq$eco$V`hj=+<#Ret?rL={3Qr_<91j2lz z8^*niP0mWv79xh#nS^E%sB2=tx{VGVKLJDIgoU4;SfE0!&LHu|ohax!>aS1a=TI2S zAc#8#SgnGcFHIV+ip=+ZW^8IIJV@Cb)}rR+t0;%ivcJX<5nWXtm6lzjDb!d1D#NeP zgvg2E%=qJf|M$!p>bFQWkDX8O5!csDt4T3W*pJ)Q-mlIcxSAspZFjC4N}ApQ=;7G= z$3S29f5|;Loen1aS1v$pa%!y4(pKS_kffNaNCptwJd>M zta4?Zc}#nwjh`Ph;wrGw@f!is>mAW~3G2VnmzG^*o@5r+Kdjz-G`%FIz}NX2O080# znW$51w9s8#*99GYT!LO)Jf_u1Yq4>%+Lw<^bDcR}-z|bD0wA1!&o(OdPUJ7R1J(l-%q=MutD4%% zotdhZYDOppCFSL9$sJzZVZae|XOi@5S~4xuvp?=DBAdavfZ>g9XIf9h)PUU19%o{ z{{1Zm(^}|DbgC)tPb(owUs<`_)_51$rlzcx9eW*PVA&PY7-1 zKRZ3|b<}A}Jv{{lvL!87Cl%niY%1p^gTuq;07lBJe!nvFYfkV5!3PqO=e4M31GJxL z-3O&*P9FH_d8fF$2d{l!Cd$%HAI>%$tCg5x8P<{M&b*RlcUGqryVWy9-%>qww_0A(Ax9$K z=`lbNPa7i`#3C*?A*Dy!9K;EK8KohK`QWlg+S<2a8(a_bF(qP>?Mt!a%m+_P8CVE8_&?IvKHYRsrja?X|K%iXbveWvzi( z4JyP&zg8qrSsv0Qe3c*m&bfO~^$$N@9g)+<>EM11Q)o7KKS|qi@8d|r7Y~tXzVy~# zSs{uZ;C4p=;)hWGR#wKp@6jr9`T-+00{XXpPzdh6VbH9Skypd5E#ry%OXDmM6HW?>{#NVi2-T74&H0mCC=jkV|Mf z5O#dSLv=+;>(5}SYi-p(OrvFk>^=|YP^$eXXh zz(d9)_`elx8!in<0RCl*QOh16ssYt9A8(=5H(O=O*$NptY0@&Gz~}Kf8bFHc!tH8x zshq#LKx^l}A9jlNTmT9?+HlERFXPbQzj|S@PA3wbQ9w?Q!pXx}(4W%*}1omDp#CRRT!V4VYyJ_jd-KOQak37pOd( zOod86{-#HfT$jndmM?P{pEL!N8>V%NPj_C>@ho8{fAbc=!MyvzjUz_Q5?Ny<28sqh^!rmTk0c_r9}QFgKGzP6oeVNz_4Q7F-|I(YVuXKm8{FLUpINK{ zk5BDIyt8NW&*-#kX5QVU0C;7IuCA_K6Hft&_v|buNN@jM>mX10#KNG~eC2W97rgD zBlHUFY{bL{CTBm&c*>AYkb|K6$pASkwEwR2=*RTkvXX?j^xMs4OZc0l(ecUAu`zIq z>o+2;YFqLb6MgOHtC@tiziYC8x=HSP4>D<}y#6&uPMng73jY5!L#~4S|B)dlittxo zL*nt$6Hx{QylcKlZ^!o4pdd59=&9(O(W|IHqJIpv^NZM>TK`-hY|V*@zG@a8q2Hba z+S-SSYBff`RHWpQO?$7C|NeHM_B94mDV8e#LoD~ylYEo?)!1CfjE+kSJVM0p3?|3J zJ-}SjpY<;oA8a@);DEWrGvdH=W5aKV=bf2}$^G5cDE?eYRNK? zdQ&`Nq*|3JXP4!b7h0Qx6%cp5Px%=_(E{~A!@xLP+lVY8d|o!wdNOd*V7n~bZ!uQS z(aH%Ch}@(7cGRW3wic~3hKh%G_v>L7SQ1yUg~Ym~)kMo{-^^}X+f-j6!TBOmI3s6HU^3{Ltief+Yl#arvddSkJuBVpi`2R-i&glO3Pv zjSUU8Qh*AgU$umKNf(G{b4y9a29t@^N5DCiM`R*=>j$A>#cHJ@=b|<5>q&bWa3@Pq zvC(ag&Mu%*`cAT{s#w-LjqG%wy_MTei^MsS)eTs6^?x1h^dX36(~3m-maXj+hFmkQ ztpRaC>vKRC0fbp=HT7+2s|7gW=rxN1_uvu&v87OB$tngOOyO3Aw$bhZidToQ3|7C|3ow`Ge9i>89P z%9`DoPp*EivH!@5ml;k^bT5t5l!8`)n7ZM`$0+hNc&Nh697NbjftC7c$ z|HfHcT>G9zt1z1X<+&@1Bt=$PK0@c4b$z^ABB!&1+@PS(z+1Z}htVJZogBEc%M??3 zOluTtG}IhGTgvI!2PZ)p-czM#^EQZx|cha1(mpKpi=TrTAj(oMatFL zR^L>nPS~=?VODOglj9-a)q(e#%l0w2ciouFW>%$CEpM4A&31E;Q5o-q(d5vdV8-%K zgX;(%GqqE9mT4GX&Y4F&@TT8{%m5<>_lh<#?e3HL45(@C&JYbtYc%S7H`PI~z>&fZ zvFMi^HyeyvH*S35CjIIRlYC#+dOP_N}A*x8EIeXqxO+ z#6~*xZUjx2D`N)L4O+XXGI&##3$z!GMa`$DDO`>>4I!%5qh>P&ymnu#OtTW~9C&d| z)4c8W>KqI4aWLX4i&_>`Vwp6Bh&K@WxFuYUZi*!K)7L`uz5ZGeQ(L~-Z|6~f6jb?Q z2kqCs0d#*%5!D;)x7$Iz{7hLY8Wz?}p6%1$JV$ds-&V&fr^e%zATrmPt-&8oO#Q%O z_*Z;Rn*sR++@mUG%Zzzf2LcWovvUmln19o@Lcp#?2v$6w#k3^4os(`zx6)`YwEOfl zW01f6X*5XJ1CN3s{e%1SjBTc7QN-f}i;JDaL|{T}yZWWAr3JG2fPe4Zu{KqaC^t{3 zq(=Tq)kS`A?$=}il<0SWFS~(&vwU8d47) zUeOv|-OBZm+L99-21$6Mud8cntegCe5D#V^Zv9}gHqWL7R={ql2xpZ z-_xmm=G>)-GP*ZrTfZ)q&9duZfA;`Z{9n0%UTwNq|HE=OfPGZ0jdDQBmA?IHOi@s* ztij$)A!A9%NQ$u~sCw@x8%mj^`}{L9F-RM2zx`b>7jqPdthhzIwLPnTRlqT~)gMO_ z1z>5EknE@*$j!?f`mNPssoC!jS*jrF1zrNr@+f6sFX@!|#+&ztV?{sb~^@$g=6#ZPPM_Xn{nF>&*&It($I_>YC7^+Od#lg+FpHlgn zXH{oj7bn*9ya)H)OgCL{9}4JJo+;Ns97zbCLj+8GAO!;L)lu9`3e@rb6iv=)LJjyu zU=gU(6eDFHP{DpsD}Ql+H>Nkoeh2P`UY%9~6%JJ{rI7heqn$;N4wb`OK^Auhg*x;y z(>8S0508ANn2l(bD`9(6U8FDQyvGxq&-C;c0KjQ;+vPL-SY}AqQ7=Dfm1rmmHXtGJ zAOKEWLCBjl5DghQ@E91>*KPMNePqnH;CG{cvY$WW#q1es5QD4p#LMCSJ&Z z6jdhF6P#Dwb~Z*Zw+>BDquDY8qH1rIOX=XfD&9Z$ptb!%>&Vi3;Av2Z)If&bLrDm0V=3KRI5{;;2#6P)Mj!waDNLl(X#H{?o-a#S9kYMo*yG${lO$9 z*8h#~Xf?|-cQ_!P0R|m4I!+)7XVW6U#H6I`f(4-by5cD&9M^mtr}R z9(ddw4?Tfj&^@;;KP{@_E~%om)jh}F@_AAQJ-M3*`FR?m(Bm$jyjh;FFGLZcqz?oM z;!ohS7C;SjW6}V)_|)^=&ChH}@mmm(&_1*a7P{D2kx-W`oXv(7J6DAdvzkw%HO2Airc+eo-9gzKC2QI^_m z^3DAeW;60Hi9xm`0-o{JV>aAR{fcOtS=ZhpVX!`Xj%9iYZHv){UYMz3pr2;LoZybq zb)6Ksw=Oa}D+O$zFchf|DFd|)J-u6ZGQ-Zcz68`38zE4*eGjD$PHqFdWmNQbEFaWQ z2<=?awCW#R^>4$TgJR2ljzgg=;f1{2w@+UqN3ZlCP0(Iyevt80yp8L58#n=-le&F} z>+>zz4l0|`5^BQPf6U{AAA&KE(Ba6<6V5zw@;T=@$#C{U3h7(>|!>=v+=*XDyhX8{htcH-^ zCF^zq7|YFUAH-aP$onCBMJa$61(W5^_Y1 zb@Mxr3L9@v8Ndj~jwj}OBABWonH6oqvG$?ZxMLLN56FJN67{b60a zUH+-nGebkcd0_moIKQZ-s;a50s;Q|7%sBTuU)(@geOJUvSv$XiZiMe(G|C)j9nEynavJ((6C>p@9Kd=W$gTx!S&qV*dV5$GYXZQc{P(WF&Y@&e| z_d9=MSdYYwAyp$9nUrj&{{OHZ_20Z?Lvjh=@asQTK*{(tFb#OD3{;39pKMygY|}EF z>DcTnH6X>078^9!AfuT&h%!S&({Ij^oa)@B@&JT!a&7~B)Nm4OlaKqK#+u@(VnuBr z#{_5(V^31yeMd(}#>)A@tDGX!>_%H7X=D!((8iilx9?~5w?*}&jhHe z`=Oyqc-?_zv^?D=Ycc7&yVoD-Wz!qva}^pu+)Yr@j~{w+=_RKZt~~3@6-9LEE#Gpr zXFN=R5Du7(-FVY^ms_sne>D-aoUc)EnoLAJ;DKQ{hzlgQ>a>~WEA@pW=v=2ZeY-em zMVwZNSKwDN+D;cH>y_>h?8$0P*Ga()`y|2be(OyxF`HT-)?mAtLx{rOw{gO{m_*Qo zWI0!%s`XR8G&b?O7xCo{ElBlNWJu&IR2iaGYX-u{ag6_JWlEY$;#By|M_huWxGrp>m1B z53!lr0>MG8Rx>hv&9J>0i(=?{KpwXKW?yiHs1!co;qP`2OmdF+ZGd=M6vz2>}DD4lfXdKS7b&F{X^!8d^ z-fxQYIzh45ya_P~QGz}ZXfLfqBJ=URUhGr0+R`1X1=Z2K?w4yPV~Rk4y7N>#ZD~4D zbQ-zr0!%jG8&Ml3_2nz^nANDswWRp$W`Bk2otZGq1F+&HUo5m^32#+lmHjLcn3KG# z9m`ZWApvd56AFG@i9hh69ht3||KeX1=)a*|ex$Nu|IzIQ( zc10AeH=JG3O=kN^205jh_vhA=Zhxa$=e!M6GI|*J_*?(V1^8IZ)n4sXup(^9svNf9 z^mccDo+MjQ8WoHs$EF-5BS+4%aj-$AprK~|FxMDI7mtBPP4*QuBTy6?QHimjphK-c znJjvdQ5`QfJoRidz)FzCMkD?S@S`Yh)@w=byM%MZ6_3vRhRP%q{ihYN-a~QKrbFJ3 zg#sDeXnEHh9&QQ7gc`oxB$G>wv9R#BdYG03K7MBmlTD`wO)2f0y8?!9H$=tpoNVFX zNxmbx3-%Je*I!(GMQ1Gg&?Iu&p*zDNxXaw}vh#ICTpQKn@goe9Z(VO_n# zl6go(h@82w5oMl&MzBs&N{U31i)p|@URZR&kE&OrJt*t(@7&th%gE>cRTzbQ2 z%1LN6%30JF5?vAD>AZI%%Ve_YvS;(j97S}OY%7%18 zu+2dB09WPuq|V9XGC% zv|W+NoI<}@WO!vWrq4gvLlj>%*6Lk&YalNCz=3<_+zLhYQ70`I%Yinb!-o5Y>(B;g zCsl|s+AHE=PEJbOE`e%!)QbY63&}K|YI?<@Yr3+TFii)knsT6To^OSm!^arEx^C-? zT$cDsEFmV=B>0g0g2XJQZxw%MZ3reEW-{q=H9Aa-qa93&mtsg zKAYKT-_hQ|D_2oqNF@t^M3f$0TI%}gd)s_L(EfaVR{KdrbgAV^oc(ot;18Yg*=FpA znrr6U%iFLBrGuU!9`CpHwjCFXIm)Ra;DWJZ5n3U9S$lUvr|aQw{@KL8C^&S=b<3EQ0W^ z1@W7;gT)xzMfr~L%=`C}E@#xdy!ieR;E>_8Tw1Dx)R|FW$Lx)kc=}c5A|HIj=RDCq zk;+AF@9j%px}=-O#KDE>V1sTHhUkCdjH^=p9|B?*6yKt29s`+fy;TrYJqgv;c?Jn zy>0DV*0(;!Ao?u$!FjO0a4ifvqm#Bhm?-}{H&YFkQKxV16D)LJJy-I^uITnaM7C&qe8`z&qIocC+8VS09LlPbgNmh=10aol1iSao^*iUmkpq z*nfyRQ8Xl1njlN%1==Z;Kz#XAb~Z@A(R96WR?I7M@FN-Tdr{(z0n_m!9@saLvn}>t zPxbv?3cZK?6=ZG(m&k^F3LK399zrgVF8Yv?*G+5`3gqez;Ojg_o__K6> zg(Uo0%PuEH+@F#*ua1rUn`PYk3=PfTE&bl!9w6eDOYJ8(81SBcF}v~@CEL*3AvdGxrr&c3EV~iMGOTE$>%_+QOTUsPw(*- z7rq6cq1LRuVn8Gj)MV9(>4%a9BYs~AnKGJEy#I0o69v!Rv4V0FzB1p5K^;l- z%08Ezqe;@pV@qLPJGCXsym>t~S-F z`F4eDRm^ZYQxa7CAx{XLSW1SfecN5*%fQXG<(f}QYq_ADdrWUzXN7c@)L(bmFxCc? zHEY!G>-2ca^wc%sN~mO|$HkTgZ4lwteA#Yc<qPxY^ni>8U3n<%X2x z`neEaeI<5c_s-*%8yqChu3{odQTy1Rq(c1ZBolNqK)+&)h~D|-X@ zh){E$%biO_IlW>~8~rvUP^Nezimq%_HH2F&bXNm+JZ7nbIiaS)D?ProRAm{{Zww-D zG`Tjgqdn|AWUGnCv~c(BB=vlJZ-R4Cq&2>lQUp;*o;gBYRw^4*_a1Xy;kQ|GUmD)_ zXudiagsq`**exANq)_duAx2Jn9t=y;nn zd+o$_4EfUaOMP3oL;roNBWcWxj&AEQ$-I%d9`#qsg(1u-{7C1$9&@*4mjj}E{yYyq zUJaUb`SiL6%l1Vhmw63PA}XX9WdN}}>7c5%-gNt#3SsJnCIDCi395B5d?;VPWIo5~j54_8|qiL`dfG4L;Xgy3!T_ zC7e_b8am=w6~W&lsRPHdP?X2uHI-^I+JGJ0F4aluZAhq3_o_*P4Ac=f>_gxJlgrO~ zmxbh4J(tu~7hMyl#idigk9uXecw01o%hCCZXKY`R=^1b z4zYjb55-}&f6v&QjEx#@krCyBOe9l4Uy^2-9%-7=8^sCQ%OVKcfL+l#T;~aNXy(B< z)#r?(Fcv8b77bRQy_#kWLiZM@V(wb!%JI+;4>2r|fbGuhQ7iA`2I=ID~?@bmQW{&Ev)Xkrz zv4?u>hDCZTSU1lR{`1tdw6w2Y?pLW#b7?eF4_qh6YHLmJ~u*$NmA7m}3 zm-J7Is?u0S&i=yVAw>$K#O!Za zzb{)FezbIDV{BRAyfYJwi2eCu5xQ9EbIV6uZezccmCVZ%)s_#5Gr5*pcXegF+g#jD zWD9-G@~i73yfE#<$kvzahnm2LG!DyYHKQ%F3;R=J{mnd0wV zoM^e&##%krjy6k1cRA^g@$PSw-h`2Em1T<4VVC8dI`@gtdXwMEl0A zuHW(IaLH?1e?s?W>w^m^3uom)Nwu6|`^Ga}M?7m7a+Dr^b~lGB!hMouWN>)oIsc|^Ib$0Cwy9{XGr=IXPn|f+_c)?mV4|5n{TM~<%nCVvD=13cbK51AF z=ysN6y$taV%+GRCQmVlSlL@e8PR#c<)m4* z2P1dxdgACjdc*gLlP5l{3XA@DI-K~F(N#Y^DjtxC4;f*(}9 zsve0@Up!$;z+byv-f9!!sTo$?#BXKay>aT?^Q}CaHWg<3Quts}!uNK);+SMD0%o>vPt2nd6u(^% zRW*H)L?{z}`-X6Td2cD-T&dlQD!@5=4GkkE_yNG{6kUaf%Yv;n48O2b+GNh*<)J>_ z%($hsU4qK<;0n});znG^P=@wJ5wFb0G&~d^3C4$yHNla!!+4k4O;I*jiZMRk+7(+D zg#-sBLtE}HA1JcFgdWwst`fcevc<^4=Xn?P(!cyXUx zeC)Jx$0jonRWSGxtE)zOuYLW*NRt4c>Q=(1pZ1uRl-6@~`qL)nn&esR21_}{-YDAf zkuaA1u`yZlT=A>jB6;kDv&d&*-}P$9$skO{TA3Q(K`4_r9$D!e=jUC7PNbrgG8wmq zU413HB4bv%*lkjS(ehXa!XKTC%n`V+g(DIS^|dsH!xbREBEL;dOBJkm@KWXY$5lQN zsJ=e0`N2ZPl&`NfSC&11fHn^wt)i!|L@S^DW%QSfl1h8Fu)KRTPFxapRn;Hy$qtaP zC2!d^hBt+Ff6Nkr8>10O9=f{O^YumkmqJ3NoyV(!(}J|*R|*n5%k8bGQzZ9o*6}5$ zg*B|PCW?JIKby0fe=hni_vJm&7)(~xP|4``Hlq}6p4YFobx;4Z;r^7(cw)PeQC>=2fE7a6FUeem)vYyNyN@HkYX7WV=8tI4dtNJb42e{0 z*0b*~u&OoFY?<8$(5ZwhsBu<6?Hut0%rawq2ug!pU5^SS+6524T>znnT&vbZo8#|w zH2-xob@jO(flICMAgSh}*{k^qrX&seruUcLG+kgzlS-VhA%O zJeT?pv8SD*y@H)BegkEAj$naf)xL$e>g|ET7H#&-nZJou{zrLETGsdEiQ5g3%OXKpy8PHkcRv9KEjgDnlLOZgQ@>94$ja6!1mBHSoXcWoBS%d!|f9CuQq*uVX>dMo&LE$K@Cj zQk>rQt7rbrK$G*UDS_&GubAwXk0J`n+fhnt)mOi)W4#(*)rnDvw-Fw8WUV~}$dUSg zQ-qL8Xo*)CItXPcM)#zAdY5r&fqFE_* zF&>ZZV$isH&7eMNq#)&!cZY7wy0v@q-1p2 zRt!Z{9Dh$gG&M4qNR1q2D88Q^?Q?haQH+Ln&BR3%lUByoSf>5u+*Cc@Z?c@e3As?D zUG&UlY>8^BH4}XWvzcKpE2d;)z0yP5)gviPe!P`q`@`FzS#$Wb`MWmWCy7BQLZk3E zMi*0+FPg_2u}~N>QWjc^qiJbkQW};Wi@Lh#_Y3trZ$w0{w1ecV?Q2mU89jdZ{`>dB z|Ku%m59$OGN*I^QO#^0Yt7;sqRyj=XPx{uy0t37)ptQ8K^8s&V#tD><4k?)U&nM9z zWKQAh8li*?wVO8Twwwu<&pi-y6F0ZUp@tg`QD{bcb!^IoYuOQSB4J7`UjC)E}x_e(;@P!1dDh@9OFaOS+fdcWB{uAbRW=uv%_OsdL(`lwA^Y zdVQI8I@pm&Hv>gVOOAhprp|mzh=1f0lS{7QxzDWEX`}P)?lQHlD3;|D)u)={YN)^H z8CpQg8*WF1ysa$X+_&-|-x+SGysw&q@fSE+U1%AJ>{D|-bm{OJ!Lr7z-F}Aab9;3* zMnLH%w$s{nKLlDr#y%7&@OPB=Q7#e+A0C}yybQSQ&XI^lBP@iU-COE>4?-Cn;U-!nBB~5B$Fiz?Hn9F z?yXiDO`WyFxa>Omp`i7|t(CSut=4sPWML4sSo5u7>dP+XDat?dkhSK$xF4{xLRtzb zZsiB*YGvBtt=#T=*RM0^MIpbn*c$CDJ=qzbryS1K95>_>dG0XfH%mXIkhs`Q$}tsI zS3`fF7GUVQ1vn@g_i~i*jh#SE!u6z}bAjcM{aVO%ex{Ufc5ikhSxgTiTJ=({EATKb z=R>}{^u=xP$f&KIz7z7CtJu}OysWJc=G8dcYqq6w2*cxhsT%d7uhCY{#gc0kz9$2fq>W*@b$KYb7Ap5 zx(M2QsZFlkjP4T-EBbNuu7-x$XmX{$DUI17vCMHl^AaM=4eYWKoZCsJvf-B#L_}1U z#G=uOOkgJ>a9@pb8XH}-x`#mvN%lqb02%1x*`!h!>??{oSiRMbViGhdXy?|}cc z<*@9#vSz47MmouwvXW<=<+9I_v|GmzZGJUmcPvXYf!OY+e7NcUb{Jt~Zf=7|0fmjd zH71^#U-!{~RN0Rc67*%1^z z?!8q3LRL%cWMy?6$A_N5xw5smr&-^qk&*PHl`otZg;;bWU13B#Z=B{6_;45-_|K)n671U{dHfB2b;|izR8;(zZ&p-{YceCGfh%FFo&di7w5cw1} zKPYX{wU-Ci9YtI;nfTm7|Le{D0ZuzX4H0h9Su?D_vo88WGKUBScEU$c) zdyC73IB_qy!EUw4C5bgj@e9s%&wylM6Q&l ztNQ^jH>Tw-B6IolaXbNwSD?6`14s?g@bqi$jw|Y_mKvN9DFIS;aT7*`fk#d0dTo@qCzZmJ&-@kYZF`~WwB2P|ZNJ)VUklB)=f&y*AlrFitMq=LAEqDBg%16FoDgM95}e57teywrg~en9vySl7?-O2BGrH)^ ztSnNhGWl$p2@}bIe!7>WW(Um65jX4&i(TW3lfO=rbxJ;=qC~A;??V0~4EgVTZe5w{ zZGfEn95qn3gvuugK9UWaBrPNTuOt;^OIui&#+w@p>M3-a?*`3u)F-VsBdog?)*mIkw zw+;deekf8KQsDXwe}~9tW{!v7umhYamK$mMmS^dwpqGM*PWz1q>9{a4_H~7bhfB(T zZD>@;UzShdca3sddEv@~CvY6UF8Yp5HD#$e4cc>;v0ry;=jeVOH}@}aGLZ|Sb;U>k z0{n=1|xc3cvmxJqREU&i!FACc!%Qsz3qom^NRdWmxr zI$Q31Psc_gO=Q#!x;w2C7%jFj-79DVAgSW|qs&kGyNf+i| ze=*{Ugx~wMqd-vj^(FeTvX)jQ-@!9nOU7Y9wiFibivt6_=WWob?!!4&Sl(p&AJMi} z+ko0CW7*O^LVk_L%(GvIlb{LjPrW@A8LKA5D3}%lms-5$oB3s*YZ-C*^nK;m&S~aj z4njf(Eqj6Q-P=SAsDU7%-L4fr4a-kx^?1VNV@7EKcYr?;=3AeJ+MEqG!3BG6kfZ?X zV?xAZUs_O5FOn_DQ*Y1&NP_IBS$K|=3a-iAYM^p| zD0mE{WATZPP7e3a_2W{I)+#Kcut$RDb~&TROYz2^cdhkOG2twuDUF8HH| zwL{xqAsUOhx|8pkOO$9fitUL)(tPHF&6Arr?8~bJnMtmZApsE?J+W%{U?GKTUZ3J2xvZ9MbTw zsvNh+q%QjC=-jt=*3!^2>eSjOmkGw)bH8(Pc+3Jv8n4Ab0V`JCklR?kds};U`t^NE z&DXDA!7-#}@7|o#DJD0ReCGmwHWw)^50Cxq0*{QfU`9i$-Cnu1*M)U_^Rp6X9I{s3 zaMS1`VPy0bXlH5O?=40wm!St1=oL-qjL#H%rZU^VI}@iYW_(ko)xx+n=4!=o&q~Wn zUJt`9^Q3jY@1vPT<;QzwcIdn{J8ac9dfCuH7OvHdPKNxsQz<{nZgs>24J}4az@thy zQz-=^=lBsO+#Z3QwOejXO0tXFXZ|TnD1Dwim9A z0^W_ZJ+1`Z<7p33nrMT7cf<0R-?k+sr*7H4JLbwYTK_GNm3q|h0cb3Fd%0gw|6?akqdn)DX;>aP7WvDDZMcXlG4XGzQpLo^ z1$G(o-2BB@)6U00000NkvXX Hu0mjfq>c;; literal 0 HcmV?d00001 diff --git a/docs/how-to/view-packages.md b/docs/how-to/view-packages.md index 0a5fd69..b9ce5e4 100644 --- a/docs/how-to/view-packages.md +++ b/docs/how-to/view-packages.md @@ -58,6 +58,23 @@ redacted package manifest and local inline styles. ![Static package viewer preview](../assets/package-viewer-preview.svg) +The screenshots below are generated from the viewer's bundled demo package, not +from customer data. They show the desktop and narrow-screen review layouts, +included evidence summaries, readiness status, and limitations. Use them as UI +orientation only; screenshots are not package verification evidence, legal +compliance proof, certification, complete SBOM proof, authoritative scanner +results, or a secure-release guarantee. + +![Desktop screenshot of the Evydence package viewer showing the bundled demo release summary, evidence count, readiness, artifact, SBOM, and VEX sections.](../assets/package-viewer-desktop.png) + +![Mobile screenshot of the Evydence package viewer showing the bundled demo stacked summary cards and release summary.](../assets/package-viewer-mobile.png) + +To regenerate these local proof assets after changing the viewer, run: + +```sh +scripts/capture_package_viewer_screenshots.sh +``` + The sample reviewer journey is: ![Reviewer journey through package sections](../assets/reviewer-journey.svg) diff --git a/scripts/capture_package_viewer_screenshots.sh b/scripts/capture_package_viewer_screenshots.sh new file mode 100755 index 0000000..1ae9d77 --- /dev/null +++ b/scripts/capture_package_viewer_screenshots.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +set -euo pipefail + +root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +browser="${CHROMIUM_BIN:-}" + +if [[ -z "${browser}" ]]; then + browser="$(command -v chromium || true)" +fi + +if [[ -z "${browser}" ]]; then + echo "chromium is required to capture package viewer screenshots" >&2 + exit 1 +fi + +viewer="file://${root}/site/package-viewer/index.html" + +"${browser}" \ + --headless \ + --disable-gpu \ + --hide-scrollbars \ + --window-size=1440,1100 \ + --screenshot="${root}/docs/assets/package-viewer-desktop.png" \ + "${viewer}" + +"${browser}" \ + --headless \ + --disable-gpu \ + --hide-scrollbars \ + --window-size=390,1200 \ + --screenshot="${root}/docs/assets/package-viewer-mobile.png" \ + "${viewer}" + +echo "captured package viewer screenshots" From 908d74b8444f36960808528bcbfe87574faa8e87 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 18:54:48 +0300 Subject: [PATCH 260/287] docs(demo): add customer CVE review proof --- Makefile | 16 ++- README.md | 2 + docs/README.md | 1 + docs/tutorials/customer-cve-review-demo.md | 94 +++++++++++++ examples/customer-cve-review-demo/README.md | 77 +++++++++++ .../customer-cve-review-story.json | 105 +++++++++++++++ .../expected-verification-output.txt | 15 +++ examples/customer-cve-review-demo/run-demo.sh | 127 ++++++++++++++++++ 8 files changed, 436 insertions(+), 1 deletion(-) create mode 100644 docs/tutorials/customer-cve-review-demo.md create mode 100644 examples/customer-cve-review-demo/README.md create mode 100644 examples/customer-cve-review-demo/customer-cve-review-story.json create mode 100644 examples/customer-cve-review-demo/expected-verification-output.txt create mode 100755 examples/customer-cve-review-demo/run-demo.sh diff --git a/Makefile b/Makefile index 84bba02..f01db78 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ GOVULNCHECK_VERSION ?= v1.2.0 TAG ?= -.PHONY: help tools fmt lint vuln gosec test test-race fuzz-smoke coverage coverage-check openapi-check openapi-precision-check meta-check release-truth-check docs-check deploy-check sdk-check demo-check local-ci-simulation-check reviewer-package-workflow-check black-box-demo-check benchmark-check package-viewer-check marketing-site-check marketing-site-production-check restore-rehearsal-check fast-check finalize release-acceptance release-check production-check release-candidate-check public-release-verify migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean +.PHONY: help tools fmt lint vuln gosec test test-race fuzz-smoke coverage coverage-check openapi-check openapi-precision-check meta-check release-truth-check docs-check deploy-check sdk-check demo-check customer-cve-review-demo-check local-ci-simulation-check reviewer-package-workflow-check black-box-demo-check benchmark-check package-viewer-check marketing-site-check marketing-site-production-check restore-rehearsal-check fast-check finalize release-acceptance release-check production-check release-candidate-check public-release-verify migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean help: ## Show help @awk 'BEGIN {FS=":.*## "}; /^[a-zA-Z0-9_.-]+:.*## / { printf " %-18s %s\n", $$1, $$2 }' $(MAKEFILE_LIST) @@ -142,6 +142,7 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and @test -f docs/release-signing.md @test -f docs/production-hardening.md @test -f docs/tutorials/evaluate-in-10-minutes.md + @test -f docs/tutorials/customer-cve-review-demo.md @test -f docs/tutorials/getting-started.md @test -f docs/how-to/integrate-ci.md @test -f docs/how-to/install-and-operate.md @@ -184,6 +185,7 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and @test -f docs/sdk/README.md @for path in \ "tutorials/evaluate-in-10-minutes.md" \ + "tutorials/customer-cve-review-demo.md" \ "tutorials/getting-started.md" \ "how-to/install-and-operate.md" \ "how-to/view-packages.md" \ @@ -247,6 +249,7 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and @grep -F 'site/package-viewer/index.html' docs/tutorials/evaluate-in-10-minutes.md >/dev/null @grep -F 'examples/end-to-end-release-evidence/run-local-demo.sh' docs/tutorials/evaluate-in-10-minutes.md >/dev/null @grep -F 'Evaluate Evydence in 10 minutes' README.md docs/README.md >/dev/null + @grep -F 'Customer CVE review demo' README.md docs/README.md docs/tutorials/customer-cve-review-demo.md >/dev/null @grep -F 'Capability map' README.md docs/README.md >/dev/null @grep -F 'Production Check' README.md docs/reference/release-evidence-index.md >/dev/null @grep -F 'coverage.out' README.md docs/reference/release-evidence-index.md >/dev/null @@ -385,9 +388,13 @@ sdk-check: ## Validate SDK helper and generated route-catalog coverage against O demo-check: ## Validate checked end-to-end evidence demo fixtures @test -x examples/end-to-end-release-evidence/run-local-demo.sh + @test -x examples/customer-cve-review-demo/run-demo.sh @test -x scripts/local_ci_simulation_check.sh @test -x scripts/reviewer_package_workflow_check.sh @test -f examples/end-to-end-release-evidence/README.md + @test -f examples/customer-cve-review-demo/README.md + @test -f examples/customer-cve-review-demo/customer-cve-review-story.json + @test -f examples/customer-cve-review-demo/expected-verification-output.txt @test -f examples/end-to-end-release-evidence/release-evidence-manifest.json @test -f examples/end-to-end-release-evidence/sample-readiness-report.json @test -f examples/end-to-end-release-evidence/sample-security-summary.json @@ -403,10 +410,17 @@ demo-check: ## Validate checked end-to-end evidence demo fixtures @grep -F '/v1/audit-chain/verify' examples/end-to-end-release-evidence/run-local-demo.sh >/dev/null @grep -F '/v1/customer-packages' examples/end-to-end-release-evidence/run-local-demo.sh >/dev/null @grep -F 'not legal' examples/end-to-end-release-evidence/README.md >/dev/null + @grep -F 'CVE-2026-0002' examples/customer-cve-review-demo/customer-cve-review-story.json examples/customer-cve-review-demo/README.md docs/tutorials/customer-cve-review-demo.md >/dev/null + @grep -F 'approved_for_customer_package' examples/customer-cve-review-demo/customer-cve-review-story.json examples/customer-cve-review-demo/README.md docs/tutorials/customer-cve-review-demo.md >/dev/null + @grep -F 'not legal compliance proof' examples/customer-cve-review-demo/README.md docs/tutorials/customer-cve-review-demo.md >/dev/null @grep -F 'reviewer_checklist' examples/end-to-end-release-evidence/sample-customer-package-manifest.json >/dev/null @grep -F 'escalation_path' examples/end-to-end-release-evidence/sample-customer-package-manifest.json >/dev/null @grep -F 'sbom_component_purl' examples/end-to-end-release-evidence/sample-customer-package-manifest.json >/dev/null @scripts/reviewer_package_workflow_check.sh + @$(MAKE) customer-cve-review-demo-check + +customer-cve-review-demo-check: ## Validate deterministic customer CVE review demo + @examples/customer-cve-review-demo/run-demo.sh >/dev/null local-ci-simulation-check: ## Run local one-command CI evidence simulation without external services @scripts/local_ci_simulation_check.sh diff --git a/README.md b/README.md index 9224c81..ae6a8c7 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,8 @@ For durable local evaluation, run the production-like Compose rehearsal in [Install and operate](docs/how-to/install-and-operate.md). For the release-evidence path to inspect first, use the [end-to-end release evidence example](examples/end-to-end-release-evidence/README.md). +For a no-external-services buyer proof, run the +[customer CVE review demo](examples/customer-cve-review-demo/README.md). For the first CI wiring example, start with the [GitHub Actions quickstart release evidence workflow](docs/github-actions/quickstart-release-evidence.yml), then move to the scanner-oriented workflow once your runner has pinned scanner diff --git a/docs/README.md b/docs/README.md index 7232635..8f90469 100644 --- a/docs/README.md +++ b/docs/README.md @@ -5,6 +5,7 @@ This documentation is organized by reader task. Implementation claims should be ## Start Here - [Evaluate Evydence in 10 minutes](tutorials/evaluate-in-10-minutes.md): inspect the public release verifier, sample customer package, local package viewer, and VEX-first proof path. +- [Customer CVE review demo](tutorials/customer-cve-review-demo.md): run the deterministic package-scope CVE answer without external services. - [Getting started](tutorials/getting-started.md): run the API locally and create a minimal release evidence flow. - [Install and operate](how-to/install-and-operate.md): choose a local runtime mode, start dependencies, run migrations, and launch API/worker processes. - [Operations](operations.md): find the canonical operator references for configuration, workers, CI, deployment, and validation. diff --git a/docs/tutorials/customer-cve-review-demo.md b/docs/tutorials/customer-cve-review-demo.md new file mode 100644 index 0000000..0486595 --- /dev/null +++ b/docs/tutorials/customer-cve-review-demo.md @@ -0,0 +1,94 @@ +# Customer CVE Review Demo + +This tutorial shows the shortest no-external-services path for the core +Evydence buyer question: + +> This CVE appears in your SBOM. Are you affected, why, who approved it, and +> what evidence can we verify? + +The tutorial uses deterministic fixtures under +`examples/customer-cve-review-demo/` and the checked customer package under +`examples/end-to-end-release-evidence/`. It does not start PostgreSQL, object +storage, CI providers, scanners, GitHub, GitLab, KMS, or SSO. + +## Prerequisites + +- Go toolchain available for `go run ./cmd/evydence`. +- Repository checkout with the example fixture files present. + +## Run The Demo + +From the repository root: + +```sh +examples/customer-cve-review-demo/run-demo.sh +``` + +Expected output: + +```text +customer CVE review demo passed +question=This CVE appears in your SBOM. Are you affected, why, who approved it, and what evidence can we verify? +product=Payments API +release=1.0.0 +vulnerability=CVE-2026-0002 +component=pkg:apk/openssl@3.1.0 +decision=fixed +approval=approved_for_customer_package +package_id=csp_example +verification_output=verification-output.txt +``` + +The script writes: + +```text +tmp/customer-cve-review-demo/verification-output.txt +tmp/customer-cve-review-demo/summary.txt +``` + +`verification-output.txt` must match +`examples/customer-cve-review-demo/expected-verification-output.txt`. + +## Inspect The Evidence Path + +Read: + +```text +examples/customer-cve-review-demo/customer-cve-review-story.json +``` + +The fixture contains one product, one release, one artifact digest, one +CycloneDX SBOM component, one scanner finding, one VEX-style fixed decision, +one approval, one readiness report, one release bundle reference, and one +customer package fixture. + +Then verify the package directly: + +```sh +go run ./cmd/evydence package verify \ + --manifest examples/end-to-end-release-evidence/sample-customer-package-manifest.json \ + --expected-package-id csp_example \ + --expected-product-id prod_example \ + --expected-release-id rel_example +``` + +Expected result includes: + +```text +customer package verified +package_id: csp_example +product_id: prod_example +release_id: rel_example +``` + +To inspect the package visually, open `site/package-viewer/index.html` and +press **Load bundled demo**, or load +`examples/end-to-end-release-evidence/sample-customer-package-manifest.json`. + +## Boundaries + +The fixture is non-sensitive and local. It must not be treated as legal +compliance proof, certification, complete SBOM proof, authoritative scanner +coverage, regulator acceptance, or a secure-release guarantee. It demonstrates +how Evydence organizes technical evidence, decisions, verification material, +gaps, assumptions, and limitations for a customer review. diff --git a/examples/customer-cve-review-demo/README.md b/examples/customer-cve-review-demo/README.md new file mode 100644 index 0000000..0b6771c --- /dev/null +++ b/examples/customer-cve-review-demo/README.md @@ -0,0 +1,77 @@ +# Customer CVE Review Demo + +This fixture answers the customer-review question that Evydence is optimized +for: + +> This CVE appears in your SBOM. Are you affected, why, who approved it, and +> what evidence can we verify? + +The demo is local and deterministic. It uses checked sample files, the local +CLI verifier, and no external services. It does not contain secrets, raw +evidence payload bytes, object-store paths, customer data, private keys, bearer +tokens, token hashes, or provider credentials. + +## Files + +- `customer-cve-review-story.json`: one release, one artifact digest, one SBOM + component, one scanner finding, one VEX-style fixed decision, one approval, + one readiness report, one release bundle reference, and one customer package + fixture. +- `expected-verification-output.txt`: exact expected offline verifier output. +- `run-demo.sh`: checked local script that verifies the sample manifest and + ZIP archive, validates the story fixture, and writes output under + `tmp/customer-cve-review-demo/`. + +The customer package manifest and archive live in +`examples/end-to-end-release-evidence/` so this demo reuses the same checked +package fixture as the package viewer and reviewer workflow. + +## Run + +From the repository root: + +```sh +examples/customer-cve-review-demo/run-demo.sh +``` + +Expected output: + +```text +customer CVE review demo passed +question=This CVE appears in your SBOM. Are you affected, why, who approved it, and what evidence can we verify? +product=Payments API +release=1.0.0 +vulnerability=CVE-2026-0002 +component=pkg:apk/openssl@3.1.0 +decision=fixed +approval=approved_for_customer_package +package_id=csp_example +verification_output=verification-output.txt +``` + +The script writes the verifier output to: + +```text +tmp/customer-cve-review-demo/verification-output.txt +``` + +That file should match `expected-verification-output.txt`. + +## What The Demo Shows + +- The SBOM component is linked to the scanner finding for `CVE-2026-0002`. +- The customer-visible decision records the finding as fixed in this release. +- The approval record explains that the package can be used for a customer + review path. +- The readiness report result is `passed` for this package-scope fixture. +- The release bundle metadata includes signature references, and the customer + package manifest/archive verify offline with the local CLI. + +## Limitations + +This fixture supports local product evaluation and reviewer orientation only. +It is not legal compliance proof, certification, complete SBOM proof, an +authoritative vulnerability result, regulator acceptance, or a secure-release +guarantee. For a live API flow that creates tenant-scoped records, use +`examples/end-to-end-release-evidence/run-local-demo.sh` after starting a local +Evydence API with a scoped key. diff --git a/examples/customer-cve-review-demo/customer-cve-review-story.json b/examples/customer-cve-review-demo/customer-cve-review-story.json new file mode 100644 index 0000000..98dd3f1 --- /dev/null +++ b/examples/customer-cve-review-demo/customer-cve-review-story.json @@ -0,0 +1,105 @@ +{ + "schema_version": "evydence-customer-cve-review-demo.v1.0.0", + "question": "This CVE appears in your SBOM. Are you affected, why, who approved it, and what evidence can we verify?", + "product": { + "id": "prod_example", + "name": "Payments API" + }, + "release": { + "id": "rel_example", + "version": "1.0.0", + "state": "approved" + }, + "artifact": { + "id": "art_example", + "name": "payments-api.tar.gz", + "digest": "sha256:ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb" + }, + "sbom": { + "id": "sbom_example", + "format": "cyclonedx", + "spec_version": "1.6", + "component": { + "name": "openssl", + "purl": "pkg:apk/openssl@3.1.0" + } + }, + "scanner_finding": { + "id": "finding_example", + "scanner": "example-scanner", + "vulnerability": "CVE-2026-0002", + "component": "pkg:apk/openssl@3.1.0", + "severity": "high", + "state": "fixed_by_decision" + }, + "vulnerability_decision": { + "id": "vd_example", + "status": "fixed", + "justification": "fixed_in_release", + "impact_statement": "The finding is fixed in this release artifact.", + "action_statement": "Upgrade to this release after normal operator review.", + "source": "vex", + "reviewed_at": "2026-05-27T12:00:00Z", + "review_due_at": "2026-08-25T12:00:00Z" + }, + "approval": { + "id": "approval_example", + "type": "release_risk_decision", + "actor": "security-reviewer@example.test", + "decision": "approved_for_customer_package", + "approved_at": "2026-05-27T12:00:00Z" + }, + "readiness_report": { + "result": "passed", + "checks": [ + { + "name": "release_requires_sbom", + "result": "passed" + }, + { + "name": "release_requires_vulnerability_decision", + "result": "passed" + }, + { + "name": "release_requires_release_bundle", + "result": "passed" + } + ], + "limitations": [ + "Readiness is derived from recorded package-scope evidence only.", + "Readiness output is not a compliance, certification, or secure-release conclusion." + ] + }, + "release_bundle": { + "id": "rb_example", + "state": "generated", + "manifest_hash": "sha256:example", + "signature_refs": [ + "sig_example" + ] + }, + "customer_package": { + "id": "csp_example", + "manifest": "../end-to-end-release-evidence/sample-customer-package-manifest.json", + "archive": "../end-to-end-release-evidence/sample-customer-package.zip", + "manifest_hash": "sha256:83dfd287d47855753cfe22dcc842b485efabe759a25eef946b2c41df248917ed" + }, + "offline_verification": { + "commands": [ + "go run ./cmd/evydence package verify --manifest examples/end-to-end-release-evidence/sample-customer-package-manifest.json --expected-package-id csp_example --expected-product-id prod_example --expected-release-id rel_example", + "go run ./cmd/evydence package verify --archive examples/end-to-end-release-evidence/sample-customer-package.zip --expected-package-id csp_example --expected-product-id prod_example --expected-release-id rel_example" + ], + "expected_output": "expected-verification-output.txt" + }, + "answer_summary": [ + "The package links the affected component to SBOM metadata and a scanner finding.", + "The active customer-visible decision records the finding as fixed in this release.", + "The package includes release-bundle metadata and offline package manifest/archive verification.", + "The package states assumptions and limitations and avoids compliance or security guarantees." + ], + "limitations": [ + "This is a non-sensitive fixture for local evaluation.", + "It does not include raw tenant payloads, object-store paths, bearer tokens, token hashes, private keys, or customer data.", + "The fixture is not legal compliance proof, certification, complete SBOM proof, an authoritative vulnerability result, or a secure-release guarantee." + ] +} diff --git a/examples/customer-cve-review-demo/expected-verification-output.txt b/examples/customer-cve-review-demo/expected-verification-output.txt new file mode 100644 index 0000000..1ad6638 --- /dev/null +++ b/examples/customer-cve-review-demo/expected-verification-output.txt @@ -0,0 +1,15 @@ +manifest verification: +customer package verified +package_id: csp_example +product_id: prod_example +release_id: rel_example +manifest_hash: sha256:83dfd287d47855753cfe22dcc842b485efabe759a25eef946b2c41df248917ed +evidence_bundle: not supplied + +archive verification: +customer package verified +package_id: csp_example +product_id: prod_example +release_id: rel_example +manifest_hash: sha256:83dfd287d47855753cfe22dcc842b485efabe759a25eef946b2c41df248917ed +evidence_bundle: not supplied diff --git a/examples/customer-cve-review-demo/run-demo.sh b/examples/customer-cve-review-demo/run-demo.sh new file mode 100755 index 0000000..5bd4f85 --- /dev/null +++ b/examples/customer-cve-review-demo/run-demo.sh @@ -0,0 +1,127 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +cd "$ROOT" + +fail() { + printf '%s\n' "customer-cve-review-demo: $*" >&2 + exit 1 +} + +workdir="${EVYDENCE_CUSTOMER_CVE_DEMO_DIR:-tmp/customer-cve-review-demo}" +case "$workdir" in + tmp/*) ;; + *) fail "EVYDENCE_CUSTOMER_CVE_DEMO_DIR must stay under tmp/" ;; +esac + +story="examples/customer-cve-review-demo/customer-cve-review-story.json" +expected="examples/customer-cve-review-demo/expected-verification-output.txt" +manifest="examples/end-to-end-release-evidence/sample-customer-package-manifest.json" +archive="examples/end-to-end-release-evidence/sample-customer-package.zip" + +for path in "$story" "$expected" "$manifest" "$archive"; do + [[ -f "$path" ]] || fail "missing $path" +done + +rm -rf -- "$workdir" +mkdir -p -- "$workdir" + +{ + printf '%s\n' "manifest verification:" + go run ./cmd/evydence package verify \ + --manifest "$manifest" \ + --expected-package-id csp_example \ + --expected-product-id prod_example \ + --expected-release-id rel_example + printf '\n%s\n' "archive verification:" + go run ./cmd/evydence package verify \ + --archive "$archive" \ + --expected-package-id csp_example \ + --expected-product-id prod_example \ + --expected-release-id rel_example +} >"$workdir/verification-output.txt" + +diff -u "$expected" "$workdir/verification-output.txt" >/dev/null || { + diff -u "$expected" "$workdir/verification-output.txt" >&2 || true + fail "verification output drifted" +} + +python3 - "$story" "$manifest" "$workdir" <<'PY' +import json +import pathlib +import sys + +story_path = pathlib.Path(sys.argv[1]) +manifest_path = pathlib.Path(sys.argv[2]) +workdir = pathlib.Path(sys.argv[3]) + +story = json.loads(story_path.read_text()) +manifest = json.loads(manifest_path.read_text()) + +required = [ + "product", + "release", + "artifact", + "sbom", + "scanner_finding", + "vulnerability_decision", + "approval", + "readiness_report", + "release_bundle", + "customer_package", + "offline_verification", +] +missing = [key for key in required if key not in story] +if missing: + raise SystemExit(f"story missing {', '.join(missing)}") + +if story["product"]["id"] != manifest["product_id"]: + raise SystemExit("story product does not match package manifest") +if story["release"]["id"] != manifest["release_id"]: + raise SystemExit("story release does not match package manifest") +if story["customer_package"]["id"] != manifest["package_id"]: + raise SystemExit("story package does not match package manifest") + +finding = story["scanner_finding"] +decision = story["vulnerability_decision"] +if finding["vulnerability"] != decision.get("vulnerability", finding["vulnerability"]): + raise SystemExit("decision vulnerability mismatch") +if finding["component"] != story["sbom"]["component"]["purl"]: + raise SystemExit("finding component is not tied to SBOM component") +if decision["status"] not in {"fixed", "not_affected"}: + raise SystemExit("demo decision must be fixed or not_affected") +if story["readiness_report"]["result"] != "passed": + raise SystemExit("demo readiness must pass") +if not story["release_bundle"].get("signature_refs"): + raise SystemExit("release bundle signature refs missing") + +serialized = json.dumps({"story": story, "manifest": manifest}, sort_keys=True).lower() +for forbidden in ( + "payload_ref", + "object_key", + "private_key", + "token_hash", + "api_key", + "internal note", + "customer_secret", +): + if forbidden in serialized: + raise SystemExit(f"demo leaked forbidden marker {forbidden}") + +summary = [ + "customer CVE review demo passed", + f"question={story['question']}", + f"product={story['product']['name']}", + f"release={story['release']['version']}", + f"vulnerability={finding['vulnerability']}", + f"component={finding['component']}", + f"decision={decision['status']}", + f"approval={story['approval']['decision']}", + f"package_id={story['customer_package']['id']}", + "verification_output=verification-output.txt", +] +(workdir / "summary.txt").write_text("\n".join(summary) + "\n") +PY + +cat "$workdir/summary.txt" From e34cc201fb548b0248722b7ba2092fbaac26eacd Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 18:59:12 +0300 Subject: [PATCH 261/287] feat(site): add homepage demo path --- site/marketing/scripts/check.mjs | 13 ++++++- site/marketing/src/data/site.ts | 16 ++++++++ site/marketing/src/layouts/BaseLayout.astro | 39 +++++++++++++++++-- .../src/templates/MarketingPage.astro | 7 ++++ 4 files changed, 70 insertions(+), 5 deletions(-) diff --git a/site/marketing/scripts/check.mjs b/site/marketing/scripts/check.mjs index b055642..d6affb5 100644 --- a/site/marketing/scripts/check.mjs +++ b/site/marketing/scripts/check.mjs @@ -48,6 +48,7 @@ const privacy = readFileSync(join(dist, "en/privacy-cookies/index.html"), "utf8" const cname = readFileSync(join(dist, "CNAME"), "utf8").trim(); const consentSource = readFileSync(join(root, "src/components/ConsentBanner.astro"), "utf8"); const layoutSource = readFileSync(join(root, "src/layouts/BaseLayout.astro"), "utf8"); +const templateSource = readFileSync(join(root, "src/templates/MarketingPage.astro"), "utf8"); const requiredRoot = [ 'lang="en"', @@ -70,7 +71,10 @@ const requiredEnglish = [ 'lang="en"', 'hreflang="fi"', "Stop scrambling when customers ask for release security evidence.", + "Run the customer CVE review demo", + "One release, one SBOM finding, one decision, one package verifier.", "https://www.linkedin.com/in/aatu-harju", + "https://github.com/aatuh/evydence/tree/master/examples/customer-cve-review-demo", "Cookie preferences", "Evydence is not a legal compliance service" ]; @@ -85,6 +89,8 @@ const requiredFinnish = [ 'lang="fi"', 'hreflang="en"', "Lopeta kiireinen selvittely", + "Aja asiakkaan CVE-katselmusdemo", + "Yksi julkaisu, yksi SBOM-löydös, yksi päätös ja paketin todennus.", "Evästeasetukset", "Evydence ei ole juridinen" ]; @@ -114,12 +120,13 @@ for (const text of consentChecks) { const layoutChecks = [ "class=\"mobile-nav\"", "mobile-nav__panel", - "font-size: clamp(2.7rem, 5.4vw, 5.25rem)", + "font-size: clamp(2.55rem, 4.65vw, 4.65rem)", ".hero h1", "hyphens: none", "word-break: normal", ":lang(fi) h2", ":lang(fi) .section--split h2", + ".hero__demo", "font-size: 1.85rem", "overflow-wrap: anywhere", ".section--split > *", @@ -133,6 +140,10 @@ for (const text of layoutChecks) { } } +if (!templateSource.includes('data-track="demo_click"')) { + throw new Error('Marketing template missing demo click tracking marker'); +} + for (const forbidden of [ "innerHTML", "Start free trial", diff --git a/site/marketing/src/data/site.ts b/site/marketing/src/data/site.ts index e1f9f7c..73a4e79 100644 --- a/site/marketing/src/data/site.ts +++ b/site/marketing/src/data/site.ts @@ -32,6 +32,10 @@ export type PageContent = { heroBody: string[]; primaryCta: string; secondaryCta: string; + demoEyebrow?: string; + demoCta?: string; + demoText?: string; + demoHref?: string; sections: Section[]; }; @@ -90,6 +94,8 @@ export const navItems: PageKey[] = [ export const externalLinks = { github: "https://github.com/aatuh/evydence", docs: "https://github.com/aatuh/evydence/tree/master/docs", + customerCveDemo: + "https://github.com/aatuh/evydence/tree/master/examples/customer-cve-review-demo", linkedin: "https://www.linkedin.com/in/aatu-harju", }; @@ -110,6 +116,11 @@ const en: Record = { ], primaryCta: "Ask about Commercial Self-Hosted", secondaryCta: "View GitHub", + demoEyebrow: "Demo", + demoCta: "Run the customer CVE review demo", + demoText: + "One release, one SBOM finding, one decision, one package verifier.", + demoHref: externalLinks.customerCveDemo, sections: [ { eyebrow: "The problem", @@ -580,6 +591,11 @@ const fi: Record = { ], primaryCta: "Kysy Commercial Self-Hosted -ehdoista", secondaryCta: "Avaa GitHub", + demoEyebrow: "Demo", + demoCta: "Aja asiakkaan CVE-katselmusdemo", + demoText: + "Yksi julkaisu, yksi SBOM-löydös, yksi päätös ja paketin todennus.", + demoHref: externalLinks.customerCveDemo, sections: [ { eyebrow: "Ongelma", diff --git a/site/marketing/src/layouts/BaseLayout.astro b/site/marketing/src/layouts/BaseLayout.astro index 97187af..11cc3bb 100644 --- a/site/marketing/src/layouts/BaseLayout.astro +++ b/site/marketing/src/layouts/BaseLayout.astro @@ -377,12 +377,12 @@ const ui = { } h1 { - font-size: clamp(2.7rem, 5.4vw, 5.25rem); + font-size: clamp(2.55rem, 4.65vw, 4.65rem); hyphens: auto; line-height: 1.02; letter-spacing: 0; margin-bottom: 1.15rem; - max-width: 13.5ch; + max-width: 16.5ch; overflow-wrap: break-word; } @@ -403,8 +403,8 @@ const ui = { } :lang(fi) h1 { - font-size: clamp(2.25rem, 3.9vw, 3.75rem); - max-width: 20ch; + font-size: clamp(2.15rem, 3.55vw, 3.45rem); + max-width: 22ch; } :lang(fi) h2 { @@ -431,6 +431,37 @@ const ui = { margin-top: 1.5rem; } + .hero__demo { + align-items: center; + color: var(--muted); + display: flex; + flex-wrap: wrap; + gap: 0.45rem 0.65rem; + margin: 1.15rem 0 0; + max-width: 42rem; + } + + .hero__demo span { + border: 1px solid var(--line); + border-radius: 999px; + color: var(--ink); + font-size: 0.78rem; + font-weight: 800; + padding: 0.2rem 0.55rem; + text-transform: uppercase; + } + + .hero__demo a { + color: var(--accent-dark); + font-weight: 800; + text-decoration-thickness: 0.08em; + text-underline-offset: 0.22em; + } + + .hero__demo small { + font-size: 0.94rem; + } + .section { padding-bottom: clamp(3rem, 7vw, 6rem); padding-top: clamp(3rem, 7vw, 6rem); diff --git a/site/marketing/src/templates/MarketingPage.astro b/site/marketing/src/templates/MarketingPage.astro index 0f4f89c..61574b5 100644 --- a/site/marketing/src/templates/MarketingPage.astro +++ b/site/marketing/src/templates/MarketingPage.astro @@ -17,6 +17,13 @@ const primaryAttrs = pageKey === "privacyCookies" ? { "data-cookie-preferences": {page.eyebrow &&

{page.eyebrow}

}

{page.heroTitle}

{page.heroBody.map((paragraph) =>

{paragraph}

)} + {page.demoCta && page.demoHref && ( +

+ {page.demoEyebrow && {page.demoEyebrow}} + {page.demoCta} + {page.demoText && {page.demoText}} +

+ )}
{page.primaryCta} {page.secondaryCta} From 7a1238560ce400275d61d0459eb28ce4abac8c8e Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 19:00:18 +0300 Subject: [PATCH 262/287] docs(readme): lead with buyer question --- Makefile | 3 +++ README.md | 39 +++++++++++++++++++++++---------------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index f01db78..55a6e25 100644 --- a/Makefile +++ b/Makefile @@ -250,6 +250,9 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and @grep -F 'examples/end-to-end-release-evidence/run-local-demo.sh' docs/tutorials/evaluate-in-10-minutes.md >/dev/null @grep -F 'Evaluate Evydence in 10 minutes' README.md docs/README.md >/dev/null @grep -F 'Customer CVE review demo' README.md docs/README.md docs/tutorials/customer-cve-review-demo.md >/dev/null + @grep -F 'The core buyer question is' README.md >/dev/null + @grep -F 'OpenAPI reference' README.md >/dev/null + @grep -F 'Install and operate' README.md >/dev/null @grep -F 'Capability map' README.md docs/README.md >/dev/null @grep -F 'Production Check' README.md docs/reference/release-evidence-index.md >/dev/null @grep -F 'coverage.out' README.md docs/reference/release-evidence-index.md >/dev/null diff --git a/README.md b/README.md index ae6a8c7..6a627da 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,29 @@ questions with signed, customer-safe release evidence bundles. Website: +The core buyer question is: "This CVE appears in your SBOM for this release. +Are you affected, why or why not, who approved that decision, and what evidence +can we verify?" Evydence records the SBOM, vulnerability scan, VEX or manual +decision, build provenance, artifact digest, exceptions, release bundle, and +customer package that support the answer. + +| Start here | Use this when you want to | +| --- | --- | +| [Customer CVE review demo](examples/customer-cve-review-demo/README.md) | Inspect the no-external-services buyer proof path. | +| [OpenAPI reference](docs/reference/openapi.md) | Review the `/v1` API contract and generated schemas. | +| [Install and operate](docs/how-to/install-and-operate.md) | Run the self-hosted API/worker path with PostgreSQL and object storage. | +| [Release evidence index](docs/reference/release-evidence-index.md) | Verify public release artifacts, checksums, production-check evidence, and limitations. | + +Before Evydence, teams often stitch together scanner exports, CI logs, Slack +approvals, spreadsheets, object-storage folders, and one-off customer answers. +After Evydence, the same release has tenant-scoped API records, append-only +decisions, tamper-evident audit entries, signed bundles, reproducible reports, +and scoped packages that state gaps, assumptions, exceptions, and limitations. + +It does not make legal compliance conclusions, grant certification, prove SBOM +completeness, treat scanner findings as authoritative, or guarantee release +security. + ## Current Status - Best for: evaluation, pilots, and controlled internal self-hosted use after operator review. @@ -30,22 +53,6 @@ Website: [Release evidence index](docs/reference/release-evidence-index.md) before running beyond local evaluation. -The concrete buyer question is: "This CVE appears in your SBOM for this -release. Are you affected, why or why not, who approved that decision, and what -evidence can we verify?" Evydence records the SBOM, vulnerability scan, VEX or -manual decision, build provenance, artifact digest, exceptions, release bundle, -and customer package that support the answer. - -Before Evydence, teams often stitch together scanner exports, CI logs, Slack -approvals, spreadsheets, object-storage folders, and one-off customer answers. -After Evydence, the same release has tenant-scoped API records, append-only -decisions, tamper-evident audit entries, signed bundles, reproducible reports, -and scoped packages that state gaps, assumptions, exceptions, and limitations. - -It does not make legal compliance conclusions, grant certification, prove SBOM -completeness, treat scanner findings as authoritative, or guarantee release -security. - ## What Question Does Evydence Answer? Evydence is designed to make release-risk answers traceable to concrete From 556baff17195bada9619461dcfd8137fe540ee95 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 19:01:39 +0300 Subject: [PATCH 263/287] docs: split buyer and operator paths --- Makefile | 8 +++++ README.md | 2 ++ docs/README.md | 2 ++ docs/buyer-overview.md | 49 +++++++++++++++++++++++++++++++ docs/operator-overview.md | 49 +++++++++++++++++++++++++++++++ docs/reference/source-of-truth.md | 2 ++ 6 files changed, 112 insertions(+) create mode 100644 docs/buyer-overview.md create mode 100644 docs/operator-overview.md diff --git a/Makefile b/Makefile index 55a6e25..32b0775 100644 --- a/Makefile +++ b/Makefile @@ -134,6 +134,8 @@ release-truth-check: ## Validate current release metadata against public docs an docs-check: meta-check release-truth-check ## Validate canonical docs exist and avoid forbidden product claims @test -f README.md @test -f docs/README.md + @test -f docs/buyer-overview.md + @test -f docs/operator-overview.md @test -f docs/architecture.md @test -f docs/api.md @test -f docs/operations.md @@ -187,6 +189,8 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and "tutorials/evaluate-in-10-minutes.md" \ "tutorials/customer-cve-review-demo.md" \ "tutorials/getting-started.md" \ + "buyer-overview.md" \ + "operator-overview.md" \ "how-to/install-and-operate.md" \ "how-to/view-packages.md" \ "how-to/review-customer-package.md" \ @@ -251,8 +255,12 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and @grep -F 'Evaluate Evydence in 10 minutes' README.md docs/README.md >/dev/null @grep -F 'Customer CVE review demo' README.md docs/README.md docs/tutorials/customer-cve-review-demo.md >/dev/null @grep -F 'The core buyer question is' README.md >/dev/null + @grep -F 'Buyer evaluation overview' README.md docs/README.md >/dev/null + @grep -F 'Operator overview' README.md docs/README.md >/dev/null @grep -F 'OpenAPI reference' README.md >/dev/null @grep -F 'Install and operate' README.md >/dev/null + @grep -F 'Fastest Buyer Path' docs/buyer-overview.md >/dev/null + @grep -F 'Primary Operator Path' docs/operator-overview.md >/dev/null @grep -F 'Capability map' README.md docs/README.md >/dev/null @grep -F 'Production Check' README.md docs/reference/release-evidence-index.md >/dev/null @grep -F 'coverage.out' README.md docs/reference/release-evidence-index.md >/dev/null diff --git a/README.md b/README.md index 6a627da..a71b9ce 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,8 @@ customer package that support the answer. | Start here | Use this when you want to | | --- | --- | | [Customer CVE review demo](examples/customer-cve-review-demo/README.md) | Inspect the no-external-services buyer proof path. | +| [Buyer evaluation overview](docs/buyer-overview.md) | Follow the buyer package, demo, release-evidence, and API review path. | +| [Operator overview](docs/operator-overview.md) | Follow the self-hosted install, runbook, and production-gate path. | | [OpenAPI reference](docs/reference/openapi.md) | Review the `/v1` API contract and generated schemas. | | [Install and operate](docs/how-to/install-and-operate.md) | Run the self-hosted API/worker path with PostgreSQL and object storage. | | [Release evidence index](docs/reference/release-evidence-index.md) | Verify public release artifacts, checksums, production-check evidence, and limitations. | diff --git a/docs/README.md b/docs/README.md index 8f90469..172c545 100644 --- a/docs/README.md +++ b/docs/README.md @@ -4,6 +4,8 @@ This documentation is organized by reader task. Implementation claims should be ## Start Here +- [Buyer evaluation overview](buyer-overview.md): choose the package, demo, release-evidence, and API paths for customer-review evaluation. +- [Operator overview](operator-overview.md): choose the install, configuration, deployment, runbook, and production-gate paths for self-hosting. - [Evaluate Evydence in 10 minutes](tutorials/evaluate-in-10-minutes.md): inspect the public release verifier, sample customer package, local package viewer, and VEX-first proof path. - [Customer CVE review demo](tutorials/customer-cve-review-demo.md): run the deterministic package-scope CVE answer without external services. - [Getting started](tutorials/getting-started.md): run the API locally and create a minimal release evidence flow. diff --git a/docs/buyer-overview.md b/docs/buyer-overview.md new file mode 100644 index 0000000..0971639 --- /dev/null +++ b/docs/buyer-overview.md @@ -0,0 +1,49 @@ +# Buyer Evaluation Overview + +This overview is for product security, AppSec, platform, release, procurement, +and customer-security-review readers who want to understand what Evydence can +show before operating it. + +Evydence supports compliance readiness and technical evidence organization. It +does not make legal compliance conclusions, grant certification, prove SBOM +completeness, treat scanner output as authoritative, or guarantee release +security. + +## Fastest Buyer Path + +1. Run the [customer CVE review demo](tutorials/customer-cve-review-demo.md) to + inspect one release, one SBOM component, one vulnerability finding, one + decision, one approval, one package, and one offline verification path. +2. Open the [package viewer guide](how-to/view-packages.md) to see the + customer-safe package review surface and screenshots. +3. Follow [Evaluate Evydence in 10 minutes](tutorials/evaluate-in-10-minutes.md) + to verify public release artifacts and inspect package fixtures. +4. Review the [release evidence index](reference/release-evidence-index.md) to + see what the current public release candidate publishes as reproducible + engineering evidence. +5. Read the [capability map](reference/capability-map.md) to separate + implemented behavior from implemented-but-partial areas and external + controls. + +## Questions To Answer + +Use the buyer path to answer: + +- Which release and artifact are being reviewed? +- Which SBOM and vulnerability scan raised the finding? +- What VEX or manual decision was recorded? +- Who approved or recorded the decision? +- What package can be shared safely? +- What can be verified offline? +- What gaps, assumptions, exceptions, and limitations remain? + +## When To Switch To Operator Docs + +Move to [Operator Overview](operator-overview.md) when you need to run the API, +worker, PostgreSQL, object storage, release gates, backup/restore rehearsal, +Kubernetes deployment, or production-readiness checks. + +For public API integration review, use [OpenAPI contract](reference/openapi.md) +and [API reference](api.md). For production status, use +[Production readiness](reference/production-readiness.md) and +[Production exit review](reference/production-exit-review.md). diff --git a/docs/operator-overview.md b/docs/operator-overview.md new file mode 100644 index 0000000..e8434f7 --- /dev/null +++ b/docs/operator-overview.md @@ -0,0 +1,49 @@ +# Operator Overview + +This overview is for maintainers and self-hosted operators who need to run, +upgrade, monitor, back up, and validate Evydence. + +Evydence is currently a controlled self-hosted production candidate. The +supported API deployment profile is one API writer replica with scalable worker +replicas through PostgreSQL outbox locking. See +[Production readiness](reference/production-readiness.md) and +[Production exit review](reference/production-exit-review.md) before using it +beyond evaluation. + +## Primary Operator Path + +1. Start with [Install and operate](how-to/install-and-operate.md) for local, + durable, and production-like runtime modes. +2. Use [Configuration](reference/configuration.md) for environment variables + and production-safety combinations. +3. Use [Kubernetes deployment](kubernetes.md) or + [Air-gapped installation](air-gapped.md) only after the package and release + evidence have been verified. +4. Run the gates in [Release validation](reference/release-validation.md) and + [Production gate troubleshooting](reference/production-gate-troubleshooting.md) + with sanitized logs. +5. Rehearse [Backup and restore](runbooks/backup-restore.md), follow the + [Upgrade runbook](runbooks/upgrade.md), and keep + [Incident response](runbooks/incident-response.md) ready. + +## Operating Boundaries + +- PostgreSQL is required for production-mode source of truth. +- Filesystem object storage is local/test oriented; S3-compatible object + storage is the production target. +- API writers stay at one replica for the current release line. +- Worker replicas may scale through PostgreSQL outbox locking. +- API keys, collector keys, SSO sessions, portal tokens, private keys, object + payloads, customer package contents, and raw evidence must not be logged or + placed in public support reports. +- Release evidence supports reproducibility and engineering review, not legal + compliance proof, certification, complete SBOM proof, authoritative scanner + results, or a secure-release guarantee. + +## Related References + +- [Observability](reference/observability.md) +- [Capacity and failure modes](reference/capacity-and-failures.md) +- [External controls matrix](reference/external-controls-matrix.md) +- [Stable v0.1.0 exit criteria](reference/stable-v0.1.0-exit-criteria.md) +- [Source of truth](reference/source-of-truth.md) diff --git a/docs/reference/source-of-truth.md b/docs/reference/source-of-truth.md index 9874e02..1e8286d 100644 --- a/docs/reference/source-of-truth.md +++ b/docs/reference/source-of-truth.md @@ -6,6 +6,8 @@ product-boundary language across the docs. | Topic | Canonical Source | Notes | | --- | --- | --- | | Product positioning and current status | `README.md` and `docs/reference/production-readiness.md` | Other docs should link here instead of redefining release status. | +| Buyer evaluation path | `docs/buyer-overview.md` | Links demo, package viewer, release evidence, capability map, and API review without duplicating commands. | +| Operator path | `docs/operator-overview.md` and `docs/operations.md` | Links install, config, deployment, gates, runbooks, and production boundaries. | | Runtime configuration | `docs/reference/configuration.md` | How-to guides may show a short example, then link here for variables. | | API routes, scopes, idempotency, schemas | `openapi.yaml`, `docs/api.md`, `docs/reference/api-contract-matrix.md` | `openapi.yaml` is generated; the matrix is generated from it. | | Local startup | `docs/tutorials/getting-started.md` | Uses in-process state only. | From 70bdc52623b2813709cc7a2999bfba1652aa60d6 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 19:04:38 +0300 Subject: [PATCH 264/287] docs(runbooks): add rotation and object recovery --- Makefile | 8 +++ docs/README.md | 2 + docs/operator-overview.md | 6 +- docs/reference/source-of-truth.md | 3 +- docs/runbooks/key-rotation.md | 65 +++++++++++++++++++ docs/runbooks/object-store-recovery.md | 86 ++++++++++++++++++++++++++ 6 files changed, 167 insertions(+), 3 deletions(-) create mode 100644 docs/runbooks/key-rotation.md create mode 100644 docs/runbooks/object-store-recovery.md diff --git a/Makefile b/Makefile index 32b0775..7ed53ec 100644 --- a/Makefile +++ b/Makefile @@ -173,6 +173,8 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and @test -f docs/reference/release-validation.md @test -f docs/reference/upload-manifest.md @test -f docs/how-to/review-customer-package.md + @test -f docs/runbooks/key-rotation.md + @test -f docs/runbooks/object-store-recovery.md @test -f schemas/upload-manifest.v1.schema.json @test -f docs/explanation/trust-model.md @test -f docs/collectors/source-snapshots.md @@ -223,6 +225,8 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and "reference/worker-outbox.md" \ "reference/release-validation.md" \ "reference/upload-manifest.md" \ + "runbooks/key-rotation.md" \ + "runbooks/object-store-recovery.md" \ "collectors/source-snapshots.md" \ "collectors/supply-chain.md" \ "github-actions/quickstart-release-evidence.yml" \ @@ -278,6 +282,10 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and @grep -F 'Redaction Leakage Guard' docs/reference/customer-package-manifest.md >/dev/null @grep -F 'reviewer_checklist' docs/reference/customer-package-manifest.md >/dev/null @grep -F 'make restore-rehearsal-check' docs/runbooks/backup-restore.md >/dev/null + @grep -F 'API key' docs/runbooks/key-rotation.md >/dev/null + @grep -F 'Tenant signing key' docs/runbooks/key-rotation.md >/dev/null + @grep -F 'make restore-rehearsal-check' docs/runbooks/object-store-recovery.md >/dev/null + @grep -F 'Do not regenerate or overwrite historical evidence' docs/runbooks/object-store-recovery.md >/dev/null @test -f docs/how-to/pilot-deployment-checklist.md @grep -F 'Required: external PostgreSQL' docs/how-to/pilot-deployment-checklist.md >/dev/null @grep -F 'external controls matrix' docs/reference/production-readiness.md docs/kubernetes.md docs/how-to/pilot-deployment-checklist.md >/dev/null diff --git a/docs/README.md b/docs/README.md index 172c545..0d91735 100644 --- a/docs/README.md +++ b/docs/README.md @@ -27,6 +27,8 @@ This documentation is organized by reader task. Implementation claims should be - [Backup and restore runbook](runbooks/backup-restore.md): rehearse paired database/object-store restore and verification. - [Upgrade runbook](runbooks/upgrade.md): verify release artifacts, migrations, and post-upgrade checks. - [Incident response runbook](runbooks/incident-response.md): handle operator incidents without leaking secrets or raw evidence. +- [Key rotation runbook](runbooks/key-rotation.md): rotate API, collector, SSO/session, portal, signing, and provider credentials. +- [Object store recovery runbook](runbooks/object-store-recovery.md): recover missing or mismatched raw payloads and package/export objects. ## Reference diff --git a/docs/operator-overview.md b/docs/operator-overview.md index e8434f7..8c8d753 100644 --- a/docs/operator-overview.md +++ b/docs/operator-overview.md @@ -23,8 +23,10 @@ beyond evaluation. [Production gate troubleshooting](reference/production-gate-troubleshooting.md) with sanitized logs. 5. Rehearse [Backup and restore](runbooks/backup-restore.md), follow the - [Upgrade runbook](runbooks/upgrade.md), and keep - [Incident response](runbooks/incident-response.md) ready. + [Upgrade runbook](runbooks/upgrade.md), keep + [Incident response](runbooks/incident-response.md) ready, and prepare + [Key rotation](runbooks/key-rotation.md) plus + [Object store recovery](runbooks/object-store-recovery.md). ## Operating Boundaries diff --git a/docs/reference/source-of-truth.md b/docs/reference/source-of-truth.md index 1e8286d..f1c6294 100644 --- a/docs/reference/source-of-truth.md +++ b/docs/reference/source-of-truth.md @@ -20,9 +20,10 @@ product-boundary language across the docs. | Design-partner pilot checklist | `docs/how-to/pilot-deployment-checklist.md` | Narrow copy-paste checklist for one controlled self-hosted pilot profile. | | Maintainer review ownership | `CODEOWNERS` and `docs/reference/maintainer-review-policy.md` | Branch protection or repository rules must enforce this before it is a merge gate. | | Roadmap and cadence | `docs/reference/roadmap.md` | Public roadmap, supported release line, and cadence expectations. | -| Backup/restore | `docs/runbooks/backup-restore.md` | Operator rehearsal steps and evidence to keep. | +| Backup/restore | `docs/runbooks/backup-restore.md` and `docs/runbooks/object-store-recovery.md` | Operator rehearsal steps, object-store recovery, and evidence to keep. | | Upgrade | `docs/runbooks/upgrade.md` | Migration and release artifact verification steps. | | Incident response | `docs/runbooks/incident-response.md` | Secrets, tenant, object-store, signing, provider, and package boundaries. | +| Key rotation | `docs/runbooks/key-rotation.md` | Credential and signing-provider rotation boundaries. | | Capacity and failure modes | `docs/reference/capacity-and-failures.md` and `docs/reference/benchmark-results.md` | Benchmark results are narrow and local. | | Security reporting | `SECURITY.md` | Repository settings for private reporting must be verified on GitHub. | | Support expectations | `SUPPORT.md` | Public support boundaries and sanitized-report rules. | diff --git a/docs/runbooks/key-rotation.md b/docs/runbooks/key-rotation.md new file mode 100644 index 0000000..8194359 --- /dev/null +++ b/docs/runbooks/key-rotation.md @@ -0,0 +1,65 @@ +# Key Rotation Runbook + +Use this runbook when rotating Evydence API keys, collector keys, SSO/session +trust material, customer portal tokens, release signing keys, tenant signing +keys, or external signing-provider credentials. It is an operator procedure, +not a certification, compliance, or secure-release statement. + +## Scope + +Repository-owned behavior can revoke, replace, and audit Evydence-managed +credentials. Operator-owned infrastructure remains outside repository control: +identity-provider policy, KMS/HSM key custody, object-store credentials, +GitHub/GitLab secrets, branch protection, and incident notifications. + +## Before Rotation + +1. Identify the credential class and affected tenant, collector, release, + package, or provider boundary. +2. Preserve current release, audit-chain, package, and verification evidence. +3. Decide whether rotation is routine, suspected exposure, confirmed exposure, + provider compromise, or operator policy change. +4. Pause affected automation if the old credential may still be used. +5. Prepare a rollback or forward-fix plan. For suspected compromise, prefer + revocation plus replacement over rollback. + +## Rotation Steps + +| Credential | Repository-owned step | Operator-owned step | +| --- | --- | --- | +| API key | Create a new scoped key, update callers, revoke the old key, and verify audit entries. | Remove the old secret from CI, shell history, secret managers, and runbooks. | +| Collector key | Create or update the collector-scoped key, restart the collector, and verify last-seen metadata. | Rotate provider-side CI secrets and pin the collector version used by jobs. | +| SSO/session trust | Revoke sessions and update configured trust material. | Rotate provider certificates, client credentials, group mappings, and session policy. | +| Customer portal token | Expire old package access, issue a new scoped token, and verify package access records. | Notify the recipient through an approved private channel. | +| Tenant signing key | Rotate the tenant signing key, keep historical public material, and verify valid-at-signing behavior. | Review custody policy and provider access for private signing material. | +| Release signing key | Generate a new release signing key, publish the new public key, and sign the next release manifest. | Protect the private key in the release workflow secret store. | +| KMS/HSM provider credential | Disable the old provider credential and record signing-provider verification receipts. | Rotate provider IAM, HSM partitions, network access, and audit logs. | + +## Verification + +After rotation: + +1. Verify the affected actor can perform only the expected scoped operations. +2. Verify the old key, token, session, or provider credential is rejected. +3. Run the relevant package, release bundle, or audit-chain verification. +4. Check logs and metrics for authentication failures without recording the + supplied secret value. +5. Record the rotation reason, actor, time, affected IDs, and residual + limitations. + +For release artifacts, verify the manifest and signature with +[Release signing](../release-signing.md). For customer packages, use +[Review a customer package](../how-to/review-customer-package.md). For +production readiness gates, use [Release validation](../reference/release-validation.md). + +## Failure Handling + +- If the new credential fails, keep the old credential revoked when exposure is + suspected and issue a corrected replacement. +- If historical signatures fail, do not rewrite past evidence. Record a + verification failure and investigate valid-at-signing semantics. +- If a provider cannot prove custody or revocation, keep the affected profile + marked as a limitation until provider evidence is available. +- Do not place replacement secrets, private keys, bearer tokens, database URLs, + or raw evidence payloads in public issues, support requests, logs, or + customer packages. diff --git a/docs/runbooks/object-store-recovery.md b/docs/runbooks/object-store-recovery.md new file mode 100644 index 0000000..552c298 --- /dev/null +++ b/docs/runbooks/object-store-recovery.md @@ -0,0 +1,86 @@ +# Object Store Recovery Runbook + +Use this runbook when raw evidence payloads, customer package exports, release +artifacts, or object metadata may be missing, corrupted, incorrectly scoped, or +restored from the wrong point in time. It is an operator recovery guide, not a +disaster-recovery guarantee. + +## Scope + +PostgreSQL stores metadata and object references. Object storage stores raw +payload bytes and package/export bytes. A trustworthy recovery must restore the +database and object storage as one logical unit. + +Repository-owned checks can verify tenant-prefixed object keys, expected +payload hashes, backup-manifest consistency, release-bundle verification, and +package verification. Operator-owned checks must cover provider snapshots, +bucket policy, object-lock/WORM configuration, IAM, encryption, lifecycle, and +regional availability. + +## Triage + +1. Preserve the failing verification output and relevant request IDs. +2. Do not regenerate or overwrite historical evidence to hide a missing object. +3. Pause affected API writes and worker jobs if database/object-store pairing + may be inconsistent. +4. Identify affected tenant IDs, object prefixes, evidence IDs, package IDs, + release IDs, and backup timestamps. +5. Confirm whether the failure is missing object, digest mismatch, wrong + tenant prefix, wrong bucket/prefix, permission denial, provider outage, or + metadata drift. + +## Recovery Procedure + +1. Restore the object-store bucket or tenant prefix from the backup matching + the PostgreSQL restore point. +2. If the database was also restored, apply migrations for the Evydence release + being recovered. +3. Start one API writer and the required worker replicas. +4. Verify `/v1/ready`. +5. Verify the latest backup manifest and representative release bundles, + evidence payload hashes, readiness reports, and customer packages. +6. Resume worker jobs only after digest checks pass for the affected payloads. +7. Record object-store backup ID, database backup ID, restored prefixes, + verification results, failed objects, and limitations. + +## Repository-Owned Checks + +Use the local rehearsal for non-sensitive restore mechanics: + +```sh +make restore-rehearsal-check +``` + +Use package verification for customer package fixtures or exports: + +```sh +go run ./cmd/evydence package verify \ + --archive examples/end-to-end-release-evidence/sample-customer-package.zip \ + --expected-package-id csp_example \ + --expected-product-id prod_example \ + --expected-release-id rel_example +``` + +For a live deployment, use equivalent API verification endpoints and retain +sanitized outputs with backup evidence. Do not paste object keys, raw payload +bytes, bearer tokens, private keys, database URLs, or customer data into public +channels. + +## Forward Fix Or Restore + +Prefer restoring the correct object bytes when historical evidence is missing +or mismatched. If an object cannot be recovered, do not mutate historical +evidence. Record the missing object as a verification failure, create new +evidence for any replacement payload, regenerate affected packages, and include +the limitation in customer-facing reports. + +## Evidence To Keep + +- Database backup identifier and restore timestamp. +- Object-store backup identifier, bucket, prefix, and restore timestamp. +- Evydence release tag, commit, OpenAPI checksum, and migration checksum. +- Backup manifest and verification output. +- List of affected object refs or evidence IDs, sanitized for sharing. +- Package, bundle, readiness, and audit-chain verification results. +- Operator notes about provider-side IAM, encryption, lifecycle, object lock, + and retention assumptions. From 2735565e1d8c7afad88811c71856a97f6e562a0b Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 19:06:07 +0300 Subject: [PATCH 265/287] docs(upgrade): define compatibility policy --- Makefile | 5 ++ docs/README.md | 1 + docs/operator-overview.md | 3 +- docs/reference/source-of-truth.md | 2 +- .../reference/upgrade-compatibility-policy.md | 76 +++++++++++++++++++ docs/runbooks/upgrade.md | 15 ++-- 6 files changed, 95 insertions(+), 7 deletions(-) create mode 100644 docs/reference/upgrade-compatibility-policy.md diff --git a/Makefile b/Makefile index 7ed53ec..7cc3658 100644 --- a/Makefile +++ b/Makefile @@ -163,6 +163,7 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and @test -f docs/reference/stable-v0.1.0-exit-criteria.md @test -f docs/reference/external-controls-matrix.md @test -f docs/reference/production-gate-troubleshooting.md + @test -f docs/reference/upgrade-compatibility-policy.md @test -f docs/reference/release-candidate.md @test -f docs/reference/release-evidence-index.md @test -f docs/reference/release-notes-template.md @@ -216,6 +217,7 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and "reference/stable-v0.1.0-exit-criteria.md" \ "reference/external-controls-matrix.md" \ "reference/production-gate-troubleshooting.md" \ + "reference/upgrade-compatibility-policy.md" \ "reference/release-candidate.md" \ "reference/release-evidence-index.md" \ "reference/release-notes-template.md" \ @@ -291,6 +293,9 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and @grep -F 'external controls matrix' docs/reference/production-readiness.md docs/kubernetes.md docs/how-to/pilot-deployment-checklist.md >/dev/null @grep -F 'Production gate troubleshooting' docs/reference/production-readiness.md docs/reference/release-validation.md docs/README.md >/dev/null @grep -F 'Stable v0.1.0 exit criteria' docs/reference/production-readiness.md docs/reference/release-validation.md docs/reference/production-exit-review.md docs/reference/roadmap.md docs/README.md >/dev/null + @grep -F 'Upgrade and compatibility policy' docs/runbooks/upgrade.md docs/README.md >/dev/null + @grep -F 'Release candidates may still make breaking API or schema changes' docs/reference/upgrade-compatibility-policy.md >/dev/null + @grep -F 'make migration-compatibility-check' docs/reference/upgrade-compatibility-policy.md >/dev/null @grep -F 'not legal compliance proof' docs/reference/stable-v0.1.0-exit-criteria.md >/dev/null @grep -F 'make public-release-verify TAG=' docs/reference/stable-v0.1.0-exit-criteria.md >/dev/null @grep -F 'one API writer replica' docs/reference/stable-v0.1.0-exit-criteria.md >/dev/null diff --git a/docs/README.md b/docs/README.md index 0d91735..6b595dc 100644 --- a/docs/README.md +++ b/docs/README.md @@ -47,6 +47,7 @@ This documentation is organized by reader task. Implementation claims should be - [Stable v0.1.0 exit criteria](reference/stable-v0.1.0-exit-criteria.md): criteria for moving from release candidate to a stable `v0.1.0` tag. - [External controls matrix](reference/external-controls-matrix.md): owner boundaries for regulated or high-trust self-hosted deployments. - [Production gate troubleshooting](reference/production-gate-troubleshooting.md): safe diagnostics for `make production-check` failures. +- [Upgrade and compatibility policy](reference/upgrade-compatibility-policy.md): supported upgrade paths, migration expectations, and API compatibility rules. - [Release candidate checklist](reference/release-candidate.md): required evidence before tagging a controlled self-hosted release candidate. - [Release evidence index](reference/release-evidence-index.md): release artifact map, generation commands, and verification commands. - [Release notes template](reference/release-notes-template.md): checked wording used by release-candidate packaging when a tag-specific note file is absent. diff --git a/docs/operator-overview.md b/docs/operator-overview.md index 8c8d753..741cf8c 100644 --- a/docs/operator-overview.md +++ b/docs/operator-overview.md @@ -23,7 +23,8 @@ beyond evaluation. [Production gate troubleshooting](reference/production-gate-troubleshooting.md) with sanitized logs. 5. Rehearse [Backup and restore](runbooks/backup-restore.md), follow the - [Upgrade runbook](runbooks/upgrade.md), keep + [Upgrade runbook](runbooks/upgrade.md) and + [Upgrade compatibility policy](reference/upgrade-compatibility-policy.md), keep [Incident response](runbooks/incident-response.md) ready, and prepare [Key rotation](runbooks/key-rotation.md) plus [Object store recovery](runbooks/object-store-recovery.md). diff --git a/docs/reference/source-of-truth.md b/docs/reference/source-of-truth.md index f1c6294..a4d25b1 100644 --- a/docs/reference/source-of-truth.md +++ b/docs/reference/source-of-truth.md @@ -21,7 +21,7 @@ product-boundary language across the docs. | Maintainer review ownership | `CODEOWNERS` and `docs/reference/maintainer-review-policy.md` | Branch protection or repository rules must enforce this before it is a merge gate. | | Roadmap and cadence | `docs/reference/roadmap.md` | Public roadmap, supported release line, and cadence expectations. | | Backup/restore | `docs/runbooks/backup-restore.md` and `docs/runbooks/object-store-recovery.md` | Operator rehearsal steps, object-store recovery, and evidence to keep. | -| Upgrade | `docs/runbooks/upgrade.md` | Migration and release artifact verification steps. | +| Upgrade | `docs/runbooks/upgrade.md` and `docs/reference/upgrade-compatibility-policy.md` | Migration, release artifact verification, supported paths, and API compatibility. | | Incident response | `docs/runbooks/incident-response.md` | Secrets, tenant, object-store, signing, provider, and package boundaries. | | Key rotation | `docs/runbooks/key-rotation.md` | Credential and signing-provider rotation boundaries. | | Capacity and failure modes | `docs/reference/capacity-and-failures.md` and `docs/reference/benchmark-results.md` | Benchmark results are narrow and local. | diff --git a/docs/reference/upgrade-compatibility-policy.md b/docs/reference/upgrade-compatibility-policy.md new file mode 100644 index 0000000..13fb72d --- /dev/null +++ b/docs/reference/upgrade-compatibility-policy.md @@ -0,0 +1,76 @@ +# Upgrade And Compatibility Policy + +This reference defines upgrade expectations for Evydence release candidates and +future stable releases. It is an operator compatibility policy, not legal +compliance proof, certification, complete SBOM proof, authoritative scanner +coverage, or a secure-release guarantee. + +## Supported Upgrade Paths + +| Source | Target | Policy | +| --- | --- | --- | +| `v0.1.0-rc.N` | later `v0.1.0-rc.M` | Supported after reading release notes, verifying release artifacts, backing up PostgreSQL and object storage together, and applying all committed migrations. | +| `v0.1.0-rc.N` | stable `v0.1.0` | Supported only after the stable exit criteria pass for the promoted candidate. | +| stable `v0.1.0` | later patch release | Intended to be forward-compatible for `/v1` API clients and migration history unless release notes document a security or correctness exception. | +| any release | older release | Not a normal upgrade path. Restore the matching PostgreSQL and object-store backups together instead of trying to run old binaries against newer data. | + +Operators should upgrade one release line at a time. Do not skip release notes, +OpenAPI checksums, migration checksums, backup manifests, or production-check +evidence. + +## Migration Expectations + +- Migrations are forward-only release evidence. +- Do not edit committed migration history. +- Apply all committed migrations before starting API or worker processes. +- Production startup must fail when committed migrations are pending unless an + operator-controlled migration job has already applied them. +- `make migration-compatibility-check` verifies that every committed migration + prefix can upgrade to the current schema in a disposable PostgreSQL schema. +- Rollback after a migration writes new state requires restoring the matching + PostgreSQL and object-store backups together. + +## API Compatibility + +The public API is `/v1`. Within a stable release line: + +- existing operation IDs, paths, required scopes, idempotency requirements, and + response envelope shapes should remain compatible; +- new optional request fields, response fields, query filters, and endpoints + may be added; +- errors continue to use RFC 9457 Problem Details with stable `code` and + `request_id` fields; +- secrets, token hashes, private keys, raw evidence payload bytes, and + object-store paths must not become public response fields. + +Release candidates may still make breaking API or schema changes when needed +for correctness, tenant isolation, evidence integrity, safe error handling, or +security. Breaking changes must be documented in release notes, reflected in +`openapi.yaml`, and covered by `make openapi-check`. + +## Data And Evidence Compatibility + +- Historical evidence, audit entries, vulnerability decisions, approvals, + release bundles, package records, and lifecycle events remain append-only. +- Corrections use supersession, amendments, redaction events, tombstones, + replacement packages, or new verification receipts rather than silent edits. +- Parser versions, schema versions, and package versions must be retained in + stored records so old evidence can be interpreted after upgrades. +- If a new release cannot interpret older evidence safely, release notes must + document the limitation and the affected verification path. + +## Pre-Upgrade Checklist + +Before changing binaries, images, Helm values, or migrations: + +1. Verify the target release artifacts and signed manifest. +2. Read release notes and this policy. +3. Back up PostgreSQL and object storage together. +4. Verify or generate a backup manifest. +5. Confirm the target still supports one API writer replica unless a later + reviewed design explicitly changes that contract. +6. Confirm production secrets are externalized and local plaintext signing-key + mode is not used in production. + +For the command-oriented procedure, use +[Upgrade runbook](../runbooks/upgrade.md). diff --git a/docs/runbooks/upgrade.md b/docs/runbooks/upgrade.md index ada5d71..3766f3c 100644 --- a/docs/runbooks/upgrade.md +++ b/docs/runbooks/upgrade.md @@ -4,17 +4,22 @@ Use this runbook when moving a self-hosted Evydence deployment to a new release candidate or release. It is a technical upgrade guide, not an assurance or certification statement. +Read [Upgrade and compatibility policy](../reference/upgrade-compatibility-policy.md) +before changing binaries, images, Helm values, or migrations. + ## Before Upgrade 1. Read the release notes and known limitations for the target version. -2. Verify release artifacts: +2. Review the supported upgrade path and breaking-change notes in the + compatibility policy. +3. Verify release artifacts: `SHA256SUMS`, signed release manifest, OpenAPI checksum, migration checksum, release SBOM metadata, and release provenance metadata. -3. Back up PostgreSQL and object storage together. -4. Generate and verify a backup manifest. -5. Confirm the target profile still uses one API writer replica unless a later +4. Back up PostgreSQL and object storage together. +5. Generate and verify a backup manifest. +6. Confirm the target profile still uses one API writer replica unless a later release explicitly documents a reviewed multi-writer design. -6. Check that production secrets are externalized and that local plaintext +7. Check that production secrets are externalized and that local plaintext signing-key mode is not used in production. ## Upgrade From e86f8600273fc90f47a28e439d4bba02de281622 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 19:07:50 +0300 Subject: [PATCH 266/287] docs(license): add decision table --- COMMERCIAL.md | 17 +++++++++++++++++ Makefile | 3 +++ docs/README.md | 2 +- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/COMMERCIAL.md b/COMMERCIAL.md index b6d9377..e6c3f7e 100644 --- a/COMMERCIAL.md +++ b/COMMERCIAL.md @@ -12,6 +12,23 @@ deployments, or other contexts where AGPL obligations are not suitable. This is not legal advice. Have counsel review AGPL and any commercial agreement before relying on it. +## License Decision Table + +This table is a practical routing aid, not legal advice. + +| Situation | Likely path to review | Why | +| --- | --- | --- | +| Evaluating Evydence locally, reading source, or running non-production tests | Public `AGPL-3.0-only` license may be enough if your use complies with AGPL. | The public repository remains available under AGPL. | +| Self-hosting Evydence for an internal team that can satisfy AGPL obligations | Public `AGPL-3.0-only` plus operator review may be enough. | You keep the public-license obligations and run your own deployment. | +| Modifying Evydence for a network service where AGPL source-availability obligations are acceptable | Public `AGPL-3.0-only` may be enough after counsel review. | AGPL is designed to preserve source availability for modified network services. | +| Embedding Evydence into proprietary products, private SaaS, closed appliances, or closed internal platforms where AGPL obligations do not fit | Discuss a commercial license exception. | A written exception can grant extra permission for a defined organization, product, deployment, or distribution model. | +| Needing private deployment review, upgrade planning, release evidence review, or integration support | Discuss commercial support. | Support scope, response expectations, and deliverables should be written down before relying on them. | +| Needing legal compliance conclusions, certification, secure-release guarantees, complete SBOM proof, or authoritative vulnerability results | Evydence is not the right source for that conclusion. | Evydence organizes technical evidence and limitations; legal, certification, audit, and security conclusions require separate review. | + +For contribution rights, see [Contributing](CONTRIBUTING.md). For support +boundaries, see [Support](SUPPORT.md). For decision authority and product +language rules, see [Governance](GOVERNANCE.md). + ## Paid Options | Offer | Customer hosts? | Evydence hosts? | Notes | diff --git a/Makefile b/Makefile index 7cc3658..32bb4bd 100644 --- a/Makefile +++ b/Makefile @@ -89,6 +89,9 @@ meta-check: ## Validate root legal, governance, support, and release-evidence me @grep -F 'GNU AFFERO GENERAL PUBLIC LICENSE' LICENSE >/dev/null @grep -F 'AGPL-3.0-only' COMMERCIAL.md >/dev/null @grep -F 'Commercial license exceptions' COMMERCIAL.md >/dev/null + @grep -F 'License Decision Table' COMMERCIAL.md >/dev/null + @grep -F 'This table is a practical routing aid, not legal advice.' COMMERCIAL.md >/dev/null + @grep -F 'Discuss a commercial license exception' COMMERCIAL.md >/dev/null @grep -F 'contributor license agreement' CONTRIBUTING.md >/dev/null @grep -F 'raw evidence payloads' SECURITY.md >/dev/null @grep -F 'release evidence artifacts' SUPPORT.md >/dev/null diff --git a/docs/README.md b/docs/README.md index 6b595dc..219258a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -64,7 +64,7 @@ This documentation is organized by reader task. Implementation claims should be ## Project Metadata - [License](../LICENSE): `AGPL-3.0-only` public license text. -- [Commercial licensing](../COMMERCIAL.md): commercial license exceptions, self-hosted support, release evidence packages, deployment review, and custom integration support. +- [Commercial licensing](../COMMERCIAL.md): license decision table, commercial license exceptions, self-hosted support, release evidence packages, deployment review, and custom integration support. - [Design partner pilot](commercial/design-partner-pilot.md): narrow paid pilot shape for one self-hosted release evidence workflow. - [Product landing copy](commercial/product-landing-copy.md): conservative reusable positioning for README, website, outreach, or pilot materials. - [Category comparison](commercial/category-comparison.md): fair positioning against scanners, SBOM inventory tools, broad GRC, trust centers, and scripts. From 21a4f59a0136aa54a82e2ac49020dc76186dd4fa Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 19:10:07 +0300 Subject: [PATCH 267/287] docs(contributing): add first contribution path --- CONTRIBUTING.md | 32 ++++++++++++++++++++++++++++++++ Makefile | 3 +++ 2 files changed, 35 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6b614e9..257b2ac 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,6 +18,38 @@ Do not submit code, docs, tests, schemas, generated artifacts, provider fixtures, or release evidence unless you have the right to license them to the project under terms compatible with this model. +## First Contribution Path + +Small contributions are welcome when they preserve the project boundaries. Good +starter contributions are: + +- typo fixes in documentation; +- broken link fixes; +- clearer command examples that point back to canonical docs; +- non-sensitive fixture improvements; +- issue reports with sanitized reproduction steps; +- small docs updates that remove overstated compliance, certification, + complete-SBOM, scanner-authority, or secure-release language. + +Before opening a first pull request: + +1. Open or reference an issue for anything larger than a typo or broken link. +2. Keep the change scoped to one topic. +3. Avoid generated artifacts unless the documented project command produced + them and the change requires them. +4. Run `make docs-check` for docs-only changes. Run `make finalize` when code, + examples, OpenAPI, deployment files, SDKs, or release behavior are touched. +5. Expect a contributor license agreement before any substantive change is + merged. + +Issue reports do not need a contributor license agreement, but they must be +safe to share. Include sanitized commands, versions, error codes, and expected +versus actual behavior. Do not include tenant names, customer names, raw +evidence payloads, object-store paths, API keys, collector keys, bearer tokens, +session tokens, portal tokens, private keys, provider credentials, database +URLs, local backups, unpublished customer packages, or release signing +material. + ## Development Rules Before opening a change: diff --git a/Makefile b/Makefile index 32bb4bd..cd93a5d 100644 --- a/Makefile +++ b/Makefile @@ -93,6 +93,9 @@ meta-check: ## Validate root legal, governance, support, and release-evidence me @grep -F 'This table is a practical routing aid, not legal advice.' COMMERCIAL.md >/dev/null @grep -F 'Discuss a commercial license exception' COMMERCIAL.md >/dev/null @grep -F 'contributor license agreement' CONTRIBUTING.md >/dev/null + @grep -F 'First Contribution Path' CONTRIBUTING.md >/dev/null + @grep -F 'Issue reports do not need a contributor license agreement' CONTRIBUTING.md >/dev/null + @grep -F 'object-store paths' CONTRIBUTING.md >/dev/null @grep -F 'raw evidence payloads' SECURITY.md >/dev/null @grep -F 'release evidence artifacts' SUPPORT.md >/dev/null @grep -F 'Security vulnerability' .github/ISSUE_TEMPLATE/config.yml >/dev/null From dcc8613228e87b59ed0f85e10a52ef5a9337f5f4 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 19:14:22 +0300 Subject: [PATCH 268/287] docs(deploy): add hardened reference deployment --- Makefile | 11 ++ docs/README.md | 1 + docs/kubernetes.md | 5 +- docs/operator-overview.md | 7 +- docs/production-hardening.md | 5 + .../hardened-reference-deployment.md | 146 ++++++++++++++++++ docs/reference/production-readiness.md | 2 + docs/reference/source-of-truth.md | 1 + 8 files changed, 175 insertions(+), 3 deletions(-) create mode 100644 docs/reference/hardened-reference-deployment.md diff --git a/Makefile b/Makefile index cd93a5d..4c7807b 100644 --- a/Makefile +++ b/Makefile @@ -167,6 +167,7 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and @test -f docs/reference/production-readiness.md @test -f docs/reference/production-exit-review.md @test -f docs/reference/stable-v0.1.0-exit-criteria.md + @test -f docs/reference/hardened-reference-deployment.md @test -f docs/reference/external-controls-matrix.md @test -f docs/reference/production-gate-troubleshooting.md @test -f docs/reference/upgrade-compatibility-policy.md @@ -221,6 +222,7 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and "reference/production-readiness.md" \ "reference/production-exit-review.md" \ "reference/stable-v0.1.0-exit-criteria.md" \ + "reference/hardened-reference-deployment.md" \ "reference/external-controls-matrix.md" \ "reference/production-gate-troubleshooting.md" \ "reference/upgrade-compatibility-policy.md" \ @@ -305,6 +307,14 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and @grep -F 'not legal compliance proof' docs/reference/stable-v0.1.0-exit-criteria.md >/dev/null @grep -F 'make public-release-verify TAG=' docs/reference/stable-v0.1.0-exit-criteria.md >/dev/null @grep -F 'one API writer replica' docs/reference/stable-v0.1.0-exit-criteria.md >/dev/null + @grep -F 'single API writer replica' docs/reference/hardened-reference-deployment.md >/dev/null + @grep -F 'scalable worker replicas' docs/reference/hardened-reference-deployment.md >/dev/null + @grep -F 'external PostgreSQL' docs/reference/hardened-reference-deployment.md >/dev/null + @grep -F 'external S3/MinIO-compatible object storage' docs/reference/hardened-reference-deployment.md >/dev/null + @grep -F 'request body limits' docs/reference/hardened-reference-deployment.md >/dev/null + @grep -F 'make production-check' docs/reference/hardened-reference-deployment.md >/dev/null + @grep -F 'not legal compliance proof' docs/reference/hardened-reference-deployment.md >/dev/null + @grep -F 'Hardened reference deployment' docs/README.md docs/operator-overview.md docs/kubernetes.md docs/production-hardening.md docs/reference/production-readiness.md docs/reference/source-of-truth.md >/dev/null @grep -F 'Required: object paths are tenant-prefixed' docs/how-to/pilot-deployment-checklist.md >/dev/null @grep -F 'Required: public API access is behind TLS' docs/how-to/pilot-deployment-checklist.md >/dev/null @test -f docs/commercial/design-partner-pilot.md @@ -403,6 +413,7 @@ deploy-check: ## Validate deployment and air-gap skeletons exist @grep -F 'evydence-worker' deploy/helm/evydence/templates/deployment-worker.yaml >/dev/null @grep -F 'healthcheck' deploy/helm/evydence/values.yaml >/dev/null @grep -F 'single API writer replica' docs/kubernetes.md >/dev/null + @grep -F 'Hardened reference deployment' docs/kubernetes.md docs/reference/hardened-reference-deployment.md >/dev/null @grep -F 'EVYDENCE_API_WRITER_MODE: single' compose.production-like.yml >/dev/null @grep -F 'EVYDENCE_PRINT_BOOTSTRAP_SECRET: "false"' compose.production-like.yml >/dev/null @grep -F 'evydence-migrate ./cmd/evydence-migrate' Dockerfile >/dev/null diff --git a/docs/README.md b/docs/README.md index 219258a..b67483a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -45,6 +45,7 @@ This documentation is organized by reader task. Implementation claims should be - [Production readiness](reference/production-readiness.md): self-hosted production profiles, production gates, and exit criteria. - [Production exit review](reference/production-exit-review.md): current release-positioning decision and unresolved blockers. - [Stable v0.1.0 exit criteria](reference/stable-v0.1.0-exit-criteria.md): criteria for moving from release candidate to a stable `v0.1.0` tag. +- [Hardened reference deployment](reference/hardened-reference-deployment.md): controlled self-hosted topology with external PostgreSQL, object storage, TLS, secrets, backups, monitoring, and signing. - [External controls matrix](reference/external-controls-matrix.md): owner boundaries for regulated or high-trust self-hosted deployments. - [Production gate troubleshooting](reference/production-gate-troubleshooting.md): safe diagnostics for `make production-check` failures. - [Upgrade and compatibility policy](reference/upgrade-compatibility-policy.md): supported upgrade paths, migration expectations, and API compatibility rules. diff --git a/docs/kubernetes.md b/docs/kubernetes.md index 7368642..2ad5971 100644 --- a/docs/kubernetes.md +++ b/docs/kubernetes.md @@ -23,6 +23,9 @@ The chart does not create databases, buckets, KMS keys, or secrets. Use the [external controls matrix](reference/external-controls-matrix.md) to track which of those production controls are repo-owned, operator-owned, provider-owned, or legal/review-owned for the deployment. +Use [Hardened reference deployment](reference/hardened-reference-deployment.md) +for the full self-hosted topology, backup pairing, ingress/TLS, monitoring, +and signing review. ## Create Secrets @@ -94,4 +97,4 @@ Rollback does not roll back PostgreSQL data or object-store payloads. Keep datab ## Production Notes -Production deployments should use external PostgreSQL, S3/MinIO-compatible object storage, TLS ingress, backup automation, network access controls, and external signing. Current production guidance uses a single API writer replica; the chart passes `EVYDENCE_API_WRITER_MODE=single` and `EVYDENCE_API_WRITER_REPLICAS=1`, production API startup rejects unsupported writer modes or replica counts above one, then enforces the stance with a PostgreSQL advisory writer lease. Worker replicas can scale independently through PostgreSQL outbox row locking. See [Production hardening review](production-hardening.md), [Production readiness](reference/production-readiness.md), and [Configuration](reference/configuration.md). +Production deployments should use external PostgreSQL, S3/MinIO-compatible object storage, TLS ingress, backup automation, network access controls, and external signing. Current production guidance uses a single API writer replica; the chart passes `EVYDENCE_API_WRITER_MODE=single` and `EVYDENCE_API_WRITER_REPLICAS=1`, production API startup rejects unsupported writer modes or replica counts above one, then enforces the stance with a PostgreSQL advisory writer lease. Worker replicas can scale independently through PostgreSQL outbox row locking. See [Hardened reference deployment](reference/hardened-reference-deployment.md), [Production hardening review](production-hardening.md), [Production readiness](reference/production-readiness.md), and [Configuration](reference/configuration.md). diff --git a/docs/operator-overview.md b/docs/operator-overview.md index 741cf8c..6d1f34c 100644 --- a/docs/operator-overview.md +++ b/docs/operator-overview.md @@ -19,10 +19,12 @@ beyond evaluation. 3. Use [Kubernetes deployment](kubernetes.md) or [Air-gapped installation](air-gapped.md) only after the package and release evidence have been verified. -4. Run the gates in [Release validation](reference/release-validation.md) and +4. Review the [Hardened reference deployment](reference/hardened-reference-deployment.md) + before accepting pilot or internal production traffic. +5. Run the gates in [Release validation](reference/release-validation.md) and [Production gate troubleshooting](reference/production-gate-troubleshooting.md) with sanitized logs. -5. Rehearse [Backup and restore](runbooks/backup-restore.md), follow the +6. Rehearse [Backup and restore](runbooks/backup-restore.md), follow the [Upgrade runbook](runbooks/upgrade.md) and [Upgrade compatibility policy](reference/upgrade-compatibility-policy.md), keep [Incident response](runbooks/incident-response.md) ready, and prepare @@ -47,6 +49,7 @@ beyond evaluation. - [Observability](reference/observability.md) - [Capacity and failure modes](reference/capacity-and-failures.md) +- [Hardened reference deployment](reference/hardened-reference-deployment.md) - [External controls matrix](reference/external-controls-matrix.md) - [Stable v0.1.0 exit criteria](reference/stable-v0.1.0-exit-criteria.md) - [Source of truth](reference/source-of-truth.md) diff --git a/docs/production-hardening.md b/docs/production-hardening.md index 42fb202..61652be 100644 --- a/docs/production-hardening.md +++ b/docs/production-hardening.md @@ -19,6 +19,11 @@ These checks are enforced by API startup. See [Configuration](reference/configur ## Deployment Checklist +Use [Hardened reference deployment](reference/hardened-reference-deployment.md) +for the controlled self-hosted architecture and +[Pilot deployment checklist](how-to/pilot-deployment-checklist.md) for the +copy-paste go/no-go record. + - PostgreSQL is external, backed up, monitored, and restored in a test environment. - Object storage is external S3/MinIO-compatible storage with tenant-prefixed paths, encryption, lifecycle policy, and retention/object-lock policy where required. - S3/MinIO object-retention policy verification has been run for required tenant prefixes, and records show bucket versioning, default object-lock mode/duration, sample object retention, and sample object legal-hold checks where those controls are required, with documented limitations. diff --git a/docs/reference/hardened-reference-deployment.md b/docs/reference/hardened-reference-deployment.md new file mode 100644 index 0000000..0cc072c --- /dev/null +++ b/docs/reference/hardened-reference-deployment.md @@ -0,0 +1,146 @@ +# Hardened Reference Deployment + +This reference describes the supported controlled self-hosted deployment shape +for Evydence release candidates. Use it to review a deployment before pilot or +internal production use. It is not legal compliance proof, certification, +complete SBOM proof, authoritative scanner coverage, or a secure-release +guarantee. + +The narrow supported topology is: + +- one API writer replica; +- scalable worker replicas using PostgreSQL outbox locking; +- external PostgreSQL as the durable source of truth; +- external S3/MinIO-compatible object storage for raw payloads and generated + packages; +- TLS terminated at a reverse proxy or Kubernetes ingress; +- deployment secrets supplied by an operator-controlled secret manager; +- external signing mode or an operator-controlled signing provider; +- paired database and object-store backups with restore rehearsal evidence; +- authenticated metrics, admin, audit, and package-access surfaces. + +Use the [pilot deployment checklist](../how-to/pilot-deployment-checklist.md) +for the copy-paste go/no-go record and the +[external controls matrix](external-controls-matrix.md) to assign operator, +provider, repo, and review responsibilities. + +## Reference Topology + +| Layer | Required Shape | Operator Evidence To Keep | +| --- | --- | --- | +| API | One API writer replica with `ENV=production`, `EVYDENCE_API_WRITER_MODE=single`, and `EVYDENCE_API_WRITER_REPLICAS=1`. | Helm values or deployment manifest, startup log showing production mode, and `/v1/ready` result. | +| Worker | One or more worker replicas with the same database and object-store config as the API. | Worker rollout status, outbox backlog metrics, retry/failure counters, and parser/signing/report job evidence. | +| PostgreSQL | External PostgreSQL, not an application sidecar, with migrations applied before traffic. | Database version, migration version, backup schedule, restore rehearsal output, access policy, and encryption setting. | +| Object storage | External S3/MinIO-compatible object storage with tenant-prefixed keys. | Bucket policy, versioning or retention setting, encryption setting, lifecycle policy, object-lock receipt where required, and object/database backup pairing. | +| Ingress/TLS | TLS at the edge with body-size limits matched to expected uploads. | Ingress or reverse-proxy config, certificate owner, request body limit, timeout, redaction, and rate-limit evidence. | +| Secrets | Database URL, API-key pepper, object-store credentials, signing credentials, SSO secrets, and portal secrets from deployment secrets. | Secret-manager path or sealed-secret reference, rotation owner, and proof that secrets are not rendered into logs or manifests. | +| Signing | `EVYDENCE_SIGNING_KEY_MODE=external`, `aws-kms`, `gcp-kms`, `azure-key-vault`, or gateway-backed `pkcs11-hsm`. | Provider key ID, signing receipt, rotation plan, custody review, and limitations for the selected provider. | +| Monitoring | Authenticated metrics, readiness checks, safe logs, and alert routing. | Prometheus scrape config, dashboard link, alert route, and sanitized incident runbook. | + +## Helm Values + +For Kubernetes, start from `deploy/helm/evydence/values.yaml` and set an +explicit image tag or digest. The chart intentionally defaults +`api.replicas` to `1` and `api.writerMode` to `single`. + +```sh +helm upgrade --install evydence ./deploy/helm/evydence \ + --set image.repository=ghcr.io/aatuh/evydence \ + --set image.tag='@sha256:' \ + --set api.replicas=1 \ + --set api.writerMode=single \ + --set worker.replicas=2 \ + --set env.objectStore=s3 \ + --set env.s3Endpoint=s3.example.com \ + --set env.s3Bucket=evydence \ + --set ingress.enabled=true \ + --set ingress.host=evydence.example.com \ + --set ingress.tlsSecretName=evydence-tls +``` + +Expected result: + +- Helm renders both API and worker deployments. +- The API deployment uses one writer replica. +- Worker replicas can be scaled to match parser/signing/report load. +- Pods read sensitive values from `existingSecret`, not literal values in the + chart. +- Startup fails closed if production mode uses unsafe defaults. + +## Ingress, TLS, And Upload Limits + +Put the public API behind a reverse proxy or Kubernetes ingress that terminates +TLS. Configure: + +- request body limits for expected evidence, SBOM, VEX, scan, attestation, + package, and bundle uploads; +- connection and response timeouts that account for upload size and object-store + latency; +- edge rate limits for unauthenticated, token-heavy, and upload endpoints; +- header redaction for `Authorization`, cookies, database URLs, object-store + credentials, provider tokens, and API-key material; +- no unauthenticated public access to `/v1/metrics`, `/v1/audit-log`, or + `/v1/admin/instance`. + +Evydence verifies uploaded payload digests and records object references, but +the ingress or reverse proxy remains responsible for TLS certificates, +client-facing rate limits, and raw request-size enforcement. + +## Backup Pairing + +Back up PostgreSQL and object storage from the same recovery point. A database +backup without matching object payloads cannot verify raw evidence hashes after +restore. Object payload backups without matching database rows cannot +reconstruct release, report, and package relationships. + +Keep these records with every deployment backup: + +- Evydence release tag, image digest or binary checksum, OpenAPI checksum, and + migration checksum; +- database backup identifier and completion time; +- object-store backup, replication, or version marker from the same recovery + window; +- signing-provider custody and recovery note; +- restore rehearsal output with audit-chain, release-bundle, package, and + object-digest verification. + +Use [Backup and restore](../runbooks/backup-restore.md) and +[Object store recovery](../runbooks/object-store-recovery.md) for the operator +runbooks. + +## Validation Sequence + +Before accepting pilot or internal production traffic: + +```sh +make deploy-check +make release-acceptance +make production-check +``` + +Expected result: + +- `make deploy-check` validates repository-owned deployment assets and the + single-writer Helm defaults. +- `make release-acceptance` validates release metadata, legal/governance files, + and release-evidence language. +- `make production-check` runs the strict live-PostgreSQL gate with coverage, + migration compatibility, restore rehearsal, release signing smoke test, and + production-check summary output. + +Complete the [pilot deployment checklist](../how-to/pilot-deployment-checklist.md) +for the target environment. Record any skipped provider checks, missing object +lock, missing KMS/HSM proof, missing SSO provider evidence, or untested restore +procedure as deployment limitations. + +## Boundaries + +Repo-owned checks can verify Evydence code, schemas, release artifacts, Helm +defaults, local restore rehearsals, and generated evidence. They cannot verify +that an operator's cloud account, identity provider, object-store policy, +network, backup tooling, signing provider, or legal/review process is suitable. + +Do not broaden this reference into a multi-writer API HA claim. The supported +self-hosted profile remains a single API writer replica with scalable worker +replicas until multi-writer API concurrency is implemented, tested, and +documented. diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 42a2f80..3d06f7e 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -93,6 +93,8 @@ Known hardening work remains: Use the [external controls matrix](external-controls-matrix.md) to separate repo-owned checks from operator, provider, and legal/review responsibilities before applying these profiles to regulated or high-trust deployments. +Use [Hardened reference deployment](hardened-reference-deployment.md) for the +controlled self-hosted topology that these profiles build from. ## HA And Concurrency Contract diff --git a/docs/reference/source-of-truth.md b/docs/reference/source-of-truth.md index a4d25b1..33d24ad 100644 --- a/docs/reference/source-of-truth.md +++ b/docs/reference/source-of-truth.md @@ -13,6 +13,7 @@ product-boundary language across the docs. | Local startup | `docs/tutorials/getting-started.md` | Uses in-process state only. | | Durable operation | `docs/how-to/install-and-operate.md` | Includes PostgreSQL/object storage and production-like Compose rehearsal. | | Kubernetes | `docs/kubernetes.md` | Helm-specific operator interface. | +| Hardened self-hosted topology | `docs/reference/hardened-reference-deployment.md` | One API writer, scalable workers, external PostgreSQL/object storage, TLS, secrets, backups, monitoring, signing, and operator-owned evidence. | | Release validation | `docs/reference/release-validation.md` | Canonical release gate behavior. | | Release-candidate evidence | `docs/reference/release-candidate.md` | Canonical release-candidate artifact checklist. | | Release evidence artifact map | `docs/reference/release-evidence-index.md` | Maps each release artifact to generation and verification commands. | From aa89b0b07baf1b2c43c1dbfb35825181bd921724 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 19:17:29 +0300 Subject: [PATCH 269/287] docs(config): add production environment example --- .gitignore | 1 + .production.env.example | 97 +++++++++++++++++++ Makefile | 13 +++ docs/how-to/install-and-operate.md | 3 + docs/reference/configuration.md | 7 ++ .../hardened-reference-deployment.md | 4 + 6 files changed, 125 insertions(+) create mode 100644 .production.env.example diff --git a/.gitignore b/.gitignore index 40ae042..0c6498d 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ !.env.example !.api.env.example !.test.env.example +!.production.env.example coverage.out bin/ diff --git a/.production.env.example b/.production.env.example new file mode 100644 index 0000000..0f608db --- /dev/null +++ b/.production.env.example @@ -0,0 +1,97 @@ +# Evydence production environment example. +# +# Copy to an untracked deployment-specific file or translate these values into +# your secret manager, Kubernetes Secret, or sealed-secret workflow. Empty +# secret values are intentional: production startup should fail until an +# operator supplies real values. Do not commit rendered production values. + +# Runtime profile +ENV=production +EVYDENCE_ADDR=:8080 +EVYDENCE_POSTGRES_LOAD_MODE=relational_only +EVYDENCE_API_WRITER_MODE=single +EVYDENCE_API_WRITER_REPLICAS=1 +EVYDENCE_BOOTSTRAP_DISABLED=true +EVYDENCE_PRINT_BOOTSTRAP_SECRET=false + +# Required secrets +EVYDENCE_DATABASE_URL= +EVYDENCE_API_KEY_PEPPER= + +# Object storage. Production should use external S3/MinIO-compatible storage, +# not filesystem object storage. +EVYDENCE_OBJECT_STORE=s3 +EVYDENCE_S3_ENDPOINT= +EVYDENCE_S3_BUCKET= +EVYDENCE_S3_REGION= +EVYDENCE_S3_USE_SSL=true +EVYDENCE_S3_ACCESS_KEY_ID= +EVYDENCE_S3_SECRET_ACCESS_KEY= + +# Worker and parser behavior +EVYDENCE_WORKER_POLL_INTERVAL=1s +EVYDENCE_WORKER_BATCH_SIZE=10 +EVYDENCE_WORKER_MAX_PAYLOAD_BYTES=20971520 +EVYDENCE_WORKER_OWNED_PARSER_SIDE_EFFECTS=true + +# Rate limiting. Keep edge/reverse-proxy rate limits as the primary control; +# this in-process limiter is a local safety net keyed by TCP remote address. +EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE=120 + +# Signing. Choose one production signing profile. Do not use local plaintext +# signing-key storage in production. +EVYDENCE_SIGNING_KEY_MODE=external +EVYDENCE_SIGNING_EXECUTOR_URL= +EVYDENCE_SIGNING_EXECUTOR_TOKEN= +EVYDENCE_SIGNING_EXECUTOR_TIMEOUT_SECONDS=10 +EVYDENCE_SIGNING_EXECUTOR_ALLOW_INSECURE_LOCALHOST=false + +# AWS KMS profile. Set EVYDENCE_SIGNING_KEY_MODE=aws-kms to use this path. +EVYDENCE_AWS_REGION= +EVYDENCE_AWS_KMS_KEY_ID= +EVYDENCE_AWS_KMS_SIGNING_ALGORITHM=ECDSA_SHA_256 +EVYDENCE_AWS_KMS_TIMEOUT_SECONDS=10 + +# GCP Cloud KMS profile. Set EVYDENCE_SIGNING_KEY_MODE=gcp-kms to use this path. +EVYDENCE_GCP_KMS_ACCESS_TOKEN= +EVYDENCE_GCP_KMS_KEY_NAME= +EVYDENCE_GCP_KMS_ENDPOINT=https://cloudkms.googleapis.com +EVYDENCE_GCP_KMS_TIMEOUT_SECONDS=10 + +# Azure Key Vault profile. Set EVYDENCE_SIGNING_KEY_MODE=azure-key-vault to use +# this path. +EVYDENCE_AZURE_KEY_VAULT_URL= +EVYDENCE_AZURE_KEY_VAULT_ACCESS_TOKEN= +EVYDENCE_AZURE_KEY_VAULT_KEY_NAME= +EVYDENCE_AZURE_KEY_VAULT_KEY_VERSION= +EVYDENCE_AZURE_KEY_VAULT_ALGORITHM=ES256 +EVYDENCE_AZURE_KEY_VAULT_API_VERSION=7.4 +EVYDENCE_AZURE_KEY_VAULT_TIMEOUT_SECONDS=10 + +# Provider and transparency gateways are optional. Use HTTPS for production. +EVYDENCE_PROVIDER_VALIDATION_GATEWAY_URL= +EVYDENCE_PROVIDER_VALIDATION_GATEWAY_TOKEN= +EVYDENCE_PROVIDER_VALIDATION_GATEWAY_TIMEOUT_SECONDS=10 +EVYDENCE_PROVIDER_VALIDATION_GATEWAY_ALLOW_INSECURE_LOCALHOST=false + +EVYDENCE_TRANSPARENCY_PROOF_GATEWAY_URL= +EVYDENCE_TRANSPARENCY_PROOF_GATEWAY_TOKEN= +EVYDENCE_TRANSPARENCY_PROOF_GATEWAY_TIMEOUT_SECONDS=10 +EVYDENCE_TRANSPARENCY_PROOF_GATEWAY_ALLOW_INSECURE_LOCALHOST=false + +# Direct public transparency fetch tuning when no gateway is configured. +EVYDENCE_TRANSPARENCY_FETCH_TIMEOUT_SECONDS=10 +EVYDENCE_TRANSPARENCY_FETCH_ALLOW_INSECURE_LOCALHOST=false + +# OIDC discovery and UserInfo live validation. HTTP is for localhost tests only. +EVYDENCE_OIDC_DISCOVERY_TIMEOUT_SECONDS=10 +EVYDENCE_OIDC_DISCOVERY_ALLOW_INSECURE_LOCALHOST=false +EVYDENCE_OIDC_USERINFO_TIMEOUT_SECONDS=10 +EVYDENCE_OIDC_USERINFO_ALLOW_INSECURE_LOCALHOST=false + +# Telemetry and diagnostics. Evydence exposes authenticated readiness, +# metrics, audit-log, and admin surfaces; configure scraping, log redaction, +# alert routing, and retention in the deployment platform. +# Do not export raw evidence payloads, bearer tokens, database URLs, private +# keys, object-store credentials, provider credentials, or customer package +# contents. diff --git a/Makefile b/Makefile index 4c7807b..bbb4141 100644 --- a/Makefile +++ b/Makefile @@ -139,6 +139,7 @@ release-truth-check: ## Validate current release metadata against public docs an docs-check: meta-check release-truth-check ## Validate canonical docs exist and avoid forbidden product claims @test -f README.md + @test -f .production.env.example @test -f docs/README.md @test -f docs/buyer-overview.md @test -f docs/operator-overview.md @@ -307,6 +308,18 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and @grep -F 'not legal compliance proof' docs/reference/stable-v0.1.0-exit-criteria.md >/dev/null @grep -F 'make public-release-verify TAG=' docs/reference/stable-v0.1.0-exit-criteria.md >/dev/null @grep -F 'one API writer replica' docs/reference/stable-v0.1.0-exit-criteria.md >/dev/null + @grep -F '!.production.env.example' .gitignore >/dev/null + @grep -F 'ENV=production' .production.env.example >/dev/null + @grep -Fx 'EVYDENCE_DATABASE_URL=' .production.env.example >/dev/null + @grep -Fx 'EVYDENCE_API_KEY_PEPPER=' .production.env.example >/dev/null + @grep -F 'EVYDENCE_OBJECT_STORE=s3' .production.env.example >/dev/null + @grep -F 'EVYDENCE_SIGNING_KEY_MODE=external' .production.env.example >/dev/null + @grep -F 'EVYDENCE_RATE_LIMIT_REQUESTS_PER_MINUTE' .production.env.example >/dev/null + @grep -F 'EVYDENCE_PRINT_BOOTSTRAP_SECRET=false' .production.env.example >/dev/null + @! grep -F 'change-me' .production.env.example >/dev/null + @grep -F 'Telemetry and diagnostics' .production.env.example >/dev/null + @grep -F 'Do not export raw evidence payloads' .production.env.example >/dev/null + @grep -F '.production.env.example' docs/reference/configuration.md docs/how-to/install-and-operate.md docs/reference/hardened-reference-deployment.md >/dev/null @grep -F 'single API writer replica' docs/reference/hardened-reference-deployment.md >/dev/null @grep -F 'scalable worker replicas' docs/reference/hardened-reference-deployment.md >/dev/null @grep -F 'external PostgreSQL' docs/reference/hardened-reference-deployment.md >/dev/null diff --git a/docs/how-to/install-and-operate.md b/docs/how-to/install-and-operate.md index 2f6bc12..e423b7b 100644 --- a/docs/how-to/install-and-operate.md +++ b/docs/how-to/install-and-operate.md @@ -19,6 +19,9 @@ artifact map and exact verification commands. | Production checks | Set `ENV=production`. | Rejects unsafe local defaults before API startup. | Configuration details live in [Configuration](../reference/configuration.md). +For production planning, use `.production.env.example` as a deployment-secret +checklist and translate it into your secret manager or Helm values; do not use +local `.api.env.example` defaults for production. ## Install From The Public Release Candidate diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 2113319..072b937 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -9,6 +9,7 @@ This is the canonical reference for current environment files and runtime variab | `.env.example` | `docker-compose.yml` | Local PostgreSQL and MinIO container credentials. | No | | `.api.env.example` | API, worker, migration command | Local API runtime settings, durable database URL, object storage mode, bootstrap tenant, and local secret printing. | No | | `.test.env.example` | Make targets for live PostgreSQL tests | `EVYDENCE_TEST_DATABASE_URL` and test-only API key pepper. | No | +| `.production.env.example` | Operators translating config into deployment secrets | Production-mode variable checklist with empty secret fields, external object storage, single-writer API settings, rate limiting, signing profiles, and telemetry/diagnostic notes. | No | Copy examples to local untracked files when needed: @@ -19,6 +20,12 @@ cp .test.env.example .test.env The example secrets are placeholders. Replace them before using shared or production-like infrastructure. +For production planning, read `.production.env.example` as a checklist. It is +not intended to be committed after filling values, and the empty required +secret fields are deliberate so production startup fails until an operator +supplies real values through a secret manager, Kubernetes Secret, sealed-secret +process, or equivalent deployment control. + ## Runtime Variables | Variable | Required | Default / Example | Notes | diff --git a/docs/reference/hardened-reference-deployment.md b/docs/reference/hardened-reference-deployment.md index 0cc072c..c2b1e26 100644 --- a/docs/reference/hardened-reference-deployment.md +++ b/docs/reference/hardened-reference-deployment.md @@ -42,6 +42,10 @@ provider, repo, and review responsibilities. For Kubernetes, start from `deploy/helm/evydence/values.yaml` and set an explicit image tag or digest. The chart intentionally defaults `api.replicas` to `1` and `api.writerMode` to `single`. +Use `.production.env.example` as the environment-variable checklist when +translating settings into Kubernetes Secrets or another secret manager; keep +the empty secret fields empty in git and fill them only in the deployment +system. ```sh helm upgrade --install evydence ./deploy/helm/evydence \ From 9f5e79dfd43960168298b79bc89f20790192b7f5 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 19:25:17 +0300 Subject: [PATCH 270/287] test(benchmark): add production-like benchmark evidence --- Makefile | 7 ++ docs/reference/benchmark-results.md | 43 ++++++- docs/reference/capacity-and-failures.md | 11 ++ scripts/production_benchmark_check.sh | 158 ++++++++++++++++++++++++ 4 files changed, 215 insertions(+), 4 deletions(-) create mode 100755 scripts/production_benchmark_check.sh diff --git a/Makefile b/Makefile index bbb4141..16a5ec0 100644 --- a/Makefile +++ b/Makefile @@ -280,6 +280,10 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and @grep -F 'Production Check' README.md docs/reference/release-evidence-index.md >/dev/null @grep -F 'coverage.out' README.md docs/reference/release-evidence-index.md >/dev/null @grep -F 'release-check-summary.txt' README.md docs/reference/release-evidence-index.md >/dev/null + @test -x scripts/production_benchmark_check.sh + @grep -F 'production_benchmark_check.sh' docs/reference/benchmark-results.md >/dev/null + @grep -F 'tmp/production-benchmark/production-benchmark-summary.json' docs/reference/benchmark-results.md >/dev/null + @grep -F 'local regression benchmark' docs/reference/benchmark-results.md >/dev/null @grep -F 'Implemented-But-Partial Areas' docs/reference/capability-map.md >/dev/null @grep -F 'VEX/manual' README.md >/dev/null @test -f docs/assets/package-viewer-preview.svg @@ -487,7 +491,10 @@ black-box-demo-check: ## Run live PostgreSQL black-box API/worker demo; requires benchmark-check: ## Run the checked app-layer release evidence benchmark @$(GO) test ./internal/app -bench BenchmarkReleaseEvidenceIngestion -benchtime=100x -run '^$$' -benchmem + @if [ -n "$$EVYDENCE_TEST_DATABASE_URL" ]; then scripts/production_benchmark_check.sh; else echo "EVYDENCE_TEST_DATABASE_URL not set; skipping production black-box benchmark"; fi @grep -F 'BenchmarkReleaseEvidenceIngestion' docs/reference/benchmark-results.md >/dev/null + @grep -F 'production_benchmark_check.sh' docs/reference/benchmark-results.md >/dev/null + @grep -F 'evydence-production-benchmark.v1.0.0' docs/reference/benchmark-results.md >/dev/null @grep -F 'API writer replicas: `1`' docs/reference/capacity-and-failures.md >/dev/null package-viewer-check: ## Validate local package viewer and walkthrough diff --git a/docs/reference/benchmark-results.md b/docs/reference/benchmark-results.md index f1ed092..aad4766 100644 --- a/docs/reference/benchmark-results.md +++ b/docs/reference/benchmark-results.md @@ -16,14 +16,29 @@ The project-owned gate is: make benchmark-check ``` -`make production-check` runs this gate before release-candidate packaging -evidence is accepted. +`make benchmark-check` always runs the app-layer benchmark. When +`EVYDENCE_TEST_DATABASE_URL` is set, it also runs: + +```sh +scripts/production_benchmark_check.sh +``` + +The production-like benchmark writes regression-friendly output to: + +```text +tmp/production-benchmark/production-benchmark-summary.json +tmp/production-benchmark/production-benchmark-summary.txt +``` + +The JSON summary uses schema +`evydence-production-benchmark.v1.0.0`. `make production-check` runs this gate +before release-candidate packaging evidence is accepted, and production-check +requires `EVYDENCE_TEST_DATABASE_URL`. ## Current Interpretation The benchmark exercises in-process release evidence creation through the app -service and audit-chain path. It does not include HTTP routing, PostgreSQL, -object storage, signing providers, or worker parser side effects. +service and audit-chain path. Use it to detect obvious local regressions in the core evidence path. For production sizing, run API-level tests against the target PostgreSQL and object @@ -39,6 +54,20 @@ store and record: - failed verification or parser checks; - assumptions and limitations. +The production-like benchmark is based on +`examples/end-to-end-release-evidence/run-local-demo.sh`. It starts the API and +worker against a disposable PostgreSQL schema and filesystem object store, then +exercises HTTP API calls, persistence, API restart, release-readiness reporting, +customer package creation, and audit-chain verification. It records total +scenario wall-clock time, an estimated operation rate for the checked scenario, +demo JSON output count, object file count, object bytes, and explicit +limitations. + +This is still a local regression benchmark. It does not prove S3/MinIO network +latency, live KMS/HSM signing latency, identity-provider latency, registry +behavior, public transparency provider behavior, multi-writer API safety, or +target-environment capacity. + ## Latest Local Result Last recorded local run: @@ -56,6 +85,12 @@ It does not prove HTTP throughput, PostgreSQL throughput, object-store performance, signing-provider latency, parser throughput, or multi-writer API safety. +Last recorded production-like benchmark evidence should be read from +`tmp/production-benchmark/production-benchmark-summary.json` after running +`EVYDENCE_TEST_DATABASE_URL=... make benchmark-check`. Commit or attach that +generated JSON only as release evidence for the exact environment that produced +it; do not treat the local result as a general throughput claim. + ## Current Known Limit The supported production profile remains one API writer replica. Worker replicas diff --git a/docs/reference/capacity-and-failures.md b/docs/reference/capacity-and-failures.md index 53076b4..06fe016 100644 --- a/docs/reference/capacity-and-failures.md +++ b/docs/reference/capacity-and-failures.md @@ -79,3 +79,14 @@ Do not publish broad throughput or scale claims without recording: - payload sizes and evidence mix; - API and worker replica counts; - pass/fail criteria and limitations. + +For a repo-owned local regression benchmark that includes HTTP, PostgreSQL, +filesystem object storage, worker startup, release-readiness reporting, package +creation, and audit-chain verification, run: + +```sh +EVYDENCE_TEST_DATABASE_URL=... make benchmark-check +``` + +The output under `tmp/production-benchmark/` is benchmark evidence for that +disposable environment only. diff --git a/scripts/production_benchmark_check.sh b/scripts/production_benchmark_check.sh new file mode 100755 index 0000000..ea7aa92 --- /dev/null +++ b/scripts/production_benchmark_check.sh @@ -0,0 +1,158 @@ +#!/usr/bin/env sh +set -eu + +repo_root="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)" +cd "$repo_root" + +fail() { + printf '%s\n' "production-benchmark-check: $*" >&2 + exit 2 +} + +if [ -z "${EVYDENCE_TEST_DATABASE_URL:-}" ]; then + fail "EVYDENCE_TEST_DATABASE_URL is required" +fi + +for tool in go jq psql python3 curl; do + if ! command -v "$tool" >/dev/null 2>&1; then + fail "missing required tool: $tool" + fi +done + +workdir="${EVYDENCE_PRODUCTION_BENCHMARK_WORKDIR:-tmp/production-benchmark}" +case "$workdir" in + tmp/*) ;; + *) fail "EVYDENCE_PRODUCTION_BENCHMARK_WORKDIR must stay under tmp/" ;; +esac +case "$workdir" in + *..*|*/.*|.*) fail "EVYDENCE_PRODUCTION_BENCHMARK_WORKDIR must not contain dot segments" ;; +esac + +rm -rf "$workdir" +mkdir -p "$workdir" + +now_ns() { + python3 - <<'PY' +import time +print(time.monotonic_ns()) +PY +} + +started_ns="$(now_ns)" +EVYDENCE_BLACK_BOX_WORKDIR="$workdir/black-box" \ +EVYDENCE_BLACK_BOX_KEEP_ARTIFACTS=1 \ +scripts/black_box_demo_check.sh >"$workdir/black-box.stdout" 2>"$workdir/black-box.stderr" +ended_ns="$(now_ns)" + +python3 - "$workdir" "$started_ns" "$ended_ns" <<'PY' +import json +import os +import subprocess +import sys +from datetime import datetime, timezone +from pathlib import Path + +workdir = Path(sys.argv[1]) +started_ns = int(sys.argv[2]) +ended_ns = int(sys.argv[3]) +duration_ms = round((ended_ns - started_ns) / 1_000_000, 3) +duration_seconds = max((ended_ns - started_ns) / 1_000_000_000, 0.001) + +demo_dir = workdir / "black-box" / "demo" +object_root = workdir / "black-box" / "objects" + +def count_files(root: Path): + if not root.exists(): + return 0, 0 + files = [path for path in root.rglob("*") if path.is_file()] + return len(files), sum(path.stat().st_size for path in files) + +object_files, object_bytes = count_files(object_root) +demo_json_files = len(list(demo_dir.glob("*.json"))) if demo_dir.exists() else 0 + +release_id = "" +release_file = demo_dir / "release.json" +if release_file.exists(): + try: + release_id = json.loads(release_file.read_text()).get("data", {}).get("id", "") + except json.JSONDecodeError: + release_id = "" + +try: + commit = subprocess.check_output(["git", "rev-parse", "--short=12", "HEAD"], text=True).strip() +except Exception: + commit = "unknown" + +scenario_operations = 12 +summary = { + "schema_version": "evydence-production-benchmark.v1.0.0", + "benchmark": "golden_release_evidence_black_box", + "generated_at": datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z"), + "commit": commit, + "scenario": { + "source": "examples/end-to-end-release-evidence/run-local-demo.sh", + "api_writer_replicas": 1, + "worker_replicas": 1, + "database": "disposable PostgreSQL schema from EVYDENCE_TEST_DATABASE_URL", + "object_store": "filesystem object store under controlled tmp workspace", + "signing": "tenant signing path exercised by release bundle generation", + "paths": [ + "HTTP API create/list/report calls", + "PostgreSQL migrations and persistence", + "filesystem object payload storage", + "worker startup and outbox drain check", + "release-readiness report", + "customer package creation", + "audit-chain verification", + "API restart persistence check", + ], + "operation_count_estimate": scenario_operations, + }, + "timings": { + "black_box_total_ms": duration_ms, + "estimated_operations_per_second": round(scenario_operations / duration_seconds, 3), + "estimated_average_operation_ms": round(duration_ms / scenario_operations, 3), + }, + "outputs": { + "summary_path": str(workdir / "production-benchmark-summary.json"), + "black_box_stdout": str(workdir / "black-box.stdout"), + "black_box_stderr": str(workdir / "black-box.stderr"), + "demo_json_files": demo_json_files, + "object_files": object_files, + "object_bytes": object_bytes, + "release_id": release_id, + }, + "limitations": [ + "This is a local regression benchmark, not a production capacity claim.", + "Filesystem object storage is used so the run does not prove S3 or MinIO network latency.", + "The run uses one API writer and one worker; it does not prove multi-writer API safety.", + "The operation rate is estimated from the checked scenario wall clock and is not per-route latency.", + "Provider-side KMS, HSM, identity provider, transparency log, and registry controls are not exercised.", + "Database URL, API key secret, and bootstrap secret values are intentionally omitted from the summary.", + ], +} + +summary_path = workdir / "production-benchmark-summary.json" +summary_path.write_text(json.dumps(summary, indent=2, sort_keys=True) + "\n") + +text_path = workdir / "production-benchmark-summary.txt" +text_path.write_text( + "\n".join( + [ + "production-benchmark-check: passed", + f"commit={commit}", + f"black_box_total_ms={duration_ms}", + f"estimated_operations_per_second={summary['timings']['estimated_operations_per_second']}", + f"demo_json_files={demo_json_files}", + f"object_files={object_files}", + f"object_bytes={object_bytes}", + "claim=local regression benchmark only", + "", + ] + ) +) +print(text_path.read_text(), end="") +PY + +jq -e '.schema_version == "evydence-production-benchmark.v1.0.0" and .outputs.object_files > 0 and (.limitations | length >= 3)' \ + "$workdir/production-benchmark-summary.json" >/dev/null From 8624a39ebe6d3cbc66e76492c4efc6c2ac10b003 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 19:34:41 +0300 Subject: [PATCH 271/287] ci(release): add black-box release artifact check --- .github/workflows/ci.yml | 5 + Makefile | 9 +- docs/reference/production-readiness.md | 3 + docs/reference/release-validation.md | 18 ++- scripts/black_box_demo_check.sh | 29 +++- scripts/black_box_release_artifact_check.sh | 155 ++++++++++++++++++++ scripts/production_check.sh | 1 + 7 files changed, 209 insertions(+), 11 deletions(-) create mode 100755 scripts/black_box_release_artifact_check.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5661285..ea26477 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,6 +56,11 @@ jobs: path: | coverage.out tmp/release-check-summary.txt + tmp/production-benchmark/production-benchmark-summary.json + tmp/production-benchmark/production-benchmark-summary.txt + tmp/black-box-release-artifact/black-box-release-artifact-summary.json + tmp/black-box-release-artifact/black-box-release-artifact-summary.txt + tmp/black-box-release-artifact/release/evydence_linux_amd64/SHA256SUMS tmp/production-check/evydence-release-manifest.json tmp/production-check/evydence-release-manifest.sig.json if-no-files-found: ignore diff --git a/Makefile b/Makefile index 16a5ec0..cb33972 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ GOVULNCHECK_VERSION ?= v1.2.0 TAG ?= -.PHONY: help tools fmt lint vuln gosec test test-race fuzz-smoke coverage coverage-check openapi-check openapi-precision-check meta-check release-truth-check docs-check deploy-check sdk-check demo-check customer-cve-review-demo-check local-ci-simulation-check reviewer-package-workflow-check black-box-demo-check benchmark-check package-viewer-check marketing-site-check marketing-site-production-check restore-rehearsal-check fast-check finalize release-acceptance release-check production-check release-candidate-check public-release-verify migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean +.PHONY: help tools fmt lint vuln gosec test test-race fuzz-smoke coverage coverage-check openapi-check openapi-precision-check meta-check release-truth-check docs-check deploy-check sdk-check demo-check customer-cve-review-demo-check local-ci-simulation-check reviewer-package-workflow-check black-box-demo-check black-box-release-artifact-check benchmark-check package-viewer-check marketing-site-check marketing-site-production-check restore-rehearsal-check fast-check finalize release-acceptance release-check production-check release-candidate-check public-release-verify migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean help: ## Show help @awk 'BEGIN {FS=":.*## "}; /^[a-zA-Z0-9_.-]+:.*## / { printf " %-18s %s\n", $$1, $$2 }' $(MAKEFILE_LIST) @@ -361,6 +361,9 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and @grep -F 'upload validate-manifest' docs/gitlab/evydence-release-evidence.gitlab-ci.yml >/dev/null @grep -F -- '--manifest evydence-upload-manifest.json' docs/gitlab/evydence-release-evidence.gitlab-ci.yml >/dev/null @grep -F 'make production-check' .github/workflows/ci.yml >/dev/null + @grep -F 'tmp/black-box-release-artifact/black-box-release-artifact-summary.json' .github/workflows/ci.yml >/dev/null + @grep -F 'black-box release-style binary evidence' docs/reference/release-validation.md >/dev/null + @grep -F 'make black-box-release-artifact-check' docs/reference/production-readiness.md docs/reference/release-validation.md >/dev/null @grep -F 'make production-check' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'EVYDENCE_RELEASE_SIGNING_PRIVATE_KEY_B64' .github/workflows/release-artifacts.yml >/dev/null @grep -F 'EVYDENCE_RELEASE_PUBLISH_TOKEN' .github/workflows/release-artifacts.yml >/dev/null @@ -449,6 +452,7 @@ demo-check: ## Validate checked end-to-end evidence demo fixtures @test -x examples/customer-cve-review-demo/run-demo.sh @test -x scripts/local_ci_simulation_check.sh @test -x scripts/reviewer_package_workflow_check.sh + @test -x scripts/black_box_release_artifact_check.sh @test -f examples/end-to-end-release-evidence/README.md @test -f examples/customer-cve-review-demo/README.md @test -f examples/customer-cve-review-demo/customer-cve-review-story.json @@ -489,6 +493,9 @@ reviewer-package-workflow-check: ## Validate offline reviewer package verificati black-box-demo-check: ## Run live PostgreSQL black-box API/worker demo; requires EVYDENCE_TEST_DATABASE_URL @scripts/black_box_demo_check.sh +black-box-release-artifact-check: ## Run live PostgreSQL black-box demo against release-style local binaries + @scripts/black_box_release_artifact_check.sh + benchmark-check: ## Run the checked app-layer release evidence benchmark @$(GO) test ./internal/app -bench BenchmarkReleaseEvidenceIngestion -benchtime=100x -run '^$$' -benchmem @if [ -n "$$EVYDENCE_TEST_DATABASE_URL" ]; then scripts/production_benchmark_check.sh; else echo "EVYDENCE_TEST_DATABASE_URL not set; skipping production black-box benchmark"; fi diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 3d06f7e..015062b 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -178,6 +178,9 @@ Do not describe an Evydence build as broadly self-hosted production-ready until: - `make black-box-demo-check` passes against a disposable PostgreSQL schema, exercising API, worker, restart persistence, readiness, package, and audit-chain verification paths; +- `make black-box-release-artifact-check` passes against release-style local + binaries, disposable PostgreSQL, filesystem object storage, API restart, and + package/readiness/audit-chain verification paths; - coverage is at or above the configured threshold; - release artifacts have signed manifests and published checksums; - committed migrations have passed compatibility checks from every migration diff --git a/docs/reference/release-validation.md b/docs/reference/release-validation.md index 499a27d..0eb73cf 100644 --- a/docs/reference/release-validation.md +++ b/docs/reference/release-validation.md @@ -41,9 +41,11 @@ That gate is stricter than `make release-check`: it requires the configured coverage threshold, verifies every committed migration prefix can upgrade to the current schema in a temporary PostgreSQL schema, runs the checked release-evidence benchmark, starts an API and worker against a disposable -PostgreSQL schema for a black-box demo/restart persistence check, and runs a -release artifact signing smoke test. See [Production readiness](production-readiness.md) -for the supported profiles and exit criteria. +PostgreSQL schema for a black-box demo/restart persistence check, runs the same +black-box flow against release-style local binaries through +`make black-box-release-artifact-check`, and runs a release artifact signing +smoke test. See [Production readiness](production-readiness.md) for the +supported profiles and exit criteria. `make coverage-check` is intentionally part of the production profile and fails early when `EVYDENCE_TEST_DATABASE_URL` is unset. Use `make coverage` for a @@ -130,12 +132,14 @@ The checked-in GitHub Actions workflow provides a disposable PostgreSQL service, sets `EVYDENCE_TEST_DATABASE_URL`, and runs `make production-check`. That gate runs the live PostgreSQL release check, coverage threshold enforcement, lint, gosec, govulncheck, race tests, OpenAPI/docs/deployment/SDK checks, migration -compatibility tests, and a release manifest signing smoke test. +compatibility tests, production benchmark evidence, black-box release-style binary evidence, +and a release manifest signing smoke test. The workflow preserves `tmp/release-check-summary.txt`, `coverage.out`, and the -production-check release manifest/signature smoke artifacts as build artifacts. -The database must not contain production evidence, customer package tokens, -signing-key material, or other real secrets. +production benchmark summary, black-box release-style binary summary, +release-style binary checksums, and production-check release manifest/signature +smoke artifacts as build artifacts. The database must not contain production +evidence, customer package tokens, signing-key material, or other real secrets. GitHub Actions and service container dependencies are pinned by commit SHA or image digest in the checked CI workflows. The repository also runs a CodeQL diff --git a/scripts/black_box_demo_check.sh b/scripts/black_box_demo_check.sh index d10d430..ebc2098 100755 --- a/scripts/black_box_demo_check.sh +++ b/scripts/black_box_demo_check.sh @@ -17,7 +17,7 @@ for tool in curl go jq psql python3; do done workdir="${EVYDENCE_BLACK_BOX_WORKDIR:-tmp/black-box-demo-check}" -schema="evy_demo_$(date +%s)_$$" +schema="demo_schema_$(date +%s)_$$" api_pid="" worker_pid="" @@ -67,8 +67,31 @@ PY )" api_url="http://127.0.0.1:$port" -go build -o "$workdir/evydence-api" ./cmd/evydence-api -go build -o "$workdir/evydence-worker" ./cmd/evydence-worker +prepare_binary() { + env_name="$1" + fallback_pkg="$2" + output="$3" + case "$env_name" in + EVYDENCE_BLACK_BOX_API_BIN) configured="${EVYDENCE_BLACK_BOX_API_BIN:-}" ;; + EVYDENCE_BLACK_BOX_WORKER_BIN) configured="${EVYDENCE_BLACK_BOX_WORKER_BIN:-}" ;; + *) + printf '%s\n' "black-box-demo-check: unsupported binary env selector" >&2 + exit 2 + ;; + esac + if [ -n "$configured" ]; then + if [ ! -x "$configured" ]; then + printf '%s\n' "black-box-demo-check: $env_name must point to an executable file" >&2 + exit 2 + fi + cp "$configured" "$output" + else + go build -o "$output" "$fallback_pkg" + fi +} + +prepare_binary EVYDENCE_BLACK_BOX_API_BIN ./cmd/evydence-api "$workdir/evydence-api" +prepare_binary EVYDENCE_BLACK_BOX_WORKER_BIN ./cmd/evydence-worker "$workdir/evydence-worker" start_api() { label="$1" diff --git a/scripts/black_box_release_artifact_check.sh b/scripts/black_box_release_artifact_check.sh new file mode 100755 index 0000000..949dff6 --- /dev/null +++ b/scripts/black_box_release_artifact_check.sh @@ -0,0 +1,155 @@ +#!/usr/bin/env sh +set -eu + +repo_root="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)" +cd "$repo_root" + +fail() { + printf '%s\n' "black-box-release-artifact-check: $*" >&2 + exit 2 +} + +if [ -z "${EVYDENCE_TEST_DATABASE_URL:-}" ]; then + fail "EVYDENCE_TEST_DATABASE_URL is required" +fi + +for tool in curl go jq psql python3 sha256sum; do + if ! command -v "$tool" >/dev/null 2>&1; then + fail "missing required tool: $tool" + fi +done + +workdir="${EVYDENCE_BLACK_BOX_RELEASE_WORKDIR:-tmp/black-box-release-artifact}" +case "$workdir" in + tmp/*) ;; + *) fail "EVYDENCE_BLACK_BOX_RELEASE_WORKDIR must stay under tmp/" ;; +esac +case "$workdir" in + *..*|*/.*|.*) fail "EVYDENCE_BLACK_BOX_RELEASE_WORKDIR must not contain dot segments" ;; +esac + +rm -rf "$workdir" +release_dir="$workdir/release/evydence_linux_amd64" +run_dir="$workdir/run" +mkdir -p "$release_dir" "$run_dir" + +go build -trimpath -o "$release_dir/evydence" ./cmd/evydence +go build -trimpath -o "$release_dir/evydence-api" ./cmd/evydence-api +go build -trimpath -o "$release_dir/evydence-worker" ./cmd/evydence-worker +go build -trimpath -o "$release_dir/evydence-migrate" ./cmd/evydence-migrate +(cd "$release_dir" && sha256sum evydence evydence-api evydence-worker evydence-migrate > SHA256SUMS) + +EVYDENCE_BLACK_BOX_WORKDIR="$run_dir" \ +EVYDENCE_BLACK_BOX_KEEP_ARTIFACTS=1 \ +EVYDENCE_BLACK_BOX_API_BIN="$release_dir/evydence-api" \ +EVYDENCE_BLACK_BOX_WORKER_BIN="$release_dir/evydence-worker" \ +scripts/black_box_demo_check.sh >"$workdir/black-box.stdout" 2>"$workdir/black-box.stderr" + +python3 - "$workdir" "$release_dir" "$run_dir" <<'PY' +import hashlib +import json +import subprocess +import sys +from datetime import datetime, timezone +from pathlib import Path + +workdir = Path(sys.argv[1]) +release_dir = Path(sys.argv[2]) +run_dir = Path(sys.argv[3]) +demo_dir = run_dir / "demo" +object_root = run_dir / "objects" + +def sha256(path: Path) -> str: + h = hashlib.sha256() + with path.open("rb") as handle: + for chunk in iter(lambda: handle.read(1024 * 1024), b""): + h.update(chunk) + return "sha256:" + h.hexdigest() + +def count_files(root: Path): + if not root.exists(): + return 0, 0 + files = [path for path in root.rglob("*") if path.is_file()] + return len(files), sum(path.stat().st_size for path in files) + +try: + commit = subprocess.check_output(["git", "rev-parse", "--short=12", "HEAD"], text=True).strip() +except Exception: + commit = "unknown" + +binaries = [] +for name in ["evydence", "evydence-api", "evydence-worker", "evydence-migrate"]: + path = release_dir / name + binaries.append( + { + "name": name, + "path": str(path), + "size": path.stat().st_size, + "sha256": sha256(path), + } + ) + +object_files, object_bytes = count_files(object_root) +demo_json_files = len(list(demo_dir.glob("*.json"))) if demo_dir.exists() else 0 + +summary = { + "schema_version": "evydence-black-box-release-artifact.v1.0.0", + "generated_at": datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z"), + "commit": commit, + "artifact_shape": "release-style linux_amd64 binary directory", + "binaries": binaries, + "scenario": { + "source": "scripts/black_box_demo_check.sh", + "database": "disposable PostgreSQL schema from EVYDENCE_TEST_DATABASE_URL", + "object_store": "filesystem object store under controlled tmp workspace", + "api_restart": True, + "worker_started": True, + "release_readiness_verified": True, + "customer_package_created": True, + "audit_chain_verified": True, + }, + "outputs": { + "summary_path": str(workdir / "black-box-release-artifact-summary.json"), + "checksums_path": str(release_dir / "SHA256SUMS"), + "black_box_stdout": str(workdir / "black-box.stdout"), + "black_box_stderr": str(workdir / "black-box.stderr"), + "demo_json_files": demo_json_files, + "object_files": object_files, + "object_bytes": object_bytes, + }, + "limitations": [ + "This check runs release-style local binaries, not a published GitHub Release asset.", + "The object store is local filesystem storage, not live S3 or MinIO network storage.", + "The check avoids live external providers and does not prove KMS, HSM, SSO, registry, or transparency-provider behavior.", + "The summary intentionally excludes API keys, database URLs, bootstrap secrets, bearer tokens, and raw evidence payloads.", + ], +} + +summary_path = workdir / "black-box-release-artifact-summary.json" +summary_path.write_text(json.dumps(summary, indent=2, sort_keys=True) + "\n") + +text_path = workdir / "black-box-release-artifact-summary.txt" +text_path.write_text( + "\n".join( + [ + "black-box-release-artifact-check: passed", + f"commit={commit}", + f"binaries={len(binaries)}", + f"demo_json_files={demo_json_files}", + f"object_files={object_files}", + f"object_bytes={object_bytes}", + "claim=release-style binary smoke test only", + "", + ] + ) +) +print(text_path.read_text(), end="") +PY + +jq -e '.schema_version == "evydence-black-box-release-artifact.v1.0.0" and (.binaries | length == 4) and .outputs.object_files > 0 and (.limitations | length >= 3)' \ + "$workdir/black-box-release-artifact-summary.json" >/dev/null + +if find "$workdir" -type f \( -name '*.json' -o -name '*.txt' -o -name '*.stdout' -o -name '*.stderr' \) -exec grep -I -l 'evy_' {} + | grep -q .; then + printf '%s\n' "black-box-release-artifact-check: generated artifacts leaked an API key-like secret" >&2 + exit 1 +fi diff --git a/scripts/production_check.sh b/scripts/production_check.sh index 566db44..aad5ecc 100755 --- a/scripts/production_check.sh +++ b/scripts/production_check.sh @@ -16,6 +16,7 @@ make coverage-check make migration-compatibility-check make benchmark-check make black-box-demo-check +make black-box-release-artifact-check workdir="tmp/production-check" rm -rf "$workdir" From d67959c6c78985f6d26c24ace2cd9d7a2c3b69e8 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 19:42:28 +0300 Subject: [PATCH 272/287] docs(ops): document HA strategy --- Makefile | 8 ++ docs/README.md | 1 + docs/kubernetes.md | 2 +- docs/operator-overview.md | 1 + docs/reference/capacity-and-failures.md | 1 + docs/reference/ha-strategy.md | 108 ++++++++++++++++++ .../hardened-reference-deployment.md | 4 +- docs/reference/production-readiness.md | 4 +- docs/reference/roadmap.md | 2 +- docs/reference/source-of-truth.md | 1 + 10 files changed, 127 insertions(+), 5 deletions(-) create mode 100644 docs/reference/ha-strategy.md diff --git a/Makefile b/Makefile index cb33972..1cb90b3 100644 --- a/Makefile +++ b/Makefile @@ -169,6 +169,7 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and @test -f docs/reference/production-exit-review.md @test -f docs/reference/stable-v0.1.0-exit-criteria.md @test -f docs/reference/hardened-reference-deployment.md + @test -f docs/reference/ha-strategy.md @test -f docs/reference/external-controls-matrix.md @test -f docs/reference/production-gate-troubleshooting.md @test -f docs/reference/upgrade-compatibility-policy.md @@ -224,6 +225,7 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and "reference/production-exit-review.md" \ "reference/stable-v0.1.0-exit-criteria.md" \ "reference/hardened-reference-deployment.md" \ + "reference/ha-strategy.md" \ "reference/external-controls-matrix.md" \ "reference/production-gate-troubleshooting.md" \ "reference/upgrade-compatibility-policy.md" \ @@ -332,6 +334,11 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and @grep -F 'make production-check' docs/reference/hardened-reference-deployment.md >/dev/null @grep -F 'not legal compliance proof' docs/reference/hardened-reference-deployment.md >/dev/null @grep -F 'Hardened reference deployment' docs/README.md docs/operator-overview.md docs/kubernetes.md docs/production-hardening.md docs/reference/production-readiness.md docs/reference/source-of-truth.md >/dev/null + @grep -F 'single-writer self-hosted appliance' docs/reference/ha-strategy.md >/dev/null + @grep -F 'Multi-writer API high availability is not supported' docs/reference/ha-strategy.md >/dev/null + @grep -F 'Before Multi-Writer API Is Supported' docs/reference/ha-strategy.md >/dev/null + @grep -F 'EVYDENCE_API_WRITER_REPLICAS=1' docs/reference/ha-strategy.md >/dev/null + @grep -F 'HA strategy' docs/README.md docs/operator-overview.md docs/kubernetes.md docs/reference/production-readiness.md docs/reference/capacity-and-failures.md docs/reference/hardened-reference-deployment.md docs/reference/roadmap.md docs/reference/source-of-truth.md >/dev/null @grep -F 'Required: object paths are tenant-prefixed' docs/how-to/pilot-deployment-checklist.md >/dev/null @grep -F 'Required: public API access is behind TLS' docs/how-to/pilot-deployment-checklist.md >/dev/null @test -f docs/commercial/design-partner-pilot.md @@ -434,6 +441,7 @@ deploy-check: ## Validate deployment and air-gap skeletons exist @grep -F 'healthcheck' deploy/helm/evydence/values.yaml >/dev/null @grep -F 'single API writer replica' docs/kubernetes.md >/dev/null @grep -F 'Hardened reference deployment' docs/kubernetes.md docs/reference/hardened-reference-deployment.md >/dev/null + @grep -F 'HA strategy' docs/kubernetes.md docs/reference/ha-strategy.md >/dev/null @grep -F 'EVYDENCE_API_WRITER_MODE: single' compose.production-like.yml >/dev/null @grep -F 'EVYDENCE_PRINT_BOOTSTRAP_SECRET: "false"' compose.production-like.yml >/dev/null @grep -F 'evydence-migrate ./cmd/evydence-migrate' Dockerfile >/dev/null diff --git a/docs/README.md b/docs/README.md index b67483a..794051b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -46,6 +46,7 @@ This documentation is organized by reader task. Implementation claims should be - [Production exit review](reference/production-exit-review.md): current release-positioning decision and unresolved blockers. - [Stable v0.1.0 exit criteria](reference/stable-v0.1.0-exit-criteria.md): criteria for moving from release candidate to a stable `v0.1.0` tag. - [Hardened reference deployment](reference/hardened-reference-deployment.md): controlled self-hosted topology with external PostgreSQL, object storage, TLS, secrets, backups, monitoring, and signing. +- [HA strategy](reference/ha-strategy.md): single-writer API decision, worker scaling stance, recovery boundaries, and multi-writer prerequisites. - [External controls matrix](reference/external-controls-matrix.md): owner boundaries for regulated or high-trust self-hosted deployments. - [Production gate troubleshooting](reference/production-gate-troubleshooting.md): safe diagnostics for `make production-check` failures. - [Upgrade and compatibility policy](reference/upgrade-compatibility-policy.md): supported upgrade paths, migration expectations, and API compatibility rules. diff --git a/docs/kubernetes.md b/docs/kubernetes.md index 2ad5971..2221586 100644 --- a/docs/kubernetes.md +++ b/docs/kubernetes.md @@ -97,4 +97,4 @@ Rollback does not roll back PostgreSQL data or object-store payloads. Keep datab ## Production Notes -Production deployments should use external PostgreSQL, S3/MinIO-compatible object storage, TLS ingress, backup automation, network access controls, and external signing. Current production guidance uses a single API writer replica; the chart passes `EVYDENCE_API_WRITER_MODE=single` and `EVYDENCE_API_WRITER_REPLICAS=1`, production API startup rejects unsupported writer modes or replica counts above one, then enforces the stance with a PostgreSQL advisory writer lease. Worker replicas can scale independently through PostgreSQL outbox row locking. See [Hardened reference deployment](reference/hardened-reference-deployment.md), [Production hardening review](production-hardening.md), [Production readiness](reference/production-readiness.md), and [Configuration](reference/configuration.md). +Production deployments should use external PostgreSQL, S3/MinIO-compatible object storage, TLS ingress, backup automation, network access controls, and external signing. Current production guidance uses a single API writer replica; the chart passes `EVYDENCE_API_WRITER_MODE=single` and `EVYDENCE_API_WRITER_REPLICAS=1`, production API startup rejects unsupported writer modes or replica counts above one, then enforces the stance with a PostgreSQL advisory writer lease. Worker replicas can scale independently through PostgreSQL outbox row locking. See [HA strategy](reference/ha-strategy.md), [Hardened reference deployment](reference/hardened-reference-deployment.md), [Production hardening review](production-hardening.md), [Production readiness](reference/production-readiness.md), and [Configuration](reference/configuration.md). diff --git a/docs/operator-overview.md b/docs/operator-overview.md index 6d1f34c..31cefc8 100644 --- a/docs/operator-overview.md +++ b/docs/operator-overview.md @@ -50,6 +50,7 @@ beyond evaluation. - [Observability](reference/observability.md) - [Capacity and failure modes](reference/capacity-and-failures.md) - [Hardened reference deployment](reference/hardened-reference-deployment.md) +- [HA strategy](reference/ha-strategy.md) - [External controls matrix](reference/external-controls-matrix.md) - [Stable v0.1.0 exit criteria](reference/stable-v0.1.0-exit-criteria.md) - [Source of truth](reference/source-of-truth.md) diff --git a/docs/reference/capacity-and-failures.md b/docs/reference/capacity-and-failures.md index 06fe016..555c2d8 100644 --- a/docs/reference/capacity-and-failures.md +++ b/docs/reference/capacity-and-failures.md @@ -33,6 +33,7 @@ The multi-writer backlog remains technical hardening work: finish focused repository decomposition, add optimistic concurrency or transaction-scoped resource locks where needed, test concurrent writes per resource family, and re-run the production exit review before changing the supported HA claim. +The detailed decision record is [HA strategy](ha-strategy.md). ## Practical Sizing Inputs diff --git a/docs/reference/ha-strategy.md b/docs/reference/ha-strategy.md new file mode 100644 index 0000000..e37a630 --- /dev/null +++ b/docs/reference/ha-strategy.md @@ -0,0 +1,108 @@ +# HA Strategy + +This reference records the current high-availability decision for Evydence +release candidates. It supports deployment planning only. It is not an uptime +guarantee, legal compliance proof, certification, complete evidence proof, or a +secure-release guarantee. + +## Decision + +Evydence is positioned as a single-writer self-hosted appliance for the current +controlled production-candidate release line. + +The supported topology is: + +- one API writer replica; +- one or more worker replicas using PostgreSQL outbox row locking; +- external PostgreSQL with backup and restore rehearsal; +- external S3/MinIO-compatible object storage with database/object backup + pairing; +- supervised API restart through Kubernetes, systemd, or an equivalent process + manager; +- deployment-specific recovery objectives accepted by the operator. + +This is a deliberate product and engineering decision. Multi-writer API high availability is not supported +until the remaining concurrency work is +implemented, tested, and reviewed. + +## Why Not Multi-Writer API Yet + +The current code has focused relational write paths for high-risk resource +families, but it still keeps a large application ledger aggregate and some +cross-resource operations that are easier to reason about with a single API +writer. Scaling API writers before the remaining work is finished could create +hard-to-audit races around: + +- audit-chain ordering and tenant chain continuity; +- release bundle generation and signature receipts; +- idempotency replay and conflict behavior under concurrent requests; +- evidence lifecycle append ordering; +- package/report generation from a moving release state; +- object-store metadata and database row pairing; +- remaining aggregate state synchronization for resource families not yet split + into focused services. + +The current supported stance favors clear recovery behavior over an unfinished +multi-writer design. + +## Supported Recovery Boundaries + +Evydence does not publish a generic SLO for all self-hosted deployments. The +operator owns the concrete target for recovery time, recovery point, support +coverage, alert routing, and maintenance windows. + +For controlled self-hosted use, the expected recovery model is: + +- the API process is restarted by the deployment platform if it exits; +- a second API writer should fail closed in production because startup rejects + replica counts above one and the PostgreSQL advisory writer lease prevents a + competing writer from taking over silently; +- worker replicas can continue or be scaled while the API is unavailable, + subject to database and object-store availability; +- database and object-store restore must be rehearsed together before relying + on the deployment for customer evidence workflows; +- any rollback or forward-fix procedure must preserve append-only evidence, + audit-chain entries, signatures, packages, and object payload hashes. + +## Before Multi-Writer API Is Supported + +Do not change Helm defaults or production docs to advertise multi-writer API +support until all of these are true: + +- all production write families have focused relational repository paths or an + equivalent reviewed transaction design; +- tenant-scoped audit-chain appends are protected by reviewed transaction or + resource-lock behavior; +- idempotency records are protected by transaction-backed uniqueness and replay + tests under concurrent requests; +- release bundle, package, report, evidence lifecycle, exception, approval, and + signing operations have concurrent write tests; +- object-store writes and database metadata writes have failure and retry tests + that preserve digest pairing; +- `make production-check`, `make test-race`, live PostgreSQL concurrency tests, + black-box restart tests, and restore rehearsals pass under the proposed + topology; +- Kubernetes values, production docs, release notes, and the pilot checklist + are updated to state the new supported topology and limitations. + +## Operator Checklist + +- Keep `api.replicas=1` and `api.writerMode=single`. +- Keep `EVYDENCE_API_WRITER_MODE=single` and + `EVYDENCE_API_WRITER_REPLICAS=1`. +- Scale workers based on outbox backlog and parser/signing/report latency. +- Monitor `/v1/ready`, API process restarts, outbox backlog age, worker + failures, database availability, object-store failures, and signing-provider + failures. +- Rehearse paired database/object-store restore and verify audit chains, + release bundles, and customer packages after restore. +- Record the deployment's recovery assumptions in the + [pilot deployment checklist](../how-to/pilot-deployment-checklist.md). + +## Related References + +- [Production readiness](production-readiness.md) +- [Capacity and failure modes](capacity-and-failures.md) +- [Hardened reference deployment](hardened-reference-deployment.md) +- [Kubernetes deployment](../kubernetes.md) +- [Backup and restore](../runbooks/backup-restore.md) diff --git a/docs/reference/hardened-reference-deployment.md b/docs/reference/hardened-reference-deployment.md index c2b1e26..fa29bf1 100644 --- a/docs/reference/hardened-reference-deployment.md +++ b/docs/reference/hardened-reference-deployment.md @@ -23,6 +23,8 @@ Use the [pilot deployment checklist](../how-to/pilot-deployment-checklist.md) for the copy-paste go/no-go record and the [external controls matrix](external-controls-matrix.md) to assign operator, provider, repo, and review responsibilities. +Use [HA strategy](ha-strategy.md) for the single-writer API decision, +worker-scaling stance, recovery boundaries, and multi-writer prerequisites. ## Reference Topology @@ -147,4 +149,4 @@ network, backup tooling, signing provider, or legal/review process is suitable. Do not broaden this reference into a multi-writer API HA claim. The supported self-hosted profile remains a single API writer replica with scalable worker replicas until multi-writer API concurrency is implemented, tested, and -documented. +documented. See [HA strategy](ha-strategy.md). diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index 015062b..f5c1db9 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -120,8 +120,8 @@ The current decision is that one API writer is acceptable for controlled self-hosted deployments with monitored process restart, backup/restore rehearsal, and maintenance-window expectations. Multi-writer API HA is required before any future broad production or hosted SaaS claim. The roadmap records -that backlog; see [Roadmap and release cadence](roadmap.md) and -[Capacity and failure modes](capacity-and-failures.md). +that backlog; see [HA strategy](ha-strategy.md), +[Roadmap and release cadence](roadmap.md), and [Capacity and failure modes](capacity-and-failures.md). ## Machine Gate diff --git a/docs/reference/roadmap.md b/docs/reference/roadmap.md index a3c3211..9f2ab32 100644 --- a/docs/reference/roadmap.md +++ b/docs/reference/roadmap.md @@ -13,7 +13,7 @@ replicas through PostgreSQL outbox locking. Multi-writer API high availability is not part of the current supported profile. This single-writer stance is acceptable for the current controlled self-hosted release line; multi-writer API HA becomes a blocker before any future broad production-ready or hosted SaaS -status. +status. See [HA strategy](ha-strategy.md) for the decision record. ## Near-Term Focus diff --git a/docs/reference/source-of-truth.md b/docs/reference/source-of-truth.md index 33d24ad..311a81a 100644 --- a/docs/reference/source-of-truth.md +++ b/docs/reference/source-of-truth.md @@ -14,6 +14,7 @@ product-boundary language across the docs. | Durable operation | `docs/how-to/install-and-operate.md` | Includes PostgreSQL/object storage and production-like Compose rehearsal. | | Kubernetes | `docs/kubernetes.md` | Helm-specific operator interface. | | Hardened self-hosted topology | `docs/reference/hardened-reference-deployment.md` | One API writer, scalable workers, external PostgreSQL/object storage, TLS, secrets, backups, monitoring, signing, and operator-owned evidence. | +| HA and concurrency decision | `docs/reference/ha-strategy.md` | Current single-writer appliance decision, recovery boundaries, and multi-writer prerequisites. | | Release validation | `docs/reference/release-validation.md` | Canonical release gate behavior. | | Release-candidate evidence | `docs/reference/release-candidate.md` | Canonical release-candidate artifact checklist. | | Release evidence artifact map | `docs/reference/release-evidence-index.md` | Maps each release artifact to generation and verification commands. | From 9b77301b7600019936a368fb086c4ad5cfd3d819 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 19:56:38 +0300 Subject: [PATCH 273/287] test(persistence): track decomposition inventory --- Makefile | 13 +- docs/README.md | 1 + docs/reference/capability-map.md | 3 + docs/reference/ha-strategy.md | 3 + docs/reference/persistence-decomposition.md | 168 ++++++++++++++++++ docs/reference/production-readiness.md | 4 + docs/reference/roadmap.md | 4 +- docs/reference/source-of-truth.md | 1 + internal/app/critical_mutation_test.go | 165 +++++++++++++++++ .../persistence_decomposition_inventory.py | 168 ++++++++++++++++++ 10 files changed, 527 insertions(+), 3 deletions(-) create mode 100644 docs/reference/persistence-decomposition.md create mode 100755 scripts/persistence_decomposition_inventory.py diff --git a/Makefile b/Makefile index 1cb90b3..b1f3ccb 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ GOVULNCHECK_VERSION ?= v1.2.0 TAG ?= -.PHONY: help tools fmt lint vuln gosec test test-race fuzz-smoke coverage coverage-check openapi-check openapi-precision-check meta-check release-truth-check docs-check deploy-check sdk-check demo-check customer-cve-review-demo-check local-ci-simulation-check reviewer-package-workflow-check black-box-demo-check black-box-release-artifact-check benchmark-check package-viewer-check marketing-site-check marketing-site-production-check restore-rehearsal-check fast-check finalize release-acceptance release-check production-check release-candidate-check public-release-verify migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean +.PHONY: help tools fmt lint vuln gosec test test-race fuzz-smoke coverage coverage-check openapi-check openapi-precision-check meta-check release-truth-check persistence-decomposition-check docs-check deploy-check sdk-check demo-check customer-cve-review-demo-check local-ci-simulation-check reviewer-package-workflow-check black-box-demo-check black-box-release-artifact-check benchmark-check package-viewer-check marketing-site-check marketing-site-production-check restore-rehearsal-check fast-check finalize release-acceptance release-check production-check release-candidate-check public-release-verify migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean help: ## Show help @awk 'BEGIN {FS=":.*## "}; /^[a-zA-Z0-9_.-]+:.*## / { printf " %-18s %s\n", $$1, $$2 }' $(MAKEFILE_LIST) @@ -137,7 +137,10 @@ meta-check: ## Validate root legal, governance, support, and release-evidence me release-truth-check: ## Validate current release metadata against public docs and helper defaults @scripts/check_release_truth.py -docs-check: meta-check release-truth-check ## Validate canonical docs exist and avoid forbidden product claims +persistence-decomposition-check: ## Validate generated persistence decomposition inventory + @scripts/persistence_decomposition_inventory.py --check + +docs-check: meta-check release-truth-check persistence-decomposition-check ## Validate canonical docs exist and avoid forbidden product claims @test -f README.md @test -f .production.env.example @test -f docs/README.md @@ -166,6 +169,7 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and @test -f docs/reference/capacity-and-failures.md @test -f docs/reference/benchmark-results.md @test -f docs/reference/production-readiness.md + @test -f docs/reference/persistence-decomposition.md @test -f docs/reference/production-exit-review.md @test -f docs/reference/stable-v0.1.0-exit-criteria.md @test -f docs/reference/hardened-reference-deployment.md @@ -222,6 +226,7 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and "reference/capacity-and-failures.md" \ "reference/benchmark-results.md" \ "reference/production-readiness.md" \ + "reference/persistence-decomposition.md" \ "reference/production-exit-review.md" \ "reference/stable-v0.1.0-exit-criteria.md" \ "reference/hardened-reference-deployment.md" \ @@ -339,6 +344,10 @@ docs-check: meta-check release-truth-check ## Validate canonical docs exist and @grep -F 'Before Multi-Writer API Is Supported' docs/reference/ha-strategy.md >/dev/null @grep -F 'EVYDENCE_API_WRITER_REPLICAS=1' docs/reference/ha-strategy.md >/dev/null @grep -F 'HA strategy' docs/README.md docs/operator-overview.md docs/kubernetes.md docs/reference/production-readiness.md docs/reference/capacity-and-failures.md docs/reference/hardened-reference-deployment.md docs/reference/roadmap.md docs/reference/source-of-truth.md >/dev/null + @grep -F 'Persistence decomposition inventory' docs/README.md docs/reference/production-readiness.md docs/reference/capability-map.md docs/reference/ha-strategy.md docs/reference/source-of-truth.md >/dev/null + @grep -F 'scripts/persistence_decomposition_inventory.py --write' docs/reference/persistence-decomposition.md >/dev/null + @grep -F 'Remaining Broad Relational-State Mutations' docs/reference/persistence-decomposition.md >/dev/null + @grep -F 'make persistence-decomposition-check' docs/reference/persistence-decomposition.md >/dev/null @grep -F 'Required: object paths are tenant-prefixed' docs/how-to/pilot-deployment-checklist.md >/dev/null @grep -F 'Required: public API access is behind TLS' docs/how-to/pilot-deployment-checklist.md >/dev/null @test -f docs/commercial/design-partner-pilot.md diff --git a/docs/README.md b/docs/README.md index 794051b..3e72a70 100644 --- a/docs/README.md +++ b/docs/README.md @@ -43,6 +43,7 @@ This documentation is organized by reader task. Implementation claims should be - [Capacity and failure modes](reference/capacity-and-failures.md): supported concurrency profile, sizing inputs, and failure behavior. - [Benchmark results](reference/benchmark-results.md): current local benchmark command and interpretation. - [Production readiness](reference/production-readiness.md): self-hosted production profiles, production gates, and exit criteria. +- [Persistence decomposition inventory](reference/persistence-decomposition.md): generated map of focused and broad relational persistence call sites. - [Production exit review](reference/production-exit-review.md): current release-positioning decision and unresolved blockers. - [Stable v0.1.0 exit criteria](reference/stable-v0.1.0-exit-criteria.md): criteria for moving from release candidate to a stable `v0.1.0` tag. - [Hardened reference deployment](reference/hardened-reference-deployment.md): controlled self-hosted topology with external PostgreSQL, object storage, TLS, secrets, backups, monitoring, and signing. diff --git a/docs/reference/capability-map.md b/docs/reference/capability-map.md index a2776be..505e39f 100644 --- a/docs/reference/capability-map.md +++ b/docs/reference/capability-map.md @@ -109,6 +109,9 @@ vulnerability coverage, or a secure-release guarantee. - Production API deployments remain intentionally single-writer until multi-writer API concurrency is reviewed across every write family. Worker replicas may scale through PostgreSQL outbox locking. +- [Persistence decomposition inventory](persistence-decomposition.md) tracks + focused mutation paths, remaining broad relational-state call sites, and the + next repository split order. ## Where To Go Next diff --git a/docs/reference/ha-strategy.md b/docs/reference/ha-strategy.md index e37a630..0dc438b 100644 --- a/docs/reference/ha-strategy.md +++ b/docs/reference/ha-strategy.md @@ -44,6 +44,9 @@ hard-to-audit races around: The current supported stance favors clear recovery behavior over an unfinished multi-writer design. +Use the [Persistence decomposition inventory](persistence-decomposition.md) to +inspect the current focused mutation paths, remaining broad relational-state +call sites, and next repository split order. ## Supported Recovery Boundaries diff --git a/docs/reference/persistence-decomposition.md b/docs/reference/persistence-decomposition.md new file mode 100644 index 0000000..e6174fe --- /dev/null +++ b/docs/reference/persistence-decomposition.md @@ -0,0 +1,168 @@ +# Persistence Decomposition Inventory + +This reference is generated by `scripts/persistence_decomposition_inventory.py`. +Update it with `scripts/persistence_decomposition_inventory.py --write` after persistence call sites change. + +Purpose: keep the production persistence story inspectable while Evydence continues splitting the large application ledger into focused repository paths. + +## Current Production Contract + +- Production PostgreSQL startup uses relational-only reconstruction. +- Production writes do not create or update the compatibility `ledger_state` snapshot row. +- `persistCriticalLocked` writes high-risk identity, key, idempotency, signing, verification, bundle, provider-verification, decision, audit-chain, and outbox state through focused PostgreSQL transactions when the store supports them. +- `persistReleaseLedgerLocked` and `persistReleaseLedgerWithOutboxLocked` write release-ledger and evidence-core state through focused PostgreSQL transactions when the store supports them. +- Remaining direct `persistLocked` call sites use `SaveRelationalState` with the PostgreSQL store, not `SaveState`; compatibility `SaveState` remains for memory/local/demo/import paths. +- One API writer replica remains the supported production candidate topology until every write family has focused repository paths or a reviewed optimistic-concurrency design. + +## Focused Critical Mutations + +| Family | File | Function | Call | +| --- | --- | --- | --- | +| VEX and vulnerability decisions | `internal/app/vex.go` | `CreateVulnerabilityDecision` | `persistCriticalLocked` | +| enterprise identity and retention | `internal/app/enterprise.go` | `CreateCustomerPortalAccess` | `persistCriticalLocked` | +| enterprise identity and retention | `internal/app/enterprise.go` | `CreateSSOSession` | `persistCriticalLocked` | +| enterprise identity and retention | `internal/app/enterprise.go` | `ExchangeSSOCredential` | `persistCriticalLocked` | +| enterprise identity and retention | `internal/app/enterprise.go` | `RevokeCurrentSSOSession` | `persistCriticalLocked` | +| enterprise identity and retention | `internal/app/enterprise.go` | `RevokeCustomerPortalAccess` | `persistCriticalLocked` | +| enterprise identity and retention | `internal/app/enterprise.go` | `RevokeSSOSession` | `persistCriticalLocked` | +| enterprise identity and retention | `internal/app/enterprise.go` | `accessCustomerPortalPackage` | `persistCriticalLocked` | +| enterprise identity and retention | `internal/app/enterprise.go` | `accessCustomerPortalPackage` | `persistCriticalLocked` | +| enterprise identity and retention | `internal/app/enterprise.go` | `accessCustomerPortalPackage` | `persistCriticalLocked` | +| identity | `internal/app/identity_service.go` | `Authenticate` | `persistCriticalLocked` | +| identity | `internal/app/identity_service.go` | `Authenticate` | `persistCriticalLocked` | +| identity | `internal/app/identity_service.go` | `BootstrapTenant` | `persistCriticalLocked` | +| identity | `internal/app/identity_service.go` | `CreateAPIKey` | `persistCriticalLocked` | +| release ledger and signing | `internal/app/ledger.go` | `CreateReleaseBundle` | `persistCriticalLocked` | +| release ledger and signing | `internal/app/ledger.go` | `VerifySubject` | `persistCriticalLocked` | +| release ledger and signing | `internal/app/ledger.go` | `WithIdempotency` | `persistCriticalLocked` | + +## Focused Release And Evidence Mutations + +| Family | File | Function | Call | +| --- | --- | --- | --- | +| VEX and vulnerability decisions | `internal/app/vex.go` | `UploadVEX` | `persistReleaseLedgerWithOutboxLocked` | +| release extensions, source, and deployment | `internal/app/implementation_increments.go` | `RecordEvidenceLifecycleEvent` | `persistReleaseLedgerLocked` | +| release ledger and signing | `internal/app/ledger.go` | `ApproveRelease` | `persistReleaseLedgerLocked` | +| release ledger and signing | `internal/app/ledger.go` | `CreateEvidence` | `persistReleaseLedgerLocked` | +| release ledger and signing | `internal/app/ledger.go` | `CreateProduct` | `persistReleaseLedgerLocked` | +| release ledger and signing | `internal/app/ledger.go` | `CreateProject` | `persistReleaseLedgerLocked` | +| release ledger and signing | `internal/app/ledger.go` | `CreateRelease` | `persistReleaseLedgerLocked` | +| release ledger and signing | `internal/app/ledger.go` | `FreezeRelease` | `persistReleaseLedgerLocked` | +| release ledger and signing | `internal/app/ledger.go` | `LinkEvidence` | `persistReleaseLedgerLocked` | +| release ledger and signing | `internal/app/ledger.go` | `RegisterArtifact` | `persistReleaseLedgerLocked` | +| release ledger and signing | `internal/app/ledger.go` | `SupersedeEvidence` | `persistReleaseLedgerLocked` | +| release ledger and signing | `internal/app/ledger.go` | `UploadOpenAPIContract` | `persistReleaseLedgerWithOutboxLocked` | +| release ledger and signing | `internal/app/ledger.go` | `UploadSBOM` | `persistReleaseLedgerWithOutboxLocked` | +| release ledger and signing | `internal/app/ledger.go` | `UploadVulnerabilityScan` | `persistReleaseLedgerWithOutboxLocked` | +| risk and security workflows | `internal/app/risk_workflows.go` | `UploadCycloneDXVEX` | `persistReleaseLedgerWithOutboxLocked` | +| risk and security workflows | `internal/app/risk_workflows.go` | `UploadSPDXSBOM` | `persistReleaseLedgerLocked` | + +## Remaining Broad Relational-State Mutations + +| Family | File | Function | Call | +| --- | --- | --- | --- | +| VEX and vulnerability decisions | `internal/app/vex.go` | `ApproveException` | `persistLocked` | +| VEX and vulnerability decisions | `internal/app/vex.go` | `CreateException` | `persistLocked` | +| build provenance | `internal/app/builds.go` | `CreateBuildRun` | `persistLocked` | +| build provenance | `internal/app/builds.go` | `CreateCollector` | `persistLocked` | +| build provenance | `internal/app/builds.go` | `RecordCollectorRelease` | `persistLocked` | +| build provenance | `internal/app/builds.go` | `UploadBuildAttestation` | `persistLocked` | +| controls | `internal/app/controls.go` | `CreateControlFramework` | `persistLocked` | +| controls | `internal/app/controls.go` | `CreateSecurityControl` | `persistLocked` | +| controls | `internal/app/controls.go` | `LinkControlEvidence` | `persistLocked` | +| enterprise identity and retention | `internal/app/enterprise.go` | `CreateCommercialCollectorDefinition` | `persistLocked` | +| enterprise identity and retention | `internal/app/enterprise.go` | `CreateLegalHold` | `persistLocked` | +| enterprise identity and retention | `internal/app/enterprise.go` | `CreateOrganization` | `persistLocked` | +| enterprise identity and retention | `internal/app/enterprise.go` | `CreateQuestionnaireAnswerLibraryEntry` | `persistLocked` | +| enterprise identity and retention | `internal/app/enterprise.go` | `CreateQuestionnairePackage` | `persistLocked` | +| enterprise identity and retention | `internal/app/enterprise.go` | `CreateQuestionnaireTemplate` | `persistLocked` | +| enterprise identity and retention | `internal/app/enterprise.go` | `CreateRetentionOverride` | `persistLocked` | +| enterprise identity and retention | `internal/app/enterprise.go` | `CreateRoleBinding` | `persistLocked` | +| enterprise identity and retention | `internal/app/enterprise.go` | `CreateSSOProvider` | `persistLocked` | +| enterprise identity and retention | `internal/app/enterprise.go` | `CreateUser` | `persistLocked` | +| enterprise identity and retention | `internal/app/enterprise.go` | `DeactivateUser` | `persistLocked` | +| enterprise identity and retention | `internal/app/enterprise.go` | `ExchangeSSOCredential` | `persistLocked` | +| enterprise identity and retention | `internal/app/enterprise.go` | `ExchangeSSOCredential` | `persistLocked` | +| enterprise identity and retention | `internal/app/enterprise.go` | `ExchangeSSOCredential` | `persistLocked` | +| enterprise identity and retention | `internal/app/enterprise.go` | `LinkSSOIdentity` | `persistLocked` | +| enterprise identity and retention | `internal/app/enterprise.go` | `RefreshSSOProviderOIDCTrustMaterial` | `persistLocked` | +| enterprise identity and retention | `internal/app/enterprise.go` | `UpdateSSOProviderTrustMaterial` | `persistLocked` | +| future extensions and generated reports | `internal/app/future_extensions.go` | `CreateEvidenceSummary` | `persistLocked` | +| future extensions and generated reports | `internal/app/future_extensions.go` | `CreateGraphSnapshot` | `persistLocked` | +| future extensions and generated reports | `internal/app/future_extensions.go` | `CreateMarketplaceCollector` | `persistLocked` | +| future extensions and generated reports | `internal/app/future_extensions.go` | `CreatePDFReportPackage` | `persistLocked` | +| future extensions and generated reports | `internal/app/future_extensions.go` | `CreatePublicTransparencyLog` | `persistLocked` | +| future extensions and generated reports | `internal/app/future_extensions.go` | `CreateQuestionnaireDraft` | `persistLocked` | +| future extensions and generated reports | `internal/app/future_extensions.go` | `CreateSaaSEditionProfile` | `persistLocked` | +| future extensions and generated reports | `internal/app/future_extensions.go` | `CreateSigningOperation` | `persistLocked` | +| future extensions and generated reports | `internal/app/future_extensions.go` | `GenerateAnomalyReport` | `persistLocked` | +| future extensions and generated reports | `internal/app/future_extensions.go` | `PublishPublicTransparencyLogEntry` | `persistLocked` | +| future extensions and generated reports | `internal/app/future_extensions.go` | `VerifyProviderIdentity` | `persistLocked` | +| future extensions and generated reports | `internal/app/future_extensions.go` | `VerifyPublicTransparencyLogEntry` | `persistLocked` | +| governance, packages, and package reports | `internal/app/governance_packages.go` | `AccessCustomerSecurityPackage` | `persistLocked` | +| governance, packages, and package reports | `internal/app/governance_packages.go` | `ApproveWaiver` | `persistLocked` | +| governance, packages, and package reports | `internal/app/governance_packages.go` | `CRAReadinessHTMLPackage` | `persistLocked` | +| governance, packages, and package reports | `internal/app/governance_packages.go` | `CreateApprovalRecord` | `persistLocked` | +| governance, packages, and package reports | `internal/app/governance_packages.go` | `CreateCustomReportTemplate` | `persistLocked` | +| governance, packages, and package reports | `internal/app/governance_packages.go` | `CreateCustomerSecurityPackage` | `persistLocked` | +| governance, packages, and package reports | `internal/app/governance_packages.go` | `CreateDSSETrustRoot` | `persistLocked` | +| governance, packages, and package reports | `internal/app/governance_packages.go` | `CreateRedactionProfile` | `persistLocked` | +| governance, packages, and package reports | `internal/app/governance_packages.go` | `CreateWaiver` | `persistLocked` | +| governance, packages, and package reports | `internal/app/governance_packages.go` | `ExportEvidenceBundle` | `persistLocked` | +| governance, packages, and package reports | `internal/app/governance_packages.go` | `ImportEvidenceBundle` | `persistLocked` | +| governance, packages, and package reports | `internal/app/governance_packages.go` | `InstallControlFrameworkTemplatePack` | `persistLocked` | +| governance, packages, and package reports | `internal/app/governance_packages.go` | `RenderCustomReport` | `persistLocked` | +| governance, packages, and package reports | `internal/app/governance_packages.go` | `VerifyDSSEAttestationSignature` | `persistLocked` | +| integrity and operations | `internal/app/integrity_runtime.go` | `CreateMerkleBatch` | `persistLocked` | +| integrity and operations | `internal/app/integrity_runtime.go` | `CreateObjectRetentionPolicy` | `persistLocked` | +| integrity and operations | `internal/app/integrity_runtime.go` | `CreateSigningProvider` | `persistLocked` | +| integrity and operations | `internal/app/integrity_runtime.go` | `CreateTransparencyCheckpoint` | `persistLocked` | +| integrity and operations | `internal/app/integrity_runtime.go` | `GenerateBackupManifest` | `persistLocked` | +| integrity and operations | `internal/app/integrity_runtime.go` | `RevokeSigningKey` | `persistLocked` | +| integrity and operations | `internal/app/integrity_runtime.go` | `VerifyBackupManifest` | `persistLocked` | +| integrity and operations | `internal/app/integrity_runtime.go` | `VerifyCosignSignature` | `persistLocked` | +| integrity and operations | `internal/app/integrity_runtime.go` | `VerifyMerkleBatch` | `persistLocked` | +| integrity and operations | `internal/app/integrity_runtime.go` | `VerifyObjectRetentionPolicy` | `persistLocked` | +| release extensions, source, and deployment | `internal/app/implementation_increments.go` | `CreateArtifactSignature` | `persistLocked` | +| release extensions, source, and deployment | `internal/app/implementation_increments.go` | `CreateDeploymentEnvironment` | `persistLocked` | +| release extensions, source, and deployment | `internal/app/implementation_increments.go` | `CreateReleaseCandidate` | `persistLocked` | +| release extensions, source, and deployment | `internal/app/implementation_increments.go` | `CreateSourceRepository` | `persistLocked` | +| release extensions, source, and deployment | `internal/app/implementation_increments.go` | `RecordDeployment` | `persistLocked` | +| release extensions, source, and deployment | `internal/app/implementation_increments.go` | `RecordPullRequest` | `persistLocked` | +| release extensions, source, and deployment | `internal/app/implementation_increments.go` | `RecordSourceCommit` | `persistLocked` | +| release extensions, source, and deployment | `internal/app/implementation_increments.go` | `RegisterContainerImage` | `persistLocked` | +| release extensions, source, and deployment | `internal/app/implementation_increments.go` | `UpdateReleaseCandidateState` | `persistLocked` | +| release extensions, source, and deployment | `internal/app/implementation_increments.go` | `UpsertSourceBranch` | `persistLocked` | +| release extensions, source, and deployment | `internal/app/implementation_increments.go` | `UpsertSourceBranch` | `persistLocked` | +| release ledger and signing | `internal/app/ledger.go` | `EvaluateRelease` | `persistLocked` | +| release ledger and signing | `internal/app/ledger.go` | `RotateSigningKey` | `persistLocked` | +| risk and security workflows | `internal/app/risk_workflows.go` | `CreateContractDiff` | `persistLocked` | +| risk and security workflows | `internal/app/risk_workflows.go` | `CreateCustomPolicy` | `persistLocked` | +| risk and security workflows | `internal/app/risk_workflows.go` | `CreateIncident` | `persistLocked` | +| risk and security workflows | `internal/app/risk_workflows.go` | `CreateIncidentWebhookReceiver` | `persistLocked` | +| risk and security workflows | `internal/app/risk_workflows.go` | `CreateRemediationTask` | `persistLocked` | +| risk and security workflows | `internal/app/risk_workflows.go` | `CreateSBOMDiff` | `persistLocked` | +| risk and security workflows | `internal/app/risk_workflows.go` | `EvaluateCustomPolicy` | `persistLocked` | +| risk and security workflows | `internal/app/risk_workflows.go` | `HandleIncidentWebhook` | `persistLocked` | +| risk and security workflows | `internal/app/risk_workflows.go` | `RecordIncidentTimelineEvent` | `persistLocked` | +| risk and security workflows | `internal/app/risk_workflows.go` | `RecordVulnerabilityWorkflow` | `persistLocked` | +| risk and security workflows | `internal/app/risk_workflows.go` | `UploadManualSecurityDocument` | `persistLocked` | +| risk and security workflows | `internal/app/risk_workflows.go` | `uploadSecurityScan` | `persistLocked` | + +## Next Decomposition Order + +1. Package and report writes: customer package access counters, generated HTML/PDF/report rows, evidence bundles, questionnaire outputs, and customer-facing access records. +2. Controls and governance writes: frameworks, controls, control evidence, waivers, approvals, and custom policies. +3. Build/source/deployment writes: build runs, attestations, source snapshots, release candidates, image/signature records, and deployment events. +4. Integrity and operations writes: signing providers, signing operations, Merkle batches, transparency checkpoints, retention policies, backup manifests, and verification receipts. +5. Future-extension rows: marketplace collectors, public transparency items, graph snapshots, SaaS profile records, PDF/anomaly reports, and AI/questionnaire draft artifacts. + +## Regression Checks + +- `go test ./internal/app -run TestRelationalStateStore` proves representative broad relational-state families avoid aggregate `SaveState` when `SaveRelationalState` is available. +- `go test ./internal/adapters/postgres -run 'TestApply(Critical|ReleaseLedger)Mutation'` proves focused mutations write relational tables and avoid the compatibility snapshot row. +- `make persistence-decomposition-check` regenerates this inventory and fails when the documented call-site map drifts. + +## Limitations + +This inventory is a repository-local decomposition map. It is not evidence of legal compliance, certification, complete operational hardening, or multi-writer API safety. diff --git a/docs/reference/production-readiness.md b/docs/reference/production-readiness.md index f5c1db9..089bb42 100644 --- a/docs/reference/production-readiness.md +++ b/docs/reference/production-readiness.md @@ -50,6 +50,10 @@ Known hardening work remains: batch, transparency checkpoint, evidence lifecycle, release candidate, VEX/risk decision, control, package, report, retention, provider verification, signing operation, and future-extension state from relational rows; + the generated + [Persistence decomposition inventory](persistence-decomposition.md) is the + repository-owned map of focused mutation paths, remaining broad + relational-state call sites, and the next split order; - worker parser jobs re-read raw object-store payloads for key formats, verify digests, validate durable state, and persist missing parser-derived normalized fields. CycloneDX SBOM, generic vulnerability-scan, OpenAPI diff --git a/docs/reference/roadmap.md b/docs/reference/roadmap.md index 9f2ab32..7ed7883 100644 --- a/docs/reference/roadmap.md +++ b/docs/reference/roadmap.md @@ -30,7 +30,9 @@ status. See [HA strategy](ha-strategy.md) for the decision record. `report.html` exports are the supported reviewer view, and a server-backed internal dashboard remains deferred until a pilot proves it is necessary; - continue reducing large service surfaces while preserving tenant isolation, - append-only evidence behavior, and safe error handling. + append-only evidence behavior, and safe error handling. The + [Persistence decomposition inventory](persistence-decomposition.md) is the + current generated map for that work. ## Later Production Hardening diff --git a/docs/reference/source-of-truth.md b/docs/reference/source-of-truth.md index 311a81a..11e3367 100644 --- a/docs/reference/source-of-truth.md +++ b/docs/reference/source-of-truth.md @@ -15,6 +15,7 @@ product-boundary language across the docs. | Kubernetes | `docs/kubernetes.md` | Helm-specific operator interface. | | Hardened self-hosted topology | `docs/reference/hardened-reference-deployment.md` | One API writer, scalable workers, external PostgreSQL/object storage, TLS, secrets, backups, monitoring, signing, and operator-owned evidence. | | HA and concurrency decision | `docs/reference/ha-strategy.md` | Current single-writer appliance decision, recovery boundaries, and multi-writer prerequisites. | +| Persistence decomposition inventory | `docs/reference/persistence-decomposition.md` | Generated map of focused mutation paths, remaining broad relational-state call sites, next split order, and regression checks. | | Release validation | `docs/reference/release-validation.md` | Canonical release gate behavior. | | Release-candidate evidence | `docs/reference/release-candidate.md` | Canonical release-candidate artifact checklist. | | Release evidence artifact map | `docs/reference/release-evidence-index.md` | Maps each release artifact to generation and verification commands. | diff --git a/internal/app/critical_mutation_test.go b/internal/app/critical_mutation_test.go index 1faeb11..f9cfd25 100644 --- a/internal/app/critical_mutation_test.go +++ b/internal/app/critical_mutation_test.go @@ -508,3 +508,168 @@ func TestRelationalStateStoreAvoidsAggregateSaveForRemainingFamilies(t *testing. t.Fatalf("relational state missed customer package: %#v", got) } } + +func TestRelationalStateStoreCoversPackageAndReportWriteFamilies(t *testing.T) { + ctx := context.Background() + store := &fullRelationalStoreSpy{} + ledger := NewLedger(Config{APIKeyPepper: "test-pepper", Now: fixedNow, Store: store}) + _, _, secret, err := ledger.BootstrapTenant(ctx, "Tenant", "admin", []string{"*"}) + if err != nil { + t.Fatalf("bootstrap: %v", err) + } + actor, err := ledger.Authenticate(ctx, secret) + if err != nil { + t.Fatalf("authenticate: %v", err) + } + product, err := ledger.CreateProduct(ctx, actor, "Payments", "payments-package-report-state") + if err != nil { + t.Fatalf("create product: %v", err) + } + release, err := ledger.CreateRelease(ctx, actor, product.ID, "1.0.0") + if err != nil { + t.Fatalf("create release: %v", err) + } + evidence, err := ledger.CreateEvidence(ctx, actor, CreateEvidenceInput{ + ProductID: product.ID, + ReleaseID: release.ID, + Type: "security_review", + Title: "Security review", + PayloadHash: sampleDigest("package-report-evidence"), + }) + if err != nil { + t.Fatalf("create evidence: %v", err) + } + profile, err := ledger.CreateRedactionProfile(ctx, actor, CreateRedactionProfileInput{Name: "Customer Safe", AllowedTypes: []string{"security_review"}}) + if err != nil { + t.Fatalf("create redaction profile: %v", err) + } + pkg, err := ledger.CreateCustomerSecurityPackage(ctx, actor, CreateCustomerPackageInput{ + ProductID: product.ID, + ReleaseID: release.ID, + RedactionProfileID: profile.ID, + Title: "Customer package", + ExpiresAt: fixedNow().Add(time.Hour), + }) + if err != nil { + t.Fatalf("create customer package: %v", err) + } + if pkg.TenantID != actor.TenantID || pkg.ReleaseID != release.ID { + t.Fatalf("customer package setup = %#v", pkg) + } + if _, err := ledger.CreateControlFramework(ctx, actor, CreateControlFrameworkInput{Name: "CRA Readiness", Slug: "cra-readiness-package-report", Version: "1.0.0"}); err != nil { + t.Fatalf("create control framework: %v", err) + } + + store.reset() + htmlReport, err := ledger.CRAReadinessHTMLPackage(ctx, actor, product.ID, release.ID) + if err != nil { + t.Fatalf("cra html report: %v", err) + } + if store.saveCalls != 0 || store.relationalCalls != 1 { + t.Fatalf("html report persistence save=%d relational=%d", store.saveCalls, store.relationalCalls) + } + if got := store.states[0].HTMLReports[htmlReport.ID]; got.ID != htmlReport.ID || got.TenantID != actor.TenantID || got.ReleaseID != release.ID { + t.Fatalf("relational state missed html report: %#v", got) + } + if len(store.states[0].Chain[actor.TenantID]) == 0 { + t.Fatal("html report relational state missed audit chain") + } + + store.reset() + template, err := ledger.CreateCustomReportTemplate(ctx, actor, CreateReportTemplateInput{ + Name: "Reviewer report", Version: "1", ReportType: "reviewer", AllowedFields: []string{"subject_type", "subject_id"}, + }) + if err != nil { + t.Fatalf("create report template: %v", err) + } + rendered, err := ledger.RenderCustomReport(ctx, actor, RenderReportInput{TemplateID: template.ID, SubjectType: "release", SubjectID: release.ID}) + if err != nil { + t.Fatalf("render report: %v", err) + } + if store.saveCalls != 0 || store.relationalCalls != 2 { + t.Fatalf("custom report persistence save=%d relational=%d", store.saveCalls, store.relationalCalls) + } + lastCustomReportState := store.states[len(store.states)-1] + if got := lastCustomReportState.ReportTemplates[template.ID]; got.ID != template.ID || got.TenantID != actor.TenantID { + t.Fatalf("relational state missed report template: %#v", got) + } + if got := lastCustomReportState.RenderedReports[rendered.ID]; got.ID != rendered.ID || got.TenantID != actor.TenantID { + t.Fatalf("relational state missed rendered report: %#v", got) + } + + store.reset() + bundle, err := ledger.ExportEvidenceBundle(ctx, actor, release.ID, []string{evidence.ID}) + if err != nil { + t.Fatalf("export evidence bundle: %v", err) + } + imported, err := ledger.ImportEvidenceBundle(ctx, actor, bundle) + if err != nil { + t.Fatalf("import evidence bundle: %v", err) + } + if store.saveCalls != 0 || store.relationalCalls != 2 { + t.Fatalf("evidence bundle persistence save=%d relational=%d", store.saveCalls, store.relationalCalls) + } + lastBundleState := store.states[len(store.states)-1] + if got := lastBundleState.EvidenceBundles[bundle.ID]; got.ID != bundle.ID || got.TenantID != actor.TenantID || len(got.SignatureRefs) == 0 { + t.Fatalf("relational state missed evidence bundle: %#v", got) + } + if got := lastBundleState.BundleImports[imported.ID]; got.ID != imported.ID || got.TenantID != actor.TenantID { + t.Fatalf("relational state missed bundle import: %#v", got) + } + if len(lastBundleState.SigningKeyPrivate) == 0 || len(lastBundleState.Signatures) == 0 { + t.Fatalf("relational state missed bundle signing material: keys=%#v signatures=%#v", lastBundleState.SigningKeyPrivate, lastBundleState.Signatures) + } + + store.reset() + summary, err := ledger.CreateEvidenceSummary(ctx, actor, CreateEvidenceSummaryInput{SubjectType: "release", SubjectID: release.ID, EvidenceIDs: []string{evidence.ID}}) + if err != nil { + t.Fatalf("create evidence summary: %v", err) + } + pdf, err := ledger.CreatePDFReportPackage(ctx, actor, CreatePDFReportPackageInput{ReportType: "customer_review", ProductID: product.ID, ReleaseID: release.ID, Title: "Customer review"}) + if err != nil { + t.Fatalf("create pdf report: %v", err) + } + anomaly, err := ledger.GenerateAnomalyReport(ctx, actor, AnomalyReportInput{SubjectType: "release", SubjectID: release.ID}) + if err != nil { + t.Fatalf("generate anomaly report: %v", err) + } + if store.saveCalls != 0 || store.relationalCalls != 3 { + t.Fatalf("future report persistence save=%d relational=%d", store.saveCalls, store.relationalCalls) + } + lastFutureReportState := store.states[len(store.states)-1] + if got := lastFutureReportState.EvidenceSummaries[summary.ID]; got.ID != summary.ID || got.TenantID != actor.TenantID { + t.Fatalf("relational state missed evidence summary: %#v", got) + } + if got := lastFutureReportState.PDFReports[pdf.ID]; got.ID != pdf.ID || got.TenantID != actor.TenantID || got.PayloadHash == "" { + t.Fatalf("relational state missed pdf report: %#v", got) + } + if got := lastFutureReportState.AnomalyReports[anomaly.ID]; got.ID != anomaly.ID || got.TenantID != actor.TenantID { + t.Fatalf("relational state missed anomaly report: %#v", got) + } + + store.reset() + questionnaire, err := ledger.CreateQuestionnaireTemplate(ctx, actor, CreateQuestionnaireTemplateInput{ + Name: "Customer questionnaire", + Version: "1", + Questions: []domain.QuestionnaireQuestion{{ + ID: "q1", Prompt: "Is review evidence available?", EvidenceType: "security_review", + }}, + }) + if err != nil { + t.Fatalf("create questionnaire template: %v", err) + } + draft, err := ledger.CreateQuestionnaireDraft(ctx, actor, CreateQuestionnaireDraftInput{TemplateID: questionnaire.ID, ProductID: product.ID, ReleaseID: release.ID}) + if err != nil { + t.Fatalf("create questionnaire draft: %v", err) + } + if store.saveCalls != 0 || store.relationalCalls != 2 { + t.Fatalf("questionnaire persistence save=%d relational=%d", store.saveCalls, store.relationalCalls) + } + lastQuestionnaireState := store.states[len(store.states)-1] + if got := lastQuestionnaireState.QuestionnaireTemplates[questionnaire.ID]; got.ID != questionnaire.ID || got.TenantID != actor.TenantID { + t.Fatalf("relational state missed questionnaire template: %#v", got) + } + if got := lastQuestionnaireState.QuestionnaireDrafts[draft.ID]; got.ID != draft.ID || got.TenantID != actor.TenantID || got.ReleaseID != release.ID { + t.Fatalf("relational state missed questionnaire draft: %#v", got) + } +} diff --git a/scripts/persistence_decomposition_inventory.py b/scripts/persistence_decomposition_inventory.py new file mode 100755 index 0000000..8ceee58 --- /dev/null +++ b/scripts/persistence_decomposition_inventory.py @@ -0,0 +1,168 @@ +#!/usr/bin/env python3 +"""Generate and validate Evydence persistence decomposition inventory.""" + +from __future__ import annotations + +import argparse +import difflib +import re +import sys +from dataclasses import dataclass +from pathlib import Path + + +REPO_ROOT = Path(__file__).resolve().parents[1] +APP_ROOT = REPO_ROOT / "internal" / "app" +OUTPUT = REPO_ROOT / "docs" / "reference" / "persistence-decomposition.md" + +FUNC_RE = re.compile(r"^func\s+(?:\([^)]*\)\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*\(") + + +@dataclass(frozen=True) +class PersistCall: + file: str + function: str + call: str + + +FAMILY_BY_FILE = { + "builds.go": "build provenance", + "controls.go": "controls", + "enterprise.go": "enterprise identity and retention", + "future_extensions.go": "future extensions and generated reports", + "governance_packages.go": "governance, packages, and package reports", + "identity_service.go": "identity", + "implementation_increments.go": "release extensions, source, and deployment", + "integrity_runtime.go": "integrity and operations", + "ledger.go": "release ledger and signing", + "risk_workflows.go": "risk and security workflows", + "state.go": "persistence helpers", + "vex.go": "VEX and vulnerability decisions", +} + + +def collect_calls() -> list[PersistCall]: + calls: list[PersistCall] = [] + for path in sorted(APP_ROOT.glob("*.go")): + if path.name.endswith("_test.go") or path.name == "state.go": + continue + current = "package-scope" + for line in path.read_text(encoding="utf-8").splitlines(): + match = FUNC_RE.match(line) + if match: + current = match.group(1) + continue + for call in ( + "persistCriticalLocked", + "persistReleaseLedgerLocked", + "persistReleaseLedgerWithOutboxLocked", + "persistLocked", + ): + if f".{call}(ctx" in line or f" {call}(ctx" in line: + calls.append(PersistCall(path.name, current, call)) + return calls + + +def render_table(calls: list[PersistCall]) -> list[str]: + if not calls: + return ["| Family | File | Function | Call |", "| --- | --- | --- | --- |", "| none | none | none | none |"] + rows = ["| Family | File | Function | Call |", "| --- | --- | --- | --- |"] + for call in sorted(calls, key=lambda c: (FAMILY_BY_FILE.get(c.file, c.file), c.file, c.function, c.call)): + rows.append( + "| " + + " | ".join( + [ + FAMILY_BY_FILE.get(call.file, "unclassified"), + f"`internal/app/{call.file}`", + f"`{call.function}`", + f"`{call.call}`", + ] + ) + + " |" + ) + return rows + + +def render(calls: list[PersistCall]) -> str: + critical = [c for c in calls if c.call == "persistCriticalLocked"] + release = [c for c in calls if c.call in {"persistReleaseLedgerLocked", "persistReleaseLedgerWithOutboxLocked"}] + broad = [c for c in calls if c.call == "persistLocked"] + lines: list[str] = [ + "# Persistence Decomposition Inventory", + "", + "This reference is generated by `scripts/persistence_decomposition_inventory.py`.", + "Update it with `scripts/persistence_decomposition_inventory.py --write` after persistence call sites change.", + "", + "Purpose: keep the production persistence story inspectable while Evydence continues splitting the large application ledger into focused repository paths.", + "", + "## Current Production Contract", + "", + "- Production PostgreSQL startup uses relational-only reconstruction.", + "- Production writes do not create or update the compatibility `ledger_state` snapshot row.", + "- `persistCriticalLocked` writes high-risk identity, key, idempotency, signing, verification, bundle, provider-verification, decision, audit-chain, and outbox state through focused PostgreSQL transactions when the store supports them.", + "- `persistReleaseLedgerLocked` and `persistReleaseLedgerWithOutboxLocked` write release-ledger and evidence-core state through focused PostgreSQL transactions when the store supports them.", + "- Remaining direct `persistLocked` call sites use `SaveRelationalState` with the PostgreSQL store, not `SaveState`; compatibility `SaveState` remains for memory/local/demo/import paths.", + "- One API writer replica remains the supported production candidate topology until every write family has focused repository paths or a reviewed optimistic-concurrency design.", + "", + "## Focused Critical Mutations", + "", + *render_table(critical), + "", + "## Focused Release And Evidence Mutations", + "", + *render_table(release), + "", + "## Remaining Broad Relational-State Mutations", + "", + *render_table(broad), + "", + "## Next Decomposition Order", + "", + "1. Package and report writes: customer package access counters, generated HTML/PDF/report rows, evidence bundles, questionnaire outputs, and customer-facing access records.", + "2. Controls and governance writes: frameworks, controls, control evidence, waivers, approvals, and custom policies.", + "3. Build/source/deployment writes: build runs, attestations, source snapshots, release candidates, image/signature records, and deployment events.", + "4. Integrity and operations writes: signing providers, signing operations, Merkle batches, transparency checkpoints, retention policies, backup manifests, and verification receipts.", + "5. Future-extension rows: marketplace collectors, public transparency items, graph snapshots, SaaS profile records, PDF/anomaly reports, and AI/questionnaire draft artifacts.", + "", + "## Regression Checks", + "", + "- `go test ./internal/app -run TestRelationalStateStore` proves representative broad relational-state families avoid aggregate `SaveState` when `SaveRelationalState` is available.", + "- `go test ./internal/adapters/postgres -run 'TestApply(Critical|ReleaseLedger)Mutation'` proves focused mutations write relational tables and avoid the compatibility snapshot row.", + "- `make persistence-decomposition-check` regenerates this inventory and fails when the documented call-site map drifts.", + "", + "## Limitations", + "", + "This inventory is a repository-local decomposition map. It is not evidence of legal compliance, certification, complete operational hardening, or multi-writer API safety.", + "", + ] + return "\n".join(lines) + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--write", action="store_true", help="write generated inventory to docs/reference/persistence-decomposition.md") + parser.add_argument("--check", action="store_true", help="fail if the generated inventory differs from the committed file") + args = parser.parse_args() + body = render(collect_calls()) + if args.write: + OUTPUT.write_text(body, encoding="utf-8") + return 0 + if args.check: + current = OUTPUT.read_text(encoding="utf-8") if OUTPUT.exists() else "" + if current != body: + diff = difflib.unified_diff( + current.splitlines(), + body.splitlines(), + fromfile=str(OUTPUT), + tofile="generated", + lineterm="", + ) + print("\n".join(diff), file=sys.stderr) + return 1 + return 0 + print(body) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) From f7fddab36f14759831ca7d187224feaab45af1d6 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 20:06:50 +0300 Subject: [PATCH 274/287] docs(openapi): publish rendered api reference --- Makefile | 13 +- README.md | 1 + docs/README.md | 2 + docs/api.md | 1 + docs/openapi/index.html | 5228 +++++++++++++++++++ docs/reference/openapi.md | 33 +- docs/reference/source-of-truth.md | 2 +- scripts/render_openapi_docs.py | 456 ++ site/marketing/public/api/index.html | 5228 +++++++++++++++++++ site/marketing/scripts/check.mjs | 4 + site/marketing/src/layouts/BaseLayout.astro | 3 + 11 files changed, 10967 insertions(+), 4 deletions(-) create mode 100644 docs/openapi/index.html create mode 100755 scripts/render_openapi_docs.py create mode 100644 site/marketing/public/api/index.html diff --git a/Makefile b/Makefile index b1f3ccb..c409e3d 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ GOVULNCHECK_VERSION ?= v1.2.0 TAG ?= -.PHONY: help tools fmt lint vuln gosec test test-race fuzz-smoke coverage coverage-check openapi-check openapi-precision-check meta-check release-truth-check persistence-decomposition-check docs-check deploy-check sdk-check demo-check customer-cve-review-demo-check local-ci-simulation-check reviewer-package-workflow-check black-box-demo-check black-box-release-artifact-check benchmark-check package-viewer-check marketing-site-check marketing-site-production-check restore-rehearsal-check fast-check finalize release-acceptance release-check production-check release-candidate-check public-release-verify migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean +.PHONY: help tools fmt lint vuln gosec test test-race fuzz-smoke coverage coverage-check openapi-check openapi-precision-check rendered-openapi-check meta-check release-truth-check persistence-decomposition-check docs-check deploy-check sdk-check demo-check customer-cve-review-demo-check local-ci-simulation-check reviewer-package-workflow-check black-box-demo-check black-box-release-artifact-check benchmark-check package-viewer-check marketing-site-check marketing-site-production-check restore-rehearsal-check fast-check finalize release-acceptance release-check production-check release-candidate-check public-release-verify migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean help: ## Show help @awk 'BEGIN {FS=":.*## "}; /^[a-zA-Z0-9_.-]+:.*## / { printf " %-18s %s\n", $$1, $$2 }' $(MAKEFILE_LIST) @@ -54,10 +54,14 @@ openapi-check: openapi.yaml ## Validate OpenAPI generation and route contract te @$(GO) test ./internal/adapters/httpapi -run 'TestRoutesValidateAndOpenAPIRenders' @$(GO) run ./cmd/openapi > /tmp/evydence-openapi.yaml @cmp -s openapi.yaml /tmp/evydence-openapi.yaml + @scripts/render_openapi_docs.py --check openapi-precision-check: ## Enforce current OpenAPI precision floor and broad-route ceiling @python3 scripts/openapi_precision_check.py +rendered-openapi-check: ## Validate generated static OpenAPI docs + @scripts/render_openapi_docs.py --check + meta-check: ## Validate root legal, governance, support, and release-evidence metadata @test -f LICENSE @test -f COMMERCIAL.md @@ -140,7 +144,7 @@ release-truth-check: ## Validate current release metadata against public docs an persistence-decomposition-check: ## Validate generated persistence decomposition inventory @scripts/persistence_decomposition_inventory.py --check -docs-check: meta-check release-truth-check persistence-decomposition-check ## Validate canonical docs exist and avoid forbidden product claims +docs-check: meta-check release-truth-check persistence-decomposition-check rendered-openapi-check ## Validate canonical docs exist and avoid forbidden product claims @test -f README.md @test -f .production.env.example @test -f docs/README.md @@ -164,6 +168,8 @@ docs-check: meta-check release-truth-check persistence-decomposition-check ## Va @test -f docs/reference/capability-map.md @test -f docs/reference/api-contract-matrix.md @test -f docs/reference/openapi.md + @test -f docs/openapi/index.html + @test -f site/marketing/public/api/index.html @test -f docs/reference/vulnerability-decisions.md @test -f docs/reference/observability.md @test -f docs/reference/capacity-and-failures.md @@ -221,6 +227,7 @@ docs-check: meta-check release-truth-check persistence-decomposition-check ## Va "reference/capability-map.md" \ "reference/api-contract-matrix.md" \ "reference/openapi.md" \ + "openapi/index.html" \ "reference/vulnerability-decisions.md" \ "reference/observability.md" \ "reference/capacity-and-failures.md" \ @@ -280,6 +287,8 @@ docs-check: meta-check release-truth-check persistence-decomposition-check ## Va @grep -F 'Buyer evaluation overview' README.md docs/README.md >/dev/null @grep -F 'Operator overview' README.md docs/README.md >/dev/null @grep -F 'OpenAPI reference' README.md >/dev/null + @grep -F 'Rendered OpenAPI docs' README.md docs/README.md docs/reference/openapi.md >/dev/null + @grep -F 'site/marketing/public/api/index.html' docs/reference/openapi.md >/dev/null @grep -F 'Install and operate' README.md >/dev/null @grep -F 'Fastest Buyer Path' docs/buyer-overview.md >/dev/null @grep -F 'Primary Operator Path' docs/operator-overview.md >/dev/null diff --git a/README.md b/README.md index a71b9ce..220f0bb 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ customer package that support the answer. | [Buyer evaluation overview](docs/buyer-overview.md) | Follow the buyer package, demo, release-evidence, and API review path. | | [Operator overview](docs/operator-overview.md) | Follow the self-hosted install, runbook, and production-gate path. | | [OpenAPI reference](docs/reference/openapi.md) | Review the `/v1` API contract and generated schemas. | +| [Rendered OpenAPI docs](docs/openapi/index.html) | Browse the generated static operation and schema reference. | | [Install and operate](docs/how-to/install-and-operate.md) | Run the self-hosted API/worker path with PostgreSQL and object storage. | | [Release evidence index](docs/reference/release-evidence-index.md) | Verify public release artifacts, checksums, production-check evidence, and limitations. | diff --git a/docs/README.md b/docs/README.md index 3e72a70..55c5e71 100644 --- a/docs/README.md +++ b/docs/README.md @@ -12,6 +12,7 @@ This documentation is organized by reader task. Implementation claims should be - [Install and operate](how-to/install-and-operate.md): choose a local runtime mode, start dependencies, run migrations, and launch API/worker processes. - [Operations](operations.md): find the canonical operator references for configuration, workers, CI, deployment, and validation. - [API reference](api.md): integrate with the `/v1` HTTP API using authentication, idempotency, examples, and endpoint tables. +- [Rendered OpenAPI docs](openapi/index.html): browse the generated static operation and schema reference. ## How-To Guides @@ -37,6 +38,7 @@ This documentation is organized by reader task. Implementation claims should be - [Capability map](reference/capability-map.md): advanced inventory of implemented capabilities, implementation limits, and implemented-but-partial areas. - [API contract matrix](reference/api-contract-matrix.md): generated route-by-route contract precision inventory for production hardening. - [OpenAPI contract](reference/openapi.md): generation, drift checks, and review tips for `openapi.yaml`. +- [Rendered OpenAPI docs](openapi/index.html): static page generated from the committed OpenAPI contract. - [Vulnerability decisions](reference/vulnerability-decisions.md): current VEX/decision model, buyer-facing gaps, and planned API changes. - [Customer package manifest](reference/customer-package-manifest.md): v2 package schema, included metadata, exclusions, and local viewer compatibility. - [Observability](reference/observability.md): readiness, admin metrics, Prometheus rules, and dashboard starter assets. diff --git a/docs/api.md b/docs/api.md index 6ea9734..92675ed 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1,6 +1,7 @@ # API Reference The public API base path is `/v1`. The generated contract is committed at [`../openapi.yaml`](../openapi.yaml) and served by the API at `/v1/openapi.json`. +The static rendered companion is committed at [`openapi/index.html`](openapi/index.html) for browser-based review of operations and schemas. Use this page for common integration workflows and route lookup. The endpoint catalog is expected to list every path in `openapi.yaml`; the generated contract remains the source of truth for operation details, schemas, status codes, security metadata, and route drift checks. The OpenAPI contract also includes non-sensitive examples for the main release evidence flow: create release, upload SBOM, upload vulnerability scan, record a vulnerability decision, read release readiness, and create a customer package. diff --git a/docs/openapi/index.html b/docs/openapi/index.html new file mode 100644 index 0000000..bb1407d --- /dev/null +++ b/docs/openapi/index.html @@ -0,0 +1,5228 @@ + + + + + + Evydence API - Rendered OpenAPI Docs + + + +
+

Evydence API

+

Self-hosted API evidence and compliance-readiness ledger.

+

This page is generated from openapi.yaml. It is a human-readable companion to the committed contract and does not replace route-contract tests.

+
+
3.1.0OpenAPI version
+
169registered paths
+
186operations
+
375schemas
+
+
+
+
+

Runtime secrets, tenant data, raw evidence payloads, private keys, bearer tokens, and customer package contents are not embedded in this generated page. Admin-scoped routes appear only when they are part of the committed public contract.

+

Error responses use RFC 9457-style Problem Details. The registered Problem schema currently requires: none.

+
+ +
+

Operations

+
+ + +
+
+ +
+
+ GET + /v1/admin/instance +
+

Instance admin snapshot

+

Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.

+
+
Operation ID
instanceAdminSnapshot
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
instance:admin
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: InstanceAdminSnapshotEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/api-keys +
+

List API keys

+

Lists tenant-scoped API key metadata without key hashes or one-time secrets.

+
+
Operation ID
listAPIKeys
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
admin
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: APIKeyListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/api-keys +
+

Create API key

+

Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.

+
+
Operation ID
createAPIKey
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateAPIKeyRequest
+
Responses
201 application/json: APIKeyCreateEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/api-security-scans +
+

Upload API security scan

+

Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.

+
+
Operation ID
uploadAPISecurityScan
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
security:write
+
Idempotency
Idempotency-Key
+
Request
application/json: UploadSecurityScanRequest
+
Responses
201 application/json: SecurityScanEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/approvals +
+

Create approval record

+

Creates an immutable approval record for a release, waiver, package, or review subject.

+
+
Operation ID
createApproval
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
release:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateApprovalRequest
+
Responses
201 application/json: ApprovalRecordEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/artifact-signatures +
+

Create artifact signature

+

Records detached artifact signature evidence and optional raw signature payload metadata.

+
+
Operation ID
createArtifactSignature
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateArtifactSignatureRequest
+
Responses
201 application/json: ArtifactSignatureEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/artifact-signatures/{id} +
+

Get artifact signature

+

Returns tenant-scoped artifact signature metadata by id.

+
+
Operation ID
getArtifactSignature
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ArtifactSignatureEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/artifact-signatures/{id}/verify-cosign +
+

Verify cosign-style artifact signature

+

Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.

+
+
Operation ID
verifyCosignSignature
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
verify:read
+
Idempotency
Idempotency-Key
+
Request
application/json: VerifyCosignSignatureRequest
+
Responses
200 application/json: CosignVerificationEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/artifacts +
+

Register artifact

+

Registers an artifact digest for release evidence and later build/attestation matching.

+
+
Operation ID
registerArtifact
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:write
+
Idempotency
Idempotency-Key
+
Request
application/json: RegisterArtifactRequest
+
Responses
201 application/json: ArtifactEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/artifacts/{id} +
+

Get artifact

+

Returns a tenant-scoped artifact by id.

+
+
Operation ID
getArtifact
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ArtifactEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/audit-chain/verify +
+

Verify audit chain

+

Verifies the tenant audit chain continuity and returns deterministic verification checks.

+
+
Operation ID
verifyAuditChain
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
verify:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: VerificationResultEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/audit-log +
+

List tenant audit log

+

Lists tenant-scoped append-only audit-chain entries in reverse chronological order.

+
+
Operation ID
listAuditLog
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
admin
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: AuditChainEntryListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/backup-manifests +
+

Generate backup manifest

+

Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.

+
+
Operation ID
generateBackupManifest
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
admin
+
Idempotency
Idempotency-Key
+
Request
application/json: EmptyObject
+
Responses
201 application/json: BackupManifestEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/backup-manifests/{id}/verify +
+

Verify backup manifest

+

Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.

+
+
Operation ID
verifyBackupManifest
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
verify:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: VerificationResultEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/build-attestations/{id}/verify-signature +
+

Verify build attestation signature

+

Verifies a build attestation signature against configured tenant DSSE trust roots.

+
+
Operation ID
verifyBuildAttestationSignature
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
verify:read
+
Idempotency
Idempotency-Key
+
Request
application/json: EmptyObject
+
Responses
200 application/json: VerificationResultEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/builds +
+

Create build run

+

Records an immutable CI build run. Collector identity is derived from the authenticated key when present.

+
+
Operation ID
createBuild
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
build:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateBuildRequest
+
Responses
201 application/json: BuildRunEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/builds/{id} +
+

Get build run

+

Returns a tenant-scoped build run by id.

+
+
Operation ID
getBuild
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
build:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: BuildRunEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/builds/{id}/attestations +
+

Upload build attestation

+

Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.

+
+
Operation ID
uploadBuildAttestation
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
build:write
+
Idempotency
Idempotency-Key
+
Request
application/json: DSSEEnvelope
+
Responses
201 application/json: BuildAttestationEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/collectors +
+

List collectors

+

Lists tenant-scoped collector metadata without API key hashes or one-time secrets.

+
+
Operation ID
listCollectors
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
collector:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: CollectorListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/collectors +
+

Create collector

+

Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.

+
+
Operation ID
createCollector
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
collector:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateCollectorRequest
+
Responses
201 application/json: CollectorCreateEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/collectors/github/source-snapshots +
+

Upload GitHub source snapshot

+

Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.

+
+
Operation ID
uploadGitHubSourceSnapshot
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
source:write
+
Idempotency
Idempotency-Key
+
Request
application/json: SourceSnapshotRequest
+
Responses
201 application/json: SourceSnapshotEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/collectors/gitlab/source-snapshots +
+

Upload GitLab source snapshot

+

Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.

+
+
Operation ID
uploadGitLabSourceSnapshot
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
source:write
+
Idempotency
Idempotency-Key
+
Request
application/json: SourceSnapshotRequest
+
Responses
201 application/json: SourceSnapshotEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/collectors/{id}/health +
+

Collector health report

+

Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.

+
+
Operation ID
collectorHealthReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
collector:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: CollectorHealthReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/collectors/{id}/releases +
+

Record collector release evidence

+

Records collector release supply-chain evidence for a tenant-scoped collector.

+
+
Operation ID
recordCollectorRelease
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
collector:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: RecordCollectorReleaseRequest
+
Responses
201 application/json: CollectorReleaseEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/commercial-collectors +
+

List commercial collector definitions

+

Lists tenant-scoped commercial collector definitions.

+
+
Operation ID
listCommercialCollectors
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
collector:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: CommercialCollectorDefinitionListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/commercial-collectors +
+

Create commercial collector definition

+

Creates tenant-scoped commercial collector metadata without installing external code.

+
+
Operation ID
createCommercialCollector
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
collector:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateCommercialCollectorRequest
+
Responses
201 application/json: CommercialCollectorDefinitionEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/container-images +
+

Register container image

+

Registers OCI/container image metadata and digest evidence linked to an optional artifact.

+
+
Operation ID
registerContainerImage
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:write
+
Idempotency
Idempotency-Key
+
Request
application/json: RegisterContainerImageRequest
+
Responses
201 application/json: ContainerImageEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/control-evidence +
+

List control evidence

+

Lists tenant-scoped control evidence links with optional control, product, and release filters.

+
+
Operation ID
listControlEvidence
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
controls:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ControlEvidenceListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/control-framework-template-packs +
+

List control framework template packs

+

Lists built-in control framework template packs available for explicit tenant installation.

+
+
Operation ID
listControlFrameworkTemplatePacks
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
controls:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ControlFrameworkTemplatePackListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/control-framework-template-packs/{slug}/install +
+

Install control framework template pack

+

Installs a named control framework template pack into the tenant as ordinary framework/control records.

+
+
Operation ID
installControlFrameworkTemplatePack
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
controls:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: EmptyObject
+
Responses
201 application/json: ControlFrameworkEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/control-frameworks +
+

List control frameworks

+

Lists tenant-scoped control frameworks.

+
+
Operation ID
listControlFrameworks
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
controls:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ControlFrameworkListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/control-frameworks +
+

Create control framework

+

Creates a tenant-scoped versioned control framework.

+
+
Operation ID
createControlFramework
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
controls:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateControlFrameworkRequest
+
Responses
201 application/json: ControlFrameworkEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/controls +
+

Create security control

+

Creates a framework-owned security control with deterministic evidence requirements.

+
+
Operation ID
createSecurityControl
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
controls:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateSecurityControlRequest
+
Responses
201 application/json: SecurityControlEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/controls/{id} +
+

Get security control

+

Returns a tenant-scoped security control by id.

+
+
Operation ID
getSecurityControl
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
controls:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: SecurityControlEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/controls/{id}/evidence +
+

Link control evidence

+

Creates an append-only link between a security control and tenant-scoped evidence or related release resource.

+
+
Operation ID
linkControlEvidence
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
controls:write
+
Idempotency
Idempotency-Key
+
Request
application/json: LinkControlEvidenceRequest
+
Responses
201 application/json: ControlEvidenceEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/custom-policies +
+

Create custom policy

+

Creates a deterministic custom policy definition for tenant-managed release checks.

+
+
Operation ID
createCustomPolicy
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
policy:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateCustomPolicyRequest
+
Responses
201 application/json: CustomPolicyEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/custom-policies/{id}/evaluate +
+

Evaluate custom policy

+

Evaluates a tenant custom policy against a release and records the input hash.

+
+
Operation ID
evaluateCustomPolicy
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
policy:read
+
Idempotency
Idempotency-Key
+
Request
application/json: EvaluatePolicyRequest
+
Responses
201 application/json: CustomPolicyEvaluationEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/customer-packages +
+

Create customer security package

+

Creates a scoped customer security package manifest using an explicit redaction profile.

+
+
Operation ID
createCustomerPackage
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
package:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateCustomerPackageRequest
+
Responses
201 application/json: CustomerSecurityPackageEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/customer-packages/{id} +
+

Get customer security package

+

Returns a tenant-scoped customer security package manifest by id.

+
+
Operation ID
getCustomerPackage
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
package:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: CustomerSecurityPackageEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/customer-packages/{id}/download +
+

Download customer security package ZIP

+

Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.

+
+
Operation ID
downloadCustomerPackage
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
package:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/zip: string; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/customer-portal/access +
+

List customer portal access records

+

Lists tenant-scoped external reviewer access records without token hashes or token secrets.

+
+
Operation ID
listCustomerPortalAccess
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
package:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: CustomerPortalAccessListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/customer-portal/access +
+

Create customer portal access

+

Creates a named, expiring external reviewer access record for a customer package and returns the portal token once.

+
+
Operation ID
createCustomerPortalAccess
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
package:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateCustomerPortalAccessRequest
+
Responses
201 application/json: CustomerPortalAccessCreateEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/customer-portal/access/{id}/revoke +
+

Revoke customer portal access

+

Revokes a tenant-scoped external reviewer access record; revocation is append-only and the original token cannot be used afterwards.

+
+
Operation ID
revokeCustomerPortalAccess
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
package:write
+
Idempotency
Idempotency-Key
+
Request
application/json: EmptyObject
+
Responses
200 application/json: CustomerPortalAccessEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/customer-portal/package +
+

Access customer portal package

+

Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.

+
+
Operation ID
accessCustomerPortalPackage
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
none
+
Idempotency
Idempotency-Key
+
Request
application/json: CustomerPortalPackageRequest
+
Responses
200 application/json: CustomerSecurityPackageEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/customer-portal/package/download +
+

Download customer portal package ZIP

+

Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.

+
+
Operation ID
downloadCustomerPortalPackage
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
none
+
Idempotency
Idempotency-Key
+
Request
application/json: CustomerPortalPackageRequest
+
Responses
200 application/zip: string; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/customer-portal/package/view +
+

Customer portal package review form

+

Public HTML form for reviewing or downloading a scoped customer package with a portal token. It does not accept tokens in URLs and does not use bearer authentication.

+
+
Operation ID
customerPortalPackageViewForm
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
none
+
Idempotency
not required
+
Request
none
+
Responses
200 text/html: string; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/customer-portal/package/view +
+

Customer portal package review page

+

Public HTML package review endpoint backed by the customer portal token exchange. Tokens are accepted only as form body fields.

+
+
Operation ID
customerPortalPackageView
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
none
+
Idempotency
Idempotency-Key
+
Request
application/x-www-form-urlencoded: CustomerPortalPackageRequest
+
Responses
200 text/html: string; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/customer-portal/package/view/download +
+

Download customer portal package ZIP from review form

+

Public HTML-form package ZIP download endpoint backed by the customer portal token exchange. Tokens are accepted only as form body fields.

+
+
Operation ID
downloadCustomerPortalPackageView
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
none
+
Idempotency
Idempotency-Key
+
Request
application/x-www-form-urlencoded: CustomerPortalPackageRequest
+
Responses
200 application/zip: string; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/deployments +
+

List deployments

+

Lists tenant-scoped deployment events by optional release and environment filters.

+
+
Operation ID
listDeployments
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
deployment:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: DeploymentEventListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/deployments +
+

Record deployment

+

Records append-only deployment evidence for a release/environment/artifact set.

+
+
Operation ID
recordDeployment
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
deployment:write
+
Idempotency
Idempotency-Key
+
Request
application/json: RecordDeploymentRequest
+
Responses
201 application/json: DeploymentEventEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/deployments/{id} +
+

Get deployment

+

Returns a tenant-scoped deployment event by id.

+
+
Operation ID
getDeployment
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
deployment:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: DeploymentEventEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/dsse-trust-roots +
+

Create DSSE trust root

+

Creates a tenant-scoped DSSE trust root using public verification key material only.

+
+
Operation ID
createDSSETrustRoot
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
keys:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateDSSETrustRootRequest
+
Responses
201 application/json: DSSETrustRootEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/environments +
+

List deployment environments

+

Lists tenant-scoped deployment environments, optionally filtered by product.

+
+
Operation ID
listDeploymentEnvironments
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
deployment:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: DeploymentEnvironmentListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/environments +
+

Create deployment environment

+

Creates a tenant-scoped deployment environment for release deployment evidence.

+
+
Operation ID
createDeploymentEnvironment
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
deployment:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateDeploymentEnvironmentRequest
+
Responses
201 application/json: DeploymentEnvironmentEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/evidence +
+

List evidence

+

Lists tenant-scoped evidence by optional release and evidence type filters.

+
+
Operation ID
listEvidence
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: EvidenceItemListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/evidence +
+

Create evidence

+

Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.

+
+
Operation ID
createEvidence
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateEvidenceRequest
+
Responses
201 application/json: EvidenceItemEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/evidence-bundles +
+

Export evidence bundle

+

Exports a portable evidence bundle manifest with hashes, signatures, and verification text.

+
+
Operation ID
exportEvidenceBundle
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
bundle:read
+
Idempotency
Idempotency-Key
+
Request
application/json: ExportEvidenceBundleRequest
+
Responses
201 application/json: EvidenceBundleEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/evidence-bundles/import +
+

Import evidence bundle

+

Imports a portable evidence bundle manifest and records deterministic import metadata.

+
+
Operation ID
importEvidenceBundle
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
bundle:write
+
Idempotency
Idempotency-Key
+
Request
application/json: EvidenceBundle
+
Responses
201 application/json: EvidenceBundleImportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/evidence-graph-snapshots +
+

Create evidence graph snapshot

+

Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.

+
+
Operation ID
createGraphSnapshot
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateGraphSnapshotRequest
+
Responses
201 application/json: EvidenceGraphSnapshotEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/evidence-summaries +
+

Create evidence-backed summary

+

Creates an evidence-backed summary with citations, assumptions, and limitations.

+
+
Operation ID
createEvidenceSummary
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
report:read
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateEvidenceSummaryRequest
+
Responses
201 application/json: EvidenceSummaryEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/evidence/search +
+

Search evidence

+

Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.

+
+
Operation ID
searchEvidence
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: EvidenceSearchEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/evidence/{id} +
+

Get evidence

+

Returns a tenant-scoped immutable evidence item by id.

+
+
Operation ID
getEvidence
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: EvidenceItemEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/evidence/{id}/lifecycle-events +
+

List evidence lifecycle events

+

Lists append-only lifecycle events for a tenant-scoped evidence item.

+
+
Operation ID
listEvidenceLifecycleEvents
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: EvidenceLifecycleEventListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/evidence/{id}/lifecycle-events +
+

Record evidence lifecycle event

+

Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.

+
+
Operation ID
recordEvidenceLifecycleEvent
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:write
+
Idempotency
Idempotency-Key
+
Request
application/json: RecordEvidenceLifecycleEventRequest
+
Responses
201 application/json: EvidenceLifecycleEventEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/evidence/{id}/link +
+

Link evidence

+

Creates an append-only relationship from evidence to another tenant-scoped subject.

+
+
Operation ID
linkEvidence
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:write
+
Idempotency
Idempotency-Key
+
Request
application/json: LinkEvidenceRequest
+
Responses
201 application/json: EvidenceItemEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/evidence/{id}/supersede +
+

Supersede evidence

+

Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.

+
+
Operation ID
supersedeEvidence
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:write
+
Idempotency
Idempotency-Key
+
Request
application/json: SupersedeEvidenceRequest
+
Responses
201 application/json: EvidenceItemEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/exceptions +
+

List exceptions

+

Lists tenant-scoped exceptions, optionally filtered by release.

+
+
Operation ID
listExceptions
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
verify:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ExceptionListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/exceptions +
+

Create exception

+

Creates a scoped, expiring release/finding/control exception that is inactive until approved.

+
+
Operation ID
createException
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
release:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateExceptionRequest
+
Responses
201 application/json: ExceptionEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/exceptions/{id}/approve +
+

Approve exception

+

Approves an unexpired exception as an audited append-only transition.

+
+
Operation ID
approveException
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
release:write
+
Idempotency
Idempotency-Key
+
Request
application/json: EmptyObject
+
Responses
200 application/json: ExceptionEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/health +
+

Health

+

Returns low-detail liveness status without touching tenant evidence or secret material.

+
+
Operation ID
health
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
none
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: HealthStatusEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/incident-webhooks/{receiver_id} +
+

Receive signed incident webhook event

+

Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.

+
+
Operation ID
receiveIncidentWebhook
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
none
+
Idempotency
not required
+
Request
application/json: SignedIncidentWebhookPayload
+
Responses
201 application/json: IncidentWebhookDeliveryEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/incidents +
+

Create incident

+

Creates an append-only incident record linked to tenant-scoped product and optional release evidence.

+
+
Operation ID
createIncident
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
incident:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateIncidentRequest
+
Responses
201 application/json: IncidentEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/incidents/{id}/timeline +
+

Record incident timeline event

+

Appends an incident timeline event and optional evidence reference.

+
+
Operation ID
recordIncidentTimeline
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
incident:write
+
Idempotency
Idempotency-Key
+
Request
application/json: RecordIncidentTimelineRequest
+
Responses
201 application/json: IncidentTimelineEventEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/incidents/{id}/webhook-receivers +
+

Create signed incident webhook receiver

+

Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.

+
+
Operation ID
createIncidentWebhookReceiver
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
incident:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateIncidentWebhookReceiverRequest
+
Responses
201 application/json: IncidentWebhookReceiverEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/legal-holds +
+

Create legal hold

+

Creates an append-only legal-hold marker for a tenant-scoped retention subject.

+
+
Operation ID
createLegalHold
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateLegalHoldRequest
+
Responses
201 application/json: LegalHoldEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/marketplace-collectors +
+

List marketplace collector records

+

Lists tenant-scoped marketplace collector package metadata.

+
+
Operation ID
listMarketplaceCollectors
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
collector:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: MarketplaceCollectorListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/marketplace-collectors +
+

Create marketplace collector record

+

Creates tenant-scoped marketplace collector package metadata and evidence references.

+
+
Operation ID
createMarketplaceCollector
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
collector:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateMarketplaceCollectorRequest
+
Responses
201 application/json: MarketplaceCollectorEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/marketplace-collectors/{id}/health +
+

Marketplace collector health report

+

Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.

+
+
Operation ID
marketplaceCollectorHealth
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
collector:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: MarketplaceCollectorHealthReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/merkle-batches +
+

Create Merkle checkpoint batch

+

Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.

+
+
Operation ID
createMerkleBatch
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
keys:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateMerkleBatchRequest
+
Responses
201 application/json: MerkleBatchEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/merkle-batches/{id}/verify +
+

Verify Merkle checkpoint batch

+

Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.

+
+
Operation ID
verifyMerkleBatch
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
verify:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: VerificationResultEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/metrics +
+

Safe tenant metrics

+

Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.

+
+
Operation ID
metrics
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
admin
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: MetricsSnapshotEnvelope, text/plain: string; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/object-retention-policies +
+

Create object retention policy record

+

Creates an object retention policy record for storage immutability verification.

+
+
Operation ID
createObjectRetentionPolicy
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateObjectRetentionPolicyRequest
+
Responses
201 application/json: ObjectRetentionPolicyEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/object-retention-policies/{id}/verify +
+

Verify object retention policy record

+

Records verification metadata for a tenant object retention policy.

+
+
Operation ID
verifyObjectRetentionPolicy
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
verify:read
+
Idempotency
Idempotency-Key
+
Request
application/json: EmptyObject
+
Responses
200 application/json: ObjectRetentionPolicyEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/openapi-contracts +
+

Upload OpenAPI contract

+

Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.

+
+
Operation ID
uploadOpenAPIContract
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:write
+
Idempotency
Idempotency-Key
+
Request
application/json: UploadOpenAPIContractRequest
+
Responses
201 application/json: OpenAPIContractEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/openapi-contracts/{id} +
+

Get OpenAPI contract

+

Returns a tenant-scoped OpenAPI contract metadata record by id.

+
+
Operation ID
getOpenAPIContract
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: OpenAPIContractEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/openapi-diffs +
+

Create OpenAPI contract diff

+

Creates a deterministic OpenAPI contract diff for release contract checks.

+
+
Operation ID
createOpenAPIDiff
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateOpenAPIDiffRequest
+
Responses
201 application/json: ContractDiffEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/openapi.json +
+

OpenAPI

+

Returns the generated OpenAPI 3.1 document served by this process.

+
+
Operation ID
openapi
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
none
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: OpenAPIDocument; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/organizations +
+

Create organization

+

Creates a tenant-scoped organization record for human identity grouping.

+
+
Operation ID
createOrganization
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
identity:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateOrganizationRequest
+
Responses
201 application/json: OrganizationEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/policies/evaluate +
+

Evaluate release policy

+

Evaluates built-in deterministic release policy checks for a release.

+
+
Operation ID
evaluatePolicy
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
verify:read
+
Idempotency
Idempotency-Key
+
Request
application/json: EvaluatePolicyRequest
+
Responses
201 application/json: PolicyEvaluationEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/products +
+

List products

+

Lists tenant-scoped products visible to the authenticated actor.

+
+
Operation ID
listProducts
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
product:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ProductListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/products +
+

Create product

+

Creates a tenant-scoped product. Product slugs must be unique per tenant.

+
+
Operation ID
createProduct
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
product:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateProductRequest
+
Responses
201 application/json: ProductEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/products/{id} +
+

Get product

+

Returns a tenant-scoped product by id.

+
+
Operation ID
getProduct
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
product:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ProductEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/projects +
+

Create project

+

Creates a tenant-scoped project under a product.

+
+
Operation ID
createProject
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
project:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateProjectRequest
+
Responses
201 application/json: ProjectEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/projects/{id} +
+

Get project

+

Returns a tenant-scoped project by id.

+
+
Operation ID
getProject
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
project:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ProjectEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/provider-verifications +
+

Verify stored provider identity metadata

+

Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.

+
+
Operation ID
verifyProviderIdentity
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
identity:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: VerifyProviderIdentityRequest
+
Responses
201 application/json: ProviderVerificationEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/public-transparency-log-entries +
+

Publish public transparency log entry record

+

Records publication metadata for a checkpoint submitted to a configured public transparency log.

+
+
Operation ID
publishPublicTransparencyLogEntry
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
keys:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: PublishPublicTransparencyLogEntryRequest
+
Responses
201 application/json: PublicTransparencyLogEntryEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/public-transparency-log-entries/{id}/fetch-proof +
+

Fetch and verify public transparency log inclusion proof

+

Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.

+
+
Operation ID
fetchPublicTransparencyLogEntryProof
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
keys:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: EmptyObject
+
Responses
200 application/json: PublicTransparencyLogEntryEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/public-transparency-log-entries/{id}/verify +
+

Verify public transparency log inclusion proof

+

Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.

+
+
Operation ID
verifyPublicTransparencyLogEntry
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
keys:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: VerifyPublicTransparencyLogEntryRequest
+
Responses
200 application/json: PublicTransparencyLogEntryEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/public-transparency-logs +
+

Create public transparency log record

+

Creates tenant metadata for an optional public transparency log trust root.

+
+
Operation ID
createPublicTransparencyLog
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
keys:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreatePublicTransparencyLogRequest
+
Responses
201 application/json: PublicTransparencyLogEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/questionnaire-answer-library +
+

List questionnaire answer library entries

+

Lists tenant-scoped questionnaire answer library entries with optional question, product, and release filters.

+
+
Operation ID
listQuestionnaireAnswerLibrary
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
package:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: QuestionnaireAnswerLibraryEntryListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/questionnaire-answer-library +
+

Create questionnaire answer library entry

+

Creates a tenant-scoped reusable questionnaire answer draft linked to optional evidence, product, release, or control scope.

+
+
Operation ID
createQuestionnaireAnswerLibraryEntry
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
package:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateQuestionnaireAnswerLibraryEntryRequest
+
Responses
201 application/json: QuestionnaireAnswerLibraryEntryEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/questionnaire-drafts +
+

Create evidence-backed questionnaire draft

+

Creates an evidence-backed questionnaire draft with limitations.

+
+
Operation ID
createQuestionnaireDraft
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
package:read
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateQuestionnaireDraftRequest
+
Responses
201 application/json: QuestionnaireDraftEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/questionnaire-packages +
+

Create questionnaire package

+

Creates a questionnaire response package from a template and scoped evidence package.

+
+
Operation ID
createQuestionnairePackage
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
package:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateQuestionnairePackageRequest
+
Responses
201 application/json: QuestionnairePackageEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/questionnaire-templates +
+

Create questionnaire template

+

Creates a tenant questionnaire template with explicit evidence/control mapping fields.

+
+
Operation ID
createQuestionnaireTemplate
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
package:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateQuestionnaireTemplateRequest
+
Responses
201 application/json: QuestionnaireTemplateEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/ready +
+

Readiness

+

Returns low-detail process readiness without tenant evidence or secret material.

+
+
Operation ID
ready
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
none
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ReadinessStatusEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/redaction-profiles +
+

Create redaction profile

+

Creates an explicit redaction profile for customer and report package generation.

+
+
Operation ID
createRedactionProfile
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
package:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateRedactionProfileRequest
+
Responses
201 application/json: RedactionProfileEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/release-bundles +
+

Create release bundle

+

Creates an immutable signed release bundle for a release.

+
+
Operation ID
createReleaseBundle
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
bundle:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateReleaseBundleRequest
+
Responses
201 application/json: ReleaseBundleEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/release-bundles/{id} +
+

Get release bundle

+

Returns a tenant-scoped immutable release bundle by id.

+
+
Operation ID
getReleaseBundle
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
bundle:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ReleaseBundleEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/release-bundles/{id}/manifest +
+

Get release bundle manifest

+

Returns the deterministic release bundle manifest by bundle id.

+
+
Operation ID
getReleaseBundleManifest
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
bundle:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ReleaseBundleManifestEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/release-bundles/{id}/verify +
+

Verify release bundle

+

Verifies a tenant-scoped release bundle and returns a deterministic verification result.

+
+
Operation ID
verifyReleaseBundle
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
verify:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: VerificationResultEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/release-candidates +
+

List release candidates

+

Lists tenant-scoped release candidates, optionally filtered by release.

+
+
Operation ID
listReleaseCandidates
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
release:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ReleaseCandidateListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/release-candidates +
+

Create release candidate

+

Creates an immutable release-candidate snapshot of selected release evidence references.

+
+
Operation ID
createReleaseCandidate
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
release:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateReleaseCandidateRequest
+
Responses
201 application/json: ReleaseCandidateEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/release-candidates/{id} +
+

Get release candidate

+

Returns a tenant-scoped release candidate by id.

+
+
Operation ID
getReleaseCandidate
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
release:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ReleaseCandidateEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/release-candidates/{id}/promote +
+

Promote release candidate

+

Records a release-candidate lifecycle transition without mutating the original snapshot.

+
+
Operation ID
promoteReleaseCandidate
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
release:write
+
Idempotency
Idempotency-Key
+
Request
application/json: ReleaseCandidateTransitionRequest
+
Responses
200 application/json: ReleaseCandidateEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/release-candidates/{id}/reject +
+

Reject release candidate

+

Records a release-candidate lifecycle transition without mutating the original snapshot.

+
+
Operation ID
rejectReleaseCandidate
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
release:write
+
Idempotency
Idempotency-Key
+
Request
application/json: ReleaseCandidateTransitionRequest
+
Responses
200 application/json: ReleaseCandidateEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/releases +
+

Create release

+

Creates an append-only release record under a product and optional project.

+
+
Operation ID
createRelease
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
release:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateReleaseRequest
+
Responses
201 application/json: ReleaseEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/releases/{id} +
+

Get release

+

Returns a tenant-scoped release by id.

+
+
Operation ID
getRelease
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
release:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ReleaseEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/releases/{id}/approve +
+

Approve release

+

Approves a release as an append-only transition.

+
+
Operation ID
approveRelease
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
release:write
+
Idempotency
Idempotency-Key
+
Request
application/json: EmptyObject
+
Responses
200 application/json: ReleaseEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/releases/{id}/evidence-flow/start +
+

Start release evidence flow

+

Returns a high-level release evidence workflow plan, current evidence counts, required scopes, assumptions, and limitations. This read-only convenience operation does not create evidence.

+
+
Operation ID
startReleaseEvidenceFlow
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
release:read
+
Idempotency
Idempotency-Key
+
Request
none
+
Responses
200 application/json: ReleaseEvidenceFlowEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/releases/{id}/freeze +
+

Freeze release

+

Freezes a release as an append-only transition.

+
+
Operation ID
freezeRelease
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
release:write
+
Idempotency
Idempotency-Key
+
Request
application/json: EmptyObject
+
Responses
200 application/json: ReleaseEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/releases/{id}/security-summary +
+

Release security summary

+

Returns a tenant-scoped release security summary for review surfaces without raw evidence payload bytes.

+
+
Operation ID
releaseSecuritySummary
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
report:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ReleaseSecuritySummaryEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/remediation-tasks +
+

Create remediation task

+

Creates an incident or release remediation task linked to optional evidence.

+
+
Operation ID
createRemediationTask
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
incident:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateRemediationTaskRequest
+
Responses
201 application/json: RemediationTaskEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/report-templates +
+

Create report template

+

Creates a tenant-defined deterministic report template with an explicit allowed-field list.

+
+
Operation ID
createReportTemplate
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
report:read
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateReportTemplateRequest
+
Responses
201 application/json: CustomReportTemplateEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/report-templates/{id}/render +
+

Render report template

+

Renders a tenant report template for a scoped subject using allowed fields only.

+
+
Operation ID
renderReportTemplate
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
report:read
+
Idempotency
Idempotency-Key
+
Request
application/json: RenderReportTemplateRequest
+
Responses
201 application/json: RenderedCustomReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/reports/anomaly +
+

Generate deterministic anomaly report

+

Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.

+
+
Operation ID
generateAnomalyReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
report:read
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateAnomalyReportRequest
+
Responses
201 application/json: AnomalyReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/reports/control-coverage +
+

Control coverage report

+

Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.

+
+
Operation ID
controlCoverageReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
report:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ReadinessReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/reports/cra-readiness +
+

CRA readiness report

+

Returns a CRA-oriented readiness report without legal compliance or certification conclusions.

+
+
Operation ID
craReadinessReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
report:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ReadinessReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/reports/cra-readiness-html +
+

CRA readiness HTML package

+

Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.

+
+
Operation ID
craReadinessHTMLPackage
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
report:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: HTMLReportPackageEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/reports/cra-vulnerability-handling +
+

CRA vulnerability handling report

+

Returns a CRA-oriented vulnerability handling evidence report without legal compliance, certification, scanner-authority, or release-security conclusions.

+
+
Operation ID
craVulnerabilityHandlingReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
report:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: CRAVulnerabilityHandlingReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/reports/custody-review +
+

Signing custody review report

+

Returns tenant signing-provider and object-lock verification metadata for deployment custody review. It is evidence metadata only, not legal compliance proof, certification, HSM custody proof, or a secure-deployment guarantee.

+
+
Operation ID
signingCustodyReviewReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
keys:admin
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: SigningCustodyReviewReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/reports/incident-package +
+

Incident package report

+

Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.

+
+
Operation ID
incidentReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
incident:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: IncidentReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/reports/missing-evidence +
+

Missing evidence report

+

Returns a deterministic missing-evidence report for a release with assumptions and limitations.

+
+
Operation ID
missingEvidenceReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
verify:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: MissingEvidenceReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/reports/pdf +
+

Create reproducible PDF report package

+

Creates a deterministic PDF report package record and payload metadata.

+
+
Operation ID
createPDFReportPackage
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
report:read
+
Idempotency
Idempotency-Key
+
Request
application/json: CreatePDFReportPackageRequest
+
Responses
201 application/json: PDFReportPackageEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/reports/release-readiness +
+

Release readiness report

+

Returns a deterministic release-readiness report with gaps, assumptions, and limitations.

+
+
Operation ID
releaseReadinessReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
verify:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ReadinessReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/reports/retention +
+

Retention report

+

Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.

+
+
Operation ID
retentionReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
admin
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: RetentionReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/reports/security-review-package +
+

Security review package report

+

Returns a redaction-aware security-review package report with assumptions and limitations.

+
+
Operation ID
securityReviewPackageReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
package:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: SecurityReviewPackageReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/reports/security-update-evidence +
+

Security update evidence report

+

Returns a security update evidence report for release-scoped fixed decisions, incidents, remediation tasks, and linked evidence without legal or security conclusions.

+
+
Operation ID
securityUpdateEvidenceReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
report:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: SecurityUpdateEvidenceReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/reports/vulnerability-decision-summary +
+

Customer-safe vulnerability decision summary

+

Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.

+
+
Operation ID
vulnerabilityDecisionSummaryReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
report:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: VulnerabilityDecisionSummaryReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/reports/vulnerability-posture +
+

Vulnerability posture report

+

Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.

+
+
Operation ID
vulnerabilityPostureReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
security:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: VulnerabilityPostureReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/retention-overrides +
+

Create retention override

+

Creates an append-only retention override for a tenant-scoped retention subject.

+
+
Operation ID
createRetentionOverride
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateRetentionOverrideRequest
+
Responses
201 application/json: RetentionOverrideEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/role-bindings +
+

List role bindings

+

Lists tenant-scoped role bindings visible to the identity administrator.

+
+
Operation ID
listRoleBindings
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
identity:admin
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: RoleBindingListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/role-bindings +
+

Create role binding

+

Creates a tenant-scoped role binding for a user or collector subject.

+
+
Operation ID
createRoleBinding
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
identity:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateRoleBindingRequest
+
Responses
201 application/json: RoleBindingEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/saas/profiles +
+

Create SaaS edition profile

+

Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.

+
+
Operation ID
createSaaSEditionProfile
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
instance:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateSaaSEditionProfileRequest
+
Responses
201 application/json: SaaSEditionProfileEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/sbom-components +
+

List SBOM components

+

Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.

+
+
Operation ID
listSBOMComponents
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: SBOMComponentRecordListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/sbom-diffs +
+

Create SBOM diff

+

Creates a deterministic SBOM diff between two tenant-scoped SBOM records.

+
+
Operation ID
createSBOMDiff
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateSBOMDiffRequest
+
Responses
201 application/json: SBOMDiffEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/sboms +
+

Upload CycloneDX SBOM

+

Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.

+
+
Operation ID
uploadSBOM
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:write
+
Idempotency
Idempotency-Key
+
Request
application/json: EvidenceUploadRequest
+
Responses
201 application/json: SBOMEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/sboms/spdx +
+

Upload SPDX SBOM

+

Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.

+
+
Operation ID
uploadSPDXSBOM
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:write
+
Idempotency
Idempotency-Key
+
Request
application/json: UploadSPDXSBOMRequest
+
Responses
201 application/json: SBOMEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/sboms/{id} +
+

Get SBOM

+

Returns a tenant-scoped SBOM metadata record by id.

+
+
Operation ID
getSBOM
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: SBOMEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/security-documents +
+

Upload manual security document

+

Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.

+
+
Operation ID
uploadManualSecurityDocument
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
security:write
+
Idempotency
Idempotency-Key
+
Request
application/json: UploadManualSecurityDocumentRequest
+
Responses
201 application/json: ManualSecurityDocumentEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/security-scans +
+

Upload security scan

+

Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.

+
+
Operation ID
uploadSecurityScan
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
security:write
+
Idempotency
Idempotency-Key
+
Request
application/json: UploadSecurityScanRequest
+
Responses
201 application/json: SecurityScanEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/signing-keys +
+

List signing keys

+

Lists tenant signing public-key metadata without private key material.

+
+
Operation ID
listSigningKeys
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
verify:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: SigningKeyListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/signing-keys/rotate +
+

Rotate signing key

+

Rotates the active tenant signing key and returns public-key metadata only.

+
+
Operation ID
rotateSigningKey
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
keys:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: SigningKeyTransitionRequest
+
Responses
201 application/json: SigningKeyEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/signing-keys/{id}/revoke +
+

Revoke signing key

+

Revokes a tenant signing key as an audited lifecycle transition.

+
+
Operation ID
revokeSigningKey
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
keys:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: SigningKeyTransitionRequest
+
Responses
200 application/json: SigningKeyEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/signing-operations +
+

Create signing provider operation receipt

+

Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.

+
+
Operation ID
createSigningOperation
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
keys:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateSigningOperationRequest
+
Responses
201 application/json: SigningOperationEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/signing-providers +
+

Create signing provider record

+

Creates signing provider metadata for external signing operations. Production private key material must not be supplied.

+
+
Operation ID
createSigningProvider
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
keys:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateSigningProviderRequest
+
Responses
201 application/json: SigningProviderEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/source/branches +
+

Record source branch

+

Records or updates source branch metadata and protected-branch snapshot hash.

+
+
Operation ID
upsertSourceBranch
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
source:write
+
Idempotency
Idempotency-Key
+
Request
application/json: UpsertSourceBranchRequest
+
Responses
201 application/json: SourceBranchEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/source/commits +
+

Record source commit

+

Records immutable source commit metadata and stores only a hash of the commit message.

+
+
Operation ID
recordSourceCommit
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
source:write
+
Idempotency
Idempotency-Key
+
Request
application/json: RecordSourceCommitRequest
+
Responses
201 application/json: SourceCommitEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/source/pull-requests +
+

Record pull request

+

Records pull-request review metadata linked to source repository evidence.

+
+
Operation ID
recordPullRequest
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
source:write
+
Idempotency
Idempotency-Key
+
Request
application/json: RecordPullRequestRequest
+
Responses
201 application/json: PullRequestEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/source/repositories +
+

List source repositories

+

Lists tenant-scoped source repositories, optionally filtered by project.

+
+
Operation ID
listSourceRepositories
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
source:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: SourceRepositoryListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/source/repositories +
+

Create source repository

+

Creates a tenant-scoped source repository record.

+
+
Operation ID
createSourceRepository
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
source:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateSourceRepositoryRequest
+
Responses
201 application/json: SourceRepositoryEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/sso/identity-links +
+

Link SSO identity

+

Links a verified provider subject to a tenant-scoped human user.

+
+
Operation ID
linkSSOIdentity
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
identity:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: LinkSSOIdentityRequest
+
Responses
201 application/json: UserIdentityLinkEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/sso/logout +
+

Logout SSO session

+

Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.

+
+
Operation ID
logoutSSOSession
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
none
+
Idempotency
Idempotency-Key
+
Request
application/json: EmptyObject
+
Responses
200 application/json: SSOSessionEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/sso/providers +
+

Create SSO provider

+

Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.

+
+
Operation ID
createSSOProvider
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
identity:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateSSOProviderRequest
+
Responses
201 application/json: SSOProviderEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/sso/providers/{id}/discover-oidc +
+

Refresh SSO provider OIDC trust material

+

Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.

+
+
Operation ID
refreshSSOProviderOIDCTrustMaterial
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
identity:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: EmptyObject
+
Responses
200 application/json: SSOProviderEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/sso/providers/{id}/trust-material +
+

Update SSO provider trust material

+

Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.

+
+
Operation ID
updateSSOProviderTrustMaterial
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
identity:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: UpdateSSOProviderTrustMaterialRequest
+
Responses
200 application/json: SSOProviderEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/sso/session-exchanges +
+

Exchange SSO credential

+

Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.

+
+
Operation ID
exchangeSSOCredential
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
none
+
Idempotency
not required
+
Request
application/json: ExchangeSSOCredentialRequest
+
Responses
201 application/json: SSOCredentialExchangeEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/sso/sessions +
+

Create SSO session

+

Creates an admin-managed human SSO session record and returns a one-time bearer secret.

+
+
Operation ID
createSSOSession
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
identity:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateSSOSessionRequest
+
Responses
201 application/json: SSOSessionCreateEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/sso/sessions/{id}/revoke +
+

Revoke SSO session

+

Revokes a tenant-scoped SSO session as an audited lifecycle transition.

+
+
Operation ID
revokeSSOSession
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
identity:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: EmptyObject
+
Responses
200 application/json: SSOSessionEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/transparency-checkpoints +
+

Record external transparency checkpoint

+

Records an external transparency or timestamp checkpoint reference for a Merkle batch.

+
+
Operation ID
createTransparencyCheckpoint
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
keys:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateTransparencyCheckpointRequest
+
Responses
201 application/json: TransparencyCheckpointEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/users +
+

Create user

+

Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.

+
+
Operation ID
createUser
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
identity:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateUserRequest
+
Responses
201 application/json: HumanUserEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/users/{id}/deactivate +
+

Deactivate user

+

Deactivates a tenant-scoped human user as an audited lifecycle transition.

+
+
Operation ID
deactivateUser
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
identity:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: EmptyObject
+
Responses
200 application/json: HumanUserEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/verify +
+

Verify subject

+

Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.

+
+
Operation ID
verify
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
verify:read
+
Idempotency
Idempotency-Key
+
Request
application/json: VerifySubjectRequest
+
Responses
200 application/json: VerificationResultEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/version +
+

Version

+

Returns the API process version string.

+
+
Operation ID
version
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
none
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: VersionInfoEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/vex +
+

Upload OpenVEX document

+

Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.

+
+
Operation ID
uploadVEX
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:write
+
Idempotency
Idempotency-Key
+
Request
application/json: EvidenceUploadRequest
+
Responses
201 application/json: VEXDocumentEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/vex/cyclonedx +
+

Upload CycloneDX VEX document

+

Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.

+
+
Operation ID
uploadCycloneDXVEX
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:write
+
Idempotency
Idempotency-Key
+
Request
application/json: EvidenceUploadRequest
+
Responses
201 application/json: VEXDocumentEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/vex/cyclonedx/preview +
+

Preview CycloneDX VEX import

+

Validates a CycloneDX VEX payload and returns advisory mapping counts without storing raw payloads, creating evidence, creating decisions, or enqueueing parser jobs.

+
+
Operation ID
previewCycloneDXVEXImport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
application/json: EvidenceUploadRequest
+
Responses
200 application/json: VEXImportPreviewEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/vex/preview +
+

Preview OpenVEX import

+

Validates an OpenVEX payload and returns advisory mapping counts without storing raw payloads, creating evidence, creating decisions, or enqueueing parser jobs.

+
+
Operation ID
previewVEXImport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
application/json: EvidenceUploadRequest
+
Responses
200 application/json: VEXImportPreviewEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/vex/{id} +
+

Get VEX document

+

Returns a tenant-scoped VEX document metadata record by id.

+
+
Operation ID
getVEX
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: VEXDocumentEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/vex/{id}/import-report +
+

Get VEX import report

+

Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.

+
+
Operation ID
getVEXImportReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: VEXImportReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/vulnerability-decisions +
+

List vulnerability decisions

+

Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.

+
+
Operation ID
listVulnerabilityDecisions
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: VulnerabilityDecisionListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/vulnerability-findings/{id}/decisions +
+

Create vulnerability decision

+

Creates an append-only vulnerability decision for a tenant-scoped scan finding.

+
+
Operation ID
createVulnerabilityDecision
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateVulnerabilityDecisionRequest
+
Responses
201 application/json: VulnerabilityDecisionEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/vulnerability-findings/{id}/workflow +
+

Record vulnerability workflow event

+

Records an append-only vulnerability workflow event for a tenant-scoped finding.

+
+
Operation ID
recordVulnerabilityWorkflow
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
security:write
+
Idempotency
Idempotency-Key
+
Request
application/json: RecordVulnerabilityWorkflowRequest
+
Responses
201 application/json: VulnerabilityWorkflowRecordEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/vulnerability-scans +
+

Upload vulnerability scan

+

Uploads a generic vulnerability scan JSON payload and records normalized findings.

+
+
Operation ID
uploadVulnerabilityScan
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:write
+
Idempotency
Idempotency-Key
+
Request
application/json: UploadVulnerabilityScanRequest
+
Responses
201 application/json: VulnerabilityScanEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/vulnerability-scans/{id} +
+

Get vulnerability scan

+

Returns a tenant-scoped vulnerability scan by id.

+
+
Operation ID
getVulnerabilityScan
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: VulnerabilityScanEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/waivers +
+

Create waiver

+

Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.

+
+
Operation ID
createWaiver
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
policy:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateWaiverRequest
+
Responses
201 application/json: WaiverEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/waivers/{id}/approve +
+

Approve waiver

+

Approves an unexpired waiver as an audited transition.

+
+
Operation ID
approveWaiver
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
policy:write
+
Idempotency
Idempotency-Key
+
Request
application/json: EmptyObject
+
Responses
200 application/json: WaiverEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ +
+

Schemas

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameShapeRequired fields
APIKeyobjectid, tenant_id, name, prefix, scopes, created_at
APIKeyCreateEnvelopeobjectdata, meta
APIKeyCreateResponseobjectapi_key, secret
APIKeyListEnvelopeobjectdata, meta
AnomalyReportobjectid, tenant_id, subject_type, subject_id, result, assumptions, limitations, schema_version, created_at
AnomalyReportEnvelopeobjectdata, meta
AnomalySignalobjectname, severity, detail
ApprovalRecordobjectid, tenant_id, subject_type, subject_id, decision, reason, approver_id, schema_version, created_at
ApprovalRecordEnvelopeobjectdata, meta
Artifactobjectid, tenant_id, name, digest, schema_version, created_at
ArtifactEnvelopeobjectdata, meta
ArtifactSignatureobjectid, tenant_id, artifact_id, subject_digest, algorithm, signature, verification_status, schema_version, created_at
ArtifactSignatureEnvelopeobjectdata, meta
AuditChainEntryobjectid, tenant_id, sequence, entry_type, subject_type, subject_id, actor_type, actor_id, occurred_at, canonical_entry_hash, previous_entry_hash, entry_hash, schema_version
AuditChainEntryListEnvelopeobjectdata, meta
BackupManifestobjectid, tenant_id, state_hash, resource_counts, consistency_checks, limitations, schema_version, created_at
BackupManifestEnvelopeobjectdata, meta
BuildAttestationobjectid, tenant_id, build_id, evidence_id, payload_hash, payload_size, payload_type, predicate_type, subject_digests, signature_count, verification_status, schema_version, created_at
BuildAttestationEnvelopeobjectdata, meta
BuildRunobjectid, tenant_id, project_id, release_id, provider, commit_sha, status, schema_version, created_at
BuildRunEnvelopeobjectdata, meta
CRAVulnerabilityHandlingReportobjectreport_type, template_version, product_id, release_id, summary, assumptions, limitations, generated_at
CRAVulnerabilityHandlingReportEnvelopeobjectdata, meta
Collectorobjectid, tenant_id, name, type, version, api_key_id, status, allowed_scopes, schema_version, created_at
CollectorCreateEnvelopeobjectdata, meta
CollectorCreateResponseobjectcollector, api_key, secret
CollectorHealthReportobjectreport_type, collector_id, collector_status, supply_chain_status, checks, assumptions, limitations, generated_at
CollectorHealthReportEnvelopeobjectdata, meta
CollectorListEnvelopeobjectdata, meta
CollectorReleaseobjectid, tenant_id, collector_id, version, artifact_digest, pinned, verification_status, health_status, schema_version, created_at
CollectorReleaseEnvelopeobjectdata, meta
CommercialCollectorDefinitionobjectid, tenant_id, name, provider, version, manifest_hash, allowed_scopes, status, schema_version, created_at
CommercialCollectorDefinitionEnvelopeobjectdata, meta
CommercialCollectorDefinitionListEnvelopeobjectdata, meta
ContainerImageobjectid, tenant_id, repository, digest, schema_version, created_at
ContainerImageEnvelopeobjectdata, meta
ContractDiffobjectid, tenant_id, base_contract_id, target_contract_id, product_id, result, schema_version, created_at
ContractDiffEnvelopeobjectdata, meta
ControlEvidenceobjectid, tenant_id, control_id, evidence_type, subject_type, subject_id, confidence, schema_version, created_at
ControlEvidenceEnvelopeobjectdata, meta
ControlEvidenceListEnvelopeobjectdata, meta
ControlEvidenceRequirementobjecttype, required
ControlFrameworkobjectid, tenant_id, name, slug, version, status, schema_version, created_at
ControlFrameworkEnvelopeobjectdata, meta
ControlFrameworkListEnvelopeobjectdata, meta
ControlFrameworkTemplatePackobjectid, name, slug, version, controls, schema_version
ControlFrameworkTemplatePackListEnvelopeobjectdata, meta
CosignVerificationobjectid, tenant_id, artifact_signature_id, subject_digest, result, checks, schema_version, created_at
CosignVerificationEnvelopeobjectdata, meta
CreateAPIKeyRequestobjectname, scopes
CreateAnomalyReportRequestobjectsubject_type, subject_id
CreateApprovalRequestobjectsubject_type, subject_id, decision, reason
CreateArtifactSignatureRequestobjectartifact_id, algorithm, signature
CreateBuildRequestobjectproject_id, release_id, provider, commit_sha, status, started_at
CreateCollectorRequestobjectname, type, version
CreateCommercialCollectorRequestobjectname, provider, version, manifest_hash
CreateControlFrameworkRequestobjectname, version
CreateCustomPolicyRequestobjectname, version, rules
CreateCustomerPackageRequestobjectproduct_id, redaction_profile_id, title, expires_at
CreateCustomerPortalAccessRequestobjectpackage_id, customer_name, expires_at
CreateDSSETrustRootRequestobjectname, key_id, algorithm, public_key
CreateDeploymentEnvironmentRequestobjectproduct_id, name, kind
CreateEvidenceRequestobjecttype, title, payload_hash
CreateEvidenceSummaryRequestobjectsubject_type, subject_id, evidence_ids
CreateExceptionRequestobjectrelease_id, reason, owner, expires_at
CreateGraphSnapshotRequestobjectnone
CreateIncidentRequestobjectproduct_id, title, severity
CreateIncidentWebhookReceiverRequestobjectname, provider, public_key
CreateLegalHoldRequestobjectscope_type, scope_id, reason, owner
CreateMarketplaceCollectorRequestobjectname, provider, version, publisher, manifest_hash
CreateMerkleBatchRequestobjectnone
CreateObjectRetentionPolicyRequestobjectname, mode, retention_days
CreateOpenAPIDiffRequestobjectbase_contract_id, target_contract_id, release_id
CreateOrganizationRequestobjectname, slug
CreatePDFReportPackageRequestobjectreport_type, title
CreateProductRequestobjectname, slug
CreateProjectRequestobjectproduct_id, name, slug
CreatePublicTransparencyLogRequestobjectname, endpoint, public_key
CreateQuestionnaireAnswerLibraryEntryRequestobjectanswer
CreateQuestionnaireDraftRequestobjecttemplate_id
CreateQuestionnairePackageRequestobjecttemplate_id
CreateQuestionnaireTemplateRequestobjectname, version, questions
CreateRedactionProfileRequestobjectnone
CreateReleaseBundleRequestobjectrelease_id
CreateReleaseCandidateRequestobjectrelease_id, name
CreateReleaseRequestobjectproduct_id, version
CreateRemediationTaskRequestobjecttitle, owner
CreateReportTemplateRequestobjectname, version, report_type, allowed_fields, template
CreateRetentionOverrideRequestobjectscope_type, scope_id, retention_until, reason, owner
CreateRoleBindingRequestobjectsubject_type, subject_id, role
CreateSBOMDiffRequestobjectbase_sbom_id, target_sbom_id
CreateSSOProviderRequestobjectname, type, issuer, client_id
CreateSSOSessionRequestobjectuser_id, provider_id, expires_at
CreateSaaSEditionProfileRequestobjectname, region, admin_tenant_id, isolation_model
CreateSecurityControlRequestobjectframework_id, code, title, objective
CreateSigningOperationRequestobjectprovider_id, subject_type, subject_id, payload_hash
CreateSigningProviderRequestobjectname, type, key_ref
CreateSourceRepositoryRequestobjectprovider, full_name
CreateTransparencyCheckpointRequestobjectbatch_id, provider
CreateUserRequestobjectemail, display_name
CreateVulnerabilityDecisionRequestobjectstatus, justification
CreateWaiverRequestobjectscope_type, scope_id, owner, risk, reason, expires_at
CustomPolicyobjectid, tenant_id, name, version, rules, schema_version, created_at
CustomPolicyEnvelopeobjectdata, meta
CustomPolicyEvaluationobjectid, tenant_id, policy_id, release_id, result, checks, input_hash, schema_version, created_at
CustomPolicyEvaluationEnvelopeobjectdata, meta
CustomReportTemplateobjectid, tenant_id, name, version, report_type, allowed_fields, template, schema_version, created_at
CustomReportTemplateEnvelopeobjectdata, meta
CustomerPortalAccessobjectid, tenant_id, package_id, customer_name, prefix, expires_at, access_count, failed_access_count, schema_version, created_at
CustomerPortalAccessCreateEnvelopeobjectdata, meta
CustomerPortalAccessCreateResponseobjectaccess, secret
CustomerPortalAccessEnvelopeobjectdata, meta
CustomerPortalAccessListEnvelopeobjectdata, meta
CustomerPortalPackageRequestobjecttoken
CustomerSecurityPackageobjectid, tenant_id, product_id, redaction_profile_id, title, state, manifest, manifest_hash, expires_at, access_count, schema_version, created_at
CustomerSecurityPackageEnvelopeobjectdata, meta
DSSEEnvelopeobjectpayloadType, payload, signatures
DSSETrustRootobjectid, tenant_id, name, key_id, algorithm, public_key, status, schema_version, created_at
DSSETrustRootEnvelopeobjectdata, meta
DataEnvelopeobjectdata, meta
DependencyChangeobjectid, tenant_id, sbom_diff_id, change_type, component, schema_version, created_at
DeploymentEnvironmentobjectid, tenant_id, product_id, name, kind, schema_version, created_at
DeploymentEnvironmentEnvelopeobjectdata, meta
DeploymentEnvironmentListEnvelopeobjectdata, meta
DeploymentEventobjectid, tenant_id, environment_id, release_id, status, started_at, schema_version, created_at
DeploymentEventEnvelopeobjectdata, meta
DeploymentEventListEnvelopeobjectdata, meta
EmptyObjectobjectnone
EvaluatePolicyRequestobjectrelease_id
EvidenceBundleobjectid, tenant_id, evidence_ids, manifest, manifest_hash, verification_text, schema_version, created_at
EvidenceBundleEnvelopeobjectdata, meta
EvidenceBundleImportobjectid, tenant_id, bundle_hash, result, imported_count, schema_version, created_at
EvidenceBundleImportEnvelopeobjectdata, meta
EvidenceCitationobjectevidence_id, type, title, canonical_hash
EvidenceGraphEdgeobjectfrom, to, relationship
EvidenceGraphNodeobjectid, type, label
EvidenceGraphSnapshotobjectid, tenant_id, nodes, edges, graph_hash, limitations, schema_version, created_at
EvidenceGraphSnapshotEnvelopeobjectdata, meta
EvidenceItemobjectid, tenant_id, type, title, source_system, observed_at, evidence_version, schema_version, payload_hash, canonical_hash, canonicalization, trust_level, verification_status, chain_entry_id, created_at
EvidenceItemEnvelopeobjectdata, meta
EvidenceItemListEnvelopeobjectdata, meta
EvidenceLifecycleEventobjectid, tenant_id, evidence_id, action, reason, actor_id, schema_version, created_at
EvidenceLifecycleEventEnvelopeobjectdata, meta
EvidenceLifecycleEventListEnvelopeobjectdata, meta
EvidenceNoticeobjectcode, message
EvidenceRefobjecttype, id
EvidenceSearchEnvelopeobjectdata, meta
EvidenceSearchResponseobjectitems
EvidenceSummaryobjectid, tenant_id, subject_type, subject_id, evidence_ids, summary, citations, assumptions, limitations, schema_version, created_at
EvidenceSummaryEnvelopeobjectdata, meta
EvidenceUploadRequestobjectrelease_id, payload
Exceptionobjectid, tenant_id, release_id, reason, owner, expires_at, approved, created_at
ExceptionEnvelopeobjectdata, meta
ExceptionListEnvelopeobjectdata, meta
ExchangeSSOCredentialRequestobjectprovider_id, subject
ExportEvidenceBundleRequestobjectnone
HTMLReportPackageobjectid, tenant_id, report_type, product_id, html, hash, schema_version, created_at
HTMLReportPackageEnvelopeobjectdata, meta
HealthStatusobjectstatus
HealthStatusEnvelopeobjectdata, meta
HumanUserobjectid, tenant_id, email, display_name, status, schema_version, created_at
HumanUserEnvelopeobjectdata, meta
Incidentobjectid, tenant_id, product_id, title, severity, status, opened_at, schema_version, created_at
IncidentEnvelopeobjectdata, meta
IncidentReportobjectreport_type, template_version, incident_id, result, timeline, tasks, assumptions, limitations, generated_at
IncidentReportEnvelopeobjectdata, meta
IncidentTimelineEventobjectid, tenant_id, incident_id, event_type, summary, occurred_at, schema_version, created_at
IncidentTimelineEventEnvelopeobjectdata, meta
IncidentWebhookDeliveryobjectwebhook_event, timeline_event
IncidentWebhookDeliveryEnvelopeobjectdata, meta
IncidentWebhookEventobjectid, tenant_id, receiver_id, incident_id, provider, event_id, payload_hash, signature_hash, result, schema_version, created_at
IncidentWebhookReceiverobjectid, tenant_id, incident_id, name, provider, public_key, status, schema_version, created_at
IncidentWebhookReceiverEnvelopeobjectdata, meta
InstanceAdminSnapshotobjectreport_type, tenant_count, resource_counts, limitations, generated_at
InstanceAdminSnapshotEnvelopeobjectdata, meta
LegalHoldobjectid, tenant_id, scope_type, scope_id, reason, owner, schema_version, created_at
LegalHoldEnvelopeobjectdata, meta
LinkControlEvidenceRequestobjectevidence_type, subject_type, subject_id, confidence
LinkEvidenceRequestobjecttarget_type, target_id
LinkSSOIdentityRequestobjectuser_id, provider_id, subject, email, verified
ManualSecurityDocumentobjectid, tenant_id, document_type, title, sensitivity, evidence_id, payload_hash, schema_version, created_at
ManualSecurityDocumentEnvelopeobjectdata, meta
MarketplaceCollectorobjectid, tenant_id, name, provider, version, publisher, manifest_hash, state, schema_version, created_at
MarketplaceCollectorEnvelopeobjectdata, meta
MarketplaceCollectorHealthReportobjectreport_type, collector_id, name, provider, version, supply_chain_status, checks, collector, assumptions, limitations, generated_at
MarketplaceCollectorHealthReportEnvelopeobjectdata, meta
MarketplaceCollectorListEnvelopeobjectdata, meta
MerkleBatchobjectid, tenant_id, from_sequence, to_sequence, entry_count, leaf_hashes, root_hash, schema_version, created_at
MerkleBatchEnvelopeobjectdata, meta
MetricsSnapshotobjecttenant_id, resource_counts, customer_portal_failed_access_count, customer_portal_revoked_access_count
MetricsSnapshotEnvelopeobjectdata, meta
MissingEvidenceReportobjectreport_type, template_version, release_id, result, missing, assumptions, limitations
MissingEvidenceReportEnvelopeobjectdata, meta
ObjectRetentionPolicyobjectid, tenant_id, name, object_prefix, mode, retention_days, status, schema_version, created_at
ObjectRetentionPolicyEnvelopeobjectdata, meta
OpenAPIContractobjectid, tenant_id, product_id, version, hash, path_count, evidence_id, created_at
OpenAPIContractEnvelopeobjectdata, meta
OpenAPIDocumentobjectopenapi, info, paths
OpenAPIOperationRecordobjectpath, method
Organizationobjectid, tenant_id, name, slug, status, schema_version, created_at
OrganizationEnvelopeobjectdata, meta
PDFReportPackageobjectid, tenant_id, report_type, title, payload_hash, payload_size, limitations, schema_version, created_at
PDFReportPackageEnvelopeobjectdata, meta
PolicyCheckobjectname, result, severity, explanation
PolicyEvaluationobjectid, tenant_id, release_id, result, policy_set, checks, created_at
PolicyEvaluationEnvelopeobjectdata, meta
PolicyRuleobjectname, severity, required
Problemobjectnone
Productobjectid, tenant_id, name, slug, schema_version, created_at
ProductEnvelopeobjectdata, meta
ProductListEnvelopeobjectdata, meta
Projectobjectid, tenant_id, product_id, name, slug, schema_version, created_at
ProjectEnvelopeobjectdata, meta
ProviderVerificationobjectid, tenant_id, provider_type, provider_id, subject, result, checks, limitations, schema_version, created_at
ProviderVerificationEnvelopeobjectdata, meta
PublicTransparencyLogobjectid, tenant_id, name, endpoint, public_key, state, schema_version, created_at
PublicTransparencyLogEntryobjectid, tenant_id, log_id, checkpoint_id, merkle_batch_id, external_id, entry_hash, state, schema_version, created_at
PublicTransparencyLogEntryEnvelopeobjectdata, meta
PublicTransparencyLogEnvelopeobjectdata, meta
PublishPublicTransparencyLogEntryRequestobjectlog_id, checkpoint_id, external_id
PullRequestobjectid, tenant_id, repository_id, provider, provider_id, state, schema_version, created_at
PullRequestEnvelopeobjectdata, meta
QuestionnaireAnswerLibraryEntryobjectid, tenant_id, answer, schema_version, created_at
QuestionnaireAnswerLibraryEntryEnvelopeobjectdata, meta
QuestionnaireAnswerLibraryEntryListEnvelopeobjectdata, meta
QuestionnaireDraftobjectid, tenant_id, template_id, responses, manifest_hash, limitations, schema_version, created_at
QuestionnaireDraftEnvelopeobjectdata, meta
QuestionnairePackageobjectid, tenant_id, template_id, responses, manifest_hash, schema_version, created_at
QuestionnairePackageEnvelopeobjectdata, meta
QuestionnaireQuestionobjectid, prompt
QuestionnaireResponseobjectquestion_id, answer
QuestionnaireTemplateobjectid, tenant_id, name, version, questions, schema_version, created_at
QuestionnaireTemplateEnvelopeobjectdata, meta
ReadinessReportobjectreport_type, template_version, result, assumptions, limitations, generated_at
ReadinessReportEnvelopeobjectdata, meta
ReadinessStatusobjectstatus, checks
ReadinessStatusEnvelopeobjectdata, meta
RecordCollectorReleaseRequestobjectversion, artifact_digest
RecordDeploymentRequestobjectenvironment_id, release_id, status, started_at
RecordEvidenceLifecycleEventRequestobjectaction, reason
RecordIncidentTimelineRequestobjectevent_type, summary
RecordPullRequestRequestobjectrepository_id, provider, provider_id, title, state
RecordSourceCommitRequestobjectrepository_id, sha, committed_at
RecordVulnerabilityWorkflowRequestobjectaction, reason
RedactionProfileobjectid, tenant_id, name, schema_version, created_at
RedactionProfileEnvelopeobjectdata, meta
RegisterArtifactRequestobjectname, digest
RegisterContainerImageRequestobjectrepository, digest
Releaseobjectid, tenant_id, product_id, version, status, schema_version, created_at
ReleaseBundleobjectid, tenant_id, release_id, state, manifest, manifest_hash, signature_refs, created_at
ReleaseBundleEnvelopeobjectdata, meta
ReleaseBundleManifestobjectmanifest_version, bundle_id, tenant_id, release, evidence_ids, chain_checkpoint, generated_at, generator
ReleaseBundleManifestEnvelopeobjectdata, meta
ReleaseBundleVerificationobjectresult
ReleaseBundleVerificationEnvelopeobjectdata, meta
ReleaseCandidateobjectid, tenant_id, release_id, name, state, snapshot_hash, schema_version, created_at
ReleaseCandidateEnvelopeobjectdata, meta
ReleaseCandidateListEnvelopeobjectdata, meta
ReleaseCandidateTransitionRequestobjectnone
ReleaseEnvelopeobjectdata, meta
ReleaseEvidenceFlowobjectrelease_id, product_id, status, counts, steps, assumptions, limitations, schema_version, generated_at
ReleaseEvidenceFlowEnvelopeobjectdata, meta
ReleaseEvidenceFlowStepobjectid, title, status, required, method, path, required_scopes, idempotency_required, description
ReleaseSecurityApprovalSummaryobjecttotal, approved
ReleaseSecurityExceptionSummaryobjecttotal, approved_unexpired, unapproved, expired
ReleaseSecurityMissingDecisionobjectfinding_id, scan_id, vulnerability, severity, state
ReleaseSecurityProductSummaryobjectid, name, slug
ReleaseSecurityReleaseSummaryobjectid, version, state
ReleaseSecuritySummaryobjectproduct, release, artifact_count, sbom_status, vulnerability_scan_status, open_findings_by_severity, decisions_by_status, approval_summary, exception_summary, readiness_status, package_status, counts, assumptions, limitations, schema_version, generated_at
ReleaseSecuritySummaryEnvelopeobjectdata, meta
RemediationTaskobjectid, tenant_id, title, owner, status, schema_version, created_at
RemediationTaskEnvelopeobjectdata, meta
RenderReportTemplateRequestobjectsubject_type, subject_id
RenderedCustomReportobjectid, tenant_id, template_id, subject_type, subject_id, output, hash, schema_version, created_at
RenderedCustomReportEnvelopeobjectdata, meta
RetentionOverrideobjectid, tenant_id, scope_type, scope_id, retention_until, reason, owner, schema_version, created_at
RetentionOverrideEnvelopeobjectdata, meta
RetentionReportobjectreport_type, legal_holds, retention_overrides, limitations, generated_at
RetentionReportEnvelopeobjectdata, meta
RoleBindingobjectid, tenant_id, subject_type, subject_id, role, schema_version, created_at
RoleBindingEnvelopeobjectdata, meta
RoleBindingListEnvelopeobjectdata, meta
SBOMobjectid, tenant_id, evidence_id, release_id, format, component_count, created_at
SBOMComponentobjectname
SBOMComponentRecordobjectsbom_id, component
SBOMComponentRecordListEnvelopeobjectdata, meta
SBOMDiffobjectid, tenant_id, base_sbom_id, target_sbom_id, unchanged_count, schema_version, created_at
SBOMDiffEnvelopeobjectdata, meta
SBOMEnvelopeobjectdata, meta
SSOCredentialExchangeEnvelopeobjectdata, meta
SSOCredentialExchangeResponseobjectverification, session, secret
SSOProviderobjectid, tenant_id, name, type, issuer, client_id, status, schema_version, created_at
SSOProviderEnvelopeobjectdata, meta
SSOSessionobjectid, tenant_id, user_id, provider_id, prefix, expires_at, schema_version, created_at
SSOSessionCreateEnvelopeobjectdata, meta
SSOSessionCreateResponseobjectsession, secret
SSOSessionEnvelopeobjectdata, meta
SaaSEditionProfileobjectid, tenant_id, name, region, admin_tenant_id, isolation_model, status, config_hash, limitations, schema_version, created_at
SaaSEditionProfileEnvelopeobjectdata, meta
SecurityControlobjectid, tenant_id, framework_id, code, title, objective, schema_version, created_at
SecurityControlEnvelopeobjectdata, meta
SecurityReviewPackageReportobjectreport_type, template_version, package_id, product_id, evidence_ids, assumptions, limitations, generated_at
SecurityReviewPackageReportEnvelopeobjectdata, meta
SecurityScanobjectid, tenant_id, category, format, scanner, target_ref, evidence_id, payload_hash, finding_count, redacted, quarantined, schema_version, created_at
SecurityScanEnvelopeobjectdata, meta
SecurityUpdateEvidenceReportobjectreport_type, template_version, product_id, release_id, summary, assumptions, limitations, generated_at
SecurityUpdateEvidenceReportEnvelopeobjectdata, meta
SignedIncidentWebhookPayloadobjectevent_type, summary
SigningCustodyReviewReportobjectreport_type, tenant_id, checks, assumptions, limitations, generated_at
SigningCustodyReviewReportEnvelopeobjectdata, meta
SigningKeyobjectid, tenant_id, kid, algorithm, status, public_key, created_at
SigningKeyEnvelopeobjectdata, meta
SigningKeyListEnvelopeobjectdata, meta
SigningKeyTransitionRequestobjectnone
SigningOperationobjectid, tenant_id, provider_id, subject_type, subject_id, payload_hash, result, checks, schema_version, created_at
SigningOperationEnvelopeobjectdata, meta
SigningProviderobjectid, tenant_id, name, type, status, key_ref, encrypted, schema_version, created_at
SigningProviderEnvelopeobjectdata, meta
SourceBranchobjectid, tenant_id, repository_id, name, protected, schema_version, created_at
SourceBranchEnvelopeobjectdata, meta
SourceCommitobjectid, tenant_id, repository_id, sha, schema_version, created_at
SourceCommitEnvelopeobjectdata, meta
SourceRepositoryobjectid, tenant_id, provider, full_name, schema_version, created_at
SourceRepositoryEnvelopeobjectdata, meta
SourceRepositoryListEnvelopeobjectdata, meta
SourceSnapshotBranchInputobjectname
SourceSnapshotCommitInputobjectsha, committed_at
SourceSnapshotEnvelopeobjectdata, meta
SourceSnapshotPullRequestInputobjectprovider_id, state
SourceSnapshotRepositoryInputobjectfull_name
SourceSnapshotRequestobjectrepository
SourceSnapshotResultobjectrepository
SubjectRefobjecttype
SupersedeEvidenceRequestobjectreplacement_evidence_id, reason
TransparencyCheckpointobjectid, tenant_id, batch_id, provider, timestamp_hash, state, schema_version, created_at
TransparencyCheckpointEnvelopeobjectdata, meta
UpdateSSOProviderTrustMaterialRequestobjectnone
UploadManualSecurityDocumentRequestobjectdocument_type, title, sensitivity, payload
UploadOpenAPIContractRequestobjectproduct_id, release_id, version, spec
UploadSPDXSBOMRequestobjectrelease_id, payload
UploadSecurityScanRequestobjectcategory, format, scanner, target_ref, payload
UploadVulnerabilityScanRequestobjectscanner, target_ref, release_id, findings
UpsertSourceBranchRequestobjectrepository_id, name
UserIdentityLinkobjectid, tenant_id, user_id, provider_id, subject, email, verified, schema_version, created_at
UserIdentityLinkEnvelopeobjectdata, meta
VEXDocumentobjectid, tenant_id, evidence_id, release_id, format, statement_count, schema_version, created_at
VEXDocumentEnvelopeobjectdata, meta
VEXImportIssueobjectcode, detail
VEXImportPreviewobjecttenant_id, release_id, format, parser_version, advisory, statement_count, status_summary, decisions_would_create, decisions_would_supersede, assumptions, limitations, schema_version, generated_at
VEXImportPreviewEnvelopeobjectdata, meta
VEXImportReportobjectid, tenant_id, vex_document_id, evidence_id, parser_version, status, statement_count, decisions_created, decisions_superseded, schema_version, created_at, updated_at
VEXImportReportEnvelopeobjectdata, meta
VerificationResultobjectid, tenant_id, subject_type, subject_id, result, checks, verified_at
VerificationResultEnvelopeobjectdata, meta
VerifyCheckobjectname, result
VerifyCosignSignatureRequestobjectnone
VerifyProviderIdentityRequestobjectprovider_type, provider_id, subject
VerifyPublicTransparencyLogEntryRequestobjectroot_hash, leaf_index, tree_size, inclusion_proof
VerifySubjectRequestobjectsubject_type
VersionInfoobjectversion
VersionInfoEnvelopeobjectdata, meta
VulnerabilityDecisionobjectid, tenant_id, finding_id, scan_id, vulnerability, status, justification, source, schema_version, created_at
VulnerabilityDecisionCustomerSummaryobjectid, finding_id, scan_id, release_id, vulnerability, status, impact_statement, source, created_at
VulnerabilityDecisionEnvelopeobjectdata, meta
VulnerabilityDecisionListEnvelopeobjectdata, meta
VulnerabilityDecisionSummaryReportobjectreport_type, template_version, product_id, release_id, decisions, assumptions, limitations, generated_at
VulnerabilityDecisionSummaryReportEnvelopeobjectdata, meta
VulnerabilityPostureReportobjectreport_type, template_version, summary, open_critical, assumptions, limitations, generated_at
VulnerabilityPostureReportEnvelopeobjectdata, meta
VulnerabilityScanobjectid, tenant_id, release_id, scanner, target_ref, summary, findings, created_at
VulnerabilityScanEnvelopeobjectdata, meta
VulnerabilityWorkflowRecordobjectid, tenant_id, finding_id, action, reason, actor_id, schema_version, created_at
VulnerabilityWorkflowRecordEnvelopeobjectdata, meta
Waiverobjectid, tenant_id, scope_type, scope_id, owner, risk, reason, expires_at, approved, schema_version, created_at
WaiverEnvelopeobjectdata, meta
+
+
+
+ + + diff --git a/docs/reference/openapi.md b/docs/reference/openapi.md index a13901e..43eaeab 100644 --- a/docs/reference/openapi.md +++ b/docs/reference/openapi.md @@ -17,6 +17,7 @@ make openapi-check ``` `make openapi-check` regenerates the contract, compares it with the committed file, and runs route contract tests for the HTTP adapter. +It also checks that the rendered static API docs in [`docs/openapi/index.html`](../openapi/index.html) and `site/marketing/public/api/index.html` match the committed contract. Check precision regression: @@ -28,6 +29,18 @@ make openapi-precision-check registered public routes and fails if any operation falls back to a broad request or response shape. +Render the human-readable static API docs after changing route metadata: + +```sh +scripts/render_openapi_docs.py --write +``` + +Check the rendered docs without modifying files: + +```sh +make rendered-openapi-check +``` + `make docs-check` compares the paths in `openapi.yaml` with the endpoint catalog in [API reference](../api.md). Add every generated path to that catalog, or the docs check fails. ## Review The Contract @@ -46,6 +59,23 @@ Inspect one operation: jq '.paths["/v1/evidence"].post' openapi.yaml ``` +For a browser-friendly route and schema index, open: + +```text +docs/openapi/index.html +``` + +The marketing-site copy is generated at: + +```text +site/marketing/public/api/index.html +``` + +The rendered page is static, uses no remote scripts, and is regenerated from +the committed public OpenAPI contract. It must not contain runtime secrets, +tenant data, raw evidence payloads, bearer tokens, private keys, or customer +package contents. + The API also serves the generated contract at: ```http @@ -55,8 +85,9 @@ GET /v1/openapi.json ## Current Limitations - `openapi.yaml` is generated in a compact JSON-compatible representation. +- `docs/openapi/index.html` is generated from `openapi.yaml` for human review. - Registered public routes have endpoint-specific request and response schemas. -- New routes must update operation metadata, component schemas, `openapi.yaml`, and the generated [API contract matrix](api-contract-matrix.md). +- New routes must update operation metadata, component schemas, `openapi.yaml`, the generated [API contract matrix](api-contract-matrix.md), and the rendered [OpenAPI docs](../openapi/index.html). - Do not hand-edit `openapi.yaml`; update route metadata or the generator, then run `make openapi-check`. Route registration and OpenAPI generation use the same HTTP adapter registry so tests can catch missing routes or stale operation metadata. diff --git a/docs/reference/source-of-truth.md b/docs/reference/source-of-truth.md index 11e3367..58bafa7 100644 --- a/docs/reference/source-of-truth.md +++ b/docs/reference/source-of-truth.md @@ -9,7 +9,7 @@ product-boundary language across the docs. | Buyer evaluation path | `docs/buyer-overview.md` | Links demo, package viewer, release evidence, capability map, and API review without duplicating commands. | | Operator path | `docs/operator-overview.md` and `docs/operations.md` | Links install, config, deployment, gates, runbooks, and production boundaries. | | Runtime configuration | `docs/reference/configuration.md` | How-to guides may show a short example, then link here for variables. | -| API routes, scopes, idempotency, schemas | `openapi.yaml`, `docs/api.md`, `docs/reference/api-contract-matrix.md` | `openapi.yaml` is generated; the matrix is generated from it. | +| API routes, scopes, idempotency, schemas | `openapi.yaml`, `docs/api.md`, `docs/reference/api-contract-matrix.md`, and `docs/openapi/index.html` | `openapi.yaml` is generated; the matrix and rendered OpenAPI docs are generated from it. | | Local startup | `docs/tutorials/getting-started.md` | Uses in-process state only. | | Durable operation | `docs/how-to/install-and-operate.md` | Includes PostgreSQL/object storage and production-like Compose rehearsal. | | Kubernetes | `docs/kubernetes.md` | Helm-specific operator interface. | diff --git a/scripts/render_openapi_docs.py b/scripts/render_openapi_docs.py new file mode 100755 index 0000000..a979d42 --- /dev/null +++ b/scripts/render_openapi_docs.py @@ -0,0 +1,456 @@ +#!/usr/bin/env python3 +"""Render a deterministic static OpenAPI reference page. + +The renderer intentionally avoids remote assets and does not execute shell +commands. It reads the committed OpenAPI document and writes a static HTML page +that can be reviewed locally or hosted as a static artifact. +""" + +from __future__ import annotations + +import argparse +import html +import json +import sys +from pathlib import Path +from typing import Any + + +ROOT = Path(__file__).resolve().parents[1] +OPENAPI_PATH = ROOT / "openapi.yaml" +OUTPUT_PATHS = ( + ROOT / "docs" / "openapi" / "index.html", + ROOT / "site" / "marketing" / "public" / "api" / "index.html", +) +HTTP_METHODS = ("get", "post", "put", "patch", "delete", "options", "head") + + +def escape(value: Any) -> str: + return html.escape(str(value), quote=True) + + +def load_spec() -> dict[str, Any]: + try: + return json.loads(OPENAPI_PATH.read_text(encoding="utf-8")) + except json.JSONDecodeError as exc: + raise SystemExit(f"{OPENAPI_PATH} is not valid JSON-compatible OpenAPI: {exc}") from exc + + +def ref_name(ref: str) -> str: + return ref.rsplit("/", 1)[-1] + + +def schema_label(schema: Any) -> str: + if not isinstance(schema, dict): + return "unspecified" + if "$ref" in schema: + return ref_name(schema["$ref"]) + if "oneOf" in schema: + return "oneOf(" + ", ".join(schema_label(item) for item in schema["oneOf"]) + ")" + if "anyOf" in schema: + return "anyOf(" + ", ".join(schema_label(item) for item in schema["anyOf"]) + ")" + if "allOf" in schema: + return "allOf(" + ", ".join(schema_label(item) for item in schema["allOf"]) + ")" + typ = schema.get("type") + if typ == "array": + return f"array[{schema_label(schema.get('items'))}]" + if isinstance(typ, list): + return "|".join(str(item) for item in typ) + return str(typ or "object") + + +def sorted_response_codes(responses: dict[str, Any]) -> list[str]: + def key(code: str) -> tuple[int, str]: + if code.isdigit(): + return (int(code), code) + return (9999, code) + + return sorted(responses, key=key) + + +def operation_security(operation: dict[str, Any]) -> str: + security = operation.get("security") + if security == []: + return "Public" + if not security: + return "BearerAuth" + schemes = [] + for entry in security: + if isinstance(entry, dict): + schemes.extend(entry.keys()) + return ", ".join(sorted(set(schemes))) or "BearerAuth" + + +def operation_scopes(operation: dict[str, Any]) -> str: + scopes = operation.get("x-scopes") or [] + if not scopes: + return "none" + return ", ".join(str(scope) for scope in scopes) + + +def operation_idempotency(operation: dict[str, Any]) -> str: + idempotency = operation.get("x-idempotency-key") + if isinstance(idempotency, dict) and idempotency.get("required"): + return str(idempotency.get("header") or "Idempotency-Key") + return "not required" + + +def request_summary(operation: dict[str, Any]) -> str: + body = operation.get("requestBody") + if not isinstance(body, dict): + return "none" + content = body.get("content") + if not isinstance(content, dict) or not content: + return "present" + pieces = [] + for media_type in sorted(content): + media = content.get(media_type) or {} + pieces.append(f"{media_type}: {schema_label(media.get('schema'))}") + return "; ".join(pieces) + + +def response_summary(operation: dict[str, Any]) -> str: + responses = operation.get("responses") + if not isinstance(responses, dict): + return "none" + pieces = [] + for code in sorted_response_codes(responses): + response = responses.get(code) or {} + content = response.get("content") or {} + schemas = [] + for media_type in sorted(content): + media = content.get(media_type) or {} + schemas.append(f"{media_type}: {schema_label(media.get('schema'))}") + description = response.get("description") or "" + detail = ", ".join(schemas) if schemas else description + pieces.append(f"{code} {detail}".strip()) + return "; ".join(pieces) + + +def collect_operations(spec: dict[str, Any]) -> list[dict[str, str]]: + operations: list[dict[str, str]] = [] + paths = spec.get("paths") + if not isinstance(paths, dict): + raise SystemExit("OpenAPI document is missing a paths object") + + for path in sorted(paths): + item = paths[path] + if not isinstance(item, dict): + continue + for method in HTTP_METHODS: + operation = item.get(method) + if not isinstance(operation, dict): + continue + operations.append( + { + "method": method.upper(), + "path": path, + "summary": str(operation.get("summary") or ""), + "description": str(operation.get("description") or ""), + "operation_id": str(operation.get("operationId") or ""), + "tags": ", ".join(str(tag) for tag in operation.get("tags") or []), + "security": operation_security(operation), + "scopes": operation_scopes(operation), + "idempotency": operation_idempotency(operation), + "request": request_summary(operation), + "responses": response_summary(operation), + "search": " ".join( + str(part) + for part in ( + method, + path, + operation.get("summary") or "", + operation.get("description") or "", + operation.get("operationId") or "", + " ".join(operation.get("tags") or []), + operation_scopes(operation), + ) + ).lower(), + } + ) + return operations + + +def collect_schemas(spec: dict[str, Any]) -> list[dict[str, str]]: + schemas = spec.get("components", {}).get("schemas", {}) + if not isinstance(schemas, dict): + return [] + rows = [] + for name in sorted(schemas): + schema = schemas[name] + required = schema.get("required") if isinstance(schema, dict) else None + rows.append( + { + "name": name, + "type": schema_label(schema), + "required": ", ".join(str(item) for item in required or []) or "none", + } + ) + return rows + + +def render(spec: dict[str, Any]) -> str: + operations = collect_operations(spec) + schemas = collect_schemas(spec) + info = spec.get("info") or {} + problem_schema = spec.get("components", {}).get("schemas", {}).get("Problem", {}) + problem_required = ", ".join(problem_schema.get("required") or []) if isinstance(problem_schema, dict) else "none" + + operation_html = [] + for op in operations: + search = escape(op["search"]) + operation_html.append( + f""" +
+
+ {escape(op['method'])} + {escape(op['path'])} +
+

{escape(op['summary'] or op['operation_id'] or op['path'])}

+

{escape(op['description'] or 'No operation description is registered.')}

+
+
Operation ID
{escape(op['operation_id'] or 'not registered')}
+
Tags
{escape(op['tags'] or 'none')}
+
Auth
{escape(op['security'])}
+
Scopes
{escape(op['scopes'])}
+
Idempotency
{escape(op['idempotency'])}
+
Request
{escape(op['request'])}
+
Responses
{escape(op['responses'])}
+
+
""" + ) + + schema_html = [] + for schema in schemas: + schema_html.append( + f""" + + {escape(schema['name'])} + {escape(schema['type'])} + {escape(schema['required'])} + """ + ) + + return f""" + + + + + {escape(info.get('title') or 'Evydence API')} - Rendered OpenAPI Docs + + + +
+

{escape(info.get('title') or 'Evydence API')}

+

{escape(info.get('description') or 'Rendered OpenAPI reference for Evydence.')}

+

This page is generated from openapi.yaml. It is a human-readable companion to the committed contract and does not replace route-contract tests.

+
+
{escape(spec.get('openapi') or 'unknown')}OpenAPI version
+
{len(spec.get('paths') or {})}registered paths
+
{len(operations)}operations
+
{len(schemas)}schemas
+
+
+
+
+

Runtime secrets, tenant data, raw evidence payloads, private keys, bearer tokens, and customer package contents are not embedded in this generated page. Admin-scoped routes appear only when they are part of the committed public contract.

+

Error responses use RFC 9457-style Problem Details. The registered Problem schema currently requires: {escape(problem_required or 'none')}.

+
+ +
+

Operations

+
+ + +
+
+ {''.join(operation_html)} +
+
+ +
+

Schemas

+
+ + + + + + {''.join(schema_html)} + +
NameShapeRequired fields
+
+
+
+ + + +""" + + +def main() -> int: + parser = argparse.ArgumentParser(description="Render or check static OpenAPI docs") + mode = parser.add_mutually_exclusive_group(required=True) + mode.add_argument("--write", action="store_true", help="write docs/openapi/index.html") + mode.add_argument("--check", action="store_true", help="fail if docs/openapi/index.html is stale") + args = parser.parse_args() + + rendered = render(load_spec()) + if args.write: + for path in OUTPUT_PATHS: + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(rendered, encoding="utf-8") + return 0 + + stale = False + try: + for path in OUTPUT_PATHS: + current = path.read_text(encoding="utf-8") + if current != rendered: + print(f"{path} is stale; run scripts/render_openapi_docs.py --write", file=sys.stderr) + stale = True + except FileNotFoundError as exc: + print(f"{exc.filename} is missing; run scripts/render_openapi_docs.py --write", file=sys.stderr) + return 1 + return 1 if stale else 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/site/marketing/public/api/index.html b/site/marketing/public/api/index.html new file mode 100644 index 0000000..bb1407d --- /dev/null +++ b/site/marketing/public/api/index.html @@ -0,0 +1,5228 @@ + + + + + + Evydence API - Rendered OpenAPI Docs + + + +
+

Evydence API

+

Self-hosted API evidence and compliance-readiness ledger.

+

This page is generated from openapi.yaml. It is a human-readable companion to the committed contract and does not replace route-contract tests.

+
+
3.1.0OpenAPI version
+
169registered paths
+
186operations
+
375schemas
+
+
+
+
+

Runtime secrets, tenant data, raw evidence payloads, private keys, bearer tokens, and customer package contents are not embedded in this generated page. Admin-scoped routes appear only when they are part of the committed public contract.

+

Error responses use RFC 9457-style Problem Details. The registered Problem schema currently requires: none.

+
+ +
+

Operations

+
+ + +
+
+ +
+
+ GET + /v1/admin/instance +
+

Instance admin snapshot

+

Returns instance-level diagnostic counts. Requires the explicit instance:admin scope; tenant admin and ordinary wildcard tenant keys are insufficient.

+
+
Operation ID
instanceAdminSnapshot
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
instance:admin
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: InstanceAdminSnapshotEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/api-keys +
+

List API keys

+

Lists tenant-scoped API key metadata without key hashes or one-time secrets.

+
+
Operation ID
listAPIKeys
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
admin
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: APIKeyListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/api-keys +
+

Create API key

+

Creates a tenant-scoped API key and returns the secret exactly once. Stored records expose only non-secret key metadata.

+
+
Operation ID
createAPIKey
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateAPIKeyRequest
+
Responses
201 application/json: APIKeyCreateEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/api-security-scans +
+

Upload API security scan

+

Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.

+
+
Operation ID
uploadAPISecurityScan
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
security:write
+
Idempotency
Idempotency-Key
+
Request
application/json: UploadSecurityScanRequest
+
Responses
201 application/json: SecurityScanEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/approvals +
+

Create approval record

+

Creates an immutable approval record for a release, waiver, package, or review subject.

+
+
Operation ID
createApproval
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
release:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateApprovalRequest
+
Responses
201 application/json: ApprovalRecordEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/artifact-signatures +
+

Create artifact signature

+

Records detached artifact signature evidence and optional raw signature payload metadata.

+
+
Operation ID
createArtifactSignature
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateArtifactSignatureRequest
+
Responses
201 application/json: ArtifactSignatureEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/artifact-signatures/{id} +
+

Get artifact signature

+

Returns tenant-scoped artifact signature metadata by id.

+
+
Operation ID
getArtifactSignature
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ArtifactSignatureEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/artifact-signatures/{id}/verify-cosign +
+

Verify cosign-style artifact signature

+

Records deterministic cosign-style verification metadata for an artifact signature without implying online transparency trust.

+
+
Operation ID
verifyCosignSignature
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
verify:read
+
Idempotency
Idempotency-Key
+
Request
application/json: VerifyCosignSignatureRequest
+
Responses
200 application/json: CosignVerificationEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/artifacts +
+

Register artifact

+

Registers an artifact digest for release evidence and later build/attestation matching.

+
+
Operation ID
registerArtifact
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:write
+
Idempotency
Idempotency-Key
+
Request
application/json: RegisterArtifactRequest
+
Responses
201 application/json: ArtifactEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/artifacts/{id} +
+

Get artifact

+

Returns a tenant-scoped artifact by id.

+
+
Operation ID
getArtifact
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ArtifactEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/audit-chain/verify +
+

Verify audit chain

+

Verifies the tenant audit chain continuity and returns deterministic verification checks.

+
+
Operation ID
verifyAuditChain
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
verify:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: VerificationResultEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/audit-log +
+

List tenant audit log

+

Lists tenant-scoped append-only audit-chain entries in reverse chronological order.

+
+
Operation ID
listAuditLog
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
admin
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: AuditChainEntryListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/backup-manifests +
+

Generate backup manifest

+

Generates a tenant-scoped backup manifest after an operator backup completes. The manifest excludes raw payload bytes and private key material.

+
+
Operation ID
generateBackupManifest
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
admin
+
Idempotency
Idempotency-Key
+
Request
application/json: EmptyObject
+
Responses
201 application/json: BackupManifestEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/backup-manifests/{id}/verify +
+

Verify backup manifest

+

Verifies a tenant-scoped backup manifest and returns deterministic manifest verification checks.

+
+
Operation ID
verifyBackupManifest
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
verify:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: VerificationResultEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/build-attestations/{id}/verify-signature +
+

Verify build attestation signature

+

Verifies a build attestation signature against configured tenant DSSE trust roots.

+
+
Operation ID
verifyBuildAttestationSignature
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
verify:read
+
Idempotency
Idempotency-Key
+
Request
application/json: EmptyObject
+
Responses
200 application/json: VerificationResultEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/builds +
+

Create build run

+

Records an immutable CI build run. Collector identity is derived from the authenticated key when present.

+
+
Operation ID
createBuild
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
build:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateBuildRequest
+
Responses
201 application/json: BuildRunEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/builds/{id} +
+

Get build run

+

Returns a tenant-scoped build run by id.

+
+
Operation ID
getBuild
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
build:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: BuildRunEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/builds/{id}/attestations +
+

Upload build attestation

+

Uploads a DSSE/in-toto build attestation for a tenant-scoped build and stores raw bytes in object storage.

+
+
Operation ID
uploadBuildAttestation
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
build:write
+
Idempotency
Idempotency-Key
+
Request
application/json: DSSEEnvelope
+
Responses
201 application/json: BuildAttestationEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/collectors +
+

List collectors

+

Lists tenant-scoped collector metadata without API key hashes or one-time secrets.

+
+
Operation ID
listCollectors
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
collector:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: CollectorListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/collectors +
+

Create collector

+

Creates a tenant-scoped collector identity, binds a scoped API key, and returns the collector key secret exactly once.

+
+
Operation ID
createCollector
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
collector:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateCollectorRequest
+
Responses
201 application/json: CollectorCreateEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/collectors/github/source-snapshots +
+

Upload GitHub source snapshot

+

Uploads a strict GitHub source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.

+
+
Operation ID
uploadGitHubSourceSnapshot
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
source:write
+
Idempotency
Idempotency-Key
+
Request
application/json: SourceSnapshotRequest
+
Responses
201 application/json: SourceSnapshotEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/collectors/gitlab/source-snapshots +
+

Upload GitLab source snapshot

+

Uploads a strict GitLab source snapshot, hashes commit messages, and stores repository, commit, branch, and pull-request evidence records.

+
+
Operation ID
uploadGitLabSourceSnapshot
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
source:write
+
Idempotency
Idempotency-Key
+
Request
application/json: SourceSnapshotRequest
+
Responses
201 application/json: SourceSnapshotEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/collectors/{id}/health +
+

Collector health report

+

Returns collector supply-chain health from recorded tenant evidence, assumptions, and limitations.

+
+
Operation ID
collectorHealthReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
collector:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: CollectorHealthReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/collectors/{id}/releases +
+

Record collector release evidence

+

Records collector release supply-chain evidence for a tenant-scoped collector.

+
+
Operation ID
recordCollectorRelease
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
collector:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: RecordCollectorReleaseRequest
+
Responses
201 application/json: CollectorReleaseEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/commercial-collectors +
+

List commercial collector definitions

+

Lists tenant-scoped commercial collector definitions.

+
+
Operation ID
listCommercialCollectors
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
collector:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: CommercialCollectorDefinitionListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/commercial-collectors +
+

Create commercial collector definition

+

Creates tenant-scoped commercial collector metadata without installing external code.

+
+
Operation ID
createCommercialCollector
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
collector:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateCommercialCollectorRequest
+
Responses
201 application/json: CommercialCollectorDefinitionEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/container-images +
+

Register container image

+

Registers OCI/container image metadata and digest evidence linked to an optional artifact.

+
+
Operation ID
registerContainerImage
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:write
+
Idempotency
Idempotency-Key
+
Request
application/json: RegisterContainerImageRequest
+
Responses
201 application/json: ContainerImageEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/control-evidence +
+

List control evidence

+

Lists tenant-scoped control evidence links with optional control, product, and release filters.

+
+
Operation ID
listControlEvidence
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
controls:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ControlEvidenceListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/control-framework-template-packs +
+

List control framework template packs

+

Lists built-in control framework template packs available for explicit tenant installation.

+
+
Operation ID
listControlFrameworkTemplatePacks
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
controls:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ControlFrameworkTemplatePackListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/control-framework-template-packs/{slug}/install +
+

Install control framework template pack

+

Installs a named control framework template pack into the tenant as ordinary framework/control records.

+
+
Operation ID
installControlFrameworkTemplatePack
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
controls:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: EmptyObject
+
Responses
201 application/json: ControlFrameworkEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/control-frameworks +
+

List control frameworks

+

Lists tenant-scoped control frameworks.

+
+
Operation ID
listControlFrameworks
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
controls:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ControlFrameworkListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/control-frameworks +
+

Create control framework

+

Creates a tenant-scoped versioned control framework.

+
+
Operation ID
createControlFramework
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
controls:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateControlFrameworkRequest
+
Responses
201 application/json: ControlFrameworkEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/controls +
+

Create security control

+

Creates a framework-owned security control with deterministic evidence requirements.

+
+
Operation ID
createSecurityControl
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
controls:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateSecurityControlRequest
+
Responses
201 application/json: SecurityControlEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/controls/{id} +
+

Get security control

+

Returns a tenant-scoped security control by id.

+
+
Operation ID
getSecurityControl
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
controls:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: SecurityControlEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/controls/{id}/evidence +
+

Link control evidence

+

Creates an append-only link between a security control and tenant-scoped evidence or related release resource.

+
+
Operation ID
linkControlEvidence
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
controls:write
+
Idempotency
Idempotency-Key
+
Request
application/json: LinkControlEvidenceRequest
+
Responses
201 application/json: ControlEvidenceEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/custom-policies +
+

Create custom policy

+

Creates a deterministic custom policy definition for tenant-managed release checks.

+
+
Operation ID
createCustomPolicy
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
policy:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateCustomPolicyRequest
+
Responses
201 application/json: CustomPolicyEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/custom-policies/{id}/evaluate +
+

Evaluate custom policy

+

Evaluates a tenant custom policy against a release and records the input hash.

+
+
Operation ID
evaluateCustomPolicy
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
policy:read
+
Idempotency
Idempotency-Key
+
Request
application/json: EvaluatePolicyRequest
+
Responses
201 application/json: CustomPolicyEvaluationEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/customer-packages +
+

Create customer security package

+

Creates a scoped customer security package manifest using an explicit redaction profile.

+
+
Operation ID
createCustomerPackage
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
package:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateCustomerPackageRequest
+
Responses
201 application/json: CustomerSecurityPackageEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/customer-packages/{id} +
+

Get customer security package

+

Returns a tenant-scoped customer security package manifest by id.

+
+
Operation ID
getCustomerPackage
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
package:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: CustomerSecurityPackageEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/customer-packages/{id}/download +
+

Download customer security package ZIP

+

Downloads a scoped customer security package ZIP. The archive contains redacted manifest metadata and verification guidance, not raw tenant evidence payload bytes.

+
+
Operation ID
downloadCustomerPackage
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
package:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/zip: string; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/customer-portal/access +
+

List customer portal access records

+

Lists tenant-scoped external reviewer access records without token hashes or token secrets.

+
+
Operation ID
listCustomerPortalAccess
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
package:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: CustomerPortalAccessListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/customer-portal/access +
+

Create customer portal access

+

Creates a named, expiring external reviewer access record for a customer package and returns the portal token once.

+
+
Operation ID
createCustomerPortalAccess
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
package:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateCustomerPortalAccessRequest
+
Responses
201 application/json: CustomerPortalAccessCreateEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/customer-portal/access/{id}/revoke +
+

Revoke customer portal access

+

Revokes a tenant-scoped external reviewer access record; revocation is append-only and the original token cannot be used afterwards.

+
+
Operation ID
revokeCustomerPortalAccess
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
package:write
+
Idempotency
Idempotency-Key
+
Request
application/json: EmptyObject
+
Responses
200 application/json: CustomerPortalAccessEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/customer-portal/package +
+

Access customer portal package

+

Public token exchange endpoint for a scoped customer package. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.

+
+
Operation ID
accessCustomerPortalPackage
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
none
+
Idempotency
Idempotency-Key
+
Request
application/json: CustomerPortalPackageRequest
+
Responses
200 application/json: CustomerSecurityPackageEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/customer-portal/package/download +
+

Download customer portal package ZIP

+

Public token exchange endpoint for downloading a scoped customer package ZIP. It intentionally uses no bearer authentication and accepts only the issued portal token in the JSON body.

+
+
Operation ID
downloadCustomerPortalPackage
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
none
+
Idempotency
Idempotency-Key
+
Request
application/json: CustomerPortalPackageRequest
+
Responses
200 application/zip: string; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/customer-portal/package/view +
+

Customer portal package review form

+

Public HTML form for reviewing or downloading a scoped customer package with a portal token. It does not accept tokens in URLs and does not use bearer authentication.

+
+
Operation ID
customerPortalPackageViewForm
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
none
+
Idempotency
not required
+
Request
none
+
Responses
200 text/html: string; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/customer-portal/package/view +
+

Customer portal package review page

+

Public HTML package review endpoint backed by the customer portal token exchange. Tokens are accepted only as form body fields.

+
+
Operation ID
customerPortalPackageView
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
none
+
Idempotency
Idempotency-Key
+
Request
application/x-www-form-urlencoded: CustomerPortalPackageRequest
+
Responses
200 text/html: string; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/customer-portal/package/view/download +
+

Download customer portal package ZIP from review form

+

Public HTML-form package ZIP download endpoint backed by the customer portal token exchange. Tokens are accepted only as form body fields.

+
+
Operation ID
downloadCustomerPortalPackageView
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
none
+
Idempotency
Idempotency-Key
+
Request
application/x-www-form-urlencoded: CustomerPortalPackageRequest
+
Responses
200 application/zip: string; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/deployments +
+

List deployments

+

Lists tenant-scoped deployment events by optional release and environment filters.

+
+
Operation ID
listDeployments
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
deployment:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: DeploymentEventListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/deployments +
+

Record deployment

+

Records append-only deployment evidence for a release/environment/artifact set.

+
+
Operation ID
recordDeployment
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
deployment:write
+
Idempotency
Idempotency-Key
+
Request
application/json: RecordDeploymentRequest
+
Responses
201 application/json: DeploymentEventEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/deployments/{id} +
+

Get deployment

+

Returns a tenant-scoped deployment event by id.

+
+
Operation ID
getDeployment
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
deployment:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: DeploymentEventEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/dsse-trust-roots +
+

Create DSSE trust root

+

Creates a tenant-scoped DSSE trust root using public verification key material only.

+
+
Operation ID
createDSSETrustRoot
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
keys:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateDSSETrustRootRequest
+
Responses
201 application/json: DSSETrustRootEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/environments +
+

List deployment environments

+

Lists tenant-scoped deployment environments, optionally filtered by product.

+
+
Operation ID
listDeploymentEnvironments
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
deployment:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: DeploymentEnvironmentListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/environments +
+

Create deployment environment

+

Creates a tenant-scoped deployment environment for release deployment evidence.

+
+
Operation ID
createDeploymentEnvironment
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
deployment:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateDeploymentEnvironmentRequest
+
Responses
201 application/json: DeploymentEnvironmentEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/evidence +
+

List evidence

+

Lists tenant-scoped evidence by optional release and evidence type filters.

+
+
Operation ID
listEvidence
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: EvidenceItemListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/evidence +
+

Create evidence

+

Creates immutable evidence metadata and optional raw payload evidence. Evidence core fields are append-only after creation.

+
+
Operation ID
createEvidence
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateEvidenceRequest
+
Responses
201 application/json: EvidenceItemEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/evidence-bundles +
+

Export evidence bundle

+

Exports a portable evidence bundle manifest with hashes, signatures, and verification text.

+
+
Operation ID
exportEvidenceBundle
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
bundle:read
+
Idempotency
Idempotency-Key
+
Request
application/json: ExportEvidenceBundleRequest
+
Responses
201 application/json: EvidenceBundleEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/evidence-bundles/import +
+

Import evidence bundle

+

Imports a portable evidence bundle manifest and records deterministic import metadata.

+
+
Operation ID
importEvidenceBundle
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
bundle:write
+
Idempotency
Idempotency-Key
+
Request
application/json: EvidenceBundle
+
Responses
201 application/json: EvidenceBundleImportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/evidence-graph-snapshots +
+

Create evidence graph snapshot

+

Creates a deterministic product/release evidence adjacency snapshot from stored tenant-scoped evidence records.

+
+
Operation ID
createGraphSnapshot
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateGraphSnapshotRequest
+
Responses
201 application/json: EvidenceGraphSnapshotEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/evidence-summaries +
+

Create evidence-backed summary

+

Creates an evidence-backed summary with citations, assumptions, and limitations.

+
+
Operation ID
createEvidenceSummary
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
report:read
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateEvidenceSummaryRequest
+
Responses
201 application/json: EvidenceSummaryEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/evidence/search +
+

Search evidence

+

Searches tenant-scoped evidence with deterministic filters and cursor-style pagination.

+
+
Operation ID
searchEvidence
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: EvidenceSearchEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/evidence/{id} +
+

Get evidence

+

Returns a tenant-scoped immutable evidence item by id.

+
+
Operation ID
getEvidence
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: EvidenceItemEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/evidence/{id}/lifecycle-events +
+

List evidence lifecycle events

+

Lists append-only lifecycle events for a tenant-scoped evidence item.

+
+
Operation ID
listEvidenceLifecycleEvents
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: EvidenceLifecycleEventListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/evidence/{id}/lifecycle-events +
+

Record evidence lifecycle event

+

Appends an evidence lifecycle event such as amendment, redaction marker, tombstone, or retention marker.

+
+
Operation ID
recordEvidenceLifecycleEvent
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:write
+
Idempotency
Idempotency-Key
+
Request
application/json: RecordEvidenceLifecycleEventRequest
+
Responses
201 application/json: EvidenceLifecycleEventEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/evidence/{id}/link +
+

Link evidence

+

Creates an append-only relationship from evidence to another tenant-scoped subject.

+
+
Operation ID
linkEvidence
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:write
+
Idempotency
Idempotency-Key
+
Request
application/json: LinkEvidenceRequest
+
Responses
201 application/json: EvidenceItemEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/evidence/{id}/supersede +
+

Supersede evidence

+

Supersedes immutable evidence by linking it to replacement evidence and appending lifecycle metadata.

+
+
Operation ID
supersedeEvidence
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:write
+
Idempotency
Idempotency-Key
+
Request
application/json: SupersedeEvidenceRequest
+
Responses
201 application/json: EvidenceItemEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/exceptions +
+

List exceptions

+

Lists tenant-scoped exceptions, optionally filtered by release.

+
+
Operation ID
listExceptions
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
verify:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ExceptionListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/exceptions +
+

Create exception

+

Creates a scoped, expiring release/finding/control exception that is inactive until approved.

+
+
Operation ID
createException
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
release:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateExceptionRequest
+
Responses
201 application/json: ExceptionEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/exceptions/{id}/approve +
+

Approve exception

+

Approves an unexpired exception as an audited append-only transition.

+
+
Operation ID
approveException
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
release:write
+
Idempotency
Idempotency-Key
+
Request
application/json: EmptyObject
+
Responses
200 application/json: ExceptionEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/health +
+

Health

+

Returns low-detail liveness status without touching tenant evidence or secret material.

+
+
Operation ID
health
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
none
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: HealthStatusEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/incident-webhooks/{receiver_id} +
+

Receive signed incident webhook event

+

Public signed webhook endpoint for incident timeline events. It verifies Ed25519 signature, event id replay, and timestamp before parsing payload fields.

+
+
Operation ID
receiveIncidentWebhook
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
none
+
Idempotency
not required
+
Request
application/json: SignedIncidentWebhookPayload
+
Responses
201 application/json: IncidentWebhookDeliveryEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/incidents +
+

Create incident

+

Creates an append-only incident record linked to tenant-scoped product and optional release evidence.

+
+
Operation ID
createIncident
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
incident:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateIncidentRequest
+
Responses
201 application/json: IncidentEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/incidents/{id}/timeline +
+

Record incident timeline event

+

Appends an incident timeline event and optional evidence reference.

+
+
Operation ID
recordIncidentTimeline
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
incident:write
+
Idempotency
Idempotency-Key
+
Request
application/json: RecordIncidentTimelineRequest
+
Responses
201 application/json: IncidentTimelineEventEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/incidents/{id}/webhook-receivers +
+

Create signed incident webhook receiver

+

Creates an incident-scoped webhook receiver with an Ed25519 public key. The matching private key stays with the external incident tool.

+
+
Operation ID
createIncidentWebhookReceiver
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
incident:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateIncidentWebhookReceiverRequest
+
Responses
201 application/json: IncidentWebhookReceiverEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/legal-holds +
+

Create legal hold

+

Creates an append-only legal-hold marker for a tenant-scoped retention subject.

+
+
Operation ID
createLegalHold
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateLegalHoldRequest
+
Responses
201 application/json: LegalHoldEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/marketplace-collectors +
+

List marketplace collector records

+

Lists tenant-scoped marketplace collector package metadata.

+
+
Operation ID
listMarketplaceCollectors
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
collector:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: MarketplaceCollectorListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/marketplace-collectors +
+

Create marketplace collector record

+

Creates tenant-scoped marketplace collector package metadata and evidence references.

+
+
Operation ID
createMarketplaceCollector
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
collector:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateMarketplaceCollectorRequest
+
Responses
201 application/json: MarketplaceCollectorEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/marketplace-collectors/{id}/health +
+

Marketplace collector health report

+

Returns marketplace collector package health from recorded signature, SBOM, and scan evidence.

+
+
Operation ID
marketplaceCollectorHealth
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
collector:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: MarketplaceCollectorHealthReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/merkle-batches +
+

Create Merkle checkpoint batch

+

Creates a Merkle batch over tenant audit-chain entries for checkpoint export or transparency anchoring.

+
+
Operation ID
createMerkleBatch
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
keys:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateMerkleBatchRequest
+
Responses
201 application/json: MerkleBatchEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/merkle-batches/{id}/verify +
+

Verify Merkle checkpoint batch

+

Verifies a tenant-scoped Merkle batch root and leaf set against stored audit-chain entries.

+
+
Operation ID
verifyMerkleBatch
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
verify:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: VerificationResultEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/metrics +
+

Safe tenant metrics

+

Returns safe tenant-scoped resource metrics for admin actors. A Prometheus text response is also available when requested with Accept: text/plain.

+
+
Operation ID
metrics
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
admin
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: MetricsSnapshotEnvelope, text/plain: string; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/object-retention-policies +
+

Create object retention policy record

+

Creates an object retention policy record for storage immutability verification.

+
+
Operation ID
createObjectRetentionPolicy
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateObjectRetentionPolicyRequest
+
Responses
201 application/json: ObjectRetentionPolicyEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/object-retention-policies/{id}/verify +
+

Verify object retention policy record

+

Records verification metadata for a tenant object retention policy.

+
+
Operation ID
verifyObjectRetentionPolicy
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
verify:read
+
Idempotency
Idempotency-Key
+
Request
application/json: EmptyObject
+
Responses
200 application/json: ObjectRetentionPolicyEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/openapi-contracts +
+

Upload OpenAPI contract

+

Uploads an OpenAPI 3.1 contract, stores raw bytes as evidence, and records normalized operation metadata.

+
+
Operation ID
uploadOpenAPIContract
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:write
+
Idempotency
Idempotency-Key
+
Request
application/json: UploadOpenAPIContractRequest
+
Responses
201 application/json: OpenAPIContractEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/openapi-contracts/{id} +
+

Get OpenAPI contract

+

Returns a tenant-scoped OpenAPI contract metadata record by id.

+
+
Operation ID
getOpenAPIContract
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: OpenAPIContractEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/openapi-diffs +
+

Create OpenAPI contract diff

+

Creates a deterministic OpenAPI contract diff for release contract checks.

+
+
Operation ID
createOpenAPIDiff
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateOpenAPIDiffRequest
+
Responses
201 application/json: ContractDiffEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/openapi.json +
+

OpenAPI

+

Returns the generated OpenAPI 3.1 document served by this process.

+
+
Operation ID
openapi
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
none
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: OpenAPIDocument; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/organizations +
+

Create organization

+

Creates a tenant-scoped organization record for human identity grouping.

+
+
Operation ID
createOrganization
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
identity:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateOrganizationRequest
+
Responses
201 application/json: OrganizationEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/policies/evaluate +
+

Evaluate release policy

+

Evaluates built-in deterministic release policy checks for a release.

+
+
Operation ID
evaluatePolicy
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
verify:read
+
Idempotency
Idempotency-Key
+
Request
application/json: EvaluatePolicyRequest
+
Responses
201 application/json: PolicyEvaluationEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/products +
+

List products

+

Lists tenant-scoped products visible to the authenticated actor.

+
+
Operation ID
listProducts
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
product:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ProductListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/products +
+

Create product

+

Creates a tenant-scoped product. Product slugs must be unique per tenant.

+
+
Operation ID
createProduct
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
product:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateProductRequest
+
Responses
201 application/json: ProductEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/products/{id} +
+

Get product

+

Returns a tenant-scoped product by id.

+
+
Operation ID
getProduct
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
product:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ProductEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/projects +
+

Create project

+

Creates a tenant-scoped project under a product.

+
+
Operation ID
createProject
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
project:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateProjectRequest
+
Responses
201 application/json: ProjectEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/projects/{id} +
+

Get project

+

Returns a tenant-scoped project by id.

+
+
Operation ID
getProject
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
project:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ProjectEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/provider-verifications +
+

Verify stored provider identity metadata

+

Verifies stored provider identity metadata and, when supplied, locally verifies OIDC ID-token or SAML assertion issuer, audience, subject, time bounds, and signature against configured tenant trust material.

+
+
Operation ID
verifyProviderIdentity
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
identity:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: VerifyProviderIdentityRequest
+
Responses
201 application/json: ProviderVerificationEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/public-transparency-log-entries +
+

Publish public transparency log entry record

+

Records publication metadata for a checkpoint submitted to a configured public transparency log.

+
+
Operation ID
publishPublicTransparencyLogEntry
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
keys:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: PublishPublicTransparencyLogEntryRequest
+
Responses
201 application/json: PublicTransparencyLogEntryEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/public-transparency-log-entries/{id}/fetch-proof +
+

Fetch and verify public transparency log inclusion proof

+

Fetches public transparency inclusion proof material from the configured log endpoint or transparency proof gateway and verifies it locally. Endpoint trust and provider semantics remain deployment responsibilities.

+
+
Operation ID
fetchPublicTransparencyLogEntryProof
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
keys:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: EmptyObject
+
Responses
200 application/json: PublicTransparencyLogEntryEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/public-transparency-log-entries/{id}/verify +
+

Verify public transparency log inclusion proof

+

Verifies operator-supplied RFC6962-style public transparency inclusion proof material for a published entry.

+
+
Operation ID
verifyPublicTransparencyLogEntry
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
keys:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: VerifyPublicTransparencyLogEntryRequest
+
Responses
200 application/json: PublicTransparencyLogEntryEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/public-transparency-logs +
+

Create public transparency log record

+

Creates tenant metadata for an optional public transparency log trust root.

+
+
Operation ID
createPublicTransparencyLog
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
keys:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreatePublicTransparencyLogRequest
+
Responses
201 application/json: PublicTransparencyLogEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/questionnaire-answer-library +
+

List questionnaire answer library entries

+

Lists tenant-scoped questionnaire answer library entries with optional question, product, and release filters.

+
+
Operation ID
listQuestionnaireAnswerLibrary
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
package:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: QuestionnaireAnswerLibraryEntryListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/questionnaire-answer-library +
+

Create questionnaire answer library entry

+

Creates a tenant-scoped reusable questionnaire answer draft linked to optional evidence, product, release, or control scope.

+
+
Operation ID
createQuestionnaireAnswerLibraryEntry
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
package:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateQuestionnaireAnswerLibraryEntryRequest
+
Responses
201 application/json: QuestionnaireAnswerLibraryEntryEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/questionnaire-drafts +
+

Create evidence-backed questionnaire draft

+

Creates an evidence-backed questionnaire draft with limitations.

+
+
Operation ID
createQuestionnaireDraft
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
package:read
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateQuestionnaireDraftRequest
+
Responses
201 application/json: QuestionnaireDraftEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/questionnaire-packages +
+

Create questionnaire package

+

Creates a questionnaire response package from a template and scoped evidence package.

+
+
Operation ID
createQuestionnairePackage
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
package:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateQuestionnairePackageRequest
+
Responses
201 application/json: QuestionnairePackageEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/questionnaire-templates +
+

Create questionnaire template

+

Creates a tenant questionnaire template with explicit evidence/control mapping fields.

+
+
Operation ID
createQuestionnaireTemplate
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
package:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateQuestionnaireTemplateRequest
+
Responses
201 application/json: QuestionnaireTemplateEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/ready +
+

Readiness

+

Returns low-detail process readiness without tenant evidence or secret material.

+
+
Operation ID
ready
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
none
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ReadinessStatusEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/redaction-profiles +
+

Create redaction profile

+

Creates an explicit redaction profile for customer and report package generation.

+
+
Operation ID
createRedactionProfile
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
package:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateRedactionProfileRequest
+
Responses
201 application/json: RedactionProfileEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/release-bundles +
+

Create release bundle

+

Creates an immutable signed release bundle for a release.

+
+
Operation ID
createReleaseBundle
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
bundle:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateReleaseBundleRequest
+
Responses
201 application/json: ReleaseBundleEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/release-bundles/{id} +
+

Get release bundle

+

Returns a tenant-scoped immutable release bundle by id.

+
+
Operation ID
getReleaseBundle
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
bundle:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ReleaseBundleEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/release-bundles/{id}/manifest +
+

Get release bundle manifest

+

Returns the deterministic release bundle manifest by bundle id.

+
+
Operation ID
getReleaseBundleManifest
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
bundle:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ReleaseBundleManifestEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/release-bundles/{id}/verify +
+

Verify release bundle

+

Verifies a tenant-scoped release bundle and returns a deterministic verification result.

+
+
Operation ID
verifyReleaseBundle
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
verify:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: VerificationResultEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/release-candidates +
+

List release candidates

+

Lists tenant-scoped release candidates, optionally filtered by release.

+
+
Operation ID
listReleaseCandidates
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
release:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ReleaseCandidateListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/release-candidates +
+

Create release candidate

+

Creates an immutable release-candidate snapshot of selected release evidence references.

+
+
Operation ID
createReleaseCandidate
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
release:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateReleaseCandidateRequest
+
Responses
201 application/json: ReleaseCandidateEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/release-candidates/{id} +
+

Get release candidate

+

Returns a tenant-scoped release candidate by id.

+
+
Operation ID
getReleaseCandidate
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
release:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ReleaseCandidateEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/release-candidates/{id}/promote +
+

Promote release candidate

+

Records a release-candidate lifecycle transition without mutating the original snapshot.

+
+
Operation ID
promoteReleaseCandidate
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
release:write
+
Idempotency
Idempotency-Key
+
Request
application/json: ReleaseCandidateTransitionRequest
+
Responses
200 application/json: ReleaseCandidateEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/release-candidates/{id}/reject +
+

Reject release candidate

+

Records a release-candidate lifecycle transition without mutating the original snapshot.

+
+
Operation ID
rejectReleaseCandidate
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
release:write
+
Idempotency
Idempotency-Key
+
Request
application/json: ReleaseCandidateTransitionRequest
+
Responses
200 application/json: ReleaseCandidateEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/releases +
+

Create release

+

Creates an append-only release record under a product and optional project.

+
+
Operation ID
createRelease
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
release:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateReleaseRequest
+
Responses
201 application/json: ReleaseEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/releases/{id} +
+

Get release

+

Returns a tenant-scoped release by id.

+
+
Operation ID
getRelease
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
release:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ReleaseEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/releases/{id}/approve +
+

Approve release

+

Approves a release as an append-only transition.

+
+
Operation ID
approveRelease
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
release:write
+
Idempotency
Idempotency-Key
+
Request
application/json: EmptyObject
+
Responses
200 application/json: ReleaseEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/releases/{id}/evidence-flow/start +
+

Start release evidence flow

+

Returns a high-level release evidence workflow plan, current evidence counts, required scopes, assumptions, and limitations. This read-only convenience operation does not create evidence.

+
+
Operation ID
startReleaseEvidenceFlow
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
release:read
+
Idempotency
Idempotency-Key
+
Request
none
+
Responses
200 application/json: ReleaseEvidenceFlowEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/releases/{id}/freeze +
+

Freeze release

+

Freezes a release as an append-only transition.

+
+
Operation ID
freezeRelease
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
release:write
+
Idempotency
Idempotency-Key
+
Request
application/json: EmptyObject
+
Responses
200 application/json: ReleaseEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/releases/{id}/security-summary +
+

Release security summary

+

Returns a tenant-scoped release security summary for review surfaces without raw evidence payload bytes.

+
+
Operation ID
releaseSecuritySummary
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
report:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ReleaseSecuritySummaryEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/remediation-tasks +
+

Create remediation task

+

Creates an incident or release remediation task linked to optional evidence.

+
+
Operation ID
createRemediationTask
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
incident:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateRemediationTaskRequest
+
Responses
201 application/json: RemediationTaskEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/report-templates +
+

Create report template

+

Creates a tenant-defined deterministic report template with an explicit allowed-field list.

+
+
Operation ID
createReportTemplate
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
report:read
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateReportTemplateRequest
+
Responses
201 application/json: CustomReportTemplateEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/report-templates/{id}/render +
+

Render report template

+

Renders a tenant report template for a scoped subject using allowed fields only.

+
+
Operation ID
renderReportTemplate
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
report:read
+
Idempotency
Idempotency-Key
+
Request
application/json: RenderReportTemplateRequest
+
Responses
201 application/json: RenderedCustomReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/reports/anomaly +
+

Generate deterministic anomaly report

+

Creates a deterministic anomaly report over existing tenant evidence and metrics with assumptions and limitations.

+
+
Operation ID
generateAnomalyReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
report:read
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateAnomalyReportRequest
+
Responses
201 application/json: AnomalyReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/reports/control-coverage +
+

Control coverage report

+

Returns deterministic control coverage with linked evidence, missing evidence, assumptions, and limitations.

+
+
Operation ID
controlCoverageReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
report:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ReadinessReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/reports/cra-readiness +
+

CRA readiness report

+

Returns a CRA-oriented readiness report without legal compliance or certification conclusions.

+
+
Operation ID
craReadinessReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
report:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ReadinessReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/reports/cra-readiness-html +
+

CRA readiness HTML package

+

Creates a deterministic CRA-readiness HTML package without legal compliance or certification conclusions.

+
+
Operation ID
craReadinessHTMLPackage
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
report:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: HTMLReportPackageEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/reports/cra-vulnerability-handling +
+

CRA vulnerability handling report

+

Returns a CRA-oriented vulnerability handling evidence report without legal compliance, certification, scanner-authority, or release-security conclusions.

+
+
Operation ID
craVulnerabilityHandlingReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
report:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: CRAVulnerabilityHandlingReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/reports/custody-review +
+

Signing custody review report

+

Returns tenant signing-provider and object-lock verification metadata for deployment custody review. It is evidence metadata only, not legal compliance proof, certification, HSM custody proof, or a secure-deployment guarantee.

+
+
Operation ID
signingCustodyReviewReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
keys:admin
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: SigningCustodyReviewReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/reports/incident-package +
+

Incident package report

+

Returns a deterministic incident package report with timeline, remediation tasks, linked evidence, assumptions, and limitations.

+
+
Operation ID
incidentReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
incident:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: IncidentReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/reports/missing-evidence +
+

Missing evidence report

+

Returns a deterministic missing-evidence report for a release with assumptions and limitations.

+
+
Operation ID
missingEvidenceReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
verify:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: MissingEvidenceReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/reports/pdf +
+

Create reproducible PDF report package

+

Creates a deterministic PDF report package record and payload metadata.

+
+
Operation ID
createPDFReportPackage
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
report:read
+
Idempotency
Idempotency-Key
+
Request
application/json: CreatePDFReportPackageRequest
+
Responses
201 application/json: PDFReportPackageEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/reports/release-readiness +
+

Release readiness report

+

Returns a deterministic release-readiness report with gaps, assumptions, and limitations.

+
+
Operation ID
releaseReadinessReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
verify:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: ReadinessReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/reports/retention +
+

Retention report

+

Returns a retention report for tenant-scoped holds and overrides with storage verification limitations.

+
+
Operation ID
retentionReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
admin
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: RetentionReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/reports/security-review-package +
+

Security review package report

+

Returns a redaction-aware security-review package report with assumptions and limitations.

+
+
Operation ID
securityReviewPackageReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
package:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: SecurityReviewPackageReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/reports/security-update-evidence +
+

Security update evidence report

+

Returns a security update evidence report for release-scoped fixed decisions, incidents, remediation tasks, and linked evidence without legal or security conclusions.

+
+
Operation ID
securityUpdateEvidenceReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
report:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: SecurityUpdateEvidenceReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/reports/vulnerability-decision-summary +
+

Customer-safe vulnerability decision summary

+

Returns customer-safe active vulnerability decision summaries for a release with assumptions and limitations. Raw payloads and internal notes are excluded.

+
+
Operation ID
vulnerabilityDecisionSummaryReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
report:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: VulnerabilityDecisionSummaryReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/reports/vulnerability-posture +
+

Vulnerability posture report

+

Returns a vulnerability posture report derived from stored scan, decision, VEX, exception, and workflow records.

+
+
Operation ID
vulnerabilityPostureReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
security:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: VulnerabilityPostureReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/retention-overrides +
+

Create retention override

+

Creates an append-only retention override for a tenant-scoped retention subject.

+
+
Operation ID
createRetentionOverride
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateRetentionOverrideRequest
+
Responses
201 application/json: RetentionOverrideEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/role-bindings +
+

List role bindings

+

Lists tenant-scoped role bindings visible to the identity administrator.

+
+
Operation ID
listRoleBindings
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
identity:admin
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: RoleBindingListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/role-bindings +
+

Create role binding

+

Creates a tenant-scoped role binding for a user or collector subject.

+
+
Operation ID
createRoleBinding
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
identity:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateRoleBindingRequest
+
Responses
201 application/json: RoleBindingEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/saas/profiles +
+

Create SaaS edition profile

+

Creates a SaaS edition profile record for future hosted deployment planning; it is not a production readiness claim.

+
+
Operation ID
createSaaSEditionProfile
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
instance:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateSaaSEditionProfileRequest
+
Responses
201 application/json: SaaSEditionProfileEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/sbom-components +
+

List SBOM components

+

Lists tenant-scoped SBOM components by SBOM, release, artifact, name/version/PURL query, or exact PURL.

+
+
Operation ID
listSBOMComponents
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: SBOMComponentRecordListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/sbom-diffs +
+

Create SBOM diff

+

Creates a deterministic SBOM diff between two tenant-scoped SBOM records.

+
+
Operation ID
createSBOMDiff
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateSBOMDiffRequest
+
Responses
201 application/json: SBOMDiffEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/sboms +
+

Upload CycloneDX SBOM

+

Uploads a CycloneDX SBOM payload, stores raw bytes in object storage, and records normalized SBOM metadata.

+
+
Operation ID
uploadSBOM
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:write
+
Idempotency
Idempotency-Key
+
Request
application/json: EvidenceUploadRequest
+
Responses
201 application/json: SBOMEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/sboms/spdx +
+

Upload SPDX SBOM

+

Uploads an SPDX JSON SBOM payload, stores raw bytes as evidence, and records normalized SBOM metadata.

+
+
Operation ID
uploadSPDXSBOM
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:write
+
Idempotency
Idempotency-Key
+
Request
application/json: UploadSPDXSBOMRequest
+
Responses
201 application/json: SBOMEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/sboms/{id} +
+

Get SBOM

+

Returns a tenant-scoped SBOM metadata record by id.

+
+
Operation ID
getSBOM
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: SBOMEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/security-documents +
+

Upload manual security document

+

Uploads sensitive manual security evidence such as threat model, security review, or penetration-test report metadata and raw payload reference.

+
+
Operation ID
uploadManualSecurityDocument
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
security:write
+
Idempotency
Idempotency-Key
+
Request
application/json: UploadManualSecurityDocumentRequest
+
Responses
201 application/json: ManualSecurityDocumentEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/security-scans +
+

Upload security scan

+

Uploads SAST, DAST, secret, license, or API security scan metadata and raw JSON payload evidence without exposing raw payload bytes in responses.

+
+
Operation ID
uploadSecurityScan
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
security:write
+
Idempotency
Idempotency-Key
+
Request
application/json: UploadSecurityScanRequest
+
Responses
201 application/json: SecurityScanEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/signing-keys +
+

List signing keys

+

Lists tenant signing public-key metadata without private key material.

+
+
Operation ID
listSigningKeys
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
verify:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: SigningKeyListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/signing-keys/rotate +
+

Rotate signing key

+

Rotates the active tenant signing key and returns public-key metadata only.

+
+
Operation ID
rotateSigningKey
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
keys:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: SigningKeyTransitionRequest
+
Responses
201 application/json: SigningKeyEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/signing-keys/{id}/revoke +
+

Revoke signing key

+

Revokes a tenant signing key as an audited lifecycle transition.

+
+
Operation ID
revokeSigningKey
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
keys:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: SigningKeyTransitionRequest
+
Responses
200 application/json: SigningKeyEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/signing-operations +
+

Create signing provider operation receipt

+

Records an external signing operation receipt and checks payload/signature metadata without logging secrets. When the API is configured with a signing executor, external_signature may be omitted and the executor signs the payload hash.

+
+
Operation ID
createSigningOperation
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
keys:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateSigningOperationRequest
+
Responses
201 application/json: SigningOperationEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/signing-providers +
+

Create signing provider record

+

Creates signing provider metadata for external signing operations. Production private key material must not be supplied.

+
+
Operation ID
createSigningProvider
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
keys:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateSigningProviderRequest
+
Responses
201 application/json: SigningProviderEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/source/branches +
+

Record source branch

+

Records or updates source branch metadata and protected-branch snapshot hash.

+
+
Operation ID
upsertSourceBranch
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
source:write
+
Idempotency
Idempotency-Key
+
Request
application/json: UpsertSourceBranchRequest
+
Responses
201 application/json: SourceBranchEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/source/commits +
+

Record source commit

+

Records immutable source commit metadata and stores only a hash of the commit message.

+
+
Operation ID
recordSourceCommit
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
source:write
+
Idempotency
Idempotency-Key
+
Request
application/json: RecordSourceCommitRequest
+
Responses
201 application/json: SourceCommitEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/source/pull-requests +
+

Record pull request

+

Records pull-request review metadata linked to source repository evidence.

+
+
Operation ID
recordPullRequest
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
source:write
+
Idempotency
Idempotency-Key
+
Request
application/json: RecordPullRequestRequest
+
Responses
201 application/json: PullRequestEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/source/repositories +
+

List source repositories

+

Lists tenant-scoped source repositories, optionally filtered by project.

+
+
Operation ID
listSourceRepositories
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
source:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: SourceRepositoryListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/source/repositories +
+

Create source repository

+

Creates a tenant-scoped source repository record.

+
+
Operation ID
createSourceRepository
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
source:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateSourceRepositoryRequest
+
Responses
201 application/json: SourceRepositoryEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/sso/identity-links +
+

Link SSO identity

+

Links a verified provider subject to a tenant-scoped human user.

+
+
Operation ID
linkSSOIdentity
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
identity:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: LinkSSOIdentityRequest
+
Responses
201 application/json: UserIdentityLinkEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/sso/logout +
+

Logout SSO session

+

Revokes the currently authenticated SSO session without requiring identity administrator privileges. API keys and collector keys cannot use this route.

+
+
Operation ID
logoutSSOSession
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
none
+
Idempotency
Idempotency-Key
+
Request
application/json: EmptyObject
+
Responses
200 application/json: SSOSessionEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/sso/providers +
+

Create SSO provider

+

Records tenant SSO provider metadata. Optional static JWKS public keys and SAML signing certificates can be supplied for local token/assertion verification without live provider calls.

+
+
Operation ID
createSSOProvider
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
identity:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateSSOProviderRequest
+
Responses
201 application/json: SSOProviderEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/sso/providers/{id}/discover-oidc +
+

Refresh SSO provider OIDC trust material

+

Fetches the OIDC discovery document and public JWKS for the tenant provider issuer, then stores refreshed public trust material. This does not authenticate users, store provider secrets, or synchronize groups.

+
+
Operation ID
refreshSSOProviderOIDCTrustMaterial
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
identity:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: EmptyObject
+
Responses
200 application/json: SSOProviderEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/sso/providers/{id}/trust-material +
+

Update SSO provider trust material

+

Rotates tenant SSO provider public trust material for local OIDC ID-token or SAML assertion verification without storing provider secrets.

+
+
Operation ID
updateSSOProviderTrustMaterial
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
identity:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: UpdateSSOProviderTrustMaterialRequest
+
Responses
200 application/json: SSOProviderEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/sso/session-exchanges +
+

Exchange SSO credential

+

Exchanges a locally verified OIDC ID token or SAML assertion for an SSO session and HttpOnly browser cookie using configured tenant trust material and verified identity links. No live provider API or group synchronization call is made.

+
+
Operation ID
exchangeSSOCredential
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
none
+
Idempotency
not required
+
Request
application/json: ExchangeSSOCredentialRequest
+
Responses
201 application/json: SSOCredentialExchangeEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/sso/sessions +
+

Create SSO session

+

Creates an admin-managed human SSO session record and returns a one-time bearer secret.

+
+
Operation ID
createSSOSession
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
identity:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateSSOSessionRequest
+
Responses
201 application/json: SSOSessionCreateEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/sso/sessions/{id}/revoke +
+

Revoke SSO session

+

Revokes a tenant-scoped SSO session as an audited lifecycle transition.

+
+
Operation ID
revokeSSOSession
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
identity:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: EmptyObject
+
Responses
200 application/json: SSOSessionEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/transparency-checkpoints +
+

Record external transparency checkpoint

+

Records an external transparency or timestamp checkpoint reference for a Merkle batch.

+
+
Operation ID
createTransparencyCheckpoint
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
keys:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateTransparencyCheckpointRequest
+
Responses
201 application/json: TransparencyCheckpointEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/users +
+

Create user

+

Creates a tenant-scoped human user metadata record. Authentication is still controlled by API keys or configured SSO/session flows.

+
+
Operation ID
createUser
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
identity:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateUserRequest
+
Responses
201 application/json: HumanUserEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/users/{id}/deactivate +
+

Deactivate user

+

Deactivates a tenant-scoped human user as an audited lifecycle transition.

+
+
Operation ID
deactivateUser
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
identity:admin
+
Idempotency
Idempotency-Key
+
Request
application/json: EmptyObject
+
Responses
200 application/json: HumanUserEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/verify +
+

Verify subject

+

Verifies a supported tenant-scoped subject such as evidence, audit chain, release bundle, artifact signature, or related verification target.

+
+
Operation ID
verify
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
verify:read
+
Idempotency
Idempotency-Key
+
Request
application/json: VerifySubjectRequest
+
Responses
200 application/json: VerificationResultEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/version +
+

Version

+

Returns the API process version string.

+
+
Operation ID
version
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
none
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: VersionInfoEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/vex +
+

Upload OpenVEX document

+

Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.

+
+
Operation ID
uploadVEX
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:write
+
Idempotency
Idempotency-Key
+
Request
application/json: EvidenceUploadRequest
+
Responses
201 application/json: VEXDocumentEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/vex/cyclonedx +
+

Upload CycloneDX VEX document

+

Uploads VEX payload bytes, stores raw evidence in object storage, and records normalized VEX metadata and decisions where applicable.

+
+
Operation ID
uploadCycloneDXVEX
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:write
+
Idempotency
Idempotency-Key
+
Request
application/json: EvidenceUploadRequest
+
Responses
201 application/json: VEXDocumentEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/vex/cyclonedx/preview +
+

Preview CycloneDX VEX import

+

Validates a CycloneDX VEX payload and returns advisory mapping counts without storing raw payloads, creating evidence, creating decisions, or enqueueing parser jobs.

+
+
Operation ID
previewCycloneDXVEXImport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
application/json: EvidenceUploadRequest
+
Responses
200 application/json: VEXImportPreviewEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/vex/preview +
+

Preview OpenVEX import

+

Validates an OpenVEX payload and returns advisory mapping counts without storing raw payloads, creating evidence, creating decisions, or enqueueing parser jobs.

+
+
Operation ID
previewVEXImport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
application/json: EvidenceUploadRequest
+
Responses
200 application/json: VEXImportPreviewEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/vex/{id} +
+

Get VEX document

+

Returns a tenant-scoped VEX document metadata record by id.

+
+
Operation ID
getVEX
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: VEXDocumentEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/vex/{id}/import-report +
+

Get VEX import report

+

Returns the persisted parser report for a tenant-scoped VEX import, including counts, warnings, and mapping failures without raw payload bytes.

+
+
Operation ID
getVEXImportReport
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: VEXImportReportEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/vulnerability-decisions +
+

List vulnerability decisions

+

Lists append-only vulnerability decisions over time with tenant-scoped product, release, vulnerability, component, status, and active filters.

+
+
Operation ID
listVulnerabilityDecisions
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: VulnerabilityDecisionListEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/vulnerability-findings/{id}/decisions +
+

Create vulnerability decision

+

Creates an append-only vulnerability decision for a tenant-scoped scan finding.

+
+
Operation ID
createVulnerabilityDecision
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateVulnerabilityDecisionRequest
+
Responses
201 application/json: VulnerabilityDecisionEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/vulnerability-findings/{id}/workflow +
+

Record vulnerability workflow event

+

Records an append-only vulnerability workflow event for a tenant-scoped finding.

+
+
Operation ID
recordVulnerabilityWorkflow
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
security:write
+
Idempotency
Idempotency-Key
+
Request
application/json: RecordVulnerabilityWorkflowRequest
+
Responses
201 application/json: VulnerabilityWorkflowRecordEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/vulnerability-scans +
+

Upload vulnerability scan

+

Uploads a generic vulnerability scan JSON payload and records normalized findings.

+
+
Operation ID
uploadVulnerabilityScan
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:write
+
Idempotency
Idempotency-Key
+
Request
application/json: UploadVulnerabilityScanRequest
+
Responses
201 application/json: VulnerabilityScanEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ GET + /v1/vulnerability-scans/{id} +
+

Get vulnerability scan

+

Returns a tenant-scoped vulnerability scan by id.

+
+
Operation ID
getVulnerabilityScan
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
evidence:read
+
Idempotency
not required
+
Request
none
+
Responses
200 application/json: VulnerabilityScanEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/waivers +
+

Create waiver

+

Creates a first-class scoped waiver for controls or policies. Approval is a separate audited transition.

+
+
Operation ID
createWaiver
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
policy:write
+
Idempotency
Idempotency-Key
+
Request
application/json: CreateWaiverRequest
+
Responses
201 application/json: WaiverEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ POST + /v1/waivers/{id}/approve +
+

Approve waiver

+

Approves an unexpired waiver as an audited transition.

+
+
Operation ID
approveWaiver
+
Tags
evydence
+
Auth
BearerAuth
+
Scopes
policy:write
+
Idempotency
Idempotency-Key
+
Request
application/json: EmptyObject
+
Responses
200 application/json: WaiverEnvelope; 400 application/problem+json: Problem; 401 application/problem+json: Problem; 403 application/problem+json: Problem; 404 application/problem+json: Problem; 409 application/problem+json: Problem; 422 application/problem+json: Problem
+
+
+
+
+ +
+

Schemas

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameShapeRequired fields
APIKeyobjectid, tenant_id, name, prefix, scopes, created_at
APIKeyCreateEnvelopeobjectdata, meta
APIKeyCreateResponseobjectapi_key, secret
APIKeyListEnvelopeobjectdata, meta
AnomalyReportobjectid, tenant_id, subject_type, subject_id, result, assumptions, limitations, schema_version, created_at
AnomalyReportEnvelopeobjectdata, meta
AnomalySignalobjectname, severity, detail
ApprovalRecordobjectid, tenant_id, subject_type, subject_id, decision, reason, approver_id, schema_version, created_at
ApprovalRecordEnvelopeobjectdata, meta
Artifactobjectid, tenant_id, name, digest, schema_version, created_at
ArtifactEnvelopeobjectdata, meta
ArtifactSignatureobjectid, tenant_id, artifact_id, subject_digest, algorithm, signature, verification_status, schema_version, created_at
ArtifactSignatureEnvelopeobjectdata, meta
AuditChainEntryobjectid, tenant_id, sequence, entry_type, subject_type, subject_id, actor_type, actor_id, occurred_at, canonical_entry_hash, previous_entry_hash, entry_hash, schema_version
AuditChainEntryListEnvelopeobjectdata, meta
BackupManifestobjectid, tenant_id, state_hash, resource_counts, consistency_checks, limitations, schema_version, created_at
BackupManifestEnvelopeobjectdata, meta
BuildAttestationobjectid, tenant_id, build_id, evidence_id, payload_hash, payload_size, payload_type, predicate_type, subject_digests, signature_count, verification_status, schema_version, created_at
BuildAttestationEnvelopeobjectdata, meta
BuildRunobjectid, tenant_id, project_id, release_id, provider, commit_sha, status, schema_version, created_at
BuildRunEnvelopeobjectdata, meta
CRAVulnerabilityHandlingReportobjectreport_type, template_version, product_id, release_id, summary, assumptions, limitations, generated_at
CRAVulnerabilityHandlingReportEnvelopeobjectdata, meta
Collectorobjectid, tenant_id, name, type, version, api_key_id, status, allowed_scopes, schema_version, created_at
CollectorCreateEnvelopeobjectdata, meta
CollectorCreateResponseobjectcollector, api_key, secret
CollectorHealthReportobjectreport_type, collector_id, collector_status, supply_chain_status, checks, assumptions, limitations, generated_at
CollectorHealthReportEnvelopeobjectdata, meta
CollectorListEnvelopeobjectdata, meta
CollectorReleaseobjectid, tenant_id, collector_id, version, artifact_digest, pinned, verification_status, health_status, schema_version, created_at
CollectorReleaseEnvelopeobjectdata, meta
CommercialCollectorDefinitionobjectid, tenant_id, name, provider, version, manifest_hash, allowed_scopes, status, schema_version, created_at
CommercialCollectorDefinitionEnvelopeobjectdata, meta
CommercialCollectorDefinitionListEnvelopeobjectdata, meta
ContainerImageobjectid, tenant_id, repository, digest, schema_version, created_at
ContainerImageEnvelopeobjectdata, meta
ContractDiffobjectid, tenant_id, base_contract_id, target_contract_id, product_id, result, schema_version, created_at
ContractDiffEnvelopeobjectdata, meta
ControlEvidenceobjectid, tenant_id, control_id, evidence_type, subject_type, subject_id, confidence, schema_version, created_at
ControlEvidenceEnvelopeobjectdata, meta
ControlEvidenceListEnvelopeobjectdata, meta
ControlEvidenceRequirementobjecttype, required
ControlFrameworkobjectid, tenant_id, name, slug, version, status, schema_version, created_at
ControlFrameworkEnvelopeobjectdata, meta
ControlFrameworkListEnvelopeobjectdata, meta
ControlFrameworkTemplatePackobjectid, name, slug, version, controls, schema_version
ControlFrameworkTemplatePackListEnvelopeobjectdata, meta
CosignVerificationobjectid, tenant_id, artifact_signature_id, subject_digest, result, checks, schema_version, created_at
CosignVerificationEnvelopeobjectdata, meta
CreateAPIKeyRequestobjectname, scopes
CreateAnomalyReportRequestobjectsubject_type, subject_id
CreateApprovalRequestobjectsubject_type, subject_id, decision, reason
CreateArtifactSignatureRequestobjectartifact_id, algorithm, signature
CreateBuildRequestobjectproject_id, release_id, provider, commit_sha, status, started_at
CreateCollectorRequestobjectname, type, version
CreateCommercialCollectorRequestobjectname, provider, version, manifest_hash
CreateControlFrameworkRequestobjectname, version
CreateCustomPolicyRequestobjectname, version, rules
CreateCustomerPackageRequestobjectproduct_id, redaction_profile_id, title, expires_at
CreateCustomerPortalAccessRequestobjectpackage_id, customer_name, expires_at
CreateDSSETrustRootRequestobjectname, key_id, algorithm, public_key
CreateDeploymentEnvironmentRequestobjectproduct_id, name, kind
CreateEvidenceRequestobjecttype, title, payload_hash
CreateEvidenceSummaryRequestobjectsubject_type, subject_id, evidence_ids
CreateExceptionRequestobjectrelease_id, reason, owner, expires_at
CreateGraphSnapshotRequestobjectnone
CreateIncidentRequestobjectproduct_id, title, severity
CreateIncidentWebhookReceiverRequestobjectname, provider, public_key
CreateLegalHoldRequestobjectscope_type, scope_id, reason, owner
CreateMarketplaceCollectorRequestobjectname, provider, version, publisher, manifest_hash
CreateMerkleBatchRequestobjectnone
CreateObjectRetentionPolicyRequestobjectname, mode, retention_days
CreateOpenAPIDiffRequestobjectbase_contract_id, target_contract_id, release_id
CreateOrganizationRequestobjectname, slug
CreatePDFReportPackageRequestobjectreport_type, title
CreateProductRequestobjectname, slug
CreateProjectRequestobjectproduct_id, name, slug
CreatePublicTransparencyLogRequestobjectname, endpoint, public_key
CreateQuestionnaireAnswerLibraryEntryRequestobjectanswer
CreateQuestionnaireDraftRequestobjecttemplate_id
CreateQuestionnairePackageRequestobjecttemplate_id
CreateQuestionnaireTemplateRequestobjectname, version, questions
CreateRedactionProfileRequestobjectnone
CreateReleaseBundleRequestobjectrelease_id
CreateReleaseCandidateRequestobjectrelease_id, name
CreateReleaseRequestobjectproduct_id, version
CreateRemediationTaskRequestobjecttitle, owner
CreateReportTemplateRequestobjectname, version, report_type, allowed_fields, template
CreateRetentionOverrideRequestobjectscope_type, scope_id, retention_until, reason, owner
CreateRoleBindingRequestobjectsubject_type, subject_id, role
CreateSBOMDiffRequestobjectbase_sbom_id, target_sbom_id
CreateSSOProviderRequestobjectname, type, issuer, client_id
CreateSSOSessionRequestobjectuser_id, provider_id, expires_at
CreateSaaSEditionProfileRequestobjectname, region, admin_tenant_id, isolation_model
CreateSecurityControlRequestobjectframework_id, code, title, objective
CreateSigningOperationRequestobjectprovider_id, subject_type, subject_id, payload_hash
CreateSigningProviderRequestobjectname, type, key_ref
CreateSourceRepositoryRequestobjectprovider, full_name
CreateTransparencyCheckpointRequestobjectbatch_id, provider
CreateUserRequestobjectemail, display_name
CreateVulnerabilityDecisionRequestobjectstatus, justification
CreateWaiverRequestobjectscope_type, scope_id, owner, risk, reason, expires_at
CustomPolicyobjectid, tenant_id, name, version, rules, schema_version, created_at
CustomPolicyEnvelopeobjectdata, meta
CustomPolicyEvaluationobjectid, tenant_id, policy_id, release_id, result, checks, input_hash, schema_version, created_at
CustomPolicyEvaluationEnvelopeobjectdata, meta
CustomReportTemplateobjectid, tenant_id, name, version, report_type, allowed_fields, template, schema_version, created_at
CustomReportTemplateEnvelopeobjectdata, meta
CustomerPortalAccessobjectid, tenant_id, package_id, customer_name, prefix, expires_at, access_count, failed_access_count, schema_version, created_at
CustomerPortalAccessCreateEnvelopeobjectdata, meta
CustomerPortalAccessCreateResponseobjectaccess, secret
CustomerPortalAccessEnvelopeobjectdata, meta
CustomerPortalAccessListEnvelopeobjectdata, meta
CustomerPortalPackageRequestobjecttoken
CustomerSecurityPackageobjectid, tenant_id, product_id, redaction_profile_id, title, state, manifest, manifest_hash, expires_at, access_count, schema_version, created_at
CustomerSecurityPackageEnvelopeobjectdata, meta
DSSEEnvelopeobjectpayloadType, payload, signatures
DSSETrustRootobjectid, tenant_id, name, key_id, algorithm, public_key, status, schema_version, created_at
DSSETrustRootEnvelopeobjectdata, meta
DataEnvelopeobjectdata, meta
DependencyChangeobjectid, tenant_id, sbom_diff_id, change_type, component, schema_version, created_at
DeploymentEnvironmentobjectid, tenant_id, product_id, name, kind, schema_version, created_at
DeploymentEnvironmentEnvelopeobjectdata, meta
DeploymentEnvironmentListEnvelopeobjectdata, meta
DeploymentEventobjectid, tenant_id, environment_id, release_id, status, started_at, schema_version, created_at
DeploymentEventEnvelopeobjectdata, meta
DeploymentEventListEnvelopeobjectdata, meta
EmptyObjectobjectnone
EvaluatePolicyRequestobjectrelease_id
EvidenceBundleobjectid, tenant_id, evidence_ids, manifest, manifest_hash, verification_text, schema_version, created_at
EvidenceBundleEnvelopeobjectdata, meta
EvidenceBundleImportobjectid, tenant_id, bundle_hash, result, imported_count, schema_version, created_at
EvidenceBundleImportEnvelopeobjectdata, meta
EvidenceCitationobjectevidence_id, type, title, canonical_hash
EvidenceGraphEdgeobjectfrom, to, relationship
EvidenceGraphNodeobjectid, type, label
EvidenceGraphSnapshotobjectid, tenant_id, nodes, edges, graph_hash, limitations, schema_version, created_at
EvidenceGraphSnapshotEnvelopeobjectdata, meta
EvidenceItemobjectid, tenant_id, type, title, source_system, observed_at, evidence_version, schema_version, payload_hash, canonical_hash, canonicalization, trust_level, verification_status, chain_entry_id, created_at
EvidenceItemEnvelopeobjectdata, meta
EvidenceItemListEnvelopeobjectdata, meta
EvidenceLifecycleEventobjectid, tenant_id, evidence_id, action, reason, actor_id, schema_version, created_at
EvidenceLifecycleEventEnvelopeobjectdata, meta
EvidenceLifecycleEventListEnvelopeobjectdata, meta
EvidenceNoticeobjectcode, message
EvidenceRefobjecttype, id
EvidenceSearchEnvelopeobjectdata, meta
EvidenceSearchResponseobjectitems
EvidenceSummaryobjectid, tenant_id, subject_type, subject_id, evidence_ids, summary, citations, assumptions, limitations, schema_version, created_at
EvidenceSummaryEnvelopeobjectdata, meta
EvidenceUploadRequestobjectrelease_id, payload
Exceptionobjectid, tenant_id, release_id, reason, owner, expires_at, approved, created_at
ExceptionEnvelopeobjectdata, meta
ExceptionListEnvelopeobjectdata, meta
ExchangeSSOCredentialRequestobjectprovider_id, subject
ExportEvidenceBundleRequestobjectnone
HTMLReportPackageobjectid, tenant_id, report_type, product_id, html, hash, schema_version, created_at
HTMLReportPackageEnvelopeobjectdata, meta
HealthStatusobjectstatus
HealthStatusEnvelopeobjectdata, meta
HumanUserobjectid, tenant_id, email, display_name, status, schema_version, created_at
HumanUserEnvelopeobjectdata, meta
Incidentobjectid, tenant_id, product_id, title, severity, status, opened_at, schema_version, created_at
IncidentEnvelopeobjectdata, meta
IncidentReportobjectreport_type, template_version, incident_id, result, timeline, tasks, assumptions, limitations, generated_at
IncidentReportEnvelopeobjectdata, meta
IncidentTimelineEventobjectid, tenant_id, incident_id, event_type, summary, occurred_at, schema_version, created_at
IncidentTimelineEventEnvelopeobjectdata, meta
IncidentWebhookDeliveryobjectwebhook_event, timeline_event
IncidentWebhookDeliveryEnvelopeobjectdata, meta
IncidentWebhookEventobjectid, tenant_id, receiver_id, incident_id, provider, event_id, payload_hash, signature_hash, result, schema_version, created_at
IncidentWebhookReceiverobjectid, tenant_id, incident_id, name, provider, public_key, status, schema_version, created_at
IncidentWebhookReceiverEnvelopeobjectdata, meta
InstanceAdminSnapshotobjectreport_type, tenant_count, resource_counts, limitations, generated_at
InstanceAdminSnapshotEnvelopeobjectdata, meta
LegalHoldobjectid, tenant_id, scope_type, scope_id, reason, owner, schema_version, created_at
LegalHoldEnvelopeobjectdata, meta
LinkControlEvidenceRequestobjectevidence_type, subject_type, subject_id, confidence
LinkEvidenceRequestobjecttarget_type, target_id
LinkSSOIdentityRequestobjectuser_id, provider_id, subject, email, verified
ManualSecurityDocumentobjectid, tenant_id, document_type, title, sensitivity, evidence_id, payload_hash, schema_version, created_at
ManualSecurityDocumentEnvelopeobjectdata, meta
MarketplaceCollectorobjectid, tenant_id, name, provider, version, publisher, manifest_hash, state, schema_version, created_at
MarketplaceCollectorEnvelopeobjectdata, meta
MarketplaceCollectorHealthReportobjectreport_type, collector_id, name, provider, version, supply_chain_status, checks, collector, assumptions, limitations, generated_at
MarketplaceCollectorHealthReportEnvelopeobjectdata, meta
MarketplaceCollectorListEnvelopeobjectdata, meta
MerkleBatchobjectid, tenant_id, from_sequence, to_sequence, entry_count, leaf_hashes, root_hash, schema_version, created_at
MerkleBatchEnvelopeobjectdata, meta
MetricsSnapshotobjecttenant_id, resource_counts, customer_portal_failed_access_count, customer_portal_revoked_access_count
MetricsSnapshotEnvelopeobjectdata, meta
MissingEvidenceReportobjectreport_type, template_version, release_id, result, missing, assumptions, limitations
MissingEvidenceReportEnvelopeobjectdata, meta
ObjectRetentionPolicyobjectid, tenant_id, name, object_prefix, mode, retention_days, status, schema_version, created_at
ObjectRetentionPolicyEnvelopeobjectdata, meta
OpenAPIContractobjectid, tenant_id, product_id, version, hash, path_count, evidence_id, created_at
OpenAPIContractEnvelopeobjectdata, meta
OpenAPIDocumentobjectopenapi, info, paths
OpenAPIOperationRecordobjectpath, method
Organizationobjectid, tenant_id, name, slug, status, schema_version, created_at
OrganizationEnvelopeobjectdata, meta
PDFReportPackageobjectid, tenant_id, report_type, title, payload_hash, payload_size, limitations, schema_version, created_at
PDFReportPackageEnvelopeobjectdata, meta
PolicyCheckobjectname, result, severity, explanation
PolicyEvaluationobjectid, tenant_id, release_id, result, policy_set, checks, created_at
PolicyEvaluationEnvelopeobjectdata, meta
PolicyRuleobjectname, severity, required
Problemobjectnone
Productobjectid, tenant_id, name, slug, schema_version, created_at
ProductEnvelopeobjectdata, meta
ProductListEnvelopeobjectdata, meta
Projectobjectid, tenant_id, product_id, name, slug, schema_version, created_at
ProjectEnvelopeobjectdata, meta
ProviderVerificationobjectid, tenant_id, provider_type, provider_id, subject, result, checks, limitations, schema_version, created_at
ProviderVerificationEnvelopeobjectdata, meta
PublicTransparencyLogobjectid, tenant_id, name, endpoint, public_key, state, schema_version, created_at
PublicTransparencyLogEntryobjectid, tenant_id, log_id, checkpoint_id, merkle_batch_id, external_id, entry_hash, state, schema_version, created_at
PublicTransparencyLogEntryEnvelopeobjectdata, meta
PublicTransparencyLogEnvelopeobjectdata, meta
PublishPublicTransparencyLogEntryRequestobjectlog_id, checkpoint_id, external_id
PullRequestobjectid, tenant_id, repository_id, provider, provider_id, state, schema_version, created_at
PullRequestEnvelopeobjectdata, meta
QuestionnaireAnswerLibraryEntryobjectid, tenant_id, answer, schema_version, created_at
QuestionnaireAnswerLibraryEntryEnvelopeobjectdata, meta
QuestionnaireAnswerLibraryEntryListEnvelopeobjectdata, meta
QuestionnaireDraftobjectid, tenant_id, template_id, responses, manifest_hash, limitations, schema_version, created_at
QuestionnaireDraftEnvelopeobjectdata, meta
QuestionnairePackageobjectid, tenant_id, template_id, responses, manifest_hash, schema_version, created_at
QuestionnairePackageEnvelopeobjectdata, meta
QuestionnaireQuestionobjectid, prompt
QuestionnaireResponseobjectquestion_id, answer
QuestionnaireTemplateobjectid, tenant_id, name, version, questions, schema_version, created_at
QuestionnaireTemplateEnvelopeobjectdata, meta
ReadinessReportobjectreport_type, template_version, result, assumptions, limitations, generated_at
ReadinessReportEnvelopeobjectdata, meta
ReadinessStatusobjectstatus, checks
ReadinessStatusEnvelopeobjectdata, meta
RecordCollectorReleaseRequestobjectversion, artifact_digest
RecordDeploymentRequestobjectenvironment_id, release_id, status, started_at
RecordEvidenceLifecycleEventRequestobjectaction, reason
RecordIncidentTimelineRequestobjectevent_type, summary
RecordPullRequestRequestobjectrepository_id, provider, provider_id, title, state
RecordSourceCommitRequestobjectrepository_id, sha, committed_at
RecordVulnerabilityWorkflowRequestobjectaction, reason
RedactionProfileobjectid, tenant_id, name, schema_version, created_at
RedactionProfileEnvelopeobjectdata, meta
RegisterArtifactRequestobjectname, digest
RegisterContainerImageRequestobjectrepository, digest
Releaseobjectid, tenant_id, product_id, version, status, schema_version, created_at
ReleaseBundleobjectid, tenant_id, release_id, state, manifest, manifest_hash, signature_refs, created_at
ReleaseBundleEnvelopeobjectdata, meta
ReleaseBundleManifestobjectmanifest_version, bundle_id, tenant_id, release, evidence_ids, chain_checkpoint, generated_at, generator
ReleaseBundleManifestEnvelopeobjectdata, meta
ReleaseBundleVerificationobjectresult
ReleaseBundleVerificationEnvelopeobjectdata, meta
ReleaseCandidateobjectid, tenant_id, release_id, name, state, snapshot_hash, schema_version, created_at
ReleaseCandidateEnvelopeobjectdata, meta
ReleaseCandidateListEnvelopeobjectdata, meta
ReleaseCandidateTransitionRequestobjectnone
ReleaseEnvelopeobjectdata, meta
ReleaseEvidenceFlowobjectrelease_id, product_id, status, counts, steps, assumptions, limitations, schema_version, generated_at
ReleaseEvidenceFlowEnvelopeobjectdata, meta
ReleaseEvidenceFlowStepobjectid, title, status, required, method, path, required_scopes, idempotency_required, description
ReleaseSecurityApprovalSummaryobjecttotal, approved
ReleaseSecurityExceptionSummaryobjecttotal, approved_unexpired, unapproved, expired
ReleaseSecurityMissingDecisionobjectfinding_id, scan_id, vulnerability, severity, state
ReleaseSecurityProductSummaryobjectid, name, slug
ReleaseSecurityReleaseSummaryobjectid, version, state
ReleaseSecuritySummaryobjectproduct, release, artifact_count, sbom_status, vulnerability_scan_status, open_findings_by_severity, decisions_by_status, approval_summary, exception_summary, readiness_status, package_status, counts, assumptions, limitations, schema_version, generated_at
ReleaseSecuritySummaryEnvelopeobjectdata, meta
RemediationTaskobjectid, tenant_id, title, owner, status, schema_version, created_at
RemediationTaskEnvelopeobjectdata, meta
RenderReportTemplateRequestobjectsubject_type, subject_id
RenderedCustomReportobjectid, tenant_id, template_id, subject_type, subject_id, output, hash, schema_version, created_at
RenderedCustomReportEnvelopeobjectdata, meta
RetentionOverrideobjectid, tenant_id, scope_type, scope_id, retention_until, reason, owner, schema_version, created_at
RetentionOverrideEnvelopeobjectdata, meta
RetentionReportobjectreport_type, legal_holds, retention_overrides, limitations, generated_at
RetentionReportEnvelopeobjectdata, meta
RoleBindingobjectid, tenant_id, subject_type, subject_id, role, schema_version, created_at
RoleBindingEnvelopeobjectdata, meta
RoleBindingListEnvelopeobjectdata, meta
SBOMobjectid, tenant_id, evidence_id, release_id, format, component_count, created_at
SBOMComponentobjectname
SBOMComponentRecordobjectsbom_id, component
SBOMComponentRecordListEnvelopeobjectdata, meta
SBOMDiffobjectid, tenant_id, base_sbom_id, target_sbom_id, unchanged_count, schema_version, created_at
SBOMDiffEnvelopeobjectdata, meta
SBOMEnvelopeobjectdata, meta
SSOCredentialExchangeEnvelopeobjectdata, meta
SSOCredentialExchangeResponseobjectverification, session, secret
SSOProviderobjectid, tenant_id, name, type, issuer, client_id, status, schema_version, created_at
SSOProviderEnvelopeobjectdata, meta
SSOSessionobjectid, tenant_id, user_id, provider_id, prefix, expires_at, schema_version, created_at
SSOSessionCreateEnvelopeobjectdata, meta
SSOSessionCreateResponseobjectsession, secret
SSOSessionEnvelopeobjectdata, meta
SaaSEditionProfileobjectid, tenant_id, name, region, admin_tenant_id, isolation_model, status, config_hash, limitations, schema_version, created_at
SaaSEditionProfileEnvelopeobjectdata, meta
SecurityControlobjectid, tenant_id, framework_id, code, title, objective, schema_version, created_at
SecurityControlEnvelopeobjectdata, meta
SecurityReviewPackageReportobjectreport_type, template_version, package_id, product_id, evidence_ids, assumptions, limitations, generated_at
SecurityReviewPackageReportEnvelopeobjectdata, meta
SecurityScanobjectid, tenant_id, category, format, scanner, target_ref, evidence_id, payload_hash, finding_count, redacted, quarantined, schema_version, created_at
SecurityScanEnvelopeobjectdata, meta
SecurityUpdateEvidenceReportobjectreport_type, template_version, product_id, release_id, summary, assumptions, limitations, generated_at
SecurityUpdateEvidenceReportEnvelopeobjectdata, meta
SignedIncidentWebhookPayloadobjectevent_type, summary
SigningCustodyReviewReportobjectreport_type, tenant_id, checks, assumptions, limitations, generated_at
SigningCustodyReviewReportEnvelopeobjectdata, meta
SigningKeyobjectid, tenant_id, kid, algorithm, status, public_key, created_at
SigningKeyEnvelopeobjectdata, meta
SigningKeyListEnvelopeobjectdata, meta
SigningKeyTransitionRequestobjectnone
SigningOperationobjectid, tenant_id, provider_id, subject_type, subject_id, payload_hash, result, checks, schema_version, created_at
SigningOperationEnvelopeobjectdata, meta
SigningProviderobjectid, tenant_id, name, type, status, key_ref, encrypted, schema_version, created_at
SigningProviderEnvelopeobjectdata, meta
SourceBranchobjectid, tenant_id, repository_id, name, protected, schema_version, created_at
SourceBranchEnvelopeobjectdata, meta
SourceCommitobjectid, tenant_id, repository_id, sha, schema_version, created_at
SourceCommitEnvelopeobjectdata, meta
SourceRepositoryobjectid, tenant_id, provider, full_name, schema_version, created_at
SourceRepositoryEnvelopeobjectdata, meta
SourceRepositoryListEnvelopeobjectdata, meta
SourceSnapshotBranchInputobjectname
SourceSnapshotCommitInputobjectsha, committed_at
SourceSnapshotEnvelopeobjectdata, meta
SourceSnapshotPullRequestInputobjectprovider_id, state
SourceSnapshotRepositoryInputobjectfull_name
SourceSnapshotRequestobjectrepository
SourceSnapshotResultobjectrepository
SubjectRefobjecttype
SupersedeEvidenceRequestobjectreplacement_evidence_id, reason
TransparencyCheckpointobjectid, tenant_id, batch_id, provider, timestamp_hash, state, schema_version, created_at
TransparencyCheckpointEnvelopeobjectdata, meta
UpdateSSOProviderTrustMaterialRequestobjectnone
UploadManualSecurityDocumentRequestobjectdocument_type, title, sensitivity, payload
UploadOpenAPIContractRequestobjectproduct_id, release_id, version, spec
UploadSPDXSBOMRequestobjectrelease_id, payload
UploadSecurityScanRequestobjectcategory, format, scanner, target_ref, payload
UploadVulnerabilityScanRequestobjectscanner, target_ref, release_id, findings
UpsertSourceBranchRequestobjectrepository_id, name
UserIdentityLinkobjectid, tenant_id, user_id, provider_id, subject, email, verified, schema_version, created_at
UserIdentityLinkEnvelopeobjectdata, meta
VEXDocumentobjectid, tenant_id, evidence_id, release_id, format, statement_count, schema_version, created_at
VEXDocumentEnvelopeobjectdata, meta
VEXImportIssueobjectcode, detail
VEXImportPreviewobjecttenant_id, release_id, format, parser_version, advisory, statement_count, status_summary, decisions_would_create, decisions_would_supersede, assumptions, limitations, schema_version, generated_at
VEXImportPreviewEnvelopeobjectdata, meta
VEXImportReportobjectid, tenant_id, vex_document_id, evidence_id, parser_version, status, statement_count, decisions_created, decisions_superseded, schema_version, created_at, updated_at
VEXImportReportEnvelopeobjectdata, meta
VerificationResultobjectid, tenant_id, subject_type, subject_id, result, checks, verified_at
VerificationResultEnvelopeobjectdata, meta
VerifyCheckobjectname, result
VerifyCosignSignatureRequestobjectnone
VerifyProviderIdentityRequestobjectprovider_type, provider_id, subject
VerifyPublicTransparencyLogEntryRequestobjectroot_hash, leaf_index, tree_size, inclusion_proof
VerifySubjectRequestobjectsubject_type
VersionInfoobjectversion
VersionInfoEnvelopeobjectdata, meta
VulnerabilityDecisionobjectid, tenant_id, finding_id, scan_id, vulnerability, status, justification, source, schema_version, created_at
VulnerabilityDecisionCustomerSummaryobjectid, finding_id, scan_id, release_id, vulnerability, status, impact_statement, source, created_at
VulnerabilityDecisionEnvelopeobjectdata, meta
VulnerabilityDecisionListEnvelopeobjectdata, meta
VulnerabilityDecisionSummaryReportobjectreport_type, template_version, product_id, release_id, decisions, assumptions, limitations, generated_at
VulnerabilityDecisionSummaryReportEnvelopeobjectdata, meta
VulnerabilityPostureReportobjectreport_type, template_version, summary, open_critical, assumptions, limitations, generated_at
VulnerabilityPostureReportEnvelopeobjectdata, meta
VulnerabilityScanobjectid, tenant_id, release_id, scanner, target_ref, summary, findings, created_at
VulnerabilityScanEnvelopeobjectdata, meta
VulnerabilityWorkflowRecordobjectid, tenant_id, finding_id, action, reason, actor_id, schema_version, created_at
VulnerabilityWorkflowRecordEnvelopeobjectdata, meta
Waiverobjectid, tenant_id, scope_type, scope_id, owner, risk, reason, expires_at, approved, schema_version, created_at
WaiverEnvelopeobjectdata, meta
+
+
+
+ + + diff --git a/site/marketing/scripts/check.mjs b/site/marketing/scripts/check.mjs index d6affb5..288412b 100644 --- a/site/marketing/scripts/check.mjs +++ b/site/marketing/scripts/check.mjs @@ -30,6 +30,7 @@ const requiredFiles = [ "fi/yhteys/index.html", "en/privacy-cookies/index.html", "fi/yksityisyys-evasteet/index.html", + "api/index.html", "docs/index.html", "github/index.html" ]; @@ -75,6 +76,8 @@ const requiredEnglish = [ "One release, one SBOM finding, one decision, one package verifier.", "https://www.linkedin.com/in/aatu-harju", "https://github.com/aatuh/evydence/tree/master/examples/customer-cve-review-demo", + withBase("/api/"), + "API docs", "Cookie preferences", "Evydence is not a legal compliance service" ]; @@ -91,6 +94,7 @@ const requiredFinnish = [ "Lopeta kiireinen selvittely", "Aja asiakkaan CVE-katselmusdemo", "Yksi julkaisu, yksi SBOM-löydös, yksi päätös ja paketin todennus.", + "API-dokumentaatio", "Evästeasetukset", "Evydence ei ole juridinen" ]; diff --git a/site/marketing/src/layouts/BaseLayout.astro b/site/marketing/src/layouts/BaseLayout.astro index 11cc3bb..5531275 100644 --- a/site/marketing/src/layouts/BaseLayout.astro +++ b/site/marketing/src/layouts/BaseLayout.astro @@ -28,6 +28,7 @@ const ui = { skip: "Skip to content", language: "Language", docs: "Docs", + apiDocs: "API docs", github: "GitHub", menu: "Menu", footerTagline: "Self-hosted release evidence for software vendors.", @@ -39,6 +40,7 @@ const ui = { skip: "Siirry sisältöön", language: "Kieli", docs: "Dokumentaatio", + apiDocs: "API-dokumentaatio", github: "GitHub", menu: "Valikko", footerTagline: "Itse ylläpidettävä julkaisuevidence ohjelmistotoimittajille.", @@ -124,6 +126,7 @@ const ui = { {copy.status.navTitle} {ui.github} {ui.docs} + {ui.apiDocs} {copy.privacyCookies.navTitle} From 2982da25e1c5bb9059e7303d2f7649f76439a3d1 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 20:09:26 +0300 Subject: [PATCH 275/287] docs(sdk): add client quickstarts --- Makefile | 6 ++ docs/README.md | 1 + docs/sdk/README.md | 4 + docs/sdk/quickstarts.md | 199 ++++++++++++++++++++++++++++++++++++++++ scripts/sdk_check.py | 13 +++ 5 files changed, 223 insertions(+) create mode 100644 docs/sdk/quickstarts.md diff --git a/Makefile b/Makefile index c409e3d..9b30ae9 100644 --- a/Makefile +++ b/Makefile @@ -207,6 +207,7 @@ docs-check: meta-check release-truth-check persistence-decomposition-check rende @test -f .github/workflows/container-image.yml @test -f .github/workflows/codeql.yml @test -f docs/sdk/README.md + @test -f docs/sdk/quickstarts.md @for path in \ "tutorials/evaluate-in-10-minutes.md" \ "tutorials/customer-cve-review-demo.md" \ @@ -259,6 +260,7 @@ docs-check: meta-check release-truth-check persistence-decomposition-check rende "github-actions/upload-build/action.yml" \ "gitlab/evydence-release-evidence.gitlab-ci.yml" \ "sdk/README.md" \ + "sdk/quickstarts.md" \ "architecture.md" \ "explanation/trust-model.md"; do \ grep -F "$$path" docs/README.md >/dev/null || { echo "docs/README.md missing link to $$path"; exit 1; }; \ @@ -289,6 +291,10 @@ docs-check: meta-check release-truth-check persistence-decomposition-check rende @grep -F 'OpenAPI reference' README.md >/dev/null @grep -F 'Rendered OpenAPI docs' README.md docs/README.md docs/reference/openapi.md >/dev/null @grep -F 'site/marketing/public/api/index.html' docs/reference/openapi.md >/dev/null + @grep -F 'SDK quickstarts' docs/README.md docs/sdk/README.md docs/sdk/quickstarts.md >/dev/null + @grep -F 'Problem Details' docs/sdk/quickstarts.md >/dev/null + @grep -F 'Idempotency-Key' docs/sdk/quickstarts.md >/dev/null + @grep -F 'dist/evydence package verify' docs/sdk/quickstarts.md >/dev/null @grep -F 'Install and operate' README.md >/dev/null @grep -F 'Fastest Buyer Path' docs/buyer-overview.md >/dev/null @grep -F 'Primary Operator Path' docs/operator-overview.md >/dev/null diff --git a/docs/README.md b/docs/README.md index 55c5e71..779a443 100644 --- a/docs/README.md +++ b/docs/README.md @@ -63,6 +63,7 @@ This documentation is organized by reader task. Implementation claims should be - [Release validation](reference/release-validation.md): canonical `make release-check` behavior and summary evidence. - [Upload manifest](reference/upload-manifest.md): schema, validation command, supported evidence request kinds, and safe payload-file handling. - [SDK workflow](sdk/README.md): current Go, TypeScript, and Python wrapper usage and limitations. +- [SDK quickstarts](sdk/quickstarts.md): Go, TypeScript, and Python create/read snippets, Problem Details handling, idempotency, and package verification boundaries. - [Collector supply chain](collectors/supply-chain.md): collector release evidence and health checks. - [Source snapshot collectors](collectors/source-snapshots.md): GitHub and GitLab source metadata upload examples. diff --git a/docs/sdk/README.md b/docs/sdk/README.md index 808e493..a8eef65 100644 --- a/docs/sdk/README.md +++ b/docs/sdk/README.md @@ -16,6 +16,10 @@ The generated SDK route catalog at [`sdk/openapi-route-catalog.json`](../../sdk/ No package publishing manifests are committed for these wrappers yet. Use them as in-repository examples or copy them into an application-owned SDK package until a release process publishes versioned SDK artifacts. +For short language-specific create/read snippets, idempotency guidance, Problem +Details handling, and package verification boundaries, start with +[SDK quickstarts](quickstarts.md). + ## Go Import the wrapper from this module path when your code is in this repository or uses a local `replace` to this checkout: diff --git a/docs/sdk/quickstarts.md b/docs/sdk/quickstarts.md new file mode 100644 index 0000000..69ca58b --- /dev/null +++ b/docs/sdk/quickstarts.md @@ -0,0 +1,199 @@ +# SDK Quickstarts + +These quickstarts show the current in-repository SDK wrappers for a small +create/read flow. They are intentionally narrow: the wrappers help with +authenticated JSON requests, `/v1/` path checks, and explicit idempotency keys. +They are not published language packages yet and do not verify ZIP package +archives or signatures. + +Use placeholders for credentials: + +```sh +export EVYDENCE_URL=http://localhost:8080 +export EVYDENCE_API_KEY=evy_test_or_live_key_from_your_tenant +``` + +Do not paste real API keys, bearer tokens, private keys, raw evidence payloads, +customer package contents, database URLs, or provider credentials into source +files, screenshots, public issues, or support requests. + +## Go + +```go +package main + +import ( + "context" + "fmt" + "os" + + "github.com/aatuh/evydence/sdk/go/evydence" +) + +func main() { + ctx := context.Background() + client := evydence.Client{ + BaseURL: os.Getenv("EVYDENCE_URL"), + APIKey: os.Getenv("EVYDENCE_API_KEY"), + } + + var product map[string]any + if err := client.CreateProduct(ctx, "quickstart-go-product-v1", evydence.CreateProductRequest{ + Name: "Quickstart API", + Slug: "quickstart-api", + }, &product); err != nil { + panic(err) + } + + productID := product["data"].(map[string]any)["id"].(string) + var release map[string]any + if err := client.CreateRelease(ctx, "quickstart-go-release-v1", evydence.CreateReleaseRequest{ + ProductID: productID, + Version: "1.0.0", + }, &release); err != nil { + panic(err) + } + + releaseID := release["data"].(map[string]any)["id"].(string) + var readiness map[string]any + if err := client.ReleaseReadiness(ctx, releaseID, &readiness); err != nil { + panic(err) + } + fmt.Println(readiness["data"]) +} +``` + +For Problem Details bodies, use a generated client or a custom HTTP call. The +lightweight Go wrapper currently returns an error with the HTTP status code +only: + +```go +type Problem struct { + Code string `json:"code"` + RequestID string `json:"request_id"` + Status int `json:"status"` + Title string `json:"title"` +} +``` + +## TypeScript + +```ts +import { EvydenceClient } from "../../sdk/typescript/client"; + +const client = new EvydenceClient({ + baseUrl: process.env.EVYDENCE_URL ?? "http://localhost:8080", + apiKey: process.env.EVYDENCE_API_KEY ?? "", +}); + +const product = await client.createProduct<{ data: { id: string } }>( + "quickstart-typescript-product-v1", + { name: "Quickstart API", slug: "quickstart-api" }, +); + +const release = await client.createRelease<{ data: { id: string } }>( + "quickstart-typescript-release-v1", + { product_id: product.data.id, version: "1.0.0" }, +); + +const readiness = await client.releaseReadiness<{ data: unknown }>(release.data.id); +console.log(readiness.data); +``` + +Use direct `fetch` or a generated client when you need RFC 9457 Problem Details +fields such as `code`, `request_id`, and `status`: + +```ts +type Problem = { code?: string; request_id?: string; status?: number; title?: string }; + +const response = await fetch(`${process.env.EVYDENCE_URL}/v1/products`, { + method: "POST", + headers: { + "Authorization": `Bearer ${process.env.EVYDENCE_API_KEY}`, + "Idempotency-Key": "quickstart-typescript-product-v1", + "Content-Type": "application/json", + }, + body: JSON.stringify({ name: "Quickstart API", slug: "quickstart-api" }), +}); +if (!response.ok) { + const problem = await response.json() as Problem; + throw new Error(`Evydence ${problem.code ?? response.status}: ${problem.request_id ?? "no-request-id"}`); +} +``` + +## Python + +```python +import os + +from evydence_client import EvydenceClient + + +client = EvydenceClient( + base_url=os.environ.get("EVYDENCE_URL", "http://localhost:8080"), + api_key=os.environ["EVYDENCE_API_KEY"], +) + +product = client.create_product( + "quickstart-python-product-v1", + {"name": "Quickstart API", "slug": "quickstart-api"}, +) +release = client.create_release( + "quickstart-python-release-v1", + {"product_id": product["data"]["id"], "version": "1.0.0"}, +) +print(client.release_readiness(release["data"]["id"])["data"]) +``` + +Use a direct `urllib.request` call or a generated client when you need Problem +Details response bodies. The lightweight Python wrapper raises `RuntimeError` +with the HTTP status code only. + +## Idempotency + +Every create/action request in these examples uses an `Idempotency-Key`. +Choose a stable key per operation and tenant, for example: + +```text +quickstart-go-product-v1 +quickstart-typescript-release-v1 +quickstart-python-package-v1 +``` + +Reusing the same key with the same request replays the original response. +Reusing the same key with changed content returns `409` with the +`IDEMPOTENCY_KEY_REUSED` Problem Details code. + +## Package Verification + +Customer package ZIP verification is currently an offline CLI verifier task, +not an SDK helper. Use SDK or generated-client calls to create and download a +package, then verify the archive with the CLI: + +```sh +dist/evydence package verify \ + --archive customer-package.zip \ + --expected-package-id csp_example \ + --expected-product-id prod_example \ + --expected-release-id rel_example +``` + +The verifier checks the package manifest shape, manifest hash, package identity, +expected product/release IDs when supplied, prohibited sensitive fields, archive +metadata, and evidence-bundle coverage when a bundle is included. It does not +make legal compliance conclusions, certify the release, prove SBOM completeness, +or treat scanner results as authoritative. + +## Limitations + +- Current wrappers are source files in this repository, not published package + artifacts. +- Typed helper coverage is intentionally narrow. Use + [`sdk/openapi-route-catalog.json`](../../sdk/openapi-route-catalog.json) and + [`openapi.yaml`](../../openapi.yaml) for generated clients that need all + routes. +- Wrapper error values intentionally avoid including response bodies to reduce + accidental leakage. Use a generated or custom client when you need Problem + Details fields. +- Binary downloads, package archive verification, evidence bundle verification, + and release manifest verification remain CLI/offline-verifier workflows. diff --git a/scripts/sdk_check.py b/scripts/sdk_check.py index b90bad9..cd5bec3 100755 --- a/scripts/sdk_check.py +++ b/scripts/sdk_check.py @@ -134,6 +134,7 @@ def main() -> None: go_client = (ROOT / "sdk/go/evydence/client.go").read_text(encoding="utf-8") typescript_client = (ROOT / "sdk/typescript/client.ts").read_text(encoding="utf-8") python_client = (ROOT / "sdk/python/evydence_client.py").read_text(encoding="utf-8") + quickstarts = (ROOT / "docs/sdk/quickstarts.md").read_text(encoding="utf-8") for helper in REQUIRED_HELPERS: require_text(go_client, f"func (c Client) {helper.go_name}", "Go SDK") @@ -144,6 +145,18 @@ def main() -> None: require_text(typescript_client, "path.startsWith(\"/v1/\")", "TypeScript SDK path validation") require_text(python_client, "path.startswith(\"/v1/\")", "Python SDK path validation") + for token in ( + "evydence.Client", + "EvydenceClient", + "create_product", + "Idempotency-Key", + "Problem Details", + "IDEMPOTENCY_KEY_REUSED", + "dist/evydence package verify", + "not an SDK helper", + ): + require_text(quickstarts, token, "SDK quickstarts") + print( f"sdk-check: validated {len(REQUIRED_HELPERS)} SDK helpers and " f"{catalog.get('route_count')} generated route catalog entries against openapi.yaml" From 4851d97e2b20215e3366f2de36ccccf0183e3cf1 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 20:12:17 +0300 Subject: [PATCH 276/287] docs(ci): add github actions evidence guide --- Makefile | 9 + docs/README.md | 1 + .../end-to-end-release-evidence.md | 168 ++++++++++++++++++ .../release-evidence-workflow.yml | 18 +- docs/how-to/integrate-ci.md | 4 + 5 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 docs/github-actions/end-to-end-release-evidence.md diff --git a/Makefile b/Makefile index 9b30ae9..dab9700 100644 --- a/Makefile +++ b/Makefile @@ -199,6 +199,7 @@ docs-check: meta-check release-truth-check persistence-decomposition-check rende @test -f docs/explanation/trust-model.md @test -f docs/collectors/source-snapshots.md @test -f docs/collectors/supply-chain.md + @test -f docs/github-actions/end-to-end-release-evidence.md @test -f docs/github-actions/quickstart-release-evidence.yml @test -f docs/github-actions/release-evidence-workflow.yml @test -f docs/github-actions/upload-build/action.yml @@ -255,6 +256,7 @@ docs-check: meta-check release-truth-check persistence-decomposition-check rende "runbooks/object-store-recovery.md" \ "collectors/source-snapshots.md" \ "collectors/supply-chain.md" \ + "github-actions/end-to-end-release-evidence.md" \ "github-actions/quickstart-release-evidence.yml" \ "github-actions/release-evidence-workflow.yml" \ "github-actions/upload-build/action.yml" \ @@ -377,6 +379,13 @@ docs-check: meta-check release-truth-check persistence-decomposition-check rende @grep -F 'SBOM inventory tools' docs/commercial/category-comparison.md >/dev/null @grep -F 'Trust centers' docs/commercial/category-comparison.md >/dev/null @grep -F 'release upload-evidence' docs/how-to/integrate-ci.md >/dev/null + @grep -F 'End-to-end GitHub Actions release evidence guide' docs/how-to/integrate-ci.md docs/README.md docs/github-actions/end-to-end-release-evidence.md >/dev/null + @grep -F 'least-privilege' docs/github-actions/end-to-end-release-evidence.md >/dev/null + @grep -F 'do not make live GitHub API calls' docs/github-actions/end-to-end-release-evidence.md >/dev/null + @grep -F 'EVYDENCE_API_KEY' docs/github-actions/end-to-end-release-evidence.md >/dev/null + @grep -F 'release-readiness.json' docs/github-actions/end-to-end-release-evidence.md docs/github-actions/release-evidence-workflow.yml >/dev/null + @grep -F 'upload-output.txt' docs/github-actions/end-to-end-release-evidence.md docs/github-actions/release-evidence-workflow.yml >/dev/null + @grep -F 'actions/upload-artifact@v4' docs/github-actions/release-evidence-workflow.yml >/dev/null @grep -F 'make local-ci-simulation-check' docs/how-to/integrate-ci.md examples/end-to-end-release-evidence/README.md >/dev/null @grep -F -- '--dry-run' docs/how-to/integrate-ci.md >/dev/null @grep -F 'upload validate-manifest' docs/how-to/integrate-ci.md >/dev/null diff --git a/docs/README.md b/docs/README.md index 779a443..f9a99eb 100644 --- a/docs/README.md +++ b/docs/README.md @@ -87,6 +87,7 @@ This documentation is organized by reader task. Implementation claims should be ## Workflow Examples - [GitHub Actions quickstart release evidence workflow](github-actions/quickstart-release-evidence.yml) +- [End-to-end GitHub Actions release evidence guide](github-actions/end-to-end-release-evidence.md) - [GitHub Actions scanner release evidence workflow](github-actions/release-evidence-workflow.yml) - [GitHub Actions upload-build composite action](github-actions/upload-build/action.yml) - [GitHub release evidence manifest generator](../scripts/github_release_evidence_manifest.py) diff --git a/docs/github-actions/end-to-end-release-evidence.md b/docs/github-actions/end-to-end-release-evidence.md new file mode 100644 index 0000000..d76a517 --- /dev/null +++ b/docs/github-actions/end-to-end-release-evidence.md @@ -0,0 +1,168 @@ +# End-To-End GitHub Actions Release Evidence Guide + +This guide shows the checked GitHub Actions path for recording one release's +build, SBOM, scanner, bundle, optional customer package, and readiness evidence. +It is a how-to for wiring CI to Evydence; it is not a claim that GitHub metadata, +scanner output, SBOM content, or the resulting release is complete or secure. + +Use the workflow template at +[`docs/github-actions/release-evidence-workflow.yml`](release-evidence-workflow.yml) +after reviewing the assumptions below. + +## Supported Flow + +The workflow performs these phases: + +1. Check out source and build the artifact. +2. Compute the artifact digest with `dist/evydence hash`. +3. Upload GitHub Actions build metadata with `dist/evydence github-actions upload-build`. +4. Generate CycloneDX SBOM and scanner JSON with Syft, Grype, and Trivy. +5. Build an Evydence upload manifest with `scripts/github_release_evidence_manifest.py`. +6. Run `dist/evydence ci preflight` to validate URL, key scopes, tenant-scoped IDs, and manifest shape. +7. Upload SBOM, scanner, release bundle, and optional customer package requests with `dist/evydence upload manifest`. +8. Read `/v1/reports/release-readiness` into `.evydence/release-readiness.json`. +9. Upload `.evydence/` as a GitHub Actions artifact for operator review. + +The workflow does not call the live GitHub API. It records GitHub Actions +environment metadata submitted by the runner, such as repository, workflow ref, +run ID, run attempt, ref, and commit SHA. Treat those fields as CI-submitted +evidence unless your deployment also records separate provider verification +receipts. + +## Required Evydence Scopes + +Create a least-privilege collector API key when possible. Store the secret once +in GitHub Actions as `EVYDENCE_API_KEY`; do not print it in logs. + +Minimum scopes for the end-to-end workflow: + +| Scope | Why it is needed | +| --- | --- | +| `build:write` | Upload GitHub Actions build provenance. | +| `evidence:write` | Upload SBOM, vulnerability scan, VEX, and related evidence. | +| `bundle:write` | Create the release bundle from the upload manifest. | +| `verify:read` | Read release-readiness output. | +| `product:read` | Preflight the configured product ID. | +| `project:read` | Preflight the configured project ID. | +| `release:read` | Preflight the configured release ID and read readiness. | +| `evidence:read` | Support readiness and evidence lookups during preflight and upload flows. | + +Add these only when the workflow creates a customer package: + +| Scope | Why it is needed | +| --- | --- | +| `package:write` | Create a scoped customer package. | +| `package:read` | Download or inspect package metadata in follow-up jobs. | + +Use an admin key only to create the collector key. Do not run routine CI uploads +with broad tenant-admin credentials. + +## GitHub Secrets And Variables + +Secrets: + +| Name | Value | +| --- | --- | +| `EVYDENCE_API_URL` | Base URL such as `https://evydence.example.test`. | +| `EVYDENCE_API_KEY` | Collector or tenant API key with the scopes above. | + +Variables: + +| Name | Value | +| --- | --- | +| `EVYDENCE_PRODUCT_ID` | Existing Evydence product ID. | +| `EVYDENCE_PROJECT_ID` | Existing Evydence project ID. | +| `EVYDENCE_RELEASE_ID` | Existing Evydence release ID. | +| `EVYDENCE_ARTIFACT_ID` | Existing artifact ID linked to the release. | +| `EVYDENCE_REDACTION_PROFILE_ID` | Optional redaction profile ID for package creation. | + +Secret handling rules: + +- Never echo `EVYDENCE_API_KEY`, bearer tokens, private keys, database URLs, raw + evidence payloads, customer data, or unreleased package contents. +- Store IDs as variables only when revealing those IDs is acceptable for your + repository visibility model. +- Rotate the collector key if it appears in logs, screenshots, issue comments, + or artifact uploads. +- Keep downloaded customer packages in short-lived artifacts with explicit + retention and access review. + +## Workflow Template + +Copy the checked workflow into the repository that builds your release: + +```sh +mkdir -p .github/workflows +cp docs/github-actions/release-evidence-workflow.yml .github/workflows/evydence-release-evidence.yml +``` + +Review and pin the scanner versions used by your runner image or workflow. The +checked template uses `syft`, `grype`, and `trivy` commands as integration +points; production runners should install reviewed versions before the evidence +job runs. + +Customer package creation is optional. To enable it, set both +`EVYDENCE_PRODUCT_ID` and `EVYDENCE_REDACTION_PROFILE_ID`; the manifest +generator requires all package fields together and rejects partial package +configuration. + +## Expected Outputs + +The workflow writes these files under `.evydence/`: + +| File | Meaning | +| --- | --- | +| `artifact.digest` | SHA-256 digest of the built artifact. | +| `upload-manifest.json` | Batched Evydence create/action requests. | +| `sbom-cyclonedx-upload.json` | SBOM upload payload generated from Syft/CycloneDX output. | +| `scan-grype-upload.json` | Generic vulnerability-scan upload payload from Grype output. | +| `scan-trivy-upload.json` | Generic vulnerability-scan upload payload from Trivy output. | +| `release-bundle-upload.json` | Release bundle creation payload. | +| `customer-package-upload.json` | Optional customer package creation payload. | +| `upload-output.txt` | IDs returned by `dist/evydence upload manifest`. | +| `release-readiness.json` | Readiness report with result, gaps, assumptions, and limitations. | + +Expected successful log markers: + +```text +upload manifest valid +uploaded /v1/sboms: +uploaded /v1/vulnerability-scans: +uploaded /v1/release-bundles: +``` + +If package creation is enabled, also expect: + +```text +uploaded /v1/customer-packages: +``` + +Readiness may still fail when evidence is missing or a policy gate blocks the +release. Treat that as a review signal, not as a compliance, certification, +scanner-authority, or release-security conclusion. + +## Local Test Assumption + +Default repository tests do not make live GitHub API calls and do not require +real GitHub repositories, GitHub OIDC tokens, scanners, S3, KMS, or customer +systems. Use the local simulation before copying the workflow: + +```sh +make local-ci-simulation-check +``` + +That check exercises the same Evydence CLI path with local fixtures and a +loopback API. Live provider validation remains a separate deployment or release +readiness task because it needs real provider accounts, secrets, and repository +settings. + +## Troubleshooting + +| Symptom | Likely cause | Fix | +| --- | --- | --- | +| `401 Unauthorized` | Missing, revoked, or malformed `EVYDENCE_API_KEY`. | Rotate or re-store the key. Do not print it. | +| `403 Forbidden` | Key lacks a required scope. | Compare scopes with the table above. | +| `404 Not Found` | Product, project, release, or artifact ID belongs to another tenant or does not exist. | Re-copy IDs from the Evydence API using the same tenant. | +| `409 IDEMPOTENCY_KEY_REUSED` | A workflow run idempotency key was reused with different content. | Review the earlier upload and use the run attempt as part of the key. | +| Scanner command missing | Runner image does not include Syft, Grype, or Trivy. | Install pinned versions before the evidence job or use a reviewed runner image. | +| Readiness failed | Evidence gap, unhandled critical finding, missing passed build/attestation, missing bundle, or missing decision/exception. | Read `.evydence/release-readiness.json` and remediate the specific gap. | diff --git a/docs/github-actions/release-evidence-workflow.yml b/docs/github-actions/release-evidence-workflow.yml index 5f73759..1ca2cc6 100644 --- a/docs/github-actions/release-evidence-workflow.yml +++ b/docs/github-actions/release-evidence-workflow.yml @@ -99,4 +99,20 @@ jobs: dist/evydence upload manifest \ --url "$EVYDENCE_API_URL" \ --api-key "$EVYDENCE_API_KEY" \ - --manifest .evydence/upload-manifest.json + --manifest .evydence/upload-manifest.json \ + | tee .evydence/upload-output.txt + - name: Read release readiness + env: + EVYDENCE_API_URL: ${{ secrets.EVYDENCE_API_URL }} + EVYDENCE_API_KEY: ${{ secrets.EVYDENCE_API_KEY }} + EVYDENCE_RELEASE_ID: ${{ vars.EVYDENCE_RELEASE_ID }} + run: | + set -euo pipefail + curl -fsS \ + -H "Authorization: Bearer $EVYDENCE_API_KEY" \ + "$EVYDENCE_API_URL/v1/reports/release-readiness?release_id=$EVYDENCE_RELEASE_ID" \ + | tee .evydence/release-readiness.json + - uses: actions/upload-artifact@v4 + with: + name: evydence-release-evidence + path: .evydence/ diff --git a/docs/how-to/integrate-ci.md b/docs/how-to/integrate-ci.md index c06e7e5..b88d42d 100644 --- a/docs/how-to/integrate-ci.md +++ b/docs/how-to/integrate-ci.md @@ -26,6 +26,10 @@ Expected status is `201`. The response returns the collector API key secret once ## GitHub Actions +For the concrete end-to-end scanner, bundle, optional customer package, and +readiness path, use +[End-to-end GitHub Actions release evidence guide](../github-actions/end-to-end-release-evidence.md). + Start with the quickstart workflow [docs/github-actions/quickstart-release-evidence.yml](../github-actions/quickstart-release-evidence.yml). It builds one artifact, computes its digest, writes a minimal CycloneDX SBOM, From 298fd1e0bf6fa7b92c4f3e7b7b958480d2e68afe Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 20:15:48 +0300 Subject: [PATCH 277/287] docs(integrations): add tool handoff templates --- Makefile | 10 ++ docs/README.md | 1 + docs/how-to/integrate-ci.md | 4 + docs/integrations/tool-templates.md | 231 ++++++++++++++++++++++++++++ 4 files changed, 246 insertions(+) create mode 100644 docs/integrations/tool-templates.md diff --git a/Makefile b/Makefile index dab9700..87e3f59 100644 --- a/Makefile +++ b/Makefile @@ -164,6 +164,7 @@ docs-check: meta-check release-truth-check persistence-decomposition-check rende @test -f docs/how-to/install-and-operate.md @test -f docs/how-to/view-packages.md @test -f docs/how-to/publish-marketing-site.md + @test -f docs/integrations/tool-templates.md @test -f docs/reference/configuration.md @test -f docs/reference/capability-map.md @test -f docs/reference/api-contract-matrix.md @@ -219,6 +220,7 @@ docs-check: meta-check release-truth-check persistence-decomposition-check rende "how-to/view-packages.md" \ "how-to/review-customer-package.md" \ "how-to/integrate-ci.md" \ + "integrations/tool-templates.md" \ "api.md" \ "operations.md" \ "kubernetes.md" \ @@ -379,6 +381,14 @@ docs-check: meta-check release-truth-check persistence-decomposition-check rende @grep -F 'SBOM inventory tools' docs/commercial/category-comparison.md >/dev/null @grep -F 'Trust centers' docs/commercial/category-comparison.md >/dev/null @grep -F 'release upload-evidence' docs/how-to/integrate-ci.md >/dev/null + @grep -F 'Tool-specific integration templates' docs/README.md docs/how-to/integrate-ci.md docs/integrations/tool-templates.md >/dev/null + @grep -F 'syft dir:.' docs/integrations/tool-templates.md >/dev/null + @grep -F 'grype dir:.' docs/integrations/tool-templates.md >/dev/null + @grep -F 'trivy fs --format json' docs/integrations/tool-templates.md >/dev/null + @grep -F 'Dependency-Track is adjacent inventory' docs/integrations/tool-templates.md >/dev/null + @grep -F 'Jira links are metadata' docs/integrations/tool-templates.md >/dev/null + @grep -F 'EVYDENCE_OBJECT_STORE=s3' docs/integrations/tool-templates.md >/dev/null + @grep -F 'Default repository checks do not call Syft, Grype, Trivy, Dependency-Track, Jira, GitHub, GitLab, S3, or MinIO' docs/integrations/tool-templates.md >/dev/null @grep -F 'End-to-end GitHub Actions release evidence guide' docs/how-to/integrate-ci.md docs/README.md docs/github-actions/end-to-end-release-evidence.md >/dev/null @grep -F 'least-privilege' docs/github-actions/end-to-end-release-evidence.md >/dev/null @grep -F 'do not make live GitHub API calls' docs/github-actions/end-to-end-release-evidence.md >/dev/null diff --git a/docs/README.md b/docs/README.md index f9a99eb..492c045 100644 --- a/docs/README.md +++ b/docs/README.md @@ -17,6 +17,7 @@ This documentation is organized by reader task. Implementation claims should be ## How-To Guides - [Integrate CI collectors](how-to/integrate-ci.md): connect the GitHub Actions quickstart, the scanner workflow, the composite upload action, GitLab CI, source snapshots, and collector supply-chain records. +- [Tool-specific integration templates](integrations/tool-templates.md): Syft, Grype, Trivy, GitHub Actions, GitLab CI, Dependency-Track, Jira metadata, and S3-compatible object storage handoff snippets. - [Kubernetes deployment](kubernetes.md): install the Helm chart and verify a self-hosted cluster deployment. - [Air-gapped installation](air-gapped.md): build, sign, transfer, verify, and import an offline package. - [Release signing](release-signing.md): create and verify local release artifact manifests. diff --git a/docs/how-to/integrate-ci.md b/docs/how-to/integrate-ci.md index b88d42d..8f2ff58 100644 --- a/docs/how-to/integrate-ci.md +++ b/docs/how-to/integrate-ci.md @@ -26,6 +26,10 @@ Expected status is `201`. The response returns the collector API key secret once ## GitHub Actions +For scanner, issue-tracker, Dependency-Track, GitLab, and object-storage +handoff snippets, see +[Tool-specific integration templates](../integrations/tool-templates.md). + For the concrete end-to-end scanner, bundle, optional customer package, and readiness path, use [End-to-end GitHub Actions release evidence guide](../github-actions/end-to-end-release-evidence.md). diff --git a/docs/integrations/tool-templates.md b/docs/integrations/tool-templates.md new file mode 100644 index 0000000..b13836b --- /dev/null +++ b/docs/integrations/tool-templates.md @@ -0,0 +1,231 @@ +# Tool-Specific Integration Templates + +These templates show practical handoff points for common tools. They are copy-starting points, not live provider tests. Default repository checks do not call Syft, Grype, Trivy, Dependency-Track, Jira, GitHub, GitLab, S3, or MinIO. + +Evydence records submitted evidence and limitations. Scanner output is not +treated as complete or authoritative vulnerability coverage, Jira links are +metadata, and object-store configuration still needs operator review. + +## Syft CycloneDX SBOM + +Use Syft to write CycloneDX JSON: + +```sh +mkdir -p .evydence +syft dir:. -o cyclonedx-json=.evydence/sbom.cdx.json +``` + +Add it to an Evydence upload manifest: + +```sh +python3 scripts/github_release_evidence_manifest.py \ + --out .evydence/upload-manifest.json \ + --release-id "$EVYDENCE_RELEASE_ID" \ + --artifact-id "$EVYDENCE_ARTIFACT_ID" \ + --target-ref "pkg:github/${GITHUB_REPOSITORY}@${GITHUB_SHA}" \ + --idempotency-prefix "ci-${GITHUB_RUN_ID:-local}-${GITHUB_RUN_ATTEMPT:-1}" \ + --cyclonedx-sbom .evydence/sbom.cdx.json \ + --include-release-bundle +``` + +Expected Evydence endpoint: `POST /v1/sboms`. + +## Grype Vulnerability Scan + +Use Grype JSON as scanner input: + +```sh +mkdir -p .evydence +grype dir:. -o json > .evydence/grype.json +``` + +Normalize and upload through the same manifest generator: + +```sh +python3 scripts/github_release_evidence_manifest.py \ + --out .evydence/upload-manifest.json \ + --release-id "$EVYDENCE_RELEASE_ID" \ + --artifact-id "$EVYDENCE_ARTIFACT_ID" \ + --target-ref "pkg:github/${GITHUB_REPOSITORY}@${GITHUB_SHA}" \ + --idempotency-prefix "ci-${GITHUB_RUN_ID:-local}-${GITHUB_RUN_ATTEMPT:-1}" \ + --grype-json .evydence/grype.json +``` + +Expected Evydence endpoint: `POST /v1/vulnerability-scans`. + +## Trivy Vulnerability Scan + +Use Trivy filesystem JSON: + +```sh +mkdir -p .evydence +trivy fs --format json --output .evydence/trivy.json . +``` + +Normalize and upload: + +```sh +python3 scripts/github_release_evidence_manifest.py \ + --out .evydence/upload-manifest.json \ + --release-id "$EVYDENCE_RELEASE_ID" \ + --artifact-id "$EVYDENCE_ARTIFACT_ID" \ + --target-ref "pkg:github/${GITHUB_REPOSITORY}@${GITHUB_SHA}" \ + --idempotency-prefix "ci-${GITHUB_RUN_ID:-local}-${GITHUB_RUN_ATTEMPT:-1}" \ + --trivy-json .evydence/trivy.json +``` + +Expected Evydence endpoint: `POST /v1/vulnerability-scans`. + +## GitHub Actions + +Use the end-to-end guide when your repository builds in GitHub Actions: + +- [End-to-end GitHub Actions release evidence guide](../github-actions/end-to-end-release-evidence.md) +- [Scanner workflow template](../github-actions/release-evidence-workflow.yml) +- [Quickstart workflow template](../github-actions/quickstart-release-evidence.yml) + +Use `contents: read` by default. Add `id-token: write` only when your deployment +intentionally records OIDC subject metadata. The current workflow does not call +the live GitHub API. + +## GitLab CI + +Use the checked GitLab CI template: + +```sh +cp docs/gitlab/evydence-release-evidence.gitlab-ci.yml .gitlab-ci.yml +``` + +Required variables: + +- `EVYDENCE_API_URL` +- `EVYDENCE_API_KEY` +- `EVYDENCE_PROJECT_ID` +- `EVYDENCE_RELEASE_ID` +- `EVYDENCE_ARTIFACT_ID` + +GitLab-provided variables such as `CI_PROJECT_PATH`, `CI_COMMIT_SHA`, +`CI_PIPELINE_ID`, and `CI_JOB_ID` are recorded as submitted CI metadata. They do +not prove GitLab-side branch protection, approval policy, runner integrity, or +pipeline identity by themselves. + +## Dependency-Track + +Dependency-Track is adjacent inventory and analysis, not replaced by Evydence. +Use its exports as evidence inputs when they are part of your review process. + +SBOM export handoff example: + +```sh +curl -fsS \ + -H "X-Api-Key: $DEPENDENCY_TRACK_API_KEY" \ + "$DEPENDENCY_TRACK_URL/api/v1/bom/cyclonedx/project/$DEPENDENCY_TRACK_PROJECT_UUID" \ + > .evydence/dependency-track-sbom.cdx.json +``` + +Then upload the exported CycloneDX document through the Syft/CycloneDX manifest +path above. Keep the Dependency-Track API key in CI secrets and do not store +the key or raw exported customer data in logs. + +If you export Dependency-Track findings, normalize them to Evydence generic +vulnerability scan JSON before upload: + +```json +{ + "release_id": "rel_example", + "scanner": "dependency-track", + "target_ref": "pkg:github/acme/service@sha", + "findings": [ + { + "vulnerability": "CVE-2026-0099", + "component": "pkg:maven/example/component@1.0.0", + "severity": "high", + "state": "open" + } + ] +} +``` + +Expected Evydence endpoint: `POST /v1/vulnerability-scans`. + +## Jira Metadata Links + +Jira links are metadata, not evidence trust by themselves. Use them to connect a +decision, exception, remediation task, or security review to the work item where +people coordinated the change. + +Generic evidence metadata example: + +```json +{ + "product_id": "prod_example", + "release_id": "rel_example", + "type": "issue_tracker", + "subtype": "jira_metadata", + "title": "Jira review metadata for CVE-2026-0099", + "payload_hash": "sha256:", + "metadata": { + "provider": "jira", + "issue_key": "SEC-1234", + "issue_url": "https://jira.example.test/browse/SEC-1234", + "linked_subject": "CVE-2026-0099" + }, + "limitations": [ + "Jira metadata links the review context but does not prove the ticket state or approval policy by itself." + ] +} +``` + +Expected Evydence endpoint: `POST /v1/evidence`. Use a redacted local JSON file +for `payload_hash` input and avoid uploading comments, attachments, credentials, +or customer data unless the package scope and redaction profile explicitly allow +it. + +## S3-Compatible Object Storage + +For shared or production-like deployments, use S3/MinIO-compatible object +storage rather than filesystem storage: + +```sh +EVYDENCE_OBJECT_STORE=s3 +EVYDENCE_S3_ENDPOINT=s3.example.test +EVYDENCE_S3_BUCKET=evydence +EVYDENCE_S3_REGION=eu-north-1 +EVYDENCE_S3_USE_SSL=true +EVYDENCE_S3_ACCESS_KEY_ID= +EVYDENCE_S3_SECRET_ACCESS_KEY= +``` + +Operator checklist: + +- create the bucket outside Evydence before startup; +- use TLS for remote object storage; +- store object credentials in deployment secrets, not source control; +- back up PostgreSQL and object storage from the same recovery point; +- enable provider-side versioning, retention, or object lock when required; +- rehearse restore with [Backup and restore runbook](../runbooks/backup-restore.md); +- review [Object store recovery runbook](../runbooks/object-store-recovery.md). + +Evydence tenant-prefixes object keys and verifies stored payload digests during +worker replay and verification flows. Bucket policy, IAM, encryption, lifecycle +rules, WORM/object-lock enforcement, and provider availability remain operator +responsibilities. + +## Local Validation + +Validate generated manifests without network access: + +```sh +go run ./cmd/evydence upload validate-manifest \ + --manifest .evydence/upload-manifest.json +``` + +Run the checked local CI path: + +```sh +make local-ci-simulation-check +``` + +Those checks validate Evydence-side manifest handling and local evidence flow. +They intentionally do not validate live provider credentials, scanner +installations, SaaS project permissions, or object-store service policies. From e3af073b5c8ad2c7e13fa75133f135480f19220f Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 20:21:57 +0300 Subject: [PATCH 278/287] test(release): add asset verification smoke check --- Makefile | 10 +- docs/reference/release-evidence-index.md | 11 ++ docs/reference/release-validation.md | 16 +++ scripts/release_asset_smoke_check.sh | 137 +++++++++++++++++++++++ 4 files changed, 173 insertions(+), 1 deletion(-) create mode 100755 scripts/release_asset_smoke_check.sh diff --git a/Makefile b/Makefile index 87e3f59..0300a6a 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ GOVULNCHECK_VERSION ?= v1.2.0 TAG ?= -.PHONY: help tools fmt lint vuln gosec test test-race fuzz-smoke coverage coverage-check openapi-check openapi-precision-check rendered-openapi-check meta-check release-truth-check persistence-decomposition-check docs-check deploy-check sdk-check demo-check customer-cve-review-demo-check local-ci-simulation-check reviewer-package-workflow-check black-box-demo-check black-box-release-artifact-check benchmark-check package-viewer-check marketing-site-check marketing-site-production-check restore-rehearsal-check fast-check finalize release-acceptance release-check production-check release-candidate-check public-release-verify migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean +.PHONY: help tools fmt lint vuln gosec test test-race fuzz-smoke coverage coverage-check openapi-check openapi-precision-check rendered-openapi-check meta-check release-truth-check persistence-decomposition-check docs-check deploy-check sdk-check demo-check customer-cve-review-demo-check local-ci-simulation-check reviewer-package-workflow-check black-box-demo-check black-box-release-artifact-check benchmark-check package-viewer-check release-asset-smoke-check marketing-site-check marketing-site-production-check restore-rehearsal-check fast-check finalize release-acceptance release-check production-check release-candidate-check public-release-verify migration-compatibility-check release-check-local-postgres compose-up compose-down migrate live-postgres-check postgres-integration-test clean help: ## Show help @awk 'BEGIN {FS=":.*## "}; /^[a-zA-Z0-9_.-]+:.*## / { printf " %-18s %s\n", $$1, $$2 }' $(MAKEFILE_LIST) @@ -89,6 +89,7 @@ meta-check: ## Validate root legal, governance, support, and release-evidence me @test -x scripts/release_acceptance.sh @test -x scripts/release_candidate_package.sh @test -x scripts/release_candidate_validate.sh + @test -x scripts/release_asset_smoke_check.sh @test -x scripts/release_evidence_metadata.py @grep -F 'GNU AFFERO GENERAL PUBLIC LICENSE' LICENSE >/dev/null @grep -F 'AGPL-3.0-only' COMMERCIAL.md >/dev/null @@ -451,6 +452,9 @@ docs-check: meta-check release-truth-check persistence-decomposition-check rende @grep -F 'Controlled self-hosted production candidate' docs/reference/release-notes-v0.1.0-rc.1.md >/dev/null @grep -F 'not legal compliance proof' docs/reference/release-notes-v0.1.0-rc.1.md >/dev/null @grep -F 'Use one API writer replica' docs/reference/release-candidate.md >/dev/null + @grep -F 'make release-asset-smoke-check' docs/reference/release-validation.md docs/reference/release-evidence-index.md >/dev/null + @grep -F 'checksum, signature, missing-asset, and package-identity mismatch' docs/reference/release-validation.md >/dev/null + @grep -F 'tampered manifest failure' docs/reference/release-evidence-index.md >/dev/null @grep -F 'private security intake' SECURITY.md >/dev/null @! grep -R -i "automatically compliant\|certified secure\|legally sufficient\|SBOM is complete\|all vulnerabilities detected\|scanner findings are authoritative\|regulator-ready without review" README.md docs @grep -F 'make marketing-site-production-check' docs/how-to/publish-marketing-site.md >/dev/null @@ -585,6 +589,9 @@ package-viewer-check: ## Validate local package viewer and walkthrough @grep -F 'Gaps' docs/assets/reviewer-journey.svg >/dev/null @grep -F 'Limitations' docs/assets/reviewer-journey.svg >/dev/null +release-asset-smoke-check: ## Verify local release asset checksums, signature, package verification, and failure cases + @scripts/release_asset_smoke_check.sh + marketing-site-check: ## Build and validate the static marketing site @npm --prefix site/marketing run check @@ -619,6 +626,7 @@ finalize: ## Thorough validity check release-acceptance: ## Run deterministic release metadata acceptance checks @scripts/release_acceptance.sh + @$(MAKE) release-asset-smoke-check release-check: ## Release validation with security, race, and configured live integration gates @$(MAKE) finalize diff --git a/docs/reference/release-evidence-index.md b/docs/reference/release-evidence-index.md index 2e15328..78f6411 100644 --- a/docs/reference/release-evidence-index.md +++ b/docs/reference/release-evidence-index.md @@ -99,6 +99,17 @@ The helper downloads the release assets with `gh`, checks the public checksums, validates the in-toto statement shape, extracts the released Linux amd64 CLI, and verifies the signed manifest with that released binary. +For local release asset smoke validation without live GitHub Releases or full +release-candidate packaging, run: + +```sh +make release-asset-smoke-check +``` + +The smoke check verifies a synthetic release asset set, checksum mismatch +failure, missing-asset failure, signed manifest verification, tampered manifest failure, +sample customer package verification output, and wrong expected package ID failure. + To verify the last checked public container image digest and workflow identity, run: diff --git a/docs/reference/release-validation.md b/docs/reference/release-validation.md index 0eb73cf..94935e0 100644 --- a/docs/reference/release-validation.md +++ b/docs/reference/release-validation.md @@ -19,6 +19,11 @@ make release-acceptance ``` That target runs the fast local checks, verifies the root license, governance, support, trademark, release-evidence, changelog, and Docker build-context metadata, and rejects prohibited product claims in the documented surfaces. +It also runs `make release-asset-smoke-check`, which creates a synthetic local +release-evidence set, verifies checksum files, verifies a signed release +manifest, runs the customer package verifier against the checked sample package, +and confirms checksum, signature, missing-asset, and package-identity mismatch +failure cases are rejected. The target writes: @@ -88,6 +93,17 @@ tags, missing live PostgreSQL configuration, missing signing material, and existing local tags unless a CI tag build explicitly sets `EVYDENCE_RELEASE_ALLOW_EXISTING_TAG=1`. +For a lightweight local smoke check that does not require a clean worktree, +live PostgreSQL, release signing credentials, or GitHub Releases, run: + +```sh +make release-asset-smoke-check +``` + +The smoke check writes temporary files under `tmp/release-asset-smoke/`, +removes the temporary private signing key after signing, and leaves +`tmp/release-asset-smoke/summary.txt` with the checked result. + ## Configured Live PostgreSQL Profile For the scripted local profile, run: diff --git a/scripts/release_asset_smoke_check.sh b/scripts/release_asset_smoke_check.sh new file mode 100755 index 0000000..ed1ac01 --- /dev/null +++ b/scripts/release_asset_smoke_check.sh @@ -0,0 +1,137 @@ +#!/usr/bin/env bash +set -euo pipefail + +repo_root="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)" +cd "$repo_root" + +workdir="tmp/release-asset-smoke" +distdir="${workdir}/dist" +rm -rf "$workdir" +install -m 755 -d "$distdir" + +fail() { + printf '%s\n' "release-asset-smoke-check: $*" >&2 + exit 2 +} + +check_required() { + local dir="$1" + local required=( + "SHA256SUMS" + "openapi.yaml" + "openapi.sha256" + "migrations.sha256" + "release-notes.md" + "evydence-release-manifest.json" + "evydence-release-manifest.sig.json" + "evydence_v0.0.0-rc.0_linux_amd64.tar.gz" + ) + local file + for file in "${required[@]}"; do + [[ -f "${dir}/${file}" ]] || return 1 + done +} + +printf '%s\n' "synthetic release archive for local smoke verification" \ + > "${distdir}/evydence_v0.0.0-rc.0_linux_amd64.tar.gz" +cp openapi.yaml "${distdir}/openapi.yaml" +cat > "${distdir}/release-notes.md" <<'EOF' +# v0.0.0-rc.0 + +Controlled self-hosted production candidate smoke fixture. + +This fixture is not legal compliance proof, not a certification, not complete +SBOM proof, not authoritative vulnerability coverage, and not a secure-release +guarantee. +EOF + +(cd "$distdir" && sha256sum openapi.yaml > openapi.sha256) +find migrations -type f -print0 | LC_ALL=C sort -z | xargs -0 sha256sum > "${distdir}/migrations.sha256" +(cd "$distdir" && sha256sum \ + evydence_v0.0.0-rc.0_linux_amd64.tar.gz \ + openapi.yaml \ + openapi.sha256 \ + migrations.sha256 \ + release-notes.md > SHA256SUMS) + +(cd "$distdir" && sha256sum -c SHA256SUMS >/dev/null) +(cd "$distdir" && sha256sum -c openapi.sha256 >/dev/null) +sha256sum -c "${distdir}/migrations.sha256" >/dev/null + +private_key="${workdir}/private.key" +public_key="${workdir}/public.key" +go run ./cmd/evydence release keygen \ + --private-out "$private_key" \ + --public-out "$public_key" >/dev/null +go run ./cmd/evydence release manifest \ + --out "${distdir}/evydence-release-manifest.json" \ + "${distdir}/evydence_v0.0.0-rc.0_linux_amd64.tar.gz" \ + "${distdir}/openapi.yaml" \ + "${distdir}/openapi.sha256" \ + "${distdir}/migrations.sha256" \ + "${distdir}/release-notes.md" \ + "${distdir}/SHA256SUMS" >/dev/null +go run ./cmd/evydence release sign \ + --manifest "${distdir}/evydence-release-manifest.json" \ + --private-key "$private_key" \ + --out "${distdir}/evydence-release-manifest.sig.json" >/dev/null +rm -f "$private_key" +check_required "$distdir" || fail "synthetic release asset set is incomplete" +go run ./cmd/evydence release verify \ + --manifest "${distdir}/evydence-release-manifest.json" \ + --signature "${distdir}/evydence-release-manifest.sig.json" >/dev/null + +package_out="${workdir}/package-verify.txt" +go run ./cmd/evydence package verify \ + --archive examples/end-to-end-release-evidence/sample-customer-package.zip \ + --expected-package-id csp_example \ + --expected-product-id prod_example \ + --expected-release-id rel_example > "$package_out" +grep -F "customer package verified" "$package_out" >/dev/null + +bad_checksum="${workdir}/bad-checksum" +cp -R "$distdir" "$bad_checksum" +printf '%s\n' "tampered" >> "${bad_checksum}/openapi.yaml" +if (cd "$bad_checksum" && sha256sum -c SHA256SUMS >/dev/null 2>&1); then + fail "tampered checksum unexpectedly verified" +fi + +missing_asset="${workdir}/missing-asset" +cp -R "$distdir" "$missing_asset" +rm -f "${missing_asset}/openapi.sha256" +if check_required "$missing_asset"; then + fail "missing asset set unexpectedly passed required-file check" +fi + +bad_manifest="${workdir}/bad-manifest.json" +python3 - "${distdir}/evydence-release-manifest.json" "$bad_manifest" <<'PY' +import json +import sys +from pathlib import Path + +source = Path(sys.argv[1]) +target = Path(sys.argv[2]) +doc = json.loads(source.read_text(encoding="utf-8")) +doc["tampered"] = True +target.write_text(json.dumps(doc, sort_keys=True) + "\n", encoding="utf-8") +PY +if go run ./cmd/evydence release verify \ + --manifest "$bad_manifest" \ + --signature "${distdir}/evydence-release-manifest.sig.json" >/dev/null 2>&1; then + fail "tampered release manifest unexpectedly verified" +fi + +if go run ./cmd/evydence package verify \ + --archive examples/end-to-end-release-evidence/sample-customer-package.zip \ + --expected-package-id csp_wrong >/dev/null 2>&1; then + fail "wrong expected package id unexpectedly verified" +fi + +cat > "${workdir}/summary.txt" <<'EOF' +release_asset_smoke=passed +checksums=passed +signed_manifest=passed +package_verify=passed +failure_cases=passed +EOF +printf '%s\n' "release-asset-smoke-check: passed" From 46bef3bc43a90331c537b803005312b3cc79bda3 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 20:25:06 +0300 Subject: [PATCH 279/287] feat(package-viewer): add reviewer dossier --- Makefile | 5 ++ docs/assets/package-viewer-desktop.png | Bin 132872 -> 172114 bytes docs/assets/package-viewer-mobile.png | Bin 55822 -> 64403 bytes docs/how-to/view-packages.md | 20 +++-- site/package-viewer/index.html | 114 +++++++++++++++++++++++++ 5 files changed, 134 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 0300a6a..fb81ffd 100644 --- a/Makefile +++ b/Makefile @@ -570,6 +570,11 @@ package-viewer-check: ## Validate local package viewer and walkthrough @grep -F 'textContent' site/package-viewer/index.html >/dev/null @! grep -F 'innerHTML' site/package-viewer/index.html >/dev/null @grep -F 'Release Summary' site/package-viewer/index.html >/dev/null + @grep -F 'Reviewer Dossier' site/package-viewer/index.html docs/how-to/view-packages.md >/dev/null + @grep -F 'read-only package scope' site/package-viewer/index.html docs/how-to/view-packages.md >/dev/null + @grep -F 'Package verification result' site/package-viewer/index.html >/dev/null + @grep -F 'Offline verification instructions' site/package-viewer/index.html >/dev/null + @grep -F 'evydence package verify' site/package-viewer/index.html docs/how-to/view-packages.md >/dev/null @grep -F 'Vulnerability / VEX Decisions' site/package-viewer/index.html >/dev/null @grep -F 'Verification Status' site/package-viewer/index.html >/dev/null @grep -F 'Reviewer checklist' site/package-viewer/index.html >/dev/null diff --git a/docs/assets/package-viewer-desktop.png b/docs/assets/package-viewer-desktop.png index 8a5dc39584403f4b8971362bcc251e4d6760a523..3de37068b20142931c44bec28b35015779c7f868 100644 GIT binary patch literal 172114 zcmeFYE_xEpMcQ)Ay0B~@h z;AF%_)I2j!*AaeT>fj??*&y_c~}Nk=-;el0bAWYxPll+X#otR zB&Ls_xKTmGHE zyLSTkHV}OQ-ce~ewu>mYQ(P_L!6+!6wWuUWws7Iho8^?xG!k1LZ|t} zk(#>I?Z98cWyAgPLZiYwYS+|^W^1jsJ3s#|pR$%#U0uVw|Lvfs=1;!Ls}YWjY*rEx zL2_~3Ft@nK%E3v`$moxO1))5y+SH)~+Pk^eb8(iB{%tYRA1_QUQ&y7ZegsTDi$EC} z%`713??1%++0}2h(gU3L3oAmWZdA{qL}6iJ9CoLLdDUb8{^YS<~+^?$HvD~ zl9OpUVk%Yz7^`x>f$Am5&M6Q$yj|_4|K0vC6a1U#95qqndKU;I0s_M6c=kG9<%@+# znOD7w^J$i@v$M-`3ZtFQz)+XZB_PGGEU)a`3HoJ0IYrz0beD(g9vWkKH`p0!k5g1A zTQA})dwd&!e)oXzaED}FTCu!PhsU04A<(f>?_57oqNIMmRbWvz#7}?frtR&`po)R9 zla88o%I9IJ>Q3B#gS+)SmhFMRw(eB{vtcUAU z-BIi={Z3wwt(9?2e-;*}w6x`ga;syt8jXe!e~`Z3sclt{DYSfStbTFGO^(lvSmno$ z5d|*@W%)e+HQRd6>j31w0vM<4ke`2~r6H-UD%amPVLH_4^w7?WRh0=u=)c)WvT6Ax z)(09Ikogm#IR_{$)|(vbvz@Q?*Vayt{Iuw>(d4xnur@BUBlUiRcNcQYAkz`Fe)*oX+ zqq2v(+&o{CL!xhsk{M`ed3{e$AviVEiXp*L8gl@47M4mg>$M(59KEdLHCtT;%I8OS zoo37CO}t|c+mz&6Bj4DF5~!9=nhTR+Ru{j`h6<iIKUvIR#}AJYvX(YZnw6^m=o+n0IO| z)=ySE_2ck>n4Fu1gF%3seY;mICU)kJ0N)~Wj`RK+R_~#tR7#9}o>PC zF-`tW0RC=YPqq#u-k>mMWyU|upO}^5!XqioD{0y-m(UWG>N>^KBzo4%qBwd@r<6&fM?8Rla zJht|a%3O}1&vMc5g~}|d2;pjrvEW{BL5T}C{eeF3VvA0P^K1%u^{xy8`?Z-TT*d<$8JFXU&ASQO}{a4aD;qb>Q}3wUrAigmy+cSI`;H+b?NWUn=8|HY`|&#BgZGAyXfu?{=CQ{P3WH&3*JD`cXzZ1pJ(B< zlhE)3;+rF37UPL)l?WTnIphCA`QGuVbEVO`xUzDj%e4z4e6ilwC)!H``|`>0@rfxZ zCjhP7d5;3uvT60)LrZ&mm6B$P3_;IpwePl>o0*a!9LFmwwa*BplsRQ^>ISM#5k4{z zPtU-K^;O{aG;S3!)vT=4^kl(+t@7|i#}rV$xQYs3ercvTTD?qz)`shxo|e`aUXVjw z9w}7PQPt94yEa?Tj$k>`fL0}i zb|&O0toRVphD&{{Rz8A35q;3chY-`jJ4rJm6x7+p96CN&)<{`Wz}g)q_zsenXw#uN%kLBCnVXhhybFcPjhLkYV4 z4qiI7655taLz3wbSl-&Pz}`*Qr(FcjN%!mAc&bNMCMJW6ko0xFlr_&F*;$`kqP=3( zN~4|h!L!v%h6cjN7 z&Q6UT=&}X0_AcIxFJ)w?3>*}-7+7oLRW+|Y$Hnd z2-IQ&6(l@}I0aN=lrRE>%W1fb}e#vIGd+8E;$wL?Y%HJCrHTfPhkXihmeaf ztQdu&!~A5#`tFxdA{zo-X;hT;VnfAbF^!SE`9zo7&SI!OEtH6VbYjAIPHhT&)g9b( z(2x=)L$hWp(BWZNfd6~Ufi7h#Aui5*Osr`JQ+P}N_GC`JwyZPG2(|Y!l4!p^8&>W% z3r-(%jTx)|wPCLZ8JUo)1-H+6`KC_A%Y8zGJ@XT5gJId7&6$215x+OD=Ro4dyP-uV zO998j!oa{!y&NrHT8)s#m&>{h;eT$u!Uwrs8GUwWEyl*|jY~<8mzKs8G{*x<2GU-5*y*XyI_9abaLKkJf83BE3Gr$W8d&#sJ(+1YQ!RdL z!Q^{)-|lWdF3I&nE!AQ6v_AzKn`rcXUcq>%0&n#>@yln-(@po(#kFEH3`y<-rj1R& z&B>}$FM>t~lq(%;P0Zrw28E)4oVL1BVF+QMn5byJ&4IhF3rWoZ#THLY3GrJ3d3>(B zctYw5ZH`I01N3Txu2xNGG_0&xMW#pi=TTgsh@nL1;4RFkT#(Xt7M}VIKMUe?wmLz? zD#D5M^x#wSgW-}In-~WEq=ByEYP2^H0e!yK1 zxENTfCxMg+*v?;wofq}c`Z-)n2>5AyIbvpG%jZT5CR`5qguqQ*D{Zj3jzs)$_a1Hc z5|>YD@rg&ZjgsV__`>y|!*lzSZvpUU{-*`d=F`z8GPWM80kM6Tt6Wyyz*54FE&=TJ z^PfV5*eQYYIa>(ag6*Rc(CRbIs`Vi>&?gLhC}1^)Q`}6gx5FH{88z(L^BT1uugJ&x z@Wh&J?=yX*pNg}yb=%y{jaw^UTkSlD8iIlIpq1=xU9@@W5Ir4DU~?Tc z$MfP@2i>Cm&Rg{yOemxBMNycOd@=30&~@w1%T~+zY?W9?_@kwo8z{d(XpF(zyGSS4 zvdf`LN%lvo5(^6Upz80msBY_CeOjPHdlVk$Hzp>~!ZQh%;wq=QWslPAVaeX9k*u|X zeRXAIq!$B*pFmb=3&m`s4|>k+;mXE|-(22`M(2c~jfwJ?%}tNms~eOr1WW47;#aWP z-BuMx;W7VT=!jvVEA(n8_Ps(Z(&KB{c}t+ikeQg7UtLVQBs92OCJ4m-CBZRtrl+0F zqX`(^+CS^S-1NM<_7e4#sndcLh<+W|Yfm&ZM?n!46&1-VNcK-tD)7JPbL7>vv_^Q! z#Hp6tg;mA6uI_ur&i&$xlO;LiQNxj&>{dJ7AVX$SF0MULOIS@+B$Jh0Qs7RV)TsRT)8ij(oxyckv#-v!{4s9DJa}5x? zpLL=LtHzGrH-{szlZkf)!+3aywrxOhu;E}$$iCFxL1AH{^#VIWiK*EE>t0;KW9eSc z@H3q{Lpa;h7Rm3-gl&3bV`E(_{v*|-Cj&DmEucUrlw%yn*O?P}?0ZgA>Z%2;S2Phz zuGLP6WC$WM@|9FfPDYQV*>X{$P&6JnGB7ib^!^?}^|j@qudJ)6`*?blYcdAkvaq-) zB|WdUG?pgjbXaKkUtz)bfwLuNzS)h9@$c6Csf4>i^l$_E)-R1od=yZJl%%92^Dk8V zwSyY3x!+ndZCjymQsSm+zP@jP^QHP-ydQgjSRLluJNVx`SM?4;ZVkHM1(8!Ys{JE` z1%facgC&GhrtFsCkeu9nHVqw4PH;xL6BCl`K+O`%5}5?YX&JZ;1!9xQB>urxp zhQVj>7K{rt`+B~{WpJT}!=FS}h^Mi?V839Iy*E={R+N+bg+H9PM#2p5cd$+ej7Sj- z;_A?9w{#!AC6>L>T3+5`RJRr~F&Te-q01{O;>mRYM(NzvGWGWvFllug-N&~XbUUmp zG{PHDQYP6uDb3m$%bC$`@eQg?HAiCsT<4yI0O+W21w1(6UIVBFVT`ZE=&^fz}BB!5ZXuC&

pPaj<8(c*^fJc9MLUVf4U zF`Yn8AUwS!TYHRV#%ih(T46Q>PA`Bcr-D#vIXRZTyc`GM;=;;`wz7kXLJot~h|AM_ za0u#&$I;9_3baaX>2OFMI@^!*Ucu|7uVoD(3e{$Y(WwYJuIUg%%%&zP8gy?AlS!UB z9t}qq4Z6Lz^y=TKALsNrH@0+n?qO%#`rZcNH#IsRTbH}p*=57zw!2wj2Vx=jb}>Ib zr^|Rgb)NYKvv&l_$}E^RCR8x(BpL7N2I39}N8O%R`VCZNgR|e_da}syfcR-AuwD{8 zdL6+iJ!J~_9-*z16uEz=p{9rShmcbCn>(y6&N@+P*-jcULt z#*#}5D%DI1#&s24*nx#m^5LsO$n#Ps=X zP%Aq^`BY|)_PL7MsmJH9Y03xTLKmdPxJZ*yt(Q&yjP3v{~A0Ap22ca)C&4m_={p>Yb1%cos zKG}IgnqO1PKTTl4u))GCsZqd6E9r%X{sHKCw6@ksG0wGr1*RdRhUp4T_#Tu2{Mca) ze}(gi6y+X9-Xk)#vM9Y3>s#U*VeQ)#oQ$Qr>b$hPYxA{iE=O4v@C53bHb=@t{ zrd=^EMP}}$(Ap8jr6Ds@m$(Ox7Ngk#cqMhFuLaARK};nRcQ#L{B-iWS{61~q&C8&m zpm1yg-rDJV6rhWBkXIgIA5_|j*{kFje6xRVI=CIzqyNI(eRI;Ra6azty8dAO_$cA8Q zwODBi8{X|b%Du)ha)M$SRV-uon3K9$ybrS+$Y zA76FceATMQBP!7}$2*vkT8nVjNXfY&%5lfUY8=@(FI16%oDQ@Sy`m$jYdKj zTKl%BwTW0~(E1Lprw!O+FrBD!fhtU6Apju?#$<-W^8A_@aOtIg(0*9)wg>MYp48iy z`i<5nB^^*1h7rsr8)ZLJWU@M@a|b=0jYD;GJO(y!%mC^54g$N^VYNZ;x_R&y-SjOf z6d0wgq2rjQb>V4lm*4NfLf?swfxX758TFiEYo{U?Z}F)#xqD5gn)!*(GLx^nBU|sR-U0O#XtLa=^?fh|{iws| zF@0nj$%{!n*3UiO9IX_{`4k&t z;3+7`X+bVda(2_>bt|;IioGTj0t+c9w|IW$;JgBGCFKvO$Jb{IgHwy` zwY4)av43*)Fg)3AxijvhDFJBTuGj7TD6i(~>T0WC&xm#ZJ<^7kXA#D*8epOzTpu^E~q5aJNMFfUp zhvS8oaw*Ygl!^o*P81Ikx5T_!v-R@$eCyrrSKE8|K>OCNu<)?xFa~Ps834fc@Q1^| zjDOKkN#&o$#`y>Jh>lyLp=ebdU0r^^#qIF}w9<0wfZJ|m%p;g!@v`nVb5ayj;}BR` zS=p521wJR#X|k<18n^G|kwd-fy9iO@D9iz$KT{nr>7yW{#)O5L3>Pxb04sEc%XKty z9_GJeDceS$6!lrJwj)CoX@UjU_ix4}(I5hT=VNpRuZK$>wsP3W0zY(gTwSde>ilf( zW5C|y7x>Lb1LCDJdx_C`5O4`OOu} zQz>SDmnvyb!Rp8fXp;k|+iFf0%5r^q>2-Ip6-~%z59;>2+8qseeTFVp=}h1_ z+HWNFL0vn|Iw;~P#)0FbW6usN+(y{MTwYT!RVHB=Jti_dIVCAW$YLxfLQ~mz<8*Yw z;%MIFaB21zU(2gssOkippP8Y-BLM`jkf7O+4%{^(9 zGOLSA+y{}4<{M+~j#Dve(9`G#IvgO0qC^`kmo=oc9U>mBH?Y0CU{L-(c@m5c1{Ongp7hh6V4Lw@)U+aRj(=;O>nfkyL+PJY*41m^i<3BFD>ef1)WV;;HU}52K*ln{1+^RLtE_bxvy@*lXA;1Ic>M{jP z@}rt~Cfi_A;z`Teo~fCcso8K0?%K?3wm(Pup+8t=;6z#~)LRVc#=X)(DgxwlVY-tn zaC+8qFp>FVy4qb-G~Og3dOT&K%YROQm$x`M?J{1XK|L|)E8HC?ayU711j~Sk8TEC7 zCN%|(J~fHPz~7j_j}PPCce~41>cr

JPVHtm;pi4s2>==~Gl|4$3BV#C?!Jj+f= zVdBoxXVj~koqp{Ob@DwgJX^pA4VQHncA_k%GM!vpR-5hc<#X7r;_K^KC5Y|UT1Cukn`1^{|K{xM zO#OH3>})+>B4TGarU8RSMEOH_MrwL`G_g?jy{O(5z zpkDoTLdf0maT|f{<;6n4145af`)#@zy4H9LW+WWPZ9mzJo3ofU5U917OEc++vc{W8 zg?Nv~=FvqGyk?;|)Q(UJUweI6ZCI%L8Tsu48DR^ul z6lyFGTgAqpoR*iH_U!9Wzi-+JZ5Hx#bc6Y*NOxHj&+meU<AiJ-*`!*$yln zm02AbKN(6H8w0WlZ5XozKE3cB1BOj1-u(rNBE>z4%7}CQ7LUt)A{_;_?o7q}#wO@V zpT#iW-`(wwjtuw4C*$^;C>8nm7Z{t967T{*^@hRoe7TveWp0f_E)H?d=FuJ@(dW@g zNe-VbAOD05@LRa|M>i+H`ucinYpiHCdF8P4^$yj1`}KAf78cB^Rv#$iAXB^Bi6n-) zy1LKJvD@p*^Zfk0TneLr&rpX9TNj`6?g*n^yVAU{vhwWQ9HcK8g^`gli!X&ef!}F+ zpj5d)?S6;i6&&!&#>p8S8Cj{kQ^1Mo@9!VvBaw%(vQXbaHBnBhGQs7l1V%}5AmH(L zH|#-&CU-j?Nj4Nu4M}!>Z7d2-bLoG`)@NGQ_|nJiak;YjvrA3g6RMlT@9(Ks;_k2^ ziGO(H|KoKJ|JMVwk@+CX!OwA8(%!q~oRIL;j>gE&%>UukOjftk*+m$1j;WI8nxmhU zQniBl6|?*s6_inMYvj@;i?^{_ODteK#Ox_b-(j`g$_^hTL`XQPsBL+2)kEh3oWI_! zCkG1)@6imliSY&t+(i=>Rs>dVtG>i_(H@ShOc>6eu&s>8>Q9?@3rZB^YVHrmsYEBFfluQ zpbDz02^l}JBV%G>A|fy{({8*PC0Fj&F-m77)qaiaTx zftQ;H9FZEHAx4+%1R=g(U`j_M^U(tgL4!C;**^ zKeZ2=9g-99GKzL^8QeWqJ~0{jcyr!vx!jHimikz9DCvA0`k6W*UIiXZ`682^emqwa zUA3!!19SPwOA70bmXuzRnaIh12yTV4(#Iq%f)xcb!qqX(!G}z`{sDk&d zy9i8f3jo=VV^3o1^0UwczX^1R3_q0kIQBUwtef}YEydtxpJ)G>sAJ8763whF(C0;A zgBpK<)td?&ht<27#zxF{7fIKL8%F)v&}f^%Pcv!P0+XN6Xar zuWX4OEF^G$V@P2lvfJ@|z{|bG*-F#r&z~`?xLprF4WfjHhcDI9j#~o?VW@Wmpa{{t zQsnizGJU)~qp9B7-mbR+GKLtSff_6nL(vGS1^gba*E_tRL&*sV6`D0ft0{#r*1|4E zD-^VOZ~z@94wykso4#t&;IQhun5hNE@MqUC@p;(p_(P3$GpJ=B?+^uVJr~<0OtyfF zU2>0NQVJ!-MXJ2a)UM|S<8o)}Fk4Ssa2>~ za5`;^r~jCJl9iP$QOtqi#x0D4`T6nfd4&l485yC`PRBbs!ZndXWo**yM}*2u zk2oIjAIi_`Sd=`dQbtu;s*{CW7f_D`=3!i2K`<~>Ijf#Cf_7joFEV<}6KIVByp6H5 zgQ4*PDT$BIPcp0GpnFO0aV#Qu4WUQHpD(B?Kp57nb18IQT>+3d1y`kL=9Q?Z2UpJ} zezM@y9nTNlbk$S842|%N$}=Y(=YHW1y&r=25R+1Wnmw@h*2f8EVc27Jj<7QiAe~w4 zll2CF)fcK1%up2&h2ScyD*Xm*YYH0_By#hX`%)RFEqi_ZN1q(g?!1_Wkzm%Ix;@y7 ztJ|6Q#&gDUY=ZkAWWY{1PnhP6i4CcW&c5`ZuFhX)Y9+`-SVPlH{)g{6Qgnqi0F zA86d|hABwzM5#p;bHE5u(f|HAm!Lpr=c*_or6u98 zVVMrL15*~%FwvvwmfWZwpBmPtmr!}E%$*bmDfa=#;oGpZk&=C2-<_TG*lp4qWRI+O zYK9UK&g8wfzpu$zDhhpIRb3gip$!9}j&wYcYTi|?rPY`hQm}aX9RJyOcIPNGEgX0P zVNVDqZ&XKr?+K}2NE{FYVV%2=^FkU;vshIo@`*att!TnRhj9eaMs@sI*q|pI7`=!1 z2A>hQ$p-{o_$f=j{M%$H+_=EbZtCxFhq$Sex~^s9OUEOtw56q~o?p=wnNX&dGf7i} z;knnS&HLrdTF&Bt#mP#7gMC2HwkWEJVx@ZX#wCySsk@F=Teg$(9#y^wElTtAqngZp z4NyF-i7&3uWM*oL=ZBO7Y&C6YWHx|KH%_}Wz?r`ziJg6-kJ{REkE>}% z5Z)18|2yyJ%akK6uQR;)*o3&TF^1*G-Rm{8$L#f+=;Y*B$NI(MdpC|fy0ji$gy6x| z=?C3b;_Uc1;9prEH7dCd?N0okI5=#>_6P=EPb*CHqX20?mFbnnu<+a3%GGS;gvE82 zdcek`g`Bq+RN{I`{k$=x3!BgY$eNFP_o*C_|EN>z2VxbvZR!{u51wQMj}*QNjks(c=zY3N&|%Uqhq8U zjnr&ZrmuNlcjMxC!aEb>;5B5fn8w1T>;5Cgig+4HF(#UJr(vO*WdQjD=5@S#ab6l` z3+=}6TAVCCURy>>IU=P>fBG1Uf!u<_%V(^d<$x{u=|GRFV|;0ua65rBHv1&LM-2u2 zyv|Hhum+{%Leg5cRE^MWJf#ZzR)7xC5T$ujX~`=oHwjCXDKjSW_efp;gR25yS9->^ zot^iM%&!C-c;Zd)A%S@7QhFWRf2wnDh zd%_+x`7L&E3BNN{Bco8XVLu3hU*lZUx!EMV>?#2H%Z+8!{3SsJV7zB$`eyaR-pV+? zjljkVr|zV8mQv%3_Tt^*)pdcI>b_sQWRqtE(jfK*%C4KN)6HaoL-yP6w~{Iy=ca5z zBU;ef%FLj+EQVJgsJgav$!g*#RIskbWX?uI^LS(a4-va!ilijriw6y9GEQ9E(*=h> z4A`Ent^^f<120-2D{k@ih*b* zs}gD|EA!m?s~N~nisyW$2~(kC3gx&a9>iI9w*H39mR*47_AoW+>kZ4cD(+e}V@k7t#WHK$4I%%+j8?>zdlJ#l?| zh5Ee+b$+m{li}9sj2$2Ck35Z4XKcpwKnWJErP`u%rd_MZQvpgl8!Kj^p{9y#8y66U zO=H_gNX{s!jhV&_W%27}0Q*`y>Upez4G)R?3oYabS?sXy)LK}<{He&LG*{;S8M>@1 zqT;@Ju{v7-hXgt7Q7<8Y6nsF(;NbO}h$8ZVr5YX0sFw2UQ}n(4d3ycylj$q0Kk98i zh%!bZC~&RmSUSIxnpYO=5~e3+CRbE3_S{_4A*;Yk7Vqv}3M%-&0n^D!Zw(r|HhJ33 z91bt2#hJasc6z$;d>Gb2<9;yOlhJ}jx7uTLSwdoPfqj>zU4$vh)sss-FH1&xlu4iX z^nY4F-co3Dd#0i5uiNr9flBF|-GX#y9y96kQ6`Tp*m*bgCm0rLuYE2Dw2U_a z=#G~23nV}2J86rR_2t`In}4=betedcJ9DJa`FzJ+RDzj|qhKT^8eUH<7#GfuKXY$Q zrWKB**|sdg;ikVy$(e?eox3Tjt0Kd{z5V=W9p_p8Mr|LpPBSqjz5D15Ur$Ily+EiG zWJPut3v;j}u~A@laq~vG+^$lvDu=MenGp3pe4i<$y`COH1iq%i(czm%n{ znVk3ab1=^rRhPD}QW8Etwy4w-Y^-VmhEJ;EMVY%!=f)bZ?gwXn@A&k7B>+t~>3C3m zHyH8talx*F`J9vxJASWy0gu`A%2Nmbf~#o_SVPM8X;P1-Es@Y!4M&DM8%RaTa-jI^ z@iny}(O>H|@YB9eScGD(;sMU5i9gX}E>jFGp`ZiM<@!L^&a>o;NFI#e1-@_J(FB+T z5r&Bw=yl=-bbbd>Z~XmazTjo%A1*@Am*e$d#fXo()w$25!#tm8Y2JJC3DA>Q8GlOk zmcY)|vx*bbY(QHJ()@+U;D_#nI29y2EP=*B02AIyS1$asc9Q#!{x>j0`%pU48`LbS zCsJu6pnt?g+8x_9E(3!YnhzVX#Dr(2wA$!CDQV`(fcB>$ym$DcAKH@2y}wSNG^L(M zvu_7bRoN9TzftN0VKN(prGD~wzCcx6@dRY}!OpjyTROZ}k+w|12R2leH;~&>{{h$wg^A-% z*B2k;5>t{YEnl2RrNdgvYjTowxV_f(R=OrjI%zg$d!o`R8{y@d=xNWPz?-5+{!k`2 zfgK`^St5;mML7)Q?KQ94+_xdi@?)NBbR;9Wep#vDAJT-rBq9En8bY|j$(fZ-06feeR zK*GwHM>$nN0jbEFKLe55u>TAuxV$hnpF2RebUzY7$6N@^4M^1r@lc}+lo2sa-oe7HxrQ>E2azf3cfiqh1{ zb~s(hpanBf|G2Q=3XYpB6P`MGC+d_8(Qj+S$LVzT;Tz-rDu+kJv}aZn;#QlwQi9gCP!_i}9y_o)oljZiMhxi9_tIOBZ7E}4 zpDov(-XAJi?_(7FbGW)PuOxNfY=PMi-l(@TZxHej%xn4T?~wR8iylVJNFyY<(~m3K zg#tQWodetQRw`fIsy=#g5$Ur7NT_NqetJycwlFu~mA9uOFG?Qoof}b5uc+vW339Sj z=%|`V{$Wb^34Z$qtrRb`z3Hg;X<&N?V{dP--Q9N5*XJ@!Mxed1sm7-NZ^_dW&p&(( zUS22@`$56q(S%1#KJ4z=7@YfrK*g4SFYxWQ)r>D)T3MvaMj(wVOoGg#D9VNcv{p~< z`6=xOyT8NAD=&4bM#{(}lfFMmg6KQFGdkN6VW&`3AS)7k{G2960Jd`Ny?3#X@aSJ; zwwS`{NUBr+@ED%Z;*Dx#zvm8<#+ zRy+4jj~uy*@}$~@pq9iu?2hrvDKM!*w2J->>IETC_qH2^#XP*JHN1L=EoDNb7*9X)vS zo@sM7SC|Y=30ce@Bi_2N^R>`4B?&w#Qq$7R*VVOp_Y07p-jtGboh&blOAPCE`%{s# ziz+BgSL$!XXx&d+}pa)xU;4QtRO^5Hk=az#5Ety4{DuGAwZnc`DP>9|YI zLUM6-e&sU5>^SWfE6L`EWV3h`ma)`CiOsJrnb|bU69|k9l_zhWw{7^H-t-;Vxx##~ z$};6B>`6R4d_3LG<702=?86?UZTW@Ila*1>>HOL$(LG?(3A{CTS%8?$6RIsP@)VrJKKSbmLMJ~Iy#@%*#;4ktz&E2=v%kKqC&;&jDbHr+Yxc^KA*SbOHRZLVAS9uwzyv@bV22!8%=j9t~J?qVBi6X4+d4K!R-a03-Db@Ej1Ki*5kOSJY{ z;d&uRz{=20WEtNJT6g2=6|;BLMSmi&PIeB6}}Y@4$a$YErrx(%HXq)`lv$ zRf!ExtBOSXMdahJx)Wn#V4SQrs8*OyNem9!YBAFAQ1J1UxVapVJp0TjTR?v%jMC%? zCMbvb4QG?JFH|UB^pzHiXt+-m6F!#KitlX{M;!|V9JL($l}Vq>(5r7LHwGW`6xJsT00ZJN|(9TS<5;$>CFnny}+nzfA37$)Jk-Ff~&S zmU13j!)cOt?XYf08d_wxSIGSQwfyR>s<_ErZuS)FF^2=-Z*??m9Iez)23<=FcLjSe zWFivPYBKt^nP^%+yGNH*SVmTMr5v^6kk4v%KCD|mT~#Yhv#-SXb;@s;f`TIC`o!GG z-1!_(rDKmSXQ!#C*%9ENFaE1p8b6;yDP6X0cv`pG&P>qQkx2(X;xQ)sT)Z(@-7RK?l7hrNtU%>{tNY5zb(m9|8|A*l8-rBmD;}BMrVk>MlaadX#OtnI(`paD z0HH-z~EL=7ZwZ^*EylEf4d3oI@Cdb8{uUGY#8u{7T=m60FoksM<{ZJ>0 zI5slQwBodwl8-;dxgh0H_ptkPhu1^ps(gRhN0v|B&hi+;62ftFWTvNMgKL#GcTl6O zrK}g*}J8H=APt0w|%o3C-yKO04fSXmeWdG zh7`wWs_#Xq=M|Q=f-kIS-Bpero|0A@HEmh=n8`C`tIRYNk^p;*_Gb2y5`xGWKT>g3 zIXDLKge@&l#?(#D;ET|w!+iMjB+yI)6iaQ38G~64U)|JG86pT;Dkqj(WW6Y!KnjF&S2Xr2L^R zJ4@bNW3egYoFRkPsp`w01{Jn(k3=hUt<7MW+ToD1-dtufIWnkxtWH&O)OoUO9c-N-z{ zI@Gcb+6yMpk;@vV|foc6t?sk zjAkU9dZS1(vNCzCKg5vunngk{0{)rG36zB;x`+rYEUbduc>E$61l+s-dC8e(~ykkRSl~)`}aq;2TFx7sdq_nJj9_K4_ z5T~87ZUTekRkO|1i4+u;tjx?P!poIVh4`|@DjGjjSG`c-0D%h{Dr)c1!g5oX3=ovs z=7-uBS5rOI8jESv8k?Az^xz6&zE8_(*g17T3tPkekXD7OQGHdL{NdHqptEHha@ zo~==;*q}6WuhL%I(xXoM+=jWi85KE&X1Do6mnG-8Ht_>#{j(Ij&1MFNb0u}V@@+%s z)d$!dL8*<7ieYi7_>DEJ=hRr1fppjQcRuHJW_Iu6U9(%IzEtP}Nfl>_` z*WlX3AAkB{{>16!L&W|Q4_b3`6*l%$x3&f+h4Klf|7iiQt+BQ5ks0S{YNk>89g-m6 zZWF>4jv9kYVTKiLJX~A~ViMA;s^I0&A$eQuhh3!EMZo;*;)4gc4#wdUSBL%~&YKYF zaGZSKm*vBXgilhCC@?Yuw|{5hu9{a{%=x#X(!VG4u?bmXgG97v4NP($B0P7FUzo4t zzpFSSui}b-EvJ9IOeM1xL7T5B{Eoz~-hDNhQ8lE`=>P^r7_x8Qpi-Bc2H46o-9knwi z3JSFsHPwpK4Fa{^a~Ls`%L%-@6Gs-F!CZzSY(`Gl!VDu7h=tkJew*)ev|&kD{84(6 zZK%v{r~@XZ;8UWSXmR^P<|%r=aYZ>b%B$94M&aS#Lfi;=3neBOviLCzA6Uwr#i%)K z^-u#~XZGgV+qtPHjdQJW+JO{*hG5HQE^&TNdMXyRZ*&rSgdvE&=i@4{DX%I64_H{M zT{ftyGKaYE)vy7;TZVD}GuTsvQ**iYc4YJ{4*2d6tqx(@4> z*%g-yQ_q16G`kE{TM2_2-lVR!HyoyBMGXxuvXj%;Oc@;RjaARHhRCqq?j#54I3Y)x zq|h?&oGeiixbRO-44=!xZ^acf%&#x}i5(>L@0Je}vfCW9L?syQGGNkUhm5{M`bab=bXp?|I2=tDkmg%ESvqKHDDs1J)_`F&&;)G>6IqD1=lm8XS{De*|7gJISaQBj|QP^ev06W&3$+f#gIkK%kA4+Sn;wj4|K=BaFMI&3*yQ_bGG*HdoO$^?iCF2?v6 zViJYQg<^BvZrEY^ThBWOzW2q}!Se1;FL|dcjb_IX!>vba7YuM(v&&BJZ-0rurf7V< zjP^rpmPI4gzoX>$ufr7R=pht?vt!7tZMVA=g-SZXgHxP{$Um^GOeRKZRas@K*RRXR zim}l@)qQ&9hqv3_@%j1laBs^t%C5dPFtjt@7a(iCgud{hG&6s1R7Cq}O%;6P=ou~a zjiWpcm*@QCa~%h9Su{GQ6W+WlWn-(539eF*(=aii2g`Qw@1TI-;OuBADJ(E$>^*;; zf54Bc;Ka=LPA=DT`q1X$@*&(DQRNgK_JS7hsMT;JRN&+=>jZmZ1I*V-*FKd4A-1nS z1mG&X>YSk&ni~3uGNsNXY4 zD`T^-M9C%&=r$Oe8|S4%cFbk8H8n5yKM5G~@#C#Y3P8+#9eN$CcTD0wH80KHCAxoN zYNF|Tn7Sf1DuxRbMrRa4df9csPT7T-lyr2>e?OP5OgefGfNcAXzi?0|k(K^!3Y|rJ2&&%2qI$ZTN&M`N4Uqm9BQii~m*9+T< zwEQ}?O)GLAVoYLui3tW!1zFD4&|8JggDsph@J~3##$gK$(UFOeOf1R@utl1?ipRAhD#<34$_lV;O%DGiBPS(@%T?w?m@ zn8-9$8z=)Fa2l^#ZR}E!C7Sd|VU>?{AE}d0P15n(`~UO4Uv_)yi`jHZqeePrg$xdL z=36iWvF4>(8hoc+HFM^h4ow!6my=XgR`m}Ef!1IB*4i4F>pYfKq7|3XPH1oiDuc>8 zh*Q*4n}w~(e78eXBv?4MzG!vzL_y&fmv-g@I(6XP#{v^$X(=>G;4GCn*+sp}jW$1x zqFif(D|=8k`&=$@ItuI1CO3EU;^IO!fvgAiOPK49j8AkX&1sgxF~jhOt;OKg9K%H? z9Rr=xdY#Q2BRj)PU)8%C5xUN(nj)*Sft~C7A`UwOf_onLdFrDXR`=^O>L4oGuBR=* z2?==pVzlwY$v2n4n6{9rEiQyl6rZvvDoXKIkactSCYyj7C`^0$yWN&AMgoNTf{Q$c zq7wb$IPD8e%Kv8dq`cRuPNe&+93oYW!@a+A{qd2NtGWtJo$;0XE;XTdWucbLV0h;f zUg*K)1jH{VK?9-%ok~eMS(tQDE`ct`e1h$UhP)DzkDOOokUN_BGH#-vj*0L%_Wu zZp1%AxEMZfv*d{F&(ANYXqdZtyVdfux;cAtw2NR&QUO?Yo>#nOZX z1n1`uYv){)R8)R^*FFmMZ$(f_Fx<)d%yQGaXlcYL&SseU9SRBFM0m&$+b^TWAugf0 zc{yXb=ARa>L+(OK_pqw*^i_|&DlO(EQGnqYi)@0LM(UFlS&Pyxq3+cth#j0f^=%28Zg2?9`5L-Lh%-Y*C z=~Qcy^IzEEd)-|U4n{M5nX<|j|Ac^Z-RsJ()_z;ZribiO&F^^69ogn&AwcN%)L4=Z zi)EN7DJDT%R@%!x(%spY$W<||=rWwD@$VDsk-vG5Vqa}ZqT{nWU&8jFF9((%KKR8D zyV2AQG7k{=2NF@1AGG@G8|Zbpp`jTJ-s1ar)0N#4w_eL+^ zS!R+R)odyL$=9idSR|~q2-7VGfGA3U{Q%y-xIMo@U@v|eCdnDp@F4kXfXuzdH@1pE zi>xtg<3jwB-1z$s1#qm<^PR3IKGb}<#Wk@G&c=_bPb}WnqlE3HUffq;BIGqN!Y9F8 zjP?S_R!xJ#Ma~tqcu5WWr+VkyvxR!*^JV$i{PVyn`g5OeTC(=?g|=JdAX-GWH6vX# zUscmj-KQOkf8RE+n+M-8k5U!9hW|ug?2-WDhqv6gc`dS!(LX=>pTMieEM@tl5W&7+ z8Tyu(^pw}FV+uqRV_&jr>pAZ42MYhc60&yF{ zxKCz>*&tBThx&loP?Wa3TponFzHYg`_H0S}j`{Q3+qU+MjJKI@sZ}CY+uGV<27P8R z^h>IxHI;-lByX|Vh{9tcUnaebPKu9=ijGzP(uBqmRPLQoTJBjIRF@i1>05_&RBeUw zEVVN5wtQHP-H=!mS-W`jy6K=^-(cfiwt-0=U5|uhkAyUko3WrhQC3ih30MDU*y$ii zvXzI0Wy2;jPU-NedVT}ea-Lz!sVa)WYn&B;6^P}wqU)F07Gt!P(?d5RBBm68{xxRS z^Ev_*w2C?&Iw!`rgODyhIE)uUP0PE_VN@)OH=H#2C`MAb9+H%hvw*}*Xav*qE65wt5@FgqeZZ&@aW{o zM271(;G4g7Ggqy7ldrTJAmc*A%($X5`g|BC$Gae+yeu`cpqxXWcqzK21l!yDe}7`J zT~B6jv`z;l743wCI7y8J^r!dqBikbSmcOU+LEkuhid3OXUw3|Gev&_gv6HQBqYz#~=M^T#cuaGt3Gd_f>65z<=)_vLz^y zEAKULV>q}$XZf-6yxD^O;Z_m<&wnK(AncL)W~P{P&xtN}w#D_^dRqy09+silx&1%2 zi!;vz!L<>={{K4&FZ{=1HpjP)g;))QnWl`4+0KXtK;eGqzML4+`rt4kv~7=x=~tx1 zr6mHXn9c0+SmG*o`Y#rs6)pLj$`>OOC!VFKsw(Dr+)I;*7g;yX<Cy06aBf32 ztFa^5w&s)H1wvU&`p{_KtT>-)#ZEa!+L<~xQn<;QoCUdvNWJl>c=2XEn4%9_-x}f-=2kRFMFb+jAu^Qh7xz5V|t%;H!8y=@E(YU(L{#cUS z=9a0l)0`G|<-}n0a#`ndavM7*q2UEeZ& zWlEc)$})PQpH%4$$94Zge&xyD_;9AGo^xzMn3x71Er`3ItML6Lr@V35|B_e5CT+HQ zug!~Q5OG}oSVUi6KdOjS3%Q**QqnE< z{rVwh}W1bbd*^K%5Qgj8FrzJ ze5!6?uox1o8Mnn1l~rF;sjTvkp&_lEvBNcLoPm26YnOO!1`>bERI6!hoEvcXyh$Dx zgwzowW=`+RyW0k(_ZC>UUhPh~B!pWMOy>0D4C{Nok`4_ zw$jYvPqsb{$|qk99T%VyXa?)5(fqdOXaErq9v*3JQ!Fhf>9$77^Zl!Xg@CQ_T-C}~ z6V1yE*82#gn2!6cbTZn!b7`sDwMbQ9G2}{q-UCHVN2dr6A*??>!6P3j!iFckkbOx@ zzwh~edYps!skMzwY4FSOK#)VR-xLTN?hK}Ak}HB0s?J13Q;dzNOwmPXfs@Yo7FB@y z`O}Jl0lztt!{R#y+0DQt&H2Jm7iDXWGRybXuKAft@`1mmB=^^l@Dga&+wAHZ!K~L3 z2!Yg>YU;zLD3ZUCei1TvNf@W{-hah9)Xr zkk5cfAs3ogl$91a4==DdF*&ub^NRVpbMN})gQ66UF_oNhl2?~;1O5@)#O~;krTB@3 z9OL6X288rQ>uYPu$9MbwfduWux3`})hE)*=X*d9wqa**km__G%%LFN-0)Z4<=H?b# zJ46wQiLLcoyZ)t?p{Ldd{*>ST%<)y`nL`5YW8S?)sur26GQ8#qI`tdqQjyE5&m^n8 z8XBD+0Mme{AU3JauRSlA2a^8x^YtuWyMq2r@n>}(na^^BC)NGrbuJfHm)2m#W(FzR zQuwX9;)*KVl&n5l#bcRdYYYJ=G}&1T9>+lfm|zfys?`jrU?p6o#$4R+Me7_43=t>r zT+^BU5;t51gazYxDy0!1U1U)SZ7t1Y5Fk>vHpYVbr$Wp+7()@q$1-_dHswV(d~BDw z(eewsJI3F?eWO%;$#VUrAy!h>!n!2PkTtI>t(T6EN=fv=)dcn)T20sXP|0R>FI*tW zsSG_N<)24qpMNLRnQbr?(z06aP8Sz*&)P!fOcMDj2ogrm zR9V(uM4#dmLF%uTtM|mwah){m4T?4zuFjIGZ4YoUc#co<8R&bIQGG2VF^RGo8mYy_ z=M()82L|j2=heSh=NM5|wHFUbIPW5Q+q;k=_4SM?NxbgLxqJ{Pmf4%nJIDpGe~Gz0!v>RB3WGDO%`!M{~D8Hty$lclT#LrxUQK z7Wj@v-|oAUnd!v2L@=GbbuVv*gPT1-ULs8jEsmJ@`JdQGS!EDIml1O(W7sb}Ifq>3 z&XG6VWyCUJxo*M4U`wjs2MLYeH!=+A4OGUe4yJdm%o>2{_Q%II!qtt3n7(t?ZV|Du znc3O>vY{dF4x3>N0n1Uo$~aEg>b7TGL;;7Z4Z- zH=X36p*hhSnG_&!bNg1klA(NVgSq)5N+Y^>E^6dtg4e67L!?s~*k5sCMak4zq zrOxCEH!r%nrPr90xY$=WHm)$ewQKE|so3)|?|yWuSQ)GPOC831)wy@xor=*p$Uw(y zhdi&AA>_Xt!MJHRwRj@59&qZX@GS4XknQp^zPx44Y)L_T{u9Id`1TcyIchyO&7+-3 z^J1JQqwH+PX_aahb7D#RM1TG!^hJElRxtlC4ieB9lq%3vpADV7BIGqn)VLO_G^;?H zq^UObixS|2e&fN-o?6dPK@?X9YcTJa5X^ z$ELAnJqTUsuXS2Mr=}ek$;kC8gU$gK(*aK7hnLvscC>^napUA1cRsaQe0g8AVn(P1Arqq|zqfln3+0D}2}_yqtzp^stYkB9 ze)0#nd8zq?_cO99rpsx5Uy7273Rc5KBBd=XDQV@z=LEPZjAyWPUvz}e^*!9Mu5pZ!IjUs1ABNe1G+nl?hvI>cH}Er zJbL3$(s`oJnmsQvoPhd>W#5{V->r3z5VWwA}at|9>Yx5(nyeLhrKB= z?LU7(&UOS6lXX*aGdpC9)F+*h`{c9I6v?l97`G1dqM52oomMWO3#I6|^jRadD#?zUizE13!3Jb@S65i(XjOE17`ec7rSXa@YDzy@{ZqD_4jH%m zPfyS53`wuFwC{MYc(!lYn(BSUt6QC#}u+Z<6nHh)bnO}za9;=3O8yk7toZh&ECXH8KvcS0br+`hohW;)?qsK6T7C+oEosHoL zFDU@)5PC~|aw&U!dKV(#vgEQd;8p7L<@^P(ej*y%9-YHU^=k?k7Ess^n?<7+nWgqVhC-nr|V(OpoFz2NCGl2k$`)T0RdDp?2W45?Wp+w)&tVYel zI~7bkt1K+M4E7O~@~`vo&ENjP*(XCM_^pkB=;LlBoR~0&Y_K;58B&loUbs4mwdK1gm|HMI(2#jh+cRVo!IqE-0aF(`6WH9_Asuv#LKrh zSjyxjGK9Dbo1>HFE&D#i$kbRNVkuL8aRyoC8)6TJt>-qMuyQIa=e%K^yMl)Wu5x_K zlG4)3#RcZQVvqg1)z3TY1DJMV2H(U)qq*A{HB++HUAVp5oFX8NZt_ttnyq7?VQAg2 zDH;2^=iYgG`eR`Sky%J=k#SG>D=F(hJnO{l*gww!b;s{~*`qfYec#2wra(QuaJO`j;tuuk5}9w>3;xF_ie}<962wBSa5ku772{|4I%=dRYTS z{OZXa6Fn}j-L;ztE&RId+QZBOQL$YG)86Fxq17im+bUg!F; zj5-J#sDnL3M^An6f+DzfqTaC9&h)IUox1q!gF%U&RqN!|+`-fymYkgVx#{VIFMDcH?1ie~=zm()xt*gT|JWOkpU+9sGysPLh~m~_4NtfniBuAQQr!GBreatsHj4|>neS@fQYD-~IY#&BlAQeKdLbGbW;I$Pj z#i&HjZe=(R&KJeE%gYt~{V&IhkRtm>tYYqHHbt^45dNK$hC%Ot|gdtQb)6o)chcJ@9MDsu|MUD+*3{g+jhRAKNCx z;1PSWn_E!exG|4^_E3J4Z*Z(iEVsS3+){E}7Iv1T&`(eJl5A^i-DH|$lxe{&oAW*M?th<*v<%l$&(eeCUBBm-X%YoYOD;t8di~ZN6cr zYpVkKfLpyR3znEj$ZtaDN9yHOzBe>G*0z6HQ43t%rbc-cMu=h&KLd`rf~X~iy^jHv zDwD%oqwsV$0aDD*YFAvcoA++Aw!OIeNi`?fk~j<&oArpMNDcGya}^Fo5W}!pj9!6m z1N{xF4P|=s5%hnaAsOX;9)Nfw)-|0^<7E{!wsZX-i}+j|`g)2wksqcInNDS5xP*me zV=o?_Y|5NGG#ids3Qb~x_WVxIW>S9Qi52C`d3Mm11cjZooBMz@phg5L{67%7^ z0xp~4gyFVyqDzdsbKn*sc(pm7%jtsu;u9f+b2t|6w*AhKd5+KaP>DL)o^U67(F8%M z+0!qLCdB(6n7E#sRdQWy`pHMt2fm#oNY_jE6#%S~c=thQZsuyIQ#vs7*6Rja=cD=s zc}YXS-~2CjNBI}K3u^uw;`8_G|0E3kT(V-9r?^J(2E(K1TSGnI`$sAZwkiyCD>pfQ z!#Al-W9gj_k1-e}@F*HTep{d9hNi^==C7matio#3`84{uD**uki;!RMq&5N~B_;O_ ztpQVB-ZD^Ac5`Wuq7Utw9E1$-a$42t e|I=mFHmb1_yzfVX@Pp{eNn%Kc6PR5!AyDlIyc;Wcs6q(IdHNrID}B!T=@Ipba3q@PU7d@5!F#3ndqJ4 zGY>puFKq5e-KnBG0&?3bxKWW51V=8p-W&a?br@h{B50^N`zwD*Ps*8d7izSjH8F1x z-G(ZY7#{|S0wDk`h$lBOQ&ASvjQfT4z{k5t8}8+D(J~WCev3|dxAUbR%{8`oziXgg z?CrbAF@&RILyF(k4NZ0^>M1^c`jq$rWjGsq8Imz?(&={OEO#T&%Y{p!LV52KJ}pJ5 zbY@oO!w0_FRj%997dJoxz_B)eKeQx#@Bu3d6RHNBweta)-r z+=X^+12W(?-o5KUb0r1J#*(F^SrMh@O9LY??Z)u&&FW@gh=6bW6o)w?^)8C+3Pas)waqCS zCNc##QbpO3t5|F|KAZ~rY^dfO8=0uwXieiRY4-@#3qE#A)2Wh%m%%m13VlOwC{zWDkIFP6*jnS^tPzTv zke*euT}GlC*L0eJ)RXuLi;4P$7?4WO5H||KW^&nyI8A3dXDcywwz}D)jhBxR(nin- z)hYxn{s;ln;D=L3Ij68v*73DdQa=BBf~kr#VpV5_<+e>})MU$g+V%Cl%WY2c(RlkT zXwe^AV`1e7LX+M?w;2y^n2}m0BQ-=fCqN62n8-d>?Yo6yjAywYrkCi_nfo-HHbxbs zlch5UJj0l)4JpqVKOPntTk{HrnmKLR4!TZ30B=rA$Qc6sAd#E@ox2K2JITpViM(C1kF%)FX6kQ z+3hcOt{8R8f+srmXQ+bW*^(3e)L^E|T`vN>g`#eK*Zbqfiqs8(=t!Ts9TZ@U5Ri}< zJ2~-UF7`@DNSG~Dp-Qf*Ki$-V9R63_Ca?JgA{U%JLyV6<6zg(B$aX9er!`~Z+3I>9 zt2-z0eLEj@A=(&>%P3NJ`@ggRgw!iKgAGV?bTLI8Khb+@npjHN0h2>(Zw? zwpu!rtwgSE6Me=5D|&+f|FCpTrB+2l2HiUd-tYk|?8I!o#1hfN7{S5{yWl%yWV||z zylYo>K|1cN5b=DUm8nG9oKIEvFh?F99$w+Z5|9we8pj>owq}d^hzeWe{7_f7T#@qC zVRl94g*->0PY(*kkUQ5*&(&5vf&oG7hwBqk=k0+x@eO%Y))Cfy!u0T61oq^nA!Pq- z8rtb#jwoT?GA{tT<@8z|wmyk*u888qh8i+YJCL=kTWRJk40VU@CNRd6DvyrL z*pth!-U~R}M5?$Pw*`{B+(AYg%#W0yI#sTweHpy7(pbMLOm_QRvDzQH;JlJYOikrr zwm;oe^2*ZyX~#D$GtvDnK;F?O6HH6lj)#FuCNKwrpX*g;re{ZcuRy?Lk?TDpkE$Rk zkNTr%i&8fuFA=I2j5EdN8AV%hX4wb+J7#=d^;OhDYV zwbwH?oCA|M>n1|>ZzFJsP;~E(g5Zs-EdF`(qL1p$r-F(bk7$jQB24? z^$+^Z)3ZGRRaI3omSPvtQDbv{2XY#4$)qDbi7e^i$>R?;W(+qkZf~2zX>Pj7 z6XlYsR-LcV@2BluU3UsOVLrS4a;AE_QhP>r1!cAT$TTw@WtpzGxjzD=_NRrlcpqSM zR_sHQ!y_a6c#l%W-Q90>q1m7-#v13NF&z*w+u5lug=RML)+itv0@Z0gW3)*11f#Vm ztEeoFfEbuEe@%l9+sAEc>%*DM{KIKctfCU>^Bu*^bmh(O-sp%AV-QnMc}4ndNITox z6u`grl3OOD(ZA*}-5RUVBi(%-c*MsRkkoG)8&R;(7qjH>EzsY^(8R2(a`8*W?SjTp z^ki9?@o>SC_psMyODOtNeP9tTw{>~W&?1boevtj>%hfuH^URdsaAcz*mCl^T=FDm za|16!`@RUN%BaoVX>Pb*<*?vTgr9sJu{+NAG)^sTiP0?uoQcAH**=8n7TLBxxW)M7 zQA#N{cb3ZCw{Q}7>eiY_Y@j>Hsf2d!ip)41!uEk!Hp}-H`PHuPICip7jm_2JADZ2b z9Ep$kmUGq2RdPU@KcgO^&38iqF&~w#S-yjwt`db7oo>zlntKBjQtZmdg^+jy=45Rx zo;^I@WIb?{tJ@3F=?y8VWFMfG*8E_GQ&Fv?@LP5J0Zvj!{W(lrd-Z|cK%BEW_oc6c z7CW)>PUq(&`g%3KRSrjQZ>VCoac*A-_}m$(^b6bZbe>vn zj;2#l@f{vwo$ly*EFB7J@iX{N4lF-+L8VEwO_=wRJ8APdId7y=#T!dGYj)t@3Qewb zLoX?9Ps*8fd97B~hkMoW24eYB!#4NksduOBe?IqMjB`JkPMvX(Q;1kylNN&W*HIuF z1v-uCM5){FPGNR-{KkOlK_5ONyIm1Z`sDp#!Y%Ud9CBM-D-IGO>xz=*QwHbZ>V~I< z-79``b+*5^95?F_m3GQ;HocJ!GP`39&i%ADFW10^Q%pjc7j5#+BU$f^(6=+>DHgiA>DuBWl0vzlY*ieffSN-@}ufT@!H(1c#{N*Y&%ihV^F6k@w{y<6SxKy@fL^P!+ED+iPqBQ8 zS?Si@-mMPxY(5ZjKYq<1%?|!Zw+7(dCq;Id%eNxg$a{%5k@xRO-#w#s6|+l4@#Vho zT$5Id zQxHOTH7wopi!q)zK9<;it7)5pl7_GfkdSU+ini6WEZ z0!p997njiIx(D4=edx|ZVkUR^a!z^2#nB585fNg;nm_7B%Obb8SqK-WyCV7e%O0w6 zUFH|*-rQgb75HJ1cTC7uMW0zF1Nw_#mKGAMDC51IqkZ8kb*c>KV-$T1e0=r+A#$8t z&2n_>p^7bBOQ5rE@#TZO+(SWk8!SuJMCXwG<3odN<(s~g05AT=5A>GGvIdAv{EjC} zyL0^3vrl0gKB2mcNp79FKc5l50!B2AUB2oMuUna`MnoHl8xuLs!hs_Zd!Q&+XN1xx z0L%ThdCg!Cs8C4Ub65O7KK&*2T7|Cp<`c1wo4cgnBXD4@D<3|vh?e;FIgkIwrCn_L z7pPw&``~PVXo)4%e^N;pwrD>-rV?|;`Sw+1KlY#Kwa8UO&eK*>Rll>a?F7|s@f97l zd6up0%sg1jyZ4N;h|k|Y6nP>$?9LdXAtJ4BsB|0YIIHy1J3?yD3Ly2)T3NzN6o2~jLGEe<{U))D*s@XIB? z7TgAX<}hTd^)9B`@nWm+WP3cTOYr`FJ5tka)mwubvZq`>aByD>Aq3$p4Et)TX3rJ> z)kOykKTzxupMxGdeq>6y;Z+Yfcu=2D6-551aZU4omq^a%p8fuP0ffsUc*@tJGJ7p6 zBQ@02B-1y8g2Lh{%J@^VG;K<=ID5N-zQwOyVm#2Tat$YK%`t?ZYE7=pm%Nq&`*C)M zssr?773D)V(;h-P%~I+4k~H@)t@7nwU^0(SvLa*;Z;Gz#cJgr;7oN0&_ zFtQQY!GBIqYL+l}6jS9e3%Kdel-zCfF7bFU6r+S{q=Oo0X!#-kyzdHInW^$#q!!$X zJ34EWlt_?N@YF+GUMGeAtdU4Y$j*`9#j8XqL-02E?OQ=>?TnK~T7^64&vU!#pHqhJ7kA|<-`3dg zgqV{B>h~J%300+zp}7ag^CUDDpEachSK6x`i@evZjJ=`kNrc_rrW`Df_y0_(oz)wd z_2+yU5w zy>`v*f`A`Y`n+5$OVAr0R3QmH5j6Q*ONX-9)fvBq7c%ZP@7k%${M68C=j7k&5X}-1@ zK39N7M1c@bkgU~J)3BSa>6eQsS2Q6Z06m(7COMWg2LjO<+qD`V>fkroR^MoE{P$O) zqN1SF0pC55k8gZRxcxvm8u>FmFEIONe@nECz*enf3#jYWNfZ2Qf)}3|E4aA`--=9zgKwCoB4t_I6@X86J%2C;45Tvt*vH{d&5kd zE#R@)yU(=kbQcZmoTm%6TPXcz4CADaw-@u(ziwtp>YB+8X|WGm`OMV6_T zQgK_`r_c>1HGZFzsoh!WtnDY|uM$&zd@=laI2@?39<8?ra+BPa^mcWeEZQx zYJPjV<6_2898SZ`{(8A#(4+2BT6cvd^sN6abf-Q^gef~FS&{- zI14C5t=a_bbT4$ze;%y?6fx_Opv%v+0=s>q?!q_)&U?BchvN}_p{GAAsEr!X-#i3GtR~%bx%P4tVhZs*_Ovrm1;$jJexb>V?ZRFL5RgCsg+ezM zRr6Z%-ViX7j}=`F+=a~6KtVZx19i5dHFN>g9bj+Vl$2LKP-@J;VXguhAdmty1ZI_rXD3k+yZ;hbRQ$EQsc_*Nlb2F+d|O{T z6p2;1Ggi$2A}dDJj!*Ii<9Yqj(NV9{XM1xNJ0pCu2G<+S8++oCV&j~+jr@!H8qDHlxq^%l&B@_@&S+e9#z}-Ust9*|uV)>C| zckUm{`4BSRp^}EgMYFK5Fovi;67cMkPikPPH0hJeK!CS4dZ&N0K6kvCpmoYpkh`}* zAv3eA`9gtQr^4M&lo9{d{E?&Tt79j`>#sL86-9GaE+B;$2ddM&II-3W;j2g`%Zhu^ z)4`=y0q7(n=lu2HsXrL`QeC0%0%!|{rY=O#tdFOD<>k>k?`fUf9Ss^lAUnO$7N$ly z){I@d3nx?M#`28pdN_x`JLv{$%;y~s&F9D==B%YnS=tf{qmK1%L5^x{kx z*+WJQLz`Q(*x z<#*KC04p6TRGvw633>3qXTto84do|~!3jpv(Pw6dK|W7}1ciCSdlLxS z9c?#Ie-{WA(M~=-q%}hVpY>-%p)xUCYok&n_hMt26Lk|qtn=&pqgK<9I5}~=N}or8 zo^&2}yoqFjPd?fLwTgW3y`26y9@cBGxem_2^*-W3ISL_z{jtZb{W4F|^_IcRE=PvY z$;6J}y^CjY{_IgnAJk)D7`m7D!+;*TJ6)3o@&lHapZ~E;19m1`lZ5~#0BOfboLpC& za~GubOpS`)RXBQ(=9T97?jUdb!5omPPbX7myt6z{5&f6}p`cp$h0hQyMYfEfo+txQ zUllr&%&$g1KHgA{Dx7{!LdZzNQ0sc|-d89r*{7Or{E19rbxhJ^k*0*Mv4X_;ZhdFY z*5YdFP9IVFE4ju%Ky^2{&sjkDw0FBaI1UbD>-EH*no*Mt zp_mdzh}FiuOU#%lH=C_cCiPWs)v!F8ZU>M7$P5A8w7F)P(Rs@JtWt&fdr*HcQqiu5 z$1E$0Gd%EEJ7|V>+T)UrNo#BOF~5$#(jas?Lmit*A+I8_Y{*sz}aLYRS%jNYoUaQ+ID4YFBGbg`95vN8_$o?yK;uuJsmB!I}_j~!A2G?R6*@E3P?5Tn^Rl2+9zPDGT(zB(1 zL>HqZq8rTwN9uYw?uprd+A+~A)Z)lufaY0ecy%L}ZUBbhKheLB{j|65Mcy<;!%%$8 zTPT$|W(xhi)|Dr=f@I=E)w6b+TRV#Q2Ffji+iKM-7EKPXf9&#s?S8x?_L=4xjOymb z%kRmyfaUxTOn3DSH}ca;v(s(_VBZG!^OH!H41dmIEQI_6Oc<};jH2zgs%Z0~zrht^ z{5bx2-Ysan(IHwt&;UfwqrHChp9*>R50eby(y~jtYS`e_mXH4$VHP{t3v&OqRW}j+ zeW3vk2#j`L7q)!{J{Nbqe|;tUREr?3`#)d*ADYvvWZ$E?HryANEBaDa@1&eL=)G9aGIL&;xKk^b11+?ull@Xy2p9jsE!E(SpByl~Qonu2 zJ3V8!IaMP+D7Oad8SQl$t*lSdDKeQDGF^bRx3PMGIeZEZQh_EcX6??J@#98nL|2T% z#f@|F)$FJV>-B#ic=&0uQF#N&Q*%wtA?W99fXZf4QW`ZQt+L%2vmcEU1z5;)VuGlM z1mSF^e=F4mK?NkDdh&N$2El2j-v+jG)q;o3WmibR3q>WBuY%MJ{DwV2KGCpwCi04w zlmB7?oHxsnT7cv1L5F&fHTTBzkzZpGFT_ zQ31g0xJKGEQ0=l%LJHs25%5Sc3rY`*R5?@=<={{u`N<4QSsMcxCihm?*IChY$1|)& z4CN`{)+fUM`9VRqw~hcmsU7Dy=Ut!2#p?8LN;jkB*3Lnl3(T5wV{+2nZh=)s`_ za;F^Dd%y7Y9n4OAJ?JjKD)zQ*FRhWq-=)%l{i*Cz@Jcq5k}z=HwRF$za?2@bdsRBF zUysulW`x08ZuX$bd|flL+0LAC5(`1OC6r+K0^FHX^_<%WyY(~!^Q)MdN~C~M%YW&g zJks&KDLo$Uc#Xt$4*lMc8&q#6`Ji7&>^Jj;X+VQEriP!Ae~`ontXyTx!oUuof;iX( zKw?bs5e2XHeCGC3{P-+J{^R7UNhu3H(KzGE8XSIbfSn?RDx=Jye(w^&F32Mwpm&=# z4tTdO6Xu+*sJnajM5+Y9kzgPb81ugz6^8nFxvV7?*ImUAvYn|mW8}+yDnP{jx$0on0K(08=f01gGSqF1xVW?CD2E0FHH}m+nqWWfwN@ zvS_{E6?;18J0fP>383LA2Rgt%S4Q8GMerKKYyZQ~S!l%VH2oPZ$BS6o;@;)3=&7TT z*NwR0LNb4hA7VGRn%P0G&rm)GpF1S8fpTN8YCQ<1x;;Sp6LCW&zI=u^q#JAX&zxj7 zzI9_Pe}B_hMbdMF3-ketXTS`af3V;h^2; z#@PYpnpkf3QQ^1S+_e6T{^&bedh3(fTM#WnIx%L*pABjUM@1DK+emA8Qab@R_@puA z)8PFpyV3FC-HBYrnVq!}RdweEmj$mREiQ*FEC1?PYmmi`Tw61(gL~^rQd>Swlm1lm zCX=}HS|gnJXAwFWag{(*_)GRpkw0Nrj)igj9yYl|^X~PSA=x4^pw=QS?G0b4LX+e9 z;yiPm8$!_Xznlp*wdi2H14^sX2Ai68i1hX{IN4)Au{IPuAY>nk+xytIZO%K$*hqnf z=MgqAmOFxYFjv<%SG(h+7L=*a2oL~e$rdr38SnyFwWxnhst_@@eEMvpyA1I<80qmauBqk;gLHj zrGe?*#=#B@W)T%r96K>#X)PaaH59}&w}yt*`a*mBpSDFa#F=^Mh z58kfKN~O(rD7i`Ga)PbbVf}+nVM|^nREyK{v;TFSD^_P$mxNYa{0R5Q3LN6ct0JylM z&6+^ie5}-XWhIZD<3mVe^_+|LDP)%|$#Fm5{=G@8gp}0fLtk$n@sVDzWAJKdRO0%= zzD)5lnvf`0=o1K;ee$_CuO-I$z=88nmO}u$I?TImRchjHX~uEc?&n>uI%9k`s6s(= z#Q~&CxMtasuCvABSBEuJ!<5zFHWBVAYT`CrTEO)>s3!`jz4qolTuklE)@xx$=|G~$6l6zo8BL?3YlZq5?r~U8zF9Z)W?dj61&J#2i>9bax>%slBfcFH_sp-c zA9dUEUiu$W0o)y;+{m{zmK$-6>vF*^(H|RM%W9YW81S0O7TD9xC`+HjP6jdtXIpc5 zn)aX|8F+1|5vK0lYpi+YwAm-sMhNGgUn-FOpwmKcraG*;M!DVeQ}E$smD!(_gx2s0>Ti;wIljSsl@ zkW`J?^%mK)(<`1-m7IP~*1BgQH5fq(a&lD3KGb`#zC&#;)syaQeX-sqh<=)F)K!&x zgpG|2AS1D|lF>~WnFaql=%nceUV>2bm6w81XmBGa5{?YEFk2|^8{D2K6=mOKwD5^^ z_4_+BT%V4Nva7-7qD=#r10E;2kk4ZQrfk)mS zupPtDqbwZ$3d`|ok?pKtveA(dgwyKU>eK^L-QO#^<7Im`&mM}pdzuL3ib-`vsx-L2 zfXwyB^pd6}F^Pj2yAREk8XW&YZ_?8?S;YMTo5-tNNfoVe(;Kk1 z{EM`o0L~#{R$J=H)?{K5V67q39D0tC`xKlj*)4e$`h}M#TmO<4c6Q}7A!NeT-QT>N zOW2FiLx4$os4SrLFR-5zBkm*MOEF8RJwEm4{`x?|R9$X3p@+~?XDP@YoAJ$LGLPdn zQwU`fQB&iR4f6Nbf*YUxS=oq;B-qsdYE=cw5>0P4HZU7g+;=dGHlB&1PbJXNf*1=Q zI0ZHBk7E7K+Z}#9!o$JZPn2~!^!+dShmTgW2kD}gR){1J{`X!1FL=^m9bzB7us97h zU106iF@URb$71oe=&_iMl*v~G$qAEHmE@fo$#JrZ!hRARbvhkvs9~+rXxzgn$=pc#-#^-=cP;GNp6&fD<)3z&;r-I^3pK~ z*CSW!QKG^hGPYBeVc$;a`$%NF`!*%z z&FRSxb+PqbLs@f+FW*QtWN0<6_+BmT@&g2a1mZ{rrJYyk;moky(10N5$7;G_XZ9Ea zB!tgS5f&N`r+#M|#?U5l07XU6f{W5&N-Au>q~6BCqPVaTASy047ap>KwPdV(oq zt@W(tZ>NYWZ}-c+9h-gM*>g2VW%@+NdvyAiks4)=MnNiuF7nT*w?>!+YkHa(x#S^u zpzQe+6Ee|TI&ZIi83L}d$kM4!@(te0Z1g(RE%!)fS8(B&?h?e#InbATT%Si;T9!(| zYVccV>gUUKMIdruGugABmErXwF)_g(Dq5kS~Ojrc81N!eXd#oPKT>*PFAx#{_= z1D?(mTo2zg8BE#})NPp6UUH?s&_(!!Ba7?&2ac>?x*?UUUV_VGyQfuPnDY;g+&ov5 zS8xK)s4zW<*E}`s>)BMiWF|)tHuRoI);&cVK~KID0RumodQ&OVA2v;gJ5~JyKo0Do(n}r~rEW;MWB|Zoq9?9Err(vb(+X z+RlZy1Z3?#+Sclnw5?eX&7c)sgo%*=;l)b=-i~>FT4tcM`lfvk5*4M8Z)rKJqi$qV$U&@w_%Uskoo5ehkSV=b}wfOROa9MY=+}0+qv&=;q zV?m>r%2!(j*UkBB9WMY2**zLTU$k4jUf7e#~* z-;d22qkhulyWXGqNG4YO@Zy!i<|uDVd*LcXY4s2cfZDAcBl#6z9HlbN0f6Te%>{+? zfuohz4e%}sS_2a}shlnT0K1v_cT@h-WsWdqbh_+5WuY88i$_Yl?gnVHx?y(=$gc;|8NtAp6v8yI>4_^}J#A}M=srB5wo$;rsXFkpaQ zklD-9{{dqQ{upmbC!H!YJ(TtJXpX)O<0jD*v1U5kn{XctKK?@ymT?x$AwjZult2jW z=UYJ=K^{gh(HIm|mtVHTDRrIeaFaXiBWj_!5HfoSvdtfNe}%_vpD{jxN6p?yx!|LZ#H8)` z2JEBg*e~;jU`x1K`mi_Pq|6e0g+A?UD;+LE-btz7 z4f!hJ!LV0teeMu)Yuq_Ca39o20FbM(p3%qXyL||p{WfQNnepUJ2$x2agWq#m8K7>t z+`va^y>zr)4>#+$#rP}6Jm@#c1(O?f%$6d)x;e<-SQ z+l8O^gMQUaK%c4Y=6nGtK9O`d)|oGb+PCHwYtsd%UCOP1dxHsAWub+_BjMxQ?->XR zFapO&Qtp`n03N2*sH-!c$@`W;%j~>ze;M*G7I1?H%CAvJ7jJ+m zO5p6=@t@c{-|eGg+q17-RJ$PK(Wn4Ys}tr^+IOg$`M;~H$+-3sfDCSYfVRWu&t3R! z`Fi}Z+II6o%KWg+2~UyC8M@C`rJ}{(M_fhhtlO>oM36|>77Q>3D8{Q5BUfRn0q!Xd zNyv$d`;r(F0&!STOqV~i`@chp2#x0^vtMKeSn z!Qq;CrdVNWa@0z!fUCh^7#I`dTcY)|zToY+u~xH{sNlUVXREQXi8^mZZ1tDPK~73i z_0LKm^XMSsb9)<+#A(>^S1w;gpjiI_ItpA?hM&L8>Hxg-YUbKzfGnLo5 zg>)Z=H$_Z0NP{CTA%VwN8|@HKTwY*o?65m`F&Cf#h?Rwv5rGT6-QAz&5nSbg4^_AJ zV%z@=GLG?a%+e=8R2^}*KmbS4LH5pofiE6Jp(K5sAm5v1quXCtr?E@8AN-f<&(8Er z(RyK1+p^CfH3<%=Y{0TJwbpq52h0eJTw0{V_~<$jHa7_x0JrV&nI>OsMn*=oX-x%` z!xz=1>Mk(IfejhH1`0Ph@3C!p^Gj-yN>U@1a~>NdXl?SvjMw-l9e+8EY=q4_=O%C99Ph1pjK2(*brG0l}`#|js$Ut~5ur>LModue^ zU}gITSe$C0PHeSy=5Nhpj#E2kIcGc<v>L9A_wa}r}@O9^yIroCsd}+f2RG@II&S9`Tvdn31>HRe&;xuITWkpy zsDY2BQ`M)0HHBUlbD*XDBqY-Cy`-eLb}lZLeVI!$BRQ)SPW2YA!-@K(OV~6}Q-cNw zl*vpE+rH$cCW*4;RcubFrAEDTA}f#ej2GlG)ozQozq_2#{0V@1O2@!)*ZD+F5H9;Z zRr`&#@p4IwOvndJFIi4L`qaR)4=@CmCOPPr*3Ns{sLsAI25hsv-KNmgdvR8oI(2c?~^{bV-9qFKAfoA z_nhB_N`WlYIh!5y2QYW+)=5k5af$!08L_eL+}n~xyWFooeg*drNcb74%xEXno;H(+ z^-x87)C2PCR-K4)EPyhaoSj#Dr`_CK>^GD|1A=ldhGDq>6Qz-rhbJ?jg2e6POp=!u zw^Uu17S2CEYsyp00*mQfT3Lm+5N)J2iIWsVguEP-x4?9b`V4a{PzU(|{N;gw@rs7) z3m(X#N9!Pimjma}YR^{`TwI20Kc-bwrg1j?ae{?clp>_BvEYDZxkl$u&a(AB+}E` zf8W!RqYoW59}D0yv1;oo21&JdQH-9hn-*`D#&zkJ>I=;RC0eonJ!(ZjFC=1Tl~N4*@IxVY!Dm zX28w^L=AaRZZLS7>efAhQU{l*XS?H0i_NBh&Z%YP&N{e4fY~Y~CMvlxny_O6+e{>8 zR-3!jmMvwQBL@m~Bz_m?4IWRx|9B-cD5*}Et=ZSeD#{vMC0o>TL`KSQt4P<>FRg%& z`sd3&BLL0hRWM=P)0kb`rws-e0Otjr#NL8!)9C2H>3esfqhoH29r&%QWqAr}us#LW z&V#*!b&uUlEB2^tf`FmB*^kNRc0wsW6j#A~GN2~@@|Dj>1&~cay)~N5i7)@S`$oq^ zM|9}T8!^AIzUz67QkMJM&hw?V4pAiHVS2X0hnDywB!v(g5Zj=GHF59b{-wrIeV1?EJtD0d!y#pZ0+u@?qA4 znEYZM1d`kQ*66<-0bn(quJKgHkxV?l1dTY^Sy=)CBxb)%s!SIAGnjCy_q4xhs4|1{ zb<~aB|ET3pTuiNUNNvxhqwzRyj~T31H&#Y`<`Efoe&QVv7Zm}>@t>dTqtjpOw$M#Z z2oA$t=R37Y`gj&|-0UJ+(}DZNmttZ)YK{k5_0BHS8SzXxp-Ac`3%|q)V+PD8+JTR+ ztfr>L*JcZQb93>cc=W|e2Sy+2l;*R0!}AHyLgHv=EcWLTj}r|O*L`Jp;=(-9mWhUj zYN7U<)zNqSN&z_gaZnR{>wpmc^XF8ReaBop3Lw_HVx-1JNAItF?PA?cvywD7eK!*m zsXJeuT3l8EHE;xaeF7_hhT~Hc7HH+tz9NeI&&BJh_Poxq0FsMC)xHqSf5iS|0>2nI z;6p7g{2ebXZ(7b&3>6G1{&d|}(+UIZoeuJwN2u^ahca=b` z{AelM5G+f9n3>CKwOmqEHxZX(6HZ!DceLP#NIMd z*kC9`AJs`HDlxKfMLtJV6;~pE5~}+zMCHDNkB*7z?(0fNEFh#W`6w=zCrI@7+k?al zj5$=mRpo3y{D8Gu`Y*-wC~0~+DD)Yg2?R+G$|yyk8GK%&%cEYljSUw+pA@r(7BUKY zC(uLxK3H6gL9U4IFI~U?;tq6lbbxH4Y*`QNcf^Hua??C&nQA11jmtV3pXZ1I(KfLW z!42UBp_7SUUwwR?V);T!!9F@`-6tN)P&hAQh?9xf(NpG0DKB5{Z;`&sOhO705|WTi zB3ER6WDYDUCl0J-jO9%_Dxh@;j37{*rVG~TY~j538XCGv?rj-oC>4UsVdx{*HWLeW z-!!8R1{0D##LL$27z%@TF#n~HNaFY#1G%ri6MEM%IyyNqE+RiWhmw|-iiQ@%V85Ro zi6{^D&~*3F_)8C_Q66sM!2oSSb+S5|W(Hm=4M8bcO{IkVjMfZ+#UGQ}J&fcDoCP+4 zCMV*f$XnuXxu>t|z|*GUz)C-6>@47%P-P)&FLYh|{aGo?U#QbqkhP8PXf^`j7Sg&c|8>Znb{=*frEw~S5LM>2U5 zDyp87(PBbsf|@?p>R?!@{F?#|P6Dw-r~jN)FtYzMfS*!{|L4K{PeSqR6aIfAOBwx& zu<|b!@c-h+{5LP1LJGCm0ankyxB~#y-~($RtgFkvcF0eUM1z4TL0_S13qvOP{ftW5n4xmGY$222|&(@_NqjY0diY>Oxcx&&IL z|GnVy?BD6@)$jJW7sh4p-;jqrN0OJ+rg9c#x^8%eMv|=jK8&F&%!-_zTUiUI=A zdOsNZTiof8#+%)!Tqg%FK?L4~9{Tn6WOhD=x#Z{NrDYcBe@&YNmgg7ys{TP917H8l z-{O~9A5t#6AIkP^gkU0-=?qLHyTDu1gD}=49t()-R~yZgN);OPUy^0~1y?`w57miZ zv9m6F@yeZJMd$iMhcQR++Zk(DX;4yQz`~0EefByetwjVB?%95+^t-b-^E? z7K6SRu=YOegH9yDvH3AW>ktK_Rzi>h|*U#x>3kdrH3q0V)@l0Q+!#DII zYHOsbvA$sEz)ge_G+9bBv{*lkhIso)3pEAw4)jerk+Y0|nAmYoqr|Ku{#3(0pEHN~$yN`Fu&YfKkv5V!*F`QC z?w)xV!OZVL?&Gj))hPhPF+L_39vBXa@s&9yEvQ~&a#FQ2TBG&NB}gf!dNbL z_ICGTjx%iiDYPv)z^e znpu7#ZC&#I9JkPK_XhjE`|mbBuNp{5imTMSHkN3~*qJ58RBOC*kq< z)tUR-n)Tfhyc96u6vQ12SB+hizJi!IqZcwI~G^MKtk6mzG3I3Yy)mFR{pgUDYOhf4sJB>o6D` z+~59#RJtVA{ejt+LYz`)|yZ5S#6L2~kJnZG~ zeIwIeE`bS)!$!gB8oU7gpZFjriRaO6os#vQ4lrfAgP3o+TPS++r=N*_mLixc>7rOH z+HnM1XonO+m_N7MLGLdoiEY!YShRcMzox1Svf6LHp&fK zjRl^r!x0}MkL1x};|^CQj`;kB-ynmQ?`-wcy2`RN*XtGUJn>C+w zG0RYkby&AJh%7W8`9;)bd2+N@$42IQ?=?F5K_My{_RMa39R-2jSIfe%Yu;?G_W7)V z_U3`0nVqi8BR&^v$(M4goa}6@#yQ8Mm*%ooFqGl~BX9sAFr~4DahWwyRSh1-Zg{i- zoTrRM5#|TghJ+9c;CE7I+tH~RV=?{Y7k_!{l^ zmM#KTeZ%lLjv^1;7aS>#Hs;9A^yQ}VWCdZMpfvv4vzBY+pyA3XU#+2%n8=FUwap^dhe%WH2)RGBRmiV`*;j&Cdu z5GrhK*7WqL?m-fg@Ta@f*KMA2-Qo;9leyvLmSuTZ`k3PeW8K^?X{Y6YdWR}S#c1G* zaN)Wkb^1qbPdtIuM(=9bcc04%+Fgn^r1_D0+l&AA>*|`I#9NYT3V0DM>CLh5r-fk1#9CUEo;>yCpc3bTjFa@p`)$EN2mNURIO1t#2SZvZ=@1d z=z^~`O;(bZqgAL`M?>E|WX)5~ebr%Zj0J5A6DzDiE-KpdZIR2(ZP9B`capoVoPvXQ zw57jkV5vEZg_l`y0aB{AGW)Y95x=LKrb7h!Ky7M%tXTiDM{UZ{*wA6XSh=R-`;V=q zsn@BXT*euuK}%LBqpt96vwde02(zqcnvR!R88Jmwi=KASsuIrf?eOWwL*7?;OeVrN*aLoG^UCkrjQAKTc~f_ zjkk$hU`qaJoYjVioTj%7RV7*A4uPxQB zZ-_|9Dc(Ni63HW!3Lu})`E4D#Uhj zWhH}}vbUOlWRjY?+)8LP)ycp~H%j(rfEi@o`y zKmsPtfvw*9&+d;1G+ppQ(9p=p1f3gwgQC2RP8q)RInQq=E_*u!vO&}G-M=a+m~XmLBpzOm#CS>QJ`xHzclR4RIh zidiFxo6Ml9ag;eIsLBQV2;RmWDR)f<`@_5arh6bCCZQhwGu#{C#kE;2m0jY6oXZwU zL)mT4@fF{#vqCLrO)uvI+SS?+oYp&4tGj1=8Vb1k`*d23XsF2Ur!luxIF3_ldEKHC zechs)8z(nLPIHi7`T3d$*pk7pR0m*tsY$$TiyEsGxvLdCH5fEoZhlXsJX@=Me~XYJ z!#}@&KoW=q7=WWnM*L)C9cO32xGnByd+I=Va%xV+n?QAS4ws+TsBf&_Y*eVb^ZhUx zz`nVu=e(1mDV2|qldGLxK|!8=*`YO63N2(lQKZUjJ9A~qHb0ou3A1w0S5Kp+){3TpB{D3hADDbsVIKN-hH$020AISP_E569ll#l`m)}kOId1O6v zO4~foXmu5%n&v+Z8#!yeo3mft$!Tv+w>zqsJ)3hF761#12@9|>Ls^zWQmksir^PDm2LE{bd# zKdK>I&Cb-(+@j-PgVlkjCc5>dG1Ml$oJ>(?A{aAfOyAO-?j4*BF3f5v=(&=4mF-Cq z4H^xOHk{mVs~%T{H7Klag|ofy=JxIylIn|I6_{WRM=4)AtsbAJx_uPW@Jrqt_qIi? zGvfM&R8*Iv*e1bcc*9elWhyu7=hm%7p^v5j|9%?}V>uBQ<9KHwKBLtO-OX^sQbGNT z)#-3V?PL>6Q4-cwI)Ekp04^BEqD!2pS?;Q9V9;Zpu`?ZWRsq;jjS(FX$90woQAzRX zibKphvYyAr5`1WgA+Mr*`SDg|GIY|Q|NL_gdyZ6M6m!!D#^Rm@ z0#Z^^Vg|~nYt{y>Ys*CqWWIw*$UB_6QU-cs*p;1&pQdxxyZ54noq#+#nUI&;LQrsqM}(PR8S0w6G<2 z(rEeDSo<(WF~wxa40jb#^xgJ+#tTiqgZ{IZ&Ps(AqC*9$WU=kXmQalr1UVw5lly0D zUmnz6?Wq-vf9viz;{6v3IF%Xpbj#1kmmU(oTYAw!`0`RjQ>Cre;m_-4KP<7bvgMNZ zJ2m>V{I7K|qB0o1=V%>S_Bm3JzL6t}dz+84pcQAXcVs_cR!cn9(EfBk>|oq62y! z9Ysm&=lnIMasqypOj6eHl>Xa5oi;Zk!Lx302|dT}e;m36u$Z>gzRXz|=8zj?9aVobSbaHzE5vq16KqH= z6Kr#N>4lEVCkIkSYz{8oZ(B$xI5ifhgV46$2HJ!}wuTlw^p+#4o_i8W;jsKvRyevu z2y}`4YOFocC?Q4>6}qoRuUSpU*Zg(y_v%@MNLxhf$jI2<3viMG8!?s!QX_$PM zrY_c7V&i4>tR8yXn=rlI!;@nc{gZlofG9W1!D*-gtQ25+8E;Q=R%x5{B#AdXKa9{N zDZu)YMb=S@vRjS$5rK7}^TU+?n>PA2rUnL2I+T9MSV;q%&A#wFSS>7ZH_$ffIx)QD zP%^jcN(t$iXl40*CM)j_;zNjrEdNY|>@YXEI136WAhzwQw*`5VcKnF0KmQfnpp#7A zh_AKaq<`po;a;}xF3bVFkc_gL>1A|$)*g4M75<9HbSt3}n;|Tjn2e03_9Q`R5M^S{ z>3nH#pX8Cdt{%egC;PTw+{ojD{6blgP_1QHEAH8TnJlISYQ){#`H;G< zR6pbaXQ@fnN`uXjvHVg#cWcHMxQlN<(P%2wHm96K>43{BLyaPKh83MQfhFOzIe=!u zj23v9+nvGk)W*lsCJbZ)q=B>26e!QZRd0*r!kbTxu+b2&Jl+;b;=>k0Q#ItJ z(xL&bGg9*7gkl!Ef}sV%7#7`~xYDCZHj6rn+$@W!ay6?UT@g3~-pRJE6ol)03wA&- zQKr{wF;`Vrcip|w&+Ht^Dw03)!QZoc^CrMpURZw3-wg{9Q6S6>M*4NJ$!M+iiA{O_ z^>uWE+JWYqYrMY-4hqHo;mC$R8p8v9y!#sSJ`N?q*o8RJhJuyPM3wbDH8m;IFjM5@rY&OpZFeQ!Y)G>I}xM)E>~G=~La~ zZum@G%^KMmW;D8%>FESQ!PZpx$xvuM)*UXvR!YBZ*?BSlmBrctRh^o_2pT9{Z(igRMWITV+6-$a1?zZ0k)x~ZZNHe`%*mk#E$4XmEbADe(J`N=E zOoLY7h=`1ks_S9?M*3tP2JQag2%hj*wX@CO>Y~K>c+B3OUO;)X92?f|+CY;h54~H1 zpdp>){)J`aec~^ZVT6v+y+s1CPS{)Li>=Ynu2{znz3h>8rTb0l0tGIJy^XV6l2qow zUXp?lTe)#kWH|QSibD`DQ=f)fmu%m@8Up;K6XMBekwwsRy0!;{A0%`{`rA{Ut;FCN zMsazE2ABi4k1YwuKz`<3mXI8Fd+ba@rOEyF9gKsn#EZDzL8Z3QeA&r>O8iuq&Fu=x z0wvu;gq9tK69Nt)#Y_3!h*jd=`{1+ZPC*zLehszqg_?;7@8GqR+A=&Z8~>cqI@O){ za-q$!8LM=3#Xe-$ygfOcfmdyrt%1)povsm+3chf2m6eoK*OZ-aX-)sLHQu|!nZkA{ z(bsbs-{hx*wYO3!5g|94!ggVbqw1Ji8=kY3Fja-kK+nbGGa(lCV+%1y2fCvi))nJF zfyu5S<&p)pUwBF6=pML8T2^=R^kc^haNc}2v_vu0na${mD(ZJUTe_R@!>F!@)l!96 zBWxss1W?gJsdJ20I&Mf#;eC8t-iITNw4lEWWG$C5UET7*-bhI4^y*r-eCb=h#`8+q z88`%}9$^-kMD!Le>a&Ff`e}Kp1GfuQ)^G9?Vm|k?U0xH=N=qW$%QxZt%Oh&4Ar>z9 z9v-PzjwOqDv$G&kvnswbo_Lw^`%b18+Zn6paN(7USWma{WTnFnLjum*Gm1}q*0PLm z=NA#`fy>&{afg{PB@6vSLE(LLTOPv^p7u}KzyAK6fW%K$Abl@ZLH+&jN9$!stH+za zURV-A8lqOB(aXZR@)<@*7{K|0+OdBKH}Cn^tIymC%jR_S-;gT@_Ml_XeEk@O2FRUE zHa?PQ7ErKSNdJ}}_%P7|wuzL~38`Wzey;^F3Y~qmx`jg`yzsafT^mNEZAku7$P}M&}9JySQ;{Wvbk#&x_ zL`eMiQPlO%sYpo1Jg?aO|2{-_8C(86TQ%%C{68m;I>TBa{&iub@Cn`T-v69ki4TSQ z|LaTNAm2L>=;{gzkN}NHz@yXU?G*py5t>pQ>gn0!*`&FnKxJ=dmvz{oASLz|g_Vp? zay;riqqh9XX@wk%8$oiZzi5DaW~o2IZ_74d!Wja476N+?4$=%h3Qo=qH$7%?D9;kX zKRJwyV#cIyTsbDcryC_=h$g_}HOHM`IF(}HHxBrmp8M@3ixj}M$)ph8-b>b(w(Hv!`V#we@fQ5#C zOmtiUP8;n4ry+p%Nj$yJRiq$?p#52wy z0C&`;Ak~BXbc>5o1>0TVD<%GD2r6Y}i}sJ;rm_9=bJ)LKvPVHm^#}Oc1mHemp6)}; z6L_F*;B_~M>19ro+NfutG3@;b|L%7?*Cl@Y_jFHwr9?@K z@m`GHR2Txt1r7>2K2eG3bi=W8J*@o*eXNYvC+q`8t2@XrgX`X(s%Y+e+Q;v13nEbX z+yMarJ;t$Bs@Wed>deBO!2mRr#twYru+LR#AFG^QPNvG59}+gC*?`M!!ubk&+}^rK zPDyjHgN7|Ei9M)-iuwHLuxaX$IOe~C=l{$X{ zm@qo@rt&K{@)eb1xeOgPBZOjp%@Fe{l_=zh-D6|2+x1_LO-mr)^FFcDhRin)l%_wJ zV+W@~zRgd+Qw|A{A58q9uB`0Xzjo~ig`bbF=GVX>pZh^kg9P5-Te}M`0pH_y49}9E zk!!u-ML-9DN)A)oEB>95wn(Ys6crB-PjLJPLzR~MuG8EQ1r4(X2zf`W-zOm<%bBLb zyX@VO5ymO5yV~mMUlfvBKdOe3xw#doQ6#IaZ+Z2Uc(_>T+jM9U9C)iM0O*5tD zi|2_CIXUF;7aZZAN3%Zr5YPy6_620#1R8%LzP9Y7yj#)IC>KSDvspg#uqu-MMZ9(X z9Z8D&gSZL{U3?yBpZVAKCpW%>Bc|gdaW>Y^EJE zG7=a{;d(K@50CLrgev(0xmP?&^!XzKs!cCQS3Mq*gI;Q7s@DA|mlq@36jAa%ZA=ri z$f8`0qRJY=3g^!5md(DhY4ymZf9s6)o?MOFrN1kz%mgcRXgQLP2P#WXY~Pt$xc53P z+sCPin*)2&{`bojPM`36NhzDD8D_hZ&{3AbcUi(>@hMFDrPS+dTXG#LdWmny>i8ce zCGG-9Qt4~;mat_rO*pzUK@Qk!5IkkI!ViRzBW7RU&Tw_!^3!WU=16pX>v*$=sL^XsBdj{2Wj)G7FY9 z|H~`%=|4GmDMMN>qu(pNwkKL6K{0&q{`lbCz^wP>`gHxI`S$CDhpCrlGZG2VCfOj= ztnZC*g!zvifux|VOaDYd%f-5|tyjGeAgdU9m1KwXJ&xOys`V|UA}aOQL&wdgo>)ba zexE+u4ax097CRJOpbj4F_r$c|)#)GU5*p-VpBLg zgzOtsiTPC~vdftU^+`FzRF*oe&U^JS=ZA@pH(Gq&tqW12Oozw4I)-k*uWd%;(1jG)wKI10QQ1cXL!)t1GA2`n3>kKjNkC9ilFRUO()fLW_6TbcHHS%`hq%8p2RpoW>aL3ff;|vi)%Z>JE{8aMba4 z7@%St9f^G%-rZ45`r`&qL1tZZNI7$<%3MH3tz7U)uGyiDAf(Ozmv-=EdStrxvS{GS zM@4Go7Xyy?w_#~>R0-8Gqi#3cN4|?1cfFL@I?vD=x~Tb4J~AU_Ym$ys5A2EuT#S!-JG93#5(?G%#llk^)igcWYYxU(Nx79Bj zpNMZFG+H4h>tv%qais;b0)z-YG;Bf+fvuojvPsvoK~z=l#dN-861>#TI3|xVeg=g< zZ0|V7I4(PYw}ypxS6p;w|kl5@NHcW5VNo#*QF1+j-5MqYER&x;j% ziCY+LT9W`LzUj3qnefaPLo?OpS2o?+x`xEMc7;lsf)TdVNsnsMxYkX2y>akm4THM2V1;@v35aE1BLX+xykM=g-zw(uuU-XyMNh!$5Mg#qgY}Fx(k8hX zSbG_8fvD~)+w|*;lB_XCBg1g7ZSXJlg2O0cPBMQAsDtj z`^&%`o_(9!Ej0ZmFv9a}U&i_4G@iXg)z+&k>RD}>w>>`xk&}n(-LA(? zW&=u;kuB1zQC;j`V^O19m#U2US@1cyXioGkfme#qoc3DX6xD$drS8OR|`BjP># z#gb^?Pb52&KStLx=G}+f7X$|j=~TVR>FLWWG~-mVU6E0jV?DZ~DpWfzl={88gBlGE zy_XTSLqZ4r7t4aA859xaKWJ}yQ10?IP6ql=Z|$>t%wOn#{O& z+Tpn=f#gxtXyRyg-L&*@%fb4l)!NQuLiAdV(SyALp+w?=w{1iI&zVjA3)#h?A`NLf zK6b(??I%o17%i5C>u_ll#wePrhV!QO>3~+>bEptnBeV8bY1_ynFHxP_D2Ak8AdyyMEQ!<$OHN#(N1?0}p0?gE_Y~R`(LY{}M5kT`fKDgEu zQ)a?q&}k@Fs?rc>WxVZyC~ugY3E5B`72M^HYMN($PeyJhj$wQNx+&#=3tvGEeTa54z+n%)mP%kCbLTo)Z#l z>EyX|!H+?>3vCLmSceN#C)nc;G2L1(@Ok;k$1`=A^qh3`Oez#;Fz$jTr?h!M)moI6 zKSj3MGP4JMnVW~FF)oZ?NV7IU?i!bU9J!RbvY`&5*x3?j&$WhA=SEM7k9D*(@~2T# zL?&IJt)p<#ax_aRDhmnmx63gxv`nC)8me$0O1e{9Lcwa;bIRve*Dz@(0p^j1(P-o$ zI}{tpLxqu1jmfu{M&5P9zVu$f#}TQ&!|7|BojOSM#hv68iMm1l93lfBiZCOb#m+WC zP8yw0jDpBw!jCH*ZYo))haS?WsdJgnwa}U4kU(3^ zEK?l}Pbd!3NuL^jajI;t*ONSAWSwAaUXgWR7o=Bj@?`(|mW0IVMV2J$v8*4r^U2&k z1R-mP%$R85lUKd9(0Zc+S|55Co1BW__`(Y!%a%{j};I0HVxPXmasukzFAGu=5Z&lb{be&vziwqGys8uVB;8WLp z;+Wbrn-oCmXZi2}Rhs|r!S$Qf-$gbYQn24~?z==rcq_5bbAj>%GDjFLD-?$>?HD1O1Ab)=7KU( zuzI*j{~r2}@WsLChjh)GPtB1gUY|Jm9A%HWsnt;(UGO{g)#Nl^AZ?eH4f;pXrzmB= zWnok|+8xXLG5X5H)TI$s3Kt~gt`~RNS*{nnF(l3m$!Co}3_hyw$tDXLr)9|#^^=jQ zg1}BaapaYkHbwNU{7Nf17B=?AP-3A;$0&b^*QGPX)flIBA+6>LtBs;VHR~7nLH(+T zMoPr5hoxF8Mx^DbxwXwpM*$U<3)C4IMlmAkFi;@XRivQV*!oEV8JG^5Y=3@tpn;;F z{7dCSm3huLhW0+fjz>KILH!eR)T{U`dK%WA?^D(l3OOJdW*eT2eca-gTR`(t7%Or^ zfz332cbGwBQL{;8ZHw|Ylg)Bb&|2nvAyuH4P829JDSw(+>8nIK4-F1%{TQGFE!6+H zvQFho+^RCVbX?~NNOXn2@Sk`71p6IGy4AT5=ReMBAVr_BrIE?VRd*BN9VqiMpzR`i ztY;F1`|~PwQeB(L(q{<{mB^^qPkln)1imVEF#obYI3+21gIs zLpzfBGb4EZGq^~iu7@KcIeRbpra&&MAPhwWE2Hjgmc3+Eyk&}mdB<2y|0n24Ebyl{ zE~mpQCpguD`@@Byp9{$GvH)>GbUo*_J6X=morq^j8~i>>{i2LcvDf1A2#d{LyQ~%d zwJqTv{*f%O;3p^(9i(Ek0dz&mz`P)f*5Ybjh+~{Lc7KT%k90j`asE{>#A(-}{T5+8 zIe8e9*YTJ$>2)WSJh%HzgRF+KxfRboLI-ErS!O0hI4K^7fKszXdR7TK}s zBndPjSh9;#);cBHn#ZL#3R->9N_US))hcCSH3#i3OdPG@E03F{Re4qkn7QrPvV@o) zoL@O$F=GF)1fY@gdIG_W^oBGZ6*gu^2k(>z`1UrSQXpV4=)6@jOr~l~J+Wlpv!!uv zQKHjAW>hg_GC|7wal7dDRX?5;(!1a8(ij$4tpnL(J$^vZ9Idgs?mRkr{VBuSdy$wp zMs0maeMqC>f|%iTGrg}+?AIU9e)^GkeJ3D;NNw207Ox(~(5ZYnD^|we{c<-~w^y#C zNy;5%O`mrckaM)Ava~iWVJ#~AN~l+)wOhMT^lNl)^p|G+A+RUBTd!$$hd7CZ|H}*5 zg^!TQA96JEujyL(ft(_p$~A=`B~g}KcUp?4*aUs--}d5HmHVTvr*u(HDI8J z20_bVXIL6(h9)lG1;YM}KpDG3@!%Q%Xy=9!uPNvlTPBbGUJK%O_VXYiQhh}lw@j~r zgj=IgE*{SX-t6?qSZ+x1ra@Dk{b%d=!IxO(jnPrdMJ_lIuIzHb8z4KlM*L}D2QB#O zC;3hOQ;;u^`I4GX6Gl3T-8S8b$nQDNjCik0BFvdt5c*g3LD1=(SD2}rEOspOeWn=A zv|i!k#j?u-b#G>Ox9`Qi(RmdgA>!pw&}7%Q+m9&s&W3|-&d;K+{QdE?Oa3+{p7=@Ew=OR02U0{f(4>PkhNX+q{i1{#Y$O$fG1nywtTm?2ienh|uzX zH%1wg&PByQrWh-~*_}IBoSTpkoc~3)DwGhW{Sqq$Gy>ZHn?^wNS0lLo|D|5_Sr+Vd z>yK(JaAHF%m8278*G>&6KUZ zF1?#i9}O^GPH*6BMbx`UqnZ(^6gese-^h&R^xMP=i2kBgp3@y3&8osush0W>?4#1G zhZ*lfneXRuscANeRZPJ(5hBRQC5iaCReJZq;oU%FCMV%!eRU2=w^SO}NxLF&!;ECm zgkFZbjc9sYbINFI^RTnKoIDGp&ohNORuvTNayXuB*sqSB>2a%nHK_R0B-4Vll0bf( zGdXNU^y* z4sI2*gs$N?w{o^dn5i(;`^i5p1P~2NA=1H3mdL7#YZWO_#sYGXgduJxg{g>G82rKK zbVGrnRUD9589uq@!h5vEEDMQbvAB=KVo)TYRnEIzaz*rAX=!!4%DaSGZh_~c&aP9R znv)j^re8xw2J>gfKSj2=A(+uIMTBfH`XJu^i?7Y&qE0aGA9%K+)77<&yHKUV2)=YA zd*-|Bk*p1;C4sF9ZOq`9fD6p>I-?nph}uuh9k7W@T^D4}C4-MzzdBN`7W%zWR%{bb z*=-&Nr|n^Z42vYTH*M&5yFVH&?-Wk3472qL4GxF#1T?t8pG_@9Io3ZOf7cyJr()3m z7D?YDb?dNC&qy!J507aCuT4^;lj2CW3_shdEIVses>Emhnlbrumxc0FA1S~ZUBXcR z?oj9>_c}WA89|RW5fS7~1&m0HQUUMs&a0hkGj**tv-fU-ujn~B`NyFP3S194$ld7} z_10T`Y|6)KZg=~t8zxFr7_YA5J0_m-BUs<{qlPAw*7wES70ejO{t+%TeF|ZFPveA#1(XUdNwf+KTq7`tuKy~r2{h-&e?cKo3>bOHT)**jN9pP-~MVD+vE90@V)UO z&r^B&1+60F-3R~B#Byn)O0tnO&*ydhfJ-HPag5lQ#5f8$g(4X>ISiPs=pL#2b+4b_ zchpK-E{~cVE&QWaN+@1}B3Yh}gI6K8^ zU<~50xXDB|)fP*LO(ACZR*C7sY+zlVEQt|`^YXJ5nSoKlge+Qqj9=Bf1n`c+8n>5g z_`SIFHg`pmC?xPfSKtJBP5=6Wv2dm|$^GQMvLgdmCj4Z!PHdgw0z>iu0!OR`0_|bV z2_?+Qu$VTYrWpqNemaRGPIcyUNW`EH7042V5G=iC#Tx8MN5@v{-}!nAc~}|M-`^5Z zH}E!-6Tjwas^NBA)Vu#IRPu_+bL^|PImTGHXTUXgi|0lwZcn8HOQN{-zc2S16+CX9 zj^jF4FS(EtAt!0qOwJk67g0f$?y%j5%QCtTobZdLaJZB1V~fGJLZ69<#Id08)P4r( zJzL;CgrP{WQypUZ9XHkoO^&YE0}#B!~lX8wxXe*1N|>m44tJKq+mX`F1;7DYHc zY+?x?+CNYcB$}2>ZR+)6`5JErFm21`Tz~C?6Dcq}Wqng)V7XE*RqDyoy^KV>9|a0$ z?u$gkPkf9YwFViZ1*K*B9zgo%i{ETK$_$`&GOuohF)1K|t z^ep%65zFHB6)C|=A38)PFm*w{@oB}La$3-zA>wf_56;=(?v&F!vni{6nDUD1XT zlk_oO$Wa(LJzW+tPXL_{HmJ{z|7p>$c8P&V>?4m|5tjiRzt&o(u6P&}cc@S-_RgUyoYy!hgP4*}O9Irc6fd9v8IqPwQK_qY;7LlImQYeg3hp;R7^X z;0albBX)KeUJET$q8cWaj{jpQK6HPC^zsMm484Cb33kX`Br?<5-ZFiu4bB06N3SJN z^l%$At~FiaDHZs^GFOQm5P;)dyU_u*Zf-cs4CL@C^Up7h2s)30jz?Kx9^mkZA>QxP zeaB~{Ob%a1boW+Hz+#lsrjUz-B?suSzO*Z*%-pgFP-@m%m@W)MS&fDySRa5y&!4K> zQftoW?EctKir>Gr5ycD5H@Kd>il{bSnr4l0dU4!;Y;d1k(;uaxmf0K;g~L@m-oT+;CW9yxDN5D@c8@1y1p7GWbwVciH5a@Q7*}IHzaJBZ$NE2VM#}10T zOE2h=XX?;45R+1@qG5@>vXSSuE1cOO_b!r zG;padudOk8j4wtk!4OZLPsLs?`cw77+hCAK9=xj}m9;}7T5cCvjtGSA38p5AH}`Tw}P}|Sjvte(9>sT zv_*gQUzbBe$M!GA`4D&AX!|i?&HeN?*)}o4*|Jch60RSk;Fl9VtJ;_L)|{3=)ERz8 z$4STXPYGU>5ZCO8-JEggHs@Od%Igd6T7f5vt)88xv1Mhn{V9s3bxzb12rS}eENZsd6$V8E{*Q`2s)C*zP)-mSDo_E~N5ijn;Gy`UH7{u=C^n?)pB zR}-77uU1=rzB5p*f5hM8b0=dlQSs)mYWKm!FjXV@Ld9|qd6OU8GZ^^=NugTR;^;#;(RdNK{m1hJb+05hzas3h)6#kFD^8j z3-Rx)DodN7m29ckfNOT$LY?01tT< zU}BKwoSF`jZ^P{3ElaEG_3N@iXf|`|d9SOl@0}*oHcV9W2^vXP;5htMv{3dt?;8{; zf5Tx-m#ul4&+|6=5|d@JZ*y^K6-^s>O>f29;F*`iTS@u~wjGy%MwDV$Igj>_ZlC33+cId1rW$atA@oCtulk z9kxFj9?I=nU*3zqqNuHKKK4^5btzA6t16~SNcQMX=QTguyUR4$gfNLja!Qhjf|ka{ zZbCtFtr8?!W;eLsJ@>fJe;R%MpBYT5ix_u6Wg&8 z27$2WBx!9_Mz9&WCf!R#8xB!+$ ztxoES+eDB>hMIR>nI_^L)Pr3@_V)wjLE)lMb?j933m&mMRN^BpMAmxGnSB>~jnDd2 z>w^?88l1H^zcTC%BMy-yhaeCxyvTlY6rBOCpPRL~?skc=5OhJrO z6n<3D&z@+*?&`*JEs=xar=0WVCvUaMncYe@N7vIbtH6?}QnOpP?d2(V%=wrjgqfV; zgMgwkO|tdDIv*ZbaM2{zU-XqI5?trOY=vXu!P8^#R6EQi>cq!&BsIc&mi`+Q5Zoc0 zncpW5hs$%d1BO{*7-F!sE{`e@NKl_(54*McgpW{h^yet3a#iMwv7?DzkB6ImB*(S& z8~&Qt!LNdCMPJIW*mTY{WFJtFmUhQ-ufk!uvjeUY;_#o4wxik{_-RyHpfM8_3csY)2GP<%DunYxqqEQ3nq+KG@Li;W?%RI6Unqj$IDZh)yA+0bv-e+FW#Ie8%H zPLNz3gecz6o$4eK#An_ey^)vwC)li1m`R9wJLBs=m2Oj{Zzg3J1gQ|zCJlS)9sZlH zY&s?#$d2a$Uy(f>(t*qJ%bVUdFA}+fJmV8ooa8ufIgyumq3xeqMj(x-8%GK8VV`385`u_*eM}Yg-^-&(>Nl)L5HhX)0Siz> z!?r^hfGJG-34@HEoWF_q;Zyt2NtB2Hv{rpx=sRQr?xKc~gZrTcA}iAV&)|v%08r2l zYU|aHha)v+K{!n!2p#>e=$ub&rs>s!PkHG=^4*i3fqg>Z`-=Uc5s5|_=#i-?^`^`U z(5z)z?f!U3r6$Y$;%b`u5flP>$s^p#V}IU?qtj7SY>+Oo*9zt$(3t7IMqWi43z;;? zqna_}V-7E1;9fp&E^Z?4l&`>x(=csTjE<8`eE*dE4vjJi^8_mJNxhiw0f1+8t6o$` zoGxFeIF_6sQhkL}K{SH}TIpH}b;m>PUxoMJ6Qh?XL=j41EFmFzJx^n;F!p?ipOa2FG)t$o%{eC6!$jni|R_49K~f6jxXmGEL4s+Tu{c}frxidy%k)Q5LbSrtLv zHQUDLJMxzp2#<@#>%|f2oS`>=A`o;dMQb4KmF41%Finoe{#-QjMM7o1EIGdXG zl{D2L%=SVkM@Zn>UdmNOB?P-@z+5M6G42LbXDLs0agF0arJqxZk>+tI4WDZz8_S5obbQt?T&4xkp=jDg0RXizuf?VmMVMB53 zLq;5(gVcW$aw;&ceq=4h$rSe8To`%6{H*_?NFQ}=OV{IMNsOsPn*ru&h@xqINJO;J zidLIdh+6qJxa@^YPveqbBxURBVO_ZpuXY#Nm%Eh8)jR-Q5PUe>;u;ANF^UfvCe5@o zyhYe6;hqZVAm-+}P~?;+wl`s@r4X_s<$RQP<6^v&mlp%tzlpqw)2xb(523_jj?2Nd z=9t;~ePfq2XaB4A=S^&F&QRLhp%+)HAl&jc>D3)^r+HQ`8(A^+CSBq`gn)(_l_GK{ z9!rDVr$Uq{+${*=<_xOu9!qthba_af@_G#m+{6u(K((8*iCG%T&d=K(qn2!Zf}tzm zSza}pvfA%Mv6U-k+AhA2U?O!TstU^_Ep2p}$>_c^wU}$08Q8(Pln$JjFWg}u(B$lhnjV1g1*pZ+{C^NCwuti`mc{a zQm^rd&qO5;s42XEa+0!EO9mY6))6IV_wnJK#O>?LqEdYB0&@l@Kb2 z5&W>3+9Ie8HFas=p$qlp$e8%c?V&DEI~ckHpqUhjt^bUm-Y z?%jIR;LwiZw2dn!Br=+*v^1k8_HcJK$`4#Ul;56ZR z*P?Z_PhN0x!xm!uqdk)7*I0pv6SVaHWlFA)7}3{Ldrecan{_2>1C(visEkOlRHj*E}Finm?1l$HmQWmevFijdw))V79# zP!F+l_~is+^eyOoh`)omR?O((``oF{D0Mb8&B9R6Getl_(W59*=Sbroe3Lh%VSl&V)_p--{74uU=S$bqboK%?MK|zs@K4P$-}8LU_w} zxj)1EhI-Q~;1Rbl02f7E89c?4D+Jsw=j&bh5N8>giupI>>H{o)%$D20+DRpA+#M!x zA{(PAswxAuYy;hq>Kp!4L5BKh@oKZd7l+^(h1;Ol*^X*H(3(T z=P*nd!2$hdtsRgB&Va1*oFUT2!$05RTSPJ*1XJ5<1m~z*p{+&chx~&>z!p8He?^31 zAPtwHft&r&=U0P|aZRCspKety2amby*59nV@kGhaF5D47Qo~^)b9Ke#IM>^I`tVGo z8FceG9yh$gp;7T0>H5RF->ZkHjP1I~9r#C$lNE@uRv{$LsM={hsPkp_41(oNQ)K2}|eg zLp&bm8Xm`q2Bh7YY8Mt%p>H89Z9Q#JYse?ExQA19Y z8{!*$OZJD*`h3vY?`X_Q7P!(Z(-f`s_c@HHwIHRkTRnPTh|#=r}SZ3fDdeBVoN5j54d3^+RrP++y(gBD4O)8}UFJ zvY$5n5moP8`(D2LY&h`FUEJkY3|J70qaQFI^Rf$4v6yJTOIw3MzZ!HorhSK#U}d8q zkpMBqIjimMB}Y?Qe^#uvrReg!2hamuqT^Q~17_Kh%p=8WC*4!M{16ld-%;WHxqb(In;5tpz$#DkAcQl zFdVvi8$>_xWi-niwFFk3cm3o4Z~=X7BVJ?H9EV23ve^*EC&CXnt)Sz3f5#JXK)cy3 zA>gGI!UGxJdFkYP#0+Lwe{%ioJG5|ZCg)ru!=Ky;O`x9Ghk3ItxfosGa!u%8#iw?` zh^ss@V3;Y9fnv`yMxh5}I3p*_$Pa(6CdKaBjT>|$uo%$uXT$o4aXs#849<4T;MF;i z)D<2(qR*>Br;#Udw-h)0?@I$$teDm5Pf8_ zJ+4a3EN%;84iVv;)qg>=LY8jjld|W%i~8B_*MO5it(D_`(A^ug(Tb17Q{UikHA7%| z<`lZfc7$?QiZg`Wkd@`#0ISHUkR<7g5OPG}u3s z>50wI_P5&#m@6&HvfZ@Dldn*#)Tqf#hYQgoi~PzmLZ`Q^m!g@%c%FJu{U)`jfmZ6a z&NHHry7XnaR_$%v$UPjMuYzWq%LZpeeBR)#^u3r2z|9U7fI&^JPBgnn==-s=sZ@Rx zv7|*_5yD`!w$8LcIz*vfn>CMW9!g1=;uQjsJdSZd&_7x7EU5dDX0dL4ukyWCjV9_3 z$rjYxPJvzzd~5YrFV#itzGru`!j;rYHwPQA`^CSzE-H;+a-`+v9ryfybN>j&0&=0nFeA|goQ=%tR@!i z&Tp<1UeMcEwbQDaw`s*ry7AYV72PgK_|>1I7ly&lg7W(PmZw0;Uv-~8vKC11fIVNj zm`Js%Z7$XGlmJ{8yeXO{!yHcj*sX_Uok_ufvD{E-L?AMe+p0%$CmUB3xt+`N?maGr zq?`ke`7A`;;o)oVla*qt$AoqUY1W`d-hGs;M*4=7S5xM0VC1Dzt%0qxZVicOrsW<# zH5A30u{UDT76(KQUQMkHZK0bqBZ^f%>j8;CdD^ZWxjWW0Dh#nNwN04Kf1J6~TAJ_H zYz9yNwy7gOZl1H_kJ-bc{+^I2$Cu~8VIx*CvIyL;^Y=tEQp2^@ihtN5_!BeR*HtB0 zsf3PP{%khRR-kMhD-d7-$(Nay~8_H{q%8A6=zR=Z*7Otqmmm@p___B1(5 z6s~E|a9y=rmvMp+Y^+Bc!HQX%L#}`74jm`o*7!;J35qEOv)m?vCt`a8P!|^X`&d+{eYyvfg$gM)+#UW?mol#VI^T zu0-^evyb1`i_V9i^w_K8Y%WfOIdW;-1qqS(bK0D9^j|5(JD|K|o)&6c+IkDW5Z759 zU($!iOS1$?bi7sTP=0Sd8`zm^Qq%pg(rRg7aF3rZ_I8NOxNu#_!9vUD9mn}gs)wUY zy6`8;g&py$Du4O-r;~5UiJepCkGtOE+IqWQ7I){{AKt%DXYy=JRxRpyVCf$ribl5{ zjO4_tbbWIPb9L0>v6a^8S-f40?NmwhwoCGxsAv(q2Ove$>{N^a7g7Pg4V+{d%uU{| z=O=d(m!)=ph*WxS@d>zG(>YvS_8i%cTq~uByX4PC@IczCj+;o);}u=ik4Kk+EtY%} z2;rp&io=G|5+WhjQVw4!cC3iFAP;V}sd$2i=N|%kgZ;lkUeMN2<+ge|iFlY`p2@wn zTd&bqJ1{?IWs^$uyBc9HeI&Xk{`2P#utI?RUBJfCPmoX-3)%LB+3*ZRHhv4u8k5@M zPZgSvjg7U7h(9U`0?Y8#0Su%@ zMjj*71=K13Tnre56aL29cV{*jSUpgepT*VuSnU7HWdHB5^(i)9JN%1~|Nj^HcX5OW zJPyrvRZQ0&aiM_*`(5T+fzL0GNimVLv$H@JVzFFkwkpJ7J5RJNo^b#w^)oP%6oc4+ zey>)I%Ta=%+hafpF0A*J6>qibG_3A=76+yw0tm8 zHo*I>!eT-y_}?EgQO9e;@@(5&bec0)20tbyJt--P;7J&t$C>$dXrV_sqaEJa@P`pO zvU_5VL*B=xvDTB`WhmhXJoabcP8uDp045S@jjHXV1tfS|bbD&h*+d*5pPKvk!@iHF z)oeXuza6?tt?%lo#dRoAYrX=qUPZ+zXinX5>txpRS$KYhLc;M^ceg1c`CBYN@(N`2 z@vo10F4qLk4`)t6TNJQvKm#d%0dPE;nqVRP14%7|epd<&pwBvZv+pgQTpUDWNw54v zXCg9KkjYisnhp-~GXi zZLwS@BIodSB&wBMZE&*>$dKjpZ=Y&Tx|HxAwy5M9zn|@gtJ`b0xiARRYPIQr2^MR% zW=gNWQm+^MMVFJA^MTaUfI?a3Qrow;iQO+!>5;iQoNB=wH+ZCZzyC1I zu{j@d{M6CgMf@Y}8z)mPwgbYmpWr{fZ=5vtpO4%Q!g_F$o4a>FYQm4!Ng`&KbR%-)!NL0qXk^VwDojNsG+}v&MW`5!NK>Q zD9|u7D~0{e3o&oA+k)l>7AT#R@%a6@ZQJg%<_M0_Uw zWkD2AlxYbJZ2*RXdDh2_kVC6k$CWNKTUR$a)Syq12)u&UvD+V6gb^Bn17K?C*2Ey< zqD*$+xOXtUe_ELNSvVIpYI~6*%Q-Ur)O@+DK8F)k=zeZ(jl`If{_o@KK>ZRd-!r(v5vjrPphcH>6#yeQYlTHnh-Sr~{2g#(~P%YP8#}ap`O?7{m7)yIk`=Rt6t6+CNCul}uaTh?=M7b{a2MHM72psZ#Qs zI2n$9!o9j`?~O%%!>5T1RjSU2gnKPNS-f!$9HFey)<6GRXXrDQ1J5in$wabVJEIpL z%$}@9$LfZ$a^JoO=N%Q@tKXeVuI^t}Rla1-|Dn@ri-;0eQE6~anMAm==~<|w+u?Mm zQzhhd^I<&%c0fl@O zSI@iMX1X}zUxJc!m@uI2?v?Fuc{o&c-9AN#`!goYrPHr5^?wmo1u;&M{ZH0>T{PHR z%iEf%xFOI);tPP3@8Zo^WE;+0v^`&~dv4{>-2}E;1R&XZO60Ol^aL4K=*-s2 zb%lO5(A$;fBPmq_+aX4ro*5Lzt{;vy1>WI`{SOzgJ0H%mX(>w&3lB@kQMHm#3k%vT z$4=#eY~(AB23=>Vaaij*w8ii+U7AMo`VDA3`xQJ|k%5acn9J}$sZ0*&mFtyp`*XDl zxg9wv!^o3vwQt|hxbPz=CbU`%KS0cY`cfv_s_Soa27^6Srz(y&Nr^c~;Mp}JpEmD! z!o{noZJrVsnGxc>$Y!3KneQb)aHfDz4i$p%8nkc(-G2Y+f!`$-KJ5x*TKz6;N23+! zLo{JpAl)AScok%^%BfjtWU|=ynd&)JEz3*{ZgVIW6~=15bIk;`vmL zc64K*Tm$~l3vQ=x8QTvCdxYMX|B0r2AubLlhx1$2f@z{T0y$|6A`V)td){_`kqNjv zLVtRBiT*C?nsARire515r(jUINtv>82r9vyc*tnYX<|PZ#6~<>2_g^fjRLTbj^aW4 zGbsZLJw2aPgkADF1oemCYEToOuFnOvT1^B!A0{tzFs57W@l z_fkS=lKvyyEPCDXN#H00ld=6gEq+R9oL7J8em$6Ky51B}e5wS->u63S_h0|a*Kk~6 z*&KBr0eR+>o_x2qVdVAIbt9}Ytx65)wq97yuE1p%*T<#i8vYK}X(E*C3%^*@eS^?# zDUGJ@RRMuBMHba@tR$hBe2UEJ@%jr1@LgCnvBi?Unn+ORr~;k|!dHu@ZQ9N-ofIpf z1=3MpdS#e2eEbDwp)fJIZeIoEz+RgS4TqrkNt@EJ zNI<(sqogOZl$`{mEe+6gVICaO5{&yVVR>+c2e0bD=NTxCmDU(Gg z+(}H@43jXIq;VLmQ`dOXs#fY;-J5T`V2`#0yS6ZJyF9|3xVX50Viw&nXPmBmAWq1p z!_j!_{t{K47uFY;td-08g0j(N{s=k4-a2HUJPIeb%}!Q(R{8Z?YuxC2rj$~GvEh(9 zfz``cyZlbMM)OrW8)^tT1=i#C(O~01ndZ$!yQ_9vr3Mr{ZtOgDyr5@_{=76x&PRuU z8p@kK%n#_dp6uYLfMC=cE}Vlg^Z1OjVWI<3<|(WF8Om9ugl9edK|(xrPH^ zu?*|v1SGPvpMk*hr#~2l02P_RiE5h0sh71+UBm{(Up9W@Qlin8+p&-s{Xr zIG!W0DcXxZk&>^3|8hE(|IBKWq4(_U144oNPn^kVzx&xt4D@+nU>TXEf^*8|mjvX* zXoy&W3+x&YGeiuwchFRK{V}(HQOkz-Zs+43AN${_tN{ze$>rQV$bUj+)gD93?d;I? zI|~ZP&(5X}SWI4SWq>ogMJj`h$6`DU7PCAYi=kA9i$y@dx4~2_w)>kLGjgE6f2h_y zgfVSvz;zqG?NF^GAJelu(@qKFmChPha}5D|Mf1FJIroe@N{VuT!>~gsPOXugB0Xu;V>h4@E6An}>0-k1_No>HD(JYquhu7L|RSMiHYx+^Z z`!qB6Msw+f$Bh3%+BkK|V9%$oAXhrI6>BXF3_FwM8!2qI&}T-3B~ zq5I4S`)=Yp=gv4-Skel^qo)URbnEZHAppvpq21P<%EUA}=g=tq>E3*v>0MT$$|r+L)WZ@rEUx?kpo| zWo#}GfW}?*GmQA0UfSmH-S}3Ejfm5r8>8PGj%)p012ZH-VhU%StN_(RM4l3kTonvE z8Q0sffK}pajQiZPD?HYSDtgflfz3m_zxJ-e1p;+ty&KGeeN+nLpTp+;Iw^ zRF70zxOuEcm}{wt(@Nt4uE^I~RZ44l-<-pDq!h>Q4K07Y$E1vmhriZP$EAsE2n62< zN2JqcT!e6b2ozoXk!2r(X^RH6ZjIGj8JWrM`0{(>aIR{0j*{J^WTghR5bdEs=fXlv z^)8XH@B#n&h{sQ8P37oJ!7ulGdnmZ`+Bf+w@<&p4H^u2Q<*nrEz(+w9AFa1!cDmw! zTlU%sT&+F}-QVA%_8?e*{LH_!vd6t?pVUzb8^)k=UCjh=m2tZTQG@IaK&K$$kxin( zxFyyfcq*My`33O9TiW5bdT^991;jc(3-mms%R35cW;d1M^xdyZ?0Zw2#eCHYI>Iu( z*bYRrg77ULQ#ZS9Ko(S6{)|8-!4U#Jm%mAtM7olZg9rZO^;$OBtU(PFna8IKj8b-o zKlLinKA;mT-d)1f)l*CsU%FmssJ@6LOO_(M|fS|qD8bY^v`Gf-jjAsaY z{w0(32-?D-YL{_?dk3Vmh94Ic57Ed!0)Y^0Qss5=c)V<6g=rs&dR`jNX!mJV;xZbo zK6rVd!Z8#HI27871lGvN;NXN8_9mq#2k-@zdS1hPOf*|ka`NB7Q-@_n9LNGl8%r9L zO-jWTjxSld>#9wTrdu;$%+0>8oHvK^#;j}! z;IP|$Ru%OChfhZ9_pWvQgEJK3=-DWqo89rI8?Q0e7=MYW(U}>6A;Q`x3e*5`o`1$r z57J0F|EdLE%jv+v6GhlJ==r&WI?s&=<&XK>G&DpjzWD*uOyVrm*uU?pvL0f@=OPo5 zo$%uArbY$v%wZIGJ4MO_Qin<`ZHY0YT+5fo9VM5k@M)4|NUogjc_ieO)1+U7os+YK-M(iZ`k}XK+FV zId6$+sU$+V783NrBmB>o+EAnZ<*3Qd{3bi8z+?f&lLB?fAEl3;1d~3U7np$vy8$L9 zqN3!KPGDR^0AP-NynGq!-aY_v-}^@bWxR29x4j$Zw22d1SwQAj+itk7P;{5Ob9A3~ zptS9{wy0c#Q}eQ&T(PBhct~Quxfx<$KXD?ZgnRJ!(yFeM8m#N$k{9HK&wpRXC!U5K zE6iAQ5)eBx@}dPK>YEb{|D^Ow%?j9eRjZsdijW|u6etY;fBd%J60ms)KO?G{b%3SH z>r%c({OKuEofZ3;j9K$7PRpIZ8Mr0`)8+=!8o|2$g7p!ZZ(*>DtqRq&l$B4wVf7a8 z{A2mUvA|^yJpQaZuobZiijKcC_@u~zq40SO7(Sj^c2+nWZ8<&9&YuEB@uVY52mabH zpZ<9xX|q$)W$73C=a@!9Xa{z$=j#Pw-xq88lrJtnSx+jOG}x+)S^t~gnf|MuY!w;N z+8NHsd4cs3-Nrm6lIX6{PCrzauLUA6phf=t0**qHktNaogz{xhKq)Cu2cAXKsvTpJ z9ImW_`|~b@{FzxFTu@9!%5g#56Uz#cIj{bfKn8yUU5!qmAD*!5?tr(1(OAaxvEUWT z(_3B7T|x;Dma|*jnr;a}Pqh+pv{aK8*p7A|T6* zK_%#On3*c-74Mt>sv04k-$6^L2Pz2bj6e;G30{U%kLRs53V{FWQt=TJ{l9-j^#86` zbeH99*72jjHN*+5LK41r2u-xKDqWao&a@SpAq8>3gqRp)y?mYaq6Vgy{Wy1+@FDev zbBO*yPEL_cxWQ~9vR>Z52dki(KWI7~fBpBs>~~*VuLaR^xP$$D(fPgcDO^DDXtX=4 zi$|DDns01sNc{V)-=kiV0G3%|XCWK)f09=p(0i$jOF^cJki)u;uN6lQ<>rV-4tPO! z=(K7phd=+@pZfIv@Hd}e`@+F0%hE%{pn8K1Q24->28zhYu&{doLH;AE%KnSfWM^m7 zFAwbO<`~0vGESM+$64AqV_z28j%0yD@erSi$#_X`LkZDY7VuYHKLBe*z~<28QB8|& z9=g=%NVqYg*&qkPN@;KV|4&-ZngtQIr$xV*@m-`7kImtwPgk+y0Rw->b|J{dgwHM5 z?bAgjf4$%d>r>9LQBb%9dN=8a%HMR$c?h0F6L52s04A#OLxLlvy6bEKh2?TU@5S*2 zyGEIb07qaI@EH9)LjAvEz;$ZUVQ>R$iJ1e)L77Zj2FB}#-HI>b`L(hFpv_Fz?2c{r z@`uDU$1nHGS2Yl$1y{@4w4z8Xj-!p9$P~vTkOUlBxav*{jLZzdjdpNy3N~iMy8zsH zGs|&ME0yZ+R{6+Jx0N8;1%Tv97XhB&W%HEr?5ADDikvVzMvJ+p&flfRLldid2N6#Q z1Z=^t9yr;`RvN-*05R1Qw(GjL53h%+M_&#C2Q9c*yMXjo?kZ&?1xcztlUQtYvlgv4 z&{v1!YFfzqvm%k{&M#|F0btAo2WZfD7zoPVgsQM$%S!Xh=oo67NGr2`e-ihx@bZVB zM4tb{1+<}#RVjOI*Qu%b#tI`e%ekd1HS%UC)LM1R)bV@ZhG9IM z2kg8M(wpdLT_ITAUtdevmYMJ_Kw=Ayu+(W>z)CB7Ynn|zWdD;4Tq|K0g|WeFG!6(1DM~zBkboTwcW((mm9G z7vYs`*5RtJ?s3p&uP(Ro|C*Jh^Fkwe>YSOeECRwt)jC^?0rsXwvz)b!`%~8RU%v_} zY^~}DF}}g2a4DQD)#S=TPfkj5GShTe|26%1cfPtYhHBX9L`^sbpGut!m@}7Wzd+O4 z5ASLC%m|>ro|Xs4(l(cA)01m-pv1@hdtA1G zqZB--_7*E}@V6i)3~qH)!V&EjO82tkl+^rdZY#I@Lz1=~+R)&qlf_8KPd!qUd5+)$ zx_mZT&MCw4JRf}PjH9;^M};A2DpM~!)vphX*&qW0MXaZ*yG^Un_KM*a14YFpXZmA^+N{t{TsaZfmxh^(gU~vQt=;P({;=Ou<}DOY z&%oe0D+;I4UewFT9GXP*c2@Cwawiq78Yo?5iPm& z64yi}P>d+Jo278}C*~`E^yupWwnV_{If1$THu>|`5~D}`iN`^iG55Cf1-Zx5|7JxR zf#^akAn?B)voj2IqWdMe)Lay(yF=ThhP{{bEh;!3m-BCO%jNXW-TYI*zAK$CnN>H0 zP&;j z5Y57k%N?FT*Yd+EeVB35uk?@n04(c%JlbhRs?X*0EPKbBl#&z_ecskdaxKMO5%U$p z_okjw1j?*>&h1&L5;7ZE`JP5bD-Pg5UEarUD>bGmk$1ni(@Ur)hEwV}SD&*z^M^r- z@W9iS^kW?HzsJ5iCaBonb#w)FKu$$n10RLbRqcKwMVeVrsu|5}lLV^<`8%gnR9La4 zeInraP=q)+Ix!U+NJBFb;%!f5piHeSF8+qA_2tI;A#aFEv#P+{Ar++4ZXWQsK<=)4 zviJz1;{pZc>(ryJstPEr&XJe0+uQrARKJ8MVeH-a@88Gw1byV+{)UZG4QbdM#`o@T z2)JasJ(q0GyGsIBU7hJvflzD{$c+K?e*jQ8P<56YOv?UV{eqX804ac1AIzye58zFe zrm!UIi)U!gX(4-k^49^`?wpuJ{oh#ho~E-gY~45;JX#_7-+^ERe*z{J0Gc{ETEp%0 zG}zFnQrH}m-<62=yYjw1=7~XBOJ$Z85fR~Ru?0^(n1;6o5-Nt%`0gEaeWlYIogO#m zfF8<(TSvy2TYc`02`g4YvK>F+Y00W^^dadYx*E$C1 zIUhS=_8i-Xn+wIDQ{L$a6a|VwCzRlSqkxx*Tc)?3xN?#5|91M&W%=73jS~4sk3GRe z0(qwF|7N2pK~2$LZ}<(SiBm4ezP`pfpqSl-C^*<#(%eLj9s(j!_9-RkZ4kMyYw7;D z;~wB1_?d$+gFKrwTe*M#BSKS8$#z&pQCF?CU{b60-33mWQoE_Gx%g5Oa8oo2f8O#; z?AwR*%GOJj4o>7?fFQi-`f&`9T3<^|G3=1HxhE2Z<*p@-sMqvosZ0SaSjQCn#=Pm7 zG^y6y2d-N|wn{R+QS|D>=HJ(^Ed(H;`%)Qr0#I_0>)%*dC{`_O?{-~+T3@`ow?~t~ zV%_UyF`SzY2$2t9#+NOL+GRne<5(zht)nYf>tkbNgwsI);X#l!pJ}zFf-k2155UXp z)DNev<*nfR@lz&H#nY^L1r=E?wZQF_B56m(A+p;SYsuczN(sR_n`s8Pcg|mIR;7M1 z;pLad!NxhBttha+xNmA=XR)|j(68T{Dn0t^3k{BH8vwzo&SmsLOCHmGa>0nra+LX6 zqKG@PFaq-D%(vFX08)$LL^>zSbs;gbxjvugQn7s49Jv@7T?Rf5v;jU9m=lntCixdY z2u{2Y4T{^HalJgWKR(t#rero9~{w_Ph6f<2&PwbI$k<|E;kmlj$>`xZ}Eh7ZR>7JOB!b$3bxn zJ_%geMk%zuyA2>77Ita>e5r*dJ7jI3A!*n5v{jo5`A;}rM)LiSk6x6GE7NJ(KA-;9 zk4g7l81wZFUhBzEFG2eSiz7|0f>oWe_+5#!$bb8-IKFbTpqO1w<-#W@tn^ zY}pKyel(EBcs5e03}E*EJ|TH;g&uCL$i+t0D`uSq~}DxcvF~KadPD5VKTuLO@K6O@xJu zdj}VnbcbD)^4JcziD+oM=(~H0S<*S6LGfUP=mJIL!9RMI6A!H^;h&3|_g3KH?Ngra z{)xda52wEXrbSl)emynKU`pa~+BV)HAD1Q3oruWC{Z$6Jndv@%XE(q-F`O6WzGq(X z7AARWYW_fijF?pK?BXYSH1we0rh@O?@ZFIhzq{#}T;z)dh2G2_JTmy{D~T6Fzg+t5 z`MD4WgTRdFj0r?Sq=zEkc2jZ)j-uBUc-shINJFy36Us2ZaJGAWYSy3i4espaUjh~q z-tTM&rCb`gs%6;zw`mP2aP~s~({%L;Nt2YaeNfn?i!z_`S8%QvD$D-!8bXFHz*VMt|Mn&SXL1>awSA%7f6 za(FoEhbWs5bsQ~Irq?z9wH;ic#ef8C2PFa<7}%@8ett30s1TH+lOr2(%w0?c-P)n4 zxqc$O0WwPf|4R)2lu-!D55R8Pp!2^AtvbE3??R65ymgO;h9*mU*gUH9$71RFn03&Y z{PHq~Z48d(_cck5mmDur9kDr?+vcOx$~`uM=~Qw z7Hf`v+v&~RfrGUP{r%5F=6Tt=bwvHKy}y+5csD+G^oiD*lzk22su@|$UNQ7RL19i9 z)G0L&Jf!Pqz-FMSbKaxD&U(h6)U94+JTFVwuXnkJo)aeG=;Qm^P0QBi<}=Sz1||z^ z;|Fu@9rNE+!hV)rSZI}rrkW9m?^vLr>Yfpe(Iz>kt?B48S?zED_;)bb%vJS{Rwu8X zzoC8K{GJA$`3M%S7e9VH+Z1*u;H_8V>ne{m+L&=LVb$X1k$+&_`Es&1Zv5ncymDiE zyXoL|7p!;C9_Y>1vcx_%Jl|gUJBVVtqq>HghfK{|CrJ}U1G(SxwM_1a$#-016hpct!aT7L`OQ%BcfF9w~`%V+A5(Q`6goghO`U4`X9P%V;n@ zEg-cEVolhq-Wq8pSqpwx&!0aGt;|mL56ccOm|Xj)#}XN3a#7XZ{ICfa>U3}PgTlfn z%wNr9 z$$BD04X6f)v6^@!%#8fh;^WMD7moCd1CiqChO9B z&C{7wY`=I4AG`T4KEKNFiztTles&)*I`_u#UvFeclQodcASirVpauNpp?-$ftO<_J zLS9(PrRo%2zvW)L%uP$DS5Fa|x(SGq@H1w3~D9hP~&m;}X@CrSNw+lt{P$=~z9*b)? zI-+*n#0;%=+zE+YJM;ZwqlE8D%IBZ$B$Xwiinjo^x?CSjhWq&VCO}EXGf&8k)^vO^ z^jF*iY#vHh-_R4tY*V6g`nHDHP@5=wEc+%5QhwNbAW`54T1@9RtWDv&ja2k$0tAIR zHE3zX@a^sr7hm@s{t{2E#GrHsClE^XX6lItQz~=cPluT3Pm-4+;b^*(-AWzq<}bA?u}ypO3=~v+{26whb_(WTHRV# zPH>BwesuRspDXVQz-F#geQWU7yaqd!^wCaC{&c;8u=H01i_(s~<wu-ZSGYMx^87kxN^--?g0MPNdBXY)6ahZZm3s4VCAqvC{p&lbyW0eVb%L3n zUYXt$emTdLN}+%3tVHvz2)?_QeC3upYN<`QrBCkt1t}bqqj#5X^OEY9g6=B}osuw= zXhQBA#iPZ6x^K}*I_FO0cLkny_dRlVSnezUpUw!8k<;3PpKj*?OCi6O?biAt7U3=l z+~Q9VLb9>1T%=4R>e}VZtHN9*Yhv_tyke$ua%$Z1&HyyMiuFdj;{W^*?Xk})G+=BIP^j0%8abYM*7Tk?bFA}iAjc85A8%%BOA3Z z7@=3_7}Jb2VLK6!*@UU-xX~fQRg{yXEZ@g>u-4X9t@}}c*|^@l2a`MySCwh!^E|P$ zaFIK!>iwqlr%1dr&Ep8Fv3s-HnLbG(GUr3Y=Qlolpk~_$=ibCI!#~lgWQPl??&DIc z&3V5AXvtJlTI~G2Z{6$n3R&YZedkHIOQh1-+6@j87}Rwp_*p%KWQQ%!vtd$~csR!4 zT>9>QuKAGF;vnFEu8(pYz;ne=N%8XX6T{f~E*zy`E6IT8<(E^hkey&s>3ks4-%{B> zr(0QiPmx3|e|_%lp0jrjhK;{!X!IbHISfB3qk${rP4*~JR&2^eXw)8&=kS(4kD!37d89Xxr`6*>z z&UA}wYwu}tiZz)UM6mLqKuA^1_zs(n1Z+a<9x4yr6Hl{uo+wHd!o=a!Q5hD%`u4rA z?@Js`-BA z8_qqpa~s=$Gfkvj&kd45Tm z&ci9bvGSgmw)BzB0UpX$GQ{-^kLPyXM%2!e-(_9-UcyN!6BH7nswp!up{St7+f-_B zS5*tJpgkwJBNYkf5hl!n%WgNb%zIW+YDe@Q+=!g0_vmfCZ&Y!Z+W-4OaTyRmR@sN# z*-E71CR`mV^t#gP2n>kO?Yw^ zkB11A;u!kfW2NuUPV$TED_NQ;EZKJ%N4Shtdjlvyr_t&JGI926EG^57!j`OG7mt+T zv#ysK*)YXcr7L}W+y4<}C}AYlqEl^k@3kDCLFg1j?AV>|zT=?2CDZwruCjf3iH-EV znxDKB;T$(!f4C_^M&Nm88{-OhUQ7qm!G>3#l9YfR-&93w4>LRmNQFG{`q1;c3@-Hg zl<23<0-U@d{3sBgx!8VBm5NIA=n~hB0cCrZMyPrMi~>7|qoDMqJjVU;MszhUi`_0~ zEy(p}pVH!781OfE$}{)Ofrt5FDegHgS%|+1@kIa3~iJaph#(DRs+XNs~W+LpiRPt$oeRj zjcWUE)gRCJKssd;*jQD9@r0=4h7~{%Fp>fO^@wc$*=z>w7uB-Yze*VwJbF1ib*JH+lX6&H+>WpTH z=a=AF1COr4oOPR$c(Bs;Xe#mncLGGieq1s#Z&iMFEv+NvZ%!ZeOeY#02XvYLdfJuo z`PXbC-PJCGR?hqB>N(0b5-C(!r>9rG=~Oc$hf!EH<3)V++78Ivu1FBHI-V4FBaP1= za-~O|aUmoqmP|l~5=jvbs#oYO(of4ED^S}S9_d?X`?H64EC< z{5A`eubm#eD3jiGlA$Bzv2}W6<=_2sDV7i(<<5xhsJI-dES_LEM*11*Py(4NGuK&6 zf9x3-1Ui3%ZBOr)FE7sr!zk&Pl6PH>;&q_{mrrU4x+dg77AtIB$jH#khAn_e!mBcs zxTKYvJ>jA7q>I^uRjbYaJ#CETuh%Y0>1^>_c3&aTNdj}3Y|}F*i93Zy(`Agu-ieUk z=+kz^_?`F|xJxhbKF176XB3!es8%8>qV3iBV9IE<8q47pcluub67};T`8M-0?jm0X z${GBpoyq;%=s%o2aBOZHefR_qPUWHRI=rr?n0?y1!Kd{>23g+%*>e=*J~#+M$`iE# zJIb{U;OamB**~ONw@()7WEeVv1zONyWQNA+^|w%^w8*R2vrN_N$+ha<&abhZ#2lI} zH|uUyLu}ws%SjT?#E2-4LR7&LdkI{wc_SAWBzVe;Yj*VKIafb14Y}Nj*J-{v<8^Q; z+=!)4fdYlgf0pzn&4zKSTpmQM4BO|tQaMR(3RptXr<5$TNwLn2=I9xSr4aDFy5_KS z&piB!Yo#cuN@`OqID7}+iOs7wpC6&NX;a)dH?H`a&*R1%6CkM!(^kX-_ggg<-tIN? zEY|YkwLh4EG;Ilm6SEBt0w{3m0@eBMGdREGJ}rPsYb^Ylz0 zaPeMqVj%GEEjT+dPm$;}S2PP%kuC^&9=}H3=68LU-inJ!@2(2E?(;eA?_!7XY@s@b zQO}NCRKJB`6YAf4ba<)P&HtZrip9x=JrmhY{M}|lKymWLN;eaXLrTWy_}eVX$5P;_ z(w@}BXVN*Fi`zlSKL=zEsAKS1r|+Jb>C4QG90jVe_kXR47N7w#W|TP>DZ8TvWb!T7 zIlGd#+X78DG&nfe>GiXnXrppwA2UFyQ1oFsV-chuTLeJFv%(OK8|mp|_ll04yFxnE z_64SdRk_>=*PC1z&!puv4w|LMok;&|#l!IQA)=wygZ6plLgo=XfZK$Fv{f8l{!Wefnvn8wMC zhU;4!8U?RILPEyWZp446J=q*Qy4fbQlyLQWQ&=OZr)qtnRvj+(w){?{0qwWPZz+GC zQ~67RDckLRlW|;4;~;MgId6@9hG<{T3#ArOYSV;)aHU!n4Mah0494zsMkx zTV&N>RyzbTW`I$lP8B*;65~h*&!A=h*TwHPE;{9Faw!ezdVy9osH$|D8J|AGH-5RW-Md!~K1~c4yF8D*eakNe<4ysfRu*)K6cfIJePwDOt4!A2 z{tCze*cYas2_B!lNe>AH11oI2ay7~xD9VF)MDl?XKoz&P*!u~l*e`k7q)P?imvy+k zz5xD#$z5Jx&FE9gIbas zhJ$UP(WW}3&4W3ieFOZ!pi7;V;D0PwrahAz^Io7LnZB_7f{u~Dv zpZLQ{nO?mwi1$U(L=k6Z(}73OvidM%&dlYoax&X;Q`d z=Icv(tm%I>plLa^<{+gmyC-1KQ1sPbeccvdYj`po9NZMd|Cb2vzo90RKw()le<4?( z^)U!)a5@(^^83-fLNVz#Tu2@%i|Fb$HM*f!yu0h!2i!aa-POo9aM7KxFQlzpE#Tkh zcb>b4vbHl!}+*#V5wpU4(!_dlpc<*tv(lec#ZW%kRFfG+14__T!^m|+qq~dUWWCE`yWGVvGZ9G9mnIi|2k+xDzqJlKO@FI! zJ0^D?VF_zL$F=>>uQqFBoPR}z`89TxEqb$5Xa>Bv%{~BYB@lw72${W2mwgKWM=GrN z_;}bwyDxpA|64~+wXzVsnR zRkT#XN(+pkbKRArmO`GV&WB6O!0H++H@!MGwgWf?d|>h0Y;0g2#1`$t8=~k*w=gVvn1z^PcXp*=LQ$JWW?!tfC0Ry zu<^jaa~%q_`q`20^xZq2WY=*7r4gBoBpYj^pWjz%|$ zf4S0!juQ!18IrLoy{@rq1U06kd_x%cbi*KUB-#lf8YU(ecJ~vDy>bOE691+4w|!Tv zbsvzt+&TRG;6i`=Np(lG!D(yB8wHXdt{aC|aixFa5&Ro zwZ8IC{e<7E)+9!{CGO1DAOy<&4?s=#@j(Haq2w-StEaL+=RE-um8OFmj(6qzKDelr z(|QevxMMIJUk@f7wcf16gM}H#~!D0}FE%azBWbA{V6{wJH z|A6YeX6)RTSq=5|XG$ChIk;LMQ;W0MKMun8za54Oh(XM?XT0fNYC(yAv@3U{t85zF zkIX?shcCa8v$+v~v?vJK?T4Q-e|Cq|!Ta>@g%_Q^q*07gnLM^{0adNRRDuHelufq@ zYN?0R(O*A{7QXtm-Ty;09M;#@4`T0#e6U_mXnL|IgRa1Ib*K;r2F4_qs7FJU0qo(|GBL|wwb+I#ZGY%4@V zA1Gko<9Raf7Vfi`P82E`!O~A^O zOU5XkLp*?^GZ}|2J}o*gc5M`u$!@Ye$+(mI_~^RiG&SGC05fMQ1-o@}qBA`G$_%d^ zjPAsYtDA6ea0T&?>`&_4uY`-RD|$#HRksKX`yH4sTwF&E#vWL6S*@ zz4;a!ao<1#THI&ZGDF*6DE=_x&c1TuV>fNtt40?jjPypbpDq1Lsr~l#raG+eOnrIe z-Y4i0p??)h@sKaEbU{@EW|6tQa(Pt7yT~Phnm@vpRt;%-@{1t00OYk58My^oc~tI) zeJw66(UT3=gU+2g>r>zD#IPXR3h+QX9TsV%G&Ed)KrU1dsxn|vf%MF3s_<~K`35#|)(7$o zi_Vlv*j}npd=+s7^wT%@hPD_NxYge2UQ+JC+g8qv4|ixb{JSG8%SQb!*%=i--u;SPYfJMH{QQ1-h#>~|ifO45>dU*f zShw+}%4AkQUa9LyD$&!f0wc#UiGY<=;S!rxmFgZ2LJ;yuJH%5^DI^KEZ!--r+!_XH z!TMOe7=Z4bv;vdwhDIJVWtTpgqJiS-&dVL=fE0uwc-1Qdy}|W}X*e`AWI2-iG?2!@ zX>*TIP;VIML7Cq)>TQO!hMqlH1uX~Qp`HkYczZSlb$)rBAwFgukBZ)9@OXE9yi9OL zH6n`@`upv8^l>*QYkcJKf)f}1)VwgQ>mHvv<+099qc@ZbjJ}*Y9vFlW%Bdq=-rTJ4 zD+qk}AMT2asGyRpuAE;ii^mtCf*_`O6)JS7zG_|~#z2orG;AkhnB47aaT^QkDRzgZ za(F5-Tw}Ukru^LF^w4JSSfRqHCgPp!>8H+P=DPXoE<&E$Bt2vL)$%>L&If{CQWI)3 zI*jMS?<#tdRTPD|Hh>{O@S~zb!c(6vQfYr&f*U*GUi(`gAJY5oBGPXG{wCGAsK2(u z$3$t6>aS9>!Era_xV zOhojzzaz-s&$)n1rts6x|hQ7go{qgP5ms{eI(RCig1hX0Z1U#NK0f8#L-I>$zhaew(#$8%*rFxbb& zF`Qhfh>EPrj*XAM8$i+MV3)I`QSf={%(qw&;0j`>Q%Q9Pu%`GNo>64hUpx$)c7+q2 z7Xvv>0{xrYA3->CPB`Ya`!+6b*lKds<$F8L4s%l--JMy+iuM*OkH>4HPPebj{JP+z zy)a06@aAx(DZ>I0p4G~7!EgM5Ai2tP2zYXB0XSTcrPo`WzkJ+gAoet5y0PodmAy&r zd&k-#WWwv<%3q0vfftnV`G&-E41sukGMiw6r>>oYw^W+h;(3$aY#!|QZ9k$>2U^BB}jxA1M>(`FwW<)rSd-cyfIFfpnDFbe1)?~*)E zrrBFFOCzQuA7uTf0!rN$s5f-m(R8ZWS~FxFriP||JsU#>%#PQILp=z;*G2f-NV^YZ zh}tm?XPCQaYd3%$H#OHkT#)CXyExXDIupN{T}vEoB*;$l`5qq)k^is02op(Pkci@XX?SOM^j}jFJ4Nl8y%rUE@4NeJCe8a5U|^O+ zkxZ0)KP!P5>F3FFHRj-jZiw^M)b<;800*jiK3u(#r0H)xD_3O$(3t6b8`8P=&+<7j zR>lb*RQhn6OYR?$Za;Uknrw6%J9wRuaV;~B%gQg7G0erbp3NF`W39T+<~zgAG&lK? z@}%Qu0FR-hKHmEck2&F;u#wxnesrz=OE_Xx1qYe`G!|P74Pz}N6p10~1&1ZYZ0>QW zz*l-kjT9haJq@QJ`-;38#p017(LX=`)j~k$PsCq(vGdAK$ZhzyzJHe+RDH<82@5N1 z7_16^tC`BlkOHgUKk0i&;nbg>f{wqg|9LT%nINb(|NJ1OPhqla2!U7%x2N?wFhw}e z?&OZw<3wt+&RokDSUYOB@d}xQRBbE@)%Sjw^(%nmoFLGlP)itS6#Xd3fd@*}Cf^^S zA?2~fl8jh--@gnh{{ARZ*kH7wV=~`v%cZ8Ctg$U=ax9P-3aF2I1r-rns?h! z1fWSViTk{Ar6b(O$OK(zkV3v#K8vSA@jWF00flnK0sJt%cks3WRsQG9TA;B3tk|z) z06G!6_5)Hbyc3l)D`J;Ua1|JI!-Io;tz`2rpSnFl8vyeI$Z>SN>p2xZ%d@oFx#hB$ z`wvDwZ}i4jb$@Su*e}`gYYf`<{m&4u@%7e5k}KK++co=onXN4W0&HvzsFHl^Yla$$ zApD}zaXaW8t$d0_f9-Y0^k)e=5QsT{lgDz;bTY>)u5+)1>JaN9iBA|tq=(34Enrr% zK5fKUu+1C6>kydJ&h|lsx6hIz&IK_vHeTbJLvl#R&WEtDus_FgH%1Q(RF*I_0L|<3 z=91?^^}Wxk^-t4l2#U*kj(`4&06!prTDvSd`eoFcM{l60}W;MYR z&1;2V>S60KdbK@# zR!!^ZPWy+O@`^K%98qZz>ZGj9QXg_s(bc%(fWt1jr(>sU0zWf@dE^sc^_)wg+w zgftM5?_VFSLljoyAA$ygrB&4B6eO$E<dRXbT*amu1IW}d<%v`N&^i1Y1~v-A-xF&1!ZqznCBy+eWoq@BEId z6RZ8_S~>1Q#whuyi^9wcY0c9>1U7#lw8PS08XkN3_>N^TW3a);#@QuOT3K2$z45aC zzisCZb0uPir^qb6k&OqVXKU2t?;dR-u?}=7|BiJiC@M<%?kqKnH~_o17%!L;YCNY* zAc)8|3-kA(OKrM-g+z)d^~#P(NS;oH``4LwPc6YU+x*3(S4TFb!4TO~<;WuXdWG+9 z1W70)escS}#j^?;YfR5po5r1{G=EYNURGE*Gs3!4v-mnT^U0@rXY%`N(-5BqF-1kM zM3Y;Y*b2e%-Wg4wOdF#O&EFQ%Rt-9Q0Nyvq0MTffWdc_%K%A;dz8M;t5;#$eJGprr-uCZlUcuIQ z%E#C>+_P%Z8SA;b)u@m5nNI(&l8>iHIM?CQpU#nd)YeYtbTyAtA%f@%ZZ7WzAc`P} z-R_6+0Gm#~^XdE$%q9jXE#oz~8DgARDE{1o&y1V{rNdPrLq*{9aL0hdxJS2;uV-}x zA>cFnsRfe6!&wh#Uj6B^Vmb#6Kh1E{Dx@?KZ~YaKbGEnqFAYpt%YQU5d3xRudDJ%f zmrFWQ#Qzi0R}|eTsi3Wij%9LXP1f9>~s6mOfc#c?5?VkfRgJ zzk=1k3z;cT5dGbml#~>`Lze{4!{ZD}JRwp@A^ELN27MnIoG|gpQx|nV)ag=qy=$$S zduHhy_i?`dC#U-=&pHYJQ=3`Q3mwumyG3Wh-P()qi0vvkoxt-nUS;Aoctoq9>kOtL zkkub-Ov$%go~1t4k_?bA@C=YnR}mr*kx)ZyGQeFye+~v#Fioay*1J7DAj;hDd5hYw z&J3q4PoPi9LqFJ8Moq0sJMS@b{NQB6h{^8TXK?#~hY120fGSxv7e7mY83Cr?n}Q~D z0~jctw{&1@d-dA2F1KSyj!LL>y*t-eX0ZxD3vewV{q_PePz`0E(oCZ|-?!YKfq`Pd zWO14&=?IMcX}NS-5cqk4At4yRkRX%ZUU4Y?$KCuFGlNE&R@{s;>?BCR1n2x0?MnI7 z_0Tjz;f+?@&gj+?XoOg`Ybe?UJhvwf5>pY=5QbN8()k`kFVI}2GtOi5;xpt1g6Z8% zF=20IEK`hK0zj(_@%RKqKriwm=on5qxi>FJ1QKfMd34eM%dIBb#>rBT&`484&P-0A z9(Y4k%xyV8=L^qq`QEoQ!|v4>E-8 z-qL#~DxskF9H6Q%!qclc+b}k(&Tu4?K|qh5ygyY|%dvm9`9|Kl(6JLdqA3^zx5)v<}`CbY(d8g&jui;svCx&b9d zdHmDq=*a}xEo9$Pzz=(m|Jt}{&;@Q+hQO8rgN&UWU{q-x9>GCq^HwQ)mv}ii{zf1J>94|7;HWZ=Cc) zsm_EKmiEYlzex9iL=ZXO2TdqHL_|bPdUUOfqgS@hgSR<3I83@UUB9`!@fd3hhU`N$nwP7Xm*Mdy^}$|9%jd z{l8Ph{|_4WQySM=J}{nRKMnVN8!#6iOCOgj6^InXBYgz0If;4xzjYn>EBsb<-vm|n z9Z`>lFLcqdQmA5&9}_Rp=C*=LT;nZL`~5FUZU1Mvk*vDD(qd9mT|b|It{9t>T8Y~X z3#r@3PC<&v&#{q?g#Rm(!BOUae7pm8DKkSu!!IJ7)XyXn>4VXNm58W4@jwxOj8w!w z%`|@lP6YTKy{`PRm#1y{VHQojeHNEMM6{B{HaIde65)5AxU>{|5Y`tK)(0MlK7vD! zHY0co^WUO+`ro2@7jR%;`UMAj5dT*-KKd?f5xQlS&L!1M{<9YUUwg0ryKVxnDd0`W zMCOg=bo?xmud%*(qJrtpl>!SJ!kOdDq8d`X{_pl`!7M2IEhrcI2 zP9+AJP+y@+gx(vs+z>Bf>;T4%7T-{6=5%n8$Hnx90avraa!4J-`nqePhI7%DWGDON zwVo}#bnn7EHWDi=RP)wVRnCP6jTnbFr&iyD!q5`@tLfYd113MS4LW)Wh_jefQcWS{ zYzXggsqcC;gRCw&7_akVJbnBhzg>pAya&r7Xex%?TZ~dWutONG!e4V-sk(z!a zJ+7{u9DfHf+i()fwuP9LSaxfh{FWlQe(PL`2i$Pwm#>g`k==UfEHx&T$E$M%r@}Wl z`NfM!N~>3*3JMDFxl^tWZH7#uXw|xtw(Rde5UvjuuwBE^IjP6!iRa^c7lze7ebf2X z!Mz4zs&BgGifIc;n4}M|HiN*dh%cyNJ+O6t(|U`$)U2LEDZXBk zNkJy6pE$SW z(E1O5PPk2;#XdF2qO8?3HmdmaAVSb`tHz-mTav*e0lwpQiBewjd~_To7K zr{P>v__jHR`9!%iOYlp<&)4+NQ=_sCWKxPAH5>;w8)ay2>g~Vl)ULL#xOiVe@WA=- zs_ZMhp|j6;8&iu)O;R0W!DC+;0}gKay}pE}p7HpOFC}hCI}G0a{b6LlZ7@uU_WVfw zZYGvR*vJivO%WUKLXEVWm6hUkI@RGbr7Vq~ZQ3JYw?@Wh|H9vv8y=~ywvvfDY@iFl z#+T5dZsNl)+_U80W7MfM&e^W8`QfyVkT&ISvpuz%)~>X@fJJe!tq_wx^VYauhTA>zm9Ab?S!PnuWtdaIg^PbIW$?e0z7^J-A~qE0}zJ zch`P(*s&+Njp$O^zBbBp_lM0bewdr=uZ&yzsRMt#n`L6PTx;T-Za@tT320}rU+0eG z-NnW_^Mi(M?cl*{Z-}M9V~AA<%Gan#OxVVrwcDbbntta4g3p$Rs>Bv^UkQf$hPc_D z?27bQq@WroG8Umicv6(q(pVOsH3S{rGs^!pFC(5zPDDg=d17zU0s`0_mpGmejWJiV zKqB@vwcBsMWy$N(^}4OBwGERVuZ??cwfKIqUuIIlKiRkRTk$lKOwqASxKn!>1*MU1 z){UY`G#SNV@<|3cyX&oZ61MYW2Vp@Eao!eSDV8*oIF1hD`4zN@zdY&;zJy6;)D?ei z9$ic7ItF1LpWI0D8$fh+|0`L>HchVE(o7We_u z(hRt)7n}8F+vO60Y@`P(!5)iN>$$1yE2$z?R+GRecirwjD&D%$qxSOBCDhZI*s1Pr zwCi{XRx$QD0^i7&>@Q{pYao#OfjcBH`>vL84lwy-nn0g+xBJvd2S^ zQT^f49L&CAn@?V)R{QId6mH~}S?Kg_4<$@Bpo%}ef^N^58MHB}-6ueuiGLgK8J9JO zaUz#aU-+9;A3xIWKHZ9#4ovRnUkpg7PJU{Rzw*hY&|Q<1zt6rIb$^ozEjLAK^|zFhzhs zjb&cDvqBOLcl++jFkZ_IJ9h{1n>t3=)%!W$ED{7Q5Rk#~qfQrVRYDBPG$MQ|t=I7E zaXFvCg@kM;5IpGZ{(NUgt9Kb9mgZdE=rqEz#A-8ydxVv&^ZhqzhZ6IXdAzLAyHkvJ z+j-5OtWJFO7@$4d=`C(79Ky9rQi;A(jOy3-{6p~eZN02PJi1D}YyNMNiEWm(%Jf+t zZ;Y*aEKYg2#Q#wLI&RPq)4})FdJEA?uS<_LleGG^4FAVDS56NRZ+37&8_!6=da4Wm z<~4!D?M=VDMGT0=R@xx~f<;j4n=7`*u^l0DT^Meb?Vq`IKfMD@*3X7#v$e7Ftsk|G zl4Qi{y_)RX_yA@fpck4#_gP2sW)gq-k7{FzTUTmpnI!LEQ8RbPM9>{*1YkeJTkWR9 z)%&UPr1%uK^LA1#`scQ4xvs~!ol$sHeTEdb{CYGTsw!BQpQKZEnuKrbpKc+t_?l#* zZaMdY=RtHz08zNRpXBD8!fsNs^wmXcRNx&RcA0V}w@_8O9y2Aw(;|8Fic#*OrNYuJ z`}78L_=`Bx9!mO%_g&nA$JM{aao2GS45VZ$fNnJecR$ znX9}*%}|m1%rq-K3_|o<*pPTI8DYEJN!K< zRQne1svZ;0G;~Vd)IAwAF3MZ$UP=qn@_Xp@#+4i4DdCbQvz1WwE;0A{J`Ho-%xsH9 zXq&h+!C(_H%R^I!+xVqo(o46pCtguOFfEHtCCzZP-hh12O-xjUZjQ4k{sdYl3>-GL zC%Mj8eOL=V+d66=mHjDUt}xQqXQN7n>5Y+4d-^Y#`>sChl5GTIQh?4+F!l#(i#V#grvn@3# z3yTaL#GYnJ<{ka9dx7tKGV$PS)4jImJ_Cbvq(N(4Jh;z14?n0&HtCR};)J2)^fD5>2ekR!6z0SFaBfiKZcS4IXG~xbg`R2P0g%naj zMFY0BWw^S}NIm*xT5ml)yut= zHZsTM6}hOeIt>U2;8FIkPv2V8R*Bt9$`E)hD}(vQ5!4X}-UgbEYop~3 z2m9J50!{_EZET=|pad(#$p_goyPa)FJZW&lA1mmE2Si&#W{vGwfW^z^776O406#T( z{&BeQOX*ISnh_BJ=cz?HO-Nq#L|ZByjXs`Q(Mc4YsyY*eb+T3*2g5BF=rQKMnFXeP zg{nZNbDV32<*&-Srwj;IPzgS2$hHVS<3tn`EFVlAoJnid4R;SXCGn1>#z(~Jw z|3|fDhmLY3)l?G%KNk3IKN`gCj0y9k?imqM0aV7rGd%CuPof=ZK5L2Q|3w0TXc&mh$l@~x9(@JEKu^u=pk15&kR?Pcq`x}%hA znD^^E4j@+@iLz1I)$ESo_uWPPAbz#UIt`^ll{JamRm`i6h*d|f+woRAP0DN18RJw< zPbb|Rds?guboZIaqKO4aN$}gPV7woad)TIsa%S(lyv!Le8z15zlegur&j@{}C{xql2;TSPg&NAXLRfA^+0Hm9rZLRF#HKxH*%xi?mm3T=HJyAg zQrPUq2;f-(8{Ycoh}@eI3tH9AJ$y>-usr|SU+2&=gGSh|lBej|bnpv$ha#P-Jw${F zpW!BOcrC-L1FcZKv3%idee9zO6o^$XrtiGGczSr^m%w{w zB1f({kYOuwLcA%`E*snEu_*KcJM$5L0v(oy##3Kf``f_~PqK8%b|s!;e}6YuQ&nI@$u&x?&gwtG#%aecRlwm6!D}&|4oR z^6fMg7qf--dP&jzJbw3;Mn0hmh@0gLIVN%^GnZ09HpB3K`n+=}0lKMgu$QYW4K&7$mC)vs5#!}MAkfMYF#|wmG~R+A zho5y{f0;{yZ^}i(*q%m0e7sK6@<_3c+}o!!I-d%Jd7Ez}jaMxVyZzXXB0jU4bh)6w zeo6)-{BNWh?ha0T4oauvg$9qVOCh`%F>lw|oSv#{{kfoLo!oZk=xq)%-fo9mkyTw$|2*5K_hQ0`q*Fz|_YB z?Hh8$H63-`Fl*#3Iw=BmZX^dji;lz6m#)tuj%u|fdXMHMU_;7EcqiYtM&I5HPh9xm~O!I1A zDkwG@-S7kSAAjNB%aSG}BFfj`t23!`T+U~LyP1_-BJJl;+XL3%@d zLk)JUf7$q+Vgy_t@Z7t#p;$1Jn^9(7qgr!k>nCEsB#MD=bE2LpOWSeT;z@Tk6l$d^ z#E$Eux{X>nxH86|*@v(hI{M$URKM^XSh%Yd^j*C|i@9!ykM?IlXc$zL{ayE$iQwCm zKN5s+nyFNgKT}vSjnJy>e@YrKG5(BH{~z)c|EYBNABLp=@fZJF8V4n1KMxF1;mm+@ zBS$G?u&*x+`IhHge@`2W{V;)c!PFxcjJ6w$28O~tB)QM>4k_u55C>7%ar4MW;Hku> zbN$9jp40s&@P?S!*S3G4Hwb4zu8}J2-wRNc&y=vBGPDO-M>z2++QKGP+Gi>uN#ud@ z!T==3*Nz`QepczxT}Em_zGASvgo$Tc`}QYA_|M&rEsC@zsV{XmWbBlnDWHoh<={oX z87!I9d6=+3^uTi%^!qj)i(k#g^DI_D<=t@0le5@KV)^=MJ^8_N2Q^zj(-ns+w zMvs$k8PYWxg;D9&S>m+ku-*bB)5d5{#-a0W>!^|mtB~uivVyMl%#t^~(!Hp<3jvRi zjfvSiPN%WI8es3p2f=@b>KXcRwcL3q6J7!?!<6jpgRMXMIV@ckvD*T1{P<6b_z89E z(TKS997E-qw->(phrW@Jqt{7)@7BYBO>KdkPe1Kr&yl-$iRF#F$l19Dz3|U_oN~&o zR1ZYcXKbE>5(08b2Ff2X%gBgZODN4+qeh-q^gq*(YMGQVEDBi``)jT4q_TtUwI74i8r8u^g+O-0iI{ zwIalZV$BP@)u4W-BM0Bh-e@pol?XY3lcmrufu>e^xd7+WaL{u8?(RAHi0B|yjCN&x zja{S@3(K-3B%ZK0KWZY%oA`r%p@MiUYJ=+TU;4CXFX$M_`CN~|JPm&iw8biw%Iu4Z zZFANKF61@#dkZ^@tXPCO%8fYYT8gLRnO-fMAtTSNvR*pwSA=rLnIY9c zWIff$@3^uyVB)RRfyvG;@3MKG*2BLq=yEI|w=(Eh$>X5Km?fXI0^E=YGSxslSU0ejaDF{B*>iW!Ox8XK2y=?m0XQdG^D?Gy zW+%}QLq~xl(fMOs`Ce)dcJC132|3TrfxZCOzLzSeEC0R5$)c zmaOmBu9I)EaB->0kB@OP7)hE?X9~L^R$%50!3lsYGBQc%X)qq@CKTo#O!KL?J==#x zVt;&=BZFe|_vRfIford*A-J*-SjB$i$3tU5D!aKFjmk`JR7bv?yH(2(hUF29x| zE9Yi!P7yj<+p@EiQ>N68&cnqfd0H#06o>Qj3y8~a_JG-y)4BQrf#T ztNkX1nL*3%uek4B=W{}g1ypFVv)N9_*3TAKS*a=Gv7$FKM^_yPh?&Bvr})dw{oY1?cflbgEpv#;x|lri z_AY{E*6xRqU7pUb{iG8F*)0_qFps>LAp9Wk1)Mgys!UXizKBdidLf_^IBp5t^@T|qyR()yx@5)!LCP@!KT zeSul=Q%fd}@?9chxazFvW8|}CSwxeCfnZ)5-(o5|B&P&X+f#S8DR^7=BS*2@^rOKf z4Q>Yov&8Ktqt#7eXOc}3(B@UzbR}OtvaK>*OYUqn96rS@(z)I>eM}-$Gjj6sX~!w4 zCa;M4FA!M|EHYKdCS)27)Z!)v8pLrf{4d(xDk`q6i55-*1b26L_W;4&3GR~M!QI{6 z2@>4h-QC?axJx6!;cm`3-x&YHeY#`(JayRRlaUd{l#9Vpu%xJ1~8CG?e*7N?7`n#CpPnFU=&4=OI18G&Ogk)Ch zX`E+pz*4DMnf~n_bPX6-m@PFJm2&)uzGSVpQsw;dnRYH*fi$s`*Zp;*o3wBwi2;Wb zG$e&#-*)5-=~(hM>3C!g%u<@q!PV2jJRS!8bw?A3b&{QAYfZ*;I4buuy>^n;8TC3! zG}^ygHqsCiX9FsPXqU>SRoL6Q8`Y$ueqz2r%;N`Wd~PMB_$1jiW`$;LYMIc?KWcci z>=5`@M87k+?x>9h1_pFHoN8^lJ&OKHZ>Fut%0wV<3Tl%ETdJN)Tn9O#T!RtEE*7ck zDz06rBHF8zK2s}a6WraP8LX9?9Xj96|wc-=-E#?7Q zz->5BX*7%kWD+}%?6wHohBr&j3Npo|g~3yBP9-|wj|(X*`gh2#4+W&@jPi1G2h3AB zw)m$Kay+6%RN2>1;`eKTrGSh2@mvG+4A>R6NHPjHTFp>VQRwVjFG%DO7#|--HGB#| zYdbKEYAQEe156-3K0aQk)X|Zu%UbLP3=i1(k;Sg}iCdVxhc(HV@WKFB3u0WfVF6(; zlw=@getI|q3I|ltuK3TNOKrj~9*FWHm;B!awQ&`V#1|A1r^ytN*g?~u*1VTG0kH`X z!NcsT?z(r3q%h31C*k$7Q*3wdHQd{y9V|EL&V>NrcFI~5sScHDE*_C~+wupPT_(@dtBgXgztoJG6IbgB|{YT;g}aW#J`T>a-cgo9K~0a2R=qjrVXiIUz2 zHs{=#pTd>b9^o0D$@fYAI4-!>&K zxADq!e1{4x)v@)hxmvu52)XNR5Po;J_4v5b=B04k-gHdIZ=m-<@mW0(56Pkh^^$3W z9l%$BS#s6}z9=qBR9tNK^uq6q{%{N-UYH+zB4Y3t3z`lkYO-HTV5v3QE*k))e`Y%s z&Smv-$XwR?lh&f+TQ{n!$-KvH;rj?A9pydA5u5aGSFhDZrY_R>Ba3ObQx;pqbm!4OJMyZ+Ki{ z5egqv~Ko6%9T##1tWx>##vw0^$)xZcMU#WZtvtMzIZCozURVII%*{NfI0 z2sH8Lo%&~OeTDJBHZ(AZib;~-0{V2#zM$3k2g{3zir$`Ws0MsiD9vQEpDs9a-%DF( z%QM8Dm;o?ygSjfB=r#ee-=9T5RUGyE>w#i^+5SPT>Bd+2%v`Rs8b_;D5zC4Ixv+o* z#gSp#jcs~@CV0I|x$YGAxC(}paY{EngxXr(a0<6Z> zJ#W_bqrX|7ash*5osj$yAqDKA6w+0l#0Dicky6z<#_tOdT?nOU zZe3;JT3Bc!+i44}@NtsQuNZ<(?cVZKVwsG=g% zhawWtP&AwZu&xx^8F%%)x91>0(|2n|B2n7|P#rA{0P}=eg6ef!I4J&2JP>arP3h8J zIyB4eknM?jkcMFnIuo*^Pg>E5u1AAnW+pn%i9Ph$cRNwx-1i<<$V(K4Ybcmk-l`RF zupvr}(kZc9Hbw`9!N0nk#&8zylauY|4Vh%lj*Z>qT@;Eq?ynh<4K@94kdS`&D+ds) z&H#npjfq$wc%(0ufF=0F>;Z$)3rBV_eVV(0kqcz43+37BCgJUA&a0`%X8g$Luq9j=3xife(c`HZjj zAK{zXb!c)XF6ZG@*WuWkPiwLj58Pi_XwU(xqaN)**gd5*vED1x=4EKJg(?hV(2~2& zT);BmEzqn=U+5;?Mq{4{i4-I*k|i|LzDYF?J>&IS7*UH^k-=@hbrdd8pZc8ENKB#k z>Komj6=Dc&(w7sZW&P-Z2c`H6f9Sp=~y^M4o?gCITQ5;- z@;FP7PA7c5C%#D(GAYsyqPJg$uIViFb3}Y_o#>20?GEllS?1~A)|`iXNgn`>FMa(Tmpk! zI`1jb`fOs4h!084?{O4sssJGSw@$opUy)?4RENH{MqF~hLDjD6=!pZd6CvuCM5B4f zZC+P5c^rBZ50K-ElhKED-QuW?>n*sSZe%|5mRs8ovEpN|=xid3DRYXf5N zqw>4Pl;DXUmGi^U#++XY-lBLn0HNcn^V|o(?P%Pdm?mInN^m*;?G3jWPWK*wbe4-= z$uxTmvbs*_Wb}seD*pJ%%%4(z-W;I2!1Rkl z>Py*=d@ zy2BGlz!Lkd+L_RXz25snm%M*oPVtN!at*F=s_|$D$#OtWM1;u51dV$=6?`69&P-jH zf|zjH=d-|tH?`oC5_fBV{=FB^O}-8LO!o=uhm_<4 zlY{Q32|u-9da?YSz=`IXobn~b_McXXk*zWoA?{s|AP9?D46U6;p+(#cJnKQPfzg>T z7Xc#X#nG6itMFfTD~pgU2eMq?Pa{EDVI})_qYh=?A_!TJtxV_A@|=+#0-qt30&^79 zfcicK9cy{95s3r-H^IX1AkJz(_z{OoYyfY@+Ovx7$b z1?A(kEjs;-4wmNU2E<%b3W3vu}`z1l-hUDz@4 zi7l8I>ye4|d)JJWn*~Cg5sLW_5SdhZx9AuFB;ECHBT6*Z#a5lkFU^H)0tL1h)^VHg zI7Gq)Z61l>^Bdwm$)<>h*R-^7?y>g;z)z(O;dF-|{oq5Q>&r-qiIH*f&qoL&6#tSR zmXDTlO)K)OnR?XxWwBu+QmKp%AHqn3`J&vBv9H0uBPqsh68Jv!m$#=hlx1CnZx-m4 zP^7u)Ziru@6L~^ZXnDsijL%j&Ggg>wI!AZn`)>;>)Fbk5t~Oo_-Q6oN znWDjU{iUO&kG-cz@lX#9#NJ%Jyy*HMexRtUYi3-J`?+j^9-oeK$E%;8?dscwZaQmS zy*BR)RW8?(bqhKkGQs-&`3bTAqcxiz9N41u#x)|05`JZ!%PSlvBL9_^X@y7I8fh?M z2I~(P4xIqa7MCNn3zmf~@rrWg|mI#K&tv%A01iWjUW=n_e2)L3H;yTQWi65G% zZ#)2pkeG~z4&bLVVpn+_y2tO6;plpc7sTH5i=Vt`ngyP|e(=0`(=RYgxkW8PBL2Ty z2jqj4sSNhe&{vb3Q%Ok{9%>J{O_+s@Zr{QnQG4#o8xA3(cP3jN75I7>Na#t^;t&y? z8Nd8xWSKeGHg7Y8U#C|;E=ykv3!^b0_Wjlic_P0^gmi44WnEC2>p0GjC1(^cy%taBsbo zY`yJnqaB!G#lvQCSqTB(?y3^VhA7JOZ(Ml1|1Q3EXbziY`8cNt-j3t z8t7y0^wjOFIfj6E&?D>ce7#~1NXjGY!&1f<$r8#s*otzq+EQu)ki{`eY_QYG;HXPYdBgQArC9 z3A@bL7<6TvJ{Zvt+K5si&z{4O!$AguMP*8=-od`b;r{-7+GMPTe5Ps;^u-LYEtljK zyxlx8R_XL`DCjP`Sc__iLV#egFego;CP1v`2RiNIaD>|5bW`3y@xHIhpCkRMt8>M> zb*pn~%rkr$d|!#N{v5U`&ejN}dBM2%_i&}B^JZsWGqi)?O-O^`b6$Dr4}a#H>`P2P zz#q3fx*Zy=Lx+xxy;k*q$M!{f#1=u(qilatR$ps(Z#1qPZSiC@kJG#+6bT4&y$_(> zYu5OZ?@vK3b5XFs;X_KhYj$DtnIusGYk+k2=d_Jz_y&WYsfSHF9RnZpp3eRTK86j9 z-Td2mcpupnEtEaeE0>Qt?J2L@8dMwR6P<6XGh@g%Ijlkv`>_E+w6aQm&+gog z3WAB(WXAN~KVs)w!jM3f>dvi8=TO1c*0x8bLq+=F+oLbo)1ALDEir?T7+h$<;3?_% zj0n8HXZcv`8m)qe;E%Y0{ryN#KD3hwdgd1HzGjM8T)QpaRgZnlH@X5{L~p>#6)iu@?%1X%9u*i(a+mV;w0+&LW_y}xY6XvfBem~53ETS207EWCNdklC}!9BXcv~9 zsG-%Zx%$NybypdwrCz;#Xz=2%D<^2rC>G*WuMzOqqFFV@w9L39S4KLVAcO0)VonWdN4#m`h;T^cbavW^UJ?Q~we!MA8n zYw+HHQB0f&Lf$w5sF%}`c`aw5+}~U@d0Z%DQ-_dX~-Al zToqNgYIa#8=-@use|osa#3C&4`z~N$Z2I$9esSncU0p>*mQg57!JRz+ARM~!;^;#F zH*{g`dA;7xg)~NTg~9+@s25$ER1+h60mmNGksbQOO`l0R2SucEpTp0H&Xo}M4p;6g=~328WLQ|l5}gHV#0ogUjD80RPt8af8rH>V#a!os~hDq35UFJb(*L-?lCNX6Lf9yV_UJZDO2 zUOyClI;-EXk5TovtBmNr2>P&aQrzyUjfpshCedxR)C zDH)MNVJpGz!Jf-QN^@E3QZ?EGFP0`uP*t_$7Nuq$2puiN@ zu>FA2*KWZ(lK#%Ol~03riz;Y|2@R=Wd$xNkEd$Og-sKNYloHVx-=wA10$MpSAGq6% zql?%GJ74Hi;Vfe&H>5*uc^j-xdY2A-yOFEnn=x$ElpNuFk%ZnPlPlJ!Xc%G>V{6pg zk@N;PptoRzI@MI>O$ukNY>plFzV-Eu&DDxWC&gc1-B9T5BICR&DEKgbVGA;K(-)~i^me?B z<}CGoy}EUhK$}Ke*xlYWtyg|uDg7?bH{{bdVk-BG>!W%a21|XmVR{`4F86C?uh03} z+1d1!a3WCI-jfsM`{2iYHW1mHund3G`OL+$yn%U0+>9?rII)P^Qc|PY*I>LUKC1?X zj~Z&3MzWRo`Ak!3a37;uTJ}3VG62kFGp}lg#UL1sv+X0M0>yM z`SN!yMTuI^@nR#gE!4lo_DD{J$7^Co$L;S`J#!taBQ^B(@X5owArFw1dSu zCD9+7hUq&J#%Zc9q0?N@9>;LlBi!A0k(3s7$_IARzbLDmLOQd1SJ8p5tAO>Uz;%H9nH0 zcRB2oIs1`^mP*&c;}a!hYh)t!xFUO+&BfNNc6$0gEvABE#d;I!1Ji=RU6OQ$S71N6 zDh6#xLGYKJT!P88+>;Z`gygqsOw7fqKNg<^{>KFn+ac9wCy>!T^%@a+|N2&`tNkM( zh?SMKQ_`(*!$NY@+_36C&6#^_DkUK)Bk_{ExTHo?NL$3c#O=*1j-J(*+2ll)y0XXv z4Oj27T0v9DV){9S>F3qzSlL~-!StoIhHG5G8n=&<(`9=H8?rh zJ!1P(5(l-&KB(U5stuAZcfQ3a#y~^ERsZtE`AFjdBGB{R6@;pE! zF(Cm4>Jo^6FyS6#^wb5cD!(@<1gC`TTm4WnIu4tczX#?8P;spQnIVVfMH-VT=;&G` z#1?2B=^`X#oV3D~zE9c^Q`FLOrvD>1(i-9CC*;LPkm41$qBQ4bYl{Lb+gAb)NXYj` z^0nslu6aYv8Xo_vzV8+s0|Eko(gQ{Nchv-)0RaGlzt?GxE9;VbO{QZ67q2XS7^Wm~u(PT;f zHIPbV(VjRApmPsTU8`XiBE4z9H$WBT5}yFGmz~$g zC+}k;Fp34!hdj~hhKS9kKmDu$0KXm*f(_VkicUYOuGsjAGCI0}pvTmbA3NKq7hZ2A zDXN&8PsiiYgs_eUMJHxI6BAX^?K>1-9$?4I+A1N0&;)*LtB25`VI<=59>G*YUzO%; z#~mL}Dxjd|rpSQXcCR-!~(8b_1TJ#%C^@xk))qy^#05!?vHY*9~5IU9&cJrpTCv<+OafK^0>AiSUD>Wqe zqxtab?s%6G)9Ojxh55y3!czV3Y+!uma(J*>Xmk+M4)T!gk>Fv-cXWapw)Z3CVyupo zwN*?zKg6MkZx*-k@qinK^f=l9SS>WWGIKibxU->&4XvK?eO`BI+Ccd2ba)(1$U0(^ z#Noki*Yq648wG@6RmL>_D(}wS1P2TZ3@jqnW=tFvC8gR83utUX1swL9u4;QeFG1Wz z22$~%A&<^ELxf#DA1YXhGM<|=PW2LG6HlFv$J=PFDU2YTQGBFPxls`F^8gr0Dri>&q!jU+QUKtvJ!dfzt;@fX zylJ4#kL~?V&_Dj03%-Fc2e7drqNk=Hp`+@Wge3%$V`^L#(|a&CT*>Z1c@K}TNbtn8 zQeFz)z-~IV8RTq31nks@j5`NA$Cbdc55Vlhx7o2> zOQ{y%F}{64o{}9Oa+7};>RnGmS^og+!a(kzu+L-a1NWSk@{(b^4LZ(pHiM&$8AOVTR>Wwg&uyn$GSI7K+ocC7Qjl zfdSVxH6~w`_hX?zl($yrp*F*&7vI_0^Zg*`I!jMeY=+HVUoULNOY>=`Z-8}M~7cS+61cnS=K6K{WhHPS#+x(uagfLH<4uThVt4*ft3_t zi~z?GXCMq|WZb^#et(m;>kPoo?1_*6hRZ3vfr$yRm)Kg9$(fn~D|;gq_GkCq0M^?^ zpwyO|B57+|oX{u#+ZzgUZhpR--MeOWay>2ladl*55<7E)^9gyjv`-1ltjs5}d)^98iRq zr)T?Qy;hY1b@9<$rK&I9`FgZ(AHY_zv)A|Cr4bRGeuDU^N}N#0zfvzbwORpw?~+g6 zN6^np$S(9cJ&Q>}~^Kh8NL)F~gLe zs?N*oC{Y&J@bL6f_MXM@9?sTY|s;?^9zX0c#99(}xLIl$%v|+fez; z9I@X^;y%%)va8bMoLRv3FTZx(H*$Pjay*%vC^j`3ADR-n(NaX61`+V=JzB=5<&dGPsLXN2*uv-h zP6Ka0gNeXp9hs&4bF!G43~ddGc)Xbli93#mWle@usnI$EUb5#T5s-G^_|Z%E7zzPc zFZ_sL|Lt?YOj0^(YEnXQpA8E;^PpcvOmKJcNj{|~Azzd=wpW z3=Dwaw=ZTxrhaaa*BxYjkv(gUnjo5XuHX}OGbf4a{@2htzwV5B{+>D4?>wj%3I}x% z>5S8IM&vM{Rj--P>89xUSss~L{%}2HdZXXuLl0z!m*AB@q@ht~bVyX74Hz9nUU(Rk zu*i<(OslUQ%N}}SMu)HA62#5+_FP5|1{xj$F_wlIbV#T`o4-dZ4K!bcx<%8$AL@&r zjTl(Ru(w+#MnTF|5CW66Iv#}ZN0ZtmPS6_N{WU2PS zkB&45z603>kp+)qch$NBFr0$DyylIFyqFEH#HB5@;FtW23!P9>(xM4N!t*c3sL7(f z<1j$adh#OpG=2u3{vL51fmww1aWmJ@?-;*6i`kY=JLg}9O;cH|n&>VZRw5(Ic^t$!%e5HjmV!5AvfrA`)>-ao zy#S&;aHA}X$ooRKeJFF@RAp7Vzjxi;r_4c7Y6aNlM4mubHr7m9Zp(vjH?D{b3=`EO zq;}UZRFy>e3&6DosEPj4lEwC1CpUp7C*d{J0}~A6s&DJz-v)&Uf^MK zSulYM0Mxon&Os-K{reUW(s6?;q^=cGp`8!D68v zy1_y=v&-7HJ*{2~sU8F5+MNP zC?_KWK#_kwBi}8q%uV{ytHU-IeTd(ve=Cy@J#-{0%Jb2Wr6;JoRqdB0v6q(s>8@8@ zQbYC4ALy3Pqq?0Bw${%FjCu%oT)BMXrgbG9FJ6TsBQz}d1wdniN9Ym7a(2mOdD@`L z2pNDOfFU9NB7vY4p3~@fDIhYJsJo2yxhF}U$p|FwveKMY854VWYq zE+~E??l=0RgJYv_O#?GxlA_kXuF$X~T$2Tf<~ZnAp)7L1f{N$o z<`f5fD;Zi`XVagmrhhE>YAzuT3;-VFID(m(a$ubYic%mGVH!(6fst2L8Nh`#pw_AJ`KS2qBC8s zL^c3C0Nh_(dfq5cIgVjaYHhhCeuu}4)YLNKmkfuDl1?NkC|LAsswkNNCm4Fba0?%u z9!$N$sFc%W&qH5b9fv1al6yd|P=}iIUbhosR8dWB(L(5RX@OBjvnzxGL1$X`?yrM% zUV~1-Wk`~L7O6MfM)x$t<@I%mJRYhGkBsdc(>;{Qv#(&b&!zU;|F{5g#PciyN_P4m z-HN01xT^G;`bclj^9#Qrsr1gcY`#*HuOG!&GBU`uddiJ1SafW=r9YdWMEUcS(-W1p z636c2Iz{0z@EcZXTUwT9hhhhy$Ry*2hr+0-vN?Uu%KY%Vnztb>ilFL!1ST*!?dy8_ z08O;Hs`4R@AVm}cfROHTIiYV3lPZ^MEULG@$8%-!dn2FrBBHJk+Jw13UPa96enTcc zEF4cYaeHgPgzHt49KImRss29P7I~uTaIs;z)4*#BjH9~aUTno&oZi7i)g?bNllPnc zi_g96A4xwniB3Y4y~PX^SHXoWXKNyxGWk~o*aCvY<);+`kuy3yeqZy+Teql=n$6DC z>emJXvsjDX0Q+V0js=AdKUvQU23kpIV7|ioK0S*!-qz&suWbyvf(z38;p

P!0+Tajs2llhxJa)w+t#r}ezZ z`S#Z{PS^1!V0y%0b1pF(m)Ww5^YhwRmjG1pCJ=Gd3LrAq2WZS8>W)o z-BHb+pPn2)>glHto#uRTiv_YIpx5W+kFAa?O=QXpGiB zhwO?K*!Em4CN{Cravsj{t=QgJbCd!s0p6rJSS}@3H%qs>VE2iLEM6l2{RdZJAC`WC z2eNqP&+x&qbO`8(0#+($nKBk70PIlyih-1Z9LRAL^S(=I z$m}32Ke0rAmL}<)W=sG{1bT$L%aFI6@Rn$IU)wjSuUtXYdD1ylU~zc=^AG870U_W2 z5VI3jP~>2tOM3o6QHqaM2UBCCqYQ=|`d_s_1de|M^}>+R`g=RmK9GMRAra?N&gI7Y zM+;9VpG*M*>@~b%#PhxR5>Vsw`j2VY6fg}7_~}oPw}Uv7_8C`zsED*oD5|d58c?lU zwu*6=8ozu;>j0%60K?TgFcc!-PbX1K4uSlS&j2XP<@Z@44Ew$R`Jp`nX*_bBboMRX zY0g|!$FsL-Ty?_Vg(ki!^wWI}1rmY$wJl-g)xR>xz9nVp&&#MQmB;8>Evg}#6_I$HJLH; zVS1HIUM%T^&naukVlT%4%|6c#PC6mEJBTm%3!f+XM<$@bD2BfsSF3)X1^U^m5hDyT zYeYnySww#;Kt62sfxE!M;!x&ifV_TRz52-#Ei#|fZhfPhI5R)5r(a0;3reI~=pptc z2QzJ-fQqmJpDM51cd7R(g6<@AOl(9H1Y{Icq>OzM3jIvtB%WL%>r_3Kv=g66WpA{BP# zv(&c~5whhI5_1&e=#qbl18qYl)OTF}h0Gwomz;JHXf~3*`}euHmINY)uzwRNz*{D< z{eN=knGKDD_+KpGuUGv4f#K?ZV$**;k`9b3B2b5-{}YEEGjg)}T8BvfbxD5uSVs5B z_WkcI3gr2vQI8UEP^GGqj@4@hJmG?whR z{!ylVa77;Mq4+>U%JUA{^>d#hGL05==LrTa@b$15{;FNR2=&jr{Z)eGHC+mH3e;9I zJSR5qAIlS>4jz~eo)d(PtMen0l1RCtSyO%06r5Q*?5Fk_7z}^k=#6>3;%nMk!gC#D ziR~dK(Sijs0oF@p9C%#zASXcd%*o12%gGtd(nv;8Py4>|%S}{hU5ZC?W$3f1gIYn!R!Xg|20 zy@k$dw(pXXC;|YhomJ)f8p^iUy`fy0AD8_i|*vV_WMmzwYj;8 zim2Y!FeAUPakG_HsKs%W0DY;}etlv&Lk}QR~H3xc9{;}K=}|85^rxCCZKOmR+Nm^ z$fFgr33^@Z4`AXlT4*mu$IIy&v(l2q?S@-j-z51-Z%C($?rzL7QfrZL*fzq*PfmQ;5)Hc;X3tq4R1ec%qVWMxmsru&&p>l&T!<)pcrWc#zV z_+g)V&OR4rtu*K@D&$y?q6QQ5f2O5}u|fq`XWa87`l_=&=_yP+Pf(lI`jPhu zL27R7h7Cc9Fl}vYjOB%MP+!YvsP49Q#bT=|B&4YR$9*d{#7G{3rhMeSTcP@re{`Xo z=5WC-%g0Uq2#or!tRPMMg{0Ij z!(htVNja!m%cwOdbrZgwRT(K0LcKrzto#19Sox<1V>chunRO+?{L|xjfby+AupzvI|Q{qyo7F){H4*=%&Fu)Wpaf} zOOe$N*M|KLb!Rt#-Rl66ql<*F%F1-1z=74>m(p=*&(VWE&B0X9+Y(b0R9Yx->pq48wOQ}(-NgTIz`fJOiwj9TMr+zlV zvZ?nWs{H2)_OrG= zuSDNN!;b#B(xhl|vQ=!>MdTUGFzc2Q+ zgI2(T)3L^;gW0Cz_*hhCTuZ;N80wk&sM~S(+MQkR?Gi%^ag~j6;5ZE@oQlI*=kj$* zLv%NZp7_ifpj@x)N!+(*gc>N};$GKeEv*3aS(kh2W@!Qs{t|o=Q~Ry*s(@e0+XMTw zBl|QS&$8$%OTSf>H0A`sdD1LQPfqp~5=a+R3a=ET2gUiHRA3 zXrqyM7!VO10sx2@)kn1k2O17)jipk*@iXfjk-Hr3S-CmX7L7&yBqb)wCcDM+KgSgz z$|;+hn<>mT#~V~JMG4XGx?XtdnVPoqG5H$65-_$7r#55rGLhnulN;(9cD!arL<;w( znk{X{PDpjA^`lavCs(Yj&sd|NLBIBX zj4H&81HPrQzR0h5WLU{v7~UR&sa%s1(Yu`Rd@{Ki-abX&AeS*WC@j%Vq1jm7yi0=7rRVRs6(6+*rS&uqfkK;sJw`bvIT;`_~Z^UYWbXtsP__E8r`H#F4v)NX-oX~78_Ui9T3e)m>0?OG*$HKl;H{%{$sigLXgkccQ%UY&I6xO_>A$IxI4dv4%jm>?^k?Qo%dF>lkW zB>TPIi7vyYTTOJ^L{!a&Pj12gck)@DPG*PF#CXz7O?9C5@Fz-(UIo!E)zUxmEKQXR zO>=ggb^~SdbhneqQyFp;Z0r{`_SndqNQs|f1rHoOM_F?&$}kq%5`|dL20VFlWDCfL znlV2{38kcmRZa8_!<|heCJmW#!0#^1`MNJci|V+(6o!$`-%0uUfP0a(D{XgB1iHw% zTe0P+nIjBPZ-vCrEXlx1mQZ;Bn!etvBs6nY4tH01w}6(ZNmruEQDOzcW#X^)R}tA% z`qR}+Y|$Mx`-~o5|cHqW5-Sq8nK-&1`SosH9wu8l7HayezM` z+N#ds@;Nrr;R4N0%1Buf(q9QLr)=FzbCHER``PK5@)1N>L&HvD9Y4Ql4l5bwt`iR$ zXc*|2K=VH`QDG5Lp)pZ^t)H3r`u)ia7RtsyO*eoX8ZbKf>1DLJGNfjh#!8Ij){hgm267hvd=+ofB+bR6CO6bm)!FnKLff=@aI)QS zl>ip=qK3N?AM}QZa1W?#h_-K{<11etlQrTn!K?B5`}k==qIF6 z@0gcy9T?)f?m`UO-TG-L%f{@Cjux~2yq89O|K_wH6{_2;b%D2YVPa$FoDI0enl3t+ zuTHpJppr|4hl9TM^mHS4!fZyt&Q5-Np+rv>7_LUb?G6xv!=9S0vytA7j|Rk1rE*P= zrLX1XUv}kb5;+{sf@Y~VsZ}p8jsg4)1fV8Xoi>-q-AX6BrQSWrQ*Qh^zQ#)nvA2_!T---t~#$9zRe?NuNECj5?SsQcbzNz_F zNCAqpTmt=&tb&1SkA388><^IqyjR{Nmsa^2ib3*)?5l`8L;Pr!QgWf0vF&*chd3=k z)$~iUX_9Z%Cn4E*VRVT&vhhiBJvw>WkRODES^iG(!bTm->oYa```!VHA15I$ zIef48l#I1Ovoo;$8yN;mH)?f$dOIezxT4fvho?RacO#N-Ge1Ht9S=~29QzVz+U&E%p@i2VjOU9*$uffi^+9iA-dWLh;D9=Mjl zp~fpuV%{(lOnyz>tn=7`cBMmhUf%aWKEzLXA^W~$v~LqZ(DM4Q?_JJ@d1GqsNvp(*uPN&!-Y{%$ba<*uHyRg z9{fdDY*-mbs85?+kxkW+6b;KqZ>D%Uv&0wnW;9nib5yhF^&Vouje!ReWA*jKC68Q| zij22%z#+qNVku_ahTa|)zoU~UlZeOadN)LHP318}^|ZC|(8AyJ$dpstNs1E#;y0w-dQ`B?tX@n?>#ZfsVU4s_+qf|R7<*}g)cBi+m|N7>2hjSnu6W#Vm*;yM|OMPTw zA{LvTqobpMeyqD|6>tGhWVTT?CjzE$F0X?uN(-ciimTJZxwxE1oLrT;!BD)R?10%+ z4Fpm+$nLWvKUq;$O`lsF6B%xKxv+W!A9fZUY%A+1(cY0uYQDR^@3wSACM}&YHFaf$ zRzm0Y%)u+2AUnkDXP%#i^;vh2(uIsRRA6{IS3@<`U~-G?^^QrkFx*YfQx<&(jqjy% z4)aH1gBR-;f%Geq@_XiTOM5h91lkmSCCrJoMzh_IvxCj^PScl1qK`Ln@y4Ue?c$<5 zGALOFvUwPF(B+86v`R|cV&+LH7dcmh`lQFUT86lo!XD|CRb|EDFfGd-wLc`;t<^}7 z9L)m?u@9N6N(LGqlR1z5n=j7TX9GObapvPOEO3KNVn40rtnSNW48#Svh){6LYGG&H zCL`WtYrm%8oO$l#P36oW8%YrueOgQ^x~70G)JCbw#z`?0q%g zlG(f%WGI5fGZ=gZ1kxy@8cBz%o@1-CC0*5Ob6thq>m8{bLvrM5`-6us1OycTt=Lnt zF*fY#bhDr%1VF=C>Nk(24vUP}72Ni&v&~-3@Hsw9$o{c~iX0)LK-6lXMO@xiHXsJ= zJSOckzp}A23%0E5Q={(s=Hwvyi_HeUqeObXE(*I!(vdHGdr78Jj4kq#IzNf5w5;h| zF2~=CR9vorhAYN%I31{7*6feT4`nW>3ydRj?*jzc=v%y~TN>*ht|*MOs;uCDO|iIe zA=M;17%8g6QEm1gQyfh%Ajv2*{gJ|&Ey|W=Z!*zqA~v(EqL*QJV3H7*Zcfh96>)xj z%CP@YhSQQ_338u$M!67+y^T?a%uc5Fuv+u7i5n4QAjs?XCU4fRxs6GC1Zx{_BzR@{ zgrq1rTSA4l+uiCSxD9F93ct|AK|iFeeZ)&@cx zEdx*{?Cf+*^yE=VMOjG;plX4+tYg0n^79uplWuXOaII~tjPJ`-op{g?q^2P-@OBj= zuB3u)*)k#nWr?Mdfr9+y*t{JDe2e|^<#E^PXIp$1L;iw%<2innIC)Fjg06sM$jtFx zojAm=Q!JkR%Rc6gn#;{YSH))%C-&;9&S*L_@kJOZ=|~O>rcfMuowg4RP4dpuyoxj1 zBT8&Ej?$G|=|;KvzmUDsx8$d+ZwCA&;RbfL=qtwS9#>wPtPE4A!kUh<>M(jDAn*du zrSE7_i;%I7Ql*&c_cY9k%zEF4YZC~(&lhWL!@L||ZE*mcIWr*#Xa^=^xvDG$H#<@Z zlT-(z1y<*VjaosCjaXUm`}1S9VJ~Z5vna%Qoo2IE8Ea~0(hyJ;WvEnrcWFpck`qH` z6S*pSD0LLJ{vq_WrwB|J9lyr zZ;wr-rj|+wagEifR!O1d=@f1(Uk-Pka#J|XlQlVLX$0;WE6mEcoDat!bEKO2B@MJm zSt-}VdqH`j;Q}p&O$oxR(j%*Dx6a%fa%idDke1A!J$uiqKa!WPGJQ?|DJk!Yi!sup z7=TJcx;EcaU3I_7uE5yW*2Wd_g6~Wgs|n>3br+18ZW)Z!SJDu)*CTp4UtKW= zj&2(pj{n%hZqa0x=U&TL78(mPtzo`}Tci^C^t;)fO#FiRm*TzKaUfoPP=lK z?epctSqe;wippMWB{>na$NmbL^iRF+*>f87h!%d(AMh@)nP(bB<>zP1v;4(AGIfka zo>Dv=^a>Zs9kp^I;`LVBa~|KV;eE)!02LLLRF;Tpfn(=K*?y!a6xP>yBm2SiJL-4( zbOOsb{nO-MJ-qOL$r-ybw|qNo{d8mTDLgjzl>*}Y6*kxt_>(1gJ&hfj=fOX}(NW8P z_xvLJ3nKDTM0D%RnbY5*$VZzItT}mcEn{piJw(<~ka@6?TfF_M`@Qo7QyYC#?p6Qx z9lWE;d@#^OB&C6B#r0{x`MXz^!T(Pe2%Y_(mRai-!V>sZuHfJ*d+?!~Z)E521&!w2YK6<_8xY91_0H2lGmK9wt4;suUoX#B96 zA(9fN1u@$FLP|&xC2)QnK>j9qcmI;(=B9u8IBV01|BceDzFglWfgPTVnx%Xz#gH8> z_MUNu0{LRdoR@^f9#;pR9Ukx`{9xfKc+d_{(29`P$mx8uwi)wTOa$uf?CPfKL^LWR z) zK%~4h_Y$+OS(xD(zgi1CM@l;#f;xOYsUeu z1oEf3M6H=7mqVmvvR;)d)y0?wEMpY#q2`R`9@nd7h_5gA0awR6w}bW}aJGVXcP|Sm z?R8>@y8yuYHKLIWK_OlL`678Oz=kp#*Y zYo}3SjOLD}G@08xE=vQS;xOxxj(7ejeMQ0b7P||+78PR#nygbf0@1a6>rxh4Y`sc0 z2EgHBFo`{)vB~;;qeXfnhBUm!bpZN=@zW>ufozpYQxJ2{c=x8tzGMop+g%*tn>(L(5sH6hj@D11kw4Ml2Cd2kK z-c1^n$)^30X2CA&Ji_y(UcG;@faAT+g5;Oog6VSOUvz|#WxAW4*UL2LFA65jrl)}; zeMGs?^$Hwq`V(9C)+5C9-Dx%)9UalsjgRk2ozdn3!EH$5$&q~$p~c;b*Xa~b0C9Jd zy4rX4LeaRUJ)q}lxs=43U6Pl#y)-;}Fz1xXsc=(CW+Y37bmBzji=KAy%M?4_dv4Wo zM(R@7LlH%XMwm-Ca(Y*WM!x=st4+E3t-SY^r9n^KN_P;p9Eapl&fBUvBC|^@=4K!m zC-{D6T(wWWemm=r&E1*T8~Bu|nVC!rQM~RHFh)eFR#ByqB-9DL;d;5yFcj(sWTZdN zT&7Hk1qDfM^o zmD2XX`RaJnmXUMV#7QU~F97$2r92bk1tlvxDH(CNE#0I$SlGrS-&OJd7Zt97Vkza*S1iU{9cFO&9RY=u>k@Tqh zo=Yw;7OBZ%C$n(x#KO@Isx*?n$#~8_()9mcIuyoV9>X?<;47zjP>%obG% zmv`(?`XP1IUV=GvS_jziPyY_B(?}e6GWguV(!88(vVs`8dYQi*LM3C zq2NH&XjG!gbxxKwvd>)M4gSbIHivCmWa)KIjR!MneyqxU$J1YOqIf9z-~1L1o!&QQ z@M>W$)5_x(OKi@iRw$1vhGx}0aW0uOJK2D&94yrEpKiyJrxgF zT^{_23$C0axx%Ph%MSnadi68$R8;pR5maD#QLEV)DVF$~vPg|5GHV?J36GhY!W=%P z_CCuBv|ktkz^-V+c4`s;6V^6 zkI_*RZXYKy=&~*@4>{{+PfO+@M59t^;mOGQkeun4%vz z#U=s`K)%4OQaHI=1FZnl<@bz#j7Y{Gr zqx8g7lNoRhMRHUj!?HImFn0ywiT)Vrq88PtKS~U)ib7G?5=Q~IabWfm+2poS_@txW zJq>39XkYB@?#fpyx4|l1g0`8UA%WDMbmf4)RKs9AnaT1U3yMj?qn!)QU7&=WJNX!U z@@H49yjzobhg8MR@HRe`T5E!-2ZpcmSeri*A0A%g^@AC9hlct37&;|y@Fpj7*k#F~ zh)N2LcG|3p@y_-oec?r%-y=?WOembL-JM8!6Rwrzr;3eY7!7n_o5!58BF9Ud5+pFY zxN+VA8fKky?knbSLjMwqG#4{k_^{rgA+>$(;WF8KPuj%1pzss6L*83AxGaK@|9&{c)c4cATb{V-w8J+zmmR2PN{;^=)V)p=1@;JAgBnQ5uYy712UP+^P%| zG1T(;p{z05Vg`P)l|e6e)(@_QZ9K z721uiwC)AEA&DSvmrgL=Ey5rWjKqn1~0G{&-4F>XMTy-``m?{Ri>EMKktu|G9xgah%($|rQLkm%qLPL8mI-4c%0=HUok|WzR?!c`&KGHu zM^TYyvDtK~^K%hlwJSilwQo}AD-6Ad=Xbd9;hG*NrIMZ=Y>*W+D=P#if2E<39$k_@ z@rGcgB|C5rw7!;;bt`M*3#(G+d27z2V!07fk(vm1x;dENu%Rq4v$;yb^18QIYGG!E zC*oH#7CR9{BfaV32cl(sq;!F-FH8vgSG9h(+pX#owWe-aiPV|3)Lc6fsgP7g#tHw8 zAJ<}SxI$mV1Na!g7$foiR9Vtv!RmTnbeYL1>#{;S7;8Rj;7?|?Q+NPg12QMEYk~$u zp5F?KNJKML+_xh5&gG6s{DI4GaOk;VWQj!mQ6tfA zrf;48b(aKqIOCxDJ~)A^ML0gjgba#xZrFp*}Z z%XX%Dv-IH=SQyrR$YfX=yb~0tCX-|~D=ou2acLQV|%Zj4#qw--+zya6OrCzCB%j^2V^V77k~2 z?a?`yvy*wq5s#1>?($xLjL=JIuob@h@i04UBvwOK8TBfU@fG@BELZ>>x<*E%`VNQ! zHmoj>z>8LTVwK!vf4*0jJ-Gq~tunFCn`($#-S)=3Lc(e8?+BCF__M!s!U(KnHRSx_ zRFoN1F>EMsv2F-1+7W*HLyl&wckK0#Yl-Vxu!54$bjv_lex?_*$&ZP6+^snnhJ82m z0Ly~*@Vc!}MXE-o@}7pUKmZ~txRX0&M&+tYdx8F^!J)L>AuW^WrTfT_G~sHhvsArqFkq3WBBG;!Iz;b=e(e^?^!_PDqC)MHGeY z{l6*F7sB#pbqBVa!x5Xd)r>n$0u?$!6h2}sJAw_lQBhHe zrt4R^3m+(?9Yyu3K}b2n`O2YU7=u>wb#LETi6Jj*Dda;YkzY9xOfQDfY4E+*iH;}c!^YOQX{!EI(IRNSPC~UvhCP>x3*kEpz$fK%MJe)mNnLqV|E5#VboZ;iRuh zX-Dbht^DIPRNF@TqTv3*VuLV+d`xEeRM{p_g_spftos3yk3B_~_H;^7{%|7h z6#IsuQl4*MTYes6|HLu|?&aI*+i+M^szqk=wJ|J((Ou3e9-SpZ{IHUj{9<{Mt}bmS ze7SlHrC&-q*2| zYVS{=t1#7MA@A)U8>3e%rj(_K4m8c#hSxMP8Lu(g?WACuZ**A%qYZ--P^UWbPT9RI zwU>{IeF&n1Z6$L}AYlOHQOMV2iZ8}4W?3yE>xaxewN$I+ZwQLJuM`mo>ZA4DD3qn`80Nj10dTSgJ1V0d>)() zn?F4}+Z(n6%C6(pt_io#5&4>N>6X?rc2}98j(rVBW|A=88#{R3b6g?iXJhRf2GXl@ zR<@{zFbTA!P>f6Lk@qnKo522{TzllJD*e+v3)Y0PA`$ywcANZLk47~>*MtazFFm)u z?6nxa<*$gV=9>?wE@>OEyoZnm?Q_(Z7|ey|V`_ztDJtctfnk0%Atk?jFSp`yjLMmz zkJ#r9ngoy!XNNFJ?3Uj=!6^U05>HT#7_$|cE6(N8U%=D<1)%Dw=*Mn=Q?9ZNh`04e zp;H*?s4|ktmCi`d+g3w}0OW$c_?o$jO&TKhT(eENft_u>`G!YQ@i213nfCUtf-9a1 zbUBAJc{(ee$KuJ&5_!5-^O3`aMTaV!>7U-06D3q{+unEWzqTm|#+YCmGvIK&p?A3X zRm67D;AFos6wzeT?~O5<1837mw@ED;&-e(b>lZ{MA(hS-Xo!XdffBj(N;Hwtts^!s zm=?P@X*Of2=HqAUJ4l_d2duO6u4kP?Bq_vrzN|zc;UGM;5Fdj$(Tc%z+@`zuC7ur( zTX(&)Va^L4RPmC@Ts~^Vf3X0A3e=d6x$TVpDC+#B$uPtitOhU*e73Y4QJE)=N|9J2 zd+InLC$}?IDkO2Z(3HaN*6IG6WX^QK4~-@m`S(m^ZptTD<$29{_C{1{1<>p66pk_L zIY^*0k-7fT$>mz_UamakN`OYGkils&A0O2fw3G9!EAW{QLg;EtqgYDQ)m85)&ZAKg zx*r|^iD**Y*44v#Z#c13^JpF&8c{u-j+~p@qY2yP?i=Q_>+9>qW-B#Sr%POxMm^ES z+QAbAOH|43jln41@91#2?BnGwG@v?tFV3hx<#`<-U$70EV7EVIW8RrgR%i8kv9x@^ zh{5=9|Ni@Mbm*X3qvH+4tJ8{v^w~24nPS5T`I4`|5iIlB6^q>=d!a;Ap3kPy`93&~ zHJhWJ-l~4x*w|Q4*O++rKxDjZOvdC6pGk@0(Wz|0mF1*XtQU?Ike&`jH! z8^V4Khr>;K2FVbYScUq;R6-2g9b0-y$M>~LTBC)N4nIV!nJQL;aL+H*szrVMXd-eS z;=!IKjsJ+HV|pjB&zsK64*7Dwv2L=|wOg2*&O}hZxLe1|!J^a1PE3%_5wbX#n!t$g z=??|rRJqxa`}t2bDjok!OWm=ibb-qt+-miWALjw|xk|DN*|s*4iw|7~m{O~(P7mcT zmgEJ(nZHj!wz0KX1F;u2S9-BUF()G3yTuZloX17qHM}C?ul|zdFYqdpJE2Q2*jUm@ zw$XXLS?5-j7ZX}C1M{V$9c!u8`n(bUS}KC!CG2ks)rug-eqgQdfPuGMy{22!Rwk;?@lI90Phg`>w2o7z{!>^>{R{nRA^F(n13 zu1D9g^fnwAU$h1h{ay&*3n!N|nJ(lh=E&xYcv&Im{>ht7wL4t6#9$`YbN4qWM>ZPC zFW~XD!KLCKLEU%kqol@wmd%^D+&u8uF`rK-Jp1IXryw)sJ~!_4fNz4s^H@7E_fn^CF4 znv}@xV)rUyUek}#(sy>48Z%oyS_Mb9Y6r`uXF{qvU$f4!Xgi+TTfc4!AAfCZY%Hpz zyj=Zh04V4r#>a<}&x+{A9ih_*IIqN9hQB9oa9^HMDE+`)peaAMJK?QlV>Sp~7{oYZ zy%5#GV}P;JKX7)x;CRMDSX>gO5KIHvj!l1C$zQlyGgRax!nY8UJ0ql@>rUa{hz}Mz3k1?ZA?|I~ zKty>Ai6Wvaqcew$Y!sc%&`>0v#<0}Vk(WWEs7U-OqgL*Oxm`YiG7t<-%2!C@9~f>C zeT(1*t!kI`JO}kIs>wqbta|u5w=tR5rZIzBwQILXEB)+XG*y7cYtLfHo(!A5z{&hH znGY(X!DQ0j67K}Fn1Uzjper@H;A=d-#=#n3>}x?Kx~RZ@*p31XG`;UbKG@ZW&AXpb zT>2b%k&nwgW;Lj{(;!X1j7*llk%=sC1aY{$fJS($6?cj3k{JYuyh4yNXww-SkXS0q zCl`QY5&3L;r|#syb##h3RM({s?Ef;(vyhlvp%2@fU8BgDww}>w`T_l#;VdI^?W}^@ zg5G7?0Rk3%N<(q%Z?Tr#u$G_vrHifB(gESof6>xA$fxpd|Ne!A+ENR`oz8VR9B7D| zH}`cwmsPr{uyH)!UlX34rj>hIZQCbnc`xN$AeM<@C^UFAxY|P5(2tUPsG#-Sxz(h0 zd@7}0L4gf#;YkZMLp#OGmrC;D+4&zW^Wl8dpL_&aC##AF1k1fu=fm9>&>qx z`V~~trYcXAvL0I)cYh94l+Ms-X&%jwQHAYqpYg0{n)O%m}v?cU;J|Xi&b&HYK zd5?dZhVGKjRCXf}M}5;!YDP}C>!sMrSoM0h(oAcr;xmqpIC^cZ>Kyji7kSxE+K3r{ zMsF`+*^QIkE2+JTY~x4{Pg8A06ho{p91CE6!t3Q>+@q+i>SFz-(VDlR5r)Tz_z;z% zDDf0MZM)f8)@Ye{m9T~Pwn@!svvF_Tz7bCrn~cDRQ%c;<`0qvMQZS6G(IcusXr#%h z&9(rh7P53jBWa=^|2U42ixliyr&pzhoi{HJp3g3X6O0YX$hsi!gF$?Qq&zEc)asN2 zmoLU4xm$P@#9R_M zn1_wV0G5=~Sic&X1xm-uN0Ve;|*o4B~lTE2*wTjP^$gMN=h_+ytjKXBB$t zRPE(@GJZ<=;LjyR)+zx5N=L;ce#8E6QFERPIbT}2i{pvMq`p*&Ws*X4P$mSOX_n(T zZddI#mE>Cy*ZLV0QaJ4KoR?Ixgaea&ao=KLsi}rH1~(gVOr?0UT-g^-$XHb~BU$dH z3VJUtWo`wY6v@QAOyU2%|6U{Y(=t_Kh)@3XAJz3y@w}L>CT+i{!GMICn}t%6-&B#q z)bVM|3_Uk9eB}z?*-wUJiK7%T@jxuB7Zg#A4kR!p@c{`Pcwt3U2^z9v1R9d*`^l;d{A z6h@37>QtdB)I_6;zCdNnr{R>`CXXsmY)(q|95XQMv#QW=Ay23uz1$=)>-g1Z>`E67jKM%@h}%}s{akP* z2B$mnZc+cC@vc&Ve6?*fa zjzM-RIYZg1t%aT|KQ5ZGxe1q(oUKGLTSym{B3Sa40Zj#yMA%fe{U|q6oF$!VD&PE( zQ(eWwR%9%f6rY7O3^cmtUG22Xd@q8zAlW_5+J|v6Z&kCB_?>>HF%PElmH;W9zhjK* z)7VZK*&XedtQG|t6<8T696W4nk(e1t&$9-GIX^?U5bO?V_mLAAM(9Z*jW&B@CbUm% zzY=$7qwh}Mj56o6y6dQUb3Dm!al+=ZUMTsaf}W#YSYNSZz+2nk7J0ch?>UfEC+C}> zG|(c;>l5_8Z@SSX{lyf14ngJ9PCO zwNqC=LoPExu2m-GVw6OAM>2nfazm+KfqE=vCRGSFa$0+6&gcL!Ze?=%I-lJ>No_xU z#hwjm*cWH5RGs&`w#Cp7DdL=zl(OQcQWUdxT@0-}Nla`qAMNzbhGfXKlmXjGJg1FM zry{3b+#^KQGkBe6_YD|fdMV)G8saL1*WCGR;p;Gq9z5=~$u80busx&eNd?lvpD!Sk zGa=741Tt28Q?whNluxnMWpOt6#U_!W8duo2h5k-QY|#?bY^JD8XQd zfDjXjD9BlWVdk4P&W{VJF*CJt5nYqLCrx(N;moCcP{+-T%pdheyn zXL5HEnVC&hmSD?fqq3QJHcmO0U>s`uZi5tvL(;kZgLJF+MBI->!;GSKC$b!dsW8fo zWygOg;5|@INm5GSDatfQM&No0`@}r0HRhPr3i=4yQN{tO6nln~I;Z=vnD4QD3ckzZ z_4n#-{XfyAW5pVhWc%|}O_^eHLZ|fqfI$B|nuzz2?;-3|-)vtb@p-)MTw}KRNx>9a z1ijdc%Ea%BX%K5O+AgZ7_vomrnPLh=?+-7lK-o%-4|GvLY}z+!#k0Dz@xHHnm=Sb zKrd#oY-X1kQk*o0I_l32&0mxDiJ-t4g**Fu=KQL02nu$Hh|)f}sT^~8IRiJE59q7Q zkl&oU3QQF~Ln>}Y30hnWPJ)xT+-UsMx6Kjh__?_`7Og-nixo9ojj558r0=6OK`2Q^T+l1cT!073BPH#!)CY4bS7QC^c~}_s`C)+N;+@D&__c9qWwb@s(V5pnJyc6SA=@_IrT1f!WM^lgxlCF2o%2FXLrpH1fpN9`uwfv= zUy&a|7>#TUTl(r-q>iJmLpOiKk8f3Gt!OsL)&htY5Et#Y_X!}WHyr;`x2i>YhpZ~4 z*FBe@=155N^{IDA`|@X0yoL3locJ?(RVpEne0DC{=yE3s`T8f=j>CWM%8Y6j)%NL^ zsN@yfR`1HXV!FgH3Nj-J`&$|Atq;DF8dA!ISq4`US8Y8xIXFjdYQ9hQZ#{%u7IB=W z?ySPjn`~7#2wC78wgyjohTb|xlEnB)L^?OtiuJ(gC~F% zc|83~5yNt+;w-(rFXG-5Nc$Z#vWmU`Qwvz_EWlQSR*0L9y6KGsa8>W|zZ8HhnQuD9 zAo@Iw_g;Wd74)YOK+M6IA7?pUWyND_GX>Xeu}9`u#`egOiiqF&_E3m7jT1%BaKP{D zrJMXB)st?f_Tq>8G#Qu$-IYK;`(@|~4AQ1BW4)@i%-M;nd$J>7uZ9!b4MPZ7>YDs< zVQTJWIQdgFsS7-o&v_8I`Q+|sA9c2Alf(N;t56_DgArZ&_Vx1GNmv7RP6 zPo^I*tk3hj&bRzkFaS+4eC@ODu0L{$l?pAR!DWkHTuf1{a zPE4SWras&4xYs)2eYgR9Q7KK1<5bQPHdmjzVG8Arr^8Ji+Ba^i3qR=Z$~xujwpUwr z>4wU8zW=Ee=@qtuS2sXNmzY%|itW08{ zPuSWGn8;8cU(M%{k&MC}OvoG&6W-9lII&RfuqV^-UnjBrScKVN{fp{q5^Ak?G@20T zijTd{I^;*Z;qy%BeBI~5azZV2F)f6J{nf))P~a4MW&Bkf)kn(k=?NE{LZf&-%hPA( znVS!3NW73-2c3~C-Z z%oc!orTp|)#z*S552%#0;Tanf6M8HGC;S5YlYO0xopU;y2T^r`f`&K69Z%hJXWbFD zp*yqufsXJk?p>v)tE7CcI^Kl8_utOi*w_>q)bYLbtbW8N znX5i#sosq!)RsvjZd$R}3OFo5n)UyD<$wfS`I^h+1oywx1R+A=OXy*hB=z9)Us1aZSIM-PiW zWho;Ua3!T9l6m!$kw6hd60z4>_o#EYwyIIYf*P)Ur$bj(mc*R{82~Ltq)> zD2`59Mi5n47I~5n1#WhqrpTY@;=QkIBhPnirr6D-r>mtN&Wdg{-boiL z_E}Ef;$>cM`GT=jG+&`AT6n(tgpXUD$xt-d100*(7+i?4y#0-tpYcgx@Vsu8W4avC zu$xDN`{{;EzA4Jlbl|ejU0;g|doMn5j)NvlTi$Ne)4- z2A!s!Z_#pge{NycIrK2DJ=)8?46^6~^rI^EulIj~TK&$9O^HWF9A!=R_*T~qw#vRx zR<9mNi*}^KQ#Du&RTwa08DnBB4d&k(t!63=7R9awwUr6P6;9Cw;k04KfHavVg$p_v zng}ghIhzq>APMOFn;{TOc%m$3h{_mo}KQf zRsiBe#y=V|FeU?~scLU;?}yllFGr=j&_EKL7jNIbO|60(k$k<@^I6R|U{SE(Jl-kC za%C_D_2Pz-Ei&l=gAB)B!^M-;0{FWzEz~b#^e=}n!Z?ztIzeet0V9PzA*+C+y{R-A zo7Hf@d=++-9-t|NrwDpexK9nxvQBDivu9qI4rMB&W5b;rXC_?~*D<=9v3I7-YM$#* zbq=RHZB0YTrBfm)7cblLsYQC`VhAV0W*=ry-ykMKc0qKpY( z1^e@*qM}91lBh@d_o>;6vGvjErcS?Z-*wM5qOK;HZ)$uyo9DP&=X#|vm!|IW=rUV> zBqG)J2h+*%jzE{1<&$Tz_f^qPt_({;I>2}G3HCDO&v^s=>FzGA?s=RiWZXcc@2i8J zm^B7_Q|vJShHh>@x7vcAF$3mk6yGe6#H4BK0tJm~!^B=<2Ip(&IU#COqbx6;-I65{ z_Bzn_V-o_PoZV@d?>VYy+9hO`+jRK2oWC*@DUu6?>cJgb?R!Sc%~-=zPQ60hETom~ zG=lfixD{8ghR;6qmIyoEjeD(qwBcHI0_#uJDympJp0yashza;>XXl*L^R>Jstj(zd z@>a>usw5sWn8WhE?#@Wy!Ia?BYlq z+8JzS@+QNts?fI`qJW+uX!tHG1Gr^QT>bTVI8 zplg)X&|SKL8XDGX>6E!KSy{O9zLHNf_+U%3U*l;d7O{}T-5JL@BDS2mv<5|EOHBfc z(aY@VmuDhAM`&FXj`)cjzW$t^MF#BpXBPjSdwKP>Wj1<3*&eZFj_eJ)t^%NY;>azR zz`Mv}_W1Vrn=CU{5@?~DLNjE5Wpo?9xr@t4ARp-`n>3-I(igoP?y;xdDnT%*5%n;` zUr@QlP3U^u`b5F zsFqiU`@CD1MajGop%e_%ZtalyVyMOQOW9xD?*MhkVXsKSS68SbD9;?#^$mwRncdcY z2Z<+|%v(^Vmo(Ae7P2ys!j-o$+_tuEIL=yI2FVnqfs8F@UO zkT3^z7%i?I&4ryWDp^Z`b{tj-dvt(QICc2PCFAxom(!PcpR`>jpnGZOf=^JiTg(pV$j2kC@ho*wg2fV>j+-u zyAQyRMM^YC#ok3bCB6MMMaj$Bd1z^A2PVNnO;DPG(oz!A$KM{L0iPA2Z!E=CT{nb{ z;r2ye2yVMU+Dl->J$@ zWNNe?&&`oj?QEjX!FicIpr<9MiK~9LvNfF}0Ry_$9Myj9k`Lo4V$(by9C-%+h_(sf2#peC_I%3JOY`Hd?CaWZ)egs8@r=1@Nm$o_Khy zt1XFR7+Zt$K!>Ne7(0pI=PNu3lI@x!rcwt7T9^uz&^4Ud*E~<=G?FOkSw<*0-)!lg?dlDa4QVZmvY?XMIy1BS^l7 z(88#i0Iwx@=ya161v+S|`iP$t0`lxrP_H4P(`~1AS9x%1@sC|$VVr}5BT?94BIq+Q zay%D@wn}wt4TV^=o2$p-UIjNKxvux-+F?0s-E z7^!;DWWHFB!{Q(xUk`Hh1J^C=zMOs5-_3O1Vp8%x$CsJEdC#5giqV?x{$r!~`qb66 z>Ud}earB?!=x6yV`%RrQ!%7v4j_>m|DwJYygjHO>R?~+#eRG0x>2G3bRF>z6%|{0! zE_u%Zn{Is8cD~_6$$)2Ox5m@W-NT|NK_*f#h~EUMmVk0Ez|x%ob!-j>?GIP#-lrS6 zmrvG3AF~>+gNQq%V&3DZWUi`;8*`u0{vS8WS1r)LB}eT!%iMPNTArS#gZc&ZG$(6b z{4>9LYdIatH0jf)JLp+_(8caDbzS0&(I+Bz7wmQkx z2v|*wXE)$ZoqhT~TVBxfnw^f0F6ogn?CIEndSj!Hz6X|i1zR$>cNm*l|0R>XibzfM zomTKp750pL{dT5Ni2pvZfYluPS*mcM6)0ZC8om|I=@ap$RxYq_1UV&Lg4SnLl0`bA z6eyQ}_OGt*6%$!K>(&ag^*TUd{rz^iTw8kUPRRJ%oeBAW&SB_);o>9l_-#?5;3@T3*<>iGcxfKT^GeY&2V|JdP*;o)i!kTnd z94cQCF`}idlLbkX#i`z#(F~laao4=2g+xhTXG79ST~0pnBiESwa$@MC0(>a~V64O$ zPA3#NNAwY_*&f7d3k0wJaq%=6C@Cp{j(@fF{1)NJ`_-jf%k4LYAY(`~*`iX;HkC*; zAL|})zu5KeL$?9V;=b>~sNpkQ)Sl@1+D;d(Q|Etb0d*`wf!$kIo_6lK^>^R57f9` z#Zj^7*GAGn*k<>Gj2`Of=rHNmz8w<2snpv{i|v6W{U`XQ&sT`17fV>0O7vdqOTKMp zSMScSYE}mEGh~T<1D62g!~8F!MLlV)bgKIt9+!_LJcnfa@8Y2}4K&K|N%{9j{xM~N z*O#r>7(fdub)lE65v*n)yNO9XX4?+$Nunq;k_*%d!zSX$h^)3ysbfkJ5Qbzq0})~r zEo3ImA{hi>-xDm60XUf2wQhL@QRPkrphX8Vh?x>gS5S)tN89^QkDIxR#OeE|M8J@= zQqsBqKk8xz{v<|6*6rW>Z$V zwsUI?Vq)qQIX`E7QzH`q9HdYF=N_NGf4HyD>x%dJlECTtx$gJCEhXvQmXq_w83{J* z`Q_+ha$t{o`X77L{yNL0;9Zi)-@+ahnkjq0n`GeLP#tbd`d@~n`cC~*FsNpZr0(fk zUXE9P+p}6y>-GlkQw{*r`D=p=ac9pfa8Ag*thelgxl5+6D!Fm=`Z zHzm@48KlB(I2jokAz=ZhG+k6f1x(gy+Wx-yHoIjnp^J&Y*kxlRzbpFXbjXOnOwucn z8>$^u_w?EAM<)_dw;wH6@9l*ro(4Qzf(D)f9TnvjoYhsFV7{&@+Rkh&SgDKi^QHq2 zR^>Tz0c`Ndyn)&t)`i&hIxV&x>jLK3J*i#M9A4Ldyk@t*wF&sF0-r6MVgU;9T>XFd z#O+XaFfsQsGxcuoq+Q98b2}1u*!{Fq=;8flh_}3)rMYH($=GM2Ghg_uAm1}t; z8=?L2gQ+Esu`P0->Ovnx`+r|@Ra;=HKpV*<`#=(VH{$59O$yYcLz8)z=Vk-R3=BYW z+8@sh2`}1VVw%{yUERi4cqp{o%!iKTpUG)IQOu(~;uv|u5slVD5*Z%6YX>fXiGJH0_CqT!sFv626(B}z}xCXXfOfucbdwOPe4O`Ug5Rco?Le_@40{48u$cbxkEmR zO8Ju)U%mzlao?2A?bU z>H<`;=$k|VZEt@_l}aU=PWkRV;Qsyi5#I(*D&(WX^LuAZ-(AL@3X*jMa($KC)e^rW z&f~*8`Q7K!+TXV7XMkS%ZX{0sKt#2@0=g^gb~ERBI5xZZ#QxOlvIaW87}46-+k1X| zE@g0jZ@%6=pC(U}MKj++Vs)I)X*Wuor;%@R3Tqm%5l~>T=;t0qEx+x$)j#P3`-g0* z9H`b7WP9nDKq&Pw-e3EpU+0Iv(^;HkVb4;HtFb8a>AXK+3BfbJd;i|&U|%DU@EC59 zH)`u}y@ZD$^O$_bsXeI;L}GBa&8gGU&nh&E-0wOkK%$0ZEfJku!o49~+S^NIXkEu9 zg%*>apiqgNF1vY^i69s{q7`;GFE1~Tp6(L>1y#65-_F^gChP3%a$9ILpV5>8X#%Z6 zjFRsXsOZ^F)k8#as%__;ob9DS>GeMSi?RGhn~phUqii9M12x|zFzuN;N0)g5wj*GE zRED=jJ(MlgVH&!Xb5F$Q{Ag-Rex|0B`U)BAS>%UDwMaO!*jswTUqz)DEhRrw?=>+q zGc$c57O>s6va@hKi@7$y2mKWso!#HybHM@)D?n{&^rdi(lt!Cr7EZYxA+(7Zx2&}} zoVR9Z3_wPSBN>*=Z?zl6>yQ+_J6+;284oSAkR6&DQ&XHtQ(HzczIlP=4E; z)!o}H#|K0jg+|CvKX@f*m;Z?G!LRMLq>-c9DAjA-S2FOD0|T}Q_Br(Jig=HY+7&^sY0 z4%o_42v`m0s~k#WGc#@530MtAZ4kSN_(w=x46)9w;ngiLZo}nH`XhqkZpPQIOH3;< zkxw!H$R)9BR!0Cwp)sFSSc)De^uu*MA4=1Dz33jt8p|L1lNjgAQwJ;c;veX|ReQp( zOY8`6apidh>FCVI=fsdl>Ws0s*n^LB%_5z0K}>xCdr;p)hvgjhC|A!@kLDy*%{_OW z@9|_w8r1Mm{|}En26#)a2OID{Lrfim@KQES4s{ajf67uVqSr>seju85-HsK1e6jK1 zV3k1=o}+_`4ff~^nw{B|b{3-nLpveJz*v%A6;~A|eo5ky z{6@&0_r3v%oCf`ZJlr08_vsQJ7ubr7E|(qP2LITMmVD0gT@&5Iqaj7eE}s925gPuh zwLO1RjipP6vv9mtEX2#*5mBJhKQ$#Ar&?hTrj1^3%a2mS2J0xkDh$0!r3E;Mz<%!{ z{ifW@Bw`+0-}4pSTG3o&8I4B5Mo?2zlQ<8R8Y0Ih^n=7fel(CcD-p;JMs7$>apop) z<)zp0n~tY^#+mI*=CF#EtXyilnprlwPK$+W1C@S~aI#h53p}aEn_STL2^uV`yw(o+ z1U&1-R!RA&4N18`LU$(AbrwC>adZ!3$hG~~TR6d~|J~1W zel0$)3W|N-4Q$d5BlLwmN4Qo4PtP7I=y}Wdy+BSAy2kZmr;>BM?5TH~PB-os$Lh(# z_H|x9UascgxnAhL#4mGqU$f2l`A{l@-+m*zy8#h)JOK67s!f zH_qgF@8@O}*B4AWEyJ?{y8M{7Q!r1+HX4?GN|zBYB|52D1X+ z2!*tVb)nnQn!oPW3RGI9@QsAeZ#kbX7^pME#fe*L!oYUQyGPI;|DDD~R>paU%Xl`x zCd$qJ=6wl~zG~(~iDeORCw+-Oc%Jw24k?jVmD&(JZh%bM+hj`#h}9ASIGF$X>#x@w zBVS5QmgKGQH{xEh>&j~PFd+jR+HhJEh4Tn3ei$M8v zG-|gMg*B=qqTy$UE8nZl+p2ahsLUNV_A%Ty=cATAWn$jSOMeuTr-CGCh1!1QG(`7k z@WHii2MK8|1;&{qs6Q#CKYZk@1XB8^E+LQ((cY-_0+IT?czIbrxWaD7u7i)w?hV?sbv|CNF7=Tk_tQjWPVfR z0x?#)3KXVZ$f*ztW=B-KizrRejH**z!&VP6W}~9(u&<;1&?-#dXYqhkes4_?#NVx2qwUik;vWyPxUyLwNFa>QS^IBu_&l#nncYxlr9HyL)sTBMtrM#{a` z_q6&=)+r?{$x269{;Hy@vI84tZ;$ z?^L!&b)EE9|EUGwY8rks@VNd}UahU#VXMxjf6UoW0n;eYfi!8;o}{?1M7@@jyBH8s z^76U|`ajMqOXceZmvVH0fCbsC|5u|zaOfo!c8E?WrG!Tmo#xf)H;Dy10L>35$- zGBB7^kHW&xzdux)8$`ES zc}-8HXUb1NNg~?0F0Woaq-}5=*c$ZDj$4CexiII1<#D{zj7WRl71i9|{;Dy0r%=ky z^11vo#(>J}ZJ8x;sO#6`;ht=;FXC1C0^t=sP$A;Sb4C{Lb+{FAf&#P>5^3zKLQGBY zpFTy@=vitzmZ(oT94wxTov6^dO2@x$FVnB4vQ~cWbm>L3tf1vkdh!i7q%jrHId&5>nwNam{Uw`@iOfL;U24A{fq4> zERGRF-=Q zgK#$}dj04g36A_=rjTIErIJ(OyL%P^^r-&?*gh1O&;j^z)9g1T0f)d-d5 zF_Xg*FNkK^Rf`z|!+x`hVi#yPMBV45D!o~F7R{%VmmD!GJD-U zJNRgQEY6e>-AcA9_3|zUkIvafn=i9JJuYAGjyj@SR8>?VnK$b`FEUmRuK@b_i=f6{ z9rK;A<58gQu^6LR8RjO1udkEyW=QnQK8V^hO{za14ph9pL39#2#@2gZWk}{fRiBtBTb)=HofsmT-0HPbKR?^Tp22$j_{AWV+2%~pf$`UA zmxIzisonfL*jJfYhB=#84H>=|fg5pmKD`xC6ppG!1~~a1DvJ^WAsUAg<02VJq(7R} z%4FHqA&MS|V&qbof^1LY4`JBkeDpy;vh91g_8g8`+cf`VF6d-wmDn30-34X%SmlYO$$A^?|FHfJns`mPg_4D2_=Stgxj%meWgNuntt&KF|gz)`gFY#fw z1Tfu-H{qsu-WRi$bD)}h$A*~-POHN6&}wYt4s+{LK`86jox0;} z+4z~MDdgFs6PB9_wU$1X^Y!_|$}OHu^y|yB9*pSq`-xd{xv!k?%~Nt-#U5g+6XUbQ zC~916{80rWkYqmhjK|Pm)Y)(>2+6xJo7~QZC%bZWRu{sBNrgQQLI_yPP5WZnN81L* z_kQO(!KH$YhXNc6n3%z}ZeQmvHJskAP^ea__U_HX@26Xby5iLrGoh>PebaaD+yPGK z&jFz$dlookqj@pWHg22Ul`nUcVyZj@A^?6|T|b+0VPXMKIB*6QCAEsuRZl zL!?`;7+UTT4gX>1Etvxe+4&JfFyno|Z8QA+{Ly1fBL^A}Z@Ld{CC45&7CJD$IQ-On zO}2DhK0YnbI9SVsg|py1gLsOCuBVWz&^ov+=3=;R6nPC9CZso@3Onos=e&aPT9LVR z)%=4kGtSn5_4-KDU4g@uQpSO5Qs2QEYviD&+*_(ew$e!B!($=j-fPV;CO|^CH4xAO z=T>v;A?lM@2No+Ww7+Lj)qPNlUzW$+Z#WQY&XnZ>o2Bx=lM+jFQ)NPXS*IBon$7~*E_vyLq zoZHM_T*5%xLn_>Mop$J%jV4T1FBRMgAL-gw9@Y`uzmG0+|D{F!#=31I`|J1@vV_%3 zEng+p=R7XF$A^R0rKxTn_6v;K_2;fp9v2J!sBQk;MUlW{Hh4LrI%dGOUu$wmh5h)k zPQ~mF0!47(=(%BH@?M8iSCmNIZoxLbVeW?z4|xMiEJT%&sNrbl_b9BLsqUSvsfzNR zBVjVQxI1qo#ZH`4+?=;cA0nGq>+Dd;E{>y()5lc_DWtAr??pDpz6g^n!L^T z2GtW?z|1|_=T{`o6J<8li>uOF@4-nuS!T|{7XrjIzaj-|%fY&fCDI7NE97BgqjLH7 zzv>xba{21%q9t8$S6d;AnZa*F!#Q?9+0-4wFjZp9g(`#`WJF(+76eGF_<|gDB>NFH z)liXoI;aZeS`a6i1FdANKU0E0sZpIN+=3yFna!zN`b^T*H9;$v3cr`kutC;+71{%% z4YallqRTzGAInSw?gQPxJ)N&!R;UAf3C|ua?XQ2|#za{nIw!lMFB6^Q60w(`H0_@% zRVp2n(Bx}&k8+i^E`|(@k-{$;AkihF7nVeRcRzEJ!B57fHA7>ai(={H8c@Nr)ry9m z@85lr@5#>9;5~~cW;H8l;~x4%?k7 z^ec7(3MAcTWb|*#j$he9nsa%#Hh}+w_V;t#<*y`13uvzf zqq7IbttZmV>*myolw@zS_%xhcw?s$W-mg@Nunox!3XO-C9-zI(vCb6tI{`I4*ElM; zoM)NI-mg%4+q{1ne9PL)z?J&K#&OXI1_hYe2Vw4SxqJF{Ml^iiwPAo6_Yf#*lKb5@ z)5W>2KbhWnd$fCl>Xp0OCy!w-PIlL&x!BColwtAP$=qC56jgUBk7mbl9}r;DgGaoH zp^DxA@g}&Blu2=p4Z{07>en2mP3X6oC!91RWYk?KwJ%jl19%HQ};orS;tn}_!m_lo6T zNL{K08Hv>zE8bD_OI7y=50tfU&~a^GSgO%)+@Il}H~d@DZv2quefMkq^JceyJDzC& zN099PpVqMl^xkHGquS$Qu490;d0;@~w2`PoA7^Y_T#=vI@-$@J~!hma9As0u2&|y(d8CeMbEaSM~4TeOXH;a#B`R z0k{?I&)jPsO0E1kK0E4y-BKI@c=!ybJ@jm7eDCuB?StD$g$m;_=7GmDv-Usb<;w>d zcQ^h_3DA8dW|hPNU7M910rKqcuD9_4+CuRn$;j@GC;5X&Kk&#uhfhk%7UH>X|7)M1 zw1V>l^+@R{eU76P4j5?52&wveknE*I0drp_d(KN0rPVMh5H$%t!@qsRHG>LPO!p5z z>0keTh5na2V{UTRYR)UaYbPIRLRxxzt-HTB0z)3P_fl`$rjw?03qT2kITgrl>gUI> z+5(V3nvt)eh{)9> z=HLol-H70Ff+wiULe3|;4mk)4hUK|UrKDbCY>Sn z?4AT?uBOTOwGnXB52iwV5}99&4PLpa0~lR&dG=kj$dF|PHRs(Wt~2t!DTbFX7g|<{ zf3?fXY@I<)NIk=Q4Jv2~s52ltOV1gzs4__61U$1!XgrTrYQ=e0K68?LY{G3%$Mhd& zzHvW1_Qr?-3JVL_KpGm%eIAUz9(!%>)&f`)Tl8Aj^y!}u5IhOeST0qa+zDxU>xIr- zoT>=kAE`|@jL-o)B{fS(t(!8A+ zaOY#rCt#rqYw~Sgwc-J43Z)cgfhS3PzSMU8z3@`NuKVm!36mWM#E+E%N-U8>A$p>?vJ8r`CCNHG6VTHYB$hyN-7FtquT`LH zGO0RWR`|15sV^s}jA~bSrC;J_xaY|q^2ZO?CL|=t&PwjsW$H@r-BhZL;7~ut#2f}? zrcEnbQyP&5kS#iI4XR1@>69Qhx(2Ne*b39K}F@C8M85l#uTk{E}P#$nW(1)$5)(x*FTV z-DJ=3?(nP6105SfHjw9i`8PxEj>fwj#(o87T-5@|H`?2N7Oi;AZhE8bxZsE|09+bC zg%S4Jk37`Rr{T)vWoYezF(e6Eq%B_Y=i(M?)!6`s22c!GYOrML`W1!0M!Up6TKMV+ za+~duBclbzTnIU!N;uO)hIn?PlNvPYK<$JuAN=a{c6QmyCROdqoSbbw@^e zVhNmQ6a*{)rM1Hff7iI}80LA>f3cSQP?k4_-k`aEYz<_lI43dHco1-qmz-K+;!?k+ zlO8(8SAN*ZpTkK1N9n<9^n*uHH$c=6S_pNO$9efBS@qs~Kfhp85B<<+BRsxA8IZ8q z#;u&qiP6xZ?F&2wE7Nc8sh$CeX0LK80QNPU?HcD%c^(aBW>OKCw^RO9HAP<8T*S~k ze`b0vQ1H8WLrm8dBkTg_Wa);v1#-f2aXZFRRz5bxU3N#&1Q%~y(H+U)7F|M}zy2AX zRlU+C%4wIjD)*2=I~xj3tty!>kpZGAH}J5W2s5Xh2=)eA^E;}^%l$Iy*oR#w6RIU5cU{khAA?{by5(8I83 zr;7V;Rjdde5vIdOdnN&6OJ%7_Kal@~ta82ij}mQkRrT$46EFbIQXeTJw9}m$acav* z)i!sVm_@*8IZ%0+0=BJHRt4MwV5Y#_=viv_C4k&v5Lv9KY6?he7|2P8$b*Rst^Cev zMD2SO8o(c4R?hkEN8aFAKIZGDNvI4=t3TK;d(ER5|0?K`;j_LQdBG!Z0PK>*@2kGq z@45<96!N;1^I6CYAy7iw7%`wEMmldC~z< z7G(^;W95d>2@w53=PP~Z2sk!2ojoxkLJB0@u5N|a-}@nfB~1{-gbDnBdhR(x1)2vo#e?NLtqx`xjI z@YN42SnG$O7jv!p7vVB#77YvlJcWrSP7MwN9Ymdv?A7}G&sl1U(nH&;4q1tf^S(N` z#fqLvsoan{u`82yC7<^Tf~zeums=>O0rFL0H{-a?c+)_R?28&(bJ%3T+e$xoE}o0; z!qB!L4gwIF&=ht{V6Mb;e?M2rPUZ7?ms6Fj-w zpTJXK(5SXZN!x#RevW#_DAUB3^QK}Qb>Y-yZrkbXIVxT0^715>+u*@(Z+(x|?uK-%wQJ}t zPO?YnzQ+}qMaU>qF`j;?`@ijQYH?qE* z&0)x5+30ywDo#9q@X{Df`TPHfTDlF97wnc?_axHX1e+?pXjn((~tAVY?VLK88r|70azxD z{R_aDWU(#V=9#e#B*D9GP=%|s0;mw7J{{Vlt7pQ%$u3xr~;F?LIp|yNQd)OFW7pMtPEwNu?*z}R&7|V>2*R{>X zID~|}4pWycnO3xlnr|3JA)2;>p$tI8sD^MU29@?rNt=0>AMzc-?!js@3sDf?( zWZgtK@L{UaDK}o%$T$g~op(2z zsK^XJPdWD(tcU0e&IB@k+)MVe(jV$D3cvORGpO^D&vAyRO^9bcwbt z8+YoenY!Yr#ZJv)e)QgWJdX5m>Hg*qSW3Q^D|{}ekw)2DJUcPvZ`z)3KGG;2H@*3} zeC|Xl=q2jh{rTNk=7%2olSQ04VqFiN|JFe)63SFX@}woSZA?V z84#pq@6IG?;mI~HGzrXTrB(&H#zt<~0z5p<4RE5Ozy0*eHar-5!|N~j^lIV`7TT-S z+PhxifDT3ftN?m)+`V_Ix1d?;yxI;vnvTa?s|gHkz^hhw{KC}CN*5U2iBR3MPSQ6; z79%w|s#%a|S$XNF#=r&j`TWZ6-F&|amgmWw?wK-%0PN%Q_TOph#{ypaG4#&fa<{B^5Xd$pYGcUazB=qJ}^_Z2`pq!y4y8 zo9xCvOTV#?pZ&zX0p!!QdK1!VPQdRN0bcM6>=#?hhYqJdcDtcEb?-d~uG2I43A%Z4 zqm|6qltsy}A%Y&4oKEc(XNPM_jU#!Lx<6l7lMg;gnoMAdw!H_7mgjz zo>A*|<^evdxdv~M_q}Kmy8exheKso*DXy;EpQYq1hx4|oP>))421;C$KCKdya&VLb zMhwIJ=5n^8iY}vW-d9`cob2qqSDx;zYsn)t*y@cV1HPP3f&c$&INEsBVSu`rTL*HOEK;h2lf-}qM4;hX6dI4Nu zmI%AL4}GQnd74-q3DL|`KJbm{UJTmZ7?_NmqYm*}D3Q=k+%J%!N+^nmlt@S;EiD2f-CasI5|d5^6qN3kX42iEbhmU$NjFIE!9Uj8 z>s;%cv#)dZm(53!3G;W5{n_4haP4s zU=_$zpqI;jQ#)Y5(7pv!Fwnx_(1kwJ+E`oZAn~q2kLcvHtK`}BY=lwH#F*%2)j z74_I7L6BuHkPbG9o`)&~PtZg;>{sUamZrZ3>e|9^`UO|m?~mdfHZPT^97RjiR}g^9 z3dxM7RXMEKsdQfO&Q|;I$FgMlc!6&{Iz?nXnAQ5YH0Lp|{hr`iBP?LWhO+6x5i@b= zuL#X`?wd{SM3H~N{knWtfVWI@of;^<(!y=HvAj+`r}7JjQM(lRrW-)mYD-FK&%q~3xz;uuK^HPMt;%i_Y>lz>YL-SCp%{8* zW~njcvG~@&1DK=e2||q{Am+3s%rJDSYQ3kxOQ|fmwdY93Az1rmt?*o+xh?RagfZ6d zNh&Z*K>yPbVP>Ld4<6x}geTyZ|zw$>>%|)5+R;c2ehy$<5|g9<#yve9`z|Eg8e~_RNwO;>qz8 z>SL5sXqhHGrPBDBqjJ<4)CGLDz>G#DL)bNgCFPIDw!9ASljUQhOIHqlEa?Qja!6KD zTOYGlj++7Y!A_>EjGPmn+x7~q=EHfBtQL!rptlqAfxeC4r^D>!-n0V2r{;kng#Y#e zCIB{9{4?h@T_rRWFR45;t`};>HtUT>yFZ26*066ya_M|6J`u4rp6T6YlFk&cQVhxL z+jTMkdLgO6*hQXJU;U9J@f3^R#0==*<~?zDRz20t5Pz~AI%2h(Cdyoz_Cy*|a^9|F zH@!0p3`{V2TX4C}G;eKOnDCgsRhrZfD%7u04eKEsA1gG9OH8I%4R_u=zNeB_?PzNh zLT{D{vM8L>$=6@wjLr1OM_n7*N5PW%1-C_ou-0k%9+%p0Voz=(?gTAC*etIT&PqqNTWEcQ7uF zmu;rhl7-PDKZtU_B3xMBr+EHc8XJq4CkQXKnb-JD&p8hlg;comjj^#2pe(sIM!e*NP0JB*7J(g~hmvf~L9O4bXJ0SJ>&eLEC-uj$KT#EqAzF&oqO zTo!~0SC|&Qu{cZHMG0MHMBv-mU!*2-aVdrXY8)5h{3=BH3w2HVr+%}v-% z>n>)t!zETF3AmoS#jpJs0u5zD)!`HnEC(^rZruuO$o8ZIK&|hC_GFbSYB63#=LjpS zP^nJ)ZF)?AR2%MA0&MYxv`u8hF>W)Bxmkz9Ok z?O^k4!Fif+29nj$G>0=H7hz3cCbAoM9k2hS4r63w+}__e>8-W~hldow$a6dZXx!GAhBiih@GQTnNs{#QMZ4d~ljm0@=JyN4(PvHwUtD(EQd&GvnUeKgLC7$j ze6Nj@OM62tb97viMZiPUp0iKJy91v6(D+my(dgUw!+At2!)O&_D_i!K+IE{0s){0G zg($G$nQzq3(0ZEm92XwQM>&pMlB= z6c)YDrG;dCKdY3mA{gYv`_vl>`$pR=e`LFLgi}9dW!%@l8>};4V*ERr$pL(gWcKN7 z`C@lsD!h)szJ#-0g9Eh~4c|{Yt!bWj8}(rv*1D206sgCyZ!YL~rou|s{AYHq8!KlLV9t6vXkCMQ0$H&YNQS zhm0-mxprw9Qs_;rGH4Uq;M-7(<*}`muCL5e_C1XnLS21gfbS0m0DE4Xk!z`Y{ z=gEl)ooeX;xDHo@q^3{(kGbfx7lezY%knc3yN-oLy24l+Cwy9bZW=cNUFaCEM#yH=)ea81znlAG1f5BfOBDhh>GPU zVmn75?o?cTXLkDu_UZg(!T;cJ=Cg0`vy(iQkY@%%q#za;%X$hD(gLGZBIF&BHTAxU zE8W6;V|{6Oa4`LkTHs93?;ZCKhj{9)(Eg*8VEHZ`$M^Zx*U& zqG4+6?aLiJBd|!_cdJNH32sCq`|#wto>5=FmJ~7-op>at=X(JVJ#*xWl0qNoeSo`S zpXj-2vncue$|%pfoYDgmiXl2`rS480iq23Ua@}Olj~-2n?NLJO2YI9l!pNQFsWgc= zS>RxuaUMRJC{&r;Gt$60-3O1rRH@vw_QDEVhFl4F;wwKypW`(7+;192e1>ZC0=&L? z)8(lLz6^jhJnzROTgz$CWxvq`bjBJTN(WLEcFe_7I$ErlOG9y>9dA1=b zRZV4y*;MJLYlPww7hm|rP+e=eNB2Kbj;&-gE|Q%CvJ~~mOVp$Y-RA3ZzVnY1z!YNQ zvy!W_tg_MJw=QwMI6X`bY-j?tdivLkO}0;;0^)g{_fi^f!@iaU$L>iSj}vvX1j&UY3&@JyK+V(7t1d+>q4c>a^~g_yFO+h*%~W z;KBPN#8P*V&}C&ww;bWC{fAxu4R&iJr}ga7m*GKb8=s`;@$9KeYpo%E)j5GUz5c!H zP#ceyn%A1YIiDCEri}slO%~T7(V)?UW!nTAwx>cp#Z6s~uUSUO=N*_ePMb2?W_({P zNl!!{tqj(6zY)=`SW##YzDD9e3W&QzdabMeJFA!%pS)M5&RVqM z6#G*k;9}`V!?Tr_XhO@cMa0|1oaz;d3DK=}ds1>Ev#WLA96ep3oLslJIgfkMK^3l} z%%7UicKvRj>$&?4lzYA?!txIu{n09W2~iYk2=9QXLhGJHdP21atq~2QREpK}37hs2 zTn6FxmO2*Gh?mjyfFWkHXnuq!4_(}kFnULHTpND7A&AH16=vD+)YX|7>QFk(OnVZv zZ1K1X!~WvyYC~Ni^)^3FqocnfeUKhMhnyv9FgL;z;i_YQ}&qKJg2W4ScTVaV7}$~y_xvwa7Vg5u+qt36=!?^G$b>IqM!csHTU zo-J`jFhk4gC93-^=$y;+0pS+03>Jw@B@O@{)B+~@Cv}9+`dW$!gfe)g03kx;^SezC z9SCF!AZGB#HkY*y5fT}tKP`ImgY(H&)`!s4RG}uTCid*;GccjZr8B%}%(oNCt;iQz z|8{T4_zQscmiytTD-rwLRaqj9gm3t}wm|U8uP(KVN%xm_<8QWMQw_S1jQQR~^(Xp4 zcbe2=3bPz2+@C*>D)tn6afyI6E?P&e$p)nroF2~E5%qy-S}V*X8Wpy3HS1qY+8;m+ zTClAZ;?FwQA>1pt+5Vw0%3gJpvcQ4P5ue?xC@`Z_OH@=X8&*QD~G&+4cqC0+(oNKzuYO@`qH zL5=BlheK!v8rq3wjV(=E1kwGnI&>wL!-)zy*7qEdtyo&Mb6s4AHd^X-0UwE{B5@fs zLVOqUJtnP;tI&RLG_M3dZ96*&c*QHEaQhf6Pm|@wr5?X(A<@TYnLYmM?)E@>i`GFa zuw!5b972IPrPipW*2Kz;;i?+3Rd(%z)ncpZ43~H1Tz$o<7ELx?cIDZ^@3Xey!~UQ6 zmFP3TD=%|_M5{Z9liw*eB91^QdheQ1>PHf)EaE#aVm?uw?Buk5EHP?MLhP2j+0I&4 zbx0h}pds%P^Frp->5vG?b2ltc>T_@nyvzO?>nv#oNg1yaD)-O3S(t_>cN0MgA_P$N z$x5AsLECx3LIBVnm(b9R-Qk2YUYJ!t@fs!`hlty8`+^t&5U$c_(`yv@PIs2N;vu1q zZ}NtS(I$)lfk7mbK=Jma?|gL9EEuFxU((VroA<{?*G=iT&9$wVr$jBFn_+#Um3+LRmQNAHhTB!DpLRO8AFoP#Lq@KUqXiY|jv+GR+enaGvnLw+~e7+}*k zb}_?sJTp~K*C$6-v@!DYN~+rFF`fLj?U&A*%G11rq6V2a4bpGR(u60BB&C{gl~|0y;{*V=VmIxq)|O=Z zzybekOo1%eetQRTR09MHQCB$bayC4qQ-dCXo=WR)OXkzFGn(+TQ*m-EEC!X&=n)0X zi?j+@6tbW4WJ)Gl3kJZH?+RSVO^;**fB)tfOnOp!rwSDCpNG{{n9nW!Q99@52!19t z0S&JxCAK;6n&5Qp-{NvSApTh-rpECZsRo0-t}coe@koc$`HClIhannHSesLJ<*&o6 zyz9#0__c=HMpT%111mu}MVbhC-2P4rk*^f>Z!ZATBv=M#J%m*kD;!u;ewH0-9Ng`~ ztvg%@;=u|5YozO^eZqz@%Nyaumi1%x)GEZIP1vEELr(V6Z@_^1vpp5pS{i; zf0i9!s9tv*ys&D!!TV=p@&ulzHuW34ED+a+h_QY1=&ABvrg@idu$O+17CpXb{cEVV zjQfiHRX&^ZA1mgKE7saDPO?&6-&wS=wIz6NT3uC@u3LXkCw)0B^lnNcJNc=>TcgX8 z^22F8v`hpk>1BL;0T4>J5TkEanQn`SVlvM!rfU1{Zx%CX($DB2mJ42fGu6SvtEMQ23q3ffB#oH1{U3h91f7#JwvIF?tc!}v0`@v)!!%6K6e&12svXq0xIt|3Q-q#0v7sJZFiZUSY|3T+3jB)x24mD|P7 zcs@530Mb)si9GlQ;Bg4Cc>dfHNQJP6Msr%rpy|rz$to(5s8pNg$g8G|r1Nc`;R{0} zNMuqZ$2Z*)5yhngtgh%5vsMPnruw#EtW}ncjBD2wkn*aB*1dXjDI(Yab24j=CExiN zW_;9pMFT*q?BAr)yC-kht@DUuUahGtU7wiSz4!LVub=Ry#Y4u()xy#7m3rDjN&Gm~ zYlmSZaEafT)}snfZivo@GuXA*5= zk});q!qfMF#%?VUrLIVoEn(melm%BFE*6V%fzo*ALj|$474s|OXKpzR8Wr?6?;~B| zIecBV?~U<$%xNZ)x8PJE1@K<%8*%U3c2RY1Ta^z{%)zx(yx0T0P8cWEDun`73DZF{P?#@*{V@uVa#Uk>=G<}KL zZJW`Jn*G+4&c)Wa1}~e6U)~Y(!1*gSzcfG7s396KK%uC$Yk8@=&z70oA>s=}w&&x# zs8#rXK2zg}-Mn$5OQSeb?~`UJ8`~X&3z~7ZY^?Rs)UFFhOp&148Q7q}vj-{~ILr*w z#__rw{DSC&=C63kR$jqy(qi69bag!kS4`}4eRuQEr;QJL@TLuBM%1C;hs;u`!via9 z7}Ipy9B%b%I37ujQ^0}ZPU-i{f|cKO_VPRy`acgI-?KW0zWE|}SV?O9lWx~g6aD9GpP=B^pPr}Bze*L=3@E&L`fbxl^Gc)InT{%g2GzX}ZEpTgRX0Ul?~&N>gLT5>dM<&$J~urWKmw)*?6+sL zXHJ_Q4b3MfH-Br%V_g=4(STqMGchl$04Pbm?$Pmz!iXY@`?OKxh|x32I5&{r!C4wQ zimFAb4m4t7Fta?pw(;ZLgzY9@f392|H%Ad|G_(JbyJu5-`%Z749O*@zxw-j9@Kd9* z?i^_Eq=4S>1ek`ont6V8b#Bm(5Pe9~Tjk_*`AP&EKkkXtyZue<`A+=N>Am3NzsXJi z3*pVT24HH!G*6p)8VhcYCW-Jf?{Tw*GSzY$38XKEt^^>@NiBc?DE-YI;ZS9L$iEP< zD`u-c_~7o{-mHrZsM=b@;xA(qL1CATE=B(EqCK%S_6Mh7YokoC zZghPY2BqEpZ>~bE9{-|r|Kie8=y2>oiVbcjK@5u#fOhB1$0~&%A|}^u;kLEX>zPP* za#B;nM>GS9p50=cR8xKFGPC7I-99v7FNSsAJGx^9|REL3r-hP0`Vp%8$KKu~O6NlbtYO z?1WWn0Dg)jnwRTDyQ+6r* zMUs_1y9?ds_Hy71lxExSceqbTu%;nPrr;`{Phj!{3r60L?f@)etLP!EiuKY4>Vj~S z-)gp2I>v2uXoX!;2CrV+Avixd3fXh{QxrlD^pNiFZv_Sb0|H71RTdkN70EGks?{S<3kM6^;3gl zN~X&B_9f1OP_4qFLqS|%w_2EQJBqc|uCzfE#hkW2oR!S^1-e&F-+;f_zIQqDbbXcY zV(LF7PotLc9yzOXO;61_EC$00vNDI zaH@~ZgY$S`&Mjvj*9sn4RgCc}T}t_K@YSxCEeAxuKxjs_`^ly-P=1kRU<`a*TRgt1 zshKxDGBzULYwH{sZIENU@Z~`#Y1je(8RyB-5ue++taqMjnZiojnWJrIAbkm(lEBbh zxd59@qUd_~a#6(Z5yTAio^@M+a|EdjQF>UK z)y^6qLjRlzdj9WjWY7CxiVYr|c)r?oH^S&V%{m2k`qEmyYE0C_J)`vg{;rNeF@ zMUj-4_}UoB`VsN%hUDc9CfTiX$>!`VeQu~DJ#H8Eo)ArRUCpD|+EOiac7dS}x@jex zc{(GDY>pe>Q8*G_i|27usWVEKZMs7=SyrmK-tMPr6J#%(@6{7smTj0=jU9iB?LWsY z^3%1>%dUVHYqDA;iQ(uN^k}LFhDHP?2MaGb7;EdvtGrD=NSePyY#b-xn?`uCa%XFd!hUe?V`ZKS z=b0N}44>0>;p>`G(4)&1|G*v9&ZP+ogjjrRcc&v%tg@Fxb*SJU<3K^Pr%?C(CuYA#X$HA1i@@= z161w$?!sV#eQRqQ%;;5Fvv5sGu!wjqMdAfl!dJ#Gsobwc8sEWzLNAL&GN|@#eQ1SV z>rGS*pcrUtid1yZ&yfXeCC-f~Y2X2+;J7cBRb1TaNTOFoLOgXtBy ze|rHRYs?E_g{g7fRg{pzV}CKCL5HqZ=dk4aGsf0bb^g&nqG(e;bViT^84VCjQ6J5l zZIQE@Q3ybP`|V#37=oqT=+7kV_K&-)m-1S(U=9Q+g5UkJSbFlpzI`8=b$NAW2oD9= z#Mx}#mc4CQqE%*e>&r~trGUt~J`8l*5E&JZC**IivF)QzH=iKh0u%9gjaBET)&kcaQh+N2M#vNbFRU8yZw=&(*OpM1o)ZpfP)%WZ98>aA51=Xww=)1Ada> z$1Lk9p0AUzgb%XOmbUT_G=2$gH$>eOmypoSx^%_;ed|m8^4w*53 zSRtN2n~7%~{$^ixcpr#(n?M=A?NZTVkaTUkP){U}_w*@Xpa%@-A2RG5aee?a!ctex z@?apfULmYCu1f9=>x+}%)%;DpF1rv9>Kr&{DECxhtg2-RK-=3z2q5yN4(4B1Qf zpNW3sI|UIKl#Wu7FRdd6V#+olo$=Y3l@n&%dKKmyGadu~&Kqoq16sUpjdIzSbp8~ogCh}|x)E5DrLG=hZ40x>&qNJnVL&|qS`=z1wYSh= z_n^}#AQ|NTRvWf2uS5!FpOq3doZ6}L%WHo#A_M9LV?_qHy+2Vx9YdlR)*xx?P&AYO zBsSm(t+m(ZTRkX|0>{65d{8*X`3<}xfQ_T#*FIzLuu{&}HJdr0IAeG4(@2G?hz6ywYp$32x zJcabvsZc-UDHn}SHkg2d30BZN`CLzQi>dMh*hf+m&-Y`>WRsySA3wax?pcXAmULwC>a0g+nLbNpvI_{Hm_Z$ z>5i=;qnUSk0*H(*ic~)UH6+~Ig2O)9`Wg!pIq#_K~}SB zUpfpdh;s}#m8m4QX%sEOsqLC=kP&o|*;A|hV^cs`Bcp%9_yHEtrJfLtS46)2*LRnq z+1|BIcx4@95Us8~$O2UGG0%hAFM=3poysFA{1{>#dGzaO7inU#ls~+~iXd=K5%NZ1 zNLHEh20DpL9m-_7TL&#S)joh^?})nm8})6>~pCAdb7dhn|sTH72`ATnWx$!mVcI*EfER4GN)Gw3Hy=` zscm@@>9rt$Zn62ym|9(r;<&%DE`XB$vAQuH?FS3;w zRtFRvApE2J5&c`}*P&LNX_EGoZu}7H+rKe;4wuy@4TDzYbj8Wr?bz)qHU?Kf1AU@D z!@2x%8KTRg#uoxUP>*dygSbVYCvo#&qZs5)Fb%&vn4%=HT^{UlAg2-3{m5mA4g{#G6 z!ketswyA!x9 z8wT=*sGc-`%9H=Z!d`yEz0O-6m5vT#mTzC;T>B?FhXYV9d0!}}La-;%b%OW&(lY!n z==JhD-?iq#hMi7+58Zxx9grT{+S1ArvS9wzbr$St)uzvv2l*HxYX2&l2qVnMg8?k&jGV>h1liH#pO)P zp(bGAt(XmI@PA8Nz5J`1dpZXj`|Bs_>pQ3DA1kE^^8N<})bj7f-T&Ff^M5`Tl>cWK zDtwT>!adx7JtW_!pUH3wU%%JWINqZ4myaCfx&A*KZj`T=PtfJp|Iu#z|GX%Rf4SLF zK-5j?!JoEs`!*Ar?6=6)4zkupvffUzUcn!mf`2bkTV~kZTUabu=t&PRa7JmdS7knQ zUVXqU7xKhf&W){i^B*Ys+s}ius3}*8Tj?-s`IGo+uRPRG^U$Zb;>q!p`0q>iGLnUm z{c0yF4)xkBdC<2fO^x+~31$!5U~HQS{j;JaIxg3pHPFP-c6QCR1jIa52@Y<$6GkmF z(%7gA7{{)0a88=Odq>1B8Cz}{3nOr)D*XlU3VdW(4?BU=m~|opul6j%^o1gUEexZX?bBtogry zSlw#bepb1Cru*gSdbC>P5zS}8YcHPme8J759yX@9KnQSiYeC}C+}8Gh(Cww7!eVr` znuLTp$i7A#uQfr3i7t{AdMURjM<7NGgWx!??C|E~T_C;AmzXz{s{W)o*c{-<{@gHy zD*W;K3rs@Z+%M*j?m}-nNums{&BdV)Bn+7Vy%0{;QZW<|T>&Pko~I=?N%(xP@6X+O zUi2IY1S)V*;|uN^Wc2v~f3rQ5R$JfP7I2j?g=EdpU{$su)leOt;^B1OI^b~qwFVip znl)B#NBu7Kp`*+c0rJn3>x_iUGzA8W1s{^t0-(@!ZV13xdaaOoFjeQq=Wv=Yt)z3| zk&K=BoSAt5W3=|f9UBu{7V@!~EdCoXt6R$VC-=>%j+w9G41E9gQZAnD{$GEhSVS(; z2g)6THwmf|FwNF6etfFPa{y{ZEBz3`f~QAC1|1^@2~)wfu5+cFLtuCG5V%knfZ~9d z%gWuWY3YnI(GQ@VZ?sqaT@+}D>0~Jr&b6)edz@D~uOBsnf^(rGM1b)3>S~$A#XXVv z_MnCNcRiM_S4T$MRa<6}4iF2uuR!GbaGk`D*l5ayYLaRe8-UjyAYqAdH=WKTJIEMbIMUFq2wi7DD*a8 zUEl4FFO&CX&rmayuDi%3S@{J4b+ytAigF6x;LfcZtHkH9CX4EDjm^4HUvahCu=!0>`l^VZ9Lm{VasoPiwm zS%9J*5_6B)ZDr7ZxBS!U0~4F5s3@G)gpT*_4P&xp=YKI%eeu~#cLa{H9$%(DvI4ZW z%9H4T=!GoEg~>aHk*L$PE^e#cAK*Iq6ZT2DHGdSA95fzTJlj>5h-uNIdeth?VdgUG0o>TzdjRiFFxD(U5{aQvCOL7`QR+Z^4jjf z*$LbdM7&m3?RyRauf^qW4&|vSNT`DtNMgP{icYypJ(OBSSz_XS6`|>1O91f~T&gEN zJWiOaH!_FQA5g{ibnf9tB^n0xtTL3GVaA=PSGmd^abQn=zTZ+|`7zq-&Z5F6Zu>vV zN%-K*G#kq=%?;_O#2D9H_VV-;)FrEw$$z;4u+nyH8~D~!&iauBfBL7wP# zZVQPw0vapsL`;@=5TW6m{f##LTzK_ktqi|%^{zg^@>Rcb-nAM`A~av9GV2=BRrpBa zR7&VZDUg<36P&hT<)CL?Tqv5iF0hzzw6$$r=Urn!R7QY!;MmKvNj$I{9w z>KwPyD4Wj>31|zn*;k@$o{Le#uDi|i;;GapHVFtjtaDl71)>VluScys>2=8t^!ft` z$Eij_mGUZ(5r_-|9nQUtDSkTxX)Gxz)}SY@v4IJ}pps?X{^jMA4}^MW--li720sdg zrQ%_Nz-pal1ABneq0tAzR9{@j(|M$}G>oO45S!1n_jHAv(7slaH9lEo=#X(8%uHp* zCjZRf!$#<|KIpBAP4T(Rb>A5>C_Fqogv5p&|NJgMuZGil(XNsj(zZ*q;pTp*Ab{)O z)Rm37Hk=jWDMl7VZhai@@=5F$a8D{#WdAFJHO(;htOCcXsq%E7&@8Lj*Z@POM6?1% zDWcjvwWKP{27!&WXTm>aaN5Hz%Tsqge-EcG$2YHC^0MY;of7>gt@eHZxvT$~UAFS` z(eomy4Q_{Id<8PK4}#scHyOA!N>3EmBKuSoB<+rmI}YYBW1^!&J3`3bpamPY28s2A zV;yI@HO}7Yi4Gs;reb>X{P%aSXTAlq^f^J^Z)E2g+1V4ATz{`2lkd#;q#B;!W-FHz zh^HRI`pC+id>K7Auq5{8)e#Xt{|_#Hm!18NAl48dGy5K>Q2S2pQ#E~gcnkg1HXZp; zV#QpeE(5$SSYA8;SA;cliC#JPG?2weHnR_7HhN_jReNWljie7lBr-aBCI0c;!V%|4 z^--O=cJhU8)UT%7&YFcL?LEwnXY9#>;%sK)Ji3kcXlX2lW0q^>cq?0Wo6|Sd%0sNP z!@C{>g)d1xN*h~0xY1wZ=TKk+u#_gFR38 zA0fWAlk#vMI0Is-HF?yS_!K z>Q%}BEr+ZSGhWBK*}$67=v;H=#c!2YpXJtOj5!IHQe?q%^?va?*SYC%%Xia0i6V2K`(Y*^hI^CGv#r!IbQMz)14s?2IZyntO9kkqi z%U{si~@F_(U>ZaH*=e;60N4`Y2(Eby#))U_&?5qW!C?3>Km#xDd;H z(DH=79Rcv;?FvNR4hzt&baq+1<=nIRwkV*5bFVMcA_CeY|x7)X1h%*hmZ-kb9(<|KSA_ufO(w;Ex@5^c(-~aNpw1QZiS%s|0nz zi{i`Soe9_-BD)d6u+-^V7{oaaqJ04+-Znb zw$o8^Va-yKy$=EgnX;G+<=T|X+Vj*0-EOP<*UE#!p7KoN*?GTq0C@b7$isVfFLfWmB~t9{iG+Lqp*S#KYKK{j}jVC7wbycE3Mw>f%qg zEq*&_4|Q20!tDz0?csYq*t37IoiLU9E^+_@1wc?xaC(C~-5WdH-ZSl!D z)rws9ne-~rh6S&vp^obC2gWs8oKthC=G$PjYHa_irN6(vd1ZG%3K77Mv3#@}5w8{B zkf~WElkt{_i%X)jA8g63TiZKY?AyKy_z0!KP+G<3gVz^3AXV|EL7hkPbhV3to}LQ# zSE`R3w!gl*&cEuj`SE9BQ^4ir*SUyi_1q4};_O|c*0^DmGyh^x9|9Pi?OXcrA%X-X zV%*@V4IZi5{B3LYKqQG91O=DzAMSj8ScjZ}wk`4dMFdeYsfMN3$`Y#a3TM8W%kSPc zqCijwK68m>9@g?xwqf(mNfkeB9#_Jp4toDlkcVvVt&UkPo6C(GRM(3d`JA_-#v6vE zCiz0!gDA6Gzxaiz%+e+>c(^U>%bXjSRB}p8F2Dm3y5LlOwzpCe5a%aUt$cwfv7g=N zKY!+zjvOZQNj|zbK1&Z2+jTzan;NPosig1>deOZkDqT@6(!L;KHQ!&9)^HfMTDcEM z&JWXmF<)O}6DI_KlwKm5Oa|`xU~-YY<8?LUGrs<*VP^i*a_3e%8ed~)8U$V9 zqz~(A9}5|`CVL-Zu#Gkd2LLS~hp(}*aei6`RlJV7twiKwG^CrVRJq0^(uNpS zq%h`sj%SYHtTXnE^Z-;=vh`h{pW5KLxsb}2FL$!o7EGa7%<~vx?<#eVIEAc5TI~_p zo*WZe4v)&E$*msHsLvcDx&~w`_a2ckh&1}$=aQ+v7C_|IA`uB0;=HDVDIk=#E68fx zznob8v5tzqcKuY^J-KCXZnN42mWSPmfu&@Nmj^5bh-BLY*S)Q#DwD%%vN+~Aeft>d zW%BQgj>|`|xSSl_)EJz)nk;E4(UCirP1#lBz|`ocZ&V8V^@@mQ0CXbFAJKBz@d~!hLzb^+ZLr*dJ zr#>z=Rk?9$Ssp0&21qW$3RVU)tIg(qLDHxfM?{Ur${>A-vHV2oyMjyq2{|p3zI`2p zDZng9!R`3k_T0fn-@BjvQ9mj@ugRrIYwq78DU98^`C_cZI7Kr#(J+B1m`SLgDb<($ zUzq9f!P;Pr7(SY@vT~%Fno1bGitf}N;F-H~Pt6I(SeE-z%_@s?^;O~Yp;4i$3b6>a zCL}vKG~p)%gMnvH#r`U!_(GA`8K;48Ggt9A^H|T7ShH)f(j}w`pIxlb!mb=uaK3W3 zWT7T6KAs$}Z{J;9@XWTIm`lGHRwxl0(%O)&&qEa*OJYfNFU70}VwZotNm4%WoK?Sh zG-2!&l2EZN%WFQ=Y+_Nv8en3m!e|CNe|))<1+SIXn7_{JvT!Nlab62<;c=mH^AXjU zo^=Hlz4}Lqv^lTFJiANn;;U=+|CDSbK8M|Xo##XuY_I{ZRDLPZhjM3!F`o3%`E2T4 zw);_TB_xtkbgLD=!mg>bGwe&r{cC%xIK6CH#iQ)ViHAM8!|Vp!Mvj9YB|dbDqoQ6l!oA=x+!wECFeLkhjWdH^UBjo_swsZR21@aTFX=F{Nc?MQxk4|0 z#Hb#NeFQ;o&L5FcNKa-keL=V$rQ4J`;W+!9rH=^cTDtSOS0L-O0)_4p-mCrOV_QY_ zSsj?HmtW2wwZ1vLy?geez6sc+!M~d~U;ZP}WLJ(n7IP^wc#b^0fB$unYbwoCl#LMn<3de6z< z9n{zV*>d~`gZjTKsq4aElYS=2e(Z%i!z9&{H=nNBzQv_}s_pJKN$6H}`NdUG!1eO+ zg9p-q8{UT%Y8pMLk}nq)<`2)d`f4U?YHB8<;-U=n5C6I}jYR)+zhNqI@XwouZxnp` zySYz3-%a~(F981eGtWQo1%@DNB;Wsjrzj}eSpW2h;lDclJH|nA9})Ox+Jl1f|MF}8 zdTFB@qUw_7=C5Rp_4RG_^%ZR;>Hi)Uq5P5(m3{U4wd!kCQ3)abSFb*J1d|8FM*nz; zCMqcr;3qZIFC88d6dn>59v-g!*V{sQd8((Um#(KPBXuwwNhX0HC%?{dL-g)d0&;2& zavmP$j&IeR|GfG|ZtrJh2Ru9>p~e@YnDIYktSG}nJ^n_fqP)a=E3HXN$4o((nHME53F14#|tW5!d@B z_~g6Ht3sxtdEG5;nZJLKNl@`MH8b-U4{VPFA374e2Qz_9eSd*kQ78rG^-`Jd&QMYr zT15n|#j2k^g^vNgUPis@dTET#B>nXLm%kg?|Gz#ISBlcXij$eqxRah*Phn~*s>qnf z9Aze{iD{hrE84cm!eH&|JaLsJS)*l!f(+Ky)(lmZ6;4N9o~|;ovMg-bGb5EMLe@H} z#ha}hWuJPClFV~5b-ee}e2VwJ2HnSs6y|ud*{?mFSr%R)9S*O(?`gb2PC)tHL`m>+dBR(Cx zDx3O@bJi>s4J!nf%WP$@=DISwmZqlv6-rb=+z-Z??cq2QR5y*n2JW`!gr*zvLR8f5 z?`qH8= z+tPvI1xvye6ie@W1gT>3;u9V^xV&DjZJq7DU!E%PR8luSp?SgBvXkBR5KVq=-^V>fkf`VJLEXs6?A+7kw0 zx{MjAcQ*qx076e1W>VL>(K- zX!OyfbWKWJJdJa`u!PHE+U+s+!+2RBlpMB7A z2NUHp>DL)bjcONEr0KVCg&(L-U(Nb^lxfj4~{k+5Vp0q-%=dR z@PBhrYCN^IgD7L)bf!G9d!L_LcT-Apo!36vYBksI4xT%cfDOqDonQGqTD3$kY~zo^ z?}yZOrMSLrcUiMhRXz5~vNKG|LP#El&H$eIJ9ssAp5-wC!$XV1XIo>47 z>QpbIckMswwJa7u^|`q6xb9JJ0i0fh8GQG~gx&*zjU`X4J< zN6LERrTKnHl(np{#Vk##*@lvHb!k!>y7>!_b)~l& zm*56UBf;zUq4WzS9gL@22fq}?d8$uWhjJ;(_jo)<)N@?Mz1vvRG%@&j_ESHeX4AIIbqzveEk+b+L$5YN&-#aJ?^SU0$j#G` zJ|t(W3;3;DRi*aU*UT}*L`3%Qpr`rh`B>GH0yY`TM@R_CgeQ#mBh+8=Hjm8>h)3RO@illycTGmOblhT#u#YH2khE zJ)kmJGBM6Tle|^i)Hx^(JCCX&JaqSh`oeNLsq(u}+~2_SY#Qfd%ng@9z779)dSdG{ zWo8mbv2lG@L{K=};P5`itt51@(ZDpE2lExFc|6Wm&?z^{lq2k@494qnXsgq?{;d;R z;}*SImGyLxHH%DB`-jReyR~unLy5_$Z747M3OI7rD-xP{&XBjCHIb(EXvM_Di0P#& zkQWUWvv^;;CG^=m3F!D7)aZ~Pw z0Iz{M(|7#qG&&8pJ&1V=%8r#vaw9uXUf%oMZAiPqB!Z_ggX(o2`uv~`?e&k>ku zH;A3=w#nnjzgbwyVz4QtUvQY-t4|fY^XEt{+SRA!{mZClNq2Sag<`HDdNA>O<6;CP zLQ%)V`-t~zWj`@>YgNR#=VQaaPtMb4d$!aF~1!Q2#BNMmv<+C~#mZ+k>Ys$MNB zBFZ_!n(C9qzA3io5bqzNBgS@O?ZC&y)zaA*NZ4q(u|rp(g`xKF^1WNa)Mt6;^e5MC z8Iy>C_seUoy!&zZHZ8J>=eB)4u$s-3g@!(mNZ?+2j32Re5VvW9rRmh>JB`!Hnw;Sx zRMQxdH=XQAQj+%w%6 z-V6O_YH`qq={)rw95rqAzRP|5z0Xd&wR*U-0tRhg<7WPb+PZ8RI(>YRgy^``6Jf@6 zWljD$_wL_w4?4$Cu>il&_|A@$(Swg6b*dL%WG;j)3=;Xe$|qSOi(} z=w5*$!8H2o6S7d9-KW3>2ntJJ1NOKPgC-9|x8y}$SeSFG;8bH?P=sNoV?b-i4>>#x z-wDYKv3X!KS!7on*AwKQ)mQUf0oFpTcB9m6Max)#fZ{!fzI~1G1;@^wV#XdW4@u^D2?tZjdSOJTXD( zryUFU+%{`r|850JpWtcClvoAb!vIYWCH~FgGGCDE@i}>2y{F@`8!si;OPyvVJ>Onl zgJ|&EXw-6Zaa_G1mpjZBaWzNNPxBNJ!4%ih>gg!o-o~6cZQTm+DSvmvRki3n|Mr~C z-4i{yjlG$eh#ZCS?wwzbGe@C{fuVBH8ZKU`=91@Tw^1OnX>ojX1doIyiC`$4A#4X? z)Z_I-{Za`>1K%OiVSHjLT@d_^?Azw!ollGUjMO+N0cQhYJvbHnQ)NPu+=Vp*=NIDO zC+M0#n2$61l{^yi8||t^Fyvd+7M0)sAU#dL9A2(}tilU~KFl1q`U}@O>^Zf_kGel( z6~Yt2Bb!dSqkGpYr5*m9zn!|j#a8y6?* z(*YOX2R~GlyeJ7rX5XVm+Hc+=Rotv2|73_LA9Q{b;TshOp?^+%61Mv9YyTsm2cG{w zn#BKK*9YTRaX=`3_HUvK(3&0tfjA=1%HuyT0Bt;%MB>HlzqR7u$NxRG#sBqb{m+yw zFHnJn)|AiN=KED4DLU#$_f7x(Aqh&=_;lk#n|Q$wcoCMti+|1<1NEPZh*2^oRy{Bx z9c;ZM(JeRwZU`smD>3@6gd{wtdha=m(oQ8gS1GBN$R;FR$<9@c7Gv~HN7WZ?qA zx7k-SgN5>;=o?DVRaDex;IQ{r5TO=5Hv}*ho545@@c0F^OO1Mou3O4`7{^ex)?^-3 z6zJqSi9G)LMq?u2?x(7*J_mOi`UA4C)~Z*Tdv(uOxWX{Jn1Y`s;MS7x_Fw;T(tUCJUr%;*%bG4o zMduVPLD8yXIXxr!`+zr=Amq3Safr>EY*1rFWL7>OKCfAEsowMahFnSCG%jV{g|gvt zRTixNmCCQEH>^7HGw=1w`*_a#M){e!M8MJ}FRah}Bg(O)juoOkeS$um(Grb0M5|(@ z(PJq)VTde#W-KNyPD5SO2%xY46cT$0Q;iv=h{e<_RQ=5%a)@T%C%uxzu)dsiQ?r#O zFAfxxJlx0Rc>_V2$~Bu6$-EA^HxoAM^jLhHh3%}_t3QFkl^ILTD$V9o2B78VxjnAYdjI(+ODK(*|+_dY5#TV1;DV7cjJ z9=kr)f{h4cshSb&0@^-cl>x>d5UstPWUPn?RZ+#*(bCVI>?@ zRSuTK!OUP;U~WV*Ptn7s-MzzQSlHkz3$_VqjWS!=vId8or^~IE-;!N1PELS%ss{B| zBT1(-I8-9_#>ZH7vs^qJdrMt9^)0SKDalIv`>ic^4T@t0v-Q?;(f6WvUMl?NXGiz= z$s8QKh`qhnvorgn^K~X5&<=EWrbK?C=R6|4;WbR2+d}2x0ADKWP}q0ywe{Xo@BZ}B z47q@VsGhvj!!S==7UPs^eu?VPeCOcR?|8jE4E)GUeEC;^ABx-dywO;yY@Fu8{KAg* zD8b@zS1df&I^VNTfjZ3 z1pDN=YWXH8_b$GVsKmrX05(Re&qOtsbUobjPow3W)KirEZ%4tus$Oj!EVaooTC-d3 zmWu;Wb&^$l>s!Aos(d$4m=^gS+qp-m6d^Z)nlhe#(RLyDM~G85tQz`yB>;E@tM0WnixG z{(=5NWcoXc`EI<)d}AUHcO-buVKuy&@7!xb9;5d5%9-nxYv-@Z$CvDo&P*{_`_Pnm zJ|INs@~ov2_ILx62X>RgMX&eJK2LB2!mH+yZ!aK`CgX!e$K5hrE&Oa`g|tXLP*yn{ zN2a%=^0;6Po#8&)S*URmUATU6+t=M4MW&opo^NfNs|>NyfaA25UI{@sZ%ak9UIfmt z@5?Xnl}>)qlfc79Uj8X~7h0(@>7S-klwGunUZx}59N_;wJG--Wmx1^T=WAZxwod}# zRWwgWxh0=lD3I`&PQoOe7@nKyp)fMFyCvjR2ET0X)0hVNivycx#+RL+3d z(pc%Js#;4e&X!RY8dk*baLTjJoi ztTaR6YeX=QeX$NQ(MR{pR!mG;0%?MEI&J29GP8+6k%m8#h#i--)W+4&>}Y9dSPm7~ zh*aKFuehnIoUD~ih;h-;(moN9k&=?Kw=$Qa-*A2|CH9Wx(QTK8MjU{1G$!JAD9g$! z%FDAe>OK1K#^d@5?)yg;8f*S`(|jj+{u6&=v#-8E;=;jQFCaVdFg<+AB993~3k@+h zX)B4eR`I6|dka;_(JH5H5|TZIosZ@Wj89fKC_dW`HlIf$9ewVWogily*p)93By3M# z(V$xUw|f3bavKANr9gmvcKa-y!YiU$S-|D;Xt=LWhZ8CXEcWs7ajI*7{!r#4@ppW8 z(@QLetZ8QyE32YfDr$p@;oi63dihkVZ9l^6cCqWdaMN8^S2Dzyb$?vpzk3Rg=;rNU*a-Q;@EtbUWQi^TOLAr1?*OjCL%ZH|8X~2G z?8ni-iYo(9Q+-BP-?MeJI=a)7bC8g}9eDj`M~;PIs|V35vU-g=}ccC zAi%ku4tIU)&MlcaOy~DW^0~06Vq#&zMohTO?XXTp$;-+4UeEjc3>w*fy6v|5PB@Zg ztJ&wh^KA{#Nz2MB188u*FBcqT8G#H^Hb`$>?Z;o*Z;mW)Sk5YDj!!-#KsNAWmVH=3 zAVM&ul~M~_yzf>Zv(<^Nfsd|0o~~}5TN~0v(c=psc0;y?=_>u*1#l!|&rFsbi!07X zTvzX~0o;R~gCoQdgUHX6$I4WEtOuBa5EvK$y~P(a84lIuDXtXyjFwfeQCEEh>3s@3< zTQ|yW&b%85%yh#%xlp~NI4NWdaqPr6p^BqlXDy%M2O&iL(wQUo`Oj0{#f+kmtm05k z#ZmYcTa!{ovoSJP704_pg?wb8l<93i(z@-hry)n=ACxW}Y zhgr`syPyqBcOaYl;^KJLwE24TEfrd`x#BWRb7f-T1~(_KWsJHZQeal$cEkcrelVkN z6%ZvlXbJ$`ysbgA%25?f>4lx1tgI{r$i?A4=6o{7c6@Y`&z~QKTBQx-;=T)v(*h*C z@*ELAPwCYoa<1`bfRr>mDdY_wTfMq;P-^O;5V|rB8Ax1K^|-y9XEThWp2Es%+XS5# zJX>91bBG5#8A_R6sW+)bMCRA0^1}jz-PW(>fLeic$2#sO@qIWekac8mxS6F%?H8ta zE`a1kmmnZDMRdxohr()U*Whk{QWRym%VSBDhy7`9QaU8Fk5=q zGviftnOQyD!?Il>u7BR4!u+OPHQ%GP=_dev0WhX2N7btWR>y}A?C{ll{xMx7^7z|(-x>AJyY37(cT2L+#F8WmN3GilVSy3e=B|?t>d=V%m&mI1{DFMMcF(cE=T`4UoDJ@f5H31ho2|hXE$K(&_fS%=8wkRoS4oEZS z1RAma{p?^7CfVmYBvvFOOqynBi%DuH|NAbTh5di7-T!K{?Y|f0|A9W<|5pwjYn~|q zAS3^6#qDuSPMEG9#>yxSeg4lyL+K^~tN!=y`)|t=_}l->2+98p6!G70@PGSR=aT&A z(1CqsKTf&?1znwZ*8V<*23ozCJMg_ebs*#IP{kkl9+#4lpovMle!# zugjTnsl~i(9FNiA4}M^8kd*x7vM(?=*!1SE)q8(9j^1sNvI@ledG-ljN!dzEvzE`z zMcNJY`eny(-%a>QIVu#$rnYeOpU!eyH+w8B!>fe3fc%cxYjhEyF^HW@rJ;thqY zU^?-`3H0xJ&60Y(;0e9ENE@Y2?qbV!`N7$Bj!e7yCIO*(Nc6x7M!2-J+yNsjyl#e3 zH%GQXmgE!!Vcpv;a+$iJL#j^c4!};Uy-nJ0UT-RUoleI_*elpB63l?0 zCO&`9n^Dt!EZlZ`kDMFpfmSfxS%c(>fE@X_!*i>Jd^C{5pJ|^gNnqnKVIZf_oGDjKV!3=$}TD{=2U#| zeg=$^(6PsB%}wGKWf`@G-^TU*k^VtUHr`F~J~*o&~^7$yYABlZdIDSL)B! z@C*TAV%=6dM-WacV9f9m$j@#Cuy>}x3;B6f(H*0rtq(oOzh6M5SOxSxsG~hxBr?L< z94Gym>bQM3Hv*>oUo1dA7^uKYX6!87A4PagFhml5l5m=RUT|?SC?X-Y9#E~fb#c}k z9Osrc34@7%T>VqwtNl1d_B*pumeFBhFrSjmf)Rb7?Up?;IX4%rx9&L+ZaywS2GY}2 zJkobAS5ypZNOZB*E`S0ly!P9qshp8#$p*FH6rU3F`FUN+LvI`^(17pg$xk4^_EiN2 z7)%b2W{R0=z$#X55-XOh>Xp-4Q`6I{e9s?m;*O1t%~$*Ot?2!uE|tTz{z}tye0gL{ zKBva1HU~hH!1f@6CbT42TMSfqc()wg69X021oEzJ%|VyF%30h->djBf#9!H^A+N6C z1t9|#xEgik-R0A6qYcu^2BY0stz=|;r74Hf&JHBVo~4>t^#z`Rt%GIgx2qNO+ zvvgs%ABerf%6j+bllp-7evdwo`e0yUCdMXm@o?@f*P`;I2k=hi*!1RM7C=^f5S#lq zu#8zsjVmCR3g-6p%HV;{`%IWZg zgc$3|%HeDeb%6UZn+M2AJWg&26v+iD8;x28uYGBG6y-7d5$9pY1N4uSQQie=Z9^J_a?$%YYtz zcDBDk)&GeJHJZcDXdvjOobLcQ2L=%6=65_94EMry2n~LfMN=RW@GalMl$01zYdP({ zSNPSjy4r6gnVKe&3Vwv?PWAFa(y*c>K2H*m4{d)?<;>}p+8sq#H8z=n-tJ9pb0sn^ z1qS+zO-%v7M5%VYRQ)i;fK~BUvoJs=|5)ca&>NYhsyep0*%MASy*p7;P@}05UBKXR9_HZl&qnSmu2lYnvgx>f<6VqEqd?4+WO58J z7`HD=ixG{V*mvOvroDX^-+bLQ*JVMA`?YKTprpmHzL_Bs`E=aS*?BOPWQFoNDLtCw z^RFul_T@_U*qE4{9Akqv*Gqu(3py?6^=tFl0t`uqfnioP>;&uXtn0v1rV#WD)C>B} zbLRH2R%1hiYhx4t%KPT#QWS6rkW(J{Y&gy)Dc!rjR29fnK6k3E63c&hOE^TPIv}v; z#E)k9SmcS`kEF`e!)2deO8m7f_LhSaL>2yiA{@6yMAtZ(nSn4Zf$&1atk-2mZhjuq zuK})G|BItHhxhoplewxw`J?#?#M`b9OaYYcsszuUV~~t0*zAUOJ-svw{ngPX`LMin zLHS;3qE}ge{V_Sq40xe!_jP@8q%z8#kmt#5ch-J&HRs-->;z$@5rtO!&1YnZ?o{$) zau1PT`}co3Xy~0ru#HBpcIzp9yj)o=R~R(`iwbsDp)?;^!`OSq4O@fykBsl$2sWx+ znO`A_fZqGYbY%GVf{!V63H1Lmncz$;+M!IMmn**MP3L`k_q_XLWL$8I&5MGq19S>Q zOT(`0Pj6PLufw)N^d6ya%_eE7;OXKMWK6pxl=$d(CEe}5gFd3L&kj&`|Tj^ZHFitYIKs0L=iqmL*p?6&4K&*JrzLj-+#2e}uXw*LkeBn++Sh zo8UB$(_z%Q^8>_asMZV5f!bX+KD(uXJIUT|hwnfeG?6W}M=1l2==VK~@tF7qc4W%+ zbg`*^wfFk9m_<}LSf$YTyjlQX#d0d<()$Gl2H>0*tiJ^mUu;cdl?G`XH0a@!98pRR z77V@KA{#)n!PeR2{G>6x;^32D4fNvdp(m0=ZiQ~;eEUX?F*G6)20H`x95*|Co(8D0 zpd5hk{-GbnLyD4*^-T>dWQ2o9F_ahCgqxvOBNtObUi{6@PX81!t9jc7}Qvuyxq)F2Rp5+KAr?;9?VeWih$t*oU&Sk0b+6OjYyg+eA0d#q2SOk-Wo9DSr4u#Rlp|J&LK7N z(rW<$fkb^sbF-K4{YgCavroH;x|L#wwROe6r1*k?T*daw9}^kkQzBxG(HgsH#6hcc z#j?Bi9jWAvcS^HJ-l}xHnllYYbp66G1%-rdi|EpP(}qhYP1~}o*N^Dvq_o(5*GQs? ztfX^WYfj0y)YOxm^GL(ip?poOk3Zn^ zLoa+%l}0F)6yCt9?QQ{dCiw@4#T+1?0MJiRB^=YMM5*oZ3VO{e9viI<^XYQUeOi&q z-+zc0VQse z-ilB!i#n`G*`&t1ZHYwEr-J>j_=HJUEhVdPJ!gV7FArL;yIN?og@I$t~U()NL*-DcwhKEP=a=7;dD{xb+KQ9BjiSot&G(Y;DioG zU@pUoel<*LxnL1u6-ghO9aVV0qGY6H?!JuL%#^;RaenNcJ{ZrRgo`^2(Wv|HGohoD%m6SM6kXnmicO%IO-~0|| z>MIg+0_KlAF_e=0sRDAk&27BFNpJC;2>0W;7RL9_V|)h|lfGHFiu?8JcclHRGMfU3 z+sDNQpA6lT^4p*km0a;|F3#B$3CpxP>PV4?r_=@tiN>#h-d3~Q!*eoPN9NTk3J@>* z!|Lg`n?LE#J9QgfZDeLG4mJRsE8qZ&xg|1dC0i0naAv7I&c)gGjmX`X316~^k%yJ_ z&6*x#=woh$H&}=TpZQ$XJw{@|#{lAKIo_G%(`nPzDI8Su%9^=}=_BNl%x%A`iMQ)qe1O*^jE}u7v?jl`xD)9kEgfRH=g=JepbLPmD;XYSP)N7bH0 zqa*3yiqTB9&h^PW9$vKDp-{Q8K2s=_>^3mTdlXWk7Podhk;pxkWoIKPi8e+C*&4OJ z6kZmWGH7uexfcfenR7~>?foRX025g^jid<}&A(m7EmcaZy4txGXMVi)MXbrUD?IHp zddx4N*y`)6R(A2ZUky!2Fkh~hk(X!rH2_3|e7KZU5-}NPz&mf56=9*~#g^06(B1t7 zH_GmwpCifeZ1ZsDX)S`&@^C-fXE5H}0g)G$&DOr7LmPYoRWfKG_fb(P^RgzK#^xO{Bp@O4@KBIIy!(c zrdh8U?C$y=U-2CBC%ID?YQ)gy8;)@$y!XJDltNM?GD%8IJa|uR7u^6qHDkzEAU9hm zjjpa%3;TdC9-LTDb%RQ`-ZKQ@`-9NFD!VzDCF79M%0Eh@;N%?Fzl!YhzPg(0JB&=S z-x&{AnaQvCZk>}pJg@D}Tc}S_1nyIrduP%44uVvHExx2225U#Ys8x}Hi=G1ZNOb{q2U{4 zHHV?>tpV9&+!O?fa$aJuHVGzA?hvlwVGBImzKCP9(Q(i|y`fQkdq}Wi7F6*nl7?p! zD)(u;9zB||Usl!GpWd0jC^l|$qgUm?JOTm~<};7gDp%lYPI9{XY<$vA6GUcae(ClBFv-D}@(0Wo_S}t-!{ScA5eYEV=X1=&U7k zW6|V}O-#g$4E{|SHCHBoQwG8vt!i~Xr*AFQ$-%hE9BQ#lo7nQuZr_c8;qB((yDZEs z*H>54-r?1C#j_y~g?K^JbqBX79f0QFiiVe$=lAd50J(_25_LmH!%W9YLZP!C_s8>WjrWkZ>1G^NW($ zAIXg;zsOwM5}Ld}$h_w{nY$3_f{&%Foeyr*L?hz|5@$5rSMTRUXoq`rQ#z>~LRyS| zZ6b?nkPDT&jJLNn^vT61kFt)(j<+`^*M+6&oT%g;)Z((_ze9X%=XWq{iGO!(eY!*MemNnNdL82X~-;Qc7z~O-NTN8x=nn-WQ=m!y6?hNUm zo$Z8&my}fiu?4II3QE|kh{D$c_#i_H;Z_etcP*wrrIN)Tk+QWL*_w_vsI~%Lmo-DH zI1y!-^AQVo(uVMpgM26Jhut-@w-_H(zWBF3`sV!hYA#O{v!wTGoSA0kGwb|C;*>acHs~>6GhLcbcS4vxu~q(TXnUr4cTzT|F_ATyFJ0K< z>|{!>x~2w~3M3C*%%(eq-@V^&_hq}JeD8z2<>`VJ|76cVc}Yg(cG&Ui!h6W zhiKV#!o#+ZQd@&=F)b-IL+R^w9z(G2fZ$X7RfN!kd2F)hea7!C>}sZwNaxh1SHvk% z)36?85gi#9qu#)tpig&}HeG@z$el?|Q!>pdv#uw$vz`5jf=~y4<_)IyG3aqw=+m9@ zk+$$xkWY%rlCnMfc0VHW{ZdOcTwTF8Jw33Z`Gon3J8G|CxRrtExw^!7hk(fZ>t66v zceJ0DHjIVL$4~tk2L_(`VxWN{ma#s1tk-&do~&ia$jze_1AVcVf7NS&vERrMOijhE%Nqu;|ucYWwXQH8nN8Y4&T#;Ae~v zl}%p0t zB3bOc6)5;I57=sJcd}S%VuO3issfYogH(ri;J1nZ}Wgur6xaoq0tQOreV>$7G~$YaVt6>Tdet(DSM{UfMWh@ zigqN?Igx?QNscx?EITu#C6)YV9ix=%{W@jnUw#P?OUP*HLg&`&c(o3M zvF0B7y;M3HQtrY}_ds^LFycYcxTgI5$qdzGR`u7qmv*eLxg)%IgJS&75<-SxllVaC zmFK1py_YozoC$!tTi*54lS1xtC_TN$v>vv%9@`O_A`ca%~-p z^B+>4$#UowNajBI!=$koA9C3?35Z1~Pig@k|3_EapWxfPj*D2yl{QnhTbl&` zHX7HXV_Bk;{MT;jB(yl?#U672B{d%T(cv!uS;A2_uut z=n*@=$L342`OjC84oj7uZ!Z0-|M}0T#9WE;I8!B8oZ=xU9)(d@9Fy!b`*!#TasSIb zDj>T|o+@Lw=WCHsM)@1&Q5aKl>8hPbLdf&^MG79nC9<#uJF((kzc>9WN<~4*4C@~< z<8(4}3M(Jk+IAe0=a=)2=K;ynil$YXXlRcm}Nd9wd zluU)#=)wNJ_+P`(o%_si*_gigm_ey_!~@!Yq>f*zBQCqD)O04-O zBBtVM)Is+zsE`l;v4=xJaWC{?ql*@YVtpa*Hae>47L+$fPso6G35+MFd z%Km;uT5JE4o<`hMM`)@=$%;(!eKGeDN^>Ncw;5)XvkwN~<Je zCoKG#B6F*^Q6JGJFb~wnLdmIghG5g%$8}D?1qu4E%s-VKW7dM05O6& zec*L@LR_jNva^<^fNi<)l3S2>cyaKfu5Re2VUz3D=<#Vd>7aV6`!5vei;C=$Pj&%(qw1|U7lULSq*2x8lhCkI*5cu@6 zL}%f0HU;^`hqu?z*2P}EvpSL>RtO2fb2w8rBTAo9NDt|wuZEA8t6HS_cG%?DwA z+OvTlMn1(KwX+kSB0axrgD;M~41YFdmxd|CK6L@Fcr7-XkR|`ct1~~oSiOQr$HZ}S zkKQ18LVd0Qe)TyBcYEbqw?y$7%xW&z{JejUdS}_e>u9iRf)8O*n4j<2)x@)}$3w7) zUrS!MC-{;QPv9K>2H57FKMw&!Nj_9(Ouubl5efN<`_>T`b&JUiBl{GxuKtb;EMy zkjs zY~HXI&hK0tc^nm}Q0zPM))vp#uTxCP&l~{QgZ(gUY%h(%S%auzerJ6)^syR@Z1N(f ziRpaUr(G3150MZh9(@N8HyoHV^}o zfEjWzo?@Xkn}U+Z!Jy!x%xYy;5?DB}4pni_Eg=UOYMS6I^cnJOc!8ZxU}{zd?z51v z=%FkxFXFWw2>qa9tfodMSg^0Vy<@r6yj7Ao_-nYInei*Y6|;iC+sW#we4pJ*px0T< z;4IE%DUR_CEm&sN5K@rwx!hJJLf&6e3DCHI6b^!Fs%lY!TG;DPl1|GnGg>~@x_d73 zez5#_wH8Yx3=Mh5I|*6Ju8NDBWLM_fO-o$qDyTrL$_&WpX>#w*m7&^wvWK*KKW3B+ z_~tV_+|SEdI9e$BSJwTUUf&gjO9{`tkX2AfEiZR98wjN!*Q;hqP{T=EG*|+q3%bRt z#TAFjgUDpbda*jBR5l|PAzp|zgGv$6^b*1bep`{{h>MrNzq&PW;k7YoP? ze$t*5_rb8vi$NN!yF6W{;gi43 zQiiag#Ge&x$@TpZuUVLxF%0|~ylG*OPhxrBcajyo7<(Mn*CmlG1x2FUM}X+(OtEoL z%)@B+fF`yFXPC?b-~H2eYW`e1r?0kOddut#!_+yZqvS*^=Q1RdN5FZn)dJPQ?4b_@aF)1h- zPEJmis+|Ic_o<^V9rzbC`0fGzFTk9zRwv?(m-ee82M8pKj(_GuYpt++$fZP9bsq7bmh2;5OA%%lOEa8W`xXSbKG!pGMi8J z2m!m%&4qojt(hqHn}gYL;nF3Tw7hz&VZ|_O@^k^D6+9r^K_k8Z2PiGW1C@`2m^Hbr zW_l9L)jpXl{<^o@b1$Pns%caK7~-qN5g@%S!acfX!3E=J_BuH_kbif4k9B$Sl1~@$uwUGzQx|1J~_tBrRgd={k;zgz1s)})6&ybEVTrY z$~!Lus&LYDnw9&I}=HMX5U;Jt;ojh5jsmS=@LY}((J#`FKR$=djkTeToMX+N6wS=@Frf?VAh2pYSJ4;LcfY>LAgwEJZ3NM)z2pL^ZF0ijYR6TW4H$k5H zwhCHVTQjn-V1RYbcoJTg^;{b3K4B(3>$h=YXJS*%szmU|&JmQOV|Q zzw2cegxQVdYjWvoG)oZx`9g{tytbOr{sSvp@nO@E8(JU4jpM@fSP%S(nX-L_AA@Xgs9uUc1&YuVr`9!7DW>Nx)(7bsd2m zMF@~K=YBxtdkPYwak@Y}+8Zm>`soN10&TvBr#OB2<{lmttUD=rBiVNfO0o{E9u;Oa zPbbAFCku8@TtMk<&Le}ro?&BVaJg`6Q{~ke_SUh^^Lxw6nv)P&iu1kH(UCPShRAhrV8JNL;inW*V3v#N7R+jDvVZ(jp?aFG zj`Pb5xa;BK@j`o0B4k;WB^ukDAS5Q{Wv%t>q1gU6JFf^|j5}K^qn!ugS@u=beSsTE z1YncfuzCMy>w-0Ty?G0bt`gEKB4pAD`>LU6akccriLe6huw^t-PJvMqvDUEx8tUKB`-IC8+gE3fGt_Rn)_xe{W-P+)t@KH#c{;?1o@SQ3`8E zXVla#q#bJ$3u{& zwb^aZEr@B|VQt55{uS@V8WFL?ZjD8;jKn7o30e_d(p!$O0iU;mihEBej;$eC-leY)!!P_6iyCOdK2^5?k^qekF?8ab5%a@)v zXuem(oF>1YT||u|@xhrbBWwf?|6_SZ1P8}NC*&iZgJu~Z_jfcivoIJpT0q8ul&XqK z@OR}Gx~z1p`l3qr1yk!Aoix;qiGfJZy$=k)*2+i;v=&q~_$UO7fT>A8+OB|-(ErA* z;)g{re-;jRu_N7yS6R_h<+6aC>m_Ef-4^%LgPt_>oS^e50tD!#nnCj?H8swzL)`*o zi3=UDPn+#hP24{c#dpmbRsiFib4}=-fZqXCL|(x2OSMW-He(v(2HQ5|RqXX9C zCK>NPq84}5gU8nQ&}L2(A%gRK1qmUmUPUt+s|!g!IFSl#k&Q>VSk*7DC`hd3iOF_q zF2}rYTs6xiL}FtETUj;|DR*YdWXq73w{;R?V$`)Hr%qA(rgWm*AM zt(DEx6`^DHft)_Y{%90?z@ih|*D6@QRdu*Rph#+4c0k{uvy7T}y}9NtK)$SD&wx7@ zXrV7iWX1K|SA7?L;*bqW!!11pFnaC)n!d>WiP^~w}|Sa z{patm<xa#)g!slHRk7do{#s?#8)aURMM7G?q)P~4_w4GQMW26A z@fLdts`J~}qM|kYQ2kcM2#083f&BwuMidUNM1;mACDFOh6`7iMDyc~2e=_X5?Iq&o zm{gXLTjMnYn-9{p^e42uI_6mKHOo>gq4%R={o&3iIp%Uj_s~PKdGjLB_`P3lCQBru z1iS0|@1l@k6$HYPj-CN?xC)=2BCfDOUgem(P;X#??+XR(#{F<2^;kIR(ZNf(2jAe? zoU{8b20}B1=p=&1veIUX4HX;-qqc zq`!9xs3UnnO#6|dfOWCuCfM9JJTzx29%$ERMBpQ z@1`CXMHJ@dGG661EUZe}N^}#gsc4twH_gYBfywGAGLxOZ=VPB-%1n4re8U zU0r!=sb~Kb6`rX-5bql-%dxs#jKlYoFEB>7q`Btnz^()P(Q&z^yM&70mRV+RP2lbd zw%&l&Zr^{^Xl?&TO!n$2=hUP|l5tkuquP#ixMM-h?b(K&V0x|1eG`okyCfPKIQcF~ z_TpD=ZoV1_I+%Oy$6|wV+x~SlohYvTquA1q{?O1#b8}zR^AfnXSCr=;>@$~@1}~mc z?Udo|2_gvK=sQsUd8OK_0H>i?01;G9-V+RdDf~@-glk;*30eCQm1e4WD0be z2!<7#Dsk|PmF;@Z6og$5;D1zk{6b=1PhgH}L`z0NPECz@-b57Bso`Us!xOiVH8aL# zi|5OEbnbj#bK`PH@yy!}p^lEa_8P=LBhc!lo~NWtk6uOdGH$3KjS2vd75S_}pv<5W za$#Z;2zdMoP>H7S6^-EQi)yDE8rV%j@2l(u(STgp;qojzEX=&3@I*wUP)&99wSD62 zd8ho3I}4NVeeUOLh#-3PwkN-9(e>TuEH{5^>gBWrk=2#y5ff!(=3c4qs1eH8QkTC8 zkQIXuK8DA(FdcEbA%EzBBbC#eJ^u`gGphqXDBIZr3=R#?D^axGQRef`%gcLC2MN^n zW(@FoPLvv(oKQ|1<+#4F4hYEp3KtmJ0RFaa+aJJgC9rG>R^S@Wte-|Ps1RQG`_~jc z!L{bXdTyK}X(zl;y0-qlRZ#um)NH1CI)Si9s>NKyrMc`QTwYzg)@2|cs52(h+I)9? zU41lt_f_oGWto^3r)TG_Gbok(SoN|Bf;d-b@ckgUORGrSf9_s9iSq%6uA8w(jjp?t zwc@Z^?f~ni$TNI&%Z24}mAr_fBz8@Swc}?YjgO)(l8|cClOaUM~p7WRxtmPt+>oPp{?%`kv`w)he)Tq?#J&s zr}QS%$wjQctYY-v24SkH08w&#_djcor2is*>7#gcDx!1Q>rPDnc`_@+*H2Z<&8K=Y-Huu@BB^Wz|PA7D^|+ z?m%~aXZu;{Zh_!S^AnDrbnFcBR@>MCF3HoE7ue3=mE<&$28ebC1NU)PfJokx4kH@i zenq2uBl`D-O={WZ+!)XENl8#V6n5YA+--}CqxEw8k?B`n6(BK_!T#7SnHDIk=;;z? z@RYvduLcJPzf?HQ5RoP(*>PZ@rDtHdC#L}b&o9&+tju|S70}mrpvwP^xU-I``fJ;~ z1t=g$9FSI!7Lb;fmX31(X^`#)X#@c!rKP*OyF|L-&<)au?w-x>d7pPZv)0UCGqdLW zsr32oz3+YB*L8iYCbpCcbCN`E3};_q;OIThd**z3zJ4XP#bvcOB&4F^I+!|2aBZ1f z!h{7wvp1cnYm#}+a0^9m5)&(@-`)fg5I3aV+x_F)QdK)vJz5Egt*rDH=x5aSp8Rch z2l!hHN0?97*3QqH*W1B)9V~XSYz)QTx5w-OC*mAvraOn|^Mnc1m7eSwH}GeXG-> z&Ir1iV=)S!M^4gl0vTLVDbEC{`4GJmZYq|aim4Kn^KSgzLteNw&{T2@wRsSy$+g!x z&*Y`io{;x^ltLp#ZF_X8A@WF1R7|w9-M#)OVe8=bYpaV3w{+?%-`hy@jdG9|$II(Z zzp+^o>MyUPP-JZR`?i!BsRs%E_Ad)YWm64Nj7Wl|sfdEh>504cFZc8;o$?L`i+DJ` zd3Q+;gJkzu+h}O~%7CYJ`r-|KngVf&8l)Fc6-R4ztmd+xVNsm=jx&j&_Qm+s(IEky zP1DKi`1qG2r#{}kWE|2aN#hrUCp+-bAGg<(LdJ;={!(g+lGbeengknplwSnm{A0)( zrNq@EXww4LvMN~ZNnY?aBeg5`ZX4VD@VDTCdX)hH$~2A>lK|@qS!lb0k}@h*mv&^8 z=z@I&)36GdYsYh%80&$?=Bl9Nwa`W2#Rc|X{Qa*1LBH?Lch9a*MlrqF%;o(btukph zryqUVyDIjOA6X5-ZmSo~;RO$BCl?wX%2qM z+uxLp#2iBgpaV@kps~5VT#%nm$-uC>a+XAh$yHms&N%;3>S}yYEU_CtUt`-QQ=Z^g zP{B5~mg^ZcgHcHj=b4P-63!i@a<%&e@edp-*}YyCvqu4k!VwJt(mCxa!} zvs3sz`1&yL1uDI~zkrfHokK2)caK-@yV%Qm%TOIebm>*<7tF9<7?=$83ix+k{+@bKpV#Qj;&q5=O z;)B1^%Bw0;nCfk=zODsttCYP9iw?thb|sY9dBOim3@j1__4~<;#f5<1^6rxGaNWa3 z9#-Gzvy!1+;3Jk7;K z{xUO|yVIU&%Kda8nI)2?o~s%{TrZ;FcZI3Fp+Zxfl@*>8eT&F+HIQ1e`E*^0EUDW^-1F9W@G z*7p$H#%Bjv@qfC!)M~#9l1+7fg6Apts#(sQl9rZRi1gnME@{)!j^`>x4e+n}nsM$b zWMw_TX@5w&Ue<4p<)063X-;wr)ui*bhqhTAe(=e3j{Q<-jAmU$dISUlIojCV*1BHU zFbK$T=h0vRnb;CC&*0REdA=Vl3sQ)GNJOUxBGcQoa4nVrh9|A~B82`Bt#e zuMZ!k{;+4Hym?b|;2mC(@|oI-PLkgZot?Sh6+JkI5W?0^k%~=jeL)`*m~}MoS1jH) z$pB|5&aJJ;cs>X8M)Ua^Qi$}7BU!1%_$z+KrQcEN$L&)uN)}NL9*G%tfH(qsa|@~U ziIX*Vndc6Yt_Y4?!u{9h5s4PVhxc)^Pl4tLmZMgSeWGABYx8qyF0^pEScSUvG%CHZ zumQwFRwtd2@(&ISSdKM>4b9}D)!B7&bPj41DK)ZKujdUztsGtKE_Jok3- zrkb>wG;v0u{4c!L3{I0dKk(JP&T`7(*9^v3J}6IsTjyf=glGCWXk=#vZ?Dd&2fWQN z(g%D*y4TFZzxy&g2M0Kt?iMpQ?w7HAb7Qug*Nl%50#hl3j8A^!VKTaaG^;b>#ijTC z^?>Q4!!qsN^D%nuZ_JP0nmXTdnzn$<*^s2VoSaw1>FEZBpFbXjCf0qdUmDq&DfT$t zo-&yqd7eF}y*(CuhJ$XeRma66e-i0ZOM5P)z9{q#Fdnk#5L1DiIkd9^=%>7DB~cP07JHAWPw98aF`^3e74{SCoI8?pRrlUsP>AFTYQXT<_q>Yu9?Ru_*;V z&#qebn%7jZnC!;Ivamk?5CdH=Rw&p4OdT5#3GGfsXkTvP(~j5Ep!o*73H=Aj7-jb@B?)W`EEZG7-;5n}HQH2@>VvxC# z&6JsKB%kgZS2iH9Fbn&6{zqh?1v9339t8SURI%;NjK4%xB4JL8KF>2`fpQKY!YWmU`ZAMQJ4rQZV*^!EhUh%FrzeWj7 zR50GPIvm1sQQdFrI-JGI$}Dye{JOSj#G;|>p)Au2bP5iIq~bK=SuA*A=nj z>?0v&Wl2}uy^Wz=^#@WLJ|GH6W(gjsV#R#@niR|r?f9O6J~QZ)f|1qz)mvTzBnXI- zTBF?sr7R9b5jn~xze{lUK>6;tH+%%%KPy#MfxUEzMXU6EZDp~wKczmgEI(vi<0txJ zF0V{NKR-Dm3#NpPIDL$w1^oH9Jsx`oUpf700c=NmOvs!)ys`-t>%-(;ZYShk%la^ zE!E-3@w5v4gNeh&_cYI zWqbxf!965pZO}$)Bp2v@dYhu=oWyXS^4;$BA2|zc|4%eLk+1uA>VBzm@&akpeU!x= z9=OQL>cfu1SBYjE5t{v3QF_@;c6bGc$A^00|9jqLTRx_pEwS6fYK;{J6!O@>7>krm z;74a;I6vFyM$>LSi!z%YIR;@dQ`KOXo#d(;O87B~_wKH)=KPzC`dJzt`0KrT@-PHD zJU)KLX>pPdCBz-$POba*+xIkoyAH~+u(ZKj>cvtZTt9xicS2-2n~;$Ka7W2QBAutF zv(i#hM;*_%%RKYw=#-<^pj06l7rn}s0Y8G%e*mx%7>j>uYB)_GSc&zV%Po(Yu$W%m z*}l)H^m+i2-bFUnnQp%dvf11$V`*yMTf^0z$f`;#`WW3Wrf=Y}y}P7ZAb6U?!4#cf z60oPA-?d-@H_iV3@x?K%bajJlKAucR2r=j%fw@=+ z5nO#km^QD>;HnAq1~1Q%jLl5Oa+M0zV@^Rp92vjkWxx6v^656eQO6Ut;JRjjde+a; zUYajtMRY)+(1~KL5|eHIX%rHR!sx1C^(x~A-BC+9D*+0M8?CuS*LwRbc0djnFuM&f zi4b!KB7ozI`15b)J<3tQLg#eY*NzgJ)Y;z7X#$I(O9A$5^yYe#v-$Kvt%hf)w{K_} z#xlP4d+PbUBs##8N#MQ%j%r}H&XTRA=o}oLaK4%L!5FRz?wziv%7o1FHSnCgd`n5W z>bOz?9LnI*cncZWA&D-Wz3!M}1TR}@0s>I`vt7D<11C=C zH%<_1(heyg{gO$m^y`d{kdPvNOzJI}Hv|_Kh{L{;)nbd6HS0QAC#!|+|``S z%)rI%7vfm^8)4xlv|J-$M?sNp636|=agT@FWw!5(%zG8`*WK+AKwX|}1*23SjwhlF zYSmCNQ480DXJh+T_?E{FQPAK`Z1Fc>I}wQ6OY>=I>9lMb87L{Irn-m!40(|g3X92N zT@U4!<1v98V7fSDi2c2yl`E!bRv%xp$tCbM^95!a5!fGIf_KMIhVWg3)J?S+zj}hh z4&uD`tVoN)UkDxMrMQ^%dl^?7Br@vGj~VuxY#ymzOTEWq;3L z)EnZEd!j<5;C(C)$X)xf;y3!I$%k5<>-1N>HH0T4+I+Sy=JI<24>zx4{g>^n1CXpB zALYBI!p3>xv0Y_%6c9Vw5kk_w_ts^Tu|@`vd{C+f=56@8i{u(V36Wi1uohz&S$>8W z%f$dw%E&l4ePVy-Y84(PZc|%n^U1o(GSRD4x!IpB@8nZU2R+|h1#^p9_S^v{owLjB zn9%10lYv?t9qnY(^#{`zZFWY7e*V0!w{eB}-CZ9S8a=koQ!S1i#*35W>}Wm<-8jrT z=9HU_m2vH9%_p&2Xe`WYnhaP}`@`@v76%Mew7k;ACoq6?;@YlhF4K0Kw2et*SHMjy z*lzt4!+Tpgfjik18HKal&3T6a+A;E^^6tdGcQAp2aj&DTt+~wR>xmg2;05f@2eYb9 zsm_k@p~%V;r>ZICXP+_6HQ1WZZnU!59i6(v7)O&3T-HHaj0rre9Z`A}zrW5AWn`kU zA6LGkq<~nvo*q>-+imw4pcw(%wYHMd)La`68-leu(GBfVW;+_3o5O!vZW$}4p6U4; z8W{Nc9Y|g~VlZUO5y&_^n|=k3BKcE*uCN6grN`Drh(}|+Vq>t2iOUHQ1V8zM5=~zJ zkRmX9m{;bOIZ!&fGg&nsM66XAj|S7(MVyC9OMR5Yp4FM*U|7{R0P!8$V}+tjxmJ=J zI5XT8FlFU59g#qeIh5zg_D826TVQ&UJtjPSWPF^3W4T>~a6DfW3l*eVf+_4V3)N+( zk%>u+8N9`h3c!KH?nbJ0w5Q=kf_I8BYM<{XV3fdYW}&{$Kh6%iCsRM%t*||@@)v_-C<6qesfob!AM`wlpTo>|B!DfuS;j0)>NTj`ULVN9O$+_{{y z!!N3x^OW|?kM2)>jqas`=CNfX+Rw;^4kG zuC3H4D@!b|=sPPCRRT-H`Ai|~hzQ>`+$??R!7d$Y<77w_r1oMw8dAHdjdz?NYM0Gs zrg1kuhl0ncJa+De3azLbxC_VwiLf`nq>+s%njIxv86IKhu z&621M9&|;n>+QXqecE_fSQ5j}<5Cu7#XHB5eQTf{RjTO$YgE7s4z9C8va(fX)U(Nt z9_$ZpZFB`1H@K||8f1b<2BP}4W;ZDqtgnI6%;fXrBL560Q?}Dw)6pWxM-j>=INV!% zg-Ir0bnf%Y?dEZ9W;9-dAOVwBvjGZ}*Zm;imK}(+6=dUr>;=Xr|TD zm#UX1C$3~9kTzUR(95vB9`H$#dkw_Ox_5MO@wxdob$?$%FCu=Dvn@w#-r1Y zVbMXd`>KA^KW zG5?~cVK$!QayxPYqKPx!tbB??54)T!*}&(qy~nDTu$~nWOr|jJClUL^QN1fElaFam^T*W z+)G=gV`9Q@Gy6_eH5TlyeX1p<7kT|B+vA`2vh+8%w&Z*7E@i4s%A<+7U8vX)flrR~ zUW$SZTsE;DaWIe#4Q&M%&_S(z@>@MIj114p%F4@QgxmS#lE!M4%(rrX$+ zdXEdO8&nsV`llwt-mz^bkoy_Un4r*XQjdJH4Xdm|fA%~bLZ|v`YctB|zRZ7lU*&-6 zk)zT~9%%yva${+y=ae~sGYhZZSpa9I$RgjJXQIk#hVBi*?z52Mil2iF`g4#tJ4qcu z!ees_9C%Xr(wv;Epw%hHzFkpakD7>>^6Z$(9_cLe>q1?cB26q?C$*P1O*H6Ooa}0-O524C_>oisJP!(8Iq+9 zhu!rly!P1^v9up)Y2@y+;H*=dVF&pyJa)HRDG&MlFm~H;d;dP8P-ci<(OFmqY11G%_~h`w z>i7sp43)*;_tQMs8!D=UP_Z(wa3aJ`$oO4km%^R2JSy($oeF?-^+6BmkH2tq;HOw+kd13QulxO(c9fG^HH)NxN7_QdIq`; zz<2!<9GUSA1aAdZM8*YpfBW|2h&sjX$%6+rXPiCaG`#=(`jYatrY`1gWzl|R2|*PJ z1r-$)xL{j-Wm#5MHp)^)gMGkGB>~lxkPr;H;G-dX_+XK2zq41I1{>U3VYZSkE{0ix z&i88mMQtoXQhFx(^qf!E+{8WNU=^QTdt5vf^)&*)D_ilBgCBOl75kPQxsK3;AeJ_F zQ@Zs2r}6R}v5F3rM+fEN&xG08$#Z?lWl&DF2>7GcY}EXnoh27||9F)G6j*Hmn*2fs z_joOAY-lB0ENfjdkc~q=@7rjg)RUQ{jO>`DpZ~~M=|mrBG)p>{Ws6~mHs<~ zmOL`_-gio`b@8+vM4$fGd;5QYNZV&E%^a9R83f61rG)Q>0)B4F3d(urCcA$p74s92`xhJ*;XwFp^83$6&(*RNmN;b#F&c19bJ|syaRAiUX=aw68l_#t0Ev3c1Y>85)1HqIU_jBa z+0E|r0}=(6ySKi6#>q(!r%@P zqbXEp%TpK&$J-HbneXL%N5vrv6`rdLR|Vvb3al*iK)H{zb{psh-!d|Adnh93HoR*s z_71X{X7m3Ag;FzGzl{h@YSh)Xjm`O=*=0kz*(NbqZKV~7W|7vqJftG@yFX$x=TWf*j5AEs(uS6{OWN zL#?s8NgO2~s4EZZR&zLQQq}2p zoeA%6hTbK(7a{)L3n0>H?;+=+bb!B^C!!7}_|zy#iS^?v&t`adIP556+dBKy@x4uR zWVKtyw&H8EJftxb*7CALtusl4sRX6rJa+QKF3fwZl>)O3N{D94tQ3A&&G{b{tHzO0 zR^!_!qO+Xv9kQ3wOu5L8cL!3Y{=;r`*t2{$#zKNxjOWmokS!si3^mQ6&LMAp+2fIh z;}iRw3z?X_OfyIQqxdJU;x=$ZSZO6ik1$E=KSWviY5M>?0UA zQ#xQe$8EG?J5Wg%6qsM00qJ+1IE%sjCK@M==P+}2pHPfUvsa2x)9@&@R|rR2 zGx8d)HSN*jy2kPj5luzT$BVe-VdbbkkuTuuf^fFq5}90& zvDLx_i)Skn&f~Vd->LhV+dKaC7)geUDyZ80w`H^nA3d*3RT0=^J+DB4qnSe`gHOoC zr5X?>B_*NID*X^~U#OUljO2|&{ExQ@Nr=STYooKc`wu+t!pJdjM>vKiGNZH`4l1mM zzt0f1Pv^36yKatWFh4%@h~CHqVsj%|;tpA8ethD_#Aqy|CtO{qHD-VR;|=O6!D71C z@mGu999YtOGo;3hMYjIbXU#1-Skzr0E1yI^zz$jw?{b(MxH7w{j@uF*9!boVVH8Xk z4cA`UzWchvp!+NdKUxQc{c-bG9y9&(mR;QJlpm)S=DC5t3JptD*QWbXP8kT--Rr-7 z`;#OSm~&Wt)Iz((#pQU}Gjux#wlTGcx-*kB;Tb%P!Z>++%EpX==W$0N0tGeMGzUx4rnMLdD0D=CGm`T%ELF z9>Bo5Cc5PE4sjIg2!)7fe>qy)wv@HNE1VWHiU{`)U2s*)mJ)YG4lo0lFZ-|zJghMr zFx#s)Jb=|9mle)pU{u+U1D~2?;#YX?`Sn;mNOnwk?-YzW4h(~L!5j3{^jAG|`9L)6 zd+|z=j{la7Mp7u|vsLq%P`B68`sIy!3~D3&LRn=BOPVy++w7c-db>MK9}}}6W#GqlNa_{IRuDJk`Fi6h<9SC&^C@Pb#|*S7j-l7PW<+#w7Nsd zi!_gsQT@}l%w41Sl3=pzd1rx$Hd3wD*9t)&WLS!Szd`OXLo*DrX*^k+jLkQm!V{Z6 z9EMM(?6Z%#O=MumW_fLEJ=0*wO^=~<`GIMGbH7U<+{s|oS`DW4{xP0&(_y{Zn6MmHSPVEAv$h&kYh5O@&l{81x8WnO_C(uyH`TQK^t=J}&ikYDXIj z9X9SpwTzX0q2!O00VN?LTwozX(87;Q{8RNwO9CZPE=1(3l4CB0fEC*3V#%>Q*yp{G zY(i&AQ^M*B?<5TMe14}3JYSgaJiUua6R0z4*M|t=Ql18a82iV~3>fiZT<| zfydnG$ruG~4zuo>?I~hVqaw+$suBzZi=}Yj6nw4+eip8wtS#>v>#FV{mhb+6?V7qz zLqUE~;(KiFYZ6^kd<7J&lSfKbEZL-QS|Kzk(yY0%a$J#~F+WAxldY&}O`E9Z5~kl> z^UxZb;kJBUtd4ajdx(|%GcvA&=N52J%|HB%9EItfbF#c~XZldtYr-P>$K#1o)0FkE zOkWAzd8MGT%AoyY3>_vjxF--z4h+EI@;C`8(2l}nD`j%rtL*L9t2|qOvxB5ZQ6H@k zYrCGybJ}vrIBYSOtu2t8V&6P$UZQNSRd25&Z=a$K9QF+(F*!$pP%)SEuTT#zD3W$Y z;G?GRucmKc7ygu7G*xW?TRYWkn&KAv&O(2a!3vPi%(?GhLpNf8EWyMx)J)zX!M%ir z{@Csx!l36Y36DRj7dW`%I11XD`UZg7mraQl9M!lG$T$9v$0Kf53aL#@d8S=GUG{r_ zTUv^*51)W|((bM<`7^!zwdWg?BgCRe7sh@+fO3xqC%X)8$(i7r@di9z#xI&p7!~+#Y?8SfTCH=2iI@z2#-!s#on)QF}{;(zh0p zaON)8R=H=&cv&iM_M9(}%UZEaS2Sx}#D#RwE->owG^-v3Zhy-Tc+R5}+^_6CC_4}z z_2!(~PgWH|ANaFm-!)WgsNUREDfpbQy)m#+z?Va6N7oU9eHf^XTRsdc__?$RB*E}A z1ss7S%4{O%EknPVp!Jl0Bbi`GKR@|1KK)2qjnA*@xYb~^W$#$?2KP=;h7TFYj*3ou zu^E__wzVWQ8PG0*AKW)FEOK0562pv z$cD2TT>7(5dc|r3eW2E5+nE$RWj+xU&nzsgQ$$N2*s!R-TNo1%ZHB&t`z)RP6+cWK zXyIo~n1;b$bGaUV-@0D%mSh`Obe3D#abSi)IHoI%CBJVWnQsi{|i6#uJ2C^+bLXjG?O|aQ~z81Azz`BiNR(69D=)Oei2h5I+{{AuGgp2u?b6Rvq0IGOODAWPvmcXBI1RoWQObK3ZF|Fi3;8T37smmafa z;z|^|2Q9>=&8zM&XmOF-^^c<2?aOND8DMksELz8YUdhdQg!OGB6OCAUmfyR4qHfX=JQ5heK{A~W7!RzqLAr|aWHJ~Z+3 zB=AJ0x1d~gGESFT-V$Mw#Tmnz$M+x35zO!P@&l0o@z|!XWhi0|?q`S^+UuBJjJzXJ?02i4d0P=?AzVb9W`s_>mjc;09Ilr!36 zG=~gpciOjk%n7`EJ&o{TM*oFHoi8%u_&^ADoPp0Rv?TLP1uspv1714>Kj>z z>E7)Al{@BbPPYhyE*g}=xs_4;7PW$KY;5Bx%0AGON=s7vs%O5uh^x1Hbo<@F%*l3C z^Wy9lo?|M}>J(r!Yywu8!ac?Edi@iy0Dc}Fpnx5ba$7Ri8-v?7AoeQc?H}Cjb6sy& zT$oK>;42*CfzIvw~D4oX{EG4u^#vUy=btY@8P8jH+pk%v9iN9U@(_*&Y$g$ z&kt0+CR#E)KdVys%W{shS8BSpK=!wd<4cY)$X*b)j;9j4Bqzs8i}8rKTJg*iDf4;k zMEX9q!}FN-Zy=o(xvczdb;##=&&ImSY%{hf)S_y#=uueqHh<+%4$(JBr^dr+K=h=C z>?(_$Luu@6+zH|O*ygh=*V?nj^e+x^gtE)N$^?s+-=$lNDO3xypXA;>w=|o8!zVw8 zsl{zYMjD#JmgaDzy1jx!H;hdb&)UKD9&~5Wo7baBuw=fzrtXYxJ3nD%@Sp;qTa~ol zoP+`g%JQiQ@sdIGWp39R4B@S%JCnc#aqD;2>MAd9HPK(Tg3+N}Hd^46w3HG)9Q zU&=%sN&?F^gjkxK&_$0@qw892RplxO1o%FFh;#pwPHh?NMt~qu8N)gaxrs3=e0e!btaHj*Q4 z#YN$VB>I9J_szD>ga}j^OsgF_n8I{oBBTh z(~y5&-}!)4B|uyL3Fv)35D>oa0zUA(2f%cWRPcg-+ux(p%6arp8*=7F4-@mh(}O^h zmGoa}t!wLnCR%N%7g6?6{_v*I0xdkbX2cJ_XV`fK~ zUNcKfz&j@H_#Qu?eDn~*%hNwBtf?~7cQL^^a6%@b>O1X8TAE({F>&kl-5cs`bP~Qf zc-^zd%Z4jeHzA2A3H(kc9feoX>}o>^q&FP}^Cjg!t?>KUS=Wlb>~C=K6s8r39934b z#V%tv3c%u%-#MhpM4Ym3@kqxty=P^WGWHemNStgNb-G#O({v5hN4;SP$ook41Tc}F zYT2S`Q+5pu@Y}2%ZalLyC()o&uFiB~(5QONLKpY2$rUq6xzeQ3`RXBZ%3DFN$BPTY zxx(?SH?G!9x!v|)JjIwe&5}6}Ml-+el7Yy$kmvZvj~{v;W_dj?95;LV`RW}JLj$s) z*JT5o4D61$-t&73BmWqMzX7`4A)(uQf+8#DC=0Yui` zA}z!qK#s?e@SXdBt)s7#Ruh$S@TPX$>EQtxhoMWMUkDuKz0uMZyn@Y<d_!%TCKJo^*hCcB)nhfHh9_Y)hUxi zhD#jo?<}kE5e{g#Q+vaNYT;%SGi{AR9;mzSK)>` zsLQTVw|Bm3;Kqb=qf5Z0hvyJ}B+XR&SHyhgIED1VDG#ZDdoIBF!r5gO!dy~2r4!U^ zt4Ma1k{(mnoa9k}X}l$tB{Q4=(h19Gvwvu+ zn4$p2#XC-E+Hua8^bEEG++7`_BcjHJH_9A%FYXP6lvxSG_@K23zvTQjvS-X5Akm7y`e`Lw+8C zM}#jIV<4I4%p_CLaMfmD(W3##m>Ek%$VnlCZi_VSmU_kGHPOQzEZx$zEfkiQ0iTkP)$?oy#8AAaqSAL^|}6~9xDH) z{q=l=%20aisK>0`=PlUxp`EOi_sWSJk()VGA36*5s$aw6thF^nrXu%jXmW^C(Pi^(_A=R|FD7QFy}AJq zgVs6Hrc+iEF>Ci;Q;vpmZ{9N@G1dxe@UK&1h91AcxS}OeUX;REWFlT(p-qfNDxIJp z1Uv2}x1metsbepmY&wF&4I!Nu9hCUq>UiG+i0$Gkb=a#tmT*1@5;T0HAM+Fu6GM&) z4Yf=jrc=4L`TpQDDqt=fbqC0RvTUZt<+fW`o!L+q`r7i*9w+ag9N1rdlP2+G&u(RNe@FKGmyYrP*YB zS=cKcjvWzGIQ_d&Ou-N66KN5AIoh12xr$CXL$~s6u5D|LE8>`SPAic=!X8$B&Fz0x zF;F(94xE!kNi%YqVE|b=OkdpJWV7Fu+tGon&iR&Fo^mgH8SGyS?W*%e~` z0=UyaFlax-&}z2P80uP8oVEkK;PgDG)82i_{sU;2EI+Xqhe}arJsB>VZ@Sv(ntyJe zusIu?$fjcKOUoJqEM4XcH6n_NBNKNwDOgaKGi#5V^PUnxKH7lR!sxiT4)+^TdJcY< zL))v4%rmQm0&|Pu%!#LY)x+0vuXO?D8G6s&CEG&qM zs%S%yxN4jRfI`6ASEp8YOk{U9AEE2xV)2QuSwfh|kzL^K3@3}x-qOnRbP_{#%4#nv zI=abqr^dVCI=4-omIQ-jgZ!NK!jO|vR8-gp)wQZH<2orinqO}KHPszwnoR7K+0{9+ z;+a~a+8BuL7|)d@!o+oDMU@wd3{c4MN^_QujEy9&m?#=vH>8TqUY zstBz{y#F{VrD8EWI!eIOLb=etrXE>gIrRr*zMqLFpfwI8%1?bLiIX+1<3! z&^d==Kj|FT=uCTTQ6_xA=+Epr6Bh1nX|RAz+=n0%Yj>fZ9*Kuhv$4{m4O>lH6kMOXN#MmOnmCiPS>%)tum~F7fW`hT zJbd|Uq8Z41*z^MIQglG2MH`cmOQ_|w>)8Oj%3$=9&S1iil}BAU#`%(KFrzfdi!6() z%{1Q4=2XNb{6w5Vf6Fc32pU1>sWtC0n*|unRttH#Rm!yht^9_PGL&?_83d=mws#PS z7K|(%u8OLi$pKjzrA+N&Mj4_B9+zeBA;#eZ!JB&Ec1Xy&JZJXFQS`XG;@cvoL(VzP z%1sr!688O8R)*c5@v&KI0wZuu+H|-;SKU?p2DL8D>DQ%>3DwU2FRUB#CNU%rGGrkh z0ngKKK+%L}NCkVse>o4K`rO$QHTtRA*0OgkSn`Vw=?+~b%?8g%Z9LDB0JjrtzC4ho zr^MvSW2=*=!HJJO?WNZ7l4;vzWv+<~O0&%N+5m|M@3qxILw9vCvBCLV!xd&?9KVVF zNuDzNF|XsF2izFh16qb(_#WWrTvT|j69Sm^#w%+EN({(O^)4@h&e~H_aJ^2&iJJQm zww}ac^F#?xzym!hENpkt*s1-5quzV_IcI=-iP6s{3J0E1f{Y&VQ89-~Hg+2J5!#KZ z!gLVoHpXL;2+q4)SEJpa1D87P3cW^`_lfmi5_v=}l4Jy7&XQ7tDbduF8F6Fum>Z)} z4{07K&ArKNg6MCV=9Om$XFjXz8d}|5T8ROm(@60RA(8GVLKTGR5>{B?nrs>s^rns- z?c#oUN~Xb;i~&gHkf)tyj?ewuJY|JI(1-DmKsk9OrL3TiB8k_$k~{WuIMcu549YjP zO<$jFUKE}thlfi};9+rX05Wx07&Ck;g;+B^j$J9eHmmY`HJba2)m2O_%;{>2_DCvt zhK=XCFax8XCuObc9&@D$8XemviD=C}$3aK$Oz@Z&rT4Kqm{%g@a*pI(wYhOPW08n+V z_a`_B1Q3W+3>Jl=K%BDRiV3f9;D{Q0xP_r-RtA&N}~-?&(%nktAy=l}ug z%afg{S~F^KAWfZjdiFFeMo1l}v<;@JOKo3K30Tf6%h;1Kwzg&F*$r!*Zeo=(hffY>xxuq%Pv^DFn!B5&KH*}2+UaV zNv-R|X*zXZ>QLcgyYfdt(P!%P$X zDP!Nripa%!k-d^Mq1*n)N=lHd2hL7GnJMz$qC3dmyiZdHa*)f%WzB=Bzr*vowmEhz zhYKFgB>Y@l8IQT*hiSv*W(4GJ3Wgl|XKzqB-kyElax4GfVCE0V6YX;@C%VVt8v*m{y4cJlcPza7E_W zfiDlrXV@F!LsY%n?B>X%Wc(z8xCI>Tl|+^49q1?X_!S{AkIjf8%=V4K{`fg$^!S3j zJYKWuNwE{N=7arR9%EjpF?>*>-?qp=DvU6%K4xWNSoF#O+?KGMmIS=tL=}jsMe+@{eX{Et z0hmb)Mg~UDAVcmhj%tnect@Ds)o)iU8R>IK6^CqSXb7CPCJpD-_~3sUzpPUEX4VKk zOdGUvq^*bKSHvY$|5 zI$v_W@(CR#S#yqhcE{$?#Kt$p1mA(TzI1QtJ9O@FKyj4V3De3{fhkrXlhm`MrE||o7*_(=`ztjm8 ztgVbP1F{hADBkcf80{|^PwzwpT#SV(8wt&LLV)vTY1n;>L$>gt)#)aT1g}x=P8+Di z5sz73&X?=ln#(mP?Ur;>8Z=Xr}m|7kWt6=`@TH(zr9-ADzJ zz!!Z>)4wbDpN5j;i`V=Y<$zBbb)fG|1B7d3Ibp6d4p=x;RC){CetGg>hxNoy;rmk6 z%nH?Wivas_Oy6o_DDEKLwR%QoW|^Hw9twzMvo|+#y8TLBB}G7!MFoK3FP-`6iq zlW?%r&vUvOs6uMLT5PTvc3}Z8eu<0wJEVjB;a9;vfeg)==%(ARyL)cCHGGDyHlnz3 za2c1CQy;19GsL7_5P4zi0ARsY#$ z9{6dm60x)xEQE~tha{#On+uA%HH~3!)h{Fe#cnnAdkQL4u+>C*OuEKW2N4}2R%fNGiyWfr$_SfrM)KLUN)l08?I?f^qGCL+x|u-!k&+b|z7%6ff+o zEWfRI6lE$dr}5r)nYU0F68T*H)E4t#8Nv4@+~S*f=O6d;eFg2%i3l<6zx$=-0CJmd zjqZ*Wkb4(K!Z;EV^^Oh;|E;Fn0(^#A=Q3dxfFRh|m!2#4t)}B$MOOwo?yNj_&^-?w zPV@QD7zWx#AWa~H>9>XdRW6bwrn?5Wg7lxZ(HNIZ4vPgjn->A%LupBKi8OvfM!`+D zJWSfDhllW~eDKuSw82#`lFah3MhH@6{UYHNqP?7`MSHVN>?Z+3aXSHD=shCDIHC&Q z-o}@CDI#6%OlIc>e%RqtyErIUfwiS1s@B_ZIyAp)Sn&BmhM%01o!$1}T3S}Q$~ERR zk_7d#G!!H)#KjWy$2AB14j~ip1t&BjW~M-2*X1;gUKHiqZ*u4Ic%U>mp($$~{xD-i zrhF!)F`gCYlpWGQHvIJ26*ew$nf;idi-Zinnnn>FKzm=z_q2fK*NJ zmeE7)GmlhYFFl0w3mbQ4Ma|4jRrJ&`kRWj|V(Ek`~aw+%6+?|_k zsxQjz2OM4e{=`4HB$}qxJKW|<<^Q9xYmbI<-NU1z5=kf`cI1956B@&aj))9$CztJ> zOXQYvne6SZP?V4m#+`~9m*g(Dp(J-kh#dwM%@8x^H}*bjopaVXYwho!nKkR3dEf7w z_j`Ze`+I)R^Lz%`2&D>}j!ApT829~<^I+&bP2i7vjjb{A(8{GLT!OTh`HlvocZ-$E zt{#w^P&xJbR#ZzfD*1xMXk3Rs(cxA9cV^z)dbryMHqUawWc&q{U#CPGd<#QVHtDSGaZ5s)B6{4Ru1T=OIUsc>H}9NKR9wrAiMb1P;6-4==xU zl>BxiosB-kS8VpmDQompq1_D>s>ZqGTjKhxb&7!Mt@b{8OKFj#TO_2UHrJOm^|MP$ zOC28jpCAiZ?b#b`QtqYfJl8)d*9%gKJXYbXo8QF)FJ~0k%!daYBNUho(iidF>M>7^ z3KBhYSB+;L+O%WSUA>1=MxT!NhjinoAtxSK1}gBz9I8KMPT_C=Il+wv0>H8xKd3K3 zTtWGSv@C2~YJ$~ysPoB$3Oo{((ci^Z&4G?=wd-uWn1!hQ{A^j0VVnJ04DERBLHwbf zV44WB5PkPnFZOYbOm&g4=xtKp6fO?}d&5Oxu;&PGke}7NlYcdq_Eh`VvuD@+z6^3U zT>h$EJ?WpJ;(=N}ajMPtYggHZ-e7%LNaO}O?nZeLrRS}Dl2t6*xgu~TzZrM9)>Z;* zZvDk+s9gCa)9C1!0#4J!ge~%s&?Lsj!AP?qd*69AqHuk_|HDLF%j>p9a3dRib$$PC zQjXxR$Q19$*->@^ag4*zL`zq)_|`j-s~;vGC$4jr2WPp86Nq7tNbft4We#G}FT9MtL5S6FC;ES*&~MoH{*- zd?ol& z&W4ELG0{O}7Xoxgr6(mP=U2CXQyhcG5!oJnut1(HspB$M0i{EqH7W{dRw~uOWu-F9 z2O}?g(MrF5*VFfTb|xnF?&4^$6Ogj+<-7?k!6P>~?!*2@yD$lH&gc`LfN0**xFc{H zoR2(d0xEveQ7{{JSd|8z^v>}&VZ&A2Oh2xt6Pe18Ux0(^1u*Is32F(Q-3-H-Zj*dg znm)klrR=TV_~sH8TSOYaxs}2U@sz<%J@FUhW-RmSpd7f>u^}2s0Dm^pi9JP*#|A5i zh;z@KTwG+W-drDk#K*H1w$)Jx&rzEX{IcEzRbCwnV^Gl}AllSXvQD)fUd0R#$tN)( zBsdv^IL-fR$!l?(^x7RcFL+)^Ewr=uF(GJTfgKHr9<$sxySHU6Ytj~5eS8)OEAJ#( z5OJa+A|k6TZ?y@1ZV!HbiT*5k?T>*;+IDmzW2{QW1jBVPs-qhLlk2bV1v(vAWD6$R z0N_R`r9V-YlXWgwY%jn(OX#&Cla|4JI&WMol{v&`K`G)0pNZ$WmG!kBjxb~hAqa5X zBl{k3F$fA=(VS3GWMPNgOL}`RsfJPr9@yxi1n;qGcyRHv4it1iOc5j{B?X6TF6ikY zQ#*OAPKry%e|iUKa0D0^Pk6iqa;w4d$zy_RzJHuc9UmX3ofn5MRNJ1d_UUc?UAxzF zxHfT6HEgqgJGxJ)%tj|5M-J;15Ksj^dB;a96OKf(sOD45$~-&aM4`eFE?#{t`XhKQ zJ->66OS@J4WY`vOSMQK?1u~#H25NFaqMA?T+5CI1qr3=eMqb`YKR=iNRDLjnV5dLHsSK&@iPbs;M1Asz% z+m~q?Z7gTRMHL^|zy`Lp%&ftd2wC?kh2038e%Ucoknab(0ehhJ7(mj1pZ}=0MeL2C z{o6#FDkUkEsJS}-#X>s`!o`wuFnZshN~XY6xXw5mKFAMag4UL%XlhT!)qZ|%Inbnq z+GW!TS@D{h8p{zz8!ck`Ko;8ZN@hFxD^Dsa8G&F{yZ8?clSll3i#9cnpH%%rlrq0D z%|bLWNm8%&Aa8J?EB$;u$EqKraCf06%YHV*)_#Mm2CyBeiTATkKgfEJ^9uJN-d6pF z>l6ir!t7t<`w)$GGc){WuWvrxsB9-(8-XF-CW*<4WM*czV1aDDpT>Jkkh93z7QK@0 zg1-PcKiPt!>uasd#YX`Scz=oYX7)!WgeXD;E*+ax@AfW?ldEe%9v*HHBcJzB%Fk|1 zX=`ntsQu})Jy%~J90+sAyEd49k+@(Q#j)&_UC|9}u;*1P3T~ZU#3g^x10O1n+9W3% zA3mI%e&$7yr}I}*3NyEUf`Lxn0F@sw;?7X{`)dD3eA_H@EHrchJr$i~&f`wTID=_L{+8HuS9RaK!z%Kbz zoU&ZNcQ$^sOUNvmuEXG%-|RG^Ql?DK+3hN6^ZdE5%PC3@_*9NKFA7_jfHfBtr^Jln(_%*9EetWc z;DcB@OxKaRkO+q)9W2p4dry8IUi+=6hlfOWmu`2ruAZJA!~bkrOj;T(Dudahk zn_(fM*@V!Up(E9i$g-QCzOkoIzV`C27fZ0dA!r|F;D2cxmppfdu&8NWZc3t!u0vVJ zcGMl$I0>rbKCf_^+cd|r;LcDGDN2lg0_1gy((3<1UdO&wH$<}^rf?P}a?XaErU+zT zC1K(Fp?pWPKr6=9Kwcdm^J7^(@XJEkyFR;xk%3a|6A4t1~?J~~I)NB*maEhMC_ zIggLN44eNFyd5?6Orw4T1>9T8vU*Nz0-2oFFGb3_7U=H1V$z6_f1><=R-FnV)0S}6 z9L#}DODq($ICEB&Z7&-swC2uhpPcStIP>?;2VDI8jpU^+a zh>NIsW}RijYGLc+4u!82w~NVq9*|V4X@_in=b&d>!~guML4rMlqQqAE(MH(yak15+ zQV{+91T6S6?s7Pp&F^s{e3-@0uPMaF8%u@|v;|*>EP@W>Kq^Cy5G0jAi2>6?Aq{}+ z$Dovf5xGJDPzI5D!pLBXpbG?1Mv@{BivYyYVdDS)e0YMzy9S>-;p^VA9Jl^l*~$C* zDPEApcaRMs!9%1x+S#h#;5-}hb*U;c!1e8*Q>5<$Y+egebf8BJMegCC=i`ctR~$~Z zGPc!P8Sft-@6XS&D@Cmef%+_lPSv|1L0|7`D2lR|Cg+on4iGLu(+HP?|Tgee7lJko+*0Ty)zxxpJ#&;J_el+{@_7f zDcuT{(7H}<*GiSLjsgJrEfdrR?1ixBEYDVU_s2`i(-ZrmhDJ)U&EnscHi_L1J4=w+ zzgt{~1jkC1>*05K>8$U5*OTk;@0U=UT`1GDvz*-QM{Bj}sc}_E%R9TJEDG7JcV`2q z2?;g*{ic3?`V?Ysv&BE#-K|y2jCrjx9y^m7S?aw9UNz2NOwG;fctu2dT1U4y*E?UP zZ%3jZ1A9bzNZ8b|5nb9VV*_2E&7emnf>waki_kU-*j1hs>M`VUSV+$_UH!m5bj4aYO)J&PJHgR z$J0{!c{}Pmznh-OAn7P2CFO;n=W90(Ve3zE(<`65J@CY;{i!C?Fay5R^_Mvd<~B!g zn<@25{3i6{&>^#dpX&$UM;@u)ZB$%UteLh?CN4{-GXd6JGDEY`*u})^!~RKCFdGg& z&hGj7q4(S5hxz+lzJ7Ga!ZU0KA-@xMCF{ueQp;1b|K-KH$K$&1fo|4!HxZS1 z9c~-aGAZFj?ySZ?yB2G$F9~BkyXf(4CAh%JEbf%KLSLsxUp}i9Ul|8n{)o-=Tg^OG ztU=`CwR{{g>_9-=LH=s6Ubk)_Wu%W_EN+f7T>!FFhKMAz?nDO)!Sx^;DRc#)l9bnt|M zV7R z--rF9T)I@6fjoT1Ypya>kkE7LIy<*pN(>5DiZ(|{6TQB9AY^mrJA7Z&N_Ws{7FVeb zsI+5cH7b-j$b);@I-`5KqbtaJ_}8S<;>yHhV{Lpl^<>1)&63M&CjgXW4p{8icY>{; z>`{J=(*+sy-I(uC#^TN5ev$r}nIhjpyl=yEp^z((!SFD>`{gH%eM-H@uRCHP?=boL z3p5~(J2w*(kp^b7?91ZB5)AO=oFB~@tQ5X5cEIgG-?pYYH#_(Jo4D(?=FlhC_n`ICnx-Ssl`g zVq(H5czl8Nzw-!In=7a1m8R66;8)~&fAgumo551OqEQ|n_VL;M`?#4VHoh1otyrx?3A6{cRYPRf6Ymg z0(+R+obRJA-48d!zFXQ7cu?QP$@>U-!#PASgemb=Nd2HiXG|B?ryc)@-D~#$oFHJ| zq?_sva3T?~8cS~6H-CHGoEbMhsuvbuw^s#>zfnm50 z0695vu^4Wl-xITzxWwn8w?Lw3AL| z1s;79_6yVv!QmBzf~?(S2HyFK-Er*SbpT^=akUS!-PZ23e>E#@{#GJ^CzsZQm>>s# zwyA5iG@<>mL`>yUNt6>-SjU_3)HzU-83cdYkLaI_=MGs6c5N#vc)C38+^iQ^Ip;0rj0|;G&R028 zvj$um70xrj1hPFnWPtkhmzZCOaJcDvTtk8U6Rnb5Bi~vy0rmMt+j=Xz*SL{^shXZz zZCV+c=n>u_GMq8cH=VBA$RiQNNXX&4G*c9$L^xPjgoL>%DT5JqKY*WnXOE8Xn&6qX z{PK!k=74T43h_}v85t{;USpIbzs7K&e zc2d^pTK1mUV1L82iup!kdaKV4PycXk(m$nU5c0XyZ50sePb9(4lDrzg#>M^X2AXK_=N}P=UtQpm5=p&k zlIW(ml08NbXwn|R2mD&LUToP~&dc^`5NN&aUD(z9aJ1X|{9$LGutjQ&=gSK=9j}cU z*v~<~x3kmfbgVUOf40G?GYB!jVO7Zg^~9QuZN$#&*bjAfzjyP4Ukwg%7=3dG)IlGq zz^MS3hQ-1mDy%A|J8tYbIXENwy3{w3$@N=vYO>9s9Ysd;jE-F3P*iHZ!)xwY51f|f zIkM2$$mP-)82#-~ROM>`p1j*Vd5ZYi&l_-MMWMbY*w|`=XJ%n;2DA_u$77{Zt=y^O zWmqASXMJ>3*7}T(NW;v1Q6cYpuI`5=BM1eF&Ew7X=%Q45`Bh`%uGx!@9y%uZ317|E zC$sAR+2W?c@|#0&*>j2~wG=DiE29&N6+e)8n9OjehUt|!xgM9L#v(F4G`%LD-^ zH74fd$lq;1N@8HkiX}ZUDQk2ud=^x#)VA4q)yacKf$D-?OPPcr1m*D|?sqDp!#Kf! zkVd?=x*GZkKbzHy8Dx&)*4P8>Jzu6i*Sq#pLIS+Ct;%u0IMSZ-40`k`a;1iTt*iYQ z7jm(+0E)et*v-AIAczK-0in{h(|`K!d2hR~kAly9lKata$KE}tm#gE4$=A*_t2>vq z`x!HM%5puD2^Pv7m1*vb^Q6Fo=P#Hz+{uhtW9qNi#OW2>G9EIR!PUuQAmQKO^dIqe zcdjkVzGA$9B*)vE{p0#n08!!X;ZJC?npeTG!mg3B1N0{SC9zcncj zQa7V!?iO0}#1BJ7XKr?SKFz=&1E}HqEQYoUY3zQMM9RAWr!q5ZF1c6yrf z1*@U}1x!Ch8U@3xozSBb;IW!ST~YqFChl_fi(w~JIPur!@c6V>$Jdopfq-p-+r%=h z?J;4AHNjkLVi+dy!Tx@1bM;=ONirg!-ofuyQ-&dWwnn>UdF~KcR9ws<0axdIa1>Wd z0iS=HG$!DCHlB_IoNZ=GotAU2uMzNirr*S2nvlcC^KG4-zV3bd2zz4lPp2f~p1-M& zB*e#Xd)-UD*mk$ez-iD}T{L`Wbl!XNVkU_*05Suj_Qz!3)vXUN#Eyh4=8mXDHswVg zr15R!MmB1p!xc9Iw$dw*JK*$uy$pNb*)q7x8MIyE{R^4(o}JBTsHx9ad`veAlDo^j zyhaxMu2)XSDwaGOASE{2X5-%8UWN?JOI`=04BC6AhY<=3VK!(Yrcb;)Ss<#Y;rXbv z+Lez%X?RN&rCV=9%xdJ9{j#+yK;LgEcfe6`+TK_(mv~ZCJ%5* z2#<=Tf0D@g!|=<7VfRLMYk-@$xa8xR@XF!}I~&~yq-a)AVOM1>l)58fbtTV~R4cg5 zbMo_cGp1P7Ue>n5pEw` z$vA<6a%XJ3t2O0!&~W`T|6kC%!}WNMpH%HUW)S&^~MJC}Xt+sAM^f(wSQ@V9hpa=d(;_bG*gouO) z+WmD-`-*bB|K3@eG3jVaMy{N%)A^LMhnp zrp4+5`POeQuIo)s+S}RMUWSZMMz)oVaU?4`i(NlOVCTD0fys`y&ScmK2a{Q8m#3F4 z!p-(tD|J?ZAF4L1JgghON19t$=s$Ux_3NwMpYpo6e-@Ps zef3yd8ov5>ac{xWQlNU7liA({v|pgdS#m(@X<_AHW8RC#LOE&G>vp{ZoXYo`1qBKF zzv3arLvI8on;jD!?J~f9=n<+VMY{e0amrp!$6rDxS~GD}8J?i9CAP z>eqUmZVXKsbb0R=|NW~4th76PU?SxH+iAVdJp%CRW->7|iktIzx#*j-U;#hD=J9`L zR=ATASh`GRNU{Sp;Xh=MMg9J1>`ZX0`zJYhp+jDg`DV6GJGhYnmlZ-zq~CXcw0uPE z%DA7NIE6j&zWP%nedG5sxZx+xMtYN`5Rpd935w6{+B2`JV#3=gz0Q=udoWd}m_vyRLHsY-YV|1RP>)4qTGS1WWxC^>}*u_bUXB z@-`g#WB^^|f>q{N(hdm97N0?T!EL|N(|#@$U6<_<$nzQ|F$ z^>4;jE?S%*WP?$z%uC$@NAsKwqk7@medvp5VzaNIp7LTZQNS?Tnr2a9e=emFY(nCt)gTu#n zyMO!-Zn6|&(9yFc)YOt@wv1M1g@ElxpD({jBZTn?urvSX=(O&eUCQO<*WQ(6bK<0z^1}$FHh)?KmMNovfHs)u;1eUMx3gltPC`qf{l#$YdON6dqWtU zL>keJcuXl{+|d^k6H|dHR(`m%GQko}u;`|&q9)$kT2feEj+j{n1nP{n5{RMqZ^o+C zQbM`_vr48Gr#Xj>Hc*#*eaFCtCs;P_db&k9&d$u-*mw7)R@Y1LO+b*Qo&$qe$n6P<$c6OF(=$~<`|1D~27-%uC3yB8_|75y}R}3A7Oj1Y2dgbp$ z#yzCmNJ#Mf2$b4Dzi-Smgp#>Goj2{|c6_-A_75I%iGH{=(3~r?2D;VP)jg2#f%lG) zK0E>;wg0nsn})^#Vr+S^+7|SlMew#M~KfkW?F%>8i z!f?>qs&#)=<%D2b!|{^hjeiOy7nj{oju->T*33fRn$J1f_iZyYT*|Q?5@-85xYY4` zXMQ}2%;ze7*FyyV$a#TTL%SBxVLyi(+XB0Y#n8oju!AYN?9{^Lq(Y=*SHyn;yPBSv z!7JF{n{J7ULKEXetx)__x`4u)CFs}CBn)A5j^VcnP8 zS##Uo+iMs5W8LoG(>01~woIwk!i%52%J3RAxSsD;H!8}h2E##7MD)^yH8*d=$UNIe zd{YPR{VUns#ag4B&p$F)jn#bw>Q8-%>T7~z^!mw!ZUP-cRp3wJ*vq-wE<~aL;rrf|hSn*o-|GpG+dkYB6Tfi2biu#(&CJGL8pS zeuh0q=#^p0;C6I!XJ=!JiD$U#WC|kHiaHdwXUgQ-n*}-eu|<sK?1Iy-#Sw1BkDE1p=~5{e+{=-*VE-&D4)96RYfG|KQ;OqmI9eKcuAfs%lRiWfZpll|J6nUgd> z6Vuys)r+2a;^3wc1!;p`KLFvesHlW}=aE}pKBncB|4|U{&)r@~>}YCZUqeAK5&xK^ z7lc&)^NJNy^!M!t^o`0;F&_jk9+hlKXhix$k3>Z zto7!>`oCCxd4N1svdM^P8o;A}i^v9DH#heIG`05X$AqMj9c$IES4bkSCD@tCYPF); zlOA&N@;>i7v3sY&oBNGDT|a)MW%`{y0wWk?yVUm%ALDc}Ixo334y1p4Jr{y6_j}tQ zI~z#$04mEr!$EM2Y5=T0VlIE;a!fO2AmEpC8#L?TWyh$X-tAh^cOcr)L2F}WW7Ugl zJXaH+)9pJ^Qo*YMNS;`pv(Du|3l0|ZeRFwdtt_n4&hO~FLm@>Fm5ovbP__@Uv~S4D z%9_uibPd^T~d_ zdw$Zmy6%m3__ONisUOlmuCGb37(E=%h&T^qaFqi$8xrL=JF@3CHEVsffj_{`yf?0w z@2M977LgYLbc8?9LpZTr5Sq;D!yu)0!Z;YnL&>|hzYnT5m~RBJe*Av4MdegbIY5L$ zO$8K?2c7Dnj^`qx8desubAP3$AJx+&m9w)b-Ld{8fPLafE2jGvf6eXjjI%cRZPcfP27SF#UDe9xLB`l6b@ zfKaIWXOtE;3&VEgGRvQWNd583BxxZc9Ib(+rOf}d&Q_FMB&X>RpT?RA2LH^y-5jY0 zj!$iG7aqn}JiofGPpMiSeEsSBx>2><;=0?n&f z_*1{2Wow`hKVGaTXiJQ&6mW`RBY#w9ZK47wF&5}khvK){wzvO`j>UzOE|*p&U0Yj9(ZKV4mY6g&K7CY>kr@HTNR+xyD1$qwY~0-3!qCoos*p5~0$&n84iqKiP>J}P?ZMx8 zuN@u0z%Ki-jijXcfI(zq(0bz~Ud%&eA-s-m)LFz9T0T;W9UgB>s@O6+V4~gsr3WHj z3Hu_etEn|K(W-ab%gedc*W*?jcAqyn&maSr;yR`JdMQff@xtz^d@ejLe2_`zZ~KqO zSPWn0|7y@tGZUk#c}v2*5@2gJ{mQ5V?10C347;wuc$g&x1$v8%ZDN@v^rN!2c4S7m zz;)NYnTY7<<|cLr5CpUT2;Jlg1^C?pU)ulu@)IN)8by`AL7w{!MKjsfD7>ASz8A5X)grk-T3Kuo1= z1oZ2H{f+2^rH#b+sII-GnZ%n?? z6B9GOYr))k@AG)9S_F*y`p~If|9rB;Qhn&75Zy8pJTxif|BTo^5(^gr-RO0gU$z_G zh4f77wNFV!bt&XIJH+!tSFW$j8a6QKN8L@(%I`wg+sQs+{go~MFDOWwnyM9A8>sOl zz);xi>1becPM0SZ0fD{pN`sN$;my8n`etq}-o{4l;nA)|^$7^LQEdTFA=c>^uDCm0 zADt&f*mR!y=g;vG*4*(7WV;f28^X{S7rmQkQQdsWI~oC(TzPfUhz8_!XIk?lj?dAo(h~w9*uz#C z3=Z!2O~W5CwqG!?7)t+())YF^F>rXR<%d+5log`X%CM~yY_71gsVSwroLv>h z*kl)EyM%&rvRP5+a!-G6ty!(sL(I-;?rHdnjU%xeECzE|Ch^}~z=R#+gmS&=Lexck zPPR}kmSuEgq;8uvL!8VTAD5%2vWmXGtKyF2dfjPFM~7an{W(MqRmg6Sl9mFVXW$XK zUNX*-+F}rjqDb%B^ZM@ig6o=~y*eFNm15X$WWKLNbA>@6bcI0U&qX^u|gps_N#tr6WxycC5OAX z3l-`Fe0lsSqa!2bk>LfjM_FH;3KxhNs3@sBuir5>Zhdche<{%$Z`QG}9+_kw zpk(rt;ePvu_<83m&PJHx_8(mjqCt_tFO7}0E&gK@_s{wz(^yg21NA7z^UYE|RA$8! z{HR?%B;&8|uZ#?ITl%bbmZL3X2gMSF&YD0i1zL1sVZSdHn##04l-34EeV2Y;v@VLW zy)HErw;p%jYIt{}{7zSTYTD@hV69Qa9h!=Rn^aXXzPbC-$HgVVhRdbCp#KuTE86qs z_}t6Y5Y@@n;Ro%QyZXGQaIx9Z#9YDGCts{9P-p)OZr#3jT!-9Mk2 z>_r76|4IMuod766uZO%Y=kS3ahPdwEfL3^bNEw+_JqND8s=+=t(1Q9zuL;wj1*7KV zj12dS+55$bQyx1l_#Z#n=Q9D_=e)e=3Ke5IPl>9V6EEheT|#cd2eKAqSTJ`#bR8NvKrNxpf0!NH3>X>-NUtOUoC1Hi)ThN(Jb&L}^o-^)tRcxVw zg+L%2QNL=^#1KxHyq0#-=<1EHCJz_)KZ?hyOa5^opY2eFk$k;$G_qVr4pMmB!fZSH zfgWZPK8IsIJOb9rw99;}J{<{`%Ia#u+_d2mKi@Z|ak<)57I@&V2=fJ5)U!^+>6QMX zy@cZghTM&EnKRZp05!Nc06sG1M6$+wMQSu8#cW&JG%OK!p8wnmZ6k43ypQxacu#7!hW8=~G2sGQJPzpM2PJ-`iFVIp` zJFO@*2;0Bg8p{u>suC8)v@*NzQGP%f{gK5P(}|oYIIQmY^8>wyIUb{^v{2CIg!V}a zK}WyUA9w19fDR6Jl|4lS#<4I6u9@(1 zYq&b?o~Ws)h?A4i(Shi%x_=$@TA$AY(~BkOvL^L#r7%Pi)b*>>#?0@jIPM2%7HXZn zLL|`3)ihND9SrNe_b+wU7YA>S%A#4LAsU>fbB&ld7Ij~}rhygyu@Vf@m&61yO)0_> zw>h{*hczz*51bhkt=$5o3!5H!KuceA??a~)^agCBr3#w0rL}QHdnghz9X%r8wu8FQ z;KI#@SDn#;CEejyp5{}S+5p+@QVWb$k}ayejwRn?!-v5%roa{aMpCo^vXA%9 zxLJfxJ+)iyBP(Z0_4;IT&u4s&1~g!Cw5G$kkfW%g=BlhK6OJb&DJvr+m|4}AvKUYl z9qpe-Z{Sg*m6y}Y7#c1BE*bplQP}I)AqtU?sCMn?LSt1?hTQX3H;b?wz_yBM>$KP3 z97XMu4U{sapP(Hc7(w0B3%rj=LMk3*^|6tyg%ceSL*JH985x@#nmJ^`fkiQ5fsGUb z{aL30@r#~Ojd7RFecc21vDDN?*JU6f0L4y&)&eP36&n#_>7bv7#qslWRU86UL1v6) zj2=!JZ!S6c{Xifg0uNt&!U%S{ro#rel@gMOrTf<&WqXW=vE6Hzc^2?^h!xyG|Kjqr z*i6qG^1ehf9UtOymIcekFYBD#_ph-0gfpRm=$VaX$0Q67D`U7-*6RWm*v5Cy`}*r0 z4PVHU3qR5cU)iujk$6ib)@U7_D?Q&wQSgSRQCt3bA>k3?QtZhB4YvP zC_VlD&Qdd`XRT)T&KM;HaBjW0iW*zd&P*pD67UA<4yDvN*I{5NKN1UEkX;;01zzau zRIfL{>mw&KB+Er8A|u5gtpRzx-||HuD#C;NA_B^{@7}-&Aq8f11xaL|?Yh{bGY&3p z(|%m1TWYuD0W{w`#r#q+d3l^S@6GnMxD@KjoOb&hy_V1GKp)hcyN7F=%o=eRi#u;7h>j*~6%*ioW zZ6&zPggE>{!Ugm^?7#A?hT*ud5eXJeMb@W+9M;1b`lf$08&=1~<>oTAC`qCohvrN| zB)Hw4APa)g!T=bNey+?%)}1RD?}>nM^Z`}N*(DLBC@hQWtw@Vsc@_D<$@@DKhN~Q7 zW8(_-sw?P$m3UFufh7t0=h>k9>EdH z$?CxU;QBHWXiHnO+CA1B#YPxImqen-rTuHB2k|$4GvYWxDAPW;2d!o^mUe{MhpDu{ z(ka7E$NjGty5B}Jc03WqP0u3yU(j-e9Pf}{vBdj%`$`@88tuYb-t$c?W?o9FioZzM z&r<$$k2N?K|zJ zq&rKrT*}f5*r7t$xeToQf6S|*EAff8n||VdX(3j{wPYI)2(lg@TX|g0XS}2-kOh;P znVGG3++Km@s((NBtgK{kRj6CfvOeMof$TSg-8S6Dul%`Fig$N*ru4hEanbP}=u`|f zS8HX#U*%7ns4j(leUDGF)6%p!^Yq6CK@P$-oIJZ-H|o<%?A03`5+iwNBpe*uEJRLE+zwY8n@ z)*OmLeekNd_k7*iTV@b@@o2^f*iqC_nEcRBFxkI>_VHln;ui3^ZaYj&wH?8&?sz2T zGt*uvf~;V52HrDXPn8>!d)Qc}#FUh{1|?buv<&3=>ocS@rzTQl{vq{e8@T$?T(p-| zh80#9e6CidW&hC2r3u^&t?I`XK)~GFS`>UNi9M+a`?+yVvFQoE*a+w_tX5cS;VGvd z{ZJqnDN!zU__4)M-F)_sk~L^_WjT+vy`drfx{c{&$(77xOnjif$inm=pGj;LvR?5DByQiA*cn|>9AN<22p-^y#F|o0m9j8jsCHLQuh@n@0 zDAJITS*WE$Fy_p*E9Q7O?xas;c!?d(yG;_#8xk0N-Z!FMVuYA5$~V}-$w@Xanm9Q7 zOD$PFAVdNfI%W~hgkbB>hM7XnI~_5WHG|czC|oTYEsu*lTdLw}-rjJxURytoG~M0Z zfuAjw*c8%5hf+jpWp=~XoNimryb1GZwG3F7Z{k8ARJM%Dw>VvuQBeKJ8J=Aza!?WD zdxp0$#ChOfnA|$=$f&sp$5sZxr+SieMR|GMI_rw26mJOCTg5o;>eirXw>0q8+)dsY zftnV(LVUb=FhyAfo4d@gBCbBM{jh!x7bqz)6h}A{Plm7qQbq<~V?@^c{Kj8{yZ3Kw zXtN{9aym^EPK2GsE^0j0!PhzV_qfX9#>(Viok%u8=~R14eKR-v^ana-7%>k_@A79F zylYkw>Or`eC&Dwh=QhXb7P2%0AFy*_5ssNHzC?aroLnQsr`e81T+2%$D%8W4l=|^d zy7C1=Oht(Ru=n;o&iEHQWb~hu5OjuUC>!jV38G39L=xr~)O5Kj0=94D(>RWlkdWek zi*i|AEy#U3*X8lsJ#Th9+&=z@VVwts{`j@HxI)grPuS^3M`!r6o|}ole%1X}9X(c&%8NVZNWu<4*A58~ebfRkAv16Zb0SW|B zZ^&&ij!#rF%G#~98A@uDsCfCf&Ynhv+cNs17eOMDj-DRED%>pUKaP)&hq<}Lm&0k} zuXUdWeQ*;CyOi04ryP~zqL}!dqqd#va+a-DIuS81!EDxeG`pt)HzMO&^GgfYOMPDa zq!e84u{oP!ei(dqx`4zLMPVVtDm*=35-XnZ7gz$@C+j_XI_t1{(Yq8XR8Hy7~#p@m=iC4ZG79F3ZWs>|mw4m`%n!=tI9aXj0|4+)BEvW0N_ zd?^Sb#1e2Bzsmv*Ix`Z|#LLCe2O`uU;i9r*SRwW4C63}BI*hWf^nOd{$IEM@-ZTbj z#7=1M>i>oPe#In8G_?38yVaG|Rb4GD*OPgxi3~1?zBw%Hau5?8jikEs^z>x8zx_8Y z427`Z6XtCAAob52)s0#sh{&NgIWPule<0B4UkH!QIZ{2s@> zR5s}(#p>Z*7Ayv42s=F67P0O=yMwVgf<6j40$%HFZqClmxGV;GZLU_Ho=+WKw`qn^ zsi~=ffg-?h$Or|;K)9DxJ$`-a#d1>=SiyLAr&_PmZR|cRz3ht^dH|KM1c04`qf|bV z+hj224~0}6FEl)ArE=k5g=Y1VcD_=J@j#S*yZgxKXp_UH|HIjG%u-Z3pPMygb9QDQ zr=8EMtjtPIZgk!sg^X;_MdAzl`&Q{Rl2cINGU>Q}yuXEnz$|fL(I{}Tu?2oLWGBBNht8W|IVJPWxPV9f15sI5gDb zl4GY4w2FxOph_L*N^6nnAm_NqZNKbyI@#xO37uW8e!N;ypJ+mr)Zucued4z2RFaUx zXJwi!yZ^^>rpseBMV`1tSVmeJ8xdCZ1Ajn64qfF&^&5|{u&{%}C9$Blw0R1HCQvSw z*_J?#Ot9HuQz+nF;2WP7GkR(q5&y&S96T?LLRO2{?Ez%DC}A2q-JdMfTTB_WIOan> zQYU03$HuOA`T5AoB2pfMZx8QJLBhUItg_@-U!(yQ6%~z*_gC9}=_LF6W2v3q_c|S( zY%%Qt?_l_eLCNSYz6O))j$=6uTZH(Cr1603S(}q?q!i{XC(FyhRt}nXhizGpsnRtS zNHT)hBuHz`!5=FPwt(i9PWZT70Y9gy2QG+wP)}>e?R4_tjI-4EI4t%!lnG)Hbh5Ph zH9gcw=w1UZoixZ{bwA?p(3Fc-S#>9-{Y!-=n49z6@A#@KmiUobA&1p>s;iI|Ja~Fu zqpS)U2yit0C{gZvfjERemwdZ1GczR-_GxrFFDQiP*40iiub@IW2GarV-rsyABqYSG z5$W?vO1RBNvE}9EwRnnUlb^4)q4&N_Z9|rq5#0@jkN49R+3Zj}NjUW1^71IoI|RiW zP_?1S;@lh-TUkRx!(x@LVjAmbx%h9q?3UA{mC>B8FhMwYcxfJUkdz9jEuvA(*<*rk zFEblUNv4mqg$YUj_U#*K($7C5=56+{|2?gw z#g>Jvt=U^u$}er77^vy#%k!Z4`1mR*KA~HU4i7)w9VY^T%$h%RbqND$D0_Q*6DF-H zDjCHo$;plTBQWMl6@}eSu+^Y}S>4^jx|l2dh_UJE+TPxLnYl<>rZbpoKs{aud``IX z{*gt;n9L%)6}Ji^AHhH*gx=oO4ii#Im)OohjkQN=5_5<>;m5SHfJ;YdA#x16DdJ^bpJF2Ry(W22!f6>GBVPaYprwh^9>N7tqFtV zk+5$t9TjS2y?izh+?DtqiSqofm5|5&8@;JNLQAaW7kVRc<->lXzOWv9<1P|UJ}w(I zND)HHzuIQDtJ{1D4;T3}Gqt({(yCdjb!*Jn*ld=7yP$`bmExM?HygC0ozF?hm4*~^ z6cuE897e}OAy$9-zvaHVL7uNIk@X3|dHxWu2U*#F30_=Io!&^9CgL9?vN^0~_P|g0 zBG@d#r&OP$F~`#vDm15Zg>x}hiH`il%tiJw^hK8tK9@iMsn7(dU2hJ_O=3a?^Q@uh ztdKuu;buevuwtqq5hX&mRXNb#U#Z)SN(GOM_X+&tgQy7y7dPAvhcaNZ2r{b#dESsK zksG{Py#j@U@H8PW*Tj@{j8BqnqFyfpw-!IsUWM->ydb`&)Tr14>^}zU{98(Q_}?WJ zHED!|jE?d)THR|5FPX2ue3{UBL_~bw((7{?{~HLap6nn8$u3Y(P>^+Ssp@I!>Ddnm z{U|RhOM%R0*d=rJ}Go%VFsskh?s{;+*d_HC){f01pL5>$HLUiD`JGXltWfH+= zn3aW$D2lU*ZrlA&>!|xTu6$F2LzNqosz(KlFYN z^2D^PLFu6-zsQ_-{23W!5l721)&-`0%{w(CgdLv*4Zz@;e8)3=Fj>T_U%%#PjLgg<}RuMZ{3d7Lo@;C;wq$smpvPg}mgh-?~WN{pg!A-YEh_SzuMj zH9SAxAvAv#dqpRoyHTu7h8$$@r&$zN7a#PK zSF@|Ogz@J3R7dO&82pW-BGT@h5E$6-2RjpJsPPYYYFd0X(F=S2;_&%3&h{W4F(OHT zmE!~XF}9L&2b3s7t>ToB{zh|$3>k&(POCfvT=WB1J|g_$gYnZP)@{4?anJo?#-TMg z*at+6o#Cu2xXvhNK_q@Zyw^_J$2|bqv6~J7Qn%!JTB{mH&J4-3ZO+H(;}u&m+06il zjuCLRIlfqH;C&K(vIgrSMAI=cfVZ%1{o{LYHaY8DaueNNzJfO@?3LTKBZ{e!%5WEB zYG%fARIt*}!Aim4vl_c+$CJ4H8t&4F!fA@uR{WDc>$kQAVJI|(guQ02d~I{*Z0e)h zsg``po^3%?!A~D434QhDW+QxE2g+Rkq+7!;ToUQ(oeS102pdwS7j4;D8OlqIK+0bS z?rK$b4AUCPD3K!qkCblb`$h9po2r(VwBP2`v^C`)nlx9yrJ--Qg;#zorVKphmfA-n z_ZxWppWvI4f|NuKCc3e3<&orWXBL+uvL1y26?&qs^<)>E*MO@r8`YoI; zNB0Uo3_8oTl?|3+Q_J{-+wkc`pz>c>yXdzn$0nn2?oks(NTEL1Yol>#XzOTTF4i(! zRm5zrJ&HE<)>-{-i(<9#DAyUz#VaiXCUNL4!uaGrkkjtk{XHV7SJkONcK912{=>7R zwnT5Wyq91RQGao83!8PIH}_s=qIw_g$m8W6z}Xp#Xy5B2bj&KVXO`|q!C9_NKYpHf z@=Q+85$%Pabv+gM#K1DU1E@b;MRG?~A6nM}DbyU=%Wkg7o(Z-dIAbDb{fSNXY4xQD zc_pK_8JzLNVrm6vt2@D?mY3?e$^;Rgcjwk!$f}@O49v(U&CKgGAtn?>74K;awms0> z9n6HZJwT}$C{fiki+ zwswO5nSkCppiO4kIVw_SGN(HMv1P+sf&m|IqkU65iL)6REX9;+(y|kKC)zcqGv|jS zu+Gk0qxg9pwLoXG{aaX}^}$4zsWp@c8R-gx#a~JcFS2H?%Mym> z6q&^Gwgyj9=X@Urtq!K9wzArC=Uo$L1pMg-x^`-M*4Y>|p-`>xx_tD*V}mrs?a2K3 zq%aSKdThi$4X&dF6|tDKZJ=j*1P^kcJ_lJijqC5RY!!r$4W@{o-XVNh<2c?y z5>wQlKZ`0B7e&WTZrm}(ylC($#dPGroh*~0i-%&L6i^8D{ngZQ>_N-U-MOU(#SNn_ zi{mh?q&go{{*`y#=vIN+KV~H8hX5jN4N;@5L>Sum-$B$M$3?=$|KiZ7et zgU#h;2Bme^6xCP9y2RLORZVR*R&Mo0NijA#BzVd(bl(LjDng^ZM7-}TuA-|bk>0X` z2@{iC%p_?J1O^+`9OX=VA%nBp2%tV`IgNLlw|Qk8L3B|QXJW&I$g37cj_h9Xlw|I! z0~1LfNm?~@bnQ~zT7f-wmVYier}rE&#S`wuPM zPLB~i#2c5MegD_ZFTRe>zTr63g!~N1>;q-7%l-G2Q~3*R{Q7B(S9B}pzrJ0j=4K>q z2MjDUE}jOe>Qr8T_W*v1sD`&y=G6hy>e#OaoRyMTG#tQ=$ehty*oh_1n7pgBq=+SK zDv@^&V^A13?iv(}pzmg7*s|Fp>D~{)^dK;__nLn#r9?mqG|GNfyF{fpIXb;Nx|E}n zjh=5x)4rsRmhIO9?%pZ+xUUs>Hf*()<-UE^q1OY{cl~@&F26hH>iVnxsShx7&5uhZ zBA(L{*Xgn0m z{h{y}HqgmSGDg|YOvF?>JdB(M9*wxuFS`;&Da3;n)A0Ac4}X>2`o&Yp%|i?8b>O&CS`h-)y4(X|DM2zy_k_hlF(D z5@N9CovcKDOT6I1X}xk0;dDpWmMj-d58D?{{j}4#ypu`BE;1h`TfA5MznFW=pgg}Q z+w&hJxLa@!4nYIK-9m78cMBFgKyddE+}+)SySo!4xVz6uy8Cu_b%n>t1(SA(aFKSjn2Aqk7$s+l`9Qq~mrjo57i?Zl2Id!0)bW)?mLfm5(L zBKX5*BVQ^Pp)zWo4_Ku-SKJ?tDR0V)p{Oix-pM~IV1`JUe)DhJL2NyJX3Bpxj~y2w z)7&Z(C~9Izy~806lNaOLf=E<$E*fjOT=SgH!f>@6z^;V%_Bct1e4;wd_E$EF;&^;O zs;D<{3+;E>UX3cb-l<4Ylo?^00cD11JE-Ha36ldFvuytp_g|WKj3f=P9Hat#MZuqo zX@$sv5Wxs;Iq$huYmz#Dk@^S5PeY6@?2^z9U zTG(=HsJ}msLk?(N34~wVX2{h(sl46;*MIQ&T37D=ib=(~J&ET@LP*Xi zAt40unE9LbgzPs)4*K&`*)=zE+#CG+b-Xw%damS(yZgi)EUS=T+?%Kw{vH&0CS!bQ zc6+Y+^#nGHl%^PH=)Hd3tR&elzvo%gZ71S!F!cR982#8^-5C8$m_Mn42(XHDxR8Or@L(DX9f{FW3ECL2+Z?Gmv@2m6URZ=TVU>-Um!&)Xd94|gF?q-NpC4ofw! zd6VZe`i{C8Uc_cT-i+9kWKpaQ_Ow`Ahu-MJWhbmn%3(|wTMd^X-{c$eN<(>~qLr(t z5Q8wNxq1>(?7m9HESJ|5F}p4I#RpQZ)~Iu6X49`z{Sn&}{VO}IQn-ajclGk>4inz_ zZtOIEVkX8W+0k;u%_75G!75Ya*o|bdCNXoBrkit7`$VMbQ-?>I8 zZ8pTG;tip8*MDhM%RYrLS3mb2CSLG<-SyH8O}ct#>xX9ytjcf6V;Q2Jj$oLx#{^N^ ziCmM0FRhv|FJ4vJmH&LRi*|nkKS!QHazTaoT6pf&*+F#tfSAah>^-u&z5QjtTC&Ro z?3WQ-wbIiV&aW)q-EUq2)DKfs;>hseV>KU{HbIKodO)~4uoA&sX{-Kg5A1v3)BkOVOi{?x1gUn7vdDG^_wzy}+^ z`jWKu4of88$%h;X*8?}IJ>0rlEXWS1lHxX2C?z{jE8uLBLfys#ExA7FDUQpgh zG9WH=d*Fj9(o11tDvc$TAQiK*5sSwE=UaF0nipmz13|Em0?yMi$dnaI5Y+$*;;!cM zqZoV+I;P0tM0+nPlwgoNX1_4@8=5F7IhN|G!uE6$SY%k=xN^!#VyXWwbSen_DR40; z_(l5T;9X(`up6J>#ZnEcb&mc>WJ%(-p63(ca#L(A-QSDP;w+;=kp09H;8rKGxK zrQ%ZFa*1CnQr@BlUcl=n|B_sw8<&ZqcBc=XoS8?*O-~!`aE?|}A^{&(U^h^< zRizY+l!g&7^Qpqo7Bx#5QPi3U zkO3sH8?39Z^i9MTha-i`1^-wv{%4f0ED_2=`JuD`>pdVf+TDp+ z>_>WQgx)e=Iy!NbrM>(zR12&d`QGlQt4B!#@Be_DX0=*o3!QIrngbvr^N&BSmbxU; z>c1dyKV05f&KkO1Zb6%jX}1Ji_MfrZu6e>L&UUt`bS3a|ST9kjUxctPrC8M4+l=d9 z-4jAU`*$Y$aAdq5`dlmTwOB$aKf%15MK^c+vyWc2cB0$-LQzo>p}dcuq{0v!RI&E2 z2wBc%@QEoYd&q2Hk?F6^#(XwGH>s2C5bgS4l-H#pgn|3A{&T@phUkq`va_^`(|Z4& ziS1>&c!v15Zv8fG!e$>w#*8dF9YE{&~v|{{w(uJ=h3W zz@x_Ceh-+iAOUa&*^hS6VsR z=CddS3`VnVvpiKw`FO=Cz}$3Y_9p!}KiSy*u2x1_;BeYs7;jl8U~SfAJf~^pWu$~y z)Tt5^qi8as`HJavqTuS2aTf&VS9g?@pELebfx>ao(Njbv2)aalnHop4W*?JB{g8=x zyGlb1IME;jWQ4XOYBiAXSqV)^Pu|)+R>EN%>;nr^8ua?4fGDviwTJCu|H92{> zSczrga?IQ0xc#@X7}Csq4vnKy&zEgyP8J^Ha^h}eY=UJk%q8<=3+bW>912xyL-5ezQAZb9kH0y)=D#0w@F>0<>crlY!qEEcryL-A|%c};(70=(GnT4R=k zZqNBOF<(F$-_E|mR5ThdkxnHN2itgcWu1VKV9D*mE35N=(*itUWE;E=_^{)dOb_mE z8~d_B|J&_oxg~6gJB3LpCMhZSQnTHq!RNizLf;^6j_b{{p#*&rlZC03mPhPtE2-KS z16z@#8DZ39Q+b~9V$pYWBH;&9JK0%#cTuaZT_TvOIz-pgw9)M|=~=4ME(CzWe869)HOxZYhH2P^q}Z0_kz^6sKIEMz3SMB_m_*fq(Za}1cVpO zMBA=}(#0@y&^lsFS;oR!cfA{4jX3(jy0%ewtJf(maEC*rT46KysWiIUYnx|zKmxE{ z2$8x#_!Sa;cvVSmUON9Kg{Q_JP4^}+GJTWwqlARjY{M}^0 zw6v9Jx%He+I${rJ{J9-wysOh2v>TkCe|Bl+XO#B0xCtA%={1)ST^-IMC#nRs_dTZ; z(3lou$c;nFue4fRjwq7Uoufpb)I%o1=x`5#0Iu;@VtSYn=T3i1;^^WtGagLE8N~D@zei8;Wyg0;U}49Ghl0jxb6A5^ zT)sPeYr&};a2N3HVUBUELXfv|4+NmHM!t(y<4-%)RkGO5WRaTi2Y4BTuC(1mp&`xZ zH@UAd_hU5A>8$E%zY&JH{?1`;)cS#aFr?3VED_lHHy3}-uv=yH5BqF5s3uAyiIWR^ zim|OXzx@a&MsXSaeYNQ!is7B-B(;_X@O+k_bw{V9u-J8DrbzXFz$0laP~UVLG*Dd` zs6?j_)5PR$@o z3-vhpbGr!MBRR2i{37u>^|d>Tj}G9BQ{XfZ zmBVM<*T_pLZWk8|506o2<&5g)B_&nB z8H-Mo4u$xdoqWquA06{o9SVw9WeI}BN+^+;G!XsbAL=bgqt~~+xUHp%^LPe`jKYN= zant1-Yeh;&CP!v%|8Vj7aaxokvnY#u|5i)$mF;nrEQcguGC}z9ee>TIi6AF~FA21Cm6)euq#`4$ z3c@#tP8{=u=iJdnmyvN2J52AaHY~NdKHr{}LmySZfK$IJ#~$bpIW7Rd!x{T+(N^m> z#eeWiU2c#~nY2=y?XLQwDvXQkiB@CVZ3_xXEn;%`(FqygLj>cJd|l)|ad>wTxL64o zpoeL3T#`#}nL;PVKGew*Ki}Q%G&S9$Ji&-V2B2@Szhg`&T|NK#1gH6xUAwxvIukSZ zoI6c#xxhzG0IJ=hS;=xn%V_QHuAP|80Dji@6{oWZKM2DE3TCw!bN$5obmC7WLL0u* zSh{8JN=6A*dOcA7K7a`RwpVwjKDz4-q*eoiBWF`tfhbl`w_6ew`Wie(nNqs}eoh*f zAN19!>F7x9Z|Av|>tS~>t3Ft{i+R9hJp?EVs2K&xRHa47=k7{=9=LkzPIbud5u%Bf zET9$e(9v2|gIY@vEi@}3D5ritNarEE2Ca!T@30O>Cgj%4Dreo7;vVE1mK1%$nsv$%B~qx5Mi^4I4FE@CtVsR%8wVKMbwF83KjzEgN3 zUsQew3S{+Vj}l#WuT3o`g?Y-f8sRKGT*|SE+I26~6=$P==m1XdslnerF~p(rGtOT= z;f@@!n3BEv_E}9irlm=bzQV+$?|LMY}<@PBa~1y+{9aWz|}?&EaFruQ0zBwu6Uoq ze)@9NWX;OLGVu`67Dm>F02zrVhz$jcRv|*nKwgy$f2qDcGnU3@bKI%yeofqNx93)< z@HR+&-R<1V8M5wUIuW7m^5?FnuR2?u2d`GR>vbAU@F`xGVUV}IT356868wd4&<4YE z+~i{8NB5?dklX2%4RW0Uh}E2muXeush$`C0fsu@yQLLQVSt9kfhffrFdPWS6A+V zo`H#%3OshqS?^L8>-E~w&$3~%Akkt1pWT-wZ{E+$N<>;+19*98^Y78B7{GjYH! zN~Ffaz+t_zLyY?6*LnE-JZBjqglxs=tktsrv+m>k$L>;lk9juya$MG|wRp?=%fvbPwL8CZ?T#oI(2W>dpq#rcLu!) z9f;N!6|P^p)bbFXXe)Qx=Un<@Yq8n)liXQasO}I`Ma-#(VLE!lxe8OV-wsMLzlVhF zWj@Ji@J?`9*=!{we*3}al>4!u4#=kJ*;k)>2f8#7Xm~vA%1aM$vi;OmR2V^O6B>qF zZIg3E?c1=w163lLi_@mM%j3FkN$A?~oEHJ#^+fcNL4Zm~Zk(FFD&$an#7b0ZwWVp(@%Bu_-G{?lD3;`vBIJ)X9{YKKoy#7dmc0mzDUg!s06pt z2q0C?{MO30SZ$@-g~B>%ysaHKtM4Wj%1+?@Rk~iuX8T(t!1QNCT}3&xxb5ct-Jzz5 zD3lnnWvT5_#kX+%Gh)1>1QLq=-=a+DJR8afbzLt)c$F=bL+`76sNA`e$!5QPCltym zU%RcSw)*G6c3t(cFP!ArG0V^phiNS+-RP~yj*#y^jX}ZTrR#BqvVb!29O1K1><19w zA;gM?!rh+ZPcWMj!rCL9%O!xP2o4z3Zb(7Aq*ifh(LQeD3siUT$LUBtfFw@+i8=xJ z{nH`;PlAYlQ;MOWqKl1=9{3|l`H%?w)uduDF}D;aS>E`Pz%rvk`S|jXLn}ze2DXhCDHpwMgSjhszR1Ls93FDsFEI!{%KQh>@$AsHK6s#TqB6Kiqeuwa zmDDrk8_6^Bd}QoT_&dz_jMBoa&e+IUinoBhm!FJh#tbF+SPB&=MhA}>7oV$4X>KT4 z5vedG5ec-%zG*o+N(NpUuJ~wVpc|f%-&&f%1LaE>C5MFNEi<=fkzAEh3?@!`*e%*$ ztdp!X)`}Lmpp=rkni#a0n(2f<{^o}8@z7{eBG;3qqzq3aU?NjbrdqALKCo|KpqmbBrpEmE z@Um8U-?T{GZgcP|vX4n_=l#S(p0_TRLCf$9169y(hFBz7B`9P6vR)=K*`zXxZND{2Pbrv+)I>Daiq$MbL| z)z1gV+2Wsc+zwud$Y6Qhu6~!+CA_Y$@jBWsO`ho*6VMF=GP0`TxsntzYe?i{x`fH$MO@`@0}L#+9~{q_@xK7??%web}^8SrzXSerrnN7Ee}G>$u)^ z(g^eR3ub)aC5O}@JxtyG&M8K(8AX9)e@nx`K{RC&ZUOT;kmQ*`eI|wrW5Avq_E~N+ z=386c_63zgwW`gsX*b8{g7o`^l!9Hg_OB##LkghcD_^}8il3fo^H@y|rzBn1?&xqn zFEQTrEY>JYiOGtpO%@XBYIIXuLwb!v9uY^rKb`05Y4jVY$|PTUn4Ui}9MsCBb574L z5(G=Do)GYO{qotVPD|C~Ql>%4OyY2%6rmzz-c$TS@!?@XO@Sk}w77JkN-~ud$CiNC z74GbOhpE+Hs3X9*T5TuvXx;mIviURg!+r$TI@PDNRz&^0NYeDr?Eh3!C}Ty7sw^#3 zlJG~91fg%Lw$Z|63YI7R_#u@v#%%SS|9e%y@YhvBw1iKRGNNDMexq2PNKEFrLNdr) z9k>v6VtkuZ$xLCuLHt~#@k&twKac#iGx2ggYv)OnbDLgeUo~_@y2nmF zQ5LYAS>)gyaZpnX&UStUPvC8si@^7!XpW2Q@&A4c1mCjO&GK#>P;$QU4|L<%{c17@O0vnMex z%_-Uw4UYlPkPFtDJXWq(0<@f4mE{JK>xsis+45~-8SAhPvJ3wz+E(sXWyXQeTFlAt zS5ehAQ#Q`m0MpYZ{5GL@vB2QUWaU0$vGInQrT&)2^9_>ecl{xp2Bf{;s+))U2u1}d&=jUFuo6GzvOWkCeH^@3@el~G# zYWV;an8RuT5;_In@jHj*fbJXN+n%*m6I_mh9Z*5&wq2*)wQuJm+iKUFtDXkRfz--& zsEJ;oTt>yodT_>i)Mw+N?(W`ZcfKB3F#bcbYw>Wu;r*fuVdtu?y**rDL~5(^f!CKW zqk)!8I*oe=H^;N_Jm%{UZ4pc6I?lHM&5nl7Kux z)!7B{(kV7pQEzvpZO7|jFdFEwwySN#`H;{SDmd!G0K{ToVQZ>gD5Rd^GVlSRC?`VN ziT>#gdcc!!{L}cRDJjrvkV6UiMGF5)Sy3^%#QHyX zDZYqgzGjQ(?(v3f|0&g}+|yHcwl0JmaT`L(YHVa=C%WNivs{Ie6x)kLV{FpNsC~6| zNM(almdby6I!m)$094)0GNV*LfSF??00Kr}+HLG}!>i|1mis-w&_9)Keb7=Q9pYw| z`DW7?k%JzZ6}U8b2R7ml&H`KJ7l=Jtf8gQ`d#%) z?f*zq+*OpG zd5;3Ph=F9PIr|@=6*L$`99v>Q#P1qClO1k}-QwkeCDTb()>$Eo#>pf>pZ5N0wRSVj zWlX3C5RUfTo{%rzcO;&2FfI!|HL+xce#T;C39PE~dvMuFXqvWTW0@9*aE7vi65Dd| zxVrMv>fSya;#4VIr}sj}$HxsLScFkkYu8Dghlq)RlH(e^Iqhh*D>cNX;PyNc@Gz=l*9#Z*Ty`FF+aH<#O-Z?8kKc2ZVaKb$~u z1afaeYiraW{|@8&00eM=C}I1~?#rpyjYPmqNkfAhNlZXJAjykhYA~ zcZvFw!NaUfW#cQ)rV6rti1?4_D4uxe=ye7ob)cb8-Q{0N&hf%~O5MV1AVEA@NW@iw zVp_6sztnc{&c^*47J7H~`tP3M=^z={9@T#s`Lu*3sA=IBJQ$-ovWinT^91{K+FkL9 z(#B3HDpGLI{K;?yB_w71=dv@)dbd5$*Tz69E%pxE++5dp*2!}2E7Ey;Pw~V*P{!9p zJe7LaIY4RLX(sy?i5A?Scw}L2{>}jBW7Qi=RR|znGjyz43CL6b7#SSC|6OKZjYV*n zB&5&4H1OMJGoMi^Avgltbqc)RDeXq7-U1{o@pK0IzH*cbFE0;Tdr>BGRT|rMUP;0syW%*2jG${U$@wLfNRIG`)uPX+xAg*tloW zS_=k3guCHxts0uz86Gq2A1Y8ADky?sZsKODc zyAG{?22)~uW%xYL3xtXk9(c|v@di9R75n=`%BKJ7*wLF>bJSL-kH`ET-`*WatW z_G`yz?ad&^tS3rG-w`go?=uhR>P*!$=kz>=CuhO-U096*2gJkDM06|T7@Ea zu0rMOR~{bB!VF`fKqlbxCnA6}%roGdA)1me1*7857+9-(VxM{Xe z5Nhrom#1D}XiIf%U0lhOhSh8b|BCmnl7$AIfd%ZmgY-d2DNjj+7i1k177k?AW`#~t zd$2CSs>#}FuXbM>!cvYrA?JK-_k@a8V#9&mLZzpEa^0~XjeNdjA_}oEZlRBLn2c)q z60!*b(I_nKHUq2Ir2v8h>#gI+(v|gWU8G`a-7XxT_nugpK?5&pWcMcCrzqnEjb4>c zr5}*L?u~jJ|I_()JaZ{S)a7#BF5n+9e4!Maj&~8os4h<{v)V+L3xFRe(}j>O(X?BB zUZIY?lwkk19l>g}+VAfC3QIX86*07V1@wpbHO*jY8S#&R{y}!$U&Mhfr@Y)-YoVej zM?JiCvg*P%dJDeDT(>@Urflh{^iWwCR*3{f-7#knmc0r0)tlej7d=1G;Gw=p;7*`0 z+ZHU1PfXcUCVST9>z#rzZ}YkO;sa^RZM@u-$NNCLmR|aRLcj+Q3CjxI@$=6KybqD8 zWeY8$fnLV6vnRZE%evP$X!`EmjC>< zR(BycCFT@yywop&bia8z?LX!p5mUT#y@QV}`uh%pI}mYKzEOe8N?TH1ZK)?XoN)(Y z?&cTofnF225pq|vy`P4)Cc7BlMw?~gnCP1~ZJJ+1rhgba+~4dEmnyGzAh)u@mh;$o zmlPNKAu%NJhigLxA1>4q;%9#Sl>zds`0LY|3_%k>VraQ`LzuEU?0?l<&zKlyfSHTr4e+FCZVTL&%2y_#i1<K328oZ-Y6%m zRu0tY$nmYeV)TkLi0%ugFLqZ7H+0&)E>BrmY8Ho43K~L5g*-eUB;Y*JoMWm0Y;Tzik$4?oozNC5ChC_>Ip`_WaJ|*%tTy<6vU718;rgFWl39`a{c( z?xhAdz80R}vOZ$XPiR%uxEm*=$;3PO+Qr4Q)`6SBYz7h13ARS~CSWWAYWgqvNPNM^ z1(Cj9Mx8b^{(+CTw?UfB-KM~Kmi6r&J4ea3)=^qARTw$c+(g%Si}_O~r29KC@<5dy z$g%$-FW)-+A2o{-=)ho_Aka^M2>eGx?uYoRA^ZAzNNK$OBVxYxC6S9V%@LplitbQu zZY(gFMhk0b1o%Fd$5J@4=bjco0WY4=$1je)O+U!~{xBfx*X2psnX&!RMrGy9Y9jLB zjeMdZ%-xrj;=T!GepL!4dHzfSAtmHf6%!SWoYcL=CT0OFSmcK2S2aq|5U!#=EiEks ze@unQ_j9OYVvn%Tc!%VBS3xw4k`REaQTgvS(}h3u{|~z-;x9jZeN&o>V&b0h#4G=3 z_unqZm;N2n@!y&WDpYjRE{UFmiI0kpo&EzeG2wfHWcm+^Abw(>l$Is|QSAb&GX0F~ zk`7Fmp40lJ;gVt1Unft7LM4vjZ1GBG7=v^`bbs8-G0Ewppc0|#d+-lbGsoxNO&S`M zIQSw-C&^3$XG5%042wyZq(L)?@JCALiF<2$~Pm6GNAkMB>3Kp;6sV;&F_D)dYT0By58zpAiScUt_*r@zYciDB1p z%_a3`Fa`B1=6CbG2T^aMKX=oYz=E#$ukE!aer97b=8wlUro!6V7?gtGJ4>1s7xd&y zQA#SbCdNg_2UlSKRkYOwzyC-Ym3Z~PAxmQ}1=@smHdJ1K{&@8G#7tFnt=U3RTS&-x zAd0?pqSdd#@5#ww>F>VEoGjZv?oG`}4N4*4e2R*XA5n&zWq&tqy*!_5rEUqxCe0kQ zECCD`Yv+Z{E~#JcI>i;GJ!ebg0S%>pxxwCh{UJ&;^hMBZaoQMwlb6L*OMZ}2(Yasr z`aRglW|14p3?o|30a||#DJA>SVUi_Nnmec})zuR%ru%ap%?$y#CS6QYQ&LJQBpi?H zz|3;B`R2<>nxa-)rjO3%TgF>1r7%gOQdzuE}pK_AhEz+mm{!Fr#0P7Fo9C|x2*#E_?jnj1!i%!LXmKcmo z!$Xf?p^DUPbMLFJX)LtHMJS*10z7!|nDfV?*T#H}sWLd=K#Km(XWiKDjhbj{RkBv3 z3^@=}uG1m|l<3)(-?^dn>3purbtUmelvcm`WOa^KT{o5&@GHzd${+#rkN(5_f@W3E z^o%kKYjt_ks)KXca8W!(6vY68(8{}``NAZBf0{(#Bzc34-5o&+n;-A#dk0m=BX*(bX*s@-=oL#N9D!-$`UMZ36n0A^Gjr-Cj+eI0H5kf7yyc}LD* zGiIC4R9>xuf&!CHOR9^xg#})74|hH9J4*wLZ+pM|c9vJt^YeGYDhw>Fz9%I$8V_Z@ zw|xZff)^hpgQUHEF#hZb09DX-3am8MZk!8ub!wL{ca056J6?40xm}$z3=?1<Yjk zZEeNPm0#dMJ2_3jB%@=*Trf(>$doJR|EP=j{p21=s@d54=_^I0rlW(quezFo(}6My z9MW3*$z@gU5*b-m^g^YBVloT1*+5=6Or0%%h{~UC&_}67d%wZU-38~l(aj1G$E%tK zk9ls-2bXmd-L^}~vHo$D*>6~2&|PE-m8=dI=hk!o`;BEaTEMl*%ZqW*Ou|iq)u^{# zGTVtT%$L=Tk4=1NqAa@j9l2v7FBym|17<4lIqvdoZ1hFw5OB1>e5{bqc7uiqJYH}( zzhf=e%w0y40la}*^SFZeZ%aCYBo+1bMVe!9CPP=2DDbp*TfzO72ngX{u^<@)?nS-Y z@C_zmiPSZI40toVk5MWzvemb_zuZff)sOzz0Vb*%6y@cG^hf))cql2+Ck9h1&y_Jm zue)7>Pmlzk5XbO3_%%|h?TVv|Q>$jS$)^`Qd}$#eY3Xc@T6kNXJF>?Xy9xf1S*sPd zHwi-rs%^;ILwX!sG|-+Gf`X*0t66Cc2@D7N_rS3%B!s>ncmM_iQ#P(#6DF6bweix^ z3#qFI4;dLsS~VFD-MinU3DwRT4;yB0>Sw5{#|u5Typ-10(O4Vh?Cem5bZaKkjDV3a ztat3?Qnc{UfGY8oI)y8i9A1ll;OSR24pR#${Pp#0%8_E@XZ4T7yk0${WHpXg`<}aK z-wcPp^Qp{|<<8e#!3zDBuv)ewQLSlqG~bkpAN*|ri6h;~M900fIQY03C_AThlAT!U z<@e)=n@tcmndNs>=Yi^qf}%pRqjj(s@1J!bSSfpj$kU;?)Q=S`gl9=pOeZdNDZ=rdI4d-)Yrj#K$|`LuCFi)@&%N;xKG@#c zA_>hFe+sRwxZI6)m@8iaLon81fM*PJw4IN13QLRG9eO8CWp#zK*f9);8BouP(7#7c2g-TBRAKxsoJH8+nV-661PXek1TTUbT}X zY;7E>Wt+^fa3nn4JM~z7{8)0b^p7*zC4}2Ik(nYaOn)H?vQANQ!b+=G!Apj+{SK|YHt%Yi_vU`5>L+tht zN7ssGjh=P$^#~M%zsE(blgQ>Spbqi4dimGZQA|usAtT?vd8RSV87SyC17}39Q-qS7 zK$LV5k)W;hLv_`USeRQ3^uv!&Yt`AGkclR%m5Y04Rer~~T|V9=*Bk7N4iug@*!x9E zNXrH$tH|-)&%HU5NC?F#6Mj9}-(uetUfV)X|B<=X`RJ2UoZ00fxbNURbNVMEAqZ>1 zRlj2bgK`9RPJIK5?omdq2JExci=DE)T{BUyI^E+{=fDg9Qw&4`Vq1POOsAsUk`g63 zKCjsPFtsM5u1vptu*Yz)v$`E%{1fhQ!-JAtXgOEsV$)0xv8|Pjq%tu(`{!YR0lKus zR9$d&Xn%;kUB#2_Lc3uvqLGM?#lhJo%+S!#TGL)Y#$-EdUsznwhowY1zh}<$`sXwv z*;=QXhwB3t_t9@c=N(^tR#ZyUmI~~x)zufkD_ylc$Y!k~OMS0JfylujqtF37*PTvhAZ&`H_E|6&TTQoW%92Sb1uZFbu=+-qa;yED7C`!zgYuWERE&RszTR|xSjk7QShuHL4u`Gp z!Xn5BgD_VN1$$;yW8SY#J>9?mCoX7PS`#({HTc)*Vp43Fkn-bxeFZ~;INnu;t z|Gn%|kio-{mx{Bqme6N6HxoBEF%uPzKb2ENN=cZnZ;NkBO2Cg8(2`Xoz#Ln%!H8AN zHpFnMRq}^F7y46W)euvY!1}%bGf-ZR@&EF~WKkI9y56 zQ0VzwYHX~}VR;S<);vD>N$(%ZDheeB3P-?D030vxxHD8?INB9lxfx`_`^I!i7aL5k zd0ogoqvC@wj~4POb;AS`%ye5bd7s`HT>?%*!js48E>=mzA1} zinOxp(^o6-=3gr_y=J70qkn>qI4VzeH%R>zYW885{+PjMHU2e)qodVkXdJl6UW|vo zcf$YqI=r5rVsE;!xc_9KQF-%zR6^~0G7*pSGl-61h+mniGP5!tPS??>`u&H{AREb? z23S!-bTOo35^*Fm1u}kadm!FjKE{t}*NaOeCvpHhq;EV06_ske3VWS^-{Q=+k+H7( z1M?)>CF$k--q0B5xBCtk$wDPd97`=r?;Ys@yC=&YCsj1FZr~9=B;?w2XBo&38hq7aZ zF<6Z;C>bROXjE;RI^2ttv!z0NofxiJ#+C`i;@Q{wwd~9R^RZ&unoixCxLHd0SaH* zpqtm`%2M^u!3*QjO}WZ-^Fv68(A>cd8Cf=(IUajXen8WrX8X-JxnnNU@zTOVp+egq zkAu~M6IAeNP(e61a%GYo`j}4Bz%v+YQkfJ)S;^(no#_ZXFaF>>``TY*LF3IITVVPb zGAt|Wq=^^iy)YbjhW>}P2Ct`^m>}NS~nb^h-jPO05|&5YIfAb(tP*6_0Lo+R1E0P$9M7y5+*`jcg6<@FCAn zu01l`mdh6mJqE++f1Q(O8_1P>9>Lb(^CE0QVNk5psa-7Xllg&9oc_*m)caHI(!8q8 zy!S4@&T5;Mbj9&{v|?q5(_Pb1Gg9NBn{-vthj4Bx%KYIU^$LsDq z(v()kuGHo)rBS`8 z-NeEGJMnKhJNKP5_b#{5HLZiai@8)cL>y)<-7GU{H=3JR_wXZr_Y<_u6g&?hg|Ae3h&02afgp+`?Df26siJ{VA-5%QF`b#H&31_|Gd3>;5mL zu_cP);s=ZVkUJ44U$OPD-7Zh!CS-}V4yW6oP1f#PyHX>&2Wyw2E2?X~9A6%v4yc}S z-$NwCHXz^Vr!XnV8UG;ag(1p$m>?LGx3z^tu;Gaj4>UQB>98@J@69r)F@vBSgJloGWZ4P&!rTrGDsQ1Zn)%cQP8}*CAWg7cztuClN$p` z?)8jgq%NWGiKmJ~sKvOL&9^Z+I!(S`1BEv&FDH*|qFB@Yqmxr@GJDxjkXCzsOb?jk zt328k2Bw08NyvJ$^Zj~T<9ro$_gDMf*m{(E*R6ryK`ZKb)dex+>n*ZLYa5Zh%kEF2 zskh-Js`+B-_S_c=v!CL;H!dl^SX*)&(i>Y0Ll;?F(+?$98;V?~wkRr3yrCuCIQlIu zk0%UFt&}?rp7(JW<31?oBc1=bsr$>f18&j%wA*(f*3HQ_{Uk)NgY^y-A$UlZt zhSKzV=k|R5d`Ar9S*iKn!W?w8+slYPu`VCQvD&7P_3bb z3ssxdHvV_FUEk53G8!T89cfz9ve*Jhyj-L{#Q+X?#~Z@WP`~f7GCJ8psGEF+untooGPkMN0 zXik#L49Y;c{r&JKN)xjUqBLj*rVi`;P40Y8Wm2e-;;c{*&`_h`1_Y)U)oIGKD6$u; ziW2j)sRkgJy$l1^!59r!pNx)<*I7&9u0i0MzIq*YGMA&?*dW%>jJ>@^qci?6@y=_) zVd>;fL19GLdS=bvy$toabnh49E74t~TSbvOg#j>Bf>VVtl87!+d<0nZdkivf4&gG&KVsY9Stv?&m8mODU6sGwbd!A<@eD&**O*#A^w}oSJuv-OO!69 zW^EVz+C;xt2xYGOJYa0q*i1yB;oG1lN|(LId8%K1nqXDQ^l}D8!%m!8q-JbDEy{^{ z;4#HzUl+C6a)!#1N;qzGuAK4Fd80C2V&Dlj5n8RuLdtXN2M5b|mx}5t`lId5o1agW zWo4sLuXq!N(|Z~5_!?Bl%8t|?vchWp%OcDKn*TN80bZNh$hy4OR2e}t`kndfS2ialV)8fUDE&BqB@BL))6@je^5FsV8NSQ^ zNPztp`se_~O`kX-AhS5?-B|+82hqNk0TS{W^4cE5obzSX>fgJfh~kpshje|u-yy2z z=N2M1wJ0sV+}$Ax6)Pz@Iw}NJ2QHEiWlzpb7|2&6BQqtj6;*`Oyg8;{gno~!^vrYO zViGdq(nk3LK#TQfc9z-;V3v!Y$wMN<#wQag;;9md1_nq8z5C$+HOb7ZybvqupUEA< z^FjdRz=DYgT>nKBFJ4w6%{=&$JOm`c*`dzg-8mWL?rZ_3wK4_Y$oOdCySE?ScRX^&tY65 zWjuq$d@GE4!{##`rK~I+Q$b9;58+{rDAI!v~9WF>0Gtzci&KT3e*DLdYeU> z@SQmU5QB2tRe;&*V!m9iM?Ee))SvPFrRGBY&q zS%pj`NXll}X?LTK)YAPm1Q=5F3Q;yz*Quu-E29*!H(8h$SA{Rf&(#x>(sH{$1DOBp z!eFk_tb5{qA#jU?3IW3wN+ihCITzzuc6AJ86l0sW4WIxdqa-H)%f$m)y)I`bEvpJC z4%m|;b6DKzNDb8I*u=#1r`^4GLX#YhH;=|CjiT~?upcs+ZR%ylN%GzJo?#|NdMcg9 zh(!&b`U4>HPN;4$ufcTb>?Ko)5*SIu^>tSJiNXoakei9gBSCUBSdC6>p9ezRJT9N8 zGneuv+cqWDP*jxWp6c587XU^w)uGM3)EJ91GYbJUl9?T+`&thy6DI~NHW^ffgP{LN zEM2aVLLBh~`js4!;*YGEw;S(nEaUiH6g8%~dC5pHPu#fd{{x4FC&QAl{LRoS6CUPZO!taTKIhM6pNjMRA|3Yi(#^!lCR; z)($!>D+IPl_VFW}+QbFKsd!EB~mPp0t`4`kIkSTb;k=s>%FIk*2N0qpU^;iXp7jAA^#-UX;(;K-`(IMRmPXxGzIFaztbYUa-6iqiDiV~E z-Wf%eJ|=E_`c3xb@$qu1Wa-s=EDrB|@xE5(W+z01SUMvC9=8^|1N<~zwBnFWEnjj{ z>xkl&jrEoOK~heytw7vw-Fk0rkY6DGu|9|)q^DDfXNetjQSg^u7kDlcl4!R%z|nl_ zVvCbi?UYKt&X0ryJCtbE9q(DVTr_j>PX~{g_$veQm+GABg?7Wq{`M%1EkWS{-O|cJ zKXT2?C#7|$~oqgpU6~qAc z^>8_+FP80fGHAbz=8zC(1VkW(S~~?KqSa8=8!f^M8yX4rd`{)CLej{L)IK>jZLn5` zojLJ49&Z@X)>4;AYm3Dk9vGIj`IY<$P(cNo^C|;7Pc~~L<@iACsH%o-tmEP1SH~uN zyXRgf2?s_Yp_$)qvIMVy^|4l|%K3C*Xlm)Ooj?*6f&P?^dm0+%?a54Mkbw|z0$uQx z&RF~N=UP&K1E8>wDOa$76m&C29>}+xfd4r#miWOgw!FL?FppX5Jb3566mWDbw?ZEa zy3-1RIW4Iy9R0KHle39kUqP$Z>LarLF%5d%08)~cZgKyN`3rZ6fSlp^^i{~<6m8I{I_8oC3<3S<-kaQh?SqgL=|(-kt4!}=i^oxh6=pq#c|ceA}b zM0e(F0RHI?FqzsX98f+tRgKvp?2R{F0%a6lxXbLO_}N zlZBbSzNw*dOR>Nwiv|+1YhUOK0FZ!30%x?K9e>_B!k4Q9-v7T*@_&WC0%$+e%O!<{ zN&ehJP`|&_bpK$i^0Gf=#Kr&z`aj_M7s%_sSs@^9E%lCnMvL~M5@WJIKb&IoD+`fu z61xAa42WoHSrvu9St7A9F*6H_5HOK{h72bVkdX^BioR5I@_1I!X<@OlWJo_L06q$g zAg>sitTF<_AIuyuf|ruFH#d~b%}gxi#jE;b@RkJZL4f-613-KKz{CDtL>)Nv1H@u@ z92^`h_-tHUj9grVfbbF6Uu3}E-VSvXWPd8CD8>HL*&$;AYDB-EIPM;Q2MGQ5?}O;w z8>?7tZQahHP1BbvR)7hTmyK72M_ZILSl6{qLQ*6=L~?9i0*SmEcx#8?_sF5kBMm~i ztDxxDSQrK=!z~?~44e#^*5=uN&ZH&;EQ|^=Sy|;o<%Il5;vQ~sDMBuSkS=Tmfr|M0 z+x%TcVRm5j&>#J~Du*0ci#}XG{f3kKPc2LMN94uiH9Z-&MgA;NG%ji-M+bU&yab{g z8>wPhOD|`Db8rs+<=X5>KJo{3LN?y7sCVW+Yc?X6ms_iK%eVj`e!SfB_<|JN@3SA? zo<->GJf6Omn1cBX5y zUSg%7glyEbf;*H4+4Ygw$C1q_biE6(sOK)K+7_l}03! z6Kj3>eYLPI5>ws4QYAZi59mEds_rl_k5wuZQ6R9bq-YQk>OKxze1spSntGob%F0T~ z@b$8*`u6`6T8zKFE&+)vd<^|s7>%&m!1jha%ddaTviG^!s^!QwlUPHAEPs)7Qts_Yc(Yw{m@a24d` z&#Wr0=Lz9%@sYgIy{EL@9a7FTn0s%#XB?g?K@Os{hzSV~5UG!jj;h){X|*~&55ckb z8uv2zH5ggRjV=rV=Qtz_k^-4q*`BFt6G5#3ZZhe0vu zy?WsqyN9M_aB02xbM3qi!eAOLNnQz)juS4pJpHoDEzjlDtk>LzNz|DuhP+9LS!nc* zj?YB#UYV*@M4U@r@(z-fDQt==3VcNuK2IH>6i7jtl^Qm*pyYr`?jXhj2cS0yF{v03 zk`r;b+6dMi-vXhx+4wI2WO z%viMH`in7LBSU0>)^Gm}RG$sE2+|bT1)78?E@+88Si#S{! zfWKmWBbCzRWU9vKKr9|g3lW5U(0A5VJyHnNTXF-d9^n#Iq(Bff)w-X1kP z{zus_@rOfVARAw;Haa(Vu5N%Q1mMgwl^<|A%E}1k{M0&rdVETS=HSBZBGVep2TU9Y zgKrb#5WU)1fV>wVx|8*S^YZ=*uw*G#nzeiUtxYl*q}c!{65AfIZ(LtbpP;IW50kAh z6YI@0ryjQCg$(^#ocrKB{)`e8VX z+!=S_f9z5NRH{b1J3qk7knXAG&`06<;e5QXYQ3G+9LRi1Ub>?^aI#!XpJ+eX57qLx z8w9g*E>$m)8WYxH-~W(G_=63q*mQVZ;KQirJvR(S*p7MJ||_p`GFO2bnJbiM?i&6_d`T zr!>POy7oxHq)M~Z{$x7Si8-CZfQ5u5iX0@6sW4k9?9r&8A?cmEF#@a$aHf7oc5y+)hB{Xahv1lqxnloE^bRk^Ih@v3}A$tS3{b z*cl+G@Phd9={rGSHVNV|E9$9ZD3h-Dm%n~+=kf)g^SIt_Czx`^0y5XZ30;-Jt9$n8V3gY)37Tp>x&WzqP6e|WX?1mKC8En;i(n`=v3URj>X^rY#c zl`*#mWDfN1q_8Y+zNpCbGFGCpNi`3Tgak!FON)A61L+r<*q>S+?Us*^uT$e-Ay5Sn zg){U_KrY=Y!-sz-!QeBp0$6{^5@X>4uy+VTByowjE4}r(%#t8F zrouVZy1vfSsB`v-ysWn)?+$3oq zo0mGB%$cs%)|6XXmw4flVYE#&N=`n;JF_Gv_sT&+yaXJuSrAiewYXhJ2+{2wFIKSW z+u9^d`MUrQ*q~^w$A_IHN4*tj*-vsLX6E@b%p`MQ0zyW)r)7>u|EsBONZ~4`#;+!* z&*{R~)HXmwM!Viro#%IlspDtLaCyrShV2fhZ_lcaQ7`S#KUgExXl-~@c>~k^_>T_& z6{TymYgH0Wvi5WiVTg@qbXJCgM(v`bY9>6E$%KyY zDg^9hq7NulG3uEsp)qja!LuL zen3FjdkbVkKXSP}A9q(WOXlpFe+!Pb`HMg^x8r2PmmH*Vn?;IDQX)@ZW8*V3>GjvT4tsoCu7KItupFF^Jx^9FI(lp!<)XEKBJx9b ztee7e)vZXV|6Zur2&(is1JiUG{Xti_ighpl2&EWEU@yy-yS0z8aA9L(;ZWYeVLCt3 z(=!m`+y;4^GTKCsrQwX#jYN+(M1h>V{nwEBbCk#r15uCIY}Q_jgW8V%@E$l$~T%HQ}z`NX=C0`P{r;p5<01MM7Lr`-F$|19}% zvyI8$HDu`ta%JkzldA<>eH})^q`*bb)?RTJ+scc{T5;hFeVYQo!7&+zW-;%hasmk- zZti@FNH+xK<)vMm`1wK7bTP9FN^;7|pj}{@KNx9DZr2yJZQ!xCDA0jn?pCB8AMN{9 zTy8V%VjC^7UKYXh1lY$|LD0^^UHA<(K-xIvLp;m){wWXCUG6c;0m&N@vIG}Gu#?qt zJ-9y|eW&xN7(s9=zL=Ha3K-5dMozpu%e1 z&2+}+Bu2HxkmR|s8B!tzaM{uzj>(vKY(>$)>R)WrNA5qZ1(#joc{ zSxMGF^&Xc!AwAZwSnZ{80$53ynMxZz|nHE5+nx|@XIg-MTyA)LO_e~k0_u;JtfKUA7j*+&WA34ICy z6r_EFY;N}qAZ5u;@Gc&>9Bz91ABjCe>Mf4SmEoOcdF&Bn-i|QZpU)v#+RgQ>LE}Vf zC2(ePL7g%J`T6+yw;Q#BZL{i#?Xvn*d9fgsVcUdU3Buo3yF>hF0S0eUphLe>Eim8h z#rzC7Am3ws_Z57gv4T8$rz8M8NVMFed1<*{hX9RonfF`REZ}(-6qyobi{Nr=y=E^^ zkGVIM?lNFGajZl~Z8!vPoci5~+gnxrk(@05U263{54t)zk@g)hY$+jcv0K9v_7|2M zNt@~D3PekcaLO2ec4UWXmDVEUy(#QWoOe{U+k`$u zy$O}nw=wB{ai5StndtAPZzc!nvXaAfBFHM>?ye2-o0n>5cmujQ1Fc4DXIIs1J?vwz zOyqahS4KP^z>{X?0*3apGgw=$ZzoRqUjey#LEUaZVDV~3naIsCJXt&ak2e)aim5UY z9$xVt5lImZ#4U#}b)_6(1Zp8weV6^t@NB;pXMv>qkrF};H7~r&9bqT|2W=kVAkB1d%89dmQrxCxiGpD$Xy=Zio;! zi&i2gE*%*mHa9De48Du}_4@kS{?DJYAL>2Ub%D!QwG8Oru7>a_<7mdCB=nf_n-ap7?Ic7+ zJ;Sp$IYgDx5~Y->)5ef+&sLbc?gllKg;CsxUK{%d2Ru04gEn&ri!9icGVU(EXkbbd z=064w$&$t4js3)VtNE?xFCtBmHz^t{sb8yzFFYwup|aro96y7PpLNc2$?0`(Z){A$ zz*?@oR4(SVe-Ts{n{M%4xk{N0pMGTOW4(d{c1gfcd*yU(gbPpxjN?XP#ZknEnuPFV z%vm-_3J;6&)u@RbmzKKj6VBvVIao9d)`RK;m5Qx7Y(A!8!0ahAz z=v=v7vUnjO5tZxJTIS}d?d`Art0oN%Ov~3jxB|yar#}KxQ;+*N4uFj4I_Ex^@hDs_ z*V~X!o8=3DqYaQ+Dwho?!Gj;H^r51$Sa-JfPDGbh)U`Mhc4VYdYJMMvI*0<+j-}2O z$D+XKyj->JZt%pxy5I`4+zbzMNL%A`Q(GLsqlSB}B{rX$b#P~)amZ*nooaEPRSF)~z zisf3p6D;e?{)EQsc}olKMw=MmL?`#A4s;B`aBIy@T?TC^mMKt4m30u0Kf-!nAL@RZ zS5Qw(NJ{zn@wjq(X9C>s+}wy&&pD;m>QGiLf<4I0Hn|~zNRsq#ccPIe)i{v z%VmEAxxsRCnosx3#^=GHfS{Uz4KUChm)G4uazv4D*mG$Unw{o1LDX$6rR`p?m*G*7 z7t0lWtV!M%^hn@H&96UPe1~MTk~zJ&VF-<(*a_WyyGX_i8F=E79;CI_=sTo`Am%l` z=>svAtA(A;9J3}1^!~q$QnG}_^-ovmnI)1cmW{TZ_oF|PVia*mKjn`21+%z@aWUJFX4@$OlUUQd-s7h&_j*s-!yiJ)?2JcP`jNCYE?E`EM8PY z2=ZR9ud$X@=roZKvQXl1xkY`EjBalJ@+EmfGJ^hP`i-8jb9O1jrb2yQtxb2V(F-th zIo{BlT^XqUdU|F>*Jg16Zz)&%X`1;Ez8vuF6rfTS^55WjF8g`yh?v(Qlb0H&fDr$9=>f#&=uZm4=j z^Sh%Hrpqh9792c#xx_nObeLIOe7hyz-miEWAt$F({VDtnjd+Vzu|gAnGt#?mMV-0q zY}qFQzGNzny88GtuDE{t{uQhsa>aqa>HnG@adH{qPFv+d&~V}D%!~e zYYX{$8Gr{!U(zX~ttC0*EQA4All2T*;tFfh{up2yvfE0X%JQhqrQh#^MQ(UhI08L! zW}%)~#blR#ks8USQb^47F)6a`DZaYt^oO1Du zQ*Lt{=A>0;?frMJvXK(?EQ8W@1t%fb-m|ZeO_nwyxRNCx@G@iMm*#tXoxB=rGj7Cb zJ>3dCo7wU;W>La?$SkP588}>JYtz~V+nljj3m7%u>e*;BZfdHW%YHj_I+bTKKA9^_ zIC%(pd}O&@ACqsK*MNPK;gcigpu8E3`Pk@kgG0R6u8P-c81$+Uiif@O2ommma4$A6 zRBL-f6L0{t7TDs`enD|uoTHt$c=qjoEC#u^TlI%pt&T=Mc5HXD{CbjJSVW@5(>(kV zQ|6ajD^&n`$1W3(N@h3T>EX0F>*R8|I+W^e4A_d>n$y@D>$GKfc^{}Awy6|YW*oa@ z2%WENGHcqCAyobYh znCNO(D!0uPoR%{3IJS0))v#G#YF@qyPRD0-ob2~d^P2`iMePEfKPhJ($7}SYuAX;6 z!#WPg9#()RI$b6yJXf&{&^c*&Lg6D(AA6y;87NUCm`qfn(ssZ}x4v{EnyoS@UyA&E ze9Y-)7n&y_IT-a7>U)Kw`>Y2GOin+?41x6pWGE>p?S+|{?%tN>zFESV9QFFF0_G1C zUqOEDyr--e3pEu@Y1a%u>ZFDfWMaT@Xi)CI#Jnv?IBrB&rY|$`sYyvJEv zDPFf8Z&P`I!{`5`B-K$o{iBvyJuSgbaDP3{BIfBma<#%>%*fDa+!EW)VPE4W&}uew zojc4!LtyH5E3l%7C1M99W0gT|s2`GH>tnmI=mck^0V{pg*u>mEE5)Uk;tUp_~nkx!f(DRd4-?molP zdLt*c)|$Z7*P2}{7o4RV?g`4YiBx(_*`y($KGj&>CCcet%+-I(4iZU(4GV{?DO=zq z`aQ5^^qKpa%SZ+G+8Or#o{3iDv%RNzpDGq4QB)O9Voc0R_K@T0&WMu%9J~P}uX3vk zNqEc9M2UI94Qkc%BWSaBhttt0bYmOzCyX4~A27`M>lf*Z^YfEUpp;M!WMBQbFV_K+ z#kGEMxvEM=kGB1SkokquBiDxwfi-njo3^dWAZ*_XU7_3Ufgw^nM9{$IWJC>|Crc1@ zhpk=heGR}(m!7BpX{zVtSApbKLnv!S@4nzbzwJOTA;Iz&q&Q@ZLm(8^fg}>wd*p6E zbQTq0`U`)zJUlFUsLbl$K<;Ex!3=Z##%8$ZZE4b_H&jGS>WJ3XQ_9bkZ-ey?JIm6i zLI$3|^T>5|-=3b3LQ|E!WHE@p3$!AYXv*l$kiTqjwfgGCs+Q@5ZzWcB)>(1udbp$8 zxoGiojAU1OTCkOe1Uhd5tcI7l^9nw0G{_;?h8p=Zq@|w6d%T)`^rDkx_+rn9@7+X7Zp7C{mjHUZV?)>3_{;U$kzAG+Z2Tx&mcW)&G3h&<2biv-woweFztuFeM ztEjPB0Gih9^ukS8yFdE7P>6$41z~w=(Pme0`ebgBUa*2nqRva~(sWv7;1w&g%eBr< zV=}HqME!^9ZW!z zkRMVcj8R+Hg>MMSPpllx%U@nxrZ*2h^Z}Z9ci$Y45T{T0mZ{Ctsz1F_!)#ZjZ>AhH zyd@P8-K{t_jin&fk?xQ9-h(NP>urOp6CMqNOv_+^+QXyY-w44`mSYiClBx=mjS+h$ zr@ZJ(_;h~v7EnAr{R7oGN=j8j0Kr*EmGzPm(Ljhg^!3ogeW!UM4l`%3e8AUvP$WD; zcHtprcYVx5Rt6nijo1j9rRb-Zp$nfDsfg5eo=`COJt|9pj=Uz(>R(YLUdB*BO6o;s zgOhq)Fsh(^IvgUX-rlXKX6WH>-e&rF7CKbyl>Wo1A_4Ta0cH+*76yFb`T@i;5nYFA zLc72%$xnt7MHBQ`nRYDPS?CGtSCVxold17!d5FlyJ|>4G(n2LbPB^#R|iXVe%Cn84WQxpD-LAI*W_C z#0#)wI_(GS!PU9oTv|(t$vBkC#`pWgj~9z5*>eEw!2K3`xk=?<6j`VYm{WgsFj)G% zQN5pxyFIgWV8MF&V;=F6`*Gtf-36XPi7I%a=4gdxex@N9#+7UsD3;xwtpJn%X7e)^ zXL8Im|D45+ix7Kd$=Qp_mId{6hnL}QK14xOOef8+-<$b0y7wwnm%2xix4Br`B=DC!zxEd ze|z!_aip84Z!}*rU{A}-zML;>tkw~xYP;Ir7_k6D;cjn+t|3L!HUQ(AfxWy;hT5}l}VNd(Fo zs{=>FS9S0)xlr}`16X3Es@jgB-2{F0#?T_?4ZL)Ar*Hu^Rhk`vqO+w=t3*x19ay)Y z*L;4v>6}K|e^;q`-pox|D}-lI?XvI5-ioVs8YcF(M?Bc4K)L500kU&mIS!QK= z)$;(MQtP;k0e+~t%*y(EPm6YH%&n|f%EIDVGK9+q^0u~W26F2xm#MGS-U|)m zeadD>*l4G-<%iT44}5YO0z&G7_VB}uD$5$JsvMKp#CSAhgl-f{g#vheE|vQ?*e#*} z`_puFJg_JC!o~)U2q@TVKCZ%Qdpo5#$p)+|wR%3H}{v%E<9xOG6>tDCc zZ}GIBvT0ikJZ4U!z=x!>I+C4wg1((Lm@lu@-Wx435GyX+03C!uw-aWewZGDRNLkDj z7Y9c*#pGuCm!=Dh8>B2yqtV$e(P$#lxN(lMGG(sTv$i3afN z^d8JgF`h{mqoblB9c;~}68o);w*bd`d=zZ+ySCjA9JevP@KTm%9*=`hD9j6iTcS27 za7f5CP~ah|a8UOk;L4U37ad7ji`pMrPG=oCl}-aND5+s#xl2&R&CWH1;aR);Pm|!kwZXY}7TMev+9O?Lp=@R$67AMHW}A z?mJz2vna~OfaZF{G{s&AO)NExUV5EZXv3_>9Z+U$vM*mWMr(AqIpxEGiXdST>9IXy zm08RN2U!YPG<1*n&ij5~W(Kb!qgeUA7yYTyYhQm73f?-sV9eJuTdUDpogMU`V{yAI zem5Uwz3AG>0b903*g@5~X%aW6sn|qUaiunK^~cx12ytC&X$h68*`-KX+fvpJO@lPo4mX@0auQ;x0w0l*XIxglVHkGJdUanz8XY^=v+v2U zZwJral0UU3twD-)7tuC|lY-N^ni(Fa#Sge0;2aO$85bliQ_)Zv&4s{|D7g#Fh-`(v zBWH^=!@Kbz6oDyiUqgg2@jycP;waVIP!x&ih>nF1T?=bMH`|UQZdoO(EXsKFI8z$z z4Zj`izE8(Oq7^^3>&Fri(DHsK51gIlag?NOK7!u@u2|)R#&;<`&%8 zdM2l>ZST*;UT|)q>YAx~6iMqM&2Ud3n$xb_`EOSJ0s3NsI0|_56+hXNibn=!5kamw zLa>M(S}C}N2N#13|xE@bUl52Y$l+f#gO12AYWgE~vGBQG5l0}A(%J=$MT!uV7H#a>eORFi{#On*P)|Aa_ z>4{LpP;(UusC@^6Kvz;R03JOC#wPa`79X5EAu%yCKKWPW;W8I`VWHbQr!KygRU169 z8oSWYkrCqoXf}W@rJUIr@@wYT+^m99g5uw-LrDUFb(n?CsL&UXzuWvMD9sE=YyM^( zQULGD1F#O8E(~UWDMAvL5sBe)4+5GGAfpvL84W`>HC*9S0uh7*5P$0c$aO%})iK0I zO41>ViGW-R1Mf&eAeUl#=GPA@TZ-)1?0j$WyeB~LA&3V~v5_e10=O3Z@2~cMdCA-W z!AF|j!#(c3&+TrDncYt6J&ToQ8WNc--tildMD%vP;q!Q|Rqu9$0DZh*samD1uD$}l znN7*si^CI1r8u2k?pAVtJ|Uip(kEPf-9zY0W@=`hNKbpTP%Fo*A>oO|Zmn#&mehr3 zqt2$H75OCz?;720(QLClQoY`OY_<3S4%@RG8Rrw1xVUs?ovoCtZE_Evu_^x_r#kHmq*6drYC2TUfMk zu{hIVR-+E~B83Ja5z2BO2>0ia5856SS2m8vT0LILW?Y!}xIc8?fBa01-eqOG%5 zn0c(yRUCGV5ZRehXbu&s06pklQOlT6xfC_wCp+*512Y z$Fnl^9xp})s&Nz)8b#aXtS(?F?rL01$Kp|fg1Td19G|VHZFYQ+old?rHwV}oO%UL4 za(kW2r~D!wV5U?dE6b~JqNF0&-W)<6OCu#Ma>eBd-P;>Y4n4WOIQm4t4e*X@hB?I8 z-R`$TXYrX!)yhgr*4sX&>znO*{GP!j2+wz12p+HE4vY&V0c-Zq5~js{Xw6jCrHixZ zk!JOID?G`I+}!#3dCd8$0#8(`#Qsri^(HdjIO{Jlo4_0UVSn)eLo}4lO`W%7Z`>;y z6i-f-L|b+#N}9?D0a7f56Pam^lw)Ddn(VA%V^iJ7KW+mhSTAe%TYh!9Hm9Irl5c(u zC$6#Qc-TJ%cCDCAS@PAhxM3HRy|6zIWme10Z=)jwVNL6tmo$j~u(SP_&)WZWBmB3Q z#}vgf*}s09wP#))D>Qa+iS`Ek+aGU_5FZ?VCMFu|3?*Q{uSBjIb-7<&hPoPyt2mc$ zj(LYaFyThR6u)juph_K~C zknIl!^U`>K=ue`}wmYy5HoR?HWuQtJ6a7n2Pn_z(8Jk z;k^Mj%qfScd_$>{HYfPq^1-s`Fh{NV`oi~=_@DBiT4OJ!cu5+bQCD47R9MWGS)@}0 zjFok6>%DD@GVga?1aI19>Y zQEwg5pmfZNAm6fpD7LXtWE!xSay9PgojUc57CVUzkXDBaovE&eY&w(Y$Fv-8Cv1yu zQ}v4$g&AXi0h$iir*t`i zpe)6DtEI}Z?j7%<$OJbEiw@PgL~Yy{b!v)C#jsR^+s`+5;0PH^cO>SV@PDC!-WE?v()+KsR~&I z1p$%ZsWe?YBJp9Q?-nM0w7`zu;9!IQpyYTPeAx#7eG8x~{*Je2ION=@d59$rYjU#C zGn0#{G66+~VR!IFjHSK3SRZIE)|;}%zPw7_BwzjpQ+vAZgLGlFrd~~?g6_g@-Ww4_ z&91h@3`E@>W_od}f}_Hkphfa&R>;o_0}`AGlzY3RMLo?nNET>YYS74J$73cPheu|* zP1zrjBP-u3nMu(y>1;5WE*jdjaa=23(Dk>?ayh>ymlf@7+GjoOI1E#g?A^xySWN6>HPX;C(Q{VsUM4r_R}-xrLgdGSM`r%I>GXtOuZ zm(p?c0hgJ%;Sd&Aqxpf?e|BbpMlKgk5teqU0ZL1q34!%%G=w+t>f9i8+s+Om${X9= zX0QyNgC%xw>b$JXzD#5)-OVMuk7s?QJR21i2#V7M4mKkWRXYm`W~oBkbH@v84aRf# z&rj>fndvem+bJV3OBjk(d|Y5V-=aS^HZ1q!<(5dx9(~6z=p?s_|57NqDk^8FIa{%1Bvs9v<@feYx2m4S?LH zE5$TP$iR3pmB9fY(iC6!G&Ix+xi`M)Whk^(@w5awdU6aD9A6cC`|EnKyvmK{iU&4p!< z6bO1}u>-PYq?%9n4eSse1?PSxq_DvU6}K$_^lamV+M14pWTC~a4-+-o;8afnh=g&r z)OKFk43G5dIS^RBKCQ<^i^vPQUv4lGD!Q+*SM;IN7q#KJutJr=6~3{+uSZ=h|vQi$I*-7d_<$uy{y7Y+~P$aN5S2bo$#)tEkKFo5x zAQDCJ!=Pi*g?h~RO)LLWwQ5}iW4)l9U;$_+nw*`aWm^Fbv3~vO`nrEbH&N)3#1=oO zMx)zSSf}TJ4bSVO*RmAfry6WgL(HcA$H&`cC?Q0d>{Kn}cA50ot_AFuK7kT*gA_Y# zZgApeGs{PN$7++-mWyfn7G@x%M`ykVJ&(!T4^0Zl@NTiRy}8FupXU$!ww9h|+ajbO z!8p4I3})>m>Y3`=NG=iD8=WgM7)c^}=7I3&-XGjrDY`iyl(kfbCHf;Coi8vr{)=^% z2}Lac`m|#wEDd(!CS10tQMDZ!a}&jy?ZpYbE`f-#)Q1Uo$|4yS7sQapzq9M{B?QPRFU z)6sCggdEcDTkB48x<0DX@I$y{1B@2Ba@|?wh8n-G0q3M98NCZeU#Og9e0dL~_X&+c)8mrx}q>;`Pg|L)-3qDQH zXUosw(8x5JqSjJ{ML;Iesez{{xQpAMeQFJtz_d+|g5^l>+3e)(TXB=mOU zc!&mh1(aO$LLsJOiDw>*G+8PVhu!FU@3ofe-vTxBYgMpxF?^A41FEqxNMDNcCVXCR z*@k~+-20P^k_*Yb!Mg#+&g_JS%QV!IZaEfl!iX#NHPoinAaoVwL6qZJvh~-sj|X_; z68QKMYm*Mc_xcWw#lxec(f3jVunk%Eb5tbPYbw%y@f398+$X0CC6%eyY1JW2wtUty z|Hs&lfK^X1T*d^=7)@A-$Oqe&hSqZGQ zE6@(@v8l7-h29m6fpqdiW?FvC5L!V(#2w#!(mF_q@jtNu@L0$LIZXuQfgvmjh@%$4-8mgC>W4ECxz(}S_t^s~?KZoYouVmWm^0|E zDw`?k(WbbJ(Or&w`-gkroJl4I(ZLYz6dJg;cL8l~V;TsB>9Bum_JQMeHjQ)Y$5((u z=zWm}xQ>oX2#-eNf#V2X9gdj0mD3O@q#<}P`-0Qw@Z7fL1Di}lDh^i*pT-SCBS9J8 z#zPDkA4-3aJL4-AiOmY%IXr7PI*nUx4S+rwM?O)XE_uPRtiSgSEi)N$iEx))ZhRJ@ zH^zdqruEYcx8>fZ1)n7#gMosF+Cniph0uP9{@o#BH z9PzUX6ho0*eZhkMkx0Hw{u)J(XiV?Kdoc86`nt<_v@+W>OpC3!JIV(pce=d<5lc_< zwQ9AQ@b%nFlA;dTHjHj3v^T6lgYM;K_sF5#-+FVQW5Al$MiR3oh49C4#@b-QT2l89 zz3ZXV&F60zuw8kc365L?4c)tVg)jg@@Yh(eb=>`B9z7p~4%&KhMVg)!}2A8Fh15{_*^NXcOom%TCVqum>a3_lr#b&z~>R1{}>CirxeHg`=h@jlt z3=|&C(5v*jP0uJmk6M4T^nNc&h{2GriG@qaWb!6kDgFp$tmfFCOs2D*<85(bhw8+9 zU|Y%Hfa|?oJ_sFQcrjlHsnAcvRwzx81~vNftIqBYgp7pLk+iM!l@3ZzTuh2@)8m?| zHYbjdlNKctiLX1PVzYTmWp-6Er*iX~iZ`vR;ci)7R*?q~|G9f^EYCfVNgUFJfsWD> zKEFI#yS<5tDgaOSm#(ob?`CCNW2G#jCYteI3&>O?)w<_~f`0TY-A}y`Yv(QXNP${69Zp{-^{(^>=^%mBw5dX*7 za0J6{F0I(R-4qGuhAAun`kt}VaKMiU9hKQnz+HEdecZmd1o=lD#H=NtaL`!zNN9UK zEv?U@I{A1B(7VjoGT;}0LZ)!NezZpG`fxJJ7xo@?4!_E`I`~8ukj^eUxE4VO&hK8F ze5OnhrIFa3`sg+2iS(P{Cl35m;PryEy#!ssXVM>pNI!XqO2qGsPY3k_By`v8zr@IZ za}s_FZ};k~Z4jM%?U-W~OJF{`CvM z9H*yc4*=w5rswtF6yy1=ICh)jvApW)>W-40_V(sLlYd;q6onUpi#`5e;4P(~(DBo^ zGVDEdnDuYJp81?Mz^~{3js^dpT)6=8DWAAK1@#rMzhi|Z|2?Lw@6#3;DH9PE#mvGq zy)ZXj7#s)JKlRDuJ4E?Ul?(ldu)`CH-7TX35766{)J@At;4-{MB_;~X*NUT8DT*fc|R|lVmo!rIgq*hpMmE8$%VSU#Wn8;exJnA z)YY7uUa8ejx~Fk>Z+$%UxnA3BgUz9H_;p#kU(kOiliq22zCAAzodpB~sHrKM9xPDZ zj!tA~b91#dnyqwS8AzV)E=wRHARb7fD~&IKpH!)K0sL6ZrTx*b3UhOv#TC&PC74a; z-0m19B{|wH`fN>!&^1ZKWlh>GI3$&f)~;El3khm&vyEOwliIINjvo{#$d~X=I4s_c zsjVwvPYOX%X~>uld(o3=%99-cZ2N&yA)uzE)sbH!rUmAav@Z>ydqdLiaTWevTg|)9 ztY)X(|EsgJjEOUhwsi$}hvHf&R@|kyd$9t=iWCMN+}+)aySsaFcXxLNcRyc`BsaM? z=g0j!nF%42Z{Gc`^{lmTv~F9S33>&}bva~YR9OGtnlw&HM^G@>rgav?(2sNy|9Ggf zt{=NQR%U($Bk}C>>n^A(58%E~NCZ6ka5yXuOm$}wcKa153dVE-gd@kwfRMd!*9)wI z@u=?XY)(9Q`f-b+`;33U$rKs^iwnmZMtyU*T#M~sWo&o$xS{2is14g;yyM$?Uoi&b zT&TL$`IYz$(W9Mt|AnXER*8kBn!)W(bSX0yJMHCsYA}eR<&K1Zi-6Kql#7guf$$?A>Wt3WhC})^@fBXnlCM90`TIhaSWEjo$dgdXq0n@X+89V1ME+e0t6!Ff`cy9Ci?T z8u&P_*$6|fnx*~QJTzq9YCSwsLGN!f!3CO&pGb?xv89`Ec0_$b3z&i)6~68DXq2~J zPRkte+F_AjSTUh&6$TpU)S*r6+g!LsG4t`ZvZ>a@3#r%V;9USXD(CG>Xi`e_g> zH8m|}Xb-kzyPS7cxAHR_?2oK+Jmt48)CW|ntI$L%gVx@znVIhuzWv;tPDS6d!tSp= z9G*e9qC9r-d1ua4H|Xo?v=OJr#X**eJKtw`0TTeLl(0zv@u!1hxiqex+9aF4#||1M z2FAZDeZ}N+<-#3p`}jTn7!6Sd}XS zm6ed&v=m=e_kP6kRS1J@k>ho!w=_2;r-9QTTZf0t#hgaMxi4U)tfi~Xt zWpCA2LZRwhzDML*l|FiwqT|&dEMn9BnX(xn776B85Kz}Hi7L7?U7!GxYt2zGE|z#F z09T7z5f}Fr)!BPmy}Nv9+3_snuakeI;(MARqdZ%PR$~Z+`kb>jL)0^<37gpaG@PY| z$aZKprS)4&3tPf8MJgc;`}aC2-=%w}*R47T2ssdy4jx6l`>}2z=CgdAe!xmQSXUc% z&n&tNI`T0ipu6ywN(joy(G8OWF}ZH5_zkK50vDlm5UvDT6IDeSrIYIND>ooEIYg-% zt!6VuHb%XN(Lkz4L%io& zFizcgVk!|r`dDXUF}2pl{j>=f7o}dEy0=1fQS}>$>Of;^yg^Dx2U-_Twld}C&qM+a zF_7yJU8La+vvzL0)8cAK=3eLKF~Mo5}u+jix^OjdSRf2qq@7OuU)bs9C-&5)&Up7 z@8?VWiUtci`4cLZBUmHV3+l(pesJu-k?-#`QT9@24rZIrI+jKRK>{P0nSv&?e0)S= z{ip?nvYH*NXXkgfdG9%vb*zF%R+V}Tv zOMNLsgw=pvia}(G&M)M?*yCP9w6I1pXroR@*2c8bC6j^+N|Lew%bj1K0teJ2aiOX-I~pN!~o z;Ugy>)E3)=Na9-^R?xmJwwe*|Y4bEVc4i`{1Yv>*7l;lBXu2tdzGVqJgKJl{^wDjL zdy-i{thu||eR~tNhWh;RZqd>Q*88M#0`+Q@$qOu;OW0z1GSw*0&;pvn#EDG{hu$mR zkQAmz(^0PdT!LW-#iFlNMgK^dvN?p+M#STnD|5F(R|70VQAGIG1bQ@V0gVJh1a!yV)k&o?F$YJ9Eynj`hVuE^n6a$^3}dIV?0JWZg`E{*M-LsvacO zJ=^B|^s^72mWS<@!9Yq$X)={*JHMoa)pJo?mi^n`u>kE()k2N-F#Tv@E-0><={<%( zo zy;mkziG(>uxru|13W1r_-R31`7GyBKgnka=pNj)-k9jiHC3;Nd)0@1$F!T%$Co(Wt zLRC>}kT|uu-KbeU0kwHdJ(au38Pqp;fFb!aqkRljrK+_lUJN=3V`9!e<*gF~3Zibc z6o0rW!f6Aes8I>RltuD0{2T@ewS-sT;Mzgp`@ zvnlMyEp^ss#5V#z9+Jmxa>bt;C5j5*XJe3&Bzw~H6! zLJsvgf^Km-f`D6EpV|hvrTdoz&eT$4qYr`1u<1w%I(UG7wiX^9PDli4BE-NYiA1>q z{!*YY%zGxQ&XAmTY7#;Bh+{iIqkqd?0_<5q=UeSM*qQNH!%yX>zJUroRF0>wp~QHP zH>}{izNZ6JBl=@tg}kqdH{eWc_(yMd&&$09Qf~Xdwu9F8X3K}aRlG=$p9+SBhN2=y zF6`Rh58Y@%UY-`kFf!mX{HTBLVgm@gDYQ5seXmT#Q${)P zg`_d&c6LePnDgzk(G$lQ2)_K&+HzBaHk+pz2-Iq$)Gg*IA08ZRvD8SMs5Lb;)fzd3 z`qT}3*VRWvR1C)08@RySihTnk!^HfK6$iZUcxKLR4^x)5iFI_l*g@9&9duO-`pK~2 zL^@0ykF)b=uX5tD_~)Vj@;&88`I+P$k5_Ih1TQnlG91-n%Ic`5&%DM1rhqg5>(8x> z2)H@}8R4(GR_pePdBx$y+|AcSe4Ar!p1thMZtSLO%!~s1OAs;ZIUoy;pkg{u_yzo` z?J;sT(;vx9(I@xU@r_IkKu@?Jvp}n{K_kJ_F{sq@N2NV?r?nTo!x1x5I#K=YahzZ} zA}VVunv4C6->36S+9eLZ98Tk{Qoy#YdY;@a(D-ylGyi)9#XgBGd|bc9xcgQRx9ks_ zd%KfeDFGm`)sY> zxezp8m=MbgvL__^K~1Pk_mqDw+kGZld1J$oP<{z$fi!Bq`s>YxZ)vV5RTXotr^(!o z@CbnMZOrjpGH&>HkzuFI<0Pzge;{^pdu zHT4DdhY$A%sz$n5>HiE{aF7f<=62)ymnLv1-Ez~ub*h%OX{st4JQc1>XH4DsgwlQ( zZ2a%EMJs)aDto}~7?pp`qiYp9ac6sH#I~BrN*2VO8NYQf2UG%Nf^A}Y_oVcK1Py-jed^)1QakPi(1_}oB@B}{ zD%~;TQ{hOxwNCNG@%D5+*gyUNM`)%d@)T7UBG!|XIx80?{0(w`ML@|9rL+qqCZKCJkM6yGQ$|#lP|W{CNIweAC|qf%P@+Owi2C3@FV3 zzDn0iwy9?6-MdMWEMF&Vb{5d&%;A6fjL(Lia-k{Tiw8_Hr?IN38FXu$Pc!Hg3l-Z( z00V>XZ4G=PzMx+b4l;^RkUS)?ERMqbVjFg-Ki$$<_4w#T}zxVCmq;OOF;L2;ht4hSK|9P%w_Zxdx7rABN>M;;oYsqI=an-}+Sz4l! z#u6cg`RC&HGNbO#<;f{HkXc)DS}ukszz~Q|`lASV!iVpS?2|E2*xHYww7)MveYmGW zd~ib3=op@;l-x(Lv@LmnK6fV6y9_;fqb5@@SIwvyq(vkYa_vq6&Y@54#uOGZ~Bs*G4-bm^_Cih9#rQ&lRB}Vk-B35ZX^4F!&1@Y zC^s6iFM})FZw!0;LbYvEmE2%!iD7%Rv8!h_L#X5Od)5}m3#d`r> zVR<62N5C3`7nmF#>a8jB=aWP}nisFTV4+vWvuOav9)nGi8c$w=O3v#M{X#(q@86E; zt#bDlUr;GS!W%pI_)*Ls0e?VMc96KnSF;F%I`S+)qh|Xb+i|OPZK2&VdW_Sh`u(Ts z+c%HMnu74|N}H#Ux9FD?20zM;d-$=iJh5JxPJvGEC!mvRK({eI<=0(yMMWfLs6`j3 zzdy6aja*O+7r$(vC|x8Um)|h03G)5~TzqVOF`{2_QgU;1Qwep&WP7al&A~$aU6j6< zJlu(x87;!$V$~$1QxNTQZ_=VuKg>Yh7nUheFR?DN1m0)Tu;EDq2#+DXXpEQk# zh<=!Hmx#kUb{2XAa|`d?il2W~zpKjj_rMRbQ&8x3d5gWz_UpLv6?#6d*-{5nnu zL2+M}BqMHVU@2#-ZJ}F#v~c+P+g=<)6ikUr5=QimG?Jx@e~gwRjAR7IzU|k&(EziM z^(|fgSAWD$pvApjcy+Y1O%`|$Azajk=iTD!k|7!OLwku)=V)XUGmonFn4Er{`xhfXnF%_pLkPxF;QqJR@|?0$6n z`P;8;k*BmJq_UQeT-Bnqaiz;8B07p&1ZRN-I0SryJ>K41HRZae*-^@D>{fl?Q&eMO zqaQ)Awh#rD<$PY<7Ev&UrsDPaIDoLUG}j>?R-A;}Lp4(>L0(IZn=kO|b*3 zHl{-M4F(N0M(6c()wN2yuQd*Xf9Q~S7cH_4plc!&&Iu4>vo=h$M#ko7Q&d;0Jtn)T zj_WPghxz(fUEBEQ>A!^<1W?D}e!ZZs)G(5$sLoJX4PqcGP}jy;H`F1rb| z$fjRqZb~)YC!7G4$P9^gr{0%eJNCp438MtxV&q|Uy-Fe@N0Vpfr?w0U4JIu6_l&A9 zpt)ye!Gflh`ENTlx51t{Ow@#CFBp5I~oC}t>oD{ zHA>>s;PQBN$pbgV1EZ!lM9(&)9i=G^<`BGnvPdLga=VE4ud+unUn%)D`y zA%iQF+$IDnb>mDDV>`lhJs!Hj8R#oA=oW))5Uf!uYe`}RB9jY`z^n0tjFGY&PcPf` zrKSx`rx{W>>AxS8JkLM6xRhF}Cs7P9450NHyv~n#qI7L^4b+>D>$}nGj%f!sW%1xW zWTDX5neJc86mUeK+>T5?D1*u5y|?A0r6a<_yBkJG{gu2j>5n-I8F=B>e?@BAUf;t* z&|3@}RMd);r6xy7hDt&n-jBRsf6<2X7OSO^Px9UNi$Ys-bRoi_X5L5~9P^+h8%9hc zLOb8`3pSkj6#jlXQQPwOdh*{oXfY7y=ESR(?uJca#SF^enDi$o>+uKQ9V z<2QY*+f5|*U;ATz1muCvB4ptjRAPa?fq)ME{8;U#O!I;{SQL`}!icP&+D`jR@OxC9 z;Ae{?lAtdzX-!`6xEB$`p+mc&_}D^nF35!a@SXR_C9iSImqBE0%&L)Jgh!yvO$&1f zNX^>y*3MQu;h#k%iF@2fA1&SloWj~95U&==*-tDYAJYAx^({LyetBk`1m(!RxnGYs z%WPZ{a^sj<{zS0Bu`^DE5))U6xJ{x0Xq#kJ+h0bte(*W4Uw&YEgQ-+c1h3Uc%I69# zL#gl@D%)L4jGahWv)6+&!HW8c^=%u zv(GRL@)0-b2QS)L%Z1MXBhJjMRL`&*q|4KA!AX4sSRO)ci@n^ed(S~ zPA7mZK}%K64~6>f=ChT)zx2KyU_81sueQ`1l8uZmx1#aCm@G?I1-xTlX>{@a6Gec3 zTca~8YXGamw=&Q8M)KK(sTSyu)sN_Ntth~Qc|FtM^W@1dM_XLnXeu$PfpM)bOL%b@ z@H$=PX)rQ|qgUL{76)xU#(QqOo1K{fZZ|(?`!G)MR`*gM%rcp)N%+2a>{iMo(+?ws zN`5iL*-1iw+7f_ImT2!wQr?R)NwP65iYX{|5f!l#249sZ72WHv z!=^^x6B(SCV!ammdgjoI+S*6hbAVth(@u^e-lY;$qRb$*h4M-IO6+GVx+bjlpW%g4 z$}K@yR?T0QXp4UTHZuN8Dg1ASO9|z!O&{g$%&*q9A-*3pPo;M&yG!kyu8P;XGV@?% zgCodaYwgk1W|OA;YZbAo{yH+Wh6mM{OM1hYBLGPaEVq3a8f|QJikqFWO$`+z z-wFM$)RYgfn|R|~TduLXR`DY#VN#z4oh_*uAzi7>g{Ci{S`35IrAOOzn zOvMxI8B=isp9n0XTE6yE;@4ZS+QLW}9B&q9y$xgBJ+%Bjo)i}s$LBt_{u>X5|~aKL{~Oek~JZbARds9tNM`<4k1hzzbUNym4OqsyHXo+i#w z&9}r=t`!Z9U&P{->^y!AUTarXU{R6AK({k_Fh21WLCegA%u6z=eoq+8)T`wHO&0mc zeQZE+ufkW;J2qMQ$`R4$Wwt%B!vCmWu;u#+9A_Gom6L<)NNj@5=oaabvk1P4CtM0v z*>Aoh7=<4nF*tpAZ>3uwkxl@`dtino>+Az@5dN{D9Eq zt83#)^fon@0I#GB&=EsFy;_*W41Z0`#i%$CY+$4rO;yraVJt^PS5BJvm1a7}bouu? znI>Px)x7=l8gJLdt6Xf0=cDjtm&e0MI=kZi4*1{o)|El4de9#~zOd}&O;DZtVDi{X zT8YIEUOo@RTxc8pp$nd@a;IzTE<_rmbdAFvhVCj?%BL1pVxa+%xF@~bkPrbs%UROO zPIvfB9OvJeXbpkcCjRTsW`}KKt_b=Tuqc!4AX2+k{jE)}cb(*0iDP zv|5{mtD(+pDN7I3BZ%@{3a0`&#Zm6hprG{V*xb?L6)tSs%hBw^I7#G9Y?Py#@)HN6 zY0-JEJj_L~)C9_c2uKqn3zFNSL}iEpLSS>LWI_Jr7j{Cd5G2isBWh+ zf$@(&kW><}eOlh87`#TDpiUuJ&2&3Rw5CtCV=B7XV5ar`1jW@<9;sX6m`h7NsMHh@ z0?G1X-&{UjuZzHBlbo|1k`tR-hX#ZjI1x5;WfExJENa55-4_(3B}kTM^`Yg2 zCySh8H_K;svyFjEtsS_z03>9@C+JkoT2QzDggNM;Ehun{hh7(L$tKho8Oy@N`ppuL z687e}@2G>=FEuTE*p??rmjni-rn1@5VmtvhP+RT$zyDVA*Lb{kc`i{4DobY@Fp92J zRIaSXd(PnxKMtlxg`0oxUQ?Tl&|sliurZ*eP5AE1?>RS`Csl^;kSCptLY!$W9_c(c zdt#v>V+}xj4~t*5pO5}5(odrGWLsJYB<1ZaE&wz2&FQK4Fq`2eUOg1qLn?8yHcrLt zas8n2MX|x4t~=NK`BFmJr6`)T7F~SYSU*H}C+@E3QL&T3M=29X(ySJxMZ9kM3)aqto(`j2AZFlq<6(?4>%j>G=(jV}p{ zxl*}5euhR`1jnaoOOXR-N!u;S#f@Ni`M^k_Ji;?YK=v=iuRqUY^fNQky+j9tjUK9h zMfw<}#SBj;8fBA3lZ&;dE&!MGbiVLki``&5)1ewCIYQQfo(0oGX$6hPH?2mq;oCOz z#BtwyTfd>5BFZ|@99kLFDjvi3qui@QR)p}QntbJ-8d=92={`yvBI`oUlZkZXkU6FF zuR-V!TkN4@m29-7B*rG&)mZHG7z6~=2vJU6)kO)rv^hJ^zoc(5(FVPfBp+<|{*4XM z+Ys*8U~;0RMjB0B;Mv5C&2}Tcay@id;qAQxW25Ij07$eA{PAt|mx9JrN?w=OXR2T5 z{fLLoR{@dWsyGX79=2W0Rv;dopCB+h4ulOm!Cp(_8(d%^qf-W6+GiFGjAhmIe4r^rI{I5$DL3V z!fY%m=;x~c4akf5584L8STI#Uz!0dr@NbGA(bcZQnK4cDi`%2YxH3=qh&UCyws6LG z%u?Dd`pZ2%lp1dIc4^b$s6-PV=MYvn35@|QxbnH`yun6fh(^9Yd+0$QK8TAfG{T(- zcmB2w=-1v3iFxQq5kE7UFVrzNVN?$zTp}P3B_2C9ymu`SmNGk;Yc=q%rfIZ4Sgy85 zEseAVa6CQ%t%;^glQ-r@SrPFI&gA(b9i5T#@`H(_ap>u~Vqb7kNZlRD7HqoU-g7_` zcS0|seNFk~2p~Qi-<4@M%;u{h0%@DV6JV2JRnKbOmo@!Y5-v!K^%X3DsZq%$}zCiV1`3(ZyjyF@>Nq0)s=Gfy35w=u9U72vH*5NC*DT+{*rFUy` zT;i#OKu%!=k8X7ggB6FXm$XF=ZKKP zv!?Sl(BuA9wljsZ9Z%to9^KW?Ez+){FJKGB&4vVsA#^haO#Yai!w4DAep*2B!#j%; zBAr*9q9n&`zQ#vchaz&lc>cZ8Kzbl6SwP&a*y!>~W9R+k;dUiLv7^ZR8-w39UK+38{>_N!L-K4UyZBKy54`eDN=#m~ JTv*TNKLA-=K12Wj literal 55822 zcmdSAWl)^KyX~8V;1JwBxH|+7?(PhOCAhmoNN{&|_rYC)y98%&cbCDrv-ht5sr&U- zom+JdAE~Z)Ug_>*4Zi? z9=vzDJ9Mb!<2h<=Y&hpUXYxVD(>NX1AG5hx^hRN@gRIDW@V zAjDxLQi+8|=2BsZ{rpTFhW?e3PBsvoKvec?;4p$5CWVC5|4lc;i?>JKKe7~RkHC6NRg?Ur?vwYABq?M4+AHq^WCtQ}ICwbZ(m-XRj|l=zO$)Hs2l5IE zx7YVq*M3z`vkhs;K*q#L`y6fZT|oR}JeS#SZe39Xa-FoiygYf1TA9f*!Fx2$EE<^* zDUZ|3PD%E*iHApj^je72mlIm_Yvz#|9ksvh+Sw&@hS+9kMXfYh#ZThe zuXi<@Z^Q{eNS_`af{ zfztBr7OE*`QO8`BhR7nC6>Fm>cSN;IJKhJ4jR_EvNX$x|`p2t;gY0b9&W(rtu?!*_ z^M79_Nx(e3TwLffgTrdFb#+`I-Oia>G_d3Gt)%|>NM%y}0gJrX=X9QOENtwrvNP?! z{*Kx40>@IcfUpd1Z!b8OwYob`@uXW~r#CAyM_Mrv`vdYIq34+BXXn%+PaX>3f<2h; z&L3H&HPQKXpTwu>e5u)KV!vAoRdx(tBCV$8@-D;u&3?gz9t(rO$8NRFdw+E=$eE@j zF>)GW{A2LV`|yx{UZH_3htZA~jab-mX9fcZB)Q8-am*yX!EifYaf(Q; z0=Aim*Zt$iSHJl5M@TT6M8x$iruheig^sKCuhb^DrN&dOroaaiypdOCPS)-EDm{o+_r;eOb^^zRR~kQ`3)NwYth zknH@*z?bd%i%s^!xf;>#Cd*|Vasu*-9f4SUderAV@Pxn!Ql_A@s9fKAnP!1pJr8MB#gXN+0Rv&-__lsE7@ zgjcxBvP#%!$*>$cDDFo|^96q_6Be*YF~l(bD2^eDXhCb9k{kLie*Y0GYUo<0bt@`r z^&BmMr~3N!>pP*y>(LF~$TeuKWwyaI=BHPoTmf8T;FROlb))K!_axl0Bzksdu*coX zg8e1FrcnGhuNQ@}`)&kF=ZC|xd*BmwM3?Nte5RUV6%{z_)~;_GR>kq({oWnQXCs2+ss(ttY`}A~kN*>-~wMC+qs+yG`S~ zvP-%QuFACvKnM#7U<*MW)*&ZV$iDTM;Zo`uji8{s@X5>Tn;{EJ^tNn|VyW?Kx>#F_ zx8RA0N969C0RJwa&M3Xyz#q6`WYjCAJ|T*F*)yPid2jn&?<~NU+w{rD@*j(KG=}(d zwI09o>0w?AVbM!B?IemKfI3WKU%>8+AEKBRmN56eXeaaC1iE+_qv&!3eT~P51Jr6O z7VUam;&G|H;iWDX&Yt@l4&OHQFz|kum>5&bRy0_s87geH8Mb=WC!)Eg3j7fJ;}t$8 z#7|>3ec4^Kq|TA+j`f~J$;@M|@4j$*m7fC(!itDWcgKmUt3P1vzP_GJSYes>%B8PJ zp2GZrOB$2odM4DrA#zkFwH*b@!Jce!7(u0=vXqpFPG)^0)561Z?K+(XHfrgo2K$O$vER++xv*6GOL zVEC1;#cftQnz)$wtXH;{Jb>b)tIOW|o`6R8yGm5jm|2=Br=r#aBN$Fv*;Vz<*zsFf z!TTGYF%1PbE(@^2BUm1B5**Durl^R`yLPM@^yMtQ(P9PJ+)%}!xu)r`%QyLgjg1vC zDi>wiOYqUdwA9NM-#$2vyg2T=zWCG8Qdmsa%43A~R&JQ(t-@heYM0;6mkx?De6gc^ z(vL#GHOqv-!=s`%iR%RO>{vm|THlrZa!0aNOJqE!c-$NzfBM3YEEcjZnMnM%&qWc( zAdrDC*R}fvU**&6Exo_27Zn}IY5wF}eR>LmLulJA@m%qb91~M(_hX*FYp-Qi6OC3H za$4(+Vg&QTtaQqvRfI`J0|%@fRL*eu_0AU*N3@l6M;Oy{b4-vn{kjW+qrkUj2yp8Eb#Wv$#S`}>sas58{tFP(Vq}y zxu*HBS+dTi@+8KeQ+AZaufmND0503yw$Nv*c?KMH?!=BxUky9~mowHvR2GhTYo$*@ z6OCfJ^TaLM|NDijctT6$U#eBqyEXUKx28qY9f^fcSd4HJjwyC3PBKPrf7q^~ZK*?c zO_xmYk<*+Na<-U)T;y&(}V_I(U)I=E-QG6gQ2l3X)_(Hy@P{R zkG=24Yy!G(VF?GtlloL^dcqMKEAHhHUmm+p%j8>{OQ!q;7i;v7=gYFSwpeXfGI(?J znOmKxn>#8+J|D$jy*%QTqF}3#=j=QSGK7h8$;PvN#=^(8F}5o{ZtOWuJ|)3e>O(zV z4Af?2Ary(RD7w`1j~930bx+TQrgn1;oBRSCy;CNNrtXW?xPl_54rVRq z{BwO$k>t}JXOU;lz$kcTa1@i@pxN#YJkMC-QwbMPE({}0O=K>UGaWmv%yU(yeW$B& zhj1$5Q7N6$RBlktZ;SlpO`=^Lu4H^-Tn%_NK|~htlVRh)zPa_xNs~#N@S}#PB~9ix z*Dl)%8d}Z#x$^sHiIe0gD%szD6hEu^1+}}CQ0IqBi{@#yeTgLU zAr!3yi5r4FKbxjf{-Mr`yu>Jc!+K~Xviz@^W8@{HY+nNN(`9KGQ7xlBE&XMt{>S_% z&e_c#4+qC;hwD_%PDzpe*zK&}o03q%N5ADwjGg;4ovc$8=w4hY%>A3qAg%Jdk61@6 z;RtC9kj*>(L7)23s%zzaQe)^2LpLzvbu%xdB{Ws?PaC&dwOXDHJ^gW@DoP|>j{Nf1jkutZ#ea{_XXdrraBlYlJe3(_S zW>aq?l5TG^v@w5;1NW}yiNvfDALmX4Jq`;mqv#DzcSIytt2g9C5Yq1^0$QhD)tKOSB3JR66#^j98O(4P-fIUjKTpGarbjAI!<;hl_=C-_# z>1(r{h>YvN%j5MD*so)T?egpEd$145hGINAk=1Qazb_toi!)?sYinQeq@+=+o`&q5 zsm}I5l%6cwppGJbTN1hKP1EWQ%#1ILH;Yf*v!tkZFVpksQB!(|$9B#4X!P!<=_dE) zw)`Xd{h}(!je9;_z>Un|aCnGOKv2+R;>i|TzFs@iQ{sR2;i0XG2!}@j#;Q9*)Pd0U zp`uH!25oeucEx_iFz7E4*+v;Bu9&GBu+t|^&E(+S`*s@I=*U0r(7Y($)gFPYGn$&3 zj&DBl+O1`AobAlUc;Az))p(Y~4k~e5zx)#%`n9=jYORjjSFHK|CN@KH^Fvm>cuM|m zkBTv6T;V>{b|=`?p>E*z4(**OfLb5gxim0@Ty5kkp&S7n@a&?d?J#3935z>&s z)0uwH;BQiI{%G4oywYX=YQNrrTqZX8_e}`)nvcUUo=q^vO4v)jF4Ibr;rp+6 z&m%>mdByieiYh%GIkSosdQIZ1>qKgSChJCL6leDOe>mW&*be3v!g$yCKse6DIhQ%OYdBIz0qDMh3}kY zhV|nNKKc>naEF_1RUENdmhPRo8RISxh-_X+TQ#Bh(+;-lrB<)^_h*+A0%%i+*eM`FAUIH}jICS3l^w z$dqH7=C)FoMu<#c^sp%$PyK0=1=#5(KheZ&CUiL13|xON5@8o=MHiV%zA+MTL;c) zlGRFiSVVn6tmp2;k7o0gQLK_l%5%mp2l(}(+FI4HZAtzn+vMxozf5)p9Qurje0BCa zx4IEz!d|DZV0d_}r=d&2sb-g|^j#_Q7jTvu|Rq2g7q&F6JO0753{ zu(-I$sy|$&7$MbYrIl816l67$c#-T_GZixHe%?FZ`5YtYw;#5(Iju54c4gF^!lYH| zS^u(=v={jA)sjnEQz=rD7SZU4plmXOG`52T-@B%r+QlCfiJ72IPy*mhblF{ zI=Sqh((3U5Tva)BOO%k3a%aK0vaFwgy~(7T+kYhHQ-%xE)1`W?zl&ha>1cM%rPnTb zdS_yCs`oqs^WLQMZj>ZHaEqHLR3#)-WyHqTIF6kInlFU>uZ~*} z7>TSI;X{02k#{eqn=B`Zmy1j$R_+tcT92lyA9t_(OBYniO@thOyT!cT%9;?`wtL={W>=r5@O=MyJ?9C1*SIIGXKwn^(gIMb^jb^;t)*8UFDOS7C%8$h z05$T!!hp8;-R;v<-k7y9?e*>LGETe%*_oB*k5En*i+fTUm?J!P!rMhD_38|j2lVje zkky;LD=c&E%Jro(;MkV@X)A}Er_|nBjI!8VP{vpTcjMClCks^ z>I8E$AQSYBJ-g0ot!X~jGyMC&vntZasC9xhi(G!a3utD@$nY#^6{wZ- zNS43cT&(79qO(UKXn^cUl36o_U1w7D81kD;?r2mUM-y41In>?;75?vjw z1N~6KRb-eWcyoK_&B&}(t#N-sNS@Cy^sbcSf1`fJ$vZX}_7_1mN5R93NGZ1bB6wJJ z1XHsA_8DTFqB%#gW3X~mkEfh1hZNq|1a2}ei*WwvSPPZr&?egbyqO?(|z*VoTXl^Uv6uMdx9 zzdskDDH=(IJ{gW8hRcI-H&|j>k)n!3ohzOu!X09?*Jl56I4SnRbr(R~Y zTNIX4n;+eqxBM<=V^jI%3@GyKkEPda5jgA%Olm}+D2wNNcdXDZdCE7n9%yKPRtGKG zI~|OM-CE*+s?6?KFTv27C3A#~2ikWpOVyG+3M-Mr5qZ)N{Z5(r)7IAYOe&s-j~|?o zj-SGydfRf%>Ka>E9Ch3~#qa)4QBR(m{0;|IW+bNoPTmZUf{OBIbdp9xD5npvGZMU_qCz@))t0IbauAggjEuU z4h|d`W*rvMP>DLJyKq%asu9#ejp~s^rv+_dOCnkj*pa>Yb5D?(l}lm>zK9=)2<86sjJBF1?4MU>XL(1I8{V`4@wq~#cvt0^ zkYg~YjNNUQlpb2`gvi`o<*;6ZjSR`zn3#n<@4x&JJu+KvbM46k>ih{=2@ia&UB0D1rjeOT}S4&i8{sps!UlVKY zNj))!4b2|RkSQ`~GL;k+CDEgj2bPMP4GPF%vu0AZSH*zHX57z(6R)k!9~`N|%9F-Y z7}a~vyk@%Rl`;hvyW~Yi=Dgm8UwXu2#_YmF*xKD}%Gyi@kc#kFbeW5%GUW*`7!4X? zHF7Pss65*|j&?4)D@HH7)BpQtXhMvL=0S}n6Hr3R>LsQo1^{?(t@^LHoqM?=r-dwWwQZQ-He>1ky9rz_~x@J!IBjI^Zk_@|M30S=TGZ=PD@B> zbI`BC|Fe!Ni9r>+E5j<9|2?0Ln>|~^`?{K$5vps$JYwfVc)h{x&cW%+1TiL1zT@wJa&$84pC@sbxi%<0Y>!enxh`3y6#V zF^jT7-XMK<4`9w%UYp?V_`O32)jVKq&++&)&*M`k{QEdZcjSl zN%5*zJb0*^aR3@XYzXP%$OV*-%j;0T$h*gLLq6S@7hAQP_94tPNl=zVUy*d>VY zdoFU06NA;va6ev6f=bH>0n5}IM7eCK{BGs-Wh07o z0S{V?)+P>big9AMv(Ex%3X(GZyGC{BXw}K&ipO?r; z6l6Xei{*ywxV!+JjF^p;1ap=hi@@M6*3DRuX8}K-^Ah>{{aT1QOG~H6p6w4?-Qu5d zZS=*K-vfZpF@3VDtq?lld4?qGjW+h{DZ@6u>(ipYe>YE;tC0Elcr10)1y%g)VFup? z?7B*J#tO}~Mhj!wt?nsa6nl_f z^Xq;VJa>8G#d?`(^yvao)A>Lip8s!BX1!Wfaq$9R#b9H3D-9J*xU>ix-8T-7ayQq- zY7#vwgx+x16;2L$!l$M9qzoss=780ug9+3jzx8y1S2@+nN|HgL@iTC9f_?=vUdE?WAKfM<1?zn$o%8E7#HvrRR7K!9b~!wP zkMCAA7xkLFBA$0jCI}a-X7jhqA+UV%TDDz&H+BQp)YF3RzucjFNJO~Op6%EXw)fq! zVv`Mx%2qL|b@%-hu-2_2)&FoQ?S%INs)6&Br@lOB%FEA6@Zm`69dP|2Vm2(6(DCS} zjEOOBJZU~()&p!wW!T&Wjq!9`d(Ae8R>8SeczZvK{VL3vvF`)CyN@l}42TXQx;iz8 zxZYo1spAE@DAT#&LU=+|o1>XgP*9Vr!7tlI&6gVo0A1N^){Z=Bf0RdVLxX|JRj7Hk zFgw4}3PG5x?#gEQy&e7K@#+3F)`l6oPg>z%${e!Tzf7tuXiQVsU4_SL2ss8fjl)aB z9MFFibQ-VmGcyZMjR>o~N{`C>!W0M|QdibDr)L!L+*d2F=;L4Nyujz@ zv1v2U2G!VQ5hjrdUR(StjLtp1Wc%&nD$;uO^ay)sVZB(UJF+B`C&2ULtE*= z6a=Igj=K-b>6(l(?tVtLreSE9JX*=yP5A{sz7X@x7m7xCHI|!TR6z;;;%`$T22CFt zZW0f@)7KEGk~<4yFV`F^XsovXEm7Lf7Pq$+(rLGJkIsCuK0 zmX5A}Rd5CH{y|>;20X7{8}lGrr!&i6;^}lSzA44bJnjg?c&etdx*-5rBPvW)f6IeE z#b-@zGifxH!%pM&-&3E`Ca@HTa)dD&*MSNQ+PRa)n4z76sN;E=lfZn`>B>l8esTAoBA8H3!aW453y07<|zZQa}CEz~86&Z3);)S8i2XCe)b{)r2JtgSraHdpLNcy@4B>}&1ks8gB`lkyp@52LrQqn+R!^^;Z|v-~ zp;B80Q8n%@PWjHSXel;29)))yBU!>tBKoRueu3qTaf$XxlWu|Tay{G}PaX^uR%}oC zUki$e>urh&Ht>jLZx2594OQUQ$go=^`PEwUUI4qiZlX2-9zo@>=$1`vV{VsAX`T^_ zVuV&2W#nLzqs&_%YN(1zm;j;i$xz8h^m`?3USmkCsS$rxKH9wPi=AZqzM?T5UZpy9M6fV)ll!(w)q+e8<*LnA$?NMM}oN$ z#_FOz+R5s*hB5GHuc#w)kteiBt0Jhpb+p=Vc!$R3w-2dD4kFOA@$iH{+?H$k8XVQz zPEXIFt5MElF@ysT+$J>U_2=Q=FRrVoM#_E(`2d%u@&k~J6v@MX{;>T>NtTD?4ly6; zg-3|nZkJA3$Pb6@Kpt<&D-19A^SWov>wGYp=M{q);6VO8LW?4R5k+epugYL}fZgr+ z%{iqyPdq$t!Xzjw*AW^!K(LYD&cJN>fUhMTi1|-ZlwGpxq}{1!*8$Qt5y^^lE}8To`~p9E?Wq)Ayst?x(h8S;I}yGAGs6-Y z)n7JiXW3%&NE`yxafj3TcsLmJxFzNfjV_#w+Pg1xSJXtln_S4Y)(3GRQ6$n|m;15(rlrL+MkBsGQ$@BB`zGpky zZ63xh@mdqdQ@{o@Xk&qITvNvp6BXurb?iDD+&Hs=-q0>rR0oB5lW~1;#ncPnE{Mb9 z%z)b9CP!$5dVq;!<^i)Vpi0g2TQ8U&9Qy0;l4vUHp8==6nog%P++Y*qRwEsfFO>}o zN6y*~R1{r=>FM7dY6#hIDSXc3hmBUC*|YGgSuArFT*lMNcgvsBpFd8lJ;zk9bX1tu zKh?xQGf^>rSYOk7cnYbiu)rO%Sy|pOVsQ~Tt^uC#WIQ}PP2twMTOvv{GMIMP4r@h{ zE=`j4G@IU=AfWr1NSnhWoIb&_ZB?7Qo#uXDCoJBmeYe}7%t3LLx8si>HYgZnNAzZ?3C^LlyH@w7Io)(!`tw;n9%RrVvz|B{Bm~8MWM9hP{{1 zaN(?rdMyN3KjW2XNXgs(88*l#hMu6B9C?m5W10Z!J}z@#F+#;b{*EsL5U zwLHHnhUUZtX*kQ-j;)#b4ET3;j3LyIbzPnOEILgFFNiZdCMuv#cx7UKH{4fT>AHN5 z>`xd3tKH8~RLE<)0ssCP!*S$NHfLetn6kRtbjUBVOE)z`^j~_#RX+{kYKgS>LpPN7 z@p;~3qG+NVw14CO*`Whvd88sY#GJ;(x%kNwYwszOSS8Hpi{TLw?eB+(a9EpoebM;W z05tZ8tT(<1qm}71V;b?JbZ!M-h$BPD?M0U@WNWXYIn{JbtFn|c`Xyd7W5AGeDLApv zRm@r&^fMRKeel<@zbV$zIJ-)&$f?(#OzE#8G_2}_1#RO0KSxr<4B~eoTI{w;bs|@o zVt%9+)c-5(I_JwbGTOLudwT~>Ir^OL!cO5CEG*!X=<&uG6emnl$si&knok;bdT*@V z6g3A0=?>IUA1}xWhfIxdrrZ+?3YQwX550Jbi*Jy9^Lk1I<~K58;@@yw_8JFst&ER1d&%q9NeinSXrw}-vQRL$y|aC@wC7T#(q= zp~9*x1h|vhEc@kpU>ra*SE=c#CXKbKfDiGl6u@65E)`s&G63b7 z3<$K%Unr4=m)>K1<7#Zk?!IJDud@KLRGm4QZTLUT-2os2@eopvN~nPIU)Ns~Xl4NB z4@0*AO+&35=-ogIv&_lSQIq9*jXT6`AfnB}@}C*iu0R4J$RQ#$l90PH=G(H;(RR>~ zVw(Hu9PE;u7&w7k^vk4yONDlOxy5i{rpR^N^DMOIal2U6ONR_D4PSyb{IOH^+XR`t{>SCi$T*>**V)P+WDlpbwnq~<$8FxRQ z6mb-C&Bwp%d;eluK2Rtdn=S1Bk&iBUa5s~J;v%Jbd8WqTj>B^5qph_q0d6u^#dw4^ zD2qg7@`!Hom@oVrE@YMHDjSncc4eO8Jcye&95#~>iHamnI!YD zy2=5S`cN5OeXKWm_LS8bqVyRq2<2!42ql>!9HQ}`)+v~<7?e(7`5gRT1Pw_C3fYeo zekZa*SUr2;toZ(=spfpLPw2fQD6CqbJ z!7D~Eo7u3_bv*QK*|w4#UB`vNC?_^G^j}+PX-u&$v{EF4mc4FwTUT41$g5qRR&it% z$$2d&n0MY;E?0xBryFgS74i%6K?dFGGJIphf23nDNI+Vxt0_vJQV6O!3b9nrKCL9D zH%tays^aPe5~_G8GXVM$8wG#NLa2N?IXT(r@O?jpZGL!o(3_8+Du>g3ERt>?c?Wbj zZ^XGV6B(Bput(jE+~7Ca>on`V@@p0uVfpm2oMn*lISSJ~G&B}TE`DL=u~}i9Pk^qT zHZXsv^M?246${<)AQ)4zN*j~j>A{P4csD#_jLLQDH95%uW zuYeV>AOFJwrm-j_CZR(U8QUjXBNpv8d_x;rb(^5-NRPV$R8atp{J&W{e6oW^{5Q!I z5&!?n{EMyOt=X-#@o{{88Hm8^RhH`Vc|<{p0ymwIqlmB994U{$KYD<$~4FXn3VA zCmtRi6ay?&0j4r|S=re!9-r^eDm2RCWA_C8UX}!5SCZz+HIZRsRYbUWY<3^=O|3jT z{V4Z{g}usw2VDgEofm&qCFK_N+e}`e2`R;Fel$LR#Z+Nau+NsY5a4h%8yCD8{<7TUg%33=V-_`f}_*msBVb$Z>EtK{|m zfk*3?6cXyxtv9REt(Q_)ua}I#-5HF+O4J%JRV~ObD4?XIG?vPP6Bq9b3=CYZHz)h% z@b~-3be=e)cJ<5oTD$-ID`cif-q_f<#yS{{ESpiACDrKWU}~e&ySb@}N8-T${n;>@ zn2%#d4_{h7nTgNyy3mS-$`#yTNk~X2qnyf?r{C%%7Hs*i;SCxeaz7PbYLhJZDUt<^ z*2%vc)EG5Nd(Q6 z2aq&0H9Z}GwxA~-%9D0Z-yMxOOMlrV?mI6nS( zu!q9&A~0rVxpbgOJdgDkWU#JZ3)4M!%!?{b^cAi1bi2i6$p99?NQzEr31BkV5ESGE2bY zlAM@dhXp-Ft4h!H42;9q?smrSyg!~V8KHt{;s~9dug}ovhfAsDY%#FS1*!map@?3YX4{JemF0QfO#T_Td0*?YEQ4lPOd11Ar+DKEQ&_6ZO1Q1l)T+a`Es;5qbp*Jobg4)q1=>x%L-A z>t;HaC5O!t+e@46O4E9$_YYuU9wmCEHprl8wV}Sg-iql6x}fRD{@Pj1m8yneA`yKw zF8(SR{+%ueC4r8r_a_v12jHW`FS&2(G?rIG8}6@X+oy+mwc}7bn8V-<`UcuutZb7f zu#W;>y}nCmP-=xgp^;jz)z#J~z}S@DF&@0JcXX$s{iw1z+LnR3_q#hMDO&Q8C@AYs z@HXH!+HX``_N48w&NPg?UJZ6<<&qKKD1nVmuz0jXJG4__^9z;x<)D%hJ!XpI8$~L_ zwhxRnY;0^*pOTZ4^C>@|TSCRJ_w#*KQc{w}-`?I&0kl*vFE6o5Ru#oG5>({mx&H5O zKL#VAYZpxerg{~+HV5LTX;dwo4kk&6h#2>2VQ_V0k*MX96?EaE0vKfLT(7nVKo3LX zu>qa-Yn~3r`-d*QgrvJkkvylCYLYUnW}aGl*1Wen}a%I)#8`GaXQQFv4rGBo6v+M?>Ssnq+1 zxyZrAp`i8Ok7pvQf>b&KZnVzBQ`?7rRHNZSob{&K+JFU_2$_TNG%Q4kAS%m0VY??M zjQhNrze{ID-d|u&5X%GN{a^32i$9nDOC=TZA_r5K1_X4y^*d5Z#biA_*HGcj%=CVh z8TbhGUfdWCW3P~^Dw#I@x$V_ht3L7YB#ZXsnSd7|%o=d_^5xXCR)~@9BSG)Kc3QnR z;*{3l^o8rEMrS?+RE_Msqa%!9c7-Js78G!LTyD~<7msK1Vco;tn)U^wq9gYkQt!|a zXqIdAfDnElhm&F=P!@^)fs<*rS$2YMtQZ&=G9ZIa@Z@B*$JKUCuvVo`0P*Jz`6LEv ze(N)Eqxd&jl&8O~L>xa67_hsLTB0lv88EO_4=%fWpL^{vyNEsbaTpT~TFvTPmI_s~ zpr?8|uhmj{AY>l;j_s=LQhSk$3;C9RP&3@Z^N3@Hrlj6q?dwP+K3g4}|A|voeRyGa z8$Iuoo+)RTPbMc7`T4LhEUMD&vm76*@!!ta38{!9ZUz?iJ6SmK{ZQb~j~rqgDfV~h zAE*%b$5&gOX%*9{=+3@Gc2RIvU5Bzz*aUu(fmT(dFxf_yu`Y>=zfpRV3Q>e{E7J@ zj`*JjP^?NvZQbWFFo)>Br9xvR71YDQqV-$vb}`v-{QOx=WMJX`)D@!MT>exn-S@g3SZ3y^ zZ_E>9#}-#;)Dlv3k(9@(!94-t@^e~CiX!OH@p#jXxze8=#Z0goDE4||K2e7ae>%iy zOa9)46lD2Wup|c^gKR-o7G}b=8A2XGWvR0vMLlJvYs@HqOhhv_Wmz2N z;{(>5#_JLifX^@n5IvcS^M?>-RIAEp>o;fqnKVZ(X}owx+;pcx64CfhbrO*F_@l+X zA$}M_n@yu;hMx048Hu72KkQCJ!CnDhD-T)PpK)~7_mSewuzK`g+>qEW{-GQ=PAavaCY?fyhRIDTYerb|Gh7t*QZI)sn|nfcxrkeOw6{^{aNh zkz19)JgVI8{D@_BSssPpZ8X4*|GNLR&=7gWQrXu0G!^)~Ft(%{^0lT-tIeE>g2K@W zu;V3pw~dLZof)m~NTW91&EM0@ld-=)rdrS(Z2WIt)qK_-sk!1LKGylXmQx_DfuVxe z*1sjLODclnNoz1&`DHsfCwkSJ@~9h==84d`Emgy1&X)kadtd*ji@w)lTR=5iUXmjY zEfD#KV$S9ROmqGLSybrTrEn0g=`GwmX9LGS!2?p~OE<6g0U7^|+2zqAk%_aa#x|xe zM`17-($dP(JO55vM4CE4+6o|FNnawY33K}$?aZ(x*R!1k|1#qbL!8Y)$@Vh6XDPLu zXhGdxDVAtQ10_T$cRn{=TcI$X^%=xz^E%`?Fy|Tj{;M!=Z}A%SHRsm`#fM5CFR)x2 z0?Q})aY$U@s*#19r1J#Yz=Ve=j)=X;?;h|(%o3X6`wL|vLYJoBKY6XC3olnHVw>lh zd?e|&;}Uicd1xdk_Qx?|*&;};;Dj6Xo%P7miFD;wbE*c&E_@1Bbx!#(R0hZbKMPer5Z)m_{=LoJmfmJJ%<;Nqbim0qrLR zghyAS-kg<<1CGV?xj}rP8h6*eNO{a#i=CoU*rBidZO3Sp)}h5(ZZiQ?I8z18$Nxs) z*?%;LXgdFs+_TjDWQ{EMF#=9%G^wQaF5-mc$QWFlxn3#0CESDPYel%JA~Ar}#}h1k zAC?1Nmq<)XEbP8GvX^9nsUmB-dhJ_uoL=Z{ZE)l=N{ikgSSYU)9_Lyma`^F!YOi+g z6bQ_dzKM|>7sNI;&ucX=}M8V`ef(j*Qdf3s z&H;>XK6~@g>QjOSutWVrDJ&L3mEwrf0zp0AmosC_fQycp&@ye|n1F0036~Cysa9TyYfaSau`G6Mn1szfPe2)t%`?@tIg_t&8tmMJGpV@-+~Vr z2B7SMg@idOLLP8*Vr9DBlZdmid^2uZt@~HY(ZRh%QuNoR?x}10P%@<}|yD$-w1WBUL|6u`V zUEkwsk4C(EYbZ+98l1$JC$J~zY;(AXc^uszGB!UW^rKF3t*9=`8bADvELWFsw{b40 zBU^BtEVGcsF!hdJix74Z*e^4D=_uH;oKJY`D(S|F698>*rnh!KTF_4N5r6D6zmG$> zB443HtFsmblI(f@;*GMu_#0S%9)3-IV+Ni$W&9)?`^(@xd)@yk=*PK@8V)%QNhBYK=m1 zm6%%YmAELncpgl;(PU1$32uK+HPxOeU+C2U89c6Hs5;Vux^c1DX)cyp0)vyTi;AR0 z;5L@!>Y8QwTY4~LwarvKW^7ki5rAJw4FEgwUJgP|sn%Bh#??>(Eh{)E(?tP_F3;IGqN4tMR6|9OEo!3_7y1h^QC^Xh{GUO!9XbpoR| z|HwG&?Wt1>Q#g)|lz{aJ0kjL8Jk!B)N-GZ5CnF`MKpP%1?a$rsXMjAr)>XAf{RJrj znnk=>w%;#*3OOOk+!`Y56`FEG42W|5a9Yay4eK+C@?|Yir$Y&mLXdHDN@-?T3bk}pM+$haP>bP);N+6{AWgmj?9Jd=3hHZ0Ml7K>cNYw{OpsM7xvz} z+Uvie4WlKaE4eZ#8B02ZVln-Ln*uVHb&sFvPW4OvANJlVs;(~D*8GEeaJP*IcXxLP z?k>S0Sa5fT;BLX4jeD@50fM``yVuHp@42U{wR*Xy?rl{M)mokiu-S91J=UCk^!^Qg zi}Kxk)u9@X)q5mwk{mT^e5-iLg<3sOCjVm0ac zzJzHva#*M-X0MYvgYlgTzOC6=kzoompr-Ln6cd8PlNS9+#Y()#zkILKQJz=rPio(! z)#sA%K33MbnNoEvCwNkW%+eF2^FB;Fngl6=?gBgoxkGq77~+()0~KxKL{d&Y!Bc92 zNiP~ChJ8YvPN4;+TJsE_g)HvqkS}VA#pyF;i6T0;|5okYDDGG0UsV_tfm3PAp@*)d?R|uD)|HIb$Bv5GFICjlylG+ca(!^W zdFn`aG_U5X8A43|Fc5)kHjL?0#&^Ts_PHoGD&JwB4`w~nEr-X zm($3Z@wcERGeHDK8DT)|Kpx?9G8U(jXJR)&Xu4nJID(RXPfI_X+6s41CWw>)~??wauULGVOC)_Nt1@ z0$iR#I5^&~9h9HmK5A6)WAIq$rp>oQIg=ybumtO~CfNO9a$ZV0<=Cpw3#Va6&}waI-kXd!BuX?tV+@R(*S zMouXa>EYCV3U^i%4$n&3v6&KN5Kv}le0c8lr2DAC{L*~!4XV$Pc?4Db=df@Ro`^#r z+v)T?x}c%DwANVS>c{?%fpZ60bdvKYYV&C1_U#jbHTrY*KU;VuVU}X(c5O5U-ii$u z{L?KP(hoG4(pB|{&Xg*S9?@<@#5-(31T@mqKR7tBUk$3XK8$8t<`nK>JrjpY4E|6R zWEi}szt^oO__DJUbms9jt@63TE#EuxUD35#7d1vcTuGcfUy!E~iRf#3ff*bgaC z`&CbkLlm%Ka|LDAF%}`m^xBg#l=?86$Ld_SVBuqtpiuX2NPOrUe&;_m2ULYcV9RefH1TZ_#?jb8q&3j9uoFcDq}7t zQQR!}$JeoNQwKaKSlRobY4U(N3NkKC@3{y7A{~U1;su92Uj`Z;M%4( z&GM`?K_FQlZVMyYOxp$l!joi>u~rkUG5H`_D4n6^G+kyG{qM1N4T_Z2NdF;Z$ce>! zFs3xGgh9=9E@ydBnsi5Q7)l0$uX@0?3-gth8T1mhjwb2LjygGEn!nguZxA)z7&nZQ z!~=koKZO24vyiazMDo=P;sM?~ZsC)Cwl*3~&(!e=q0 z$CHpSC?FFN*%8@Q*;2s((!QugJWnDfF&+^ny1lu5Wl3RGNkvuF_#zbi<7GrtR9s|4 z5Y`nZ^H|^5@GvRH56%fF8HBj-*w`3w0|yR}Rij($5_xLl4GldiPi)(?TacP!`9m)1 z>vmF~DK*e9DPGR!kfD5gN)}X_vsmifrHRKXS*QLmODFEygx{b3b zk~6$@UJ8Y=E%K#p0IKNsgCpyq{y{|GYk8#8v6meGe(l&=3>%6=Sxy=7fb*;=!6o>U zmOg5c{nwUuc-pV@mgG$dP&vATIoR1P6!CdZCatziy7*hEqKTQ!=UC&Ya~i1LjjfDR zj&zJ>`+n(UsHuqh%GWWhs%YliL<&@RrF7{wz(5Jo}O*4HZ74> zcKL=9&jh{cX*zifyZ`yr=X3DD1L-qhtBi8zA&c#d zre-3Or#{n$Pv}Cv1H0=bJKf&1VQ$j|+9W}3`8JyZUkDri2)O#OF=pvfF(_psDFd(- zj=p?OgnJbEY}2I6lq*c_r3+jY!HvzsRKBo~3-ATYm;VK@uyFe1qNNyK^JXTtyIj1! zX3MjJ*#(V!74X0SZwwzDr-0Lsix9m|Hv+mX=l6Um$&qCq4dK6j5xAXhrOb&}C(f`} zmd_80!C_MDwo{$o9-n{)KdLXv7s>=AG(z-@`9;^?;g=Al43p9G$FBzmhX)5WeqiiJ-pVR^oXPB)rx?Rgi`$UgpmQV2!{bA{g^qR+z|=f4 z8%CWBz;gC9E2khNuK=o4{{Ubjj3l0k(Y>$zws9d-w35(NiaXH;Aq?VA9 zDlwb{KqOVXH?H&=oy#>p0mr|sQC@B@a&N!@an*98^HL?{1H4!8E3e-aab{efKNS>1Pk7ksz9mE_*;xEhV-D%DGTN8zS(-f;N`(gm8M z)X4nZ;RMb`^PxBFQ@;T!N8TqSLcn2xW!CpGo7n>eec6o|RVlLNaAAQvtESv_36n;r zO6J($J+lFm$3$T3@knTgiNcY&?pfWsdGPV-_WFFui-yoTt4!!E10R!+3=HM^cC}oZ zh(%Dq*|>Rd*h(rMO&moMl+Sv4DqgjW z-X4Tu_39aUEDFmvYaKqhjf|0-;x{MHe6&oetxoGArjFPu_7FoPnZxRNFTdDu>K;a( z#~*$7x|Q_AiBvUY}JTjAO1#{ICsp&lm)1d3OR7L%>Pq962# z0k&0YMmfSA;F#^EQpoh%`V-=!s4O`l@#G^V=nYF}b=}nY;XJVa=1M(NK_S|YWSTnY zSd{*bh@X-881^H{wyC}ST(!C>J-{LJc{-sqsq?d>2XJ3XB{`3BbMiS&|Gx+k z&(mbQ%K;Gd|Dgp~R~=RN?Q7Lpj2dEKCUk8{=o@rju6k{JD~>dW8aUkySlBpenu~=# zN%;Ml*0ff#N~Bw)rRW~h?91C9wJ$tJ9a6{czg3t1K|x}Sc68}AR5c~ zJ;35a%3_yTkPXT|Kju7y=uEMOTc-4b#?biuhhtK*bBgbUDh=+*XULt_=fOS>b0wv_dkOj z*4MI=X1!1PTi1u=MNFQGroiQzqGX&@*hIQYO7jC{|0o^DCnn+iAj-;?!95y_HWSUmY#4&;?#-XAPPp;5tR9bUeT<(*}#1SrJZi~#n@C; zu^hI9=lIiUOOUza0AL_5Z%Ju)Gk%Yai2}mU(B_suxfq{9dBg!zO^!Zz_pF&<+LP=qVl(MDvwsr~fq^PI{zwE?B!2;cFnG%6od~tz{ zi}~MSTuL`bOW5-!FkBQ60#Bw|>(BGCz-^+V9Qhew3ovG_)cO1*Yy7~I`kl+bWjozD zg`DMW5=4z+-{EPYWZzC0&Lsc19;imZX*!|eoyw%U_4|yYD`!6LOn1H919H502}J+=T$e;)Qm)`2lZ2nj0C*5(q9vq7E19`EXD-8OB_- z^>r+v5MPU59D@x`qunA+m41%`#5_!OwF+gFkrQw;ZOw+{@a+3-+v^LuTy6ZQu)G)6 zP4L)i?7Qi4lMp!i)5XKckh?$6S)HR>pam*ZRA5jz&|L5J+hQg7Q^OY-@z^q6sm-}P zRi(P{+PRErNzKlFvSmI%e7fSJ^`~&)nrgc*jsMO4g+iT%m^b|V5|TiXWGxVe+ zp!DE-x=n5Hp~d8C7fh$!;h2iTFkSwE69AM@pbHB6Ufcp;7Mt>u7a$t~U0fD;o}zGE zn9%ywf<*8k)dim%+wJREoKGDy*R#(T!_QKz^&m7;)4~rv?Yi39F2{d##tvtz^aEZV z%hhN#yX4_T%4|&3Kg;6OJ9`cI=JU7lqHC_GTr%Y))_#hAD3%ISp~MuxcoiZV6)lKw zFcG`~GGaZS(we`x61Qi0wzXMd3Hlx4cTHUnD5%kBqVEx)+vm3N`*^wc{ore|3*|IL z8?V+LpPd33Zij+v9|rHMv`$tADgsUV1h>HiZo)bJoo@FJJADT;725~veia5_QP6J3 zX_-pZR}VdcmbRxml{6k@@57^VwS4*56Hed<-PzL614R$kH=j>JDog@cxj3Q6sfg59l4D&EeH0LKhv9QLJQR-FH6$d~J&mEE-|o?(klI5XvEKKK zmtu(p*0&GmYFy=og~(XW_un!SkSW1zmTr}lG}Nn@&KphP@GR7y@oa*IKr{}w@wG*( zT&gF&%C!aMgH@h=8aUUM@{co%zeMD9&5YhA($eBYjuXV5wRE+|^jns$LvXUzfvU)u zEmREH3(Bf#GQy@8F~9rBE4LYy4_xg`P*Ne?V(DvQLJzDRe!`{{!ZE1IQ!|()MN!iN zbE-#SZDM_TgD&sCXkdDHr0`qvpWan40oa$;F9yg)WeW z;ZT#P|AQ&2@s^a!&WNVVvMfmazW_v{iA3p0U>Ha+l}>`ZTWy9zPCmF2QvIomC0S${W-tM{|kazGH z8H6M!!Ve8lq109pU=EcVs;f~>Vkd|&(UOKg8Vi1gb#j)hg{cqk(i{NOe`O}7or|8K z6;z;wiRk){uZ}fS@32-!LSAKp!tW&RI8FOLPXbx2pCV7;uN+${Tds){4LvnxJ6rGp z6UsNHh$xV3OG8DT-mp_!ITrAAdF$WukP^mx{`rhdut0FQSxB`ROG#63o5S58jdU_k zwEa;L`l@11y9bn;$FG13iinL6(Sp4Ky+$rTccBHONWL1iL==7toTdp{IOTDq-!&+4 z4P?F7^ET`XN`|`c5)X;XpId)&5v#-m9$zE+ZC@c3zdc%yZ*6U{JjK>UBMBlx#^H-# zL&2fd_TyIN)n-oLXm8BM5wMx{edjsmJmYuSQOn_PMQ!N0-ErDyw@t4m(#;n1!h8Kt zID9w{$=hhf>a~U-jig5{viM;`OU75^i2%I|YUK?0pGZ1f@acjxoIOgDNh%#*AIT@g zpUfh{L~b9l@?Jt{qte6OK>eXX{9bPegzEDd3}`MtYl%epTSf+05mT$ghB0FQiS76z z&i+}_TR1&YB94$R$l&{sOg<4@9haRREXpB}L9RW&NIavXW|YMI;Tjd%m&)d1#DqjD zdd2J;7mJCD8JH8tnW_r&hZV)1LSoc6Ym>+mWT1~5FtBR!>k4^Nz>tX7lb3=*jW(zU zqp|^rJQ=;*v=c=A8!LN@CkvgtLUkdOxC(Ma%V0e946&a$__=D#e z*;3g^p1s6@L;i`ITO$Sgpwz30{-<#Mj~|0#_tebeFz<8Dr&sBQTmrnJ8?f$GZ(z$I zAdEx4WtvwL_D?r%i1|DR!1nNN)(sg1NbO>TY|W6K~4a7qhHYQ4CdDQ z=5Ur}n}hT&xb`#P`9JD4$~_`)5#o#n5*e%*g8-FW2<88ESB|wzV#*ImJ-rTLIFKwU zTs*W0@}EQsBBImMH15A5l`yJ{Ya=uuQYE^8!6qi3WP;-7KwOo8y2}Qg| zSZV&Zu#)n}zo0D*Hf<8yg$=;CK?E=o(N?%wNH6LF(u@AznKX z3LOJOtdGppbQ|~w=w<-QDGp`unWgJTVWGLTZQhS=ssyXQ66Mj)lK=Em|IaS7^6{%f zIRyn(=#@ir@QeHxE9--UFUMbO%-Iqa*X@6j7Y2#;RgJ~mx-{NCd<9ZADE+BPJqR8I zxE971W)w-ONx@R$QbU7Fiy4Rjp$f}kozzF4NKDLCU1n7a{iN^!_XrIn#OJm+UT9)M zPF4tg3#>1yP+)iHkH17KV(H%Yjf;M9uqdFJsT@2@_s9K(KAG6rM;kN#dwrs-4iC+i z(uhDi-LcixZt|5nY(^E7G~tb=-U_6_sFY7_OLa#ITooyK{nQj+J91IUK8Pq^*NF>u z{tXuW&#uN_Y0>puNYdLWAi3DXcpu_a7wG=8_iRP5rOrF7hV=(eL0;|tqD&U@Sv$P~ zFEbf-0#HsDr>|e8TJC@-4%a#N0$8j;N1d+YBjUUB)=KHYfs7w=Q(e9ABlIYje!Is< zSH_oh!;B1)*}ILphI?Xu-^0_w!YcJzf1hp7+1g~DsQJ~lXK7kCZ{awT5JZIF_;Xne zT^Ybwjcl!nhfr?xA6h^}T%3^C|zo&_Dj=~dIGWkm3NONdtZV+Hwc{|iU`Moe3FEv{)wD{hN_{q2WOcL>&uZMZ@ zU(#!~9gJ!^09=RlY6(a)(FV5@0a}_E9I3F5=_7oZb$mc0^}0HtgetcEMYg5XeBL(H z-_L2Q<~rG%WY2XLNj14$!o;Z8YGrH2?Pk_}!m06TS+!eZ_oPV!0whlCovW4D)Fg`F z>gozrYz~!F;_pLDE#>v@FASu_hi|?;k@1tE^OSo+^>^cn^`Q_7Bn>f2?KdeD<*t0k z)&QQyL=HvdL~^qkM92;M_-sVdyEkHCoyDhlM+W47 zvf7?ESdOB@qx)(Ki2nFJ2*vYIWN=h2*2@q%4FJjC$cVw)@@omYU~l(&y+pFYJRH>6 z5iD7bN>z>M8Z018;DzkLR3RN&P&vdC}j=kNz}@Ae&Jo0Rtu~A0}$busWMqem-+!4Ttq7VC-|9 z^SkUmWh>g@r_!loin4k3*@i0u_y>UNfO~>tDia}EkQ}02*rt9@B-rV5kJdkWzIG2d zE%e#99i|@9VIR&{?rF5gioMfKE-<8GGXt1s2y&Z$;rnYP)+O|jRcz@{F$g7~CYpOs zN>PH?aXHvnSZE(Wp~%;;>jj{h206OmVjx<9W)%2HzQk9~Zl^r6GIsOlvEl-16O2W7 zLIE8#lFS(DAWhKqe1CKy*USm$klVU}eZdHKdG+%6RW6w{1?ndP2@v>$5*@ymtXj11 z^oGbjv4a+cd-M-0F+3y0?wjuu`i}a)V6ui;8AVJcJ72p`x>;^Z3%3X{A^%rdTNNYa zTH*R&*GxBTTJ`q#_-=sIW5;_xB*A(T7Xk4I^IJBNycd-3k*yCKgUj@C@QvR$mY~PA z>nO>4gReta@6IAF!-? z<)tk$kg=A_?+$7OhtM-l=r`gY0#fY`lU}h^<{H4e!O--^!HqVdq~mn)d#N-J6NHY^ zlu8G6D}8$xJejw=AG+8`PTw)#UokuZeBqZ7RQ9&i~2Vh@U*m z_$FP4MR*6`=|z7!<|Urea|W;qb~$KPE~*rYJgZd4^uGXjlP!895;?UmzZ=faiIs8? zNjh!|c8?-3h=R6D7{i}kpU-{*%cPhIHoIv#RM{=l2=o#0uoByP+hVg?@@6TS?3vP% zx6+J#wS>7UnKbx%IdY4#3R|$GC;$W7fr##>us;m}_o=5woWK#)QRI$@eeVdoEQ-Ks zw;ZLgL#zC@lOCnzz58nMvctoDC^7Pj=?U4{1~p3$$CdpT93IP}`vuS@elR%Nf-Z%b1^KN~sI-NWM< zlTnSCd#7{xcKHF|Ld{pHOXv~#6iT!k4!mLG<2M1Vh9pa-$7kx!mb;5OHl^H7ZZF$R zcFN}Em}TS)SF9Sj%Gs{vp3xHbZG-Ge_5Y?S2O3n>l%$e}Av4l@YcOR`<=NkwQT~V8 zz4aJn4=!&<$b}@TcP;U4IlEromywqCF9ov8w+GXEcdM{EI+0v=7R_KcdZW1D*jSUk zcKdE5KG!>RUs|07_}9Co7{2?n_Cf&@W5<)7$4=PTp&>e|BH+mb%{y3NP9VoE3xN!Xwx4wEG3%MIWo7SgofN^^3mfgC+BRz<`QNJsuv#s`QcB*5pq|J>%`+83ZI zV_=ZaE&)&hHjgC;3c{;>pT{E(`_H8x6p|G$Cwts$6CKrM>g-lp;)BQqZI-lc~;sa#GIlId{vBbac+;)+MREQTUf-P23*>W37XGj7AF?3HBA`)uhO#f zS)ckRxrwv}%=O*T6z)c^n410D!sod{5`^6C>12WfFSpkET%oSlk#qq^3+fjR%tu5^ zCGn3U1=hP)z>%wOXoa4j688X&)hU2@vEBYY#XL|YsOgNKR2>%^+n`$!>@^>|WfaM? ziH4RrHzqa?1fFS{zX@!&y8#59-d8VM?e;voQOU9<63;*N+OHg=7B2#x%-BOpIWenN z%jK8g>t_c;0ljuf^G3_V5ru(BZZV(lRRYvB`z(?T313z_j7NB9%8TNo$Wbs6^ginl zrq-~O9$YxR+mB{jW|Nki|x*V7`Gp8gq8cZ$5J*s*b?QrSyf z-EPL+lh-x`nv)@+vaZ(FR-)ZcC~p{E>_F-q6XQCcikm9VKD*CqsokzMuR|d+veo(C z_;VcgWai7o9y~j|kPOySCvuO6h{;j^XB?%o4qsy-wUfQmXP`-e<4d)JzBU-L-0sCE z;`DiPsz(wP(|3s4;e1F!Z=u*IU1dNo`F=Bt$JXz7 z21`@xexhmsqC62wnPxy)@00HM8t;37OBaY9q22K!!A!4H%XF z{DFE*uP(|$!2RT>lM+H3lAJlnfpGm+1JAZ)vOTSR{8DW5z^Gmy-V%YZE4zgX+Po{H z`{0F<>|(n-HX?g@WlEzqZe7hxhtE|RGQid4z}98s}CK1SwFB-LPCPi&|6`n{`PxGam zrPb`YPqt~!6J#!RDgeo}wCi;{X`Wngvsw`e17uh|_!e5K7Y_Ncgo$rDsdI~nGS0EF zk3Pac&*rz$6kMV|+I+=339wCWdEF2$dkZ!-`H~kW4kQ)diN-ijU<`pAmlaQ_aj*in0*YpyV>+hIeCmtM;LHRW`)O&IPNN99X6kN!ncNbF_e(!2Or~`KCX_zo);Y8J3*gJA; ze^9AR=$iY%U}IbK?T1G^;x<-m6hqj?`~8@ZfJFVS-R&{IGyMhkAM!$qK&eWBP9q~fzeyw$S9%%^I zDi9cznZf42_l9=ZO;brD{jRdiswI;=vTHQ9)^@!ys4yU|8y>zbijGM&sjmkLoG!(j z?iryybO8XBn<@b%RMz6WsVQ3jXeNYQahHf&7u6*se5;E9b~@IRZ>G#+0)`#3oRXU) zc`aknNXW&61U7Pq7Kg7(Qu3r7#cdi!8~6+`BR}J1f(Q1;B{{r=jD& z_Qz(>S-Q=dEd7cNvN#$7W$Sz0=R}3KzC}>;h^ok5B}>!__Wh# zpB_1%;!CNnhvh_ekg<#`@dB5C{}9yTAmDN2@g5+W2sDf6iUM4g{a>+A^BgbxpQV76 z`jWq)7@C0k^4%IN26NLF5=lzLx!MxYhw>MfaQ^0J#DH5K^z7bTR|oXPOTRoz6ZqU1 z*FsANxQXC-qkbnl00jOoy02No15WLZhf7Zi?eS@>#uO0CABhEX3X$wKx~dM20)LlF zKxSER(@(=|gaHppcm&g4T|(qf2VZjQhU;Awx_|)HCKo3PRMnuXzF(pOAz4HMhMpoE@(MAd$&3ja*T1ioa@*-? zV8~+0>HUL~3dNpMH6H6J2l}sOGog1ERzgPS4Lfd95PA#=I6BsA13D9k1+Ay)m_jxm zchXC~#C<%O@06H%`fr-Hu+?0z&}xghl8Zc&i8b7UT(^d*j)xY}Hq4e5EhCKhkZ~u1 z5XL%B2ZLZ|i~+SEqHeRBI`=|1U13!VOa8Vv09@UUe}H1KePY_m>?FoRfk#=TQs8C-^whv z_P~i3+8mQJPE{g|Og*>z+iar~(Pg0I?rnx!Z!P9@xPAEL5))-m`<(=!x{e4NlC)`5 z%d)Z819uFvuFL(mM9kd2Y7q``JPD&w;X_SdD*&FF(t8iEy~Ft<%VVI_uvS~X4%GAV z9;Uw#wITQ8opWhjrg4vvMVA%(S@Gbw_+v%%12zjl2ev(q^;sqHV|To9alI5M^>gp< z$hY@_iS13!dJYnR4s!pqPzD${REU0^&Xs`=s!>P;KGh`I)cAIr8Ywa4X?W!CtQPo zpWP<6DW2d8`}JBaWrFCT&1%G4L`X_%6kB-?`pB`Mc8&L?2Gd{YA$6{hKAp75BN0=( zW*bjyZT27J-Gj%BzX1fle-&q`75BF>csR(P?$;mTvbapW<0kBiz>(Nag9k``beb#n zI@;PMVlz}R*nWZHZr1a9(aJrJ0P{;2cA>!>&!jOU1OMY{ZVx-bi|!g63g}N zLiN#QDOA-TBjznmc$(zrlf6Oa4ZG@7Dt5=xVUiU2PS`P2Gr}L``fpca!35JC=@@yT zwFV_G4j|E_La7@ms?bvuLcs_Y@Me%-GQv+h{w6=4)L4ekAVwi1l<+ur>5UF1LvFCh z>QP39PEE&}u%pxGvXQyTo=J{nhHCVdCut)%&e;dF$6nm$Nu=m>OokKhmmU}qiyra@ z_cA05hszb2i>qJ~=n1!H4hkxSoqf<};(Y?K3g8nSydA-A5<6qTh)uA!bwU&WarjF= zpgL#%r|L{X;zSqV?GLET*v6@BUgq=l0HQI>DR_fd5*PnZ#Z-x=R6yy4^8g?yujBv! zvhx4eW#x`2xJ#rd=>MKZQTIk>*6cZ6empZd3zpkYW=}LL3exNI+--+<3S1J|!(ujL- z(7J>(H$N3Z3U>q;jG@JY`9EHLGT)~Geu1a#64p2D2bi3sJQ!=4=~2|~mA$!WLNw8T zib$JV#~bpv0`Y-}ZM+zwnCjn_ffjB?@Sr%{zy8-{>`?2FdZ5#Rjx9-bUO1ab0nU+& zlna;AlKZPuhw^$(UDgHSUmV)~7rd6@KRORM$&v8*KLKDAcsV*}OX_FI7#mzXye{8U zE}tdVGWjm=)=-q=Pd_wkmOP&C#303jKBt@d_ep{C-z+x$sQLxP8Pcy^XviT-`eGWYngK~pZ( zw#(^Skk#wf8Ztq&z_44fjaTMe4ju(T!1YMBoMCEa2CF$d?nmh0?J+>d5{$(fO`*fb z#63CQj$>_iC+>87^IY?GQ-nTUB@v8@jl~9vMIu1u^bg4QP5J?j$7S=}yWTfY@tw%x zj3Jm;V|d(HOG-;yctWNn=J7tetAY(d;3?H0!|w7p?p>N~M>!EfjvAa`Y_F>W*^*eM zzL>D6sun&x^kWP$wY8;S&dOp*Cmvzv+dtUPwsm!OW`93?>?6R&?pFko?eKuAJTNfm z`Hf%5=jbaySgF=)QhCeda`;Hd9WogNt298^V*9|Tv9dTgcy*>92XJ7%gOh2sadja5 zkg3#13^$KwD>Qj%X`e1Ooj>`-#KxjEe|uZupx>(>4LGmL{MgdE8WW?CVLZTSc?Up` z%txE}J#XXzvEHj*Cs9=FCl13(i{&JIaKKWt1O4vv(<6zH8ybnbyTpE&&&|dgMj8*` zL*(VzkBg4>d|-C{%*>(QQTvIXo^@AgYN{@|A_ZK_-tKZqWk$ES0v}J|6qU-f-bY4X zW<5Ll{P5(kQtLi=gZ1Hq$gu6~j~r7GuST<9TMBfV_EHsqeA-M=LBv%mKcqN5SGfi+ z*FUnPHxkx4Qza#5b@}!>ROjS`9coc)A}YE@zCTw5D-lWI_ls+5^1=m zHMBE`(r^e z2tOHEcM+IO!x8UJ=ITDHwtg-ahsSyLc58MJ@;ts*l+FZbG~StMxa41p3af~4ammcd zWM`}O$tjA^1Vo3q$mFVu#3`l!RPK7-MK51&*G~b-7 zbGXkoDNO4Kqr00yB@&U?{U&DOn1g$r9p3!>nB-0|`07LV$6UU~#%QG^)wvA~K}T-7 zjpbZ6d$K~^|A>h}eo~F5j5w5xv92`ihMmQxNn@fo5I|yw4dWlqeVFWni1l#Zsr9{+ zM~h%mX08Ez<1!kBt`2+~bTzY;?(e75%> zozU`&F{l|u;z$XDU|d~k@{}X7Mw>xqvHe>TnTZnZ*L&mI1>*T;cJU@M4?xop+j01Q z?{+z9h{^bSmE?FNgU*};-caBpX-J8pUTkcn{c<(h;O*ZVK^)N0n}v9nE5j>*_AAMP z*SiWqs`dXeAze8!_;~)D7pF3EvQSD1ctQ6Npfmd4`+vjJIIB%x<`5^QjyM_&Iz1bl zheRA4a)E|g^rLfLQ&Rz+)=G=ik1qC+K=5&Q-SpBYS__0B^o8|0LRkOp| z{M;Pv!S`;9@ev|EurxJ^?Q)yn%#YO?gRZ7J@K;v`Hb>=;&dzL?B{L~(Ih3Iz0W;_}In6~EOE2tCZr>gu zbKY!p4gFw11UEL4MnS^9gn%!O@9ba|vpayt+D@-~d{J6j3x|!Ru2y>7tMgO#^2cU7 zf#1!3Tw;(uUxxZ5lIS#Oqi$jd-1%H_F9g|7j%G6zGX6NVdmD0wy4h zr6{oY=;}N=tas_we<4EmizAtF$+0T3%bdKloo_1XIL2G!|L4Eo&W!r~(!KmqZB z#YPmt7Te)*s#)hf^DAjjM7gq(e&$!V)2qFBut~j)(0X$ecI9g8YhFZzXnBsHPsDk< zI~E%&hrQl1SY}phI9qyc<;y?Mmwh`Is-iu_>WWR7Zcn@HuGA=SZtjT&C2^+J}NVD)Q z>l%hEr(OTNSqJ!0K$_-igOA((90FoMyeAAweB}DEqBrPG5jgg)wtdd+BC4ulc)rDB z(BUOZuJ~T1XAaI>u1aT1>05nvzk1nYI66K$D#~y$E=!Zr6cgK?TQw~J7e^L@Lz?Fa z-kW9E6kxg#(f@rBEg8+4H3T^2;a;G2URD(r+BxJtKVGM9RVH=6ER{KJ^Fk9|l^sp3 zw#VhrWVe6al|{juCWuH|&}y-=+6DUM$`fWht|Jg;q%mVNB}`E%shyofT}nCpB)Fw% zoo>%}LH~AIVd>ySl^4MwjSq6UiWU}&Ul(^#aZ2RV;~pk@A*mS{#@Bsn4H>hXgRVm^ zFp#o_h$o>W{*=|{=Zok(K19D1zTa3yHQBCty)5vwukhsX-vtl0>I=aYmg%=!>`%6W zAa-@~KWWs}GGqMrccqXy>snP*YZ8g+^t2w`4TF3{Ndqwp9g6ZQp{x6Rl0FJY`^w?= z+ky78WojQZ3-SHKuj}J^dtEIZm*X|Jl?UU)ouHh~rO9-@e79`cjEs!6HNg-BoJ!5^ zw(1;4U(vmV?yw$IG2U*mHICzb;XhEK;Yh>Ni}nLjl(Q z?mvF^f6uo99*Ubrmx3*mzh(&t5&yj0h|vGg0_gwUj;0?Hgo%eD0)`a|ZZg7p(o$e9 z6(&9w2ncN@#+TNff0DUdtnWtfCP+mE2J-lNnrv@(1VNmP*Z&P}QKTQ>?Xive&ODa^ z&yT~_&D;K7{*s95{5+VW*cKk`z1Zm3uB$Dy?G<1{o%c*9PRjYiUxHCYfW41=HaYPj z_yP6m z31CV=s!B>+ar&{6t`*7jdt@oyPS3rE*Y->XosztUIeOr7byPpk-BUKVEB-PaYN=br!1wWpxUEvTtB)*3hD0CKPtw6f3(P6gM z>Gde+E$!=bPWyL5V5SN!mfZfBaf8$Hn-uXRNX82#OW3!BGv@e@qeP!z?&=;9Ea2MV z@fQB*l)Tbf|2G|2o*y1X-o-H1VBQRtE&1?k4k!na=NNL+a~jh5)zz`zuLt)}S7GCr z^tu9EfMI9o=;%h2Kvzw@LQjKUxk1*0L18=$D5JL*o~P}m=bydLR_=ja11ot&RZ)2O zF!J)9VW%&bpx|1uk?*JX-sC85Bdt6Hj-2twlAh&f;8l3FACuwC&DjT(3qQ~&EfQOs&ZIxqVgqJn&^mVA{E z8yzX=^G0h17bO`QX_cR6h)U(;3sCyV$y^)3XwW#C2_`ZVv5#zP{#V6Ox96)Oq`||9 zl_?a_;Ii1j51*a#nBb`OyWG5(HFKb{(fZ~L5NL(I+E36h zQwxtLi93JK(7CMp$NTvBaIQw(126)$qhuZYE;nwF1e40>x|4Ky+=E2rCiy#+D>cB8 zRec$?FKB<)y|^a0b1y^@8R4aST92DueG7WcAS&q1rh?MW{J$APiDn$C;9<^ z=u%sdrBLi;X@*Y2gX%^9x0*n_-|s0C8o9mRMqVgwNcg>N&CCG#E&;mXeQIVF3+^%h z(Lq<{|K#^@>>nBeSe$Qt#Wo_nptTwwG0}C^xZ%kjzhzlomzzd*zMhYv>&yOt;X?X_ z%}wk4?39D!&?G50u(Ip-WL7)t!~Ny#QIjjJL7~F_+p;^6_+G6Ll|?htOsVm`b^P_dq6LZM!kvH{m`V2+ktBBw_Ctcg7oOq2Mp`;i+wk2rB%?EojaPc z3Hkr>;vHCqqb7fWN#SPi<3%YGT#*Rfp70$g)gjSN9x9&!W|Twr(0Gzi z;P?-u{QgbU{dbRnuUi$6_-s1+!^FtQ*zJ=O91Inn0SpF>W3&TsyLrXMArL^;mk4oz zJijo@*y=5jBdLTzxIh|2J(+6okwk#U=j>|Dj?UID@kiFprO$G~YK>!fJPI;$kUW?1y7uLRF5Sm($$>CoYv^>JjJR*71JLzwU=|AkTQI-RUCvH&@s9I~MRDM0gt8 znWtMn1D=zs`CvS0Os1o&rfifZ%=ZUXovG2~q5kUksIg3Fk?_0(9 z-`^ROt7fLBUv}~pVBM+%v5n9?Z~oH~Ko3m9gAgEz0J{HVn26(jpdP%0^e-wz`on|DxFHZia~&% zo$^V24D9`hes9e9SvR-3wh0&qz<`ZPc?e{y9wscTJKTPv&_HbQX}P?+46X`x^2WZs zHXo_eVX8E-QHEq;J+|Kw2h4LiOdSC!?_yzalIdGPNH%ncPl>bvrpj|eCyqg^5$AZfy7gVF3OEHU#)(HBkLqM0mjVp&L0#`$ssC2f0+X2S{ zzXE|x1(%>N+a9gns8f;!lYZ-E^8K;MYrB}Umz!OtuK=DE66oEvUNMpIGMCxWGIWFs5Y6sSsg0v$r=EOm7NK-1XFEZjkh zM49G`vbeYzctoZ_qI$Uzas9)G0IBakfw6H|=v`SrT!u~C9*E0;+*n}W3IVs1p&IRML*#^-p1gQXgPN(mujaC59f={MbH=u4IT<-QXMkgF*lM~qC69fDlu;@+_wn8j zan*hW4eLmkD-<<7shAuX0j0hOG`d2Qn2A3Y<|&SkjN{LvVWxdgs&UbvkN9b!woHy>-T(xN?8_e<|H>TP~3zD zwGI9Qt;QdZl{8R69OvHsI9cQ<*maiuBaIbkb?*|qq3fG`#*?# z>!3K_Fk3JQ34suTySrPk;6Z|0a3@IchTsmt-Q5W;!QF!gcZcBa(75fJ-|SS)t)1PG zn!ER3s*9Gd`+J{ro+AToOGcD82&xkCFibXQ*UPVj#CtNyzfxjjO2?D&g?xnTgNw}> zd|3fzf-Km3Ppu*>^yOTiA zjGbMzbQt0!bcXzY0GgS#JjuiXY$pGB7$2Dd|8Ejc-rp@ioDA*c#p~l5D$>Ji33X+K zevfzoKY|*G6-+1nU}&h}nN9Rb;Lgsh8jq$eco$V`hj=+<#Ret?rL={3Qr_<91j2lz z8^*niP0mWv79xh#nS^E%sB2=tx{VGVKLJDIgoU4;SfE0!&LHu|ohax!>aS1a=TI2S zAc#8#SgnGcFHIV+ip=+ZW^8IIJV@Cb)}rR+t0;%ivcJX<5nWXtm6lzjDb!d1D#NeP zgvg2E%=qJf|M$!p>bFQWkDX8O5!csDt4T3W*pJ)Q-mlIcxSAspZFjC4N}ApQ=;7G= z$3S29f5|;Loen1aS1v$pa%!y4(pKS_kffNaNCptwJd>M zta4?Zc}#nwjh`Ph;wrGw@f!is>mAW~3G2VnmzG^*o@5r+Kdjz-G`%FIz}NX2O080# znW$51w9s8#*99GYT!LO)Jf_u1Yq4>%+Lw<^bDcR}-z|bD0wA1!&o(OdPUJ7R1J(l-%q=MutD4%% zotdhZYDOppCFSL9$sJzZVZae|XOi@5S~4xuvp?=DBAdavfZ>g9XIf9h)PUU19%o{ z{{1Zm(^}|DbgC)tPb(owUs<`_)_51$rlzcx9eW*PVA&PY7-1 zKRZ3|b<}A}Jv{{lvL!87Cl%niY%1p^gTuq;07lBJe!nvFYfkV5!3PqO=e4M31GJxL z-3O&*P9FH_d8fF$2d{l!Cd$%HAI>%$tCg5x8P<{M&b*RlcUGqryVWy9-%>qww_0A(Ax9$K z=`lbNPa7i`#3C*?A*Dy!9K;EK8KohK`QWlg+S<2a8(a_bF(qP>?Mt!a%m+_P8CVE8_&?IvKHYRsrja?X|K%iXbveWvzi( z4JyP&zg8qrSsv0Qe3c*m&bfO~^$$N@9g)+<>EM11Q)o7KKS|qi@8d|r7Y~tXzVy~# zSs{uZ;C4p=;)hWGR#wKp@6jr9`T-+00{XXpPzdh6VbH9Skypd5E#ry%OXDmM6HW?>{#NVi2-T74&H0mCC=jkV|Mf z5O#dSLv=+;>(5}SYi-p(OrvFk>^=|YP^$eXXh zz(d9)_`elx8!in<0RCl*QOh16ssYt9A8(=5H(O=O*$NptY0@&Gz~}Kf8bFHc!tH8x zshq#LKx^l}A9jlNTmT9?+HlERFXPbQzj|S@PA3wbQ9w?Q!pXx}(4W%*}1omDp#CRRT!V4VYyJ_jd-KOQak37pOd( zOod86{-#HfT$jndmM?P{pEL!N8>V%NPj_C>@ho8{fAbc=!MyvzjUz_Q5?Ny<28sqh^!rmTk0c_r9}QFgKGzP6oeVNz_4Q7F-|I(YVuXKm8{FLUpINK{ zk5BDIyt8NW&*-#kX5QVU0C;7IuCA_K6Hft&_v|buNN@jM>mX10#KNG~eC2W97rgD zBlHUFY{bL{CTBm&c*>AYkb|K6$pASkwEwR2=*RTkvXX?j^xMs4OZc0l(ecUAu`zIq z>o+2;YFqLb6MgOHtC@tiziYC8x=HSP4>D<}y#6&uPMng73jY5!L#~4S|B)dlittxo zL*nt$6Hx{QylcKlZ^!o4pdd59=&9(O(W|IHqJIpv^NZM>TK`-hY|V*@zG@a8q2Hba z+S-SSYBff`RHWpQO?$7C|NeHM_B94mDV8e#LoD~ylYEo?)!1CfjE+kSJVM0p3?|3J zJ-}SjpY<;oA8a@);DEWrGvdH=W5aKV=bf2}$^G5cDE?eYRNK? zdQ&`Nq*|3JXP4!b7h0Qx6%cp5Px%=_(E{~A!@xLP+lVY8d|o!wdNOd*V7n~bZ!uQS z(aH%Ch}@(7cGRW3wic~3hKh%G_v>L7SQ1yUg~Ym~)kMo{-^^}X+f-j6!TBOmI3s6HU^3{Ltief+Yl#arvddSkJuBVpi`2R-i&glO3Pv zjSUU8Qh*AgU$umKNf(G{b4y9a29t@^N5DCiM`R*=>j$A>#cHJ@=b|<5>q&bWa3@Pq zvC(ag&Mu%*`cAT{s#w-LjqG%wy_MTei^MsS)eTs6^?x1h^dX36(~3m-maXj+hFmkQ ztpRaC>vKRC0fbp=HT7+2s|7gW=rxN1_uvu&v87OB$tngOOyO3Aw$bhZidToQ3|7C|3ow`Ge9i>89P z%9`DoPp*EivH!@5ml;k^bT5t5l!8`)n7ZM`$0+hNc&Nh697NbjftC7c$ z|HfHcT>G9zt1z1X<+&@1Bt=$PK0@c4b$z^ABB!&1+@PS(z+1Z}htVJZogBEc%M??3 zOluTtG}IhGTgvI!2PZ)p-czM#^EQZx|cha1(mpKpi=TrTAj(oMatFL zR^L>nPS~=?VODOglj9-a)q(e#%l0w2ciouFW>%$CEpM4A&31E;Q5o-q(d5vdV8-%K zgX;(%GqqE9mT4GX&Y4F&@TT8{%m5<>_lh<#?e3HL45(@C&JYbtYc%S7H`PI~z>&fZ zvFMi^HyeyvH*S35CjIIRlYC#+dOP_N}A*x8EIeXqxO+ z#6~*xZUjx2D`N)L4O+XXGI&##3$z!GMa`$DDO`>>4I!%5qh>P&ymnu#OtTW~9C&d| z)4c8W>KqI4aWLX4i&_>`Vwp6Bh&K@WxFuYUZi*!K)7L`uz5ZGeQ(L~-Z|6~f6jb?Q z2kqCs0d#*%5!D;)x7$Iz{7hLY8Wz?}p6%1$JV$ds-&V&fr^e%zATrmPt-&8oO#Q%O z_*Z;Rn*sR++@mUG%Zzzf2LcWovvUmln19o@Lcp#?2v$6w#k3^4os(`zx6)`YwEOfl zW01f6X*5XJ1CN3s{e%1SjBTc7QN-f}i;JDaL|{T}yZWWAr3JG2fPe4Zu{KqaC^t{3 zq(=Tq)kS`A?$=}il<0SWFS~(&vwU8d47) zUeOv|-OBZm+L99-21$6Mud8cntegCe5D#V^Zv9}gHqWL7R={ql2xpZ z-_xmm=G>)-GP*ZrTfZ)q&9duZfA;`Z{9n0%UTwNq|HE=OfPGZ0jdDQBmA?IHOi@s* ztij$)A!A9%NQ$u~sCw@x8%mj^`}{L9F-RM2zx`b>7jqPdthhzIwLPnTRlqT~)gMO_ z1z>5EknE@*$j!?f`mNPssoC!jS*jrF1zrNr@+f6sFX@!|#+&ztV?{sb~^@$g=6#ZPPM_Xn{nF>&*&It($I_>YC7^+Od#lg+FpHlgn zXH{oj7bn*9ya)H)OgCL{9}4JJo+;Ns97zbCLj+8GAO!;L)lu9`3e@rb6iv=)LJjyu zU=gU(6eDFHP{DpsD}Ql+H>Nkoeh2P`UY%9~6%JJ{rI7heqn$;N4wb`OK^Auhg*x;y z(>8S0508ANn2l(bD`9(6U8FDQyvGxq&-C;c0KjQ;+vPL-SY}AqQ7=Dfm1rmmHXtGJ zAOKEWLCBjl5DghQ@E91>*KPMNePqnH;CG{cvY$WW#q1es5QD4p#LMCSJ&Z z6jdhF6P#Dwb~Z*Zw+>BDquDY8qH1rIOX=XfD&9Z$ptb!%>&Vi3;Av2Z)If&bLrDm0V=3KRI5{;;2#6P)Mj!waDNLl(X#H{?o-a#S9kYMo*yG${lO$9 z*8h#~Xf?|-cQ_!P0R|m4I!+)7XVW6U#H6I`f(4-by5cD&9M^mtr}R z9(ddw4?Tfj&^@;;KP{@_E~%om)jh}F@_AAQJ-M3*`FR?m(Bm$jyjh;FFGLZcqz?oM z;!ohS7C;SjW6}V)_|)^=&ChH}@mmm(&_1*a7P{D2kx-W`oXv(7J6DAdvzkw%HO2Airc+eo-9gzKC2QI^_m z^3DAeW;60Hi9xm`0-o{JV>aAR{fcOtS=ZhpVX!`Xj%9iYZHv){UYMz3pr2;LoZybq zb)6Ksw=Oa}D+O$zFchf|DFd|)J-u6ZGQ-Zcz68`38zE4*eGjD$PHqFdWmNQbEFaWQ z2<=?awCW#R^>4$TgJR2ljzgg=;f1{2w@+UqN3ZlCP0(Iyevt80yp8L58#n=-le&F} z>+>zz4l0|`5^BQPf6U{AAA&KE(Ba6<6V5zw@;T=@$#C{U3h7(>|!>=v+=*XDyhX8{htcH-^ zCF^zq7|YFUAH-aP$onCBMJa$61(W5^_Y1 zb@Mxr3L9@v8Ndj~jwj}OBABWonH6oqvG$?ZxMLLN56FJN67{b60a zUH+-nGebkcd0_moIKQZ-s;a50s;Q|7%sBTuU)(@geOJUvSv$XiZiMe(G|C)j9nEynavJ((6C>p@9Kd=W$gTx!S&qV*dV5$GYXZQc{P(WF&Y@&e| z_d9=MSdYYwAyp$9nUrj&{{OHZ_20Z?Lvjh=@asQTK*{(tFb#OD3{;39pKMygY|}EF z>DcTnH6X>078^9!AfuT&h%!S&({Ij^oa)@B@&JT!a&7~B)Nm4OlaKqK#+u@(VnuBr z#{_5(V^31yeMd(}#>)A@tDGX!>_%H7X=D!((8iilx9?~5w?*}&jhHe z`=Oyqc-?_zv^?D=Ycc7&yVoD-Wz!qva}^pu+)Yr@j~{w+=_RKZt~~3@6-9LEE#Gpr zXFN=R5Du7(-FVY^ms_sne>D-aoUc)EnoLAJ;DKQ{hzlgQ>a>~WEA@pW=v=2ZeY-em zMVwZNSKwDN+D;cH>y_>h?8$0P*Ga()`y|2be(OyxF`HT-)?mAtLx{rOw{gO{m_*Qo zWI0!%s`XR8G&b?O7xCo{ElBlNWJu&IR2iaGYX-u{ag6_JWlEY$;#By|M_huWxGrp>m1B z53!lr0>MG8Rx>hv&9J>0i(=?{KpwXKW?yiHs1!co;qP`2OmdF+ZGd=M6vz2>}DD4lfXdKS7b&F{X^!8d^ z-fxQYIzh45ya_P~QGz}ZXfLfqBJ=URUhGr0+R`1X1=Z2K?w4yPV~Rk4y7N>#ZD~4D zbQ-zr0!%jG8&Ml3_2nz^nANDswWRp$W`Bk2otZGq1F+&HUo5m^32#+lmHjLcn3KG# z9m`ZWApvd56AFG@i9hh69ht3||KeX1=)a*|ex$Nu|IzIQ( zc10AeH=JG3O=kN^205jh_vhA=Zhxa$=e!M6GI|*J_*?(V1^8IZ)n4sXup(^9svNf9 z^mccDo+MjQ8WoHs$EF-5BS+4%aj-$AprK~|FxMDI7mtBPP4*QuBTy6?QHimjphK-c znJjvdQ5`QfJoRidz)FzCMkD?S@S`Yh)@w=byM%MZ6_3vRhRP%q{ihYN-a~QKrbFJ3 zg#sDeXnEHh9&QQ7gc`oxB$G>wv9R#BdYG03K7MBmlTD`wO)2f0y8?!9H$=tpoNVFX zNxmbx3-%Je*I!(GMQ1Gg&?Iu&p*zDNxXaw}vh#ICTpQKn@goe9Z(VO_n# zl6go(h@82w5oMl&MzBs&N{U31i)p|@URZR&kE&OrJt*t(@7&th%gE>cRTzbQ2 z%1LN6%30JF5?vAD>AZI%%Ve_YvS;(j97S}OY%7%18 zu+2dB09WPuq|V9XGC% zv|W+NoI<}@WO!vWrq4gvLlj>%*6Lk&YalNCz=3<_+zLhYQ70`I%Yinb!-o5Y>(B;g zCsl|s+AHE=PEJbOE`e%!)QbY63&}K|YI?<@Yr3+TFii)knsT6To^OSm!^arEx^C-? zT$cDsEFmV=B>0g0g2XJQZxw%MZ3reEW-{q=H9Aa-qa93&mtsg zKAYKT-_hQ|D_2oqNF@t^M3f$0TI%}gd)s_L(EfaVR{KdrbgAV^oc(ot;18Yg*=FpA znrr6U%iFLBrGuU!9`CpHwjCFXIm)Ra;DWJZ5n3U9S$lUvr|aQw{@KL8C^&S=b<3EQ0W^ z1@W7;gT)xzMfr~L%=`C}E@#xdy!ieR;E>_8Tw1Dx)R|FW$Lx)kc=}c5A|HIj=RDCq zk;+AF@9j%px}=-O#KDE>V1sTHhUkCdjH^=p9|B?*6yKt29s`+fy;TrYJqgv;c?Jn zy>0DV*0(;!Ao?u$!FjO0a4ifvqm#Bhm?-}{H&YFkQKxV16D)LJJy-I^uITnaM7C&qe8`z&qIocC+8VS09LlPbgNmh=10aol1iSao^*iUmkpq z*nfyRQ8Xl1njlN%1==Z;Kz#XAb~Z@A(R96WR?I7M@FN-Tdr{(z0n_m!9@saLvn}>t zPxbv?3cZK?6=ZG(m&k^F3LK399zrgVF8Yv?*G+5`3gqez;Ojg_o__K6> zg(Uo0%PuEH+@F#*ua1rUn`PYk3=PfTE&bl!9w6eDOYJ8(81SBcF}v~@CEL*3AvdGxrr&c3EV~iMGOTE$>%_+QOTUsPw(*- z7rq6cq1LRuVn8Gj)MV9(>4%a9BYs~AnKGJEy#I0o69v!Rv4V0FzB1p5K^;l- z%08Ezqe;@pV@qLPJGCXsym>t~S-F z`F4eDRm^ZYQxa7CAx{XLSW1SfecN5*%fQXG<(f}QYq_ADdrWUzXN7c@)L(bmFxCc? zHEY!G>-2ca^wc%sN~mO|$HkTgZ4lwteA#Yc<qPxY^ni>8U3n<%X2x z`neEaeI<5c_s-*%8yqChu3{odQTy1Rq(c1ZBolNqK)+&)h~D|-X@ zh){E$%biO_IlW>~8~rvUP^Nezimq%_HH2F&bXNm+JZ7nbIiaS)D?ProRAm{{Zww-D zG`Tjgqdn|AWUGnCv~c(BB=vlJZ-R4Cq&2>lQUp;*o;gBYRw^4*_a1Xy;kQ|GUmD)_ zXudiagsq`**exANq)_duAx2Jn9t=y;nn zd+o$_4EfUaOMP3oL;roNBWcWxj&AEQ$-I%d9`#qsg(1u-{7C1$9&@*4mjj}E{yYyq zUJaUb`SiL6%l1Vhmw63PA}XX9WdN}}>7c5%-gNt#3SsJnCIDCi395B5d?;VPWIo5~j54_8|qiL`dfG4L;Xgy3!T_ zC7e_b8am=w6~W&lsRPHdP?X2uHI-^I+JGJ0F4aluZAhq3_o_*P4Ac=f>_gxJlgrO~ zmxbh4J(tu~7hMyl#idigk9uXecw01o%hCCZXKY`R=^1b z4zYjb55-}&f6v&QjEx#@krCyBOe9l4Uy^2-9%-7=8^sCQ%OVKcfL+l#T;~aNXy(B< z)#r?(Fcv8b77bRQy_#kWLiZM@V(wb!%JI+;4>2r|fbGuhQ7iA`2I=ID~?@bmQW{&Ev)Xkrz zv4?u>hDCZTSU1lR{`1tdw6w2Y?pLW#b7?eF4_qh6YHLmJ~u*$NmA7m}3 zm-J7Is?u0S&i=yVAw>$K#O!Za zzb{)FezbIDV{BRAyfYJwi2eCu5xQ9EbIV6uZezccmCVZ%)s_#5Gr5*pcXegF+g#jD zWD9-G@~i73yfE#<$kvzahnm2LG!DyYHKQ%F3;R=J{mnd0wV zoM^e&##%krjy6k1cRA^g@$PSw-h`2Em1T<4VVC8dI`@gtdXwMEl0A zuHW(IaLH?1e?s?W>w^m^3uom)Nwu6|`^Ga}M?7m7a+Dr^b~lGB!hMouWN>)oIsc|^Ib$0Cwy9{XGr=IXPn|f+_c)?mV4|5n{TM~<%nCVvD=13cbK51AF z=ysN6y$taV%+GRCQmVlSlL@e8PR#c<)m4* z2P1dxdgACjdc*gLlP5l{3XA@DI-K~F(N#Y^DjtxC4;f*(}9 zsve0@Up!$;z+byv-f9!!sTo$?#BXKay>aT?^Q}CaHWg<3Quts}!uNK);+SMD0%o>vPt2nd6u(^% zRW*H)L?{z}`-X6Td2cD-T&dlQD!@5=4GkkE_yNG{6kUaf%Yv;n48O2b+GNh*<)J>_ z%($hsU4qK<;0n});znG^P=@wJ5wFb0G&~d^3C4$yHNla!!+4k4O;I*jiZMRk+7(+D zg#-sBLtE}HA1JcFgdWwst`fcevc<^4=Xn?P(!cyXUx zeC)Jx$0jonRWSGxtE)zOuYLW*NRt4c>Q=(1pZ1uRl-6@~`qL)nn&esR21_}{-YDAf zkuaA1u`yZlT=A>jB6;kDv&d&*-}P$9$skO{TA3Q(K`4_r9$D!e=jUC7PNbrgG8wmq zU413HB4bv%*lkjS(ehXa!XKTC%n`V+g(DIS^|dsH!xbREBEL;dOBJkm@KWXY$5lQN zsJ=e0`N2ZPl&`NfSC&11fHn^wt)i!|L@S^DW%QSfl1h8Fu)KRTPFxapRn;Hy$qtaP zC2!d^hBt+Ff6Nkr8>10O9=f{O^YumkmqJ3NoyV(!(}J|*R|*n5%k8bGQzZ9o*6}5$ zg*B|PCW?JIKby0fe=hni_vJm&7)(~xP|4``Hlq}6p4YFobx;4Z;r^7(cw)PeQC>=2fE7a6FUeem)vYyNyN@HkYX7WV=8tI4dtNJb42e{0 z*0b*~u&OoFY?<8$(5ZwhsBu<6?Hut0%rawq2ug!pU5^SS+6524T>znnT&vbZo8#|w zH2-xob@jO(flICMAgSh}*{k^qrX&seruUcLG+kgzlS-VhA%O zJeT?pv8SD*y@H)BegkEAj$naf)xL$e>g|ET7H#&-nZJou{zrLETGsdEiQ5g3%OXKpy8PHkcRv9KEjgDnlLOZgQ@>94$ja6!1mBHSoXcWoBS%d!|f9CuQq*uVX>dMo&LE$K@Cj zQk>rQt7rbrK$G*UDS_&GubAwXk0J`n+fhnt)mOi)W4#(*)rnDvw-Fw8WUV~}$dUSg zQ-qL8Xo*)CItXPcM)#zAdY5r&fqFE_* zF&>ZZV$isH&7eMNq#)&!cZY7wy0v@q-1p2 zRt!Z{9Dh$gG&M4qNR1q2D88Q^?Q?haQH+Ln&BR3%lUByoSf>5u+*Cc@Z?c@e3As?D zUG&UlY>8^BH4}XWvzcKpE2d;)z0yP5)gviPe!P`q`@`FzS#$Wb`MWmWCy7BQLZk3E zMi*0+FPg_2u}~N>QWjc^qiJbkQW};Wi@Lh#_Y3trZ$w0{w1ecV?Q2mU89jdZ{`>dB z|Ku%m59$OGN*I^QO#^0Yt7;sqRyj=XPx{uy0t37)ptQ8K^8s&V#tD><4k?)U&nM9z zWKQAh8li*?wVO8Twwwu<&pi-y6F0ZUp@tg`QD{bcb!^IoYuOQSB4J7`UjC)E}x_e(;@P!1dDh@9OFaOS+fdcWB{uAbRW=uv%_OsdL(`lwA^Y zdVQI8I@pm&Hv>gVOOAhprp|mzh=1f0lS{7QxzDWEX`}P)?lQHlD3;|D)u)={YN)^H z8CpQg8*WF1ysa$X+_&-|-x+SGysw&q@fSE+U1%AJ>{D|-bm{OJ!Lr7z-F}Aab9;3* zMnLH%w$s{nKLlDr#y%7&@OPB=Q7#e+A0C}yybQSQ&XI^lBP@iU-COE>4?-Cn;U-!nBB~5B$Fiz?Hn9F z?yXiDO`WyFxa>Omp`i7|t(CSut=4sPWML4sSo5u7>dP+XDat?dkhSK$xF4{xLRtzb zZsiB*YGvBtt=#T=*RM0^MIpbn*c$CDJ=qzbryS1K95>_>dG0XfH%mXIkhs`Q$}tsI zS3`fF7GUVQ1vn@g_i~i*jh#SE!u6z}bAjcM{aVO%ex{Ufc5ikhSxgTiTJ=({EATKb z=R>}{^u=xP$f&KIz7z7CtJu}OysWJc=G8dcYqq6w2*cxhsT%d7uhCY{#gc0kz9$2fq>W*@b$KYb7Ap5 zx(M2QsZFlkjP4T-EBbNuu7-x$XmX{$DUI17vCMHl^AaM=4eYWKoZCsJvf-B#L_}1U z#G=uOOkgJ>a9@pb8XH}-x`#mvN%lqb02%1x*`!h!>??{oSiRMbViGhdXy?|}cc z<*@9#vSz47MmouwvXW<=<+9I_v|GmzZGJUmcPvXYf!OY+e7NcUb{Jt~Zf=7|0fmjd zH71^#U-!{~RN0Rc67*%1^z z?!8q3LRL%cWMy?6$A_N5xw5smr&-^qk&*PHl`otZg;;bWU13B#Z=B{6_;45-_|K)n671U{dHfB2b;|izR8;(zZ&p-{YceCGfh%FFo&di7w5cw1} zKPYX{wU-Ci9YtI;nfTm7|Le{D0ZuzX4H0h9Su?D_vo88WGKUBScEU$c) zdyC73IB_qy!EUw4C5bgj@e9s%&wylM6Q&l ztNQ^jH>Tw-B6IolaXbNwSD?6`14s?g@bqi$jw|Y_mKvN9DFIS;aT7*`fk#d0dTo@qCzZmJ&-@kYZF`~WwB2P|ZNJ)VUklB)=f&y*AlrFitMq=LAEqDBg%16FoDgM95}e57teywrg~en9vySl7?-O2BGrH)^ ztSnNhGWl$p2@}bIe!7>WW(Um65jX4&i(TW3lfO=rbxJ;=qC~A;??V0~4EgVTZe5w{ zZGfEn95qn3gvuugK9UWaBrPNTuOt;^OIui&#+w@p>M3-a?*`3u)F-VsBdog?)*mIkw zw+;deekf8KQsDXwe}~9tW{!v7umhYamK$mMmS^dwpqGM*PWz1q>9{a4_H~7bhfB(T zZD>@;UzShdca3sddEv@~CvY6UF8Yp5HD#$e4cc>;v0ry;=jeVOH}@}aGLZ|Sb;U>k z0{n=1|xc3cvmxJqREU&i!FACc!%Qsz3qom^NRdWmxr zI$Q31Psc_gO=Q#!x;w2C7%jFj-79DVAgSW|qs&kGyNf+i| ze=*{Ugx~wMqd-vj^(FeTvX)jQ-@!9nOU7Y9wiFibivt6_=WWob?!!4&Sl(p&AJMi} z+ko0CW7*O^LVk_L%(GvIlb{LjPrW@A8LKA5D3}%lms-5$oB3s*YZ-C*^nK;m&S~aj z4njf(Eqj6Q-P=SAsDU7%-L4fr4a-kx^?1VNV@7EKcYr?;=3AeJ+MEqG!3BG6kfZ?X zV?xAZUs_O5FOn_DQ*Y1&NP_IBS$K|=3a-iAYM^p| zD0mE{WATZPP7e3a_2W{I)+#Kcut$RDb~&TROYz2^cdhkOG2twuDUF8HH| zwL{xqAsUOhx|8pkOO$9fitUL)(tPHF&6Arr?8~bJnMtmZApsE?J+W%{U?GKTUZ3J2xvZ9MbTw zsvNh+q%QjC=-jt=*3!^2>eSjOmkGw)bH8(Pc+3Jv8n4Ab0V`JCklR?kds};U`t^NE z&DXDA!7-#}@7|o#DJD0ReCGmwHWw)^50Cxq0*{QfU`9i$-Cnu1*M)U_^Rp6X9I{s3 zaMS1`VPy0bXlH5O?=40wm!St1=oL-qjL#H%rZU^VI}@iYW_(ko)xx+n=4!=o&q~Wn zUJt`9^Q3jY@1vPT<;QzwcIdn{J8ac9dfCuH7OvHdPKNxsQz<{nZgs>24J}4az@thy zQz-=^=lBsO+#Z3QwOejXO0tXFXZ|TnD1Dwim9A z0^W_ZJ+1`Z<7p33nrMT7cf<0R-?k+sr*7H4JLbwYTK_GNm3q|h0cb3Fd%0gw|6?akqdn)DX;>aP7WvDDZMcXlG4XGzQpLo^ z1$G(o-2BB@)6U00000NkvXX Hu0mjfq>c;; diff --git a/docs/how-to/view-packages.md b/docs/how-to/view-packages.md index b9ce5e4..f124526 100644 --- a/docs/how-to/view-packages.md +++ b/docs/how-to/view-packages.md @@ -39,6 +39,13 @@ running the API, load `examples/end-to-end-release-evidence/sample-customer-package-manifest.json` or press **Load bundled demo** in the viewer. +The top **Reviewer Dossier** is the quickest read-only path through a package. +It summarizes package scope, package verification status, SBOM metadata, CVE +decision status, approver or approval context, linked evidence, limitations, and +the offline `evydence package verify` command. The browser does not verify the +package bytes itself; use the CLI verifier before relying on a manifest or ZIP +archive. + Before sharing or reviewing a package, use the offline verifier for hash, structure, archive metadata, and optional evidence-bundle signature checks: @@ -81,15 +88,18 @@ The sample reviewer journey is: 1. Read the release summary to confirm product, release, package scope, artifact digests, and readiness result. -2. Inspect vulnerability and VEX decisions to see the recorded status, +2. Use the reviewer dossier to confirm read-only package scope, package + verification status, linked evidence, limitations, and the offline + verification command. +3. Inspect vulnerability and VEX decisions to see the recorded status, impact/action statement, approval context, and whether the decision is customer-visible. -3. Review evidence contents to confirm which SBOM, scan, VEX, release bundle, +4. Review evidence contents to confirm which SBOM, scan, VEX, release bundle, approval, exception, and redaction metadata are included. -4. Check verification status before relying on package bytes for review. -5. Read gaps for missing evidence, stale evidence, unhandled findings, and +5. Check verification status before relying on package bytes for review. +6. Read gaps for missing evidence, stale evidence, unhandled findings, and exceptions that did not unblock readiness. -6. Read assumptions and limitations before using the package in a customer or +7. Read assumptions and limitations before using the package in a customer or internal review. Use it for: diff --git a/site/package-viewer/index.html b/site/package-viewer/index.html index af0b82b..be12fc1 100644 --- a/site/package-viewer/index.html +++ b/site/package-viewer/index.html @@ -100,6 +100,16 @@ gap: 26px; margin-top: 24px; } + .dossier { + margin-top: 22px; + border-top: 1px solid var(--line); + padding-top: 22px; + } + .dossier-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); + gap: 12px; + } .summary-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); @@ -221,6 +231,19 @@ background: var(--soft-warn); color: #6f4b12; } + .command { + display: block; + overflow-x: auto; + margin-top: 12px; + border: 1px solid var(--line); + border-radius: 8px; + padding: 12px; + background: #101418; + color: #f7fafc; + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace; + font-size: 13px; + white-space: pre; + } .empty { border: 1px dashed var(--line); border-radius: 8px; @@ -286,6 +309,7 @@

Evydence Package Viewer

+
@@ -307,6 +331,7 @@

Evydence Package Viewer

const statusNode = document.getElementById("status"); const summaryNode = document.getElementById("summary"); const nodes = { + dossier: document.getElementById("dossier"), release: document.getElementById("release"), artifacts: document.getElementById("artifacts"), sbom: document.getElementById("sbom"), @@ -423,6 +448,16 @@

Evydence Package Viewer

}).filter(Boolean); return values.length ? values.join(", ") : "not present"; }; + const firstRecord = (rows) => safeArray(rows).find((row) => row && typeof row === "object") || {}; + const joinRecordIDs = (rows) => { + const ids = safeArray(rows).map((row) => { + if (!row || typeof row !== "object") { + return ""; + } + return row.id || row.evidence_id || row.manifest_hash || ""; + }).filter(Boolean); + return ids.length ? ids.join(", ") : "not present"; + }; const pick = (obj, paths) => { for (const path of paths) { const value = path.split(".").reduce((current, key) => { @@ -535,6 +570,84 @@

Evydence Package Viewer

addMetric("Generated", pick(data, ["generated_at", "created_at", "checked_at"])); }; + const renderDossier = (data) => { + clearNode(nodes.dossier); + const packageID = pick(data, ["package_id", "id"]); + const productID = pick(data, ["product.id", "product_id"]); + const releaseID = pick(data, ["release.id", "release_id"]); + const sbom = firstRecord(data.sboms); + const decision = firstRecord(data.vulnerability_decisions); + const approval = firstRecord(data.approvals); + const material = safeObject(data.verification_material); + const audit = safeObject(material.audit_chain); + const releaseBundles = safeArray(material.release_bundles); + const verificationStatus = material.hash_algorithm + ? "Verification material present; run CLI verifier before relying on bytes." + : "No package verification material is present."; + const approver = approval.approver || approval.approved_by || approval.actor || approval.reviewer || approval.decision || "not present"; + const command = [ + "evydence package verify \\", + " --manifest package-manifest.json \\", + " --expected-package-id " + text(packageID, "") + " \\", + " --expected-product-id " + text(productID, "") + " \\", + " --expected-release-id " + text(releaseID, "") + ].join("\n"); + + const head = document.createElement("div"); + head.className = "section-head"; + appendText(head, "h2", "", "Reviewer Dossier"); + appendText(head, "span", "badge warn", "read-only package scope"); + nodes.dossier.append(head); + + const grid = document.createElement("div"); + grid.className = "dossier-grid"; + [ + ["Scope", [text(data.product && data.product.name, productID), text(data.release && data.release.version, releaseID), text(data.redaction_profile && data.redaction_profile.name, data.redaction_profile_id)].join(" / ")], + ["Package verification result", verificationStatus], + ["SBOM summary", [text(sbom.format), text(sbom.component_count, "0") + " components"].join(" / ")], + ["CVE decision", [text(decision.vulnerability), text(decision.status)].join(" / ")], + ["Approver / approval", approver], + ["Linked evidence", [safeArray(data.evidence_ids).length + " evidence IDs", releaseBundles.length + " release bundles", text(audit.result)].join(" / ")], + ["Limitations", safeArray(data.limitations).length + safeArray(data.non_claims).length + " listed"], + ["Package expiry", pick(data, ["expires_at", "expires", "valid_until"])] + ].forEach(([label, value]) => { + const card = document.createElement("section"); + card.className = "metric"; + appendText(card, "p", "label", label); + appendText(card, "p", "value", value); + grid.append(card); + }); + nodes.dossier.append(grid); + + const linked = document.createElement("div"); + linked.className = "split"; + const left = document.createElement("div"); + appendText(left, "h3", "", "Linked evidence path"); + table(left, [ + { label: "Kind", value: "kind" }, + { label: "Included IDs", value: "ids" } + ], [ + { kind: "Evidence records", ids: safeArray(data.evidence_ids).join(", ") }, + { kind: "Release bundles", ids: joinRecordIDs(releaseBundles) }, + { kind: "Decision support", ids: formatRefs(decision.supporting_refs) }, + { kind: "Redaction profile", ids: [data.redaction_profile_id, data.redaction_profile && data.redaction_profile.name].filter(Boolean).join(" / ") } + ], "No linked package evidence is present."); + const right = document.createElement("div"); + appendText(right, "h3", "", "Offline verification instructions"); + appendText(right, "p", "muted", "The browser view is read-only orientation. Verify the manifest or ZIP locally before relying on package bytes."); + const code = document.createElement("code"); + code.className = "command"; + code.textContent = command; + right.append(code); + linked.append(left, right); + nodes.dossier.append(linked); + + const boundary = document.createElement("p"); + boundary.className = "note"; + boundary.textContent = "This viewer renders only package-scoped JSON already present in the selected file. It is not an authorization layer, does not fetch tenant data, and does not expose raw evidence payload bytes or secrets."; + nodes.dossier.append(boundary); + }; + const renderRelease = (data) => { sectionHead(nodes.release, "Release Summary", data.schema_version || ""); const grid = document.createElement("div"); @@ -767,6 +880,7 @@

Evydence Package Viewer

throw new Error("JSON document is not an object"); } renderSummary(data, fileName); + renderDossier(data); renderRelease(data); renderArtifactsAndSBOM(data); renderRisk(data); From f6ca5dab9d99fa08410174b8bb706a13a4c711fb Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 20:27:04 +0300 Subject: [PATCH 280/287] feat(package-viewer): show package proof summary --- Makefile | 5 ++ docs/how-to/view-packages.md | 8 ++++ site/package-viewer/index.html | 85 ++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+) diff --git a/Makefile b/Makefile index fb81ffd..4b7893a 100644 --- a/Makefile +++ b/Makefile @@ -575,6 +575,11 @@ package-viewer-check: ## Validate local package viewer and walkthrough @grep -F 'Package verification result' site/package-viewer/index.html >/dev/null @grep -F 'Offline verification instructions' site/package-viewer/index.html >/dev/null @grep -F 'evydence package verify' site/package-viewer/index.html docs/how-to/view-packages.md >/dev/null + @grep -F 'Manifest Summary And Proof' site/package-viewer/index.html docs/how-to/view-packages.md >/dev/null + @grep -F 'Evidence Link Status' site/package-viewer/index.html docs/how-to/view-packages.md >/dev/null + @grep -F 'Package Verification Result' site/package-viewer/index.html >/dev/null + @grep -F 'Signed release bundle material' site/package-viewer/index.html docs/how-to/view-packages.md >/dev/null + @grep -F 'limitation/non-claim copy' docs/how-to/view-packages.md >/dev/null @grep -F 'Vulnerability / VEX Decisions' site/package-viewer/index.html >/dev/null @grep -F 'Verification Status' site/package-viewer/index.html >/dev/null @grep -F 'Reviewer checklist' site/package-viewer/index.html >/dev/null diff --git a/docs/how-to/view-packages.md b/docs/how-to/view-packages.md index f124526..f487b68 100644 --- a/docs/how-to/view-packages.md +++ b/docs/how-to/view-packages.md @@ -46,6 +46,12 @@ the offline `evydence package verify` command. The browser does not verify the package bytes itself; use the CLI verifier before relying on a manifest or ZIP archive. +The **Manifest Summary And Proof** section gives a second proof-oriented view: +schema and package identifiers, redaction profile, manifest-hash field, +evidence link status, signed release bundle material, audit-chain material, +decision-export presence, and the package verification result display. It is a +review aid for redaction-approved package content only. + Before sharing or reviewing a package, use the offline verifier for hash, structure, archive metadata, and optional evidence-bundle signature checks: @@ -108,6 +114,8 @@ Use it for: - inspecting package manifests and limitations; - reviewing artifact, SBOM, vulnerability, VEX, approval, exception, readiness, contents, and verification sections; +- checking manifest summary, evidence link status, signed release bundle + material, package verification result, and limitation/non-claim copy; - following the reviewer checklist for package scope, included evidence, excluded evidence, hash/signature verification, non-claims, and escalation path; diff --git a/site/package-viewer/index.html b/site/package-viewer/index.html index be12fc1..0425af5 100644 --- a/site/package-viewer/index.html +++ b/site/package-viewer/index.html @@ -319,6 +319,7 @@

Evydence Package Viewer

+
@@ -339,6 +340,7 @@

Evydence Package Viewer

approvals: document.getElementById("approvals"), readiness: document.getElementById("readiness"), contents: document.getElementById("contents"), + proof: document.getElementById("proof"), verification: document.getElementById("verification"), limitations: document.getElementById("limitations"), raw: document.getElementById("raw") @@ -823,6 +825,88 @@

Evydence Package Viewer

], data.reviewer_checklist, "No reviewer checklist is present."); }; + const verificationResultLabel = (data) => { + const material = safeObject(data.verification_material); + const releaseBundles = safeArray(material.release_bundles); + const audit = safeObject(material.audit_chain); + if (releaseBundles.length && String(audit.result || "").toLowerCase() === "passed") { + return "release bundle and audit-chain material present"; + } + if (releaseBundles.length) { + return "release bundle material present"; + } + if (material.hash_algorithm || material.canonicalization) { + return "package verification material present"; + } + return "verification material not present"; + }; + + const linkStatus = (record, field = "evidence_id") => { + if (!record || typeof record !== "object") { + return "not present"; + } + return record[field] || record.id || record.manifest_hash ? "linked" : "missing link"; + }; + + const renderProof = (data) => { + sectionHead(nodes.proof, "Manifest Summary And Proof", verificationResultLabel(data)); + const material = safeObject(data.verification_material); + const releaseBundles = safeArray(material.release_bundles); + const audit = safeObject(material.audit_chain); + const decisionExport = safeObject(data.customer_decision_export); + + const manifestGrid = document.createElement("div"); + manifestGrid.className = "summary-grid"; + [ + ["Schema", pick(data, ["schema_version", "package_version"])], + ["Package ID", pick(data, ["package_id", "id"])], + ["Product / release", [pick(data, ["product.id", "product_id"]), pick(data, ["release.id", "release_id"])].filter(Boolean).join(" / ")], + ["Redaction profile", [data.redaction_profile_id, data.redaction_profile && data.redaction_profile.name].filter(Boolean).join(" / ")], + ["Generated", pick(data, ["generated_at", "created_at"])], + ["Manifest hash", pick(data, ["manifest_hash", "package_metadata.manifest_hash", "verification.manifest_hash", "verification_material.manifest_hash"]) || text(material.manifest_hash_field)] + ].forEach(([label, value]) => { + const card = document.createElement("section"); + card.className = "metric"; + appendText(card, "p", "label", label); + appendText(card, "p", "value", value); + manifestGrid.append(card); + }); + nodes.proof.append(manifestGrid); + + appendText(nodes.proof, "h3", "", "Evidence Link Status"); + table(nodes.proof, [ + { label: "Evidence family", value: "family" }, + { label: "Records", value: "count" }, + { label: "Link status", value: "status", badge: true }, + { label: "Reference", value: "reference" } + ], [ + { family: "Artifact digests", count: safeArray(data.artifact_digests).length, status: safeArray(data.artifact_digests).length ? "linked" : "missing", reference: joinRecordIDs(data.artifact_digests) }, + { family: "SBOM", count: safeArray(data.sboms).length, status: linkStatus(firstRecord(data.sboms)), reference: joinRecordIDs(data.sboms) }, + { family: "Vulnerability scan", count: safeArray(data.vulnerability_scans).length, status: linkStatus(firstRecord(data.vulnerability_scans)), reference: joinRecordIDs(data.vulnerability_scans) }, + { family: "VEX", count: safeArray(data.vex_documents).length, status: linkStatus(firstRecord(data.vex_documents)), reference: joinRecordIDs(data.vex_documents) }, + { family: "Vulnerability decision", count: safeArray(data.vulnerability_decisions).length, status: linkStatus(firstRecord(data.vulnerability_decisions)), reference: joinRecordIDs(data.vulnerability_decisions) }, + { family: "Release bundle", count: releaseBundles.length, status: releaseBundles.length ? "linked" : "missing", reference: joinRecordIDs(releaseBundles) } + ], "No evidence link metadata is present."); + + appendText(nodes.proof, "h3", "", "Package Verification Result"); + table(nodes.proof, [ + { label: "Check", value: "check" }, + { label: "Result", value: "result", badge: true }, + { label: "Detail", value: "detail" } + ], [ + { check: "Browser package view", result: "read_only", detail: "The viewer renders package-scoped JSON but does not verify package bytes." }, + { check: "CLI package verifier", result: material.hash_algorithm ? "available" : "missing", detail: "Run evydence package verify against the manifest or ZIP archive." }, + { check: "Signed release bundle material", result: releaseBundles.length ? "present" : "missing", detail: joinRecordIDs(releaseBundles) }, + { check: "Audit-chain material", result: audit.result || "not present", detail: audit.head_hash || audit.latest_sequence || "not present" }, + { check: "Customer decision export", result: decisionExport.file ? "present" : "not present", detail: decisionExport.file || "not present" } + ], "No package verification result metadata is present."); + + const proofNote = document.createElement("p"); + proofNote.className = "note"; + proofNote.textContent = "Signed release bundle material and manifest hashes support reproducible technical review. They are not legal compliance proof, certification, complete SBOM proof, authoritative scanner coverage, or a secure-release guarantee."; + nodes.proof.append(proofNote); + }; + const renderVerification = (data) => { const material = safeObject(data.verification_material); sectionHead(nodes.verification, "Verification Status", material.hash_algorithm || "not present"); @@ -887,6 +971,7 @@

Evydence Package Viewer

renderApprovals(data); renderReadiness(data); renderContents(data); + renderProof(data); renderVerification(data); renderLimitations(data); renderRaw(parsed); From 3755e8719a08a67bc3557632cd59a181eeaea9a2 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 20:29:41 +0300 Subject: [PATCH 281/287] docs(commercial): define readiness review offer --- COMMERCIAL.md | 41 +++++++++++++++++++++ Makefile | 5 +++ docs/commercial/product-landing-copy.md | 25 +++++++++++++ site/marketing/scripts/check.mjs | 32 +++++++++++++++++ site/marketing/src/data/site.ts | 48 +++++++++++++++++++++++++ 5 files changed, 151 insertions(+) diff --git a/COMMERCIAL.md b/COMMERCIAL.md index e6c3f7e..7d3308a 100644 --- a/COMMERCIAL.md +++ b/COMMERCIAL.md @@ -35,10 +35,51 @@ language rules, see [Governance](GOVERNANCE.md). | --- | ---: | ---: | --- | | Commercial license exception | Yes | No | Written permission for agreed proprietary use cases. | | Self-hosted support | Yes | No | Deployment review, upgrade help, troubleshooting, and security notices. | +| Release evidence readiness review | Yes | No | One scoped release workflow: install/configuration review, CI evidence upload, first customer-safe package, verification walkthrough, and limitations. | | Release evidence package | Yes | No | SBOMs, vulnerability scan results, OpenAPI checksum, acceptance evidence, and hardening notes. | | Production readiness review | Yes | No | Configuration, backup, restore, evidence handling, and deployment review. | | Custom integration work | Yes | No | Collector adapters, evidence workflows, report templates, or deployment hardening. | +## Release Evidence Readiness Review + +The default paid services shape is a scoped self-hosted release evidence +readiness review. It is meant for teams that want to prove one practical +workflow before deciding whether Evydence belongs in their release process. + +Typical scope: + +- install or review a self-hosted Evydence deployment profile; +- configure one product, project, release, artifact digest, and redaction + profile; +- connect one CI path for SBOM, vulnerability scan, build, artifact, and release + bundle evidence where the operator already has those files or commands; +- generate one customer-safe package or evidence bundle; +- run the package verifier and walk through reviewer-facing limitations, + assumptions, gaps, and non-claims; +- document follow-up work as repo-local product gaps, operator-owned deployment + responsibilities, or external provider dependencies. + +Deliverables: + +- short written readiness summary; +- completed or gap-marked deployment checklist for the reviewed profile; +- example upload or CI command path for the agreed release; +- one generated package or bundle with manifest, hashes, verification material, + assumptions, limitations, and non-claims; +- prioritized next-step list for production hardening, integrations, or package + sharing. + +Out of scope unless separately agreed: + +- legal compliance advice, certification, audit opinion, regulator acceptance, + secure-release guarantee, complete SBOM proof, or authoritative vulnerability + coverage; +- hosted SaaS operation by Evydence; +- unlimited custom collectors, scanner replacement, broad GRC workflow, or + customer portal development; +- public handling of raw customer evidence, tokens, private keys, database URLs, + provider credentials, or unreleased product details. + ## Commercial License Scope A commercial license is a separate written agreement. It does not remove or diff --git a/Makefile b/Makefile index 4b7893a..29bbe01 100644 --- a/Makefile +++ b/Makefile @@ -97,6 +97,9 @@ meta-check: ## Validate root legal, governance, support, and release-evidence me @grep -F 'License Decision Table' COMMERCIAL.md >/dev/null @grep -F 'This table is a practical routing aid, not legal advice.' COMMERCIAL.md >/dev/null @grep -F 'Discuss a commercial license exception' COMMERCIAL.md >/dev/null + @grep -F 'Release Evidence Readiness Review' COMMERCIAL.md >/dev/null + @grep -F 'one customer-safe package or evidence bundle' COMMERCIAL.md docs/commercial/product-landing-copy.md >/dev/null + @grep -F 'Out of scope unless separately agreed' COMMERCIAL.md >/dev/null @grep -F 'contributor license agreement' CONTRIBUTING.md >/dev/null @grep -F 'First Contribution Path' CONTRIBUTING.md >/dev/null @grep -F 'Issue reports do not need a contributor license agreement' CONTRIBUTING.md >/dev/null @@ -377,6 +380,8 @@ docs-check: meta-check release-truth-check persistence-decomposition-check rende @grep -F 'One-Sentence Pitch' docs/commercial/product-landing-copy.md >/dev/null @grep -F 'Why Self-Hosted' docs/commercial/product-landing-copy.md >/dev/null @grep -F 'Pilot CTA' docs/commercial/product-landing-copy.md >/dev/null + @grep -F 'Paid Readiness Offer' docs/commercial/product-landing-copy.md >/dev/null + @grep -F 'Release evidence readiness review' docs/commercial/product-landing-copy.md >/dev/null @test -f docs/commercial/category-comparison.md @grep -F 'Vulnerability scanners' docs/commercial/category-comparison.md >/dev/null @grep -F 'SBOM inventory tools' docs/commercial/category-comparison.md >/dev/null diff --git a/docs/commercial/product-landing-copy.md b/docs/commercial/product-landing-copy.md index 3c0fca5..b8f90e2 100644 --- a/docs/commercial/product-landing-copy.md +++ b/docs/commercial/product-landing-copy.md @@ -72,3 +72,28 @@ bundle, and review the self-hosted deployment profile. See [Design Partner Pilot](design-partner-pilot.md) for scope, deliverables, non-deliverables, support boundaries, and the AGPL/commercial license path. +## Paid Readiness Offer + +Release evidence readiness review: install or review one self-hosted Evydence +deployment profile, configure one product release, connect one CI evidence path, +generate the first customer-safe package, verify it offline, and document gaps, +assumptions, limitations, operator responsibilities, and external dependencies. + +Included deliverables: + +- one short readiness summary; +- one deployment-checklist pass with accepted gaps; +- one SBOM/vulnerability/build/artifact upload path where the operator already + has the files or commands; +- one customer-safe package or evidence bundle with manifest, hashes, + verification material, limitations, and non-claims; +- one prioritized follow-up list. + +Excluded unless separately agreed: + +- hosted SaaS operation; +- legal compliance advice, certification, audit opinion, regulator acceptance, + secure-release guarantees, complete SBOM proof, or authoritative vulnerability + coverage; +- unlimited integration work, broad GRC workflows, scanner replacement, custom + portal work, or public handling of raw customer evidence and secrets. diff --git a/site/marketing/scripts/check.mjs b/site/marketing/scripts/check.mjs index 288412b..349c1c7 100644 --- a/site/marketing/scripts/check.mjs +++ b/site/marketing/scripts/check.mjs @@ -45,6 +45,8 @@ for (const file of requiredFiles) { const rootPage = readFileSync(join(dist, "index.html"), "utf8"); const english = readFileSync(join(dist, "en/index.html"), "utf8"); const finnish = readFileSync(join(dist, "fi/index.html"), "utf8"); +const commercialEnglish = readFileSync(join(dist, "en/commercial/index.html"), "utf8"); +const commercialFinnish = readFileSync(join(dist, "fi/kaupallinen/index.html"), "utf8"); const privacy = readFileSync(join(dist, "en/privacy-cookies/index.html"), "utf8"); const cname = readFileSync(join(dist, "CNAME"), "utf8").trim(); const consentSource = readFileSync(join(root, "src/components/ConsentBanner.astro"), "utf8"); @@ -105,6 +107,36 @@ for (const text of requiredFinnish) { } } +const requiredCommercialEnglish = [ + "Release evidence readiness review", + "one short readiness summary", + "one customer-safe package or evidence bundle", + "What is excluded", + "legal compliance advice or certification", + "secure-release guarantees" +]; + +for (const text of requiredCommercialEnglish) { + if (!commercialEnglish.includes(text)) { + throw new Error(`English commercial page missing: ${text}`); + } +} + +const requiredCommercialFinnish = [ + "Julkaisuevidencen readiness review", + "yksi lyhyt readiness-yhteenveto", + "asiakkaalle turvallinen paketti tai evidence bundle", + "Mitä ei sisälly", + "juridinen vaatimustenmukaisuusneuvonta tai sertifiointi", + "takuu turvallisesta julkaisusta" +]; + +for (const text of requiredCommercialFinnish) { + if (!commercialFinnish.includes(text)) { + throw new Error(`Finnish commercial page missing: ${text}`); + } +} + const consentChecks = [ "analytics_storage: \"denied\"", "ad_storage: \"denied\"", diff --git a/site/marketing/src/data/site.ts b/site/marketing/src/data/site.ts index 73a4e79..9bdc7eb 100644 --- a/site/marketing/src/data/site.ts +++ b/site/marketing/src/data/site.ts @@ -372,6 +372,30 @@ const en: Record = { }, ], }, + { + title: "Release evidence readiness review", + body: [ + "A concrete paid starting point: install or review one self-hosted Evydence deployment profile, configure one product release, connect one CI evidence path, generate the first customer-safe package, verify it offline, and document gaps, assumptions, limitations, operator responsibilities, and external dependencies.", + ], + bullets: [ + "one short readiness summary", + "one deployment-checklist pass with accepted gaps", + "one SBOM, vulnerability, build, artifact, and release-bundle upload path where the operator already has the files or commands", + "one customer-safe package or evidence bundle with manifest, hashes, verification material, limitations, and non-claims", + "one prioritized follow-up list", + ], + }, + { + title: "What is excluded", + bullets: [ + "hosted SaaS operation", + "legal compliance advice or certification", + "audit opinion or regulator acceptance", + "secure-release guarantees", + "complete SBOM proof or authoritative vulnerability coverage", + "unlimited integration work, scanner replacement, broad GRC workflow, or custom customer portal development", + ], + }, { title: "Commercial boundary", body: [ @@ -851,6 +875,30 @@ const fi: Record = { }, ], }, + { + title: "Julkaisuevidencen readiness review", + body: [ + "Konkreettinen maksullinen aloitus: asenna tai katselmoi yksi itse ylläpidettävä Evydence-käyttöprofiili, konfiguroi yksi tuotteen julkaisu, yhdistä yksi CI-evidence-polku, luo ensimmäinen asiakkaalle turvallinen paketti, todenna se offline-tilassa ja dokumentoi aukot, oletukset, rajoitukset, operaattorin vastuut ja ulkoiset riippuvuudet.", + ], + bullets: [ + "yksi lyhyt readiness-yhteenveto", + "yksi deployment-checklist-kierros hyväksytyillä aukoilla", + "yksi SBOM-, haavoittuvuus-, koonti-, artefakti- ja release bundle -latauspolku, kun operaattorilla on jo tiedostot tai komennot", + "yksi asiakkaalle turvallinen paketti tai evidence bundle, jossa on manifesti, tiivisteet, todennusmateriaali, rajoitukset ja non-claim-teksti", + "yksi priorisoitu jatkolista", + ], + }, + { + title: "Mitä ei sisälly", + bullets: [ + "hostattu SaaS-operointi", + "juridinen vaatimustenmukaisuusneuvonta tai sertifiointi", + "audit-lausunto tai regulaattorihyväksyntä", + "takuu turvallisesta julkaisusta", + "täydellisen SBOMin todiste tai auktoritatiivinen haavoittuvuuskattavuus", + "rajaton integraatiotyö, skannerin korvaaminen, laaja GRC-työnkulku tai räätälöity asiakasportaali", + ], + }, { title: "Kaupallinen raja", body: [ From ea8ca8e7f7dca5a25fe39e7fb5e9bc420f66b593 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 20:32:06 +0300 Subject: [PATCH 282/287] docs(product): compare adjacent evidence tools --- Makefile | 5 +++ README.md | 6 ++++ docs/README.md | 2 +- docs/commercial/category-comparison.md | 20 ++++++++++- site/marketing/scripts/check.mjs | 32 +++++++++++++++++ site/marketing/src/data/site.ts | 50 ++++++++++++++++++++++++++ 6 files changed, 113 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 29bbe01..93e87cf 100644 --- a/Makefile +++ b/Makefile @@ -386,6 +386,11 @@ docs-check: meta-check release-truth-check persistence-decomposition-check rende @grep -F 'Vulnerability scanners' docs/commercial/category-comparison.md >/dev/null @grep -F 'SBOM inventory tools' docs/commercial/category-comparison.md >/dev/null @grep -F 'Trust centers' docs/commercial/category-comparison.md >/dev/null + @grep -F 'Dependency-Track' docs/commercial/category-comparison.md README.md docs/README.md >/dev/null + @grep -F 'GUAC' docs/commercial/category-comparison.md README.md site/marketing/src/data/site.ts >/dev/null + @grep -F 'OpenVEX tooling' docs/commercial/category-comparison.md >/dev/null + @grep -F 'Vanta, Drata' docs/commercial/category-comparison.md README.md site/marketing/src/data/site.ts >/dev/null + @grep -F 'Internal scripts, spreadsheets, object storage, and ad hoc databases' docs/commercial/category-comparison.md >/dev/null @grep -F 'release upload-evidence' docs/how-to/integrate-ci.md >/dev/null @grep -F 'Tool-specific integration templates' docs/README.md docs/how-to/integrate-ci.md docs/integrations/tool-templates.md >/dev/null @grep -F 'syft dir:.' docs/integrations/tool-templates.md >/dev/null diff --git a/README.md b/README.md index 220f0bb..00bb143 100644 --- a/README.md +++ b/README.md @@ -161,6 +161,12 @@ does not upload files. - Dependency-Track and vulnerability-management tools are strong for SBOM and finding workflows; Evydence focuses on release-level evidence, decisions, bundles, audit chains, controls, customer packages, and review limitations. +- GUAC-style supply-chain graph tools are strong for relationship exploration; + Evydence focuses on release manifests, verification receipts, and + reviewer-facing package evidence. +- OpenVEX-focused tooling is strong for authoring or consuming VEX statements; + Evydence stores VEX as evidence and links normalized decisions to releases, + scans, SBOM context, exceptions, and customer-safe packages. - Vanta, Drata, and similar SaaS GRC tools are broad compliance platforms; Evydence is a self-hosted technical evidence ledger and does not claim legal compliance or certification. diff --git a/docs/README.md b/docs/README.md index 492c045..cdbd676 100644 --- a/docs/README.md +++ b/docs/README.md @@ -74,7 +74,7 @@ This documentation is organized by reader task. Implementation claims should be - [Commercial licensing](../COMMERCIAL.md): license decision table, commercial license exceptions, self-hosted support, release evidence packages, deployment review, and custom integration support. - [Design partner pilot](commercial/design-partner-pilot.md): narrow paid pilot shape for one self-hosted release evidence workflow. - [Product landing copy](commercial/product-landing-copy.md): conservative reusable positioning for README, website, outreach, or pilot materials. -- [Category comparison](commercial/category-comparison.md): fair positioning against scanners, SBOM inventory tools, broad GRC, trust centers, and scripts. +- [Category comparison](commercial/category-comparison.md): fair positioning against Dependency-Track, GUAC, OpenVEX tooling, scanners, SBOM inventory tools, broad GRC, trust centers, and scripts. - [Security policy](../SECURITY.md): vulnerability reporting guidance for tenant isolation, evidence integrity, credentials, collectors, object storage, signing, reports, exports, and raw evidence payloads. - [Support](../SUPPORT.md): community support expectations, commercial support boundaries, and sanitized bug-report requirements. - [Governance](../GOVERNANCE.md): maintainer-led decision process, contribution acceptance, release evidence expectations, and conservative product-language policy. diff --git a/docs/commercial/category-comparison.md b/docs/commercial/category-comparison.md index 8c4a788..c2189f6 100644 --- a/docs/commercial/category-comparison.md +++ b/docs/commercial/category-comparison.md @@ -25,6 +25,21 @@ customer portals. It does not replace them. | Trust centers | Publishing selected security documents and package material to customers. | Public portals usually depend on curated upstream evidence and redaction decisions. | Generates scoped, verifiable package manifests and static reports that can feed a trust center or be shared offline. | | DIY scripts and spreadsheets | Fast local coordination for one team or one release. | Harder to keep append-only history, tenant scope, signatures, audit chains, and repeatable package structure. | Provides a repeatable API, manifest schema, verification commands, and release evidence workflow. | +## Named Adjacent Tools + +These examples are intentionally respectful and category-focused. The named +tools solve useful problems; Evydence is aimed at the release-level packaging +and verification workflow that usually sits beside them. + +| Tool or family | How to think about it | Evydence boundary | +| --- | --- | --- | +| Dependency-Track | Strong SBOM and component-risk management for product portfolios. | Evydence can ingest SBOM and scan outputs, then bind them to a specific release, decision trail, signed bundle, and customer-safe package. | +| GUAC | Strong supply-chain graph exploration and relationship analysis. | Evydence stays on release records, package manifests, verification receipts, and reviewer-facing evidence rather than replacing graph analysis. | +| OpenVEX tooling | Strong at producing or consuming VEX statements. | Evydence stores OpenVEX as evidence, normalizes customer-visible vulnerability decisions, and links decisions to releases, scans, SBOM context, packages, and exceptions. | +| Vanta, Drata, and similar SaaS GRC platforms | Strong broad compliance workflow, policy/task tracking, and customer-trust operations. | Evydence is self-hosted and release-evidence-specific. It can produce technical evidence inputs, but it does not claim legal compliance or certification. | +| Syft, Grype, Trivy, and other scanners/generators | Strong at generating SBOMs, scan findings, and technical outputs. | Evydence records those outputs, preserves hashes, links them to release context, and documents decisions, gaps, limitations, and package verification. | +| Internal scripts, spreadsheets, object storage, and ad hoc databases | Flexible and fast for a small team. | Evydence provides stable API contracts, idempotency, tenant scope, append-only evidence behavior, audit-chain records, package schemas, and reusable verification commands. | + ## Why Evydence Exists Release review commonly needs a single answer to a concrete question: @@ -46,6 +61,10 @@ Evydence focuses on that release-level answer: - Use scanners to discover findings. - Use SBOM generators to produce component lists. - Use dependency-inventory tools for component management at scale. +- Use GUAC-style graph tooling when supply-chain graph exploration is the + primary question. +- Use OpenVEX-focused tooling when the immediate task is authoring VEX + statements outside a release package workflow. - Use GRC platforms for broad organizational compliance workflow. - Use trust centers for public or customer-facing distribution workflows. - Use Evydence when the release team needs a reproducible evidence ledger and @@ -57,4 +76,3 @@ Evydence supports compliance readiness and technical evidence organization. It does not make legal compliance conclusions, grant certification, prove SBOM completeness, treat scanner output as authoritative, or guarantee release security. - diff --git a/site/marketing/scripts/check.mjs b/site/marketing/scripts/check.mjs index 349c1c7..3cc6dfe 100644 --- a/site/marketing/scripts/check.mjs +++ b/site/marketing/scripts/check.mjs @@ -45,6 +45,8 @@ for (const file of requiredFiles) { const rootPage = readFileSync(join(dist, "index.html"), "utf8"); const english = readFileSync(join(dist, "en/index.html"), "utf8"); const finnish = readFileSync(join(dist, "fi/index.html"), "utf8"); +const productEnglish = readFileSync(join(dist, "en/product/index.html"), "utf8"); +const productFinnish = readFileSync(join(dist, "fi/tuote/index.html"), "utf8"); const commercialEnglish = readFileSync(join(dist, "en/commercial/index.html"), "utf8"); const commercialFinnish = readFileSync(join(dist, "fi/kaupallinen/index.html"), "utf8"); const privacy = readFileSync(join(dist, "en/privacy-cookies/index.html"), "utf8"); @@ -107,6 +109,36 @@ for (const text of requiredFinnish) { } } +const requiredProductEnglish = [ + "Different from adjacent tools", + "Dependency-Track and SBOM inventory", + "GUAC-style supply-chain graph tools", + "OpenVEX tooling", + "Vanta, Drata, and broad GRC", + "Scanners and internal scripts" +]; + +for (const text of requiredProductEnglish) { + if (!productEnglish.includes(text)) { + throw new Error(`English product page missing: ${text}`); + } +} + +const requiredProductFinnish = [ + "Ero viereisiin työkaluihin", + "Dependency-Track ja SBOM-inventaario", + "GUAC-tyyliset supply-chain-graafityökalut", + "OpenVEX-työkalut", + "Vanta, Drata ja laaja GRC", + "Skannerit ja sisäiset skriptit" +]; + +for (const text of requiredProductFinnish) { + if (!productFinnish.includes(text)) { + throw new Error(`Finnish product page missing: ${text}`); + } +} + const requiredCommercialEnglish = [ "Release evidence readiness review", "one short readiness summary", diff --git a/site/marketing/src/data/site.ts b/site/marketing/src/data/site.ts index 9bdc7eb..ac61293 100644 --- a/site/marketing/src/data/site.ts +++ b/site/marketing/src/data/site.ts @@ -222,6 +222,31 @@ const en: Record = { "Evydence is designed for teams that want to run the evidence system in their own environment, close to release, security, and CI/CD systems.", ], }, + { + title: "Different from adjacent tools", + table: [ + { + left: "Dependency-Track and SBOM inventory", + right: "Evydence packages release-scoped SBOM, scan, decision, bundle, and verification evidence for review.", + }, + { + left: "GUAC-style supply-chain graph tools", + right: "Evydence focuses on release manifests, verification receipts, and customer-safe package evidence.", + }, + { + left: "OpenVEX tooling", + right: "Evydence stores VEX as evidence and links normalized decisions to releases, scans, SBOM context, and packages.", + }, + { + left: "Vanta, Drata, and broad GRC", + right: "Evydence is self-hosted release evidence infrastructure, not a compliance platform or certification service.", + }, + { + left: "Scanners and internal scripts", + right: "Evydence records their outputs, preserves hashes, and adds tenant scope, append-only history, and verification commands.", + }, + ], + }, ], }, customerReview: { @@ -724,6 +749,31 @@ const fi: Record = { "Evydence on tarkoitettu tiimeille, jotka haluavat ajaa evidence-järjestelmää omassa ympäristössään lähellä julkaisu-, tietoturva- ja CI/CD-järjestelmiä.", ], }, + { + title: "Ero viereisiin työkaluihin", + table: [ + { + left: "Dependency-Track ja SBOM-inventaario", + right: "Evydence paketoi julkaisukohtaisen SBOM-, skannaus-, päätös-, bundle- ja todennusevidencen katselmoitavaksi.", + }, + { + left: "GUAC-tyyliset supply-chain-graafityökalut", + right: "Evydence keskittyy julkaisumanifesteihin, todennuskuittauksiin ja asiakkaalle turvalliseen pakettievidenceen.", + }, + { + left: "OpenVEX-työkalut", + right: "Evydence tallentaa VEXin evidencenä ja linkittää normalisoidut päätökset julkaisuihin, skannauksiin, SBOM-kontekstiin ja paketteihin.", + }, + { + left: "Vanta, Drata ja laaja GRC", + right: "Evydence on itse ylläpidettävä julkaisuevidence-infra, ei compliance-alusta tai sertifiointipalvelu.", + }, + { + left: "Skannerit ja sisäiset skriptit", + right: "Evydence tallentaa niiden tulokset, säilyttää tiivisteet ja lisää tenant-rajauksen, append-only-historian ja todennuskomennot.", + }, + ], + }, ], }, customerReview: { From 8b7600f9d56811ed5d6ffd86634bf2577507c62c Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 20:34:42 +0300 Subject: [PATCH 283/287] docs(production): add readiness traceability matrix --- Makefile | 12 +++-- docs/README.md | 1 + .../production-readiness-traceability.md | 53 +++++++++++++++++++ 3 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 docs/reference/production-readiness-traceability.md diff --git a/Makefile b/Makefile index 93e87cf..a992648 100644 --- a/Makefile +++ b/Makefile @@ -180,6 +180,7 @@ docs-check: meta-check release-truth-check persistence-decomposition-check rende @test -f docs/reference/capacity-and-failures.md @test -f docs/reference/benchmark-results.md @test -f docs/reference/production-readiness.md + @test -f docs/reference/production-readiness-traceability.md @test -f docs/reference/persistence-decomposition.md @test -f docs/reference/production-exit-review.md @test -f docs/reference/stable-v0.1.0-exit-criteria.md @@ -239,9 +240,10 @@ docs-check: meta-check release-truth-check persistence-decomposition-check rende "reference/vulnerability-decisions.md" \ "reference/observability.md" \ "reference/capacity-and-failures.md" \ - "reference/benchmark-results.md" \ - "reference/production-readiness.md" \ - "reference/persistence-decomposition.md" \ + "reference/benchmark-results.md" \ + "reference/production-readiness.md" \ + "reference/production-readiness-traceability.md" \ + "reference/persistence-decomposition.md" \ "reference/production-exit-review.md" \ "reference/stable-v0.1.0-exit-criteria.md" \ "reference/hardened-reference-deployment.md" \ @@ -310,6 +312,10 @@ docs-check: meta-check release-truth-check persistence-decomposition-check rende @grep -F 'Production Check' README.md docs/reference/release-evidence-index.md >/dev/null @grep -F 'coverage.out' README.md docs/reference/release-evidence-index.md >/dev/null @grep -F 'release-check-summary.txt' README.md docs/reference/release-evidence-index.md >/dev/null + @grep -F 'Production readiness traceability' docs/README.md >/dev/null + @grep -F 'Traceability Matrix' docs/reference/production-readiness-traceability.md >/dev/null + @grep -F 'Unmapped Internal Findings' docs/reference/production-readiness-traceability.md >/dev/null + @grep -F 'External Blockers' docs/reference/production-readiness-traceability.md >/dev/null @test -x scripts/production_benchmark_check.sh @grep -F 'production_benchmark_check.sh' docs/reference/benchmark-results.md >/dev/null @grep -F 'tmp/production-benchmark/production-benchmark-summary.json' docs/reference/benchmark-results.md >/dev/null diff --git a/docs/README.md b/docs/README.md index cdbd676..bfa1192 100644 --- a/docs/README.md +++ b/docs/README.md @@ -46,6 +46,7 @@ This documentation is organized by reader task. Implementation claims should be - [Capacity and failure modes](reference/capacity-and-failures.md): supported concurrency profile, sizing inputs, and failure behavior. - [Benchmark results](reference/benchmark-results.md): current local benchmark command and interpretation. - [Production readiness](reference/production-readiness.md): self-hosted production profiles, production gates, and exit criteria. +- [Production readiness traceability](reference/production-readiness-traceability.md): maps production/productization findings to repo-local evidence or external blockers. - [Persistence decomposition inventory](reference/persistence-decomposition.md): generated map of focused and broad relational persistence call sites. - [Production exit review](reference/production-exit-review.md): current release-positioning decision and unresolved blockers. - [Stable v0.1.0 exit criteria](reference/stable-v0.1.0-exit-criteria.md): criteria for moving from release candidate to a stable `v0.1.0` tag. diff --git a/docs/reference/production-readiness-traceability.md b/docs/reference/production-readiness-traceability.md new file mode 100644 index 0000000..e8172c0 --- /dev/null +++ b/docs/reference/production-readiness-traceability.md @@ -0,0 +1,53 @@ +# Production Readiness Traceability + +This matrix maps the production-readiness and productization findings tracked +for Evydence to repository-local evidence or external blockers. It is an +engineering closeout artifact, not release marketing, legal compliance proof, +certification, complete SBOM proof, authoritative vulnerability coverage, or a +secure-release guarantee. + +## Source Scope + +The matrix is based on repository-owned files, current Makefile gates, committed +docs, release metadata checks, and the local production/productization backlog. +Provider settings, public adoption, real customer validation, live hosted +domain state, and third-party security review remain external evidence sources. + +## Traceability Matrix + +| Finding area | Repo-local ticket coverage | Current status | Repository evidence | +| --- | --- | --- | --- | +| Release truth and public status | E1-T1, E1-T2, E1-T3 | Complete locally; published release verification remains external. | `docs/reference/release-candidate.md`, `docs/reference/release-evidence-index.md`, `scripts/check_release_truth.py`, `make release-truth-check`. | +| Golden customer CVE review proof | E2-T1, E2-T2, E2-T3 | Complete locally; real design-partner story and adoption proof remain external. | `examples/customer-cve-review-demo/`, `docs/tutorials/customer-cve-review-demo.md`, `site/package-viewer/index.html`, `make customer-cve-review-demo-check`, `make package-viewer-check`. | +| Documentation and positioning clarity | E3-T1 through E3-T6 | Complete locally. | `README.md`, `docs/buyer-overview.md`, `docs/operator-overview.md`, `docs/runbooks/`, `COMMERCIAL.md`, `CONTRIBUTING.md`, `make docs-check`. | +| Deployment, runtime, and capacity proof | E4-T1 through E4-T7 | Complete locally for the controlled candidate profile; hardened target environment validation remains external. | `compose.production-like.yml`, `docs/reference/hardened-reference-deployment.md`, `.production.env.example`, `docs/reference/benchmark-results.md`, `scripts/black_box_release_artifact_check.sh`, `docs/reference/ha-strategy.md`, `docs/reference/persistence-decomposition.md`. | +| Integrations and API inspection | E5-T1 through E5-T4 | Complete locally; live provider validation and hosted API-doc publication remain external. | `docs/openapi/index.html`, `site/marketing/public/api/index.html`, `docs/sdk/quickstarts.md`, `docs/github-actions/end-to-end-release-evidence.md`, `docs/integrations/tool-templates.md`, `make openapi-check`, `make sdk-check`. | +| Security intake and public trust | E6-T4, E6-T5, E6-T7 | Repo-local release evidence and exit criteria are complete; private vulnerability reporting, branch protection, external review, and account settings remain external. | `SECURITY.md`, `docs/reference/stable-v0.1.0-exit-criteria.md`, `scripts/release_asset_smoke_check.sh`, `make release-acceptance`, `make public-release-verify TAG=v0.1.0-rc.7`. | +| Reviewer UX and commercial packaging | E7-T1, E7-T2, E7-T3, E7-T5 | Complete locally; real buyer validation remains external. | `site/package-viewer/index.html`, `docs/how-to/view-packages.md`, `COMMERCIAL.md`, `docs/commercial/product-landing-copy.md`, `docs/commercial/category-comparison.md`, `site/marketing/src/data/site.ts`, `make package-viewer-check`, `make marketing-site-check`. | +| External trust and adoption tracking | E8-T1 through E8-T4 | External. | Tracked as provider/customer/reviewer work only; repository files cannot prove public adoption, GitHub Pages health, analytics account settings, or third-party review completion. | +| Perfect-score internal closure | E9-T1 through E9-T4 | In progress until this matrix, exit checklist, fresh audit, and internal-score summary are complete. | This file, `docs/reference/production-internal-exit-checklist.md`, future audit outputs, and final docs/finalize gates. | + +## External Blockers + +These items are not hidden repo work. They require provider account access, +public repository state, a real buyer/reviewer, or third-party participation: + +- verified public release state and release-asset availability; +- real design-partner or pilot story and adoption proof; +- hardened target production environment validation; +- live GitHub/GitLab/provider integration validation; +- hosted rendered API-doc deployment health; +- GitHub private vulnerability reporting or equivalent private intake + verification; +- branch protection, required checks, Scorecard, and repository-security setting + verification; +- external security review; +- real buyer validation of the paid readiness offer; +- GitHub Pages/domain health and analytics privacy setting verification. + +## Unmapped Internal Findings + +At the time this matrix was written, no known repository-local finding from the +current production/productization backlog remains unmapped. A fresh audit can +invalidate that statement. If it finds new repo-local work, add a new tracked +ticket before claiming internal closure. From 782c178b8a0fcc05986a6b3fd9d38063fa87f979 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 20:36:37 +0300 Subject: [PATCH 284/287] docs(production): add internal exit checklist --- Makefile | 7 ++ docs/README.md | 1 + .../production-internal-exit-checklist.md | 70 +++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 docs/reference/production-internal-exit-checklist.md diff --git a/Makefile b/Makefile index a992648..0273a0c 100644 --- a/Makefile +++ b/Makefile @@ -181,6 +181,7 @@ docs-check: meta-check release-truth-check persistence-decomposition-check rende @test -f docs/reference/benchmark-results.md @test -f docs/reference/production-readiness.md @test -f docs/reference/production-readiness-traceability.md + @test -f docs/reference/production-internal-exit-checklist.md @test -f docs/reference/persistence-decomposition.md @test -f docs/reference/production-exit-review.md @test -f docs/reference/stable-v0.1.0-exit-criteria.md @@ -243,6 +244,7 @@ docs-check: meta-check release-truth-check persistence-decomposition-check rende "reference/benchmark-results.md" \ "reference/production-readiness.md" \ "reference/production-readiness-traceability.md" \ + "reference/production-internal-exit-checklist.md" \ "reference/persistence-decomposition.md" \ "reference/production-exit-review.md" \ "reference/stable-v0.1.0-exit-criteria.md" \ @@ -316,6 +318,11 @@ docs-check: meta-check release-truth-check persistence-decomposition-check rende @grep -F 'Traceability Matrix' docs/reference/production-readiness-traceability.md >/dev/null @grep -F 'Unmapped Internal Findings' docs/reference/production-readiness-traceability.md >/dev/null @grep -F 'External Blockers' docs/reference/production-readiness-traceability.md >/dev/null + @grep -F 'Internal production-readiness exit checklist' docs/README.md >/dev/null + @grep -F 'Required Internal State' docs/reference/production-internal-exit-checklist.md >/dev/null + @grep -F 'make production-check' docs/reference/production-internal-exit-checklist.md >/dev/null + @grep -F 'every external item must have a current owner and status' docs/reference/production-internal-exit-checklist.md >/dev/null + @grep -F 'fresh production-readiness audit finds no new repo-local remediation' docs/reference/production-internal-exit-checklist.md >/dev/null @test -x scripts/production_benchmark_check.sh @grep -F 'production_benchmark_check.sh' docs/reference/benchmark-results.md >/dev/null @grep -F 'tmp/production-benchmark/production-benchmark-summary.json' docs/reference/benchmark-results.md >/dev/null diff --git a/docs/README.md b/docs/README.md index bfa1192..cfb7f5c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -47,6 +47,7 @@ This documentation is organized by reader task. Implementation claims should be - [Benchmark results](reference/benchmark-results.md): current local benchmark command and interpretation. - [Production readiness](reference/production-readiness.md): self-hosted production profiles, production gates, and exit criteria. - [Production readiness traceability](reference/production-readiness-traceability.md): maps production/productization findings to repo-local evidence or external blockers. +- [Internal production-readiness exit checklist](reference/production-internal-exit-checklist.md): final repository-local closure checklist before claiming internal completion. - [Persistence decomposition inventory](reference/persistence-decomposition.md): generated map of focused and broad relational persistence call sites. - [Production exit review](reference/production-exit-review.md): current release-positioning decision and unresolved blockers. - [Stable v0.1.0 exit criteria](reference/stable-v0.1.0-exit-criteria.md): criteria for moving from release candidate to a stable `v0.1.0` tag. diff --git a/docs/reference/production-internal-exit-checklist.md b/docs/reference/production-internal-exit-checklist.md new file mode 100644 index 0000000..f2e50cc --- /dev/null +++ b/docs/reference/production-internal-exit-checklist.md @@ -0,0 +1,70 @@ +# Internal Production-Readiness Exit Checklist + +This checklist defines what must be true before Evydence can say the +repository-local production-readiness and productization work from the current +analysis is complete. It does not make Evydence legally compliant, certified, +complete-SBOM-proven, scanner-authoritative, auditor-ready without review, or +secure-release-guaranteed. + +## Required Internal State + +- [ ] Every repository-local backlog ticket from the current + production/productization analysis is marked complete only after + implementation, documentation, validation, and commit. +- [ ] Every completed ticket has a Conventional Commit in Git history. +- [ ] Every behavior change updates relevant tests, docs, examples, OpenAPI, + migrations, release evidence, SDKs, or deployment assets when applicable. +- [ ] No known repo-local production-readiness finding is unmapped in + [Production readiness traceability](production-readiness-traceability.md). +- [ ] Ignored/local audit files are not required for public documentation to be + understandable. + +## Required Gates + +- [ ] `make finalize` passes. +- [ ] `make docs-check` passes. +- [ ] `make release-acceptance` passes. +- [ ] `make marketing-site-check` passes. +- [ ] `make package-viewer-check` passes. +- [ ] `make public-release-verify TAG=v0.1.0-rc.7` passes when public release + access is available. +- [ ] `make production-check` passes when `EVYDENCE_TEST_DATABASE_URL` and + release signing material are available. + +If live PostgreSQL, GitHub release access, provider credentials, or external +signing/verification services are unavailable, record that as an external +evidence gap. Do not silently count a skipped live dependency as an internal +pass. + +## Product-Language Checks + +- [ ] Public docs avoid claims that Evydence provides legal compliance, + certification, complete SBOM proof, authoritative scanner results, + regulator/auditor acceptance without review, or secure-release guarantees. +- [ ] Release evidence is described as reproducibility, integrity, + traceability, assumptions, gaps, exceptions, and limitations. +- [ ] Commercial pages state deliverables, support boundaries, exclusions, and + non-claims without public pricing unless intentionally added later. + +## External-Item Status + +Before assigning a maximum public production-readiness score, every external item must have a current owner and status: + +- [ ] public release state and release-asset availability; +- [ ] design-partner, pilot, or adoption proof; +- [ ] target production environment validation; +- [ ] live provider integration validation; +- [ ] hosted rendered API-doc and GitHub Pages/domain health; +- [ ] GitHub private vulnerability reporting or equivalent private intake; +- [ ] branch protection, required checks, Scorecard, code-scanning, secret + scanning, push protection, and Dependabot security settings; +- [ ] external security review; +- [ ] analytics privacy/account setting verification. + +## Closeout Rule + +The repository-local work can be called internally complete only after the +checklist above is satisfied, a fresh production-readiness audit finds no new repo-local remediation, +and any remaining blockers are explicitly external. +Public status must remain conservative until external evidence also supports a +stronger claim. From c2de8a41a6985d253ce48861b21dce94ddf4f231 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 20:39:16 +0300 Subject: [PATCH 285/287] docs(production): record readiness audit closeout --- Makefile | 6 + docs/README.md | 1 + .../production-readiness-audit-closeout.md | 177 ++++++++++++++++++ 3 files changed, 184 insertions(+) create mode 100644 docs/reference/production-readiness-audit-closeout.md diff --git a/Makefile b/Makefile index 0273a0c..6b28b0c 100644 --- a/Makefile +++ b/Makefile @@ -182,6 +182,7 @@ docs-check: meta-check release-truth-check persistence-decomposition-check rende @test -f docs/reference/production-readiness.md @test -f docs/reference/production-readiness-traceability.md @test -f docs/reference/production-internal-exit-checklist.md + @test -f docs/reference/production-readiness-audit-closeout.md @test -f docs/reference/persistence-decomposition.md @test -f docs/reference/production-exit-review.md @test -f docs/reference/stable-v0.1.0-exit-criteria.md @@ -245,6 +246,7 @@ docs-check: meta-check release-truth-check persistence-decomposition-check rende "reference/production-readiness.md" \ "reference/production-readiness-traceability.md" \ "reference/production-internal-exit-checklist.md" \ + "reference/production-readiness-audit-closeout.md" \ "reference/persistence-decomposition.md" \ "reference/production-exit-review.md" \ "reference/stable-v0.1.0-exit-criteria.md" \ @@ -323,6 +325,10 @@ docs-check: meta-check release-truth-check persistence-decomposition-check rende @grep -F 'make production-check' docs/reference/production-internal-exit-checklist.md >/dev/null @grep -F 'every external item must have a current owner and status' docs/reference/production-internal-exit-checklist.md >/dev/null @grep -F 'fresh production-readiness audit finds no new repo-local remediation' docs/reference/production-internal-exit-checklist.md >/dev/null + @grep -F 'Production readiness audit closeout' docs/README.md >/dev/null + @grep -F 'Fresh Audit Result' docs/reference/production-readiness-audit-closeout.md >/dev/null + @grep -F 'found no new repo-local remediation' docs/reference/production-readiness-audit-closeout.md >/dev/null + @grep -F 'Production-usable with caveats' docs/reference/production-readiness-audit-closeout.md >/dev/null @test -x scripts/production_benchmark_check.sh @grep -F 'production_benchmark_check.sh' docs/reference/benchmark-results.md >/dev/null @grep -F 'tmp/production-benchmark/production-benchmark-summary.json' docs/reference/benchmark-results.md >/dev/null diff --git a/docs/README.md b/docs/README.md index cfb7f5c..b3f0916 100644 --- a/docs/README.md +++ b/docs/README.md @@ -48,6 +48,7 @@ This documentation is organized by reader task. Implementation claims should be - [Production readiness](reference/production-readiness.md): self-hosted production profiles, production gates, and exit criteria. - [Production readiness traceability](reference/production-readiness-traceability.md): maps production/productization findings to repo-local evidence or external blockers. - [Internal production-readiness exit checklist](reference/production-internal-exit-checklist.md): final repository-local closure checklist before claiming internal completion. +- [Production readiness audit closeout](reference/production-readiness-audit-closeout.md): fresh audit result after internal backlog implementation. - [Persistence decomposition inventory](reference/persistence-decomposition.md): generated map of focused and broad relational persistence call sites. - [Production exit review](reference/production-exit-review.md): current release-positioning decision and unresolved blockers. - [Stable v0.1.0 exit criteria](reference/stable-v0.1.0-exit-criteria.md): criteria for moving from release candidate to a stable `v0.1.0` tag. diff --git a/docs/reference/production-readiness-audit-closeout.md b/docs/reference/production-readiness-audit-closeout.md new file mode 100644 index 0000000..bdc3f73 --- /dev/null +++ b/docs/reference/production-readiness-audit-closeout.md @@ -0,0 +1,177 @@ +# Production Readiness Audit Closeout + +This closeout records a fresh repository-local production-readiness audit after +the internal backlog pass. It is not release marketing, legal compliance proof, +certification, complete SBOM proof, authoritative vulnerability coverage, or a +secure-release guarantee. + +## Latest Visible State Inspected + +| Item | Evidence | +| --- | --- | +| Local repository | `/home/aatu/projects/evydence` | +| Local branch and commit | `master` at `041465bc48f7a8ea3d0536db423c617d9c8e026d` (`docs(production): add internal exit checklist`) | +| Public repository | `https://github.com/aatuh/evydence`, public, default branch `master`, AGPL-3.0 | +| Public branch state | GitHub reported latest pushed public `master` behind local by 32 commits at audit time. | +| Latest release checked | `v0.1.0-rc.7`, public prerelease published June 1, 2026, with archives, checksums, OpenAPI checksum, migration checksum, coverage, release summary, SBOM/provenance metadata, signed manifest, and manifest signature. | +| Public CI checked | Recent public CI, Marketing Site Pages, and CodeQL runs were visible as passing for the latest pushed public `master` state. | +| Verification run during audit | `make public-release-verify TAG=v0.1.0-rc.7` passed. | +| Not inspectable from repo files | GitHub private vulnerability reporting enablement, branch-protection admin-bypass settings, repository secret values, security setting toggles, analytics account settings, real buyer validation, external security review, and target-operator infrastructure. | + +Confidence is high for the local repository evidence inspected here and medium +for public production-readiness claims until the current local commits are +pushed and external settings are reverified. + +## What The Project Appears To Be + +Evydence is a self-hosted release evidence ledger for software teams that need +to organize SBOMs, vulnerability scans, VEX decisions, build/source evidence, +approvals, exceptions, audit-chain records, release bundles, and customer-safe +packages around a specific product release. + +The README now communicates the buyer question quickly: customers ask what is +inside a release, whether a CVE affects it, who reviewed the decision, and what +proof can be shared. The project presents as an API server, CLI, worker, +release-verification toolchain, package viewer, and self-hosted deployment +profile. It explicitly avoids claims of legal compliance, certification, +complete SBOMs, authoritative scanner results, regulator/auditor acceptance +without review, or secure releases. + +## Production Readiness + +Evydence has credible controlled self-hosted production-candidate evidence: + +- precise `/v1` OpenAPI contract and generated route matrix; +- API/worker/CLI tests, package viewer checks, release acceptance, and public + release verification; +- production startup validation, single-writer API stance, scalable worker + stance, PostgreSQL-backed persistence, migration compatibility, backup/restore + rehearsal, object-store checks, release signing, and release asset smoke + checks; +- Helm, Compose, Kubernetes, air-gap, configuration, capacity, observability, + runbook, and release-validation documentation; +- signed public prerelease artifacts and verifiable release assets. + +The strongest honest classification remains controlled self-hosted production +candidate. Broad production for most uses, regulated production, and hosted +SaaS production still require external environment proof, verified repository +security settings, external security review, and operator-specific controls. + +Score: 8.2/10. + +## Feature Completeness + +The core product path is implemented deeply enough for a real controlled pilot: +release evidence ingestion, SBOM/scan/VEX/decision handling, release readiness, +bundles, package generation, package viewer, source/build/deployment/security +evidence families, control reports, package verification, and release evidence +workflows. + +Remaining gaps are mostly external adoption/proof or higher-trust deployment +dependencies rather than missing repository-local product surfaces. The product +is not a broad GRC suite, scanner, trust center, hosted SaaS, or legal +compliance engine, and the docs say so. + +Score: 8.6/10. + +## Security And Open-Source Trust + +Strong repo signals include AGPL licensing, governance, contributing, support, +security policy, issue templates, CODEOWNERS, pinned workflows, Dependabot, +CodeQL, Scorecard workflow files, conservative release permissions, release +signing, package verification, redaction leakage checks, and no public claim +that release evidence proves compliance or security. + +External trust blockers remain: GitHub private vulnerability reporting must be +verified, branch protection/security settings are account-level checks, public +CI only proves pushed commits, and an independent security review is not present +in repository evidence. + +Score: 8.0/10. + +## Marketability And Positioning + +The product story is now sharp for self-hosted software vendors that face +customer release-security reviews. The demo path, package viewer, commercial +readiness offer, category comparison, and bilingual marketing site make the +value easier to evaluate. The dual-license/support path is plausible without +public pricing or unsupported compliance promises. + +The main marketability gap is external validation: no public adoption, customer +story, design-partner quote, or third-party review has been verified. + +Score: 8.3/10. + +## Differentiation + +The repository now explains its boundary next to Dependency-Track, GUAC, +OpenVEX tooling, Vanta, Drata, scanners, trust centers, and internal scripts. +The meaningful differentiation is release-level evidence packaging and +verification: tenant-scoped API records, append-only evidence behavior, package +redaction, signed bundles, audit-chain material, verifier commands, and +customer-safe review surfaces. + +The weak point is proof of adoption, not clarity of positioning. + +Score: 8.2/10. + +## Repository Quality Checklist + +| Area | Status | Evidence | Severity | Recommended fix | +| --- | --- | --- | --- | --- | +| README | Strong | Buyer question, demo path, status, release verification, comparisons, non-claims. | Low | Keep status synchronized with release truth. | +| Quickstart | Strong | Tutorials, local demo, GitHub/GitLab examples, SDK quickstarts. | Low | Add real pilot story when available. | +| Examples/demo | Strong | Customer CVE demo, package viewer, local CI simulation, sample package verification. | Low | Keep fixtures in sync with package schema. | +| Tests | Strong | `make finalize`, package, docs, OpenAPI, SDK, release, demo, and worker/app tests. | Low | Continue adding tests for any future public behavior. | +| CI | Adequate public, strong local | Public CI green for pushed state; local branch ahead. | Medium | Push current commits and confirm CI green for current HEAD. | +| Releases/provenance | Strong | `v0.1.0-rc.7` assets verified with `make public-release-verify`. | Low | Re-run after every release candidate. | +| Docs/API/config/ops | Strong | Reference docs, OpenAPI docs, operations/runbooks, production gate, traceability. | Low | Avoid drift from ignored audit files. | +| Docker/deployment | Strong for candidate | Compose, Helm, air-gap, hardened reference deployment, single-writer stance. | Low | Validate target operator environments externally. | +| Security policy | Adequate repo-local | `SECURITY.md` has safe intake rules and non-goals. | Medium | Verify private vulnerability reporting externally. | +| License/contribution/governance | Strong | AGPL, commercial model, governance, contributing, support, CODEOWNERS. | Low | Keep commercial claims conservative. | +| Changelog/versioning | Strong | Release notes, release truth checks, stable exit criteria. | Low | Update on each release-candidate tag. | + +## Scorecard + +| Dimension | Score | Notes | +| --- | ---: | --- | +| Production readiness | 8.2/10 | Controlled self-hosted candidate with strong repo evidence; not broad production. | +| Feature completeness | 8.6/10 | Core release evidence workflow is complete enough for controlled pilots. | +| Security and open-source trust | 8.0/10 | Strong repo hygiene; provider/account security settings remain external. | +| Marketability and positioning | 8.3/10 | Clear target user, demo, offer, and differentiation; adoption proof absent. | +| Differentiation | 8.2/10 | Release package verification is meaningfully distinct from adjacent tools. | +| Repository evidence quality | 8.8/10 | Extensive checks, docs, release evidence, and traceability. | +| Overall | 8.3/10 | Production-usable with caveats for controlled self-hosted use after operator review. | + +Confidence: medium-high for the local repository; medium for public state until +the current local commits are pushed and external settings are verified. + +Verdict: Production-usable with caveats. + +## Highest-Leverage Next Steps + +Next 1-2 days: + +- Push the current local commits and confirm public CI, Pages, CodeQL, and + marketing workflows are green for the same SHA. +- Verify GitHub private vulnerability reporting and branch protection settings. + +Next 1-2 weeks: + +- Run the paid readiness offer with a real design partner or buyer, then add + only sanitized, permissioned proof. +- Commission or perform an independent security review and publish a sanitized + summary. + +Next 1-2 months: + +- Validate a hardened target environment with external PostgreSQL, object + storage, backup/restore, monitoring, and signing custody. +- Re-run the stable `v0.1.0` exit criteria against a concrete candidate. + +## Fresh Audit Result + +The fresh audit found no new repo-local remediation that is not already covered +by completed tickets or existing external blockers. If a later audit finds a +new repository-local issue, add it to the traceability matrix and backlog before +claiming internal closure. From f2f1869cc81bbadd9332f96b3b478790e5c22fa3 Mon Sep 17 00:00:00 2001 From: Aatu Harju Date: Tue, 2 Jun 2026 20:41:29 +0300 Subject: [PATCH 286/287] docs(production): summarize internal readiness score --- Makefile | 7 ++ docs/README.md | 1 + docs/reference/production-exit-review.md | 11 +-- docs/reference/production-internal-score.md | 78 +++++++++++++++++++ .../production-readiness-traceability.md | 2 +- 5 files changed, 93 insertions(+), 6 deletions(-) create mode 100644 docs/reference/production-internal-score.md diff --git a/Makefile b/Makefile index 6b28b0c..9f87ef9 100644 --- a/Makefile +++ b/Makefile @@ -183,6 +183,7 @@ docs-check: meta-check release-truth-check persistence-decomposition-check rende @test -f docs/reference/production-readiness-traceability.md @test -f docs/reference/production-internal-exit-checklist.md @test -f docs/reference/production-readiness-audit-closeout.md + @test -f docs/reference/production-internal-score.md @test -f docs/reference/persistence-decomposition.md @test -f docs/reference/production-exit-review.md @test -f docs/reference/stable-v0.1.0-exit-criteria.md @@ -247,6 +248,7 @@ docs-check: meta-check release-truth-check persistence-decomposition-check rende "reference/production-readiness-traceability.md" \ "reference/production-internal-exit-checklist.md" \ "reference/production-readiness-audit-closeout.md" \ + "reference/production-internal-score.md" \ "reference/persistence-decomposition.md" \ "reference/production-exit-review.md" \ "reference/stable-v0.1.0-exit-criteria.md" \ @@ -329,6 +331,11 @@ docs-check: meta-check release-truth-check persistence-decomposition-check rende @grep -F 'Fresh Audit Result' docs/reference/production-readiness-audit-closeout.md >/dev/null @grep -F 'found no new repo-local remediation' docs/reference/production-readiness-audit-closeout.md >/dev/null @grep -F 'Production-usable with caveats' docs/reference/production-readiness-audit-closeout.md >/dev/null + @grep -F 'Highest achievable internal score' docs/README.md >/dev/null + @grep -F 'Overall | 8.3/10' docs/reference/production-internal-score.md >/dev/null + @grep -F 'Remaining External Blockers' docs/reference/production-internal-score.md >/dev/null + @grep -F 'controlled self-hosted production candidate' docs/reference/production-internal-score.md >/dev/null + @! grep -R -F '.audits/' README.md docs @test -x scripts/production_benchmark_check.sh @grep -F 'production_benchmark_check.sh' docs/reference/benchmark-results.md >/dev/null @grep -F 'tmp/production-benchmark/production-benchmark-summary.json' docs/reference/benchmark-results.md >/dev/null diff --git a/docs/README.md b/docs/README.md index b3f0916..33fef82 100644 --- a/docs/README.md +++ b/docs/README.md @@ -49,6 +49,7 @@ This documentation is organized by reader task. Implementation claims should be - [Production readiness traceability](reference/production-readiness-traceability.md): maps production/productization findings to repo-local evidence or external blockers. - [Internal production-readiness exit checklist](reference/production-internal-exit-checklist.md): final repository-local closure checklist before claiming internal completion. - [Production readiness audit closeout](reference/production-readiness-audit-closeout.md): fresh audit result after internal backlog implementation. +- [Highest achievable internal score](reference/production-internal-score.md): score summary and external blockers after repository-local closure. - [Persistence decomposition inventory](reference/persistence-decomposition.md): generated map of focused and broad relational persistence call sites. - [Production exit review](reference/production-exit-review.md): current release-positioning decision and unresolved blockers. - [Stable v0.1.0 exit criteria](reference/stable-v0.1.0-exit-criteria.md): criteria for moving from release candidate to a stable `v0.1.0` tag. diff --git a/docs/reference/production-exit-review.md b/docs/reference/production-exit-review.md index b833a75..c0015b9 100644 --- a/docs/reference/production-exit-review.md +++ b/docs/reference/production-exit-review.md @@ -71,11 +71,12 @@ SaaS-ready, legally compliant, certified, or secure-release-guaranteed. ## Decision The current repository can support controlled self-hosted evaluation, pilots, -and internal production after operator review. The productization audit closeout -in `.audits/production_readiness_v2/` and `.audits/product_code_audit_v4/` -supports keeping this controlled candidate status, not strengthening it. It -should not be marketed as broad production-ready for most uses until the -external controls above are closed, the +and internal production after operator review. The tracked +[production readiness audit closeout](production-readiness-audit-closeout.md) +and [highest achievable internal score](production-internal-score.md) support +keeping this controlled candidate status, not strengthening it. It should not +be marketed as broad production-ready for most uses until the external controls +above are closed, the [Stable v0.1.0 exit criteria](stable-v0.1.0-exit-criteria.md) pass for a concrete candidate, and a fresh product, codebase, security, documentation, and test audit confirms the change. diff --git a/docs/reference/production-internal-score.md b/docs/reference/production-internal-score.md new file mode 100644 index 0000000..8192e38 --- /dev/null +++ b/docs/reference/production-internal-score.md @@ -0,0 +1,78 @@ +# Highest Achievable Internal Production-Readiness Score + +This page summarizes the highest production-readiness score supported by +repository-local evidence after the internal backlog pass. It separates +repo-local completion from external public trust proof. It is not release +marketing, legal compliance proof, certification, complete SBOM proof, +authoritative vulnerability coverage, or a secure-release guarantee. + +## Internal Result + +The repository-local production/productization backlog is internally complete +for the current analysis: every known repo-local ticket has a tracked +implementation, documentation update, validation gate, and Conventional Commit. +The fresh audit closeout found no new repo-local remediation. + +The highest honest repository-local score is: + +| Dimension | Score | Reason | +| --- | ---: | --- | +| Production readiness | 8.2/10 | Controlled self-hosted candidate with strong repo gates, release evidence, deployment docs, and runtime hardening. | +| Feature completeness | 8.6/10 | Core release-evidence, package, verifier, readiness, and review workflows are implemented for controlled pilots. | +| Security and open-source trust | 8.0/10 | Strong repo hygiene and release integrity; provider/account security settings remain external. | +| Marketability and positioning | 8.3/10 | Clear buyer path, demo, package viewer, readiness offer, and adjacent-tool comparison; external adoption proof is absent. | +| Differentiation | 8.2/10 | Release-level evidence packaging and verification is meaningfully distinct from scanners, SBOM inventory, broad GRC, trust centers, and scripts. | +| Repository evidence quality | 8.8/10 | Extensive docs, gates, release assets, traceability, and local/public verification evidence. | +| Overall | 8.3/10 | Production-usable with caveats for controlled self-hosted use after operator review. | + +## Completed Internal Epics + +- Release truth, README status, and drift checks. +- Golden customer CVE demo, package viewer proof, and first-screen marketing + demo path. +- Buyer/operator docs, runbooks, upgrade policy, license decision table, and + first-contribution path. +- Production-like deployment docs, compose/Helm hardening, environment example, + capacity evidence, black-box release-artifact test, HA strategy, and + persistence decomposition evidence. +- Rendered OpenAPI docs, SDK quickstarts, GitHub Actions guide, and + tool-specific integration templates. +- CI/coverage/release evidence exposure, release asset smoke checks, and stable + `v0.1.0` exit criteria. +- Minimal reviewer UI, package proof summary, paid readiness offer, and + category differentiation content. +- Traceability matrix, internal exit checklist, fresh audit closeout, and this + score summary. + +## Remaining External Blockers + +These prevent a full public production-readiness score but are not repository +implementation tasks: + +- public release state and release-asset availability must be reverified after + every push/tag; +- current local commits must be pushed and public CI/Pages/CodeQL must be green + for the same SHA; +- GitHub private vulnerability reporting or an equivalent private intake channel + must be verified; +- branch protection, required checks, Scorecard, code-scanning, secret scanning, + push protection, Dependabot security settings, and repository credentials must + be verified in provider/account settings; +- a real design partner, pilot, or adoption proof must be obtained before using + adoption claims; +- live provider integrations and hosted rendered API docs must be validated in + their deployed environments; +- a hardened target production environment must be validated with operator-owned + PostgreSQL, object storage, TLS, backups, monitoring, signing custody, and + recovery controls; +- an external security review remains outside repository-local evidence; +- analytics privacy/account settings and custom-domain health remain external + website operations checks. + +## Status Boundary + +The correct public status remains controlled self-hosted production candidate. +Do not describe Evydence as broadly production-ready for most uses, regulated +production-ready, hosted SaaS-ready, legally compliant, certified, complete-SBOM +proven, scanner-authoritative, auditor-ready without review, or +secure-release-guaranteed based on repository-local evidence alone. diff --git a/docs/reference/production-readiness-traceability.md b/docs/reference/production-readiness-traceability.md index e8172c0..9fb492f 100644 --- a/docs/reference/production-readiness-traceability.md +++ b/docs/reference/production-readiness-traceability.md @@ -25,7 +25,7 @@ domain state, and third-party security review remain external evidence sources. | Security intake and public trust | E6-T4, E6-T5, E6-T7 | Repo-local release evidence and exit criteria are complete; private vulnerability reporting, branch protection, external review, and account settings remain external. | `SECURITY.md`, `docs/reference/stable-v0.1.0-exit-criteria.md`, `scripts/release_asset_smoke_check.sh`, `make release-acceptance`, `make public-release-verify TAG=v0.1.0-rc.7`. | | Reviewer UX and commercial packaging | E7-T1, E7-T2, E7-T3, E7-T5 | Complete locally; real buyer validation remains external. | `site/package-viewer/index.html`, `docs/how-to/view-packages.md`, `COMMERCIAL.md`, `docs/commercial/product-landing-copy.md`, `docs/commercial/category-comparison.md`, `site/marketing/src/data/site.ts`, `make package-viewer-check`, `make marketing-site-check`. | | External trust and adoption tracking | E8-T1 through E8-T4 | External. | Tracked as provider/customer/reviewer work only; repository files cannot prove public adoption, GitHub Pages health, analytics account settings, or third-party review completion. | -| Perfect-score internal closure | E9-T1 through E9-T4 | In progress until this matrix, exit checklist, fresh audit, and internal-score summary are complete. | This file, `docs/reference/production-internal-exit-checklist.md`, future audit outputs, and final docs/finalize gates. | +| Perfect-score internal closure | E9-T1 through E9-T4 | Complete locally; external blockers remain visible. | This file, `docs/reference/production-internal-exit-checklist.md`, `docs/reference/production-readiness-audit-closeout.md`, `docs/reference/production-internal-score.md`, and final docs/finalize gates. | ## External Blockers From 476b163c4272245bdc730fb869b7c51a108d64ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Jul 2026 22:04:52 +0000 Subject: [PATCH 287/287] chore(deps): bump github.com/minio/minio-go/v7 from 7.2.0 to 7.2.1 Bumps [github.com/minio/minio-go/v7](https://github.com/minio/minio-go) from 7.2.0 to 7.2.1. - [Release notes](https://github.com/minio/minio-go/releases) - [Commits](https://github.com/minio/minio-go/compare/v7.2.0...v7.2.1) --- updated-dependencies: - dependency-name: github.com/minio/minio-go/v7 dependency-version: 7.2.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 0b0fc0d..ffe059e 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/kms v1.52.2 github.com/getkin/kin-openapi v0.139.0 github.com/jackc/pgx/v5 v5.9.2 - github.com/minio/minio-go/v7 v7.2.0 + github.com/minio/minio-go/v7 v7.2.1 ) require ( diff --git a/go.sum b/go.sum index 16b8683..0837f4b 100644 --- a/go.sum +++ b/go.sum @@ -76,8 +76,8 @@ github.com/minio/crc64nvme v1.1.1 h1:8dwx/Pz49suywbO+auHCBpCtlW1OfpcLN7wYgVR6wAI github.com/minio/crc64nvme v1.1.1/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= -github.com/minio/minio-go/v7 v7.2.0 h1:RCJM0R1XOsRs+A3x3UCaf3ZYbByDaLjFeAi+YCQEPhs= -github.com/minio/minio-go/v7 v7.2.0/go.mod h1:EU9hENAStx/xXduNdrGO5e4X5vk19NtgB+RIPjZO8o0= +github.com/minio/minio-go/v7 v7.2.1 h1:PfBfwvKB/MmqyN8Vb1G9voWisaM9OrLv+WwOvMwS9Dw= +github.com/minio/minio-go/v7 v7.2.1/go.mod h1:EU9hENAStx/xXduNdrGO5e4X5vk19NtgB+RIPjZO8o0= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/oasdiff/yaml v0.1.0 h1:0bqZjfKc/8S9urj4JuwepX41WX9EoA6ifhU3SV06cXg=

gqu8!0a5-$LGUl#aYsf zB8my48=Xco_3QLm#wjlm?`uCTgIrX&3ErqptwpnVLsXUOTL!ACX3l*9o zQTDX=uQKh$baZs%1@nrT0`~J$t6Qf_H3&JZI3+s(b4nDkXE)&MpG)b>UHTXl6dg!z zWP~m=MrUEc3k58rqSA+}J$qqK9cu=;k6u<3ZJBq`y&uF)z%gC6qVX0oN^H00J_6Z= z=bxtXdI+|-%OY_bFGQ1vxp)^nc)Y33%@%fPeRUP18=(Grp0OBOz(Wd<4v*U0(!GwK^Tp-2iMxi!;^L= zkZ3Ir319|gvldiv|J^T-N&1Mu$44NA2*bcPn-0!ki#xGU-MB1}Qu26hvMAk=%t(Ms z!w5+@4sebL2zTuSre+-xrY-DXZW%G?aB9lRJ&x{o%nSiJpZF$s9M;GB2+V4F_KYa!8j=gq%qIL-s&Yy!XQu`gh2+wf3x4IQX!~ zQgRA=u}G{>V5=PEpj+4$S01!f|JtMc0>TabuSYl!D#&+U~8OV`K!@o9e!D6px3 z^0GVpwOaJlk|tBVrB`B`VWO_Bqq9!Kt@Kb-vEHh{WfW7RSY~<6b?X?Qse{k^0cKh_ zq!W&i8|sxPcHhf~j+m>;wfzV*Tal8&1-54xQqW-5x~|xElqgW;qq^V@{b+hFKc+_S zHzU*~p(%xD*GdTLnmo}SHEVVJk>6~7cxDq3X?(xg0{Jod*-w79uqfUgWsWN`Q4KvQ zfrpD=cw|gQPL76#hU`5iRs^jC}ygx%Hl;MTJ@X1Szsb=Nl z@brz0@X09CVpD`;IJL&#s$Ya30d<0=90|n=CJBWhkL4rP^CNxkrlITWm7{te*edTJ z6}6}+`St!W^M-W{(R1~pQ+)kdc2|}{E?0{ZWwDSi@K|SY0C5Lm4MtK*l9ceKsHB3T z6R4juyuJhuqHL4o8|?vLF$QsbW@e4+1|0*BUlqAW;6#Gd1D~QHCr0xk9aER(Q|ID|XWSlE`UOAxDb^v~d^-`98TL{IINAqu6M4aiXWf-WE{)4VE$%;?Op0y))u&a;Kc zQZ;(cj$_Qa9*YyS^3bOCz2G?Iw=JU0}#$l0$Y<>X`{ksC2vC zCRy>{pAgh@k2~2bjrza;M?)##ussl)G7RmJ34#?ek+=}?u`bh z?f;Z{M^}f0H7gEWeP8Y$9=P1M?UMl{X;?QpwU`3FsQ-hY|Mqb@hXD=ewK(|1tc1`c7FL^!!Nm_Y|bx;X{Ck#7_S=IH2Hsaq()whlk7r+RET!!r^9 zXv2n{qa^SQao@I8Mje35Xb#X%v%f1`dk;LUbYJ6_4%qI%qBHs?GfVlUz0CrVY{{zM`={K1;k{qBufPNj`m$41hP2AUTqCpkaDm_Qp2EW4B+36N zdA-CF4SZAA-l(ubdqf8$B@qCn5r6>waQEdeS4t7LfrG5&Sv4xA$)TLpLrW@GZT$~| zfo6AIe}v(eq2L5H7aKb}fJ$z^m>Lc#5=Tc*1R_6ohMmFJJJ1ib{QQ0ZRM~AD7#Z)0 zi17#YJ=ov=$vw;XL1=fq={?lCjVnNn#d|~Hd!^lBhwnzQw}-Aka0o6$90_l7%J1P?8_FFth%E{ak(5qc^w%U+$R)1Rjok zr1Ki>eZEZ3NtW=OBGN|Sk#t`gPb8HF>1GU0HmRt2>(-CCj6SM_R>rq?bk;*U66Eix z98CUxPr|aj6R!L1ZK_D82z@_BO+az;*G9+;clOhA#)SfpN6{dN!HlRLLmv z?x*~K(%&y)<&x>oFnf~{E*?3{=ep3oJWEACon{zxj>eM)kGbx-i%ywBr-iuAFHu+D zkj^6M7(V_wUGg}MxLx6zv30PMopP4(8<)IK)EKKmIirY@j7p%x6lr%4y-1!FB~CF$ zZAwuQ%gQuM7(o6vD??enHGY1dkV1bk$;EEe@h&Z;%QZ{D;~}nYh;lLx3O5+G_&p`IVRRSImsg~= ze>3t*FlU=CkZs+}8+l(4a7vCSfI!~*0)*@c_fO6a{OUb<)gk!&<-eCesN4IG|NDP? z>rK?c!lIebZuc`BQOg%~7*|)`Chyn~!9Fx3{m_wvkb<_1Bu9)5;pK zu*P)TOo{VoX=#Ot%Q>v)r>3~Qw&xzMO|S!?hsG#nu&gaDbBno#cWMTG!637WVyxgfOmXth-(bC344Ez|3GGJ1IfigH>5^@@k|3xE%9c-`HDP_M3Gi4p{& zjLoX$1bp;lg?nu(rt6C1adB|4lo@52hU-fgfuWB>(Q9jKnwqJ)Y86aHz5u1#r96Q- z5gZhRfX!mDbcwuM7mPrNd@jQ#-|#;!fVRctg75fw@^|Nl(5k%Pw2r_|S=BV+mzllM zDgv%AZgIKe>0H-<8xbJWLjndBIe!@8u-lb*uk?9?{re=&Eeqc13Jb4KPXofJikcc4 zro)Dc3XZ(ZPQr{QV(0UOG=YhUNiU#?fF<|FKRY5&s}Lai@VJ#hkTFGjz8wGi`S|taiAnt4{V$zvp0%FD zw?&0u32=uAz}$#{*UeC$>F#*`XG}$9B`!Mp^*!hZ76Kfcq4D<&Hpy_1U4K6>=?=2< zMIaO`^sVK{ro;R(I;||R{o!u!jHI+Q>o00(p|6E<1e~m#-j6rbDRJp>bfl~NBqS&p zH2d9P%-_DTc>c-qZM*`2<#*-fPLn$+T3Zv#Z@8_a)V z1a6+118-U;pSUZ~4y9e!;G&wm{NnJ@eUB&w67ta4P(U9dAzwh?I;XC_#gAGrhFiVc zcBze$uHJDSRaGfD^_Wcg;mG7@>yxDMOL57gMR^Kh;*X!Dq(_GmT3R&s3!ac4ph?(f-hZ-4)7^&e7l2q6M@rwanU?_aPJfSi$J*8T2S<%%~`K5+9m=6x3k1ZJkE zSXh0{EvHtu!c8$p(q`dcVeSp+w<`@T5MaNm$0_giT z`F-AtJC(g31~cOmGUVU+&!QK*>#IMT&@?5*#l_TFbX2HmDOFg@1adF)pFpkuCH8NT&M`eqp(2r z1r*H8$lDMfKXR(2R*~bur1wi?g#%wzfY<$$%mqBpx1z z^$HpailW9tDa5;=Y1qJLXA+x;T;lz5yj8sEQ4zWw0SmfJ&)UGM19#>Oxi zxKU+)U%L}$YjJ1^2EPS$@*BlnUWQy<)wH|+{pxZV<3R!OHPRhs3yhhWS%O)^R0#Va z$h*s9=b_Qh57=qY(9tpJeswyPL$vp-A+~nfA4E0V9|%x(0x`wed9nTJuW;Gc<1KD7 zFeM8OZF_qgh-nC?nfS`1YbQQ z*m$+Ud=WVs&f$!u_OH)%H1+?`tIUTYIV`og(oQ?DirOi{%xO(#oC0P+W$Uf6KRR4M ziaN6M!$(aaAw%iSpUYJlc{#zrvcINrShhJc21G>rAj}E0CL|_r!nD;}l>6ZGR*#qyy)*IV@&sfU`K=zAayf78x4iu7X;Q6_^gRT-QD=Sk|OEw+( zM`&3kbvO8sNH70_3i7}=S`t%JA9q2$5jW1%!_+pegl<rFx3{3bEj1QL zCeZtJl5HF2>2D`!P-XEXt?dA&6uGPapz zJN(r*6{S^!pVDmY(bo&*Sw231=i4K&pR{i885tWFl$Xm|7oZ{iQm-Vsab zFPhR$l*2bhp2mN*emBsUh@@D z-6yD&@{SXS1Dh;vH-{#Z+q;m6`v(WJnc0MQr)ql750t=SU0$;2biN??C$F6TpKR|Z zhm|@Z?$Z~NuiHS>0?)YuwthnE%pJ;ftM#^rBc&~0Fa#0IkJ%}wWpG|zua;Wn?*JkM z!$V{b5h#SbpX@dFDk%*B=oCzRqKlrHUH;XD0q+n8w0wp8N6+#P+$$RG{qT=u?Emep zDeKG z)xL%`jrueCvEyD)~mGZ;CW z`ZYf`6F0UQ&WhOX7zWY?b5}*H$4M`t(4jWiw5g7W_u0*!M|aT_rIMxq)uoc#rvYZ;@-hBzAaZq}a|HGfRy}wL(T6K2sfx)I+%PIB;6V2E* zJA2^=CX?ys3+1>EDt1?^Wn&H|2jKvq$lvvTU0Ys5fbz zskHRqyH=2BEWAXCNC%zF2EFHa5b-z(jan4b9B> z$q@3ou_@2ZHc?_Sq!$_@IKqauIxUBVg?709hUzsiAl_BGy1G(Ot5Q&q13E`X$Yu*< z+nweylMYKN5%b9u5brL6h4N!*=f=kq^@n=C<8u|1mcsU_VwuQcd`2;V2T}yBIve60 zpyl9n+1}3+{A~=L6bM0*`aZd{8m-e9+-jGUJj#v*(^B$;@3JpoNpL#WJ5H?wyNUNp zOJ-;_$iZ^`e7!aL=W(E><(j&VPJT&A$MndEp)Y8u`Ug>UM+ZR;OI+R3f>V*-`{7xq)eC>-|Ax;&<710x=omu#tR~nA zNeME)xzSO=!@~`FT3WazfdY9?OiQ4#hQo01+?lp~CxPZXG)3ehe`<;UWduK;3yIrdPL)%+NWx00k z-YNppCEYF3A>E)T-AIFUcb7;@ceiwRx3qM3cZYQBljXCXy`J}b_dC9C?D4IC*YF;C zU*~;Za~|_|98>x9q5Ph$u%@zRiO2oU`|j>rFz#ezra%oL7R~@jU5yMwURz%_G&IyI z{ZXkTqMqz;xU|Dr59$%JoNP{Zyo7fJjQKBQ$Qsle+7JDxLkVntClE#AmVef zP;ffWvK*+}UnH`cZ%^3jbY_Z#rezR?bDq_F`V{7PzFpSS^Tt{|x4;Bd;v`utcK&c4 zW^z19mt|;r(w=htlVrKhtvx-x#pjGV-w&A|LclDBk4%tYGmbj<-DWCfbZW?4{|bj7S{UE zUm>@a=J;&^P15;7ws#B{{60UmwsD|D ziG)RId7tN5CY^OUFw0uIdD_cFbT<)|@A;=Eu3{!~V=!L`1}B`RG&$ zSSgp1n3!m|TTC5_Ef!+AH(8X-RV`HY)VXx8MnrJ6IV6sH`FE*WlWC3kUwoZCTr8UF zjm*))It>a4iRUrd?2io|!j4vo0?lHUf$q=FPFm&qpsON7{bH~U@zL4kwzUO&2RmI` z8yw*DbZz0=SQZ9`;a05+P{&*z&Vgch*y9-(^J2psp9SLI3Rp@`9V8sdw(ifM1ToDHlsd{xQUKK?#)?E zMGSTGbLL>hKKOWcv#t!dVhyuYF^G{;)8CuKqLIWyJkU}=!W1O=B?)eIA#+|1M6&ko zoD&$~F&h@Bu7Z-=C7BVXZ9Z}I?18>({*eD>EN^ma4d&qH<-e?#Uj_f~Svb+SyWF`r zkd_G8t)ZTz(xI>bV(pPgJ52t);Xgxos7OA?JKK@IV6P9xgPM(WB>5*kHedi=ntZze zPa(p-wGWf%00x-w(2z@h)z6mlrI@WR8$X2bvm%!iuyyASU@?dzs8A1aEpzSWRD-<2?yDmii;6(sN{qo;E^So zoH6tTTm#pT6A?B4_RWnhi4PO=@+FfMyW`hi z-iEMIQPI)i9W%-^MRZiP9(+-1nBXOu9rUSPW~T0TUt{-t|KNb6y~DbkIhETS zo|&=2HPPbzH8sv~>)%>H4Y?0G^z(4@!h`0ol+!s#^z=u5movJ=AX$xsf=<%C%Jv%8 zlUJf2_tvrDH!JvW^)fx4!AO;=74@bLB>?iLPACmUSUY`8Z@P1jrJ(nBbdXeVg`YWJwA=wR_HGFH24 z41Vhxq_S(DAK;pUmGejl9+rz)j4|OcDUbr51A9tMjK$ zY`@VCZS0IQuHA%Hnap#_km=sOk7ag8l0@Ug!x*Qhuz2|PIJkpEa#{s*4gI@T-j6*i zr)L=PV30hTg!~1&ON@rXB>$(kdZI-x(g5@-e!HNXy{U3d$HPZuC&-_tM7B?SfRi5s zCS^BjBu7|L-Hu?K(f*i))QAv-CsAPP6vtKtB2wy4pOC0N_MsOyc7Fq*!cFD0I2k;gHst~A_QmM5ZIYuFs09mFJBg%&5U$5K@^&iU8zWVw3F(J|uTC{b) z$jFS4i?F!5{l}4-?dTpdUxbZkZ$5d0h)-P0(4bQQd7cbL@k|!QDVqG26(>AR_pvld z5M}VZ8s=~nKiV6yfOgLxvlGWh3x)5BEf2H4~ey=Ty6I*IJST zrLb~X>>}Ol6-tN+B&)tAuFqL;9z0O z%I*h0-XJ`Fz3w{eWitm{04E1N>6rFcS2F`ED-^uKmdU$XzOwRsQAzV>@IWJstw$1< z8%p8nWwSCi&WD48<8vK%48#VN$^2N3u-t2%`C6-m&$ybQDvBEJmm2HOZQFc1}ml`aLsU*S7u z6T44sx0gq~b^^Su?O*v*d3{o0d;JW1l>E-OALh)nYYFXBeWIgXvwZ^sj4sVx(4%35 z<+OVCzEj@8bzEOxTh8o&G|F|djg4qLJUk|*;F=709QH8I8Z^qJlx{u~yX*PI})F-ZI}j87RovZ$)EI%iTk4@Mmc$^toAcW*xp3puimvEjg&dWBa$QG ztiF$YC+)Fimx_pb{pS>(g*H_u7MdYJLiykfjQB{BQd64`<$AG9bg_wrUpI$$*hAtv zeb7f7fI<5wcri%=jd-+F%-V@uz3Z=K(N`nTcBxKx-RzVo$gBQ>7@Y}!H3+$f$gfk_ zn>vp`A{H5qmWqnpudbGz_>~|c@W1$#3$zhU3t-m;OJEU?V}L#Lb#~Nmh?YNqUSC&u z9i5(@nYm)V@$Tx%F<~v0+sSn^$il%>-Pl>ZGnuO`FqS4O_AvmBl7oZ2_~yp-Doj;Y zRY)xcKVbS zOH1~78a9{Pg*FHCqiJm&v!;d4iQjj16=62-ojO-YMd&r{9UN>xMU5QeFiKWbpyb9r z?V@38Pmy}5UHanybr~pp4~@sS+Io6fIYUWqC*>zfTAMfnnQRYhen>ybn|bsjZquy@ zoBPc#zEkY-JKT_(kGD(f?mB@ zT=I0i7wu|SzZC(Dp4Qjb1M+u;xkmc&MloqV*FLtUWQk!o91T|Y5Awc!n{Wl`?1p?jSwqgOS!E2FYIHF<;tC& z@(r@6a5%(V1duj-K#XUGn!n1|9EPnZlB=XRtXUfEs*@&7Z7ecE zS-w&^lM^k`V9_|2pu?u_4;6`RaL_SZvwr^HfErg(u)A3H7Xn`klQ19N$Q@&Q7< z$wDCboyo72&_%T$x4qTk-n9^S@5Ed$_OY8{mBA@MdGN2+*8h_II&O78zT#Nq`eXCk zXv3T6nCR>R6@4bRdPI)njebmpDhs!(xHxDpD5UftQfjWRc)59bjBJ`Bi2Xf1(=%nR zHxFJ+EU{79c6&6vp5de|ogsb*7LCXeshVj_GQmu<7?t1#wF=?5=aC-XvRFT>5cwjtlb^vvU z)=0Hhv;L*Wlhb|g7$y4YF>lk{=k;S?o6lBX?oHuj>}12#%EOJoLZMy6MrX|TNuGez z1W|ce->V z^`j1ZLQy^ryYr~>83lm;0fDxiaCn>MpYVuykP}u8lZH`egcI@t5zf)gAn|M-7%FYK z5pX0OzXdIwqU>GHx2iH2Qt#nMAt0v$DU69F2@d)aojOMEhe23P@Le~!WKURTO0{_? zp}WC4y}#67LI9tPSDUM;tKVOjjyYiw@F{ACCH<G~&d&P|KQAhP-PlvGB3euC>K?emV>y@#b@$42MK{hc+bhYZpAikI5N&jGm! zzN(B9jqWc!jk&ci>+KEb9DlJHH#$y;e3cTHpMKn2I6eLDtz==gk62Ux6%UUGL0@vo zWBYvW$2d~m^_(fvgm#nNy> zZtLvoYDI?xih+^Mp$RX4FMzz1K5uypbLeDSwvtObxWZ;LY%GYuwoq<)dtz5UHIW$h zhLkouIub6C5xzrT{F*ks+KZyX`z8nKE8>GE{Y(a<{$wmcd_Mh zx!ng2$Wzb=IF%!P-}x<*vppUSq;$~GG{lpcobG*tg9vGWN_tKWPMahGC$ry$@{nqy zx$mKF?fRbE&UzWzU;$0F5c^lZhD!jn4s=bWZm9Twy(gr1LL#cG@$ zt3SGw6!P+es+Y=$X}F<$T}sP1lC70nW(a)A$%XNeW>6(ca1HI~T8*1_`hT*4Ztwyf zBdLhbZs2=Ytb4}>&K5Ib15y%JK8ufE&SgS01!#q9>VsVD&FA&^7&9yXsA4gkBEp`4JtZaXLbjWm$4X4ONTZhlalaQx?f|W z)vdT4?!O<}VaD9rMDIC|UvEqsuL-|Mx!OcPq^qnl0|+oNq};n23q3z#@}>{E75OP6~?bgUPv! zOp*+ej)jH!myoyoB!q;Tu6JV`P*CgaAt53qH#eH-M+RgjpdX{N_GQ< ziLx7D5y7vJ;1HTHT`3L6b7i9L>})HKmXIW*#K26;a*>;qX=G*DQ@z1-Vq&7l&bw$`n$uD-~GX7u!YPB(}dAFsmU!_1oE!FF{q!PN`u8Wwlle!U7AhZ(=v;9!Aut+3kf9ZNr$%tH$36B;3G?0C$fHG_eq zPwr}etI0q1rd)w9{>?<~Kh@Q|O>XxL6te&Z;b;#)lf)cM4Gj41eTrwzj)i%tJCHDe|3=)Uz~N8Ve;Ir5q)~h_JRWGU6Q$+lxgE70t#Z)5i}uCR zIq|FM47YlQHG?_Z&R9-I`(ejBrzg8oEPM z!%{V$sasjIyz+P^lzGj`>5Pi{B?%7?0RiDWKh_fnwbI03hAT~3T?0j=^&>s6%qlXv z&pTiTd#4*eRDdXralutWMms&E_~Dl_R2Dh8T#h99c8Q$xc9F@nU}YtXwuz@1R5jkT zyB75~+k#-+f`S5hg$Xtl<+it2T=wu}lM@pG{ujx`nFUPRg4V|QULEPm75esR3ruMkN3wS?2i}i2TUvkeG9K+XXUBMo)jXRyZF_ilxYI*LHJC&F{Tp3pI(kpG7u{Ug z%*y-vhjPSMS5{yiV`5^u_&n(NYRf8${u}ZF&evcd0RVMnJcC@()B7PcOt;N~ik_8E$^X_H`iq{zL*P|LZ{Cqv34C(C{QY7@rn5Ple_0H*;@hx{9iQw0KS64^WOzZGcz*) z*a1Hu=={qxFNngz05pZCM^W?lqagYZMKbvh*0G*R0tU=!dvhhJ@Ym5D=^dv+zCUuZ z7Mjn-j#w};FvB5`MYbmj*x--PPE3sRBja0B0U-wPj*pnjm|rDn^x6$hPLLbZl=i`j zhxV457Z5$-rVi8o-&uT-9Gx8d`}^KxM$00Msg9nOTlZP&Dd>TaoaC*OwQlu>T{s=V zO%Ra&Mc`xX&{S1RDD za^Az4Z@^4Qh~Tu{F7@(5ly-jEUV=hGQYqZngpb@DStpBV zVq$P8BhBDO%*x6-+r%znW~1!(W`B`oBC&{jT6BC~Ff~2x?Ne2z1QcL{Z^TgV_|a(S z372ZDK=es4E*tB<`xS6%64h7giLH%cBhRv1Ukw9EuwSY0F2*3xP86xhPJ*TB&CBYT zt)W!V0SgWKr>0t5nsdPg{#Ghc_X=f{2^Yq#Y+``Vk9~eA7Ar0uq(q}>e|QH8YKaH* zf6dPy1UAsohvz6CRU}$g2pN_fd9Uq3VE22<939=8@jN-(%Brcj_##zwaDbyk%Itj(&R}>+>+r}3KomdN?*w$=Qs;vY z1XHSZ1&7nDP-LcB7kb@$XSma3L@{t#SKGqC|KttuIlNiV-Xa1@%qkB>n?q*D~HTrdGg zG%OUu&DZi(%U=Lt_$6~PbN5#;K>|Wlk#fUi(rJb=xJjV@#hu=iJiQG;Go+xIibQA)1lyiVCVqnnP}L|DOz|(_J|rcp z52kW)nI*7te6lt+{@Rl2pKB@4~pGZ1U9U=C@rv*Ve^BsSe2E_2m5?3b2RFCMP$!YVxHP>NE* z z04#Y>^xQfdAUihJRsuBo1;1;$8P(Jm1||zNOw6;nRjwBr#*60M8%-)UIJ5jV>wVvJ z)m7vy%+F_LWCV28#3ulPm4cY@1Z)+kF^7bFIo~rd5FF&+_!rp|lNc+-@H36U;mG&u z#!+Y)${0LhdjlD1R;zqKk0MSmT=!=pcn{R_}%`V;w9Xb-chWO}-~pc;;j>JIaamMoSl8lx-o zB=(-&7>V3E;Ni^(X#?j z?<0&zR`vcX7v`o0Fa?j81Tq4kJe-9jl)2V9R(fJ^o*07vYoPnDPx&_?{tz;fDdGa~ z>B^;Kt{O!e%@23VElgvGG)A94_aNe$tUgM|A>L9mn?Aaz`4kf6{|>7UCa2s@2%j z{^JjwYj*!9s*S6L>L<+0+kADEV*?N0V}*wws`2}`=W~EI)v7dGb=*AjXvvY%Nlps+ zz27Stl9`i(i$Z{b<4k`gIh-q#`R00W+Yn&22`MqoxAx18P9JnLI@%xr`jKBy5FWcU z@M|(`hhZrYb5MvEDI*gM{62$!sjZpWfe6x<7Z4C?N%Tz2Ro1Wue=#lx6$X+WS5gE# zENpC~W6%hAuR4)qkuPgq0akR-dFHqq@9X0u{9%5n#lr%um&W?_8sqtg%wN=$TsA+C zSMWc}IyW{Iw;D>%*=*rR=hPHHg%CP;ceboJ(2}jw(Zt5YK*cw^c3OY70vJQH!{s2D zC5EBL)6vs=oMrRL;}kXnywu(_`(QS#b^Viybo+SJI-r1}b~&xuciOLQz$*s8d470^ zU7b9jVtpsz@pLB&Wf=Uk(U6Yy`B!+`RFS$#ab^*ZNwsI6a8==c;r;D}z!z=pbRVCr zl}vD$}DkLCFL#!k|H za9CTYB}a)jFx0``ik6z5QVxK?AZlqai36@fL16+=pTHGx`1FPLh? zrbfX)-JPqUAF1u@1HhQN+Wg_mB_C0W?(tD$HMzybU^YeF9|qpOK0CX+wpvd|+Su4Q zsyoQeniCNv4A6XSamde!&zvsyoj!f~WTd>ar&Lm2Q32YUUR&qAN^)mhR2^u1JYV?m z)IW2iVi*X#M;i9GA&L`Hk`g&=-_|~D1>@(%;vyXhHw`7%S?`+Pad`a3T>N$H(8N0b6X)Ot0e4oDBeq>M z7PD>kF-YLe`m~Hl;=v?%$Jt2~zTDNFG_NFY0MgO|G}1nww4{DOFCG@rY(QY7&hj&C zkiXK_;gEQiRCF;YIA)C1KT4c5N=xo8b2j%*y{1AU`WckH&MNpXgnFNn`o!RXLO zl&0%75#@c35tS7(`059W$An;oeZq?~=5o0o!dqii+IQ^ZLk4R;|hG2cOP z@uIuKzN)PowNC) z8)kN&IO^PkmcUfGT`KhrVL^UDE;A(@=~YuCQr5lvad?~fp7CB>e2ZNtI9gQn4u(?^ z5kbKcpFiVLKAv7Pw;_Asr1?cg2I3*VM*Ze-cIrOwA@c#9>KP#%EchX~>kf9q^^bbS zSDOfpPE9e#@rY@9Y|i~4^Jnbr#p%J zV#we}F*k185&9I~+?=B5n3Q*JU8@E|XaV-$DiDAv)v?xP3|HHCa6Jod3-vK3ZJFUk zx+MLT`ODwkW{UbcQGi`dU&?RHc;S4zu350db_cPEJ4C4olLxNub=x5ER8G6^A=MW+ z%oSjca&fqT&?MJKwoXk9>i_Ow+}o>OG^}R#`>vk>Z((6!g~x93>67?G^k3}&z=l*a zHZ3#Lt#=`Ke-tekbEV*4J%dc5Yn_gf(awSk@!phbn2ZQ6x2N}4-w zc4}Ri^5&od5|)FlpplLbG{sDYKtlh+NF4_(j}!WWa?*tN(g^w2cu%%D_Ko3^yv zo^)wdV0bBPw%z?QrOISL8yBFpxdl%?Z?e`QHuK7F*|S&CVq3RP$%(uQ3w_Rn8>&c0 zxXkcMJ=BIp3xVbbBvJ+AT?# z&(hg-C~X%AN5jJGS8i6mD2BZSOp|aiDq$S}`g&pRgGI*@iJza(*?F9=i5%~~rBUm7 zVhq46oe6^r!tDBXQ#cyP>j{u|+kk}UXY17YsbJE~BmOFesTYL6_&>CIlQ8uyDnZm7 zvSXdSLBzn@_2kbr19=J7%RSh?jXq>5{MI%pDJ=Xp_S1+N!>nvZDkSW9x9G<_`&F!A zV}epS7=K_XYd2mX-jc4r`jb&ZYHIgaM9qzTJr#prWm>Y}&E~=F zy*U)2RsA#E-SUaVfb0(|);n`j#G@ub42Y)3V&ZH99iDYUV#H%Mi(3MpzI{6yqwZ}g z-F82HtIR>zgMv{q|H@;XL0s<-2sd*kjx8*sdT6tM!C@?!Dn*AV9}ALf&ghi1YHNSI zerwjaX=>PBY8VwSxT395iWY{=B=f$1+1yb6^G`1j4s&d^@*QF3$Oe1rbHRqd_Ea*v z)#>7bi;|lgD9!l!hL`w&-In|(J|Y2wW&_5}A^<1{2kC&_S5N155>i4^0^#`b?D8_u zKZvY5G&p!cx9U2qL*Nm2YGnzeWQ8Z&f2^5p>>SzoEbKUK?&8A58x73oBUIu?lu$3(?c_6ome}+}50Nbk;}?{T7ZJ z6g4$9H8cjtZG}W!VxuU4Cf1Ylmcq!WSfvUUswdTXhaaIeA2fZSP?l1VF!L*-^EfkT5|@?S3S-@6XwaMV;EPWlB0b#dYg>J20Lo ztEj=K6{m8APha<(X^&MPrBIcvh>E`C6+$RuQc*{5?{l|+yKkWYYGY+#;lC6z=Wmg~ z$hNbqxB$%X2CZ+8YI%0ldd)|y0_1afxYrypWDOSzFOmnEcz0q|5 zLqp?`y0}{#75BEoN=lPpx=BG^_|*-oWRBX=(#1FJINiVj&&8(Nw2w^pWYOq;sqAa^ ze5=GDGHezyK}uHiCZx#3#mZ{-z$U*i{~N*)7^c!5TtDz)`u6opjHu@3GdbVt+iY71 zEklr)XZHtp3j0t~=TjKvw_b2d>P!;MNdUfp*Y(cycl|+%xuj0Ch`?Fh>RyX!_{yk{ z@33o3f=Zh_2*~i|5LEK;Z^YX`K{tGDW3We~q1BqkD9FijkUWWD{8s1CS2)39+KK-7 zG_1`Ud09GMciFZ_(Ip?MDT05!Y*{D$XhRNJ)%%(7Pjw6bjP}8oDl_GszPo7M?hkj6 z7;;ZR7=7t=L)r#M>5OKJ^UAY(lQd=3c3<7b5suC*XONAdNbnPO*JfNw&E|HV1+J~E zex%dVmN_9%EdVL40>938gXcygzT6(vv^JY`#4LRKc9#=!K#}kQkHrN3LjT?`pJ@>q zHP`0jlflOPzMk{l-|hYS*h|>&eL;lHR}E=_4S!nu28%#jTW;9LVpW4rchr{2B;$5G z&Zmt{-6G?RAh4c}UoraxT~As0Xk~qIY|f*%odbk!wzu7Z)2hahbCGB zBLdjVL87D`;oG-1y*2OxFNitE=zC25;dvJqjrit3J@#u@ILPOS89Pmf(3hrYsHU!E zGa+Vs`q=UMdM%j9%Qj8xF4wD!+g}Ch>vl5c+E$vUAZQ0-Q6w%y`KKiH8ksz${rFSo zZ&lKUvgA&^pjx|uVP0yK@!={DIUzA?hDnT?%Psj6aO2`mzI&+GIQOcJ4X_~eSqh7~ zvho?&x}lwZ5e#pu?KrFZ&TgWN&B7;aK;&~N5_ad;(0)wZwroi#_HFHXEaJ-a5*`>R zczsDeyN6M*^a6SL>qpJmf;U~{WlLq+tLt^84eU;nZnqdV{^qT(j!`bKE?9A~6p;jM zQXx9o8!Z|}1Z`wcR{AyE+n&evBxZoBtXe+{hGXSB`G*2pkC(>jT9GUit*sG0HtO`6 z>J`>2fEzuw%6^Di1DRf#RVq5?eL`SXmionzUCD0sXUxuFEFBN9=RJ8JFM-pde|xeC z_wM#?V-F;=R=b4Aj0S!eWh%D@!K3+1k^zgA$Z(&{%G7mk8X-S08w|xw2JRv#5Ydu~ z$;t-pOFsvDM96-=kB}Sf<&6d@k9~0f^+~^+DE?&>5rdiuA1Z@`ea{esx4F7XmWj&` za(bw#O+M&Lf<;sSl?1UuZz5Y6UWejsuCK@Od$ge#D_9$=C@Xiq=0V&2DV6%27`D{@ zcLs)-^4q@{K9myVlU^lTk(QPPBKdpG#~NSQ%$XbGEtdrg|J@Ygi#{Vt8n? zyu{c?y7g;PL&vDXsfp^PS5FBnue&w(4(b^L-8gt$6mWZHAGLB~rD19x#5E*V% zp)1I?#)Y&S0w7MctG^%j0o192$w*M_^9)Fwyzad;!Eg8Si01vb&ctGQEMJd7&hCjMB$%#6)xMfHSUgXp?(Z zm}y)csA#%B5jf^taSehoPv|x2KYtOp&KC(yT}%=wK{cHGjN9)uOn3$$sFmiT$JNcH zjU6Y*2mi-XkDZm*sKs)C4L}FsHE`f`tLrtE$N7Uy+1O~1=#W42Dq=MQ8PV}RJ395b z7j{>iLyU z!10dOi|OvJle!i|0#OJXB(sEffUQMDG%o_7Jix1{_YD$^ub#?J>5s@8c?Bh;$i~dm zt!WkaEGb>otoR`*=-_^^oi@_0Drju{W*EdQ%CAFZf|CuRqE1+N(>?PIB*P;TB(Z&C zsOe^78}puLkO6N#ZTDkm*T)hvr)xroX~GjrUPU!E=eCKxxkg>GyhL;!mP-yIn$@<2 z;oL+e`jn>aYmya&AN*C^E-8k3M)_I1DPEZdiuNLl68t4yDzr#{w8*FBN3emSDL;8M zYrhDAtU^B?)!v_af$#t;=4rIxAKLnZ26d7H)DW-Bm-&K_7jhv8#L48wQ4Vlw4Ic99 zN5(Whp#a}qOKGy@-gvPy zd^68ojK65WV^*G^=7D_*E!Pz)6BUC|Q*B3tE2ev{^D&7}35j=>1N!RUc>#wU7sPB} zBXlD$jD+f>M#f{h(s<8nH6YXxy6tEDOEAmDHw+qY$q+0dLr#lN z=TiQpeH9MD>VlL)=CS)K=H@hd55yM{*+YmS9E9jUfX8%P<6d!ph>r_00xQbZjP#Ap zuKQy()RF*Ep9YLu-+E|9+|P}JtepI_r()G?JGi<~o}Sjj7(?p_w$sfO+$X9xdD|+= zM{660_*PSi)}dY(^1*T;4PHVd=#<;}k|}UyL5B-CO9N#tTU~jP6RZ|XY=%EJFVy{V zQ-42ma)R6)3nG$of~4JE$HKWgrvvleNosRRwWOqqt;F2{<;CQp#Qqr};lz<&^F90y zWdUvN8+*|3at*ks@0-)YU(~#s>+#%9t+icwg%7`~f0lAzlDNaJdoOP!I5NK_{jtgMAnqDF=!Z<*{vB*njg5s zMrZ^x(jonDQE$55wPOMb;?ra7I5zn57*_o#zRzdzJtZLBlTMAtJm#q{jQ;%)D|Lwc z>K@JhkXJ?ec&BoV;6>Fy$#~r6`8D##WX?~~{2mh?>jq!Ifk?M+14~PEj>$8(>C>*O zzjfJWc=B%(j#jbmv}Lj+W&yTQxUOw?X!~<;bgUBCY9yp@aAT?a*Or{r}z2!5#K;UpXl|`v$y~A|n?0AAmpgJSOUS9PB0* zsx>ABBNNk)A0?onLzR<_0JdlaS=o#qs-FuRoW>sYTZ5@n2;_3a^`)EOfk)c&g^<}$ zvI&3kVlfUDizShKZLN20_l6iUiX*V!isvXb9lWXoLJeU6*MC1}XtRXK%xjteYi|B^7(k}3`GJZJzS)6t1;R3{)1P1%BA}}d zx3`ZD4l2sazrNYU+1=IG-wcy{U;u?cY4IYwo!vk<>4#rztiG@H^z^!QME)ZfrgyLc zDAR2ax1n6g((!(Owts(jlBHG_D;Phv!KN)astqw z*z)ucVBC<_>Tq;_{w3{VvUQKm0@Nu<^hrnv2>498)1@oGa*!}Fr*S?B5Eu|nP+HZ> z3ZaT<%2$dmP(RTXJTak=pTCP+R49&t6^hRVg}S%93j#AFr$!Xw8HhRFO|-2H1Dzk{ z1{aIxphyD@IsN_>>-0|+Dd7JH775^3pL%=GMMnbz#r{gLfpKmD%ThcAYCwxk?Di{; zQ9(gLKmcT=|Gq>516(t^bg&i6*kli|iLO`2=@aBxpA_uAfXYoWg&VR1@H~toj1`H_ z%e_>+Oy&1r>XI4GS?5Sh%B5O+lLPC=jZR&|V!C02{oOTo{rXp# z;)^Az;(~%N;MwswlfsTk7>QRdlC^g4-~t1CJimX31-t{+^48kaxctz4m=LyztSsyU z`ZDI5w{J7Z1Y;A^N-UO|kB^F4pNaN$XJ1Mm|Ct7$isku&gEumKygyT+f6e@PH0I^) z`O3z|{V{K1gf-=rxlX-SDo=w05+S47kGx7CpRd<&aBzSDa!uvu8mIov!e8S4H2nO2 zC*lCZL`Qw??b*|l3$XiFH-Hx68D0qubQ4V$EODL-T&#z>JoL%V{t<%3*zV{FvoZG{ zsWn$0otiiMw~Vcy3CbMP!<~h0>8Y4&omZM9lYpEvkd+PYVhV>tA64ZekLz{B6N5Ha zHsvERM^y1ULTLkD1&@^^<=H??tV+H1$g!qYyc<8h_$uw!>=vXPQXjB=8SRRK1@CDygpz3>%pV3C7meeZbBH zqq0oGcgH0F7HzzX=4{HX_4kTA>;6L$Nh>Q%(0D+J&B}tw%1@ft(I42vYAP#{Q4R{y z(-l-yI4x2}IBjhDlvY+yjzw7RY5Lo|Zc};OE?B7o+QftZnhCi4*5vh|c+#ZdzW2S%*m>|- z|MB{b@!v+XhVV71IEDvcz_Dg$D>*@lD5-iEWB}_)P`-YB4H+ahmkczy-LyylLGh_zz^q!VZI$jUiufQf{l&@#!df zz=DDR^r!e}cT?B4gR;cqjFgf|>+8$4yL)HAa{cL3Kxhg5$hfi{yQ9{`?mO_R;4?6Y zJ=+?TOuRUVM(EAUd;Z`~l92%t(jFdyL%ILIGdnQakWa{t`dTQt(0{}1s3QF*vjdeK zQYnxiCVE1~YX5L|y&j1PlqzI52IW%AAp#fD%sK{l6_r`wc1Pl^t*sYScnJxq_+N0G z%uIlL5+G;_kb#)u-Btm=N(ZB&!AfkP@FL<}JtT%-HI;AI zV8#M6lt%~B!rI$c1JI%_4`+W3bwg-^nGGD~3EqV%X*ajy>%kvO8ugBam4&Xu9|z{x z<_pd6(>{VtbF36VYc4fcbQcP%WBe01~pST)227!%j zz#SwezRACO(69pXLNzZrDJe+AdEbM@X_xGW9OpCoLvhtWaWNUwlgfgrPh>0nme(^g zz{I4G$lmqKmYAmJJsTk@#DWeb-6p!LJa$f_&K#%JNY~a1h^7lkwK_Ylmr+zKW;f0a zlP1J6y!IExH3`~`1Nt)>VPP`53&xp8O5~dbO9-LurL*ncvkL-3neOGM@E>7* zA|m>d))DO-klnovgG*l)SD1&2W^V>sBoJetRx@vU#{(V07c6DTsk>*h1C}=4>X|e* z%@$E|ah+!oms>upKMWs3Z>cvDjqL48_?zSLeYs?B_lQ}PPv?Chyw*8Axg{tAdKb{Z zXTgaaEjG%_s+c!xLysiX*VmhIAJ?gj>@@yg5*U+ zx3=d{uu+L@{`J(-vUKUhp{7Fl=+J85BnmFxK*ownuX5QXTnGxuzi|(2+IVbrp&U{- zu982Y*MM9^Y;x=(2C?`V3?MQ-Vn@jpB7{?Yy2)lO(;pYdc&+$$%yHz?+|!f!r+59m z;-DXd$ROUVfrM`sz#fQJpP4)`5XAn?1$58b5}U%5Noh)p;@%TY4(%nKDf{_Jt#+FX z#zY_o!qyo#8>0lpL`8hSragBL@~hDKmA%4ngj2;D z+@HFy)^Y@&yYo_gV!ZMaCKh=9m$jR+?HFtb+}+(v_gVl(AFWMWCbZPO8mu87oSzi- zDysegEY0ti>=S)%STYOuFF{BBQV4EyKwj3ck-=Qw*m`h=`L}u(m>PgFBlP)Ejk&}c z^H%=bOoLqstINhkQ^D;O;JT{ODR^IFUMRiqWb>Qb?Zsq~Mj?*^1UQ*6Ffd`)Z>SM9 z>ueV}wx}5p*GLrPeevXL#UE>g?aRS4@GCU$nh|~eMHRPLb$YBPa#A006 z2j)AAg$lFA%k?o}`DQ@mc<{CoU2lb7po%TNB5xFx#d{Y-a}a}2psmop1y+saHEPUp%PvgZ|SXzN*M66$=z#xO0z;q zFkYkT_)o=FCNwE20ZgJ9-yh{rJA(BfLSNVZ?NIimqa%ypu@{0^0MY+z@APr8xB0ge z1=T8PZPL5CCX<8AzXJ0z=t7NlW{RNL!Sdh;2)CD4z#J?lisK=R0-IfUyk_-G89Ofq zt@)#)s+#QE$;WO8qPx3B_)}=FbzS1E*;y4uU-~UCNMayO3#tKLJ}HTehuI|{;JIC1 z+OvUdGnZgSth3{X17kUOu$L+H)kU_e7;nburdeN3`n zVEvjJ8d2_#o%MZGTS1KSP z{DYqw`D{>p-HB&6j>_{8uu?K=MWdZpEevf(sIB?hvrX zqC3*lID_ffT;b&O(KOLiODdS4_w^t{r>Dd$B2kY|P09I!+`YIsf6n~ZvMzgQe_@t( z&;Cl(bsv>dSv7J6Y&k>|3R&lSupPh+Cv}?UzO#R7cxpkX0c_D>a@W6*qW6o8L0xK| znKy3A%c=2D-4r}Hi>2o{I_p_kAGdv_`;m14>IE_UX*0Ym7$6iV2LxV7IK{R(qRzNS zgdv{bd`kzrE&85zh%usQUl0Tnqx-{2AGYKc6%F(lH_6MQegXRd-J`xwl9`n-I_tF0 zmX(&P)|ob^gv4Y`&@nM?YA5wMW}%C13fMyM>Q|>DCgv3uW)voaU6WB&LL*(^HhKDY zwY+*N=g%X70-Dxh+^{w6H-C3Ycv^e~#SK=l@Vua;>?T>8xkXG4@^_Y(k-@&)C%+!- zala?a&(H65kov$El-WpicCm1L+#@o)^l($P30BT%ukf11!&PZCu{#{_T+q=nQ*U`K zXoyq===89;!H36sJ#hRgD{O2ZSTkNe7@oukiDOp9r2v-$ROEc9>-Nstl6BIF4mwnC zZ{b|!-oV`WX!&W_?MU;KML1jry8z{_8y$y=wzkz8ebDPzewLMAkfGNfn0svBpo>Q& zDm_zo2GSWJA4avxTdU3 zyUF*QQ|He7YU)mI&EL( zzg4GKIZ^FSQ~njY@42ugEy9Mu+F_FZTX9A7oQ(Yga0L@Ed^u%78meeKWB$CrRUln%>e;pxnvf#^|8SqWxr936Dc18HY^EVT1K@;)W-Wktgi7O{*UU>Z z3yKve0v{Yp?xhoK@|I&%rC<=Mx(!Du4m|9-rb)Aitd}c_wm5-PEXkl16z$%<_Xw!b z6%If=kBJFP2Uf7(a2i*sGlOhGx&PwVV5^d^%n_!PP@c=cuvo{!1cw$q%}0mF@iJr5 z@nX3bA@Ki#?)n?HJua|03bvs=cw$IjB$1EKxpZe*y9Ntmghyn@1_I+JK#_Uy9|LxL z=tm%Okjd+e`y8C}p;#@UMBPl7m^+-X&8A~Igj?*3eghyjcN2+T1eE_h!*|F2<_|hz z64Hmi`HmuWVRS0-SGXkc|1TahfSCR}eJ2kmGodI0Y-KZafjM;(Ac^a*gIwb5?5wLJ zT+r*yzdV~atWzl1#D8DtPXUyj-MQxE)s;ehdFuj_!oolEof%#~q5YfJ z*wxonJNk|9MZkT^9-h@WKeu_w_5LR%@fnwb0!XySr<6-2eGyK*Mhho*TtSup+h6Cn z+Fl1#y!H-}zLyT&E|J~st}SQ#)%rT|c>2Gh44+h9T#YWno-4CPmJ^sis6y3J|%&SN?$eDIfW|4mi<`_Z7@I|JVH5crGt1VBLZX=O!D zP6-4NF2 z`XzgdX$|w&nSXdK5ZXpZHuepdV1yOlNkr(rpxJBalhE_IWLn$VI}Zz=f74#lW%B3p3RdIrE5*0!po zUzxMm0910_)-dy<%*^CXxK!7GY0ELsjQ_`Fx^=8u1S$EfzzC`h*$i zD=dVBC;_IBvp<(W*Xbb=C0|CBQ~;0}Uit+Nxbs|%8s9g7QFQ$TV3^&kZ|RNj?(8kh z8(JDfbS!iLn+G@=vk(Sd(-HpAYgz<%0Bu&_vn@k70gxAOZtr@-R1;*~3hJ+F&yQAY@HI z8e2&UiXjN_^Y2~6U+vHnu`1e6YaFyZMkrlj0byYPWdJiuk@I9-1>lrHTSvDVT^+iv zAG+rKg5UI755<#~&6As8Y5WhZ4QO@&9l$y*%(vtCcDyFF9z-ATp0DwFg=CSdQDX_T zPtPU+jF}>IUo=OA%l)m~jP@%QW}RA>swWvdg03Yz0N6cg)Pm>A+|VhWK+JQh1%-?q$W|WwMRD zq`K{+P8fvn1fJrBvqwJ~)6bmsR=4iwGCj9YLmd=>nJQbq(p~%O;S0=t3w| z*OY34B{el2i)I`2Iesz!MOHG$mFf66F`AwC1V095{U z;}2T{GJW{0^jf2zh zr(s|f3h)8&@&Q8}|Gm#c;)ec}mK0a1SD1UPe03WnbTATscfXV+Jv33BpJ2KYl8+Mj z1_Vsv7!{8|F?-A|8vrh?nkmW@o=Q0-j~0Nv`cMy^bGtkRyVEf6S>1gT*?;ZcKa$Sp zg(0d*C~*tX(7c6Pu7>Q0-eGdHG%aY@PH?Evu`IWEcy$)n(_uk@oFCnJ_3Od1JV%Z0 zJtv!uQij~3+}lYBSJCg=9L{zDbIW+&+<}c*yg0ygfSj~UvY!Oe1&(t9U9ajJe2hdpB`+&GZ2%p5wah0!Sb9zm8i`X^*dts&Y z{|b8vq5Mz28ib^q$3Ng6z?oSEJw;ZXzkB;hcz1K0-y8@L5S_fxeGxOvnK`uIvV;LN z!(mDQnD(~n)-~0h|KRlW3vV}hE?IY$a9L8h#+z*N+#CgQ1TfLY+Tq(UZk7Y^T_C~8 z;AC&zuUl?vz((Wt6IAW+R`8Ry5jhD7XwdfNw^(3>J@GEYdDjpKum(cqfbOaUBHpJ@ zRE$zy`vAs>gdd^w>Z%$wi`r?tN;^7QgdB3>?3>i+e8EghJ5-YxlHTUBbzr;SS?Gs4 zebtEB?_!&DB&dOj@>)D{A|isQ(r+OxmqVo>;#DF&aeKXaGdUSeIBuQcRvy4Ie&KZ8 z1Z?H-g5F~Y&iHM>n}o1QeLTJgT=T+IIRy>=|MV$S@c=RxTSK7xg=&BI*&rh#kd7AB z`0sSI*V-^`-n|E1|K87zL;?OiWfk$Usbt|q{48j5)g;7Uv6xus>XqHQV&67YOn37E z8qbQEC6sO$QSn=X_rNV3)~Mldi^HOrt@G^PT0nn0P@bRJ+yv@$Q-omr0$B4bccn># z*d9k;7|s0>C*cMMfcL$^45#10uNs%<-m(a|`RH^lHus)3NVuy+*Z|V>fQFI`7R?T` z?6?8_y8eK~4D5$|i{sZU2;7p9#%nTDK6(Vay(hMKC-hDyZCO4IFpU7s4UO=w25pgk zyM8?`fH6I13k(H`Go+aTF?6S#VT(lr0`#$aF&lrq@hL(Dmd7_ z%F8v{0wNOV@&lHp06!UpEH+Ycd#A-085v8m(qz$p?xFdpnZyh2f*>nHLh1;)fk33@>te}c5`z0neG7AyQ{c+RfH~F@{)^`mGts}#e3F!AM z|1p@ECSQi)@8&D;Bje7s6&2yq6GZ>8u}waY^>3hxsW3twcgsYirA2b)bixE7Y)b52 z%eQ`S!7zFrCSr+-20LvaPq4q-4cLDx<5uM94I;dKa)b5{VM zw^M@_G&bAUo*>hC*w=>xglLB{ckEQRtwZE19M($x`BKC=!iflPnEUma(16^`?}KFT zzh#lHXaW=i$~Qv&`lh!fB_%kCTvI0#rc#>Tur3?Mr_>rJRbOPk=<2aXo8kd=^1pC! z(Zc`^P8gf6Pk*t@=pN7|0Cs97EO2{n_4?rX#9lkylez3uV`!RzM|fr0(rZBqO%NQ~ zj{MV9<2uAj2dZ8;O7VApP+(C}v8L>Q8S@l>{`{M{0^IONk%7QVw7aN@mX_WfNKenb z;&FxdsG!5=i)7qYO(6eeu}QS*H~+yY7qQ`3Ud2h7#ofn~q%;-KLIq)Sh3sOA9v*x~*maQm zCT`FqF5U=dO?Pq{) zl5RWF+B5(nVUA-;A@`StB|_%f1Yl?auFi?axZK**uGy1^H(&iLGH6kV1nh4boOb89 zyjBpZR-iFIghJS+#v(3{m*6$9Kgo_^nwQSkAMZru_fiYVbC;eFoP_Y>*6(|kK21o)dHTb zxx;me~$mApTwYk8+P@IsP<+YVeLCA`5z%r3$6Y5z(FE=Fp z!jZ2XjxR{H|2fqv<3T|~mC#OL;RdwvAPTrA19hUCci4hW0bSxVKjbx# z1@I2x%JqpN!1NKOy9G!e9B^o`Gq>P0__LWbOMr(G3fVS;VY9gQe`hB=Z@Z{R&>$t;OgA{p?SEyVvfyX_Pp#N`kP zY`}&&Pcv`O9jKAF%3e2t(BB*7kXP9OL+nGrc`N4`j};0Kp$a>o;sI2oOf&1s`EqvK z(3l+TtGA_f0l*X&5GV|kfVqi(0QD!nTnnWYOF>5m4N!lE-@Xs(9}?mR+7a@2>`p-f zo}b7hoSbe*vPlBO$j!_WKX!&i%w0xXAx84LJjN_WKT0-Jc$S*2wBivG-o5=Mhf3<1 zc&iHF*d{)le3twIWUmw#JzKP`0Nz~r&u@cWTvoheVbFBGsko0Fp0nR_dEu*S>JV++2ea>jo`l(cRlj?GbU) zS~_4$g@VWZ>%Nv?%6M0{vU=WTVo5^BHfo^iYEv#~PDAtE_1bI-zcnE9^oN~OY_znz z24;OKf+GI|ePeBParuvnjxCVcD_0x6ZKj6gXJw~*NJUN7tv6Gn>m2}W_38c}SZrpp z#e6CoF&oFLzdrZCHx)(i2oopV?+N_fo=ou4seX=8$b&A zRMd#hTyDX)eidvJQ#h(ff7i(SgTE@Bey$ldDkBIMSMVu`di#QzXx7{ z3;z%Rwk<}1d44Ke-Pms5g?%};&)mQ(!vJ|qxfs)IY>t5U-SGG93|pRT_t2Y){^;s2Mk zkiY-;|CjiY|C1MVP;4H_(;SYnzHaohpUT|1t3%*s z(&j4tcijmWF9N1z9{DQ5xaJd3cbkLTrQ%>kH1lTNpAgMy_UkC`D$A}9z~(#QR*Cfk zrc*lhmSY=`iz-EG(%IQ*aadQu9xF{wtKtD{Y;TOE@o_;M5|%CUP1tCTx7y9!1Vhu-I{cE4>R!ff8F1__bAe`_FfyyV zGj|6&i1jIaWVCFy5AS1h;!*m`oyx}FUUG^%d>-i2+83c@CI*=O#x_=$VzxEBjU89a#3RA8=00O2i0y;cbj;t6y3+2s0|H+fRqv z+p8WEW8WXiWV0OlBwN!M`S zfbgu@W7wS6Zz`!)OH?sjTHX9a_K~8+4dE5#3hfAV<~{ ziO!_j1T#l3y1O<8f_Z%bBn_>eSCW4V{-d?{$a4QiuSDsr!5pDGhnzTD#Qf!Y%(9 z=fAap%7B3$qs?gt%&7P)Dh+zlMA_esZlge|!abV8J*9L1X%6SD(Sx#w3;W+7+Y1y0#dLmax<=v;99k%yg6UHe^Pub{%U!jSR=Pup*8-_6f6cnA{rK8b1oUUmgWz&hi^l z0E^P=cvi=-S%e=$zjRepVgi?KWWTt-p8oieOVE7#yyIQblu^MaTK=k@0y*7*Er_ge zAYzp-6Og75cTLgCgO_}WYE)3ba-ApPp&Pa0SyGM} z{;C6|4})=Z%s2OAhLx2ykTg*}!OUYC)qYmO>XuW|!HHG$V{`XGNo zjp0zeW{q(I7q-~XcaisyLEQh2M<` z3X_Hnd+wu=YF`wb*PZLx6w>*k-}Qv7bhyu1xeGE|J?Bhi3UJol9Mu^V60Hnn!Nd~m zc)}?5SEC410X~=`qoZsVC8`DK_Ts-0p!DJWwjktNfzd0S_sn07wKcR}(IK<q+?1-6V~LEKw8V4t&q9wU-6R>xypW+G4s?A-ybW~V#)dS@}MWTuL2YID{)JMqV8Gvs!Ul2`<~ip#c(_;pFr`^-2APxIJ@VR}R$)Qh z{%sd@dNs5ItetDL57S|(U&vLST(_Iy?|G!N_U3&c{P`KF*F;$*d@H_*0l7vv$2xp? zwg>MKIW0_iUFeowM867SvMawO6UsK_;s-k}h=fr@IElxDVH|O=r=w;K$4o zoqpUsoXqGO;&Q&!{j$P3cuy0-05HShFlkA!!|cJx902eh4|Ku zM@PG@o>n$d;ORwl-!@2>+fG1G>bo26#*1xyJ)4bflygn5QgT{y#t$w>LpQN(a-!q# z3Jcp}7Of{C7QuNzN+|@NRz*LklHbw!X>)_~giad9T&l??%&!PI1yL^}>JYDCS?eLj z0fsg@lGX@0>S~A@e0-PZ)BV2%i~wy$mYyp4aJd9pQm3Y|*=mYEo<0B55{X zZAFU)fx|5rv7B7EupGktZKFsMqDYgahMqGt|(mkUlg8!AHax_V|~S6UBmhg z1TpJBD)h5)@+r=0l6{;{x3yYr7|B92pp2MEx#A~YKQOFD9nB0= zo%eXwf=Blp96F|D@;+n!{mD>reZw5<#%xq8udKO%2hYu}(*T+NIF8&|pblqWLfe@s z{g>(aP@hh|lkl$oVGh^I_Xm-{p|z`1v?f&RjqJ4#K440$6eszeS5i=W@N%7j5vkI7 zykSi}5D9w6D}Vn#R*iMmu`Y zu`qVsPxC2@=m~53C1v~rw$`u$38%~+Vl~5;y+^X=6&Jxy{PgGBIqI})WU#Uk%iR*u z9LzBo82Izd>ALdDDsDo~b!iNQOGncVo^jFF3$_oPYX&t_4$`Y7^!MR6KL|oN@Grj^ z?2xgvfILxB;EH59?j9RIu5TN0wymu1j&*l;H+22;)I-VQj6fW@_jgG zelojP&yjTl!wYS(lqQ4*65lWSx`2ftAGb#`K5Mc1i2jo@tAd z7Xu-Gus1rQbHWz}LM^++k{oss9ozLjl*FCu65k#Rb=bLcz#QbaTt0!zLj`;IvzSI| zZ<>9>aRJj(x6N`9jD8ux_U0+ItzmdIF7`{9&;coKeTv{5X;}LA{(&B;lkt`B6qi)e z`idf^t?RSDQQr3G7b zjDNkZf#DoqM6n5qrt-sJ4~-ZKO}43ivXKf+M%j3m&tVRdm^Q{viJo$QayJYiNnsUk z4+sn6WB<4svvgkDyd;_nHvzHe$4z0J4h{qF6gRvL)_X4_!2xQfPLlCkwoTV-P*)tc zxFX;YL@gz-G&@GpShB)NkN*vMZ8oCO2U*ZavB z%oKCYn$GNV_16{)#lK55sje^JIu34hNl;QmV%g^B=1KGr^&QW(@>^Sx!&`xEj$vZ; zT)MR}Wc75?|XG;%JbnMmhy;n2_qY)R^bZ z&#D$uN@<=ZM^Dx7uem6+cziiAjQFncSnYP+jlkWM745NmZGG){aNwlrVvb@8_93PG zwWr|Rl8~47__S1>rfk`Uje=5?^LyPyv60hu&6h)PVX2D(C|f9G96Mv z8tFH`LY>%M_9LC!fj~~gi^setIp<)z?~wu{B03*4Hc5LY8hr52=WWLEW|+AS__i1H zpXsaPy_y|qd5*%SNpwBetQkc0DsH^1|0vK*CTj;8wU~x+U9K}N*@iC?W<=QPw{dB$ zM@Oppt0E?2VxbU?Y%jhCyBG9j##6Ge8~{hDUw{9l{(84;GQRkSad}daF#!QgAgl}I ztdz$rGV%*CF$Z)YUxc6R31ur&RnpD*rOq`r7{PQpDQc_Fuy!(@M|}dnk|;i?p<8J6 z+*7fZx(sJSbb6Nep`(q)1GqflC3 zK2B1kzRVm+@IZh1lI6Q4cxE_QIOjPo`R#RE_hdocFS}4tM0-b*{k<>>Kf(!YAYUCv zO6~~*d|-U6+<%Ake&+Douq&2H00~H=`)zkMbm9yrEi2UG!0wQt`NU^#LJqb1qoVt6 z4(K1&eo0tYlO)}b{Yto}L2eqcoR_J!z`YEAc=I$8)%1!^(<2B4Rn%NUGsz7)c!Fj5 zWz~4^P$!tw92s5PxYz{-{UwsVg_}99zDka`b<4N*EXQk`sA--1UdX-TR z%t$X9YMg(y_>Ny3AQt>?@fK&TbCn4;?G|4q6X+FN^atx# zVa|IdZEiA&0o$RuZ#))X3r{`ls@fk27_u6D1+9LblTeFccVd`a>6N-7lHDs1aaOKb zX;+PpG$t8HJg!ec^VpHB<`7jRKX_r|&=g%(q8`ITqIkO3_`J7;P-q^H^$-0TLrq*;^ ze|hfc%ap_&@8PZ)Aimp@q3)!DG&C!r@r3CPUpM^w!!QB7dL zuk4qH@%xwyc10c%7U%f<8(NbKg`&fCnF3DtEejKx^f=^(Q-5iHjH701Tpk4`t@@jU zLdOGSnG(WJawTBL+-kXctq^wkfEg7S%O1Rf?JH-oyp{o%5{;_fQ`Pi5j2 z9;YueBGv^-(lzHH>>V2Y8IpoxwkzQnC6%N&M{pjCUZPO;?*d;5U}2@2K=Rdhi&v8e zpPYcs+BNp$eQKLbPa~`NF7c)swk9o{OYdXdfy0-Ds3bR}mz*PR{bzE&HL_ce9?|LT z6!r-tOO#GOa-K%}jGehkGyAOWY~0er&9`y>nHr;=74euE311O`u^USBU4nbfksR=@ zWm$!YcPzhmk+YBv#Cw;KJm9Q@pv4pSj`ck5Y{4T2j;4@lIbXrNc9aKUhR@{RT7atK z)Ej^D!8SEg@c(oPk%M-~2H+!BFMl*`j!QE~qX%D`Z&>{lJ!y~|U-^XdpbZxsr%3?@ zLm42BN@->-zt)`gQC(s70zpI|AtNr*usha>Gs^i3V%ekcK=Zo@WOtqQ{I+=`FmE>U zIi`QuqH=Zv*h@95jqxIa*}n~MQroN9|8Y;I!Y>O9pK-w@$YC>w(E`y8k1=V1i`Ds2 z^NDeFBVG2d#{`sBRTN;|;OMQMW7H~rvlLNLr_gr7o=>jYbB4 zDxTjkc%?n|^>ABhsMUG74?RrQmu`z|b4g2wDezX=Nrv!C4nAG}B80<|a}?v+Fv?N? zyh~>7h}hsYd9)A!CgGr`DIOV5YAl(Lybos`6iRUY9_L|~!durH=X@RP(*@eI_R_|u?WqP`vOiChL6jByaQD-@u z>&`THUv6RnnV=y8ieMM2y~`>Z+QEFCl)UrDgrcIB58w0wtu&v|r^RHg{a!r=dB4*9 z2OzM$6!pbl^PT8|0#p*YPaRFjDhgT+;2Pfet4AIY~eZLg-=& zXF-u~^-V;6gFeF>$|r^T@?otenDyiemc&N?>*fP4&ob%TuaeV~rcM%6e%DqNo#LuG z)cpsWge;bvD9NmD?Ro{r| zF-)FRhNlz{H*>W!CO}`n$lstA8}E`bm&auAMfb;ZOn2SMWI?UQj%5k=cQ%^=j{b|S z=!ys;=6)wp*Yn6_+s0`MX)ux158DfUtu;hrnUjKr_h9>|^$6D}XwUmh2jtOZ8#I`2 zsi7NebhWk|Vp*<>l#UiCkF;=ad;fE-zz1sTNfDS{m2S&fyXk2iveOf9TyVge@1GoJ zDa3n2g_r&O(I_L31E+7zwiIAcYb^41V|y!GES;a#ZH-7ir2r2L?UtH@g?*huYvosN z6R*@qlrr?Z5xlGd@ziCB942o%9#QHI%NFlnoWsQ{dSY{aHka$NE_MQZ)H>oiku4O^ z+JnoykI_idg_KyRab(;%(~Akam#|!J_G+N7nP5 z+^6XSjJ-?y$kk6dStSWA1mV&o4?#9*XW0ePr7L1ESjrNi$&c%2d=2Lp*LToMFb*ri zas=UppBQ|+8k2+xf!ncF17V6`#XFGq`==no{8qa~E8*}NKfmbZA20~!9K~I;eBqkS zJXXu@-4QMRoy4?n3t5MXs!IHs5mUeR>ks6mdp4vU?$X!rzBTzWwHIaAC1W{ioJ+9` z2F+~vv$a*YOtRsJ8y8310!buJ9_1ys=vQ6DBa$$Qzs9_nsosYfWfno$eX;u{``ew% z@lIsCi}}Xsb^0Xa64=}3O>MXkvi#|IDg_~P>v!4BYO+Vz&llMu9}rdH3=GHnY)0sH zo{27u0KCFS!OsW%b$7h(!uuep9Jp}rqsOT-qbVhoI4mW4e|AmMY&PTNW+(o;t?U|( zF+JA--DtDI{hdMoqV3JB2jMrcM+6$&DGexiJn;LBr{|T`ZmRRCCPOFUYMJtXSn-3?;+$2a}5u?b5Th9Spe9C zVX)cfhwfbd%Sq2`p0(|1VGsIkA1p70guSfR@&{-S2|sBMlomn=f!$Y#9ME>T+0B3+hi-5SB-!$eO&L}poBHNXUh3viNAh?j( z4}&P^?uR7O;e4REU+KP$m2egi_=HTdf-TGne*21^^m9LZU>ptuDKz-b-yw9?go1K= zJBR(@T^U`_y|%Qh3#Z<0Jtdn?k63#XDk>)B0{r?Ur4zm9%9=GyikVPEg7`)?0h_t|m64@rA6c`R!TassM#HX@eSFx~AhA^uMz8J~r- zm@7VUo#-f~Df(P}u2J&vAQ+a-+AG4s7sXI^SVg2JUyJ-S%@=)oc65ce4`%F|mF9E93Yp(i7JnvtJxKi;#~~yY?0ofKANWuQT!P>|Vq?1d zV&ahnAwG42kFR?VY6@0GP_EM~x$tY8pP1*sEWIu}D<#Z@z{zjf$B8a$MYylMp5O9m zpYm&_g`;KJ$3mzsT-`PdETOxn*9~=0e}3LXTMup8qH*Z*g;mViCxRq8^wN9JOP5>6 zhmSZ2ZK!nwLS|AL9Ucuu&JBdDD6Z;RBZiJFJ4Xan7)|*@Xf;Hmd=y%Dq^X;pNwQRbLqqq)N>JA$O3sp4&h$G{2 zC(g^tA3kvVSW0KUKX#I(pymS=?uB#t@td!Qe~%&P;_6OO8v_rGm?N~8fmv|Ye6xWX zr4q0}JpXgV&_m@xiTlP*1=I2Erixrg>T|d3Bc^@9envqrI z&$z+p@2T5@3-hWO`6=e~qkRUa?lyiNr=OsjXCv?AF)!Wf_p^;fLt>S$ z__ubt-?*_T@Ldk+;b{6!Rt?9zIrH>us;2wG z5_-+Jxt|itPSCJULR#KWNrh{(XZj~IJNc;wul5$snYiJV0(`Jl_u>UkHdn~w56*(z zK79_L4`+LU;L$G~-r$ST417AZ5~W2-mDb{(}Oo zD~t+fkioC%;7TRoM|u$c3cJC;_Fz@iZ2}Jwb5xpTh%+pVJrLa}yLe2W)6PBno z!{U{UZ2@E=M@V(k-X3K^jhY-OFnQPS>>$JbH5L_b+q4=Lxp%4grhh~hhg|~!w15ke zq9@dHhCF<@;}2dfHn|HRS9bK&(x9drY+JLl883jJKhcqZbL$Y>p1@_n!GfnBfzjfB zo&0k-E6m3ALjCfnjyDkp*k0`yH*}DyWb^=dHxyrw5Pr{$mS66JDbs+Mmr}=}0tnSJ zABeq?J`Jy6#3`FoEYZ@9lVu;fbdV6Sd&jLXeY3`r$IxcQSl4KEe=|w&Tac$dE)PU9?h1FQdh9j^0YOyNBr4X2+n<5*99k)hV&l zCW|)qKm#pJ>Q8Nl&AVeyi=mwPA)q$QI=NSl!IWXs60tUfJz83MlDAId_aHX}(48j_ z&B88Xf}dZP&5diaX0iEt|I6&-O_oj=R+^Vn&2hFgP-K^Zo&|^g{^~# z=V~Z@MjWU7%~HU3_mY<;6=NMSgBzYuOq@e~yLBcc@@ zXA`QgecFRIdA|g+f!b zujqM|=<~bNedVH=QaX9o!Vva>^{r87D?uy9E^Wu);7p0aV=pv)KtYVwLb6Mh^V6fy z>48b))XHyO`ua+EkwdrmLQMP*dG05SN`Kdal#Y@;0u_j?(SAz-@t9P&rb^xjDK1a1 zLPdC-1_5cC<*ad+9>;W***MQJy5&sOwDaM=7lbocYCpOPb!{fAD?-W=k~Eh&p4Rzf zD{SjEL`HfiNS~q2bFZGvQ;#<5J`H308G~P7QuH$g)3xVBpH{FWjr7#C#eHT;+y~{F zHPd%k#RIBK??vxt4_kH}jq`8zQUNt$+%k|Bep3xqFyKkytPdq7y&a$P8*hrL-Q_xo zZm1mV5}8@$4fEk@hRE+y9=uCNw~K3^3hoIKf>D{TT26O$(e+@tv=tMIk9?@tQ5fW6 zN+$Z$xUiNYD06VqT$l@=>gU0)y*;_$VhO{FbCI4eaH)9 z>M{cT2X96+EvSq?E#uoBoCCXRU?zpI*hnzXe4jx^CbU+2{`Q!u(1%pjf~R(D9dc1W zj;GanbxS8lxm(zY@rqLeyR^SeVV^(`usG|`R`RPop)V3KeHT#o2_;_VAtE- zEeteoOA1izsjpDeLRoLDfMAibB>B`&ca zJ9&-&>EL^tFsI%`U{}n|beDMTM8{4CxOj{RR$}SeS4o=FD-~>kC#s44=*^o@-+SB+ zT2N!eE(upH{GNQdJ79b9yRsozut1v7r*)$S*Gmp4}Put-+L(j>FfSNa^2N z!22W;bo7hyi6jI%l+N2rapUpjAu0ZjyG5YUfDdkfLnJV$=}pr@yTmM2iAI!0IA_)q z>k4HjYJApwjej&)9X8^>3>2#m;;{Ca^&;N(AaFqP@oh?=R5>bFYV&t2KLQE|u~yHr z@Wulr)kg*6ica?naHi*IcX?*LtUi-|;lRqzEZ8NwhiRo&&%(g9BPr$U25}aSrLM&| z$BDQl9)nQlXFyYACfS&o6%S?cAwXtLfphjK(_NemsUIsL*DNTvj=<(1r(TOpAL_Wj z=iaD&DDPxmH;4>+gF}V#mO?8*izkM#GC9Kg{H9YT;&i7{&V=!$fl=qzHQxk|FXK50BBi!a&iZXvQH=KC$tircY$UM5 zs>oC3{SVR0olitMcMdP?;+j0 zV|_U@rMoDWUFKU@g?rL|hyL-%kh)9BsqR6?*-m~iXn^hqs9N$}_nvl}oJsaIaD!%K1S07@36{07S!+jzQiVyoWw z5ZY+6`fR)qfi3kzvx6-LVCFsrn-kU+G3+`mHk7tbv#hycTx8E3hm?z*+XBkeZ=RTUjYT{Q%g`cEZGWQGfu z!*^anozWHhgXc{9EZAX}f7D3|3 z7`*1nX7i(CwwYRku-c{C=4NzgF)@V?7;mVd$aAD5@7+w0M>(WIGkimzy~cQXO{_-3 zx*B&{c3@vUrnEk_@EYCKFW11xOUAJsFs!&mK;Om^w?oMnHfr(hJMENI28{Rz@W70* z7S>#bebOq!&#Nm7O=)S3+!{A49s(KUVB>H*I@-C{M2dx#dp13ck&)6FJycan7VSHQ zE!^O8#Y4Zk{qkeh73bBenxBb{GAgeh^sASz)meYwTf~2V`|4FU;cNWAKY8_v_!@Qf zUk_hZ2EBs&*W+NmH-JUx@0Z{qNjucP9)ClDLcZm4pZUY$tJmST% ztCN0ZA+q;ppthpF{S%QF0>?tgw?8TqYE``8ynMMbIEU_Z(2xfvL_ zlrj6Zx?J>y9*H2^zklRZ`-}Z6fo$#(?uj73b21VVg}gnM--<0uCmJ&aeNUaj?z&_> z;{SRsn512y5bU}CIKJ22{E9(aq`FClr*@Ai3YI%{;n>}Fg(#Wc^dNbBb~kvnw(aJK z+ePDmkd$zR`^fI9A2{0Ogpk9B{m85+8YGJu{R};y6KLKsqOT8Y;I^c^G^4O4ZCE*_ z>2dvRLLGtY-$%xx!EL@#RjyaurA>$|rN$Cnq$1GPDT|n!4_ZQBMw;qG#?b5y4Yv?V zO@@PhsVFs<&N=@%&V3>*pCbiHx{i_dlbaIvyE(HSek^td>xjmcrJI`?b#u9i^7Q3e_l-TZD8&}(w8;B2;E4My zkFh!;?$__q(3TUooJQ3}Uhh1a_rZqh+C8r(?VjqXI9e{eSupeELnR;-<>B28>+9>D zD`GovCSX=tnXAfyR_o7{smA!Ae3(?@+*XqVWbFBT}l1LRyN=H%|mPO z-KlI}dydWp{n0~c_S(VDwVJ{-ew$6c9#=eax!0z{_pOegfVlLi4_19^poGIopNp;gq$~l_sL&%NB#AiXJ{T^xvpO{6Qx?OisZz z(EFz1x2^(Bfu#+HmfYxKk?d)JIer*nm6oTg?zkJ7Rh6XIyO>fU6~qC1$D6+>MXNNO zClvIIt}<228R^Zi&vc9_>F{@A))R%uX);Ck1;w=3ZF+fG$_U2Fxn zZlB9#U)QsoP@xV5k$vBnk@5xR@`i7H+;k)ROE=M*f)mS9&5d(MA zV{4a!ntCrzJBaI=Kmw^}1A-~5X`4X7bA94Vlc)NDS**NF`N!=&5;*uk;U?yHbOfJP_l zzJc&?ud7JSRj7s|0R?UT?%ie_O`EIMZy(yGJ}PdJ<|d=rOqqonw{>?<;4`W#ya|MoL7Z0;Q95`FgU9x*u*$;!v0wt%J{ICmH z#fHp-UpRJl@5YXGms{NrYub=;)aQb~a)vc|uCD}fgxBwJ4feN)SCqpYIh7gSloK%3 z7Rk5C?Z?C?Pc~@la!WU>%I17h=xPNbQ+#(* zy}tED4Tsj$@kyBN;pF9xuLft)5`$QN3{7`^=r)^hrLruvaqwH@uHU)yqYd}yRr2@E z;%a5kj-6%|D_8s?k+Knh3{G3*nk|qSW9JjcPEw&YBcV_+cRCc4 z8W|nV_?039jsuH7XOMb z1Yps>0@#T9JumA7j?=p*+IjUvG!joQ3vPx6bz%mF`iqPKWXpT`Ce`e^DN6T?Ls?)x z6l8&LMfQi?o*+5u{wO}w{JiGQE6?IGv!HY+iJxS*HC5)!K(Nc>1m%$n z&E(w0)scpH?I!f}SaXM@dDY-x3SGN7uR>B|619}evf9hD+CqyYvo-HuY`<`p5C#`#hNGBQH@lBwmd^SsJc_J5d(1-~ z=O-LX=*g^$UQz$?wETAThm}Hw`a3MO!W>fBWjGN0Ib~nla8XWxGE=d*$Z#by5DVY=iGma7uFuN}p%?z*dvUzWo7?N4EYNd9ANBWZvu*)gfgIuT;hVcmonBRvi*z{K;J-Q?w9x>-N8>d+V4u zyDna|Mq8jjixw}XxD|IO#ob*C#bI!_;ts`&!{9o&OQE<8Zi736>)_m{@B4ixxi`7V z$vMeM&Oc;AX7;n6wfA1~Tfeo}sY&JbaFvM(lX?Lb(8746PE=&D=(CKk)LhC<&_7(=GIz zx!LJ!iH(e8f6xKv=gCKIR2VF=6HKlk9GlZq<7Ca{>v?N7UNQh(jQM8~32A;T;h@jB z?C?Zy!m_~W-p;0x-Y$(q^m98-h+c556OssN!`GVg2n|R7bwMb&ShjTq`Yq|}`J17+ zr8s4U;;F(~*n!`1K<^*R;*_Q-3!EjRr;yBF>eYAxL^Zlc&-KFfxR3^`SXhhaI4~os zN)?0YG*z<;%oQBc>jDEKQ+O^P<1=pN?-_gBiG!Ra?zg&^;U5jRVbeBFN8=q{KJr*6 zd?QRClLIm9@JP_H7`qiA!Ik@cn)g#ZP@YbnVKi4xc@9$u$kzC}cZ~V-1ZUksyYm*n z)?{TJ|JT>M(rWO_i3K|g+_&0U@OlLV7n}vhUAFcvw7Pzg(rUWcPE~#pKgIr-sWy?- zE_tFjc|0=QucV@glM!o3)PFKY)b4b%oj8anC*rAhnMx18C8#|V9W40uRm+0KNfx?e zbi3>%u@#n6Uc_{F;q{|naEg4gP&(xPCs0cCUT&Bh$LZiprm4HwR?RV>^!o>BxYC#8 zbmx4R4&yn>)UJ@qcWL^u8?Rd1TaUju(*+B|me`nT^MJz%*!w2q;T!n;O`yr+ueW8n zr*;}*==ShvjQUyAxec|-}I`h2#X@d0Z7Ub1o#-*$6n`0m)K z@*r*QJi6{*M7L1|D_@g2;@XPM;r0}T6QyxMb-okH#IU4D_PWwJ@Wjf?GLI0we^;(Z zec*sLzjHT?Jish2tdn$U`CYAw|EXE!HD zHs_M@A(`AWr88gUgc@flLT0ZgPYd1$=wgX4CzY#5gO+OT*G~Cej5l$l83{j5i}t>3ce8th$5i@&h9#u=FOM?oF0_$JcKS|8jmTV4{WA+v zi-XWT+`-AU>Co`o19!X{lOp3Qf#21GE9RZjY7^r}9Onqc)1{bIn_bJP6ts+`R)g<) z{`{#q=g(R)Mwh=$Oe?S^U?MZW>%_Cum~n1!wIy~6f=ya>bmFt`)w%DT(ergdbRlD+ zNn#zS+o-qSzi$i$f*9TvE`w7ib`Jzd5ax=LPxTz1dF2#mjw}E1UwVD0gzS3%*o@ic zPB>gL$M0jCFn`Qq|L8*%zVlpN!qaiKH{d;P8f0mdu0`QE?G zEsq4%IC(reAPjtQ-S##&&X9cl<8u8zOMq7%kt=AKAX5|u{6+~XT@H5TPf8|a$*>&5#rb( z*GJ2yBPUcOdFxGzWk|ZrJs9+<%k!tY0=;G3i@zuD%2<*?1Gw?|6!GxzxXhgo?Ylx#1V}$7I_S`6s2^B;%XI5+kdMW~#i7DpiMy1Cd(Y9M7t7Uq_EBgTC_Eu^RFN_#|+$5D-hZ6kVm#cB>Y z7Jlc__If0mM(qv9)ud&RZ&lewd}iQZ4|ywCz{)F-SFo}1ovK^Zoxe3TDYc~EM;Go=igWZn?!mGPLzQiXRg z>Xx^48tv-QJHc9xTkPwy^wx{IjBTEtaRjT(@5q=)bk$Xq@@$nPUzLxFxd}Alkm5Wr zuGBUqGK!YU9qGlqB^J0tI7!hG*xQEzp0}#%4EVi>x8C6`Mc1{bvzkfHH2)l$Q0Jj8cYH=lS_%;p1%;@fo%6C3&knFa zCW>zcRO}S9YtUnrl>8|fOux}1BlmA(KomzN$5~~fqO(bHD$kgR^+<7U5?}U+1u40P zZyiqhC}pSGiC9r;3v0DGAx9s0x~?}omWa>IC1ZQ#;FEv#Y(`6!pemRq$Rr zxEAmW4A*###HCYClHW>81^IbR!uc;P;bnTQzyQ{u!Qt0g*F< zH9Ru;7Nhx>zM2~2=xxz$E2=q7OY@tTvRYzeC{aFyeG#hS(Kgx=WwI8jy96mE=5Q%V zA8y!WA*|(FNd|9X^t!7{3_u;d!((?uGMcJ6uSJu=G7_9DodFx%@C*wW=Z-;l3AJ%` z3D_;ghZkjFu8;6Bk0cE9z2w4^j8e_FED9=W)kUzO+hpnN62%vv@^Yz|<{Z2qmv3iA zRAwei4o2&~?UCG0%b6OryA#s9Wwq{(*`s>20jG1vuI``N{RR3YsX6&zFBZC{&$Ll-{JYe0^&|J8a^uD5sVP4G(6ViQ3rS)SN8jbldfIb_)qn zrQHp|qc9|M+;@MIx$fxx>L9J>;Kq@Fi-NCf=60?%U{-?oc^sfL>i5{gD03Rk$gufW z|LVUdS&pB^S*p0GeJ~QWk;jRX8tgXLPs%1H-4|SYs&|a&v#Pjj%$*H&CLsqyHUj1uroJGAwlc$I{S8?CX(Rpwxk7^d#VG zKWq}VHc0KywGPhTP=f6g8Kok^0Y}8(blfXeDdFT1QC5GOE$dK&CgTx(U2WGa z@Gn66CGa;Z7p+A1|G-XZ3HkhU3|H{~*YVSTrVY4O95@Q;6y+W$FdHnb*! z{vS#GegCvol>dJI-x%`$7w!GupY8vdp(Py@$T~k_{RgzZx_D1$X0Pz@&#wH>D?G6a z(pLG;=l?IJ{eR0_{=bp<|NU8;|GRZoW`08L+^%EK`=LpF+fUk_Bi~4DNK0%;N^VHn z9+Us~se*zirW+fQ+nYH^D9iZ93}H!j*Gi3P@wp;xHQ&)$=A!+yRl3HP3G1{c&15nU znlb)G=@nS?%*gd=>C|72p;6n!_fi)qdjGi)5`0mb%{73`aSm%K#zJ4^!Ktp zNWyDav3ef2{Ei;eO{&V=nwtMeBWvM9(^J70n@#(C=J-WK=(KO25ea^gCEUCAk%^3m zaJ$>M&ZFaWaByJKZ=M>fR2A=?UXVAvPfVw8$_9fM`YUVWYbIg!WKexqG{RZJF|@zS zM6EvADdPCt8(S}eTwO|xHpxHC?@2F4R&nVA;gDh@6BHfR!AAoD)E zw6u$|4+<4@cz{QyBK-W8DLzr+6RK8Lu~|-59IiZVeNi75Z@$>lvQ*JEcKpn zD%tO+ZC}37z57}K*7&>vQk)^JDboGq$7Y!nrVBpkHd+; zYvR$0gwNo!8~*TZTiSI{PXjf!oO_lP$Re^k#9VCzVX zq-%1rpwcja$vywN6sWYe5kri&2Xpwl3UL~e3C7d1>g_APyGA) z2P;LKof8dK<|BEX54q{DfR>RGnc|?sf~fuYgajIMMg6pJKfKhs!;3Qyx?erZf*}G- z`mOmr9O3#_vn|qB9eI;21@eaW13!IR+d+#j2;XB7QoS$CF7NRw>mHmII6MBnJ3GsT z!q3&*z+p3gyc2q6wbC11-~y%$M?K&#z#VN_kB0arKuh;EC3%Y%MR z+-^xrnohf(uI7*RC4P0GAO7A^qMQ+ECBWwXD~NLY(>yNf@Ura|`9);Dmcn#59GvoJ z6a^;S5xg^9YCg+%na8ot1Ho084T=tN5xf7z0`mM;7-$7$93A)PP-o;aTD#hK*h&X6 zL5C#texog#IM|6Bm&G?WgS;VUUExUz+>1D)8bNxfB^HgUs zt_fS(8j{OVqtZuCPQYE+o>~T1)_07_ zfjIr~Zs7L=zZyfTc&OeYugejyADYhj_8XKW1#ndBK}%o>^}9Ppna|;QjdNv|R4?>Z zr&M%E`0@iF`UYb-yv}BH&DSBjOT#CV$%E$RyV03^MlmrSjL~z2di*^0{~TmM;DaS} zh;s3+5mW(U!eq0Oeh0xMJASL3KjVTYCMf$&`wlxz`hz?{m#Vc8KKJ^q!rmCs$M#x2 z0d9vLTy;sw&?xkLJkp?{rJJ3dHRsOi$I8XwGi%T2tt||FuU~DuzJt?xv{K#rAo)f` zrDyVMg|7j7;yQ>sOv2F+y|M?ZKhgjzBgg{t-@Ja4|6ZgLqQL4DJ{?RdLchIA6LtD z8{Hbk`dxP!_3w@oP_UcG)2Ls+8n&5SIcL}`6nba-e*X1Gf7p}X%z@{)-I^I&8#hS^ zQsc+!GRCTy(M<1eceW-f1}%BD@r#I?ajs@Mwo%0=N!QGrHcWmy)gzuBVOeUKp&fl^ zpdqU?KwxQog}QO>K#op?&Jin4?MC&_1oDk*i;cL9ex&;*8frKeuMg1~HN#q7hg=}b zRj{d~k4{{M#I?Ife05TeY!rsis%|ds-|aX}&gU=*=O|kZu@_vHY#QXaZ0U`z@gL4i zyUe*?*50O?&7`*??WM&e+(ONn)S-QaUFVc_H*xMTt<=H^42HSwL;UyZqS|gDMzy{N zC5h&H^D?cIxryEm&9s(LZSSXQgKQ)^17DF*CGk>z^1)mh8lFg1RQ4$}szoAqomwnP zC0TOA9ZBq&jQ9xqw2C#ul_xA&B(cTEsXQCNpB}B^`We-pDm@GH;LF_8hf9&Og+Km zcs4&4L4pMsGSt%+E|Xnm1~RQM0Y8sSX+P^9F39$RX?Tl*0*+qS7v4Q#w=OLz@!6WJ z+%GACv33*=m6rAu?!=npPO~Gu4nt?!)B#v8+Ri)8o>Tc)1&m8hZs&ambFdYcKuW!4 zi*Ha6u|}F-=L=R7Ci5A$4<3nKGi8Lm?dsK=jU*WuIgZ2bMh zGWVda;5F*v6W%5LAPQ1UF(H3;T;;EDg^;d!SeKl05xAJ&3fWG1v;R!U~( zehRno5$h>{@NC3nCbb);`Df(&#eyTMz%n@2OY7ISwUue3C6p9V%P4oZJJOowMYxx$ zkVtWJ}#D2Z!xP zH6}_jFL+OIe-V=WCSlD+;@)0gel1#nde5#TwWyMXrp5SqW|jQ~I}XhTv;CAVB3~c6Xvh#_t(A{AR!gI54hs0?Wt`J@{PvW%CR@cN~AV-julyqFe zgHI|OGlj!i)2+oomB*u%?8!S~v_O{_(q<0U5`A4njQXUYX^R;F=aCtTg@m*eM`3pJ z+1exB_L&Pmw+B<9Piis4-g~9DrbnBcev0!Jr;(QMF_bQ!jYYe&m8n;N#x0i}{+>&r z>F9sysbeUnYUH#Eq%2o2%+xk*@^O6P_00?`jY>{>mCS%IeCL^^2E2%-=Zmyi$_H$1d~V||DLF}Ji#H1P#Y-FU?HiCs(KM&a^H=l#)va<$Y`kK2JpwhmPf1Ia`ZH+L&~KuFOM3nHhUUoUBe={&Pacgk&`bL84>=o0|!+5<@qI~ z`t7|*{<_@OrZD<$ zY&qU`uXCQ_d~OJ8GV0&YY9h3=*#e~mrq?xT+I1#cwWOxH0Clem>zn2(Xb(pJwGeZjMR;O$cGvo zB1<@zcT<5rl`;!=Nq0D?birn?8?13M$LHqVs>yZAI^PT?v-;4Dj$&+uK?t3Ag+4#uf$6#@GZbC0~=Kiur@%8$t|4+bG!Z9Me zGy{!@RrW=trC|s93gnv->(A?{`y(9r+%${g2HkZ1ljqzn|Huc5o*AOJWSoGg^!ciU z#9ys9P4k?&oR+gmNV!5UIv5)KEwRaKT^(!X2>>z&iODAdQ)yBoVx@$;jX#`kDNU<}cqv-lNlJ*_x zN2EBnmg5cDr_dR1dgg6}WSJHl(2Gq#aRFmj*3$>x>Y^0ZW4s22z+; ziFSGXYHvYFm)Uf4r zl)k0KUR=4tLn3O$`9f-nIA)ZUX=dYax(Fkxg@cmjW(+Y|4X-9h8@9xyvvywQt;e!R zwL3+C)3C!qA=4!kN1fkM(iglsEb-1k#$+uZD*}GmrAt~G3Bq0K%4u%{*V71wa_a(J zFnjLK%id^I5vmi81$cXs^iT1O7;LtfpFb5;X&5Cr35J{7wQg#1zHeii1?!}Xn31F}(HcocAo2#+w!<>o`47P!aFaa;>Z^oK$8!j$S1YI|3YHN+H ztnL84)*$soGcT*lbDhw@+V~v~PWAP2tFh*jg8bs~JO`KqUb%jwbLwKO|1H4te)5F& zhe$s&Ip7unSx@m1e_fhc*+78GsQ^T*6OjwbEM4&q{KUWEHH&N4aYJs}KUDII(! z$fT>Rnt_`Tn^6X){*yAN>KGr8bnO<1f>_-vJW(^6{&1VJg>(Qf7PDZyLnY14L%GR* z#j7+z;+W8(mC_w%Pc72>krP~;)+hz(Vu>kWFKY+ zuc7dS&Z%h=6r+@PzUBMjACr_|p}u_OJM#*-*;k5}Yc{LJ4NBeA6x{je zJxwj|r4(FQkbXS-;>LehBu;xWG$brw# zgoQss2Y=q(EsY01L+gAFKs+5JtJh9@mwyBQfMA8LjU!c5O)YhGkDaU~E5$)|oCPM~ zZ&85FdB<6-5>Z!{a(i>Sl*qCdZG4^`(3VkN8S_oURb&@$yg(ff#kQg#&ceL7-fZdD zKkoi1WsLr~*Hbucl~b9M-c>KUmOHE}%)-nOzA9=Rd37)qNu?M5=)U=1EMQJ`ipNJV zMD}`1cWt^FQYJg4$*Ui_>PcPiiHvK z(UBcz<9nXH!&y;+-c1=+*{De|ZU4E2dD}^@DM;_3=E1pplvLU!19#gAtE+`J@p7GB*DUB?62R9Xzc z<4>+%@1Nit1HuNlIkls;iSzJ5>qMMFZ&1&^MYs>NO~8RuLR$49*WrVgSzl}n+NJJ= zadnNQfk=+C-f6bk7{!cB3aveM7&xb5Ghzmgj9#`!P*-m13MKdRUR$Np!vK{uQRuxU zCxeH5yvnc*AHV=&{;>je(*~bKLQq(@l$(y zVq)#1<;v_(VXs5+R35tx(rU`7n##mA%PDYwQ4Z|Y`JP&SAQxMqrHR&CvcsjRn7WvM z!%RvVvSP{WnOQLo69UMyHJ#RvPFDx3--yc?&{Q+8MD#u1R~d*1iK-~8K6t4N00I9k z$C8vs zM~FKcIYXuZ5VU~{3O@T*i*w0Jmfa*e6`xy~3zeN)x7UxVDRbElM+YrCVkB&>{%5r|>N zRM}5t0hirXrW0g(9QXejZLWze*$;hu?9k%Rt_%uW=)q#5`Ea^j;m$)4rp(Eo`$N&@ zfuAL}G5zUqMiSH`#yU9YQ9mvLi-^eToZ3L7d2P1ri8+m)Yq*~{y?2*MuB!q%)0^)- zL45AS-6uzGC&%H&nUm*M9rUMFO0ex3wo#>);}06zvfhIcTQx&zEuKqQ!dH9E?k&%| zb3qNQ1-p1rh5BWEvYgK_V_ySx0{`Zd29)as$UT>iNz~j|Ck2}4IsQp;#aFj@hVJt@ z(tF7Zy(4WNX`Idr-MyiaMTsLAU#A70csEcrxQP8K8}sfYGUZAnOc z=uv!kEQq1d2I5^d9g9rinEp3sr}9QJ)KijCF!~RSuFd~kp4+3m#qMIG70W=T9+R%7 z6VEU{vzg@GZTSts9_^kvZCWcKQ0g!@tCm^PMNRs#N%0$y!=uLQAUlFA+KybsyX~Ak zmj&QJ=wD#-i)c*j(C{BoqGe$*lS5#u5IrWw!Smq@7^M|Wsm)Im34=nS9Y7j!bFF+ZhZ)Nhwaxi(bSpEG?i0nyB;j8qBrGnDDIql&<^A1f zrC7IdOh9ZzB5Y3w0>i?p0Fzx>D#K0(lo&Q6_7-veLHvK9h*=MM%01&O{*6J_ze(Pt z*kOzGZw~UV=Jc#_-!s{h@A*?&T%@V*pQ89`CBP22vsUL z3tbBx`kneOAZ>0pZ!lh20Gq6^=6q;q--?_c4L$4os$%GA6-!u{F&$b=a~4}?PFx|T z+Oz`$lZ&x2;V!w0FZF6n=&3z*bC%A^(Cf`tji>|AnN7wkT-TT4-PzPkkiZ}IZ`%S= zVlu0$CRkad1ySws;$venc&7T=C|$^!p6VNZ|51fHfI1SP;Qg~X>&{d3(9b5|i8xaK zAXHvPP8jv6RA`lyr;?VpcM)hyLiKz3*r5$4dUMF!P|g#{fa1@B^?E_AIWZXz{+KrH*RO zAoG0SF;%qMhp`E(PoyGQ-V88OQ*p6={YO;FHw#G1=#ObQpLlu2<#0U+2fpa3rBuoO z`=hV_5$6Ax+xRvxx2x^a55Q`>x?sm68~;*jQy>PWj`E-B|Br>0%4}YNt>WVRAKvD1 zTUkm3%;w(S-U1XgwQLq@5S|JbDgeDWQwQlcc_+Ob=-d?L&w#Eb~{jMrVu)OP6}g8jX1!#0m6rrr*(;?Xx11>z3+>yP zb(7{)GW>ERmkz5pFfuY+m(OTlT_-FoE&Zq;j~PF2tdT-0)bK*>EhhsX3uJ)#7CcsJv&mHo{DZ#qPc` zol&GkA)JB?Z#u~Hx3qXY#~Vpjm|6%JHnb|#AIwkDH~5_H#ou~g*fqJD2@;)kT47@d zrnDTZ@$S0~Dg4#I!9d*PWF?wY_&q)*!5j*CRE+8MeGgukYI4i@iC9$;4G))3;dlB( zD0gw?e#sF(IT2@0#>8qcArbOPbZuFu)v7kq!g{v$vyv6-Me0aqqat}wl)Y#ZmSy56j zDI;U`;5M;18auGEvd)u`2u}Fc%G6S}R>q4zy$XcqiTW-$E0^4R6;904b!uM~h^u;j zg%ZucgSRQ1_TY`wJ>8tqdcI|x5FxKZgZYB%P{7rFr%M#cjXU_|r3y;xq?H4|PIP9kQD-*t_%UhRn*-Kj-jv6!r zF_OM$p?%rZE2n>Qfsy~Dx4Xo}?CPhtF6_+Gb<0Ey`=-@#IC%|Xg z66w@ZPvj2MT0xO#uDyb+s_|}1zu)`M**`z`?mhDoF{Y6A{{^gTySliPOh)U+4?F1w zTrQHF&fAO(jCu~vh-2{dYt>sWZ%%^R^1b=F8jIxk%l;*tLf-xDF0Cfx78c# zxJNMLS+l4qO$uii{~7M^?>Y{(b7U0coG0RA%Q$-UsJ0(0eYrY~R}+X)OMwO_uY){8 zB2G?`v;0EGP4a^PaF=7?AVl; zpatX*9<%n3j9i|0>^W|Kv(Vy6Z+-FS&qr|Kk{GGHjnA00t-Z6c^47-2_zZ?3^Sc=4 z#4SqpV$D(YdQ->_(}{aGVh)-=2d)hze#}>!7ITesnlkfNVitVZFEMC7}6A% zXz7#MFI?Vi$y&rD5YNJ2ILvmt^{4}qmEvhlYc$l(>m$NyvUrqhS7C|^(>?#i0)C-- zzw5kUgzslZofmIWPOEKI+96Ng3qQYKZj+XVW|4J{p~XTUr4RZ`ICTqmj5zODx=pxK zVjq-dR3ww`@o15ybK?I>`RI?J=S{rkpZTiUotNsJlDUA9I7eJ1mjHnmn+>+d76Zrg z@DCpc$t-=}ci<2usJpxOj7BMsvQ6;XspjW^aR|^!)9q^E>&51#aUNzgJ$(Ec)&@?`s`UYw1qMQUC zn<9n0B?kB|I8a$;u1)PCcDn8yhP0VGOP-OMB%U7Ufsx7Ya;*kSME467C0&l)^3xX@ zbH_uKQMk;4Puz<`Gx!iJoa|DPvg=nf7ud}|3+^-vrNoT!2$hr)0noYY1g_Px6SShp z!p~EmJx`oksUX>x@Rg>-O(ACdT0GJCeMb%>_1fo0gq_vjZOt>EB1<^sc79Ib^@##? zxnKK#$X!EqwHucpuoTJg#nY&P@DWc(+}w$8tierw9wW$ktOCYL_##x&H^sSyUvRu= z`Dup8I@%GxFdb8Jl}mJD2&31rVs{|LVVL*E(1ro1kuExs2hTe?Asn1dZavN9&JOu7 z7U=Biecb`K-2H45&!f#cd$GF5_%ES6&CX?MQ)GRT-G?>ydoR*U-_!S-l5mQwfW-W! z1A;!#?G;lMK==tig>Re=rYol&a<+@Y+^)Lv z3~g-k73a9Q!@^J|!@HYKin>33{H=I%;AgM2|E_?f5AbLf9i6>)wiE}q9yzl^1llNu zk=p&fUX(}E6g}81D;A9T_d=_$W;_)g>=ZIbq)=Ldu}5bO@sx(gRkXBHZpL*pTe3E7 zDNMQ9*>R+(sLtS8#4vUYv}n&Bro9&^2?2RzI>Y`_Uv(o9EhLHGc098oC0@YcT15`y z4^_~dgqVt>NGjBsFBeN@SBjpAjj`HD;{T#c4xtbJEC2dJ6}@@j0M|pbDh=j;ETyYl zA)$opzgHV0oGqwsX<0}P=PZJSy;Q4bd5lkXT6Y!#7=Atcw2Lyb#n`%A!_Cn<5NkBL zC{n`w_IEKzNzTf5zaENJ91g@j# zZGZ5qLg{XyPXGCf2piMH{M%Qg^ynklS7!8S(T&mH-jfvqfZn7U(aSlcF5jTWu~UWqErd)lT5T!RN@8Nw4`&-EBCG3@Tyx;BY(Af zDi6a|bBxwi6B2r&i2w3lVz{LG<58khl<+eB}_9>zo=$W@a5WJ;UE-EP+Wg8z?Qe{9n z)G$E|RXb)LMq#?f3_!sw+vVx6rrWyvdJ0w!sNaI25rga*_`^jUiGVcq(DIZU^Tb+Jd~bHs}57I zI&QCqI?QD9A&ABymVcURsjW`7t7I?sEtMwODLEb>ffI8`mDf6Lb@}diy||Mw$1Ojs z3yDx_C4wo){dwce0>$3mOy&Jsd}TAF0O_wC#LSca-6Tswf!Qla{oQJ3S+Q9;@^dT4 zq0-VbR+b7gYFA|x5g~D}McZ_A7B%DbHL_b2|5-u$wfpJLaARS>FCrrQO;*lRYa`S> zde9s_UvHt4lhPe;Cmfa5LiGMTV||%YoV|q-?Enc&xk!XmQnEik5`KPoSO^|!CK1uo z1Fh~Oi_7VvyWYx)i3N>JGo(zLs^^b!yFMJP7mDOK*jnj;iz=U%Pu|lg=0@M=Vr4G}my}65G4U*p z&)sCFzDi$Ykcp%g%fD|#CTlRwIEPQ`p*)Ssl%p8ZohqYe)OA4j#w*V$o2%446Uel2 z#JlV~L+chGm@KDgSa1E-I=88i*0|Q^U2lE3(coWm z@ivg5P%aM)RyjC}6Coy;RlfZx^$Eo`f?!%)RW(_v7_j}SV>3A3%vckx%7nD(hXS6( zWqD*^iDWi+g@csoauCU6$drnDbrqX2Vvf0!BKyN{A=V|Y--L1$+nakXd$T8cOj=g# z7_`xK3`8<-&_D}rJFC}XLV8gwZ$uT5j6~B!c3y~|cwJ)Re(T;sliL~cI3H4dhu@HU zfvrdHF~V4d8$$jM4mqH&@!hYsk>r&E?gQCa&r5ypWiER>Po)1sE`M=}4=zI2G{yin z5p4Ru%Ax;1#!9D=O$8_^jV1JDWqIE~CM*^D^+NYe(ozqY%td#1cTKWQB4XVN?sJ{V z0Ne3h1d1Epbb}L9Vq#1T2Rn1Ir46q~4;NMrt$b!He9R}pKnlt2`mMe?y3`jB`^hfu zHgB6?w8K`==AB`|b$s&mQI!8o+F^G$6`Q4w&v?VK1x$^}d0?BVI^>6ulRWES05hgtOP6E7dd3nE;yMEZI6W+t}Q3Zy?Rm5-e7osWYDFdWd(+d%HT@E zj8~=p6K`MsZrzl3(Vm7!M_hcb_Er`>3;gL5<=mvTc&HcewDaz4kpEGzg^r3dzsD*N zH+SYYslwD`d!q3_GEw#RB&zrW4*H_QO77qvs)wgSFJHQ=prvv-7k>M#U|t{BAp zxBGzwGnRrpo*wm&i?zxya62QIk<(@@#UG$+%JVh&L`V8Ctv%_&e@0~ZV}R*~@9g+Z zbjZy*0y*uMM&(wfbu)VNVzU9rWGEr#)dQElH0dvrcU{|5N*HvUUvz1JCg ze|SxS=z6DqhrY9ihpqUJ5Hg8?Jt^lVv@7@fSR8|P? zD$h$`rJe@hBoeg;osUm!&z-4@Us`VgxbqvQU49l0j-~rmWArC&vbGXt^=&x-!F*O7 zu?^XASiab8T;~PK8>Nbc6pI7&KP+()gdO=YbUkokL6&p z`lF_{%aipdPue)?q*-}bQ3Mh;P9q`Cwll!Z3V&WA@*z`YB~=i?<5M&XJGU0k;itb5 z1{Q`IGfQg9!d~~qNE!0!V)xUTF9p2UPUd?v=^9^(QfL>Tm(e_9aas%6E?1vZ#bK_r zQ@7!AxKnr?4x&#M{Ij`Lw8B}gVutN;9kkP=V~EN0o7rXSg-~eNAm<9zk0-(J3)Ksz zH|*LKKeDoh570;j1o>z**|R!T%ud_bDAzAmjIl0cv}LWo)W(> zDzQ=Ne9IDfiSa8@(xV=U5B)lu%xm2Id zMl4oQ9_IEAEv$zMhiph1Z-D1sR#OBCWlP42NJeOC)<8?@M zs)dtlR|uBT^I8JutkVElF;y`&zAE&}(o(CGd~=w93Q_F=%P+9^q%P%bSmfh=-p5MG z)Fth@gQSF*)hv5h-QH*32KsWTvVCHn$du2)Q%@V1(gV3;9z(&~d7#zo9McMlidOd%IK$!0 zm+h)uhr~L^eH-hU6qcdnvzdn262|aENI`nF^Tdd_d&J=3=R?{u#lrmJ30H`@QqPl+}Q=G7}{jl=DukniHRxpoVXe{zjcV3o=H{OpN!1E~X zn}B_f`6#7lZHMlk*4lD1I-SO4CGg5rKMS+?G=dU^!bEA3u}&obZm3KF~*s65y9lxK}l+d&e)|~!AIY|oFP+lq~^$OE0HjZ*lHqfL2T%OB*ttF&iBV?c{h2mCg zalmigxO<^*=NC{%;MY(6yn^l%1A`1|eyNGjf$#BJd9!b(o@5@@6nyr@AqnKg=1Uxr z=fUz$%`Uzcx=7Wg+ck$=Kf{PGoksjrgMx0XwK%@%KVJ%xNv#dI(BCz)99#AQE>XBf zs7cMvYXEe>oVB&3=k?MBh|AqM^O-gyl`4KaA4v-2-V$iz=rX}n$^1-Rc2|g9_2H7w zP|#Hiau&w@&Z%ho#9R12SPb=6)I#F*G#V{~#b=!c&xzZ}NAM;gW5#^7)3%Vs3UGT2 zNTc;f&p`hG5x<=PJzuOGzhpnn{*5hzEE*7n%b1Kab&w-o)yq|*PBz9uJ9TItu%uIxC`Sg@Rk_V-2?5YQpl*xlgvs`LKHW}v z3%N}xtH7F0ub;dLZoknL$N)nhO^z8KVT`6Ga^Bo;i}eQQK9{=Jm@JVG{(;M0q3@#K zUcb*XjT3IFD2`5H#sa@$=3p5e8v|FK17MWi-L_*#EKS|VhVAnuuX?%GAXJv)2~!AP zt0yT>COZe4fv^Z(b*D&toC0NME0Atr(gdd@bOYB?V9y(bx*Yu}dYcoVs_GD>ubSVE zjc1;(7XosoLyWt+DcHDsqcrx^(433ww=XrBF8SjDhjSDFSb>jZX)%<$% zwkhzq$j%lKQBj*KGk}`< z^y>$F8mNmq_k`Dc7l0)F^80_9JJWcm`*)91+$v=sif|WY$Z}gJgb=bXW6zB2A-l0N zlwC-6!&tHtA?u7pwq(gVcCu&5zHjH-eg8YJvpqSF&Ur8oXI}H$zTfNmT%Y&nm)WL< zphLch$qe|~1y|U2uq4&a#AW4Ag^5+Fv5by3xHE7Oi#%UAZSEr#{Anb zy(ZSYd2dJEhc+Y~i{x8D#IY)!t- zR9=Q5@Ob`kn>ZZZ%-iQ%UitCullcDG_N8SlEPXQHf=RB>qDF5*$@n9b|Cw){7T?dJ zJlJTZeL_k~mF<+%ck6Hoa+jO~b#CiPPTJu8+5OO^!F+NEM^P-Dax-z7lvR1aM_y9Sq2j5Jj)z{1 zGG+x*>0S3xGncrEpYe+6N1b?4Keky?+8ip-L_>ho5GHeC~Qu+q3czLL%%cWrid($D?A}w zS`u|t;ElW1tw;Rf77lGI_jCSq+V?Z-M$~Ao9^dz%T%VqL-E>s5q}|p1agk3PlH%N4 zGg8UqW(3NvuD<5X$&9lJ(Ss7DIsvKU2EF`__5>S&15}*0*yUHuqM=-Fv~3g?`x%-! zN*>&mw1s*V*&V+7-T1{rsqGCK7ID9wX{kjOdr{IsGSu76dV=^6ZVZYTxk0mbr<`!P5r$Zm9ji~&UaC>^dD?2bZ*y~-&&`mz| zR`MQXM}L<8(u2;pg_~R#ghhwfv|V*4>b9xm?1tyVi5*@BanL%^pUt36le?#-V1)vt z_-o$}6cSKG!-Iv5ytK3kRPSJKu8PbJ%aNuRD~#b?SH}}6pu)DC!7^c>tvLd_MX9ac z8D~WvMJHROZo@Ko}rTyHpJvVX%KK=5x*97i^m8@U7WI{O<#aAZVQ=aa>WST&& zsph<)0~HaoZf&BB>6H&YqLZ0dLcAQ^S)Y93&hm|Obse&8eptc2!D^6_fR(0(g_o9z zZD*P-hVv@9B7W`-noaiD`(AQxaP{JwCu5Y+z$H#8L@?|2fy6og~T7mYa)om3gV7VroTM|ez{GLKd`oi0p-M5meQT}l^o-~H5$ z8n{c14L+J09y1}>O;$!tr8OD3*TGOtp{5LDy=8+(I^@l#qAu}N`! zMWC&+$TLke_}5JodOw7oOD>|tevo~Ucan+)n{<#~Z5;1P&)fCS4OE@fvxaUgp`t>d zs2|`TD#O#9sUb>1S&uImKgd9cR|*UBo5JXJRt60m*|bcxwiezU*ZZFQc$VEsV^Jhv^L-WS{N`o(*DqggNLc?|!UQcj3vYU8!@ zo@MYj9JRahxlGg7%WbsEnw0EMNk>wJoYu)Kne;?^0@?1p8kt+rgVQ8Mv{9{JUJ0VB z%a$QsyezgG+2pcocA8MlI*#&u6vl#JCM_McG(Te^fBl9_lIgu^VjX`_x}G}g_mpH6 z1D1xo!YsT`?|LbAGJ`^&t03LegGItK^P3RCf&SdQBM~e4V!uIv%$?zZ=h<}0ZjIu{ z2Lp2i@1+NAACG+fYSO0FH09M2+^q!efTH$Zl7K%fr`9^znDXk(&xjmawxtKrk+XM5 zbnLzdj4wu5797xg^fsu$Yw0cO5EqDRZ%jYY-L@>d%tb$1W#6&M!gurGY(J7XRMcs7X|pX35T}u@j(FIWP8fvih!d#?diNT$f&uPiIu!)0ErvNDo00L(LUB zGvi?)*GqMIyXB%%044pzpH{p^40tK~FUAMPH@+7BOI zgxaZnAt2++dD}KG;Oe*ol!QaYN$xkRKh?OjVwNoC^r-YF^SdHLIxqL<)oOMHXFDf3 z3^);-dbHZOp7lf)|EYx2UidW6_;+f}Rm)^PEiG=3hnhqU>=q3B$olW8*iA)*Dhf0_ z6xTd-I%RBmJ!)592S||S^%3zg48^(~9x+pN+|YTSZ`g@VR-c$~b}k<%tJt6ZQghJ! z`9ztupw!=4&qtvvZ8*`^6DW6=G*YVsl z46)H&Xfksc$1AA9mz~X{M=Hw7XvS0Y9s^`vAI!XXh_vDEGYvT}B;@0EmL~)DUG(hX zBXWlc6Q7zeWuohlfdLI_yz0xXT0yDX&!1*|O?i>mjm+V)Zp~9)k1kU>OxLGz!}-h9B_r8*3uZBs{NhbtkGliLi)fr_SI<%{^@ zE&LsxbRZBuP_bM)qLqnyCV2Ew}n)T)j!LvjOb4nHQ=CoiB55$U@cji7jHwWV0?Kn zL1+~SH%X#{|8S$u>5PKoccC=$$g8`2MjsV3b-y2x#j8%>s`3i4U{y@hh**2a6`2fI z=(onG)u(w;R2S*6-QpJ&;x;{5x&_)sv=eg0hTbq`dEhFGWR$zQH9^g8-~Jq9*nMSd zYj=4ltAiM)SotK;t;wafw&7`gZj<_UZg=djO>=&C^qN&6GW4ML+XkiJBDd8Y;rQvx zVT$MW`mNFi&nHmrgmpXpgAgo&xgh3S1%^#{o1XWHI;%+I+$J7I-~au--x1B7(Q3QN zFJ%x_y!Vt-gMWrtB)L~R=jRW${jXjccQPn*1lwpok(45jv@r{sjG0^B8*lFj$SG)W z?S8d+=QPy>atgFw_`LT>VV4yj63xmejki5N52KsyRA$4En2pt+vj~4lk$R*vvN@KwXVX|M5)gRp*Z?^4&R{x5pnOf4EE) z3$+ygyfdD6lG@B=ZO$H=ZS;;tT#3qblWLnwwK$YqrctCpkz|6ZCRTPGI{CU zU%MXZ@HAGWo|HUQ(o?(Fm_ak~_<%o10D_YV%zWCh71Y2`=Xvwt>hu+gP1(#TDJ%7? zSpLBVP8Pslq#E?MK~gL~Ek5M)URWaZ_72s#oqej&e7Q1Axaz@_^(P+zZ!POqF~y*1 z_jD=>wYsMJq0p_;v$_kO#Kr*&8ErM8ju{Yq$bs7X#vQPtwm-b{?)5)~5x2*g6{sEy+JkG`1w1A8C=4p29u zjab(&4do+u+drymQ)f@71l3+fJxqImuUx`)Oy}vP^o3~qXT^V_IQF))* zYe;~{r>9C7-JPsbD|S}|JIX_GZPmd2PBP4!X5M5dO!d;b zbKW+znmKBvaG*%kw_D%{XT3(#am$r{%zK(0<&71sdwFb`wf)yN&!R@I;#;r8?$tHW zP^YQ*o=&BtT<;zE*4exiA(*fwRmQ%%JYdSu1W-@o%0kO=KK~1}c@z#g;o;a45#jCp z6O$e!1cA!*mGkuXYLAS(dUoL36efEfeh~JCVkxJn8kC=ocm|m+ZC%~+QoGMTWiwx? zN{OMn&BKF%qNT(ytfK=-#N-WQ{6ETBha3D-;*g4zjV3^a2ad4_kGm9U6Kbp@-G$~t zY(c8kAmik{L$xUfZvk&!UQvGus^SP`3om*5K;Ee{#J&4!i%X^SiDI^exs%2jNE<5d z+N}xSY6flwVl&Rooin+9E$!e8=Pk-G5s?GuoAobT7*1|-NxEywMjXj-ZZ5Q>W%Y1p zU^`QGJx;TZ-HI(xd{o9#wj+1MC}msn*=uckw|2cLQnR17traPV@&}miMQE(Q*n)Tb zvbh2RI}ndQUEo6~hhZmfQcn>1cgXKVF#3(`-}k>ReU~(Mc*|yD0U^Fe7v=T9S+Z?% zM*Bua5~+Xsb$}uvTy z$MIjvw8TR9Dwj9tY!-_(WhvCqPCueE^@pwgox{HN!qA<&;vf}Vqn1tEhCB# zSbA`^Ar8ny{UNmXpq9kbdj5ppFZE)=nD8;@$7lGA~aj0T_G6!)kiHJZ9fNl2txzxrl&G((*>SBm^;#)9=kB{2s(7UHkoZg(>6z zc?_hSA}41McKikmANnnMYP~+!e%rW5SbvrFKz(DkTSD)Mq=6g*vo+1+bFW+IXT_LK7!*} z7ydqV8>h)B*M};r2M08a8*Bm=;dz=3yLkc8=^psK&Gq4rI@;|njf=9cabab*BG*RV zeGcT89r9A4 z0YK2;tutK_SDg-5}fO`WK`?ba0lPo&8^wbHTuC>S|~D&pLp@6BH~5 zEc=wJ1l1h@Yh;6eHCRxNtWNu6-Y#)KxtwNaGQna9D9SPn9L(D0=H>$Ntjp zFVHNq+^uMHL*B1_Qd@&DfVN6&(j>T{_rlL~OD#Ehc-B_VMeei5Ndo=FX*29{7#?TI z&7(3BH(0be#F5Hcb;*;pmC3^XHoh>^gmuY*li{}4;RSnj`IwabIpn8>Q04Ee-N;%v4^(%zGD?)FwP2D)Fc_54p zm<;J7ac(yEZr$q5GWZ-C3KfaWdT~Md{eg_DEBEQ?0l(Z|fzWMQFf;&T#~h0W)Nd#z0}rn3E3DA|9zst7u?7#RE+{Cx6s@YFB8?23HoFq|c_@vDrvE}7j zr7X;~4)hG^!|0{#jOl&UnjPiZNJf6XhAX3}!AOe8Aaqk?iJ57Jfl3A4r5gFep^NcE zvvGYS-~Ztx^qz7BxZ!rTtV23eaW7s-c40)!qoqj?qJE#=gR`ye?Yu6e*KTk{Ztzh7 z+nE09Lw(RHe4kz9jWhBJOGGU3dXF6;b2 z*#K)I(-8L@7y$oHMw~vzEx7KF%T2CvfGRs`BKS%$<gKW5aE~^7_QRim_5YV)vcOUU*xUxi>|TuCDORBOYzRjC^5?2N~*-TfeWY$2DQBStq*T5I!crI z2pTp1qQZ!XHcl-pEyJ+W)4dft)t>#q3zn_puw(75o)JQM?|=rOPrDRR^oQ>|&HCjS zU(E9GptiR5`@di}#BIKP`TXS09Zx&iD?zDZ<&nCI3JS`43OFlRTSVS|QZi$_^{qRR zN~)^IGm^vy^fcBt+D#z0xCI(VjiN6?$9C{IXs0Ea7M+y9XG#OpS+z~@{i0HZbBZ(%O3%_iA=*L&cxgzTUqc9 zAb=p?^Y0kVudl{Qx;KJ1fW3XuuB2>X@fI2=(B9Dz6T_>c89GjCp;I*;WOFl4&Qe$8 zzmq-0QCG4Gv#2nyJBZ^9pPLpIhWq?G52W-9KMGY=ksTqOC$W@K#jH` z;Iza%GL)w$gFq$N1SL6D6=V%`bq$fafc_7^I4y-ZgzKv5>Z(0A<&yJkD7guaz!Wl9 zvN}E-NXK){LeA5mWEGq-eE@L%ZE^bb|F#j}e+iS^_wxs4p}B!qtE=OytEuC79}55T z4nTfb-?+i4V-e&~8+;A0YBY1a!VtNiOu!(e`JaBJ9{dXPe=Ms0F9S^L&%rZ!evUEg i76eb`AHUkfi$qSSY*xn_XQ5vYtD>CRqY{~?Fa8ZG50|(A literal 132872 zcmeEt^LJeBA8p#G4co?UY^!l&Yof-DZM%(an-klb*mfqiZRgJWzW4h_+_mocY1Ub1 zopt8H-utsZ`w3By6GukCMSy~WLY9;e0YE{)W2$b9+;xwFBVHw^{#1xivxP}w#8 zWEJ)ox+Wg{MNX?=etf*L0?gOeFRiWHORH|DXLn1htMoLO-!UWn|M)v{dY+$cGyxbm zyx-SrC-_ZF3Z3syM$_+mg9}aem>_Td_ew~ig8sih6^4jAKm6}D;Ya-c-9G&PxBnZe z|EIuKwmXk3z0BR%qCE&LdL3t*j#!Sg)cKmSLn|=|sNNqfGdstM5^RAhvPqjVV zx6UNblS}uwCv-65;sP7X;wg|Y5G&edMpa)T{rkzv-k)rtUYHc8m=P1p`0QWsp#_wV zRb`tUb#&G;o-2&T+!l7PHR)5?qGJ+){syltS6B8YBBG*?fsxMtd&5EQ6_5HtO>|Nm zEtj@3%-=$R3?MMDI>%d2PtR3E*|itGt5LOldGFx2g{eZu->jaxKt*H&zdtU-C(=pq zQLT=S3|wiI>#fm~OlL-=iK3_cH;#4Z>%7++Q%YaI#`Gf-%ql0~{QJ2@FJCquGWJH3 zf16m0ygo+BSb)!Qp6wm0*6 z$cWMBkX*~?Ap&spW}!iSmo{ozl>s~nXnQx&KCr7JC+VU%~lqy#OmrFgw@hnEp!R?_nOqJDUuhVzh zaC`gvwMyMRq@iQN0&%6s4pB)q>p`Oa;v&Fn?6g}|w^OFiD{#AM-XY|YWc8miNgfyyT>}(w$d?Y*!T#$cT zRB-rwWrc}lk?zcJnf%0fO$|%<7mY^C8aGYFKcw{ZuS2Z&vCsi)PLI4$; zoa5TAcbUC4Zg*P?FOOyY5lnP+d_KFk-O|Q*NcKK6pxx3d6 zA60wow(FesHg$81&+oj~y^HtuK`@@*+th=vb?M*D(5Z_ISwHbDsZ!TKWNWWbk(Ji> zWQ2)64FIp}LwuNZbmXZ9IR%BohscK}|3d4`$XgIqv!cw-RG!Joh}>yL^8p-&g?MB} z7rSsaiRr=f1!9s7Lo$!3tY`@J!lr?VS_N2&b{_~CSKz=9YtkLz4}P2Z{2JVnNnT}c zKF^nv)LWjW5Xfe}alO2X80jfo=3t=3`6D4Io5t$XSD$tdLpl96vz?N*pK$D=!`n>! zE9-r%m6BHpO&HN3u2IKZln3oiv@qec73HmQU!uC2X=a9X3oZ8L)z5m}qt5lMt|DVO zQOim};-I$}(bE$ehLWN%9}X^n-+Swhfy(iGynb{cz13Ehsby;XF$^!ydl@uU$>Dsp zB3?1kOpUIU*QtJN;j%Z8IVj30wYzs|{&Z5{`|5rGJ-t0Wr-^=>%%Ud}RdJe9$;`=` z^BePZ>tqB1r(v)^_`Soo-w^W?I;#kDZ;4slm&*DkR(0)_4zA&X+6qydOx~xw+gs!^ zcxz05pu+PobZ(x#N!gOeriIb$DhPKbU$WXMR4KRJ7BSw!-MrYb3>X*8WLQVN>)?aOSvC&bj;8TVRX z)F(O3ScJhaeMZ3@5aooS*JxN{WD2HUp2kSSq*JHG=Kmtn*Y?!_C@v}V z^~&(0Zqe}`tCGi=06^D5T%?_bIl92>eZ+6^hHzHkrJd$fis}6hipcyS&eYP??6zEB zaqg2`qut?FdH-jsPmF#Of|KLvttV&g;^AMo>m0VGInQ{h=;+Wr@B6K=80hKA=W5i2 z#eUS;5VRs=hNFBM9v=t09P|c`wStq7j}~^yRQ{%0uvbP#;R_o+~&Po<(6c3?bT^`U#P_VxyC#5-GQ zNJ#{b3=cb=d{;PXRcV`bk>P7!yAv3w6rP#gn+swZcdZo-F+f9 z<1PG(ytt5GSk>4u?&Pu3dMyGS$z8Y!(XU9zg(lo$8RS5K9d? zxkOO(>auF37I$I5&tSueHv`L;+=_Dcu^w5UmlN2eJI~!diks5o>d&YXoGYz=1&JX% z)trQkx9GKuQU&wAN2_Xc`N9$_)Dad<;Pda2r(t(ge9UmaB~q~`!FcQs#}@gF@XOJ1 zzjxK)=FDq>i?!dORuP$A4M87fN&n_x>22pw+A{U@K#*Mi&PYzKVgs4I)sd>@5+)({ z{!Cz8w(wUEus&?5ZVw}~*1?`a<~0egHV>Odm0rC%#sgg3KJzq(2p-*Iz%oJ^6(S0aoZB`7QHq>aREiJ;>0TPrb5L7pm>4XJ-T! zrgnGaDmfjHKPzhGJ$vRgr__k$i$@}h>oukAtB;1K%2=eQpI-s&md#&1=5)nhkl$Qw z{oN&c;1U%jy`jTl{>x@L(CB1LmU`>@DMH>}3ZcAV_Vp{;K5R&Co&X8~SAa!^Aaihg z>pU$jHD=l)-rZ>jpE!&z;Irph*=NhAl>m#{ckP(8G_|8htLO8LpuyaJmYdQHu4+xi zzgXQCOUZ{brAkSeJqHUW507_yR!No4%GGsD7$*hx3%hn!c(fd{Sx?13%LE_ZsPBn* z_m-k2IUSA$efEs|Peve&J}JKard2qu1@uXb&o_jS%RN8x-Q~(^twYef<9ea3qx69V`0Q!{hSER*jI1XRae z{Za|hCkm@_8!fg8+~Q<5BF6bCVO^CzgOr?nC_d0Uhx$)<`^jo;?QbPF=vQ-JQWO~2 z4wK=ZeFhBvdKx{ZHv-Tw>&S@DD;b+F0mr^JF~*e<=o7pkG6kRM3!M_5Lt48jju4#X2lqMKZt_Y)r? z`;m{mCQ#y)3qqgj!-6==)MwkJTOmb-+(+quE5?_;N#E@#G4?w2wofS3G#=|d8^f@S z)~jzTCAk)qCS3(ZWF4kpcMh-HC+&*WfsE%Y2q0J=DAb!{a1dM@W%)7?bToNU%sp~i zD|gI_;eY+A=*#$wgx?b%F>K&V{tG2xnSkH~rf{~Q;hQH80oq8xDlG1!=0XjXkL@H; zjfYW4NJzxjMP?LOKUKyo%^G15YwI=ewc0vt00kL2Ib|V4Ei=8`QLi99K0bzoNSH70W+2E2i}<*lAJcO? zEhaHEKJ@iP;h5tz7hVYtVV_yZbhYI0P8%M~)|cEZAaZnQs`Lc<`B3RLgK#7NIqG3$ zV(|9TLHPP8<3ZeF|&$EthIqPhbD19X%u ztuU~nfkFwlt9wxmBIuI1wbj(ZTH_F0s zYxQT&SG=0+SDhIYZdI6xwqbQ~aa2ucx^F|4U*WTSjv?ZzfuS`D!XET2S79r;c}i_6 z!Tp8v2z@Z{h#0lM6?sLI!3U+75FEK~7`f>3a#sJfFxh$) zH2J#uN;cuYrRBvt{D;VOv+?lHy6u8yg(&6CQ1B{1pHZHQT66oSW?owhU-e>Cd1N z@)bf2IB?2W&?d&m8#?6R?d2B~4D?a5U@UY_MdIOZ@6s|N*z!8iwuFSp(n|+o1yh^z z3+F`S@1S>G3LY;n(|8`0T#xa55AF_-3Pt!&;J*{W{CIP8Z{b#kaX;$EV~#<{bvffZ z0+;t_|E(5+UDmg4aj_bJ{XvDxVs%B;rCIT#(VXJfWhwAY^pT60xL69qsf!vX1uSD` zXb3WWJl}IK&lR-`6yWubb^xS{iir5rMo@Z|$G!)h=%_>Rs@1vgrE*+MFol{G)9zV@ ze8MO2&T6F!^cR$wo_=x}hqcF`rD9Lr$Cw9q+0AZ3B@Nlcy=D*r3)Vd;eQWSidawB_ zW-n!4jdO)~l`<{i^XOo?T2)tmyIGFBuw>LE{x<8#Wo0)Gv8QF-wmsYjZsy4j4 zKTk8pK<-Mq{M@IBAMcd5sGlPBAjiC0TVd373m6(7ce|dyFX;4grkNEG6%tB!jvZ0+ zbs=TYh5l zKf)577nje}RQEm`k4{Ruzj+J;a4O!9ys@iQt`>A6T(d$7dy82CXmWCL?9IuEMvrA&S=oqSR7H~s zEcP8Pw>`k?lM_#a)osSJDxIa{@tvPf;0;Fl)m4H^F(U4fTAucn)VW&aIsu=4baFEG z^=f)X>TBb^?bN((hu1C86dp3F0Y)|!UXM!z9H*CC7@X#2kIE|X7Mhyvo~L~md4Fx% zJQok0ovcJe!_JhA)CN+KZAC;x6w4wqihw0rmKO^)%O9Y!4+7iLE%)UJQr@Lq&Q@}4 zpqNpp4zt=1`D5Hd4w0a8z9*TOdP`XDjWxRAJq@uy`H-$qG<;J~j^4Kp!XZlP#88*q zj~q9mpDXrb<#gRIu2pM3Bv|IbXgv*Zl103O!zp`(mxqDF!04=Tuz%C8X((&>#vYCg zd+us~vhzqe!3!}>>~Ls?Gx=Qt9>2oa#7SD5@wl$kN@0HNwO znyGCi8N~cRKtey-)0q_)V{+|^_`CJaklgM^*Mp}s3;GqjpXLI!@vbE%=01{0pYpDD z13tw24FzJ`w0+wCDZ-ikWB42A`kowbY!}o^1VqcYXn@=uhFXiF+j$l+N-J#E8!#{k zz-*jCdJsFx_glf@%3@mAO@6qTS(!!cUh~+BSLy3H{o@j0D$;ut#^dhhDEw6N~F|W0jGIvK6h$xrV0wt zy0!M+9fI47dIYgb07^Mc+oM4_1c2uR2pMNq(-u7$VrB6;dM#!DeT^$5gp@J6C#YT% zCKI|L@>IA0!`Ho4?>9jpd-!6~6p;ZR-@3wvA26JVHU4XAM16s(${5w#*dLva%S~XT ze&YJFbB(M|0Bil_IfDo4!sqPuU3Vg0{{s0Z^FE(_CTPR}YWRZe`~B5OI!gVN z8tfa#C)*b}-vDMo&nqP>tK)q`a<4EZApzWC=9cxr07e|U;N$gn z;n^rrl?OR^c@9`4GFd1{4l$SJtrv&drESOyfe7An_^e8K7}EPPnV_GxB;}M6zdfb& zek{)6@aLbOd5MFQDs?<;R$5$^@?+L(Z6a?iPc6$=Vf(L;T(Q1g6ibISH-BEn$|EB< zEm`KQ#OL+==7DNpf4ax#&a_^h;eZ%g`$;Y)G1gq=5(+-RyTM9hs`Q=8I{3>|T;i<& zhM|px>|dcX2j&+{+WIp7#tldf`JIw-WOXfIZgA>N{1n1$f3ndg?3oVW;z{{}xb9#+ zpgbVvgh}oG3@AXc(!fYtd>pA3k~Tjut<-%D(|7{dGXZOcxlfm44JBp51RN$uIV0Yn4_^3Sd9=QVakTr1KWl zb$C1Ne8&u~E;2X6;&d-@6+XM2eB}Jvn^Tl)j z8PhK>o_qwS7pO5t^vi8#ejc21>rJQjw@<4V!GnW?2W2OgG*>t{sxDQPGqsxV4y6>{JTuaJdhKh*Xd5>8ZJ6mxl*9 z5zpXU#<*O1g5`Qb0cWbdgaa%t*BwXo5f1AE+xz~*5eVrv?S3Qtih+ZXk(5-JlcTc^ z8lMzw4~vjj$CQ)|K`zB|I$};HC~T;zvKAiyk&;Z%dorq1q|u!}1U`JwwFP+_hx>pbW9IxNWs1|~p6w6DqlaBz4uTVXWS z9LMTq4)mqs7`O%Kan+Y~zAA<0$Tu4G)ad!OPv|t=%`bDZJdrNP1_+@hCK{inYt~uJ z0PaRw*H~Tx>0QqFcXTu$RUL<4LP5%JrMy6tyHV8D4^UKLt*y_~1=7$TKi1ULSXx=( zaa!|wzqoR9k7e?up_Ew6m+5(zL&KxUWNNiVC7#8JvSpRKsvpRLXm%D>;Q`#>00 z59DVsBZm$u+@@cqkD*hq78KJkUfNOYrsFq%pq@K13FPq@?g&qqCBZ(NKhcb^Go8tM*ao1qk(t z0YO9*Q3U&8Ok|qX0sBE3;@;IAE=J*1`yTlh&-OyS$hLKtTzB zb78NkG!&0C@6XrI7b@4oaadcNjwvW8oL`@A=StP?PrwdCvE&`hoz))qX9H10N$fqG zFh5kwepUaT0(4QMZzw1!nQhNHjt+L6pl?Fs4^bD_A9L|Fd5KkN(n4feSRY-uD6;N; zEg+=$JI(MuMlcq7?sr{o#TX&GDPB*Wj;|WFFJt5B9mArW5>eI!*nhG@^vyFX+nSR4 z`{9tFI?v;>vg8%Rn;rHe33w7SSS%Nr;NjtI&U2pu7?_xm*vwmZr^`=IPX_(rhf{g* zvPhpkC9_+oIy*ZX8yowN7D?=21_oVw>F4e00Jps6(CE|AFLT_QAPiwiF&<_CUE_a^{~GWaP-$K z(CIq1QMtoo-D#jgcxy`^7B)ber~YuY7VTcu-M#BoT1&8EV-0vQi3Z z=jb$h2i-{t3wvF*6`z#1{%~Yitg|`~2;)RRK*Z&=Pv&tTSw1*1kg?4AYvB3v(Lz0C zBAt7FcshP>rTTbdj0e>aQh?7tgj_{v!_06OkGdj>)km!!QGzg=`I9f`rJG` z0?R$X%Qh3K{0)(^V@*vk&tj*lbSYjCO*1%Hgi8@9jXACiQ2q_Iu|G)rWrVT!3;b@* zq`Vx+zsVGoEb#%l1DfSP_ju?Ui&oVKcH8I}7}QU;$Mf_w2DM%?cW0|< z2??SfA~|i=*evExc820kM5GjyeYYt3`}_06ql`gwE)`PRvQ}G7o3(rNj4w5h51Nb} z>eq=7x9q-mlOSwQUc1c`+U1&p1j0!T_bYAIb_31@NUKf{i{NXlN}{FK$CVI1xVc;4 zxQ3QxAjCZ7bGd%8Sw3>0bPfs-x95BZ**@;Yhmh*Fu5z#yHJAw47#_R^$+hr$I=^h( z#fdvNIGJ-8znsL+*6p`xCanK(GYop(K4t}m^Y@<99Uf!-FkdNybtp{dZgE&S=n@u} zla!Oh*o5cV+D5xO)AHDT$%(%Iss_T>B!Kcp=MLW43nOhICJTkx#SDHYa#?xIfJj7} z>xtw;b#?H04+#ms$Y(hs<~9N73(}pv9i2A&Fv4j7fZZJX==kvH=&-lH-^~^D`7`pi zab9XW;i~uWn9Bz!|C_g04>L0}j0Bc}6o`sQV$h~iY;`^@DxwNi<@J1s-onb@aRG)5 z4-c=ly0|zw$;!!r?01L5u-ektW?Fj!k&hRvNkx%&c6a%Bc^R}@c1})Ka)cFGhm;EC zkcs%UQUr9a>da=4kdb@3yGvA_bCCn0qM|l*6c7BJ>vzsR*Ot_vUm+i@|I@A-kjp$@ zc)o5gVAO7&%dgJM`M?NgWo^9mtD_=l-=ZPGpNT;W#GI|`Vnn{iw=fVz2w2W>dI*w$ zFy6#*hkL0{mbEdk?Xn#8e6?5he61iOqnw=_(u17H?2rl>S+Ir_u>nFf@n_)no|?I| zS7_fILqq=legYo19IxfXxza=H)u!-{sWdryyoEXzg9m8kl(f_p&~p{eJHwKd1}E0n zuQ_ojR?IXw1hG32aVdyc2h^~e;$lu>IGx!szSr_3$WCyZJcRmmZ(J$l8T<-1N zs7VPKuY2W;d{SO6(+`^zVh6b&p*qk4;HZpaqNB4*N;Hm;%+1X$ecMmnAt?a}uFlQP zHRG6eEiNuXO24iYGm>%+W@fw5WagHZ7Ayv>e<1C6z8vzPJoBeiHw2=_*o}=1eZ|j+ zh++2q8ylZ$ORf}$eEMR!Ug09Frs{|}nfZwYWj7EN0f2CM33T@a87-~uwt&*ZE?KvC zej%pL%S!{#;`>LytD`vUQ^WPu6_`sU9s?YL&IM3Z4ULkwbvAe2nvC2oWIO@;tW0Jv z3G_V8H#SCu$^SMuURgRhnm0zfdU^O{Q=hBv_Si%V(;1bd`#q55iE|@Ljf8?YaiEjY zA8KGdiUEDTT;tc3F(#BiNJ;3`WLLX5(&+%i<51<`;6UI0;d+t1p)IY`;q7%aTTCvU z7~dk1K%=s?wbhgqKM%QPcUEV)`1y4tLpZ+^1@J;(0h}!<4jLUD?F+*~#b)}`jmdW1 z=61cf$qSl6RZl1m(K{#1z+}+WJ)H^8L0^@SdE@jmf1<#02VQunGtW>={_9jL{&SHz)x|=u9v%F*7?H^VYNNEDZXI?lw{0M7jcST+y4l1ZQ)I+iR)%JQR!E9ptLByS~)tFu)OeeA3?-Pxk0<$ zSng?BqO_D06O@3&0)rK2h4yTRyjlrBX@RO_Vz#8@@Yh6x_`;ooiJYtJ{z~#!za~7i zk5DfR-@biAqmsXgv4&LZeZNg-R5pn*}cQm5TC(9j#EYhb`+ zI$yF*XfN%hNF@S~m5l1)719bi89_PK;B$Q-qvQ3R)>(U-SkbAooL6|LcRF0$8?3H{ zuzdU->ZjD#^H6<{x$2A=i0RE*TXVqd@OE{LWfNata%ZKP$>qXM${IE;E}yg(@gg$yjlv>@uXwI|Wj z$EmknHKETtHV&sRdT<*iv9a;_VG989OlYWw8HGQ>nwlOnKw0UetFv5<0;z;*gMsPZ znmsiIg&!VwC!;B>jaJKhr>C-Z5o_%pGdB=m8&77=Ga5-G;`hwPAmnxorjX0zbvs?E z&l8IXg;?}bQcEpPw6gfzj;8MJ?htG=)ug7Tt}CzcrPjU8QzfS-uQ%Mh0YMLNY@%}N zlmZ`z3mghZe`zWF+StFhp0Bezam5$Pg>o@A-s{vuW1F1=D9wnW5Ghzz!l53dq$cjI z;+~zI_i5ve24OiP!~G7v6-_OfB01)Q@pY?lEg9ScIZF!sR-aub7pf6dU{nW(%!p|_$f140c4?=>?8A@_%ZYFE@ z4==0MNS|_`_`JL^*tq`*Dnk7Myv)b|ll(3xiXto5j!tORwdZJd8k|uQb}(W7XeHJV!u4NV<);(N?0V z%(k6)9pz(4VXGEXsn)D@jcSI9Bx$_E;O43)cSr3TXsh7Km1;crbu5ZWMjklX-0KScOSG1{^Q3VI~?g@A#)o$6l-$hwa_)c+p zLwY^IA)ec=G77|yxEd7H&s|k*-K@v=KpQCUz!ZWVvBu~e7>vyNgg$Pt6c@Ji%}VSI zf25jRX%6{(3((LQ1uYJsAS*iy)|ggM8Z{%Y%tB1qL=9J-R@h)4sN(Wf{U4 zyZNE~k>!6Mnk9!rSwtD>9eY)8RbBBi2jF5OBR9)SvZFu0CCkT9uv+0b5L~`3$2s^+ z((@p69PUwn*p#G2aRa$w6>5s+B($Fm$|Zi=YOCCSs;y$Z_kHP!wZFQyvM`l7G%&~= zIsWc&JM@f9sat5gQ&*uTD<(xk+G=`^rc|3m;Cgu>o1dSY>{mcBR$0!VIsQ^GJi@qQ zw{{$BApy{k<3k+VJRP$#zp#eU`8Al{gywn*_Q=|Rae$t)TQ#4i7+&g$J#!Zc*L)xB z5^{KN+q=2iEFFv~C7Q&&o3PTE&qT+}4H{|_Z{<=MF9=N6#llI#d0FgaGWZyB?#N@{#oyAp*a;dsqL=xFai`wi)_fO&QZ+^H# zReAwqoUBKTGCxie$*J!W#=In`4jQP&-Ymmju0Kcm=& zq^msip4o+BCNS_6GKHBjy&L^3qfvm%G#`;(;Jv!-a?iOzSd06&Et2JN_Xv&GKVG!7 zl)9>7ZQ_WeekBMDjHI0DuCi#F07=*WRWe?#KpskY zI`k2h0;p*Xr*>S|Nk)A+Sj!V`lA&Q-;6pw)v^k$k0+;nDHm}PM_kGWNBnC4)Y%Ia@ zv}5-T z7kBt2YieO3DJCKB-xD% zU&q{b&1s5)diONdwi7yg&=BTz_Y;Pav?PwL8R@mpOcStl4BI~q<%zQ*4naV}{75xB zTIkZ(2y2?fKDoS+MT{*jA@+C4)ix}~QbZuI4TxE+9#CFJ22p>UGnntu(UlYvw3%n1 ztj+7cA2ABamT9#j@>m3USwb3YTrq!c|SvVofkIQ5}C|-eZtT? z?i$sXwdN|&i79J-fTAONQm+?GsWWw+r&Ow@axlI4hmcKv01nQoQ2TSlo~U63znlC- zUhA)jQ)5xVh$qqspwR_?WY9aLZQR?khs*jj2TVdw$QE}u)=|Gs3U%J-U3J;gC!tKL zOHBI8Ii;lGw6is7T^mwI3bS{Kgi(#n`yo zvuoI^xiDie{8zK@jpjdSEC~9>-x*ahw zAM0L{tGtH!SmT_E3@<{7!LBnnZlte-a5Fn>!8OjY@*Nc8rj1RF0H~s+2F|8gh)`k~ zUid+S-DIRxa{@)C&Xi3#7dg;N>`Ag(ay{SZ9$`hp{QEGG5)5*3mHu{Km@4XIlM8IkK;IaP8pLZpXt7lVN6 zzFCk+@qcFoO2Q$H<+~Ed2un}w^+R^ksy$+9ML~3I=JLdl|7nO4Mcu}O%9jnu?toA> zV^x8X;#VZ zyBY`Rx0X|Y9GJ=<6pys0i)A?2Z#gx&{OVT+mj#M&v+C@6qu}Aern0 zaZFpoH!e5WYDrNmdA2!MuXuCZ61g+0o^mZ|*@m)5>4Fj}S;6S|I><=~PaMhWq9!C~ z6J?A7Dlrkg$cG(EhJM9)!o){O6~ol!qqX~&?C)3-j2;b43_jjp*)|_knBWE~9k$1N zn3XV@1lG#}EXH*~V=wp(|&XU{R?`F z+d!9OZQ?ZJ@$r4+ql&)%_QA~K11w8|_#@YTH44VkPLqIx0Z9I zSp#2!5Mecyy3amsGUuPxI=@h;xEXne3evSEd(ZQwMFiTeU8m6>l!mc0Z##WDRMOQD ze4_mjsjAwhigyJdp{H}x{2VgINM}fb<~GsWmE1^(;LBD<-1VtksP%F%>)vgwt~b!f zTr-D;a=I9$@&*q#ZDMUVKP@BPAKPXy%9#UTR36kmB7^22Y2|GY;f-wQzak~d_jxBk zL#DnL_o5>%Q8o4iipr+@I+;jBB)HYvHHgfT`!&!DvcBt`isaDlbuU+4uWsY%qYS>W zrY#>S(0ymjYNVl-R9vOGI^!p5?!!~Jn7Ibgf>;{`PPv~Uk?*PT2pdn?B-_%*dmNH=dgw4JqsDAe%8SgwC^nnV|jMg!v>+Xo6x! zB3%8)?`4y+XeT*iq_xnDi_Wq4WdZ&4ry#Kn8?uz)4in@0{@fJSxjChg37Mj(ARABR z$AVsj)BeMKb@Ybp-(79v_C2Y9zv&C`{#$fde6?nr3~t5{4N$`x|4D0LdC2}O*M7?k zSpL^HwQVpipoDy%&V*J5Hp4xUE4LXbKoKQMRbPBPJA{zf4W8(=>cfv-5d=igo!4_9 z#k8L+o;j_vX?BN+bFBk|;J`V|u#_~CwFO7D3B7x%7xe4G`PMlo7`ySTtFysa*21FW zIa+4sl)l8#!rXP9{NZYQ5<=>?_2}pBB1|ukFnu9sO5-tCd*6je9+H)f&iIRw`j6SQ zUuutCBdG9|Pbo*GqX$aMLRl``n*lv1HTG9T9UYCc)(?9DWSOzbuSyD12 zHeljtZ8`Yq(un0k`g`XG3Jc zl>0dupGPf7WCYI^Kc$8hCQI*$7R~eSs6o~N->Z`(<3akFrpTp)6oXKg$VQb^Fh0Bf2-hM|3FuTIlh#i&{bWxAy#_eMK{C%VQgJ2$hWh)J{f z3qtG7N;+G6yOswY_0wMxG{m#V9lF+N)raljsTWLqqczvSEyNotu6Dt(k{c=xML|{l zUDF`ILan0+pL=||b#AGneRbT$wZk}r%ii=bLhN>n`c&Q`uX*Tns|g1^NA)b9rFH4H zN16N(TMr%?xd11puBt|QH}~j5Fq1&p@t1gcGCrk6O_?5-7Q6k;0t=VMN?qlv@)uv< znf=Q4%PV>Li6R}@LXel0yX`sX_RhuYj^qcKjF!;KXm6E#6iV#3Z|6PyD{cEy6V%1U zE!-OAX`FS%MqT3q7MrQ=4IJ9sbu< zUR?xpAc=BgcBB>;Yhha58uPH0mZbwduVy3pjE=j})7{j9T2pzs^yV6;RUu}@wV0OK zzQ!}|^n?UHt8QCoFtqqMug|6N(Su%pU>gU@SEAgc@>Tx3tT$Cmb{L3X(_;c@eejEj zNlQ!P;VE0p=Yw)UYrDtyXMCP5dVN~f4PHU=1HJtdnJl5xsD!P2?pyrst{o0oHtvrw zKNi7c1^G`;?IUBf-124G9Ga?PPe-y?jO%{}i?F%4)De}oD+n}4hA`O?!$Tik7j~(= z@TjSa`^BCzmg}eION3^0+b`|xoDh-2igI&Q8ygaouEqL5GO3#@yUW#fmnS0>$R{2y zHu53j^1NsKuCdY4%Jn6I0mYI*4P#(NnmvP+Zj3ZF`b@jyiqhwi#w&Z4Ym;y^Exqaq zA)G&|61v;XBaI(F3Ik@Q&6Ba6%@=abF^~h-MU6JE#Nw;Y%Gj6t^@npINL1#;%0f~~A`@hr@$3>`k9tGj%-960P;|{$f$mJFF}w_h>idHNKv+ z7T#vt+dKa$KUt*G8IX3fn*bFV-JXFbhSOY&lR2b$Fnrn{x1R|)SO7U<1tiFREqsT4 z{mNZO-BRwZPSm^18NG+}{v{>TbIhQ2c^pkJyW7 z>o@bw{tCf4{oehV;q7wypnBCj5h)v;lmwibu04z-<@f}-R*quRI)&5qddT)m|9#KrA9FMi0tNMkDQ z5qbk{!$X6%cy~7`PlMT1f3cZ}2wMPaQ{(V@5acjoD{6W^V~V$e5}Ka}YUUbfe>ncx zZ#t+z0!I`E?)H>~l=gZZw4HMmheB6x${7p$tvJOvz{~Sa7b52ST zJMr@~S2HZngol!2&s52g00BLSTL9Fr`&nDryCZt?Q>gW5I-5{O3qyOEl@&EPwbR`e zG7YViwB%aT^<=Mv&+O!uOGh5~pbLn6>$Fb~-XOx>`fZ~0)*!U*gUwN8vMR4lQ&bfn zlgVW=Y-(h*_6q~y>IyzGvp}CRp@LDTRobHuv-Wj8K%uyPXSf&ufoggg*`h&ly^pMD z!jQzjktVyv!Rhe?2TjglKinJ{d50;)26#+&PF_4Z~l>Mr#V85?7RaGQ9-a`@WI=g@sk~@5epOd#z{3^UnC!sJxAj z0i>FZmZKas8>vpVp08^Jyzb7n?`JDXGAW*GH`SJ@^O8g>%Z$;l6qW1Vzx9lTSZmK! z7iNHTy}*&j@1G?l(XmQxOnNvDzPz3Plf70zfrJYbV|;yul+!&0b;Pu)Dy1GFN>hXx zYJkyy^y&HW0bWX4x_SyZF`(Jb+L|z7v!_Uqh@ra9IRM7Gf zT5J*+fmB-CC$Z)%>-KuE7UZL#tejnhFn3WqQ`{z%wy|{N<7B68B@64;-06~Yb9JjJ zK$E1QKL7CLHYRkQEg-bP7}$sS`zGelZRn_+Au1C~wd(x$F(z_ARJ4-g(63AK)Y zp|fd!>Fet=*Tlj|rlwJ>4;2$}RjwBGPmfTT4a`)UaV1)BN$h*BLLFH+rE*S-s_|CZ zEA7K`MX<}cdS+-r?6^e+70o6lrjgi^sd`u!*x36|)A1#zki2Gv{8%W{D;KfK;sDfMUJn#FF+ydI>=^&FbG6+)R$X{YI1Uv z$?4VWhf$Ij4i0%w!G>5h_dFf(4}Kn%(Y5a?4E|LtK=qtgx!xjgt6vQ#0;zmPA{Fa$ zcH(oJ^wi&*;@Q@i&aV*c3o0&Vn@dUBRHb!ABu$YU&jo-2g9A-42u3Vf8k3VYBJcP5 zS&^sQ%5U&FV4ytiz*j!8x+mvAR5vS^OzFl@RVPp~FG?_c>h^{dtc0 z!h*Q-@>$U>5ZTaH7A`iSDT%c^drZKYK=ze@W5N@u>_E%XE zHJKY1j%a}SX?ogcxw39XlKFD&>z(FOh)l-7*kNI*Jz6N$&gqktMUvNT%1lnie`TKU zAC{3(jz7xP^?2Uh*#&rZ{mgDg5Z9KicWJzXNdA`hgU1LS)V^Mk<$CLWT97vmXlSr( z(W>r_ke}ci?%I4Yb)TxEQwac^hNmE`p~1q+TDtgRd08VV>~Wl`iv-LrE>?UC+-*UhTdkAb!1Xao%aEukU`t z8i~Oaa~2x8(cL#X#yT#ER>AQj*UUtx%;fILEyFiXd;M!jysE`~AuN3w=1fV6$k%&G zTun|hs{)Psd<>WML*gttnZObj@KY-H4JJJR6ngCj2fw!L$S!olf7`Mt7ml$@YizOx*>3B5cdTX`S+qSi?O=%ZslUq_>ek;up`qy{OUv3n`iRx+9tE3iU?=FCB&=Gc!{`Pzc`P2WkW7WcY(se zS|HmjrD!9Gh%#4P{9l)BXEm#8Ou*jbGAbDtFAL-*too1%`fM%=5hTXmy zOvbxeIDuV;)|t4GB^U8DGafM}+~p-6x(D^YA375M#^xew4H| zu{C4|Fr_aV(kfBn|Li_KE{~0mulJvi5x1Dd%UDax^DBSX+Dos0jIZa1Xm_qa>Xna6 zeA?3B8}1Wdnp`w_GN$I@X!f3tng~Dk_&VN5`?2x6i7!7NulbC#@s(#}rNxIa#W6kI zH5WU}jQkAI4SE6i8(X%u@rrZ3oZ{y*i5YRK1H?{Ems(8@;^kr&c9qUt1=&wkh;yjR z?z^5}R!zEMC8^4X8JQ*1SA3i>RGO&RQ^K;0^G%4!_6te5!g_9cG~cieTXeZYX$~Ep z8jFdF$h3O%k^PS;j1YS6CmA|r#bZ3yIEg%cMVfz3u=cz1W@2&Cdt)DPLdr?ddAf8{+gY z@)^hupuC?Lg{9}d5tmA8a%xPrD2&jHeg1cTye1}kW-|#Tkv&(f{j0X7@TYr`C?O6A zHl;g-(b&kS+vX!H3$41SI_+E5&BgYdc}4IqWmrWBbH7bbKi>!p2q@b)I4%DbcBfh` zI{<)-1#4%`zESCKby4*LQ-v1xkEa77-9z>V>wm)IFIKbg-EZdWg%3p}Ku?;)TfyUc zLfz?TI>8W}xbGJ4THOGJm8d_R?BLjgeCyQ2c0QYl!-z%b&A(~ZV z|AqqAnEdNvP@!hfigQo<5??z&DS@X8Eew0HVeQRT1gh}d6jS=v2_^6|4v_bH@4E~N{5K-(B(AZlE% z4tl8=I%ol(^Ke`3r#f$(nVTfyC^(vg_{~()$g^6sl?19CY1Uu-Oh-7EncNB$5u)(- z*Fz@fb3U2gkt$;yRe|N&2DA1~HAa?uHO%|7#g>=b0xW`-f3y}NwW%?J8A>vGckZ)y zMb1}$x9snmK!>Y6AQSW}rO>`l?1>PCEncCX6W8M~@tGW)D!-~sYGY%=`3AY}lZ%$T z{CEAY?xWKb`!6#$;Mu~5#L3B=iI0wP@-bit?-j%{Dg;$9Qo9)PU zYFpJ1Iym{%WL_TN#BR|SqZC=*+}toE;9xyh3|md1XpAYGvA!G))`H9_B(Dc^*j|ML z#h^wG^m_J?}38Qu06jn~twLI_QW@ zEAr3B*cz4tpSn+IlinbK#U%K}Tq#6&G5Fv!+BH`Jjs9m;c&Ojj%U5YfzpidXj7m(*c{G{+2L4A1LY3BSsbk!(o_EJw!uYrdKLt8TW8Vu= z=!hY^fJ^P|+YGBEkAk#pQv;J;@OtHrpU4q?j0V&O%m`VE5jw~m5xNMEJpX2i_q28} zRbVIdFhNZ2>(RdO4VV`3aF?%PfJWtcaZ>O)-%-P!l`Y}VQ7|1@(L}>1IL2=y_^$_+ zM_TyZ=z`Z-*%<*sNYux%X=yhlIO=@V%hcCGKmRp42+K!yU3^>Dk^3dTo(6HF+9*nM zsEj;fWYtYe0@)VrvycB?1RklQ?GWYvehI!7`R@;d@9FsdZ!h`({nOY+%dyWxCBOgo zjV!}MlVj)*1ya7a7-Awes|xApNPaW4w1iq(YC(l45L=ja)8D>+z504pR}z)=?c2Bg z)xw8f5!3Tjw2axgZ|+Fr1O11-U`m8Y3=DqxD>3wUNDqNPOi@}>K~YvgQdL_*Nk-NG zM)jkEki%2p6opl*bj3y18DENhmVOQSrLwJ=7!`ea?j8Ck%Fcq6lJ*1@MSL0l zS=BOR%g>R!w)S$?uy^#djp?@@{&Pelv1{kB`sJ;gs(GX(MDL(S9-NJV!B*>+O|sQ6 zNmW@(F~h3kz&DPbVRjtRI{^j4we%l0G72)IMC@&Wij8FSbwtQ5-YDSa>HN}0?Ph%W zdNAnt?2TjV&>2Q8S`#*ye0>3*kFE`mfi<$=^C*?o$Wb&jpWS}{c_duLw0YdvaFPfd z74fNGPhNTjhba8eRaR6@U}jsJM#A-CqrCsr135lZrg3b&68X7?FCj6Ytd=Jj2|>WX zy@{%j*4g}g=oRpq-?33HWJG1Mnz05-X;cfjvdicsX|MTlmx*d8Q`GG%R zL}Dxxm1p9qFwz&vfUWgSG`9CP_{veowSllz6$4yCgtWX~y3BR`=WOpoAo2?TvjReo z!P_DK_jW8TlcU~Y`p7>SjaZGc_!W;`i$*7TJugb7!l90YENBd~LCu?KL;Cn*-wXAB ze}2D)Ajc2KTlb=;XsFglG`TN(nS~eSN&ow!fHuX%;8`k~_EeuLv+T^)Cmy?-F_-2K z;mVfKp;wCdHTZ0>82-5Kuu1>R3&0jdM++eSWGJhnLqRn@q5NSW$kow;lAd0K z>8R!tpWEqcDjIJE&b7^Ec+WxJUH+90`TDy4fJ|^*h1Jf<=-zdFJ^-9eN2Vz_7~Bsd zWPp2^)Rs&^dXeOr)q;CJxV8#y=MtRLpK>4X7NS@+A})%5miQeAItAmUx)&A(Yat>` zOV>7M(xhCOF$NgObcGVwv1PSVGLX*x@l?p2VUz{G+i&$oQ+%$_rl!GlT9KLaM|UIb z#?$cdX!RyH)L4z0=;5*il?jbX)9*Su(oFaavk@;-ItI%P7Ye*l2Avx*NJ zb#>XTyF)T`jxtmW{)p|&lusHyC&8Ms`XkjX5_>n4{K-9@Af+Hftx{pFuFAfktjv~C zyYB8XSQ`}M;ntNg48+RCMFTD5dE^!k0n+Q{XeswvY`- zYDK&M4$`q5`Kd*!!C5HhpBi@DnO}Xivp85QD&i6!7bUFD^M;06Lh=h5h3O z)aoBT~+PW*g}n@_C&2qWze6y}n;QL1P_N#B|{Fm-uVd_~3WB*H-8! zo15rBCMzpJ%9Tz|ywLM^!2MvOTSHDPJNAh8@U8h(>sZmyr+>KJR9R~5Vv{GLtK<6Q zSb+i`z?8#8%L9lIqyGd2*?A+|x3#5{30!8HohxMAm5t?_nvPd&ZlK`eQaPY*;E|^Y zCJ3-mjtwz&w6%TtL4`p)BPIqtzeK%fqA_1yX2c01;4J9Av=9d(QL)fN@hScNKN9}5 zV3?Tk=F4Bcv^AYIY6tU#5I-_9tD%(U!kiofBki#{US=M;nCuh**Rz>&waS8l4$;nr zhNnavu)Y@Zf^j|k(ma#w^n&%9*+j-M{C*OV4V31VumLz}8a5yvSH=nZVw!0+d7fp5 zvU28jF{Wn}s{4^2fq^3Ry@YDLDXs?bqL6fn!;?o$FEx2nI!WbObaWTFtSR zXZ#0McVTo?<*3nWz?y^h*5iEKAV3%W#xDKC9&G{Cq|D;@o&?GJ7@#{PWjb!=4^EP4kK^W1$g9_~YLKtXRj4tbzmw#B+RXIdo9wed- z?mTdY*#z1q-f|TQxLu6i1tRzru=AF0Nga9L4MA$%Ql663)v0W37|;Seon_Bpb}mh9 zini0%rJi{AtW64C!AIqam-D(mz_kvJlZ9yrWKF5XdRG5 zOMj+@{TQ0!#~|I6zX_9d;0S_^`4@~Aj8>`W(IqKH>2!HjG8S2q&avyEEs`gW+xyPS{i)l%_Xp`DzMhT__O|^Ziz=mUQLw4^$~QnH$=aksULNv&MDs}eC&CRM zT?^?`0=i%GX)VPFHEh{5cNk-8oeY@QP1ihwJxld}JQ4;SsYw7}(&3z@>=Za}WTPeB z-(KyvG>Qsg_-aq53U+}D00{|c|IfK}XHXdt*J90H@8(=XgBvnkZNt2#2YmVNDmgpH zXnWh(W{i?jK&#d!lx%VFXqvWI>t@)N!K|E4Wqh&W#K=~P#okmyas4d?zyB_$R1-ZN z9S}aW7ZmL8O_9gAaq;r{Ev#nvHOxXuAq+13&i4U{bHsJ4`devbPmoR>4tQ4fh&u$S zD4h0nMaA6R)<^|o_oIOCq=@rhCgxuOwlYL`94jV^xn#KT+=>>rlw+)s{Z?Q(B7o=- ztE(n|X>ZEfkjq!Rz^|e`Mq756BM()l$^C}{z6j8cs*_cXM0V(vM4dYNq}vzvM@_3C z4&ui-@LAH#6ELxR@noC^*wb~L3MXKDremd+?U&xl=7!7oF66Hy-qQvMMiVW3@BIj~ zGg*pA4ozxO+RJ~MB>`0cCWu&~8vLDCFc+jgLONQMqh2ZfKuoG>m-ce%_ z@g?Sc7uT*!ZFXz-S?Sgsd3@O`Y`-in3xOV<_%b^7n;p}&&$RrKkzs>HyBtqH#CH>W z@7Cp+?64~+Wt>}54&4NP0q%T(fu%~hoXNY&(Ks7<-+scLZ@Yv9kW>t!Ln$??zWv;b zoX@j3DRWYyyhcPQ(W;dwCD%4* zqfpKAa2U=Nyr5*g)msk^MHkRDvoPpw(axO4jq-08CwqiD zflPUnj3X02#J(Asmk7s|wiCl%=#?M0l2{2_l#6oO{#2^gLHCgMsEBffQ%k z(J8TV6Q@Z$mGjLe51%V(6rk01_Oe14F0}9IMFhB_>1p64(JN7@ z!*o7+S^U8+Ey1lihPpKOnB(Pz9EMKh$d6)F#i_fKRXmP24&Q$eB<zmtYJH4u+pDmC7;@q zl~ZGQkdxKwE&1aYH&`urXqLT16Yws3%`{gMt7wOihA?@-8~V(M<|0=(K2zMt2vuSj zNhLo!q;ruWo{*;Rfi1VYYN30(Uqe(RdOZ>c9Z_$FMwCc*M<+KqBlPvsj!bw;kR1};^4ft)c+dXi@ex$6wvu`8uko@ zH!%$ncwG6D3fM*m;PvNlk}8apR*=;}b*~*+QtOzix|SE)w<`QYED|QF%MF*ALbkSPz#eEG6Ty}PS=Fp*D6Ra0Nll9D%F8n|M_?Mq&` zy->)Yg8rxJN91n5NqW4$kgCJr#hfUTztq&xn7zk^X^K^N`=vmRU$oB)P}I6=XhmX7 zhJE>OAagk-~eu8%%2l3HDhU~=k+rvw)qmzV^Qg7dq zU`g1X3D!Y38hdva6`(>Io8~G+tyIRs{d(eVFF65;?4^wmYHp>;%CbcauDR|oyI<2%k9FwhdiB4~++6m><2&imQd%DB5VT^g`UiQjZviXzdU;)o z4Ps;duP%OwWe6;jVcE%)jW5?)_%_71 z*#EU8hOXmn20z}MC$S@B#$vP9~jA+xyb!f3Se}eIez%?vF&} zM80*i3Cj6$Oan6X!#`d$p(O2WKiwHV2}Dz~EYH`Ya+-Rr$}Nry!?v-u&v41m4aDg~ zpO3FDRKgDUtl4DUEa6>e0GTBu+>Wly2c=d{R6;Dm2K@!Rj>+;~Z7*>am{~Us2KnmcvU1LN5RRsy<^y%= zUWxhO!0PJqBCU*S4{jBjt*|gP&-6I!YQH+7oETS0;3!_IvcOKTR1|?95PJkvDNl@U z&*UdrkkSL>gR_um4C(g3HB^J6&`PWQ$NX=opPZ(y)t@}jm~={syCy2)f4F#;7#`o5 zB$rnqfg&iDTKx(4H9$Q3qFj(vx@T8=W$^iuVEYR!ea&PUXWvn_vj6q`m4mt(`%C4B z6XYeLO1=UvZRamULIJsjXsx7(S-fTU$YICV-^YhdH8X`mgc# z&jk4s$7ep`RB=SctO&R(XTfhwK4-Q%otOdO zoz>6(!5^Q;*Dv4cp#Rf%{d?q||1U8MAhStgJ^BCm>1&Zn^QmH((85jN6sy2e_Q9Qr z2A=)5GA516qoKL;2zzNHK1UBxw9)pyZtb`mdl?er&4oKT=3_I4uXUaeSkAW51V}K&3X3a*@KN+4Bzf3Sik+Kv_A0%#;1pT#v}|< zYBFj?OAPjV6%4&Y70C3wISSaD4JW5-i|LJY4jdm1HeVyBMqq;jCzV~|FYV;TAKpsG z*#-v+L(ghA-IsV0Wt3t9P&mYSb(3$rAY$oL$HxuGGbdAY*Yi{q)=K=>Lk zJ)Pd}TD?(v>pd?^y4WQ+({D;3L%`>>mVk6v6pOf6Bb~_ZwPJ(?qcB2flDjbFu{SRO z^TsL0l)KxT;502l47W<<1MDg3JJqryVNNI~qQR(|f<7p*aUa^Y4o#U?K5dk-XA8yB%=d zC$_gUU$h4+3NTGJj*t%!3tNZFUJVG`Eva~otZF!tgB>w6TD37gBUO%+Fc%%5JH2ol z#F{r@H~c$qvFQmb>!`4$@#AXcxj!Z;uN3Zwb3FIAx0*P0(8EUQpxk~- zs8xlO*M6jSOz@K78?I{-%EsK~5(OvaNPM)Gp}ygS#dNZkBI(mRo3YD>s4BB@PiRI6 zpD($9yFVmsm&&+m_G0c9>6!fjTbZxDQi9RwxoBRVi7kFn+8;x$`p&TMvD{P7q?Cd5 zC_-T6t00!;NE=yRTdjP4_Q2+VSGZJT7|GZuKHu<=TEGn<<4^qPu7jPEoIN>UtR|OI zFNvMguPL0EQP4IZ79W=V!+A4)PO3LDDmag^`YP3WKda^N;eGC?_v@TNEuCgOPW+9{ z%@OTl>wK~bHqtt*3@Pk{x7W2@(h1@(ZncN2$8!xFZ}&vIJIV^>cJkx6t*9olp%)pY z+O!rvO_v_A1v#V{OaXc5b#_FCsu?F^@5$cFY3|OrXJ&|WcLs9)AWePyHeI!FezAUQ z8~K8FqIk-ByeIz9vbe^8Z(ci;kj)RzWWJ>DSVt+8lu!H74j6uJ3?}(bmYN*Q*O6P$ zC@gQ=!56V-3BQ>>HcW79^YRE8oS;3fNzWLC1(5B#1f0%; zl4M=^oz^RS8S2MOO4Sn==_f67Dp~F?pJ!0_8*HUTn-R~H`@CHV&4T-F_7hCiyQ1)s zGKeDG7zXc+;n31bsH+nqFW&*$z`=CI{){);!=2qoK{~&wlYoN@YxBi3(y{GY?V~}! z=SiC5jgKc{Yv}WLJ^y6g|ME&ac59FzCts=3YDo5W!aiQkf^oZ94*xGONh5iX^FR&h ziK$87{A6dJVMHbBv*PUvMt11?Q^8t`H4i^6*djWb-zcc5=^#A5%`Jb(AQi9=&*z(N zJo=bqmm^0+yIzLlQe$_)sd0XK`6AUXAi$>B@?eJwGFP}LKaLYwkO>7ZKEb)s$DP_b;R>rWK| z&_Otysoifb-67(yKK?YbM%flj(Vs zXB;@>`-@iW26`girZ^&*QW!8pLe|voe6B_F#e7(vj;^`jix*IuAHxDlhkQ=LRudKM z7sqaEkE<6NOaimyj2WZaN2}3u=H#<2slz_N+iuDJ7sH#8jh@yFBbrjvoew(vMA3@W z(vX%IY4-7nxL&=<{tXtEl->aGp}xL8+4x>whmFnk!zD++djm#HF3vag^B%XWopbq9 zm}+_HmzRZ0%R-Sme#2bD8RTsj;q^e%zXXN!Cdiu2Rqk!yR>Bq9T1vh-eSK%qGuH>7 z_P03KxV}XWA?FI^<4NMT-&kDeMhEoxO@YS=w%^Cyb>yeyOSa1$4WbQCY75K~Jbnjd zw@Z27+Rs#z@jKL8_le4>Nr{LIOdXN(+1T2`llWNPFvpo8NJ;^zOfHNL&Evy^fH*!K zufy5yuUx^evbC=Soj^d5=55}b6sJOaM;N2$bnmCSbA$H@6U>>ynE6H! zbFOe+ct&IW-UgevV~HPK9iIL*N~Hz-gs!rGASk6)vj)173S7w4>HTjAs&)FbBnvcI z_f8hd$%Gzh zVDoGKWndAtku2fH2Gk6Y(9s1dgg6+A9Ebk!mnB_#W`mL0-($1fNsDY`Z@ai7$Eh-T?huz%Dz;qPbmPKa1mnV}Ub1c!~va*Yw-o%U$zV8-#t;e(KnmVBn9RKMm_Zg*X`kbLd z9vgEs83`E)*FpGJ9iNAUz^|&1%?UF<%LRVu#qElEd3O}s!&>)s(j1n;>XMIA(b7ko zt4G>^hz97vnoY_T;=!D2L`;NQ*iyB}0$=P{ObiD>?me{CL$inNci4Y+hDVQpqvOH4 zbjnrX9mDN@W1ZvoB_aWr;{$r}+>qG8f3{y^QM^}9-RqYY-^|sU`$5^2)BTi&la8X__bU#ZjLWp7 zu5LFKx-dfvGF{S-Z8MNB0cVo=p5{e8orC%AW219Q;AYM!b-P*meSl{%*jb!zKbRyx zXjX;4l~?w>84BZ{ug4(SHC5?=)(ZU(7Embs;ugv5TLNpt55{I*Vj5ZSI?D)jicdAbDaXFmL&U5gw7y8%< ze~!bSQ77+^q>R>jyvN{Ua`FA|68i(~huw-y)6s_c2Add{^NytCz40ntt`$&lH@%gt zsr3l27sEIbr{9??$2Jgfk>De7Ll5e$b=L5I}{Gh+*#Wy53G_2a`@0=av~S zf1OHeVo;I8*fh$?%v^U&dF%tsYF&C!3kx#^8CI&*>)M|FAhl+k8;WdbV@O|&W%lbl z9=IQk*)3Wq*S-)X_3heaA<9s4Q!kk!aHNtOvbshrue4ekE%i*Qs@jaR_9o0-hYtMT zmT)!mnv8(siP(c7Bo{$RMlF$;F-kU%gJFO`YYyAmRl`j3b2JUU^{-DcPk{k@Jg3o2 z_GmyL!cx$#J*evN32{YER0BSZ;=K4f%Im)cb=Io~{n~upS=erhDnmTgU+s6E0{SK{ zV$`Ca_);_t=5$Cuxm2ygdUyQ>Emtq2GnB0f2-h7>#*W>ov#`OPz4Qs0YH_V zN)(Ax$3Q{(f#A--IYMO;gCFA}zw`wzu7L~V2O1nr@8lxR#Nmkv-QJeUaC(OXBdh}R zb2YW<-5gw~78dR&bOvH;Cdg5;e{dlFJPjmRLHgHTuI8g}z@<_>9fRl#6BAm8fEZO= z&Q@94^-zU2&J}EI>@}iiFq$)dsP1bkm4kW=aC^7Q=G?|V8lX5nx+pJZC-g^*bq5jj z0Pn*6Tu;p*G$wL*BZ{ozlXd~-j|>crpWQwbdu>k+piC7lqM>4IJnw}R2vRBcr>TB`wjl# zaW*+@@aJ>2r!jL`&#B*ds6GpP;`VM~c#JGTL>pN4z3=i)tj z3s^UyLvf!JMIfM2dZ0*K`BxjW_Iqf=fJA}!)KtI?`p+^CYW>fyT z(~#Zv_cGcQx&u`}n5w9s^5ojmu8`lnKWOesGf!)4Jt-dbU|5IbIbDC&j5EHI2 zZp;HDL7UzCn7K6gNd+bYii(uehPC`q&)A~H%`WEM$=ZP`j2g!e%G97V5MP7U*SgqT zwuKz%c4Jr&K*WNBKbt6MRLY6==E_aY*YG?oTq^UE8rum* zOTi%IKDgeIQr>8CdW`y4dvFoZi>>x8eUaX$7bjrUD?edUiB{}o*x&JJ+ivwD^d{>p z>ZwH*GQas8_M4`78RQ%FH39oYI@OBox-r+OkQCk%?W9@N^U3?pJs?_$AEh}f=2lc3 zt)VryPDr=+D#z{1*G6UR=CHbL!zU93Yb#n_zdc zFwzykGbnjBkD7LRCknS-8GIv5wg>I;_%nD74)@a^jnW1|bVR$#5A_b%#n=O0S;UWX zuIwLH+kdfm(|WZpCZv%FlSz42Y+haI^ct%@msha+Ldc@qXR73#8?8; zFHn%nUs#fVoJ}#s=p#?WS{?#SJ@SJcTRBcA>&sPp-=$qoKC)7gBw%WqMj$RE)LI+J z^-DVkoDfy=)~EfrJj;fL2GQkCk-irMP?>R%tW$o1LwBfn9dFTUrr%>mVY60+=4xxz z`UJ-q+iOa$%lFn7xqAWaNf9DGkUtK8X*M+btP#;T3p2UwOgA~ub6(pM8a zKL09rlfgXB%tFJB#hdVO!WLUw-zx6*+u@96aiymxmBh$p4g(c)TKo-j4W-^@%28qDg{&@*_f*8K4Q@A_?E(&j1lvd`%|`i^aKe#d_d8Xf z`uD2c9w1&4gmU4z-pxi*V;J#2yflz;v|CrnA4OGTTpGd!I^#l(VYMeQi z_36KX%12I*r!rM0wumSizK%5YoE|6NZq2N|K3K^;LY{s!M?dU{r*Eauv18}$IQpZT zTAWi<^lksN9$ezIw0}WT95|VWeYkjyNQvnK%t6AURg06$?U;xJ);UiLmj7*?2 zTemH}&>2Rq-LU9JXiQv``P#Abv&vFRlv0boL|i2vr~61MAI8l_X_=S=czF{swL0kv zdWA<;9~R$kucwjt&vPVJ3CkY(8D)$DgEkRs@g^cQ-^6 z4b8r%z3us2`|SBT9nBa|iUYj)nTVeiXw+{8YcL)%X{oVo;G!RD^39gI)6eR_Ow!EF z4HVk@-v7+5HlF=Ss$P=*>)tr}l@Bfv4;1swBU@QYSy{wjj_N~StkuZmWP{5_Q9=Uh zlvn>n+T7-Vt63ZY%p@22xEslMq>SRMf?ydf`_JK7z zQg%R}I^RyySob3k_X`R7kwmnNb!GOrW>;|MX%zOaYp&WG&giyusG77(_vmVd3!^+5 z^DAFw%Og#&$Ricc1x`Ilp)>T@9lS5(|J*seV|5zT>4i-jHH5kS{Ftw3vBvT8X>l?u z1PPGS;RuZ!X3H&1S>-%#tC4S)P-*mHL6)!;4sn^R43s(HU!tv1 zooCr4?S4;`wf^0N83?A4VwmXg@6{#;ZR$$moV!DgT8d88>8xHMlz{p>L371#efQS zQRlq#n@IAbcDeb*WXbO@geE(2(xA-UEW zmY+Z33-a~`nnaz;w2KGL8)-Id?KxBeu(Upw{_FG8)8B%kLpe)&3LC|-_|9~}B<~m8 zI9j$_RyG8~X@!lRevHFxOD2vvXaxh`^po?cfU>mv^65D!+s-!S2$bx0_82=bTLd%I_OF}1|bY069WzgVwjf)%n`*&GM!N_cF-aB}z5cU?F*FQum zijy4%T|Vw2x_4a@%DMz_XFnF7_k9@L3G{b7CW<(|ZG=F(qhNqAM{F>7UK)eP0cr-C zU081Jvd!5$SKIuQIyMjbI+xP5(9zywt9}Xfz|)peM2+e2W`rj38{9CEis*M`nJUO2 z3c7N!}g#_g{5!v&o3_7@)M88No^Ugr7_qE ze+C?5`Hzg3}pXg@K38?SH_k}>5fc;NOK&k(ayWhi(aL;L=CM!tgmx7nN`s|3m zYj-STt;}capRL48%>U-cH!n4sbqC6<9IB#$XWIn-qj*`q8Y?d91K+ne{(Ayi33~p| zeooBCTs$7uO#czo9P=(S(t%g}d&vJk2%xvbMnhOS94;-VpE@+2oz}VQ%95rU$$-a+ zhc4V+?pHu3+@#>H0{?|!s#5-_37Bd&%ZhsLSeK!H_> z&_f-AW>x8UW$pY&9YfRpY%YtrYMX_Swl?9R_iB}u>@)sFa(tL%+-nEKFY!~pTbYfO zLO=@UY-}AJh%rs9KDs(~(`ZbP1sPdgAp~!zsk@p$Oh>up*r8u&%2*U=?PSRWG-Xt3 z)9GpV7{C}0M0HcC*@Ldn#eoyd!i0XV!9^8q0_^#=K*Ta-*x2yZ_ zueB@%ZelP{2$uVzt6k^Zklu|rwPh4~@WJdAk~8Bc&{KkuSkga&33nSZ55}prdq5)26fZG1?0y6{E)d7+VSTXqu)j}&yzEEBWjfqXo55MA-tzAk zZHa}cjpga-Wx>)L9B$^PhOE#@rz5HPoiA4ltD9}}vjJE(Ps!R-2!OiAxmuAuh4#C0 z>}rdzZADwba~KW*@p;x?KkMg^wbRy7Flsdv%{CRuT$t9W;$`DVI&Iptjqdec3V3I_~tbV~2hlDRP-iCMu7+=e5*ksZ^#Uv(H+YXJW z>^Tlu^~qRlje$uOsPchlNlZQ% zXy?AL1y~u~jm5C`PtG(w&7-0|Jr{|bV=x04)$WH`(g*S|pr9w7pVz+UI;&qE9&CI} zv*55;2z-nKx~&^ z9=~<3kuY2ir|QeAVhll*VO|{z4%Lw}5j8Fs%f<2VHmYoDUodt`k5#ieUVIIu+GwEq z&4{!U5T#3EYZRo10DT6wg$Sh1#i*lZNK}$;xzc#|dLj#WN9=%s327TT2JD}KRk+X7 zE)nE&r;Dz{gELhXrS^{LpRd8=yuo10(;&Y}(d%g=#Zfz`|Bn9GOz2}7eI})BtQO_# z$Ozh`hzN(({*8L9WDq`4ex%jBamq*&^|n4eJ>72GZkPED54GwyNlB@E)aVyGrSRrT zi$4ivY$y$AD+!|}x%n)|^$I0BrxfT|GpX(!2w(o+2QQmm}LSw1V=+XgTxiMI?MFj|1URO;neh1s zD&FSAZZm*PeQ>)U_Xb$^bZlMzS`K4sL1(r}H_rOT=JAl1V#I5ZnTZzqyR0HNJnBy` z=bf^WinZy;??p(7UHhW<``Ty_gp_?7rfb$@zqNAC-SEw4Ldxi0J^Q+ryA~%TJR*Xf zizD0Wrzvr=YlDm39r_Wrfx!jY$B;>pa)ss4HWpM=ZT7bed%WvB89&(E+T!eb2gzHbNkB#jmLQmAN%9k=5t(=0a{$jkgtYj306QSXWF=zJej{y4PM zWjiEtFW2ZYLjnxpke9{(Wf_mp2E#{e`FIn}wy?m3INxAbqp`)Q4cYx$j;~xbK9P63 zeYs=Ah)=e_U2eRnpU`B{{+jNIV!Cy^OHQbHj$c68X!mrDJ+Rj5_&+ldK1kv4)vLZK zb6m}wgoNG&v+kll3pr`6fs*oedW-!h#mNwm*TK-3c}k~oI$vVIL`B1MxB7SD{nen% zKmG!i`@0$#@TZU_VO#HLE##}O(pz@S*hWtJjJ5ym?r7g1@F2GFGyOrY;^KBy;J0VM z!|T#?TIYVG0CHNlGvi`nKxaxjuzWx)*y<`7l|X^dI48&*21A=Chd?jxUHS|$Oj_ZW zWaZ3UY334apVq2r|KZd!V2I${KIcf zk5A4B;~PrzXnvGf4|v7O6)!Zp?B95!;WX=AFUah~+fah+HyEPhRG&iYq46KhNBiUes`}LoKJHqm-{y0+dni zvtiL5aJbX5K+nIsSkBf!?>HHFDlBGd(%dB_>3Bm6g3uGcuc5Kr=et}&7+2p6$;lVK zpZM~kHsW+@C_TSEuiRN=d~Cxwe-nf7C;77{Ap#0tKffd0q&Wd-zP-5<70+J6W?O|z z2|Jh0HOB;C8Vzbxa58Zf|H=9{ap)b){tRD)Y^y^c6SXSXzG^SvqHIvQf^P{^xf(e! zdW}5iiW*Y3`#qk@5hU}?yu66S%TCwV+@82w zcDXE1T*wq~eh$QYt**WXhh5q;A9Qd@*62-zyFEH{Et3|1(B<6Gzr2jx)&uQ|tI4y&8LLi8!%gif0E^41#KB|)F;Fz}z2$)W$ z{`L*orM1ir&8h<9$?O3PP=;XSmGs_V{;OoK;bK#t^r!~{g96g%$YCEo{9ojKWl&vR zuw{%01PBhnf;)uZ5Fo+bCAho0LkRBf?(XgqoC^eZcXzkheDdbKs+nI?BUN*LrEV_g z9_`(|di7ct2gNSk=&lil^=rDWuV(&i`JIw}pX4;oLROjGn{GC|td5dG{g< zv4JPxZ$A$uw34~CRm|GWR=?lfLsUwio7_^Uv#8N=+KdSKY?hRNv!LiKY#>H7qceOH zmk$sXI2Lw9UP>*;Cjzs6Q`^>!8Jl2+6WtX<+&uOrbSj~n|5CW3+=jB_c0ScyEuQt% zy0^qHHScs?<#;37TCgg&IUrtnxZ3TmIj=_d1M$E~$^@%ZIGWbs0w=O2ZnDqa#Dl6= zn&|l*JgR6pe6af=$&E)qzYb=I>1?E}IoL0ZgJ@2zG0pzXZ!^`7NcUTUAIF&Zw0F@w zXCg2M?B?O=?ho#51_s-|0!s1T^%dlk3uP5Y%nCZNurLZ&JeBdwCqUF z>zI+8fr{lb@>f*M4?NI!{%RZ2@422(WI~V){evREHkz4QUZ`5# z6uaX;hy05o3(xzPe>wcX9koAq8~|&wwQUG9NPN701<};Z+Qhi{#t3?XZOf_Kc=oSo zj1;b@Ub(?BFrawj!o59rqP#jSQ%O{;F;36U7oqh64lPZ`E3j_!9*f`e0E!^XXaPXo zwy3#UdtYKk%eA1A@0-FkXpI(35YZqb#W+c4sv{NO7$$JHa@|!F8v6K9W5tW;V#V=7 zK$3_JC{SWG0h{71R@OcqE+(c3)#tBx7XiyDs%l1X)!Q#10Qak-cSFCT#L?}tmM+kV z$qBAn?;3whW^a}T6BG$4^SLFht@Xx3A2ph}|9UHU&}IRxr^#kB&A%K`g}~yslzDJ+ zZD?E+FGH{jD+}FX5Ve@&1ul0CJ>V9=9jKDn6a5YgkJNT5X@P;($+?0$nwk9wAZdHi z_G>e!7QIF2C3y6q3E{s&pSW7j8ip|G)@ZIfJKKBmR(Q`Bn<)UMjjxU-CIZdV(6BgJ z35liUYw!GK3{@=mNsW-5f@#N9aM_@#1x`zuip&f3*qnCIg@8O?c}=3aQ?r++w{)Wi z{znXqI8hGSSX@@y;N?r2+P0QMza?gi&&1PU!uApq0Tqvzuk-CS_Fw4^ zUj66T&n9@XS-JV7DPJ3dg0SDF?>b*dHHr@f8^cc@hK0vZShb>)!;O`HVXJqGSh~u# zUgkmjdZv!qRBha~`_p-EtrKvGHfa{M%>t)>x+y7K6y3rnH``xF%h_!2m^dn=EXp^5 zLiW5U$tl?J`bv6Qd%n-%eQO9%PDt_fcLNzidf)!$LCJfnkA|4jHHVC6?dwXAoLLcV zy-jAu!x>NvK?yUNj{~(;fw7J}J>Y^3n4NTvE6UzX@!yab&6R3wMZG7nmuwhDZvagY z^!cqT3of>Y!-%OBo6A6H12<4FVIe7>vy-^JXc?2;yXu3nwJS;FmN4j%$OcVEadR`FGxu@d2-X4k{5%znN(((eegtd~rMX7VS=l!;fKnenzo z1s})QAuTV!K-0LpgfmalqQ2(l0fDf*iNW63DYrI#jjsZ1#=ASbD%(RgF_@9ZT&G1z z*XJpiY7+A=*u~N5V(}fVt8rLd;W`OwH-v#xUIK%gjtA=elxXSe^W8x{+w4JA#rZLd zsjY3G^x5v_176gl#|=OwHZGa+>>$j6yWfuYbPU4q{ZZ#AtW2hmxUi>keafPbwZ<;ph_U5oDxgvZC$~~C0G(bv z9~CR>QU=(i3whISs zOdwd6mZ(V2>Y#4~aw1Ti0ftT`kO`A^Qbl3q6|X5&(pG8!G9sqN%IzCfFg|CGb4n%I zQ5fUKqiJh#2{}OS**DEa{s~HCxJh{cS%_};$5caG8wS-Mp8gpC5(Vbvrx))eWaZLX z_Y-1*bMst<`I%vDstPtQMp2Dsf4pvl2@8vU653f~jy&p4$0~Q4?E_>sUfxci>`Hd_ zZ90Ua6|`q7sL07wC(=~<%jH&n3|*{jvjZMbmOxy|W5dq4bpn&cSV?w&^K7lgu!?%! z^GYBIb$ce)WO)%J*E9GnrwdSeAhBQllbQkM+Se4hc(KPhT(7e_%5VFYnnACtcD!Gg z$zUxt^^sRzS*QgSlc5IXKKTJ~bY*iaF? z>Z4F1R1c)ae*=-AxD%Wd01|%>7&Dt4X+`Pjjpb>XnH{~qXZ2&Y$P4_v9RU`OCbka- zN|gXEaxSN+$hzaYl!GWZ!~=JW@?SAVsrwycH;V(q>Ee`_5Y8mz7)VOrokn?i1uO&; z7`PowRaOdj3YW)h}uve}27u_F#W! zLF>wfyVx3}ba``gd{YN(*9sMDJg`fD&%LiU;AGY>sfsi0Le-I$FZa@R_{&|?3+*WXG@!; zeI9^p!TZ0C;#q45!QityazN&s<`)tIay5wm{PK|p(7bO6wkjZg98AtlD^_fZr~dc9 zR#OA|aPtAi1L)fvj(fIOQ+0satuRxacz>AR*!cBgzSOq|U?|nQtR4RaM5&=1u-%%P zPRqzvnzSnZ?*L4lpH>d_2(fkG?!1kI2n`S+6isY?B7TDjf+?m0dWWu+BY4R<$l)(; zw#%FDKjo4jI*X+=+yD@>Jk)&st@*LPC@A-R z0YI6P$ZS<7e24&I_b$`!7t6an(3&h8wX!;mE}WaIm4%;)gPZqxg6~8%7V9nVsZAV# zb3MFDO3nV4sn$k36N}Acf`2aC9WFO0p+9!MNY~N?(jmWdPymtuLFeC|OH?Kw5f&7T zPx#p4y6beCylWLA4_J4ATP$`cRj6^;7BMFTEIa`^)G`%sHt)dfGH5AOsLI;FJNi2E ztuvYlV-@*~xIX`mluacg5sIWdyM!Qp z2pFyJtmw2rN5=7wDNQn`7ujU;OOg#LMd5d#Uc<%Dpi!-xPjywfDEj^=l7<5O?*23X zwdMY?D2t5u*6nf_sEtnNzG>h^L0MOwpP~Ev0XcGe2Xa$=KqJ-*J}|FyC>JxKaCEr3 zx(qp`QMbtS~ z-cBBHbA#fUnK(J0*c0@aY)w{ga=4usubLX|9&h}nN4rOmhhkI#ZG_C?;?9P#zD(=% z3+@mb2t_#q78H#Rx6h#nGP5#G)mXUtN8m;~RBnU8=t|V%HekMHY!)XanyIqhP25jZ zoxX9jIczNoMT{BR%YwIm=%Dt-9cFg8fUYq%G*l$uce?pm$pY|@_!Hk2#=lSY>JgY% z;uZ=1c7(;=e`4SLNA35aqj`NUKd&&5o@j4(M#9`35vWUUUH{LDKS)o{9w1&~_NYt7 zwgMuwq@-%J{#70kFNA-Am0itYm<~#z-dZ21a(=Z|AIgvaIQPpqk&Bmi`$A&g_2X>$+~5Q&C4TsVtdz{shRm{C zG{8FBIstji#WCiR3I!DzSW`c3M~~1?Pn@x~`?436KO*wUTWD8KX9%Q!@&E|R&DGv4 zR&?6|pIY+(Qu3ZrI$qLOK5waXM`|@d4;#GEb>PiqTknYL7nU=1UAk$syM%l5pwwV{ zt=x7!%^Xnj$Ogzj&iFBM^0FFNu!8B_Uti%47R7&A2aP&x#@ra6-F2{v$_z_{1o|s9 z_)X69DF}uw+tn{`h=_<}>tXNb{|XQm5cvG}!9H^axyA5PQmuuhM{^RdA|T+4i6IC7 zlpFs5lQe(l#=n8jx@nlBZPj$g!F~5O3jtmKc^*IDQk#04Ce1?PSsnYXmLro{jSPMO zmFlZEuSP3u$H|dz_2={b(!cG#(=^T$AF{A`$1kqjGuT^abBO>&P-~Y!Z<(rhiB=Ml z(%c~iEUonpAzX6Bv$TfoiA<`lM4UGKcKs5S$U z{sctv6eo}=)7_N`Jb@2j`#JIy*{L}2^0HNo4v2W^Wg?@_tgEJDK>jy6p6B>5A_{C6 ziUqx%a>tA}W(yYTm(8nZ>LfT*RdPVGJwdm-F7~tTQBeatP+JD*{NOsB6OaH!f0)